Rename tools to ao-<foo>
[fw/altos] / ao-tools / target / dma / dma.c
diff --git a/ao-tools/target/dma/dma.c b/ao-tools/target/dma/dma.c
new file mode 100644 (file)
index 0000000..1762b65
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdint.h>
+
+/*
+ * Test DMA
+ */
+
+sfr at 0x80 P0;
+sfr at 0x90 P1;
+sfr at 0xA0 P2;
+sfr at 0xC6 CLKCON;
+sfr at 0xbe SLEEP;
+
+# define SLEEP_USB_EN          (1 << 7)
+# define SLEEP_XOSC_STB                (1 << 6)
+
+sfr at 0xF1 PERCFG;
+#define PERCFG_T1CFG_ALT_1     (0 << 6)
+#define PERCFG_T1CFG_ALT_2     (1 << 6)
+
+#define PERCFG_T3CFG_ALT_1     (0 << 5)
+#define PERCFG_T3CFG_ALT_2     (1 << 5)
+
+#define PERCFG_T4CFG_ALT_1     (0 << 4)
+#define PERCFG_T4CFG_ALT_2     (1 << 4)
+
+#define PERCFG_U1CFG_ALT_1     (0 << 1)
+#define PERCFG_U1CFG_ALT_2     (1 << 1)
+
+#define PERCFG_U0CFG_ALT_1     (0 << 0)
+#define PERCFG_U0CFG_ALT_2     (1 << 0)
+
+sfr at 0xF2 ADCCFG;
+sfr at 0xF3 P0SEL;
+sfr at 0xF4 P1SEL;
+sfr at 0xF5 P2SEL;
+
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFF P2DIR;
+sfr at 0x8F P0INP;
+sfr at 0xF6 P1INP;
+sfr at 0xF7 P2INP;
+
+sfr at 0x89 P0IFG;
+sfr at 0x8A P1IFG;
+sfr at 0x8B P2IFG;
+
+sbit at 0x90 P1_0;
+sbit at 0x91 P1_1;
+sbit at 0x92 P1_2;
+sbit at 0x93 P1_3;
+sbit at 0x94 P1_4;
+sbit at 0x95 P1_5;
+sbit at 0x96 P1_6;
+sbit at 0x97 P1_7;
+
+/*
+ * UART registers
+ */
+
+sfr at 0x86 U0CSR;
+sfr at 0xF8 U1CSR;
+
+/*
+ * IRCON2
+ */
+sfr at 0xE8 IRCON2;    /* CPU Interrupt Flag 5 */
+
+sbit at 0xE8 USBIF;    /* USB interrupt flag (shared with Port2) */
+sbit at 0xE8 P2IF;     /* Port2 interrupt flag (shared with USB) */
+sbit at 0xE9 UTX0IF;   /* USART0 TX interrupt flag */
+sbit at 0xEA UTX1IF;   /* USART1 TX interrupt flag (shared with I2S TX) */
+sbit at 0xEA I2STXIF;  /* I2S TX interrupt flag (shared with USART1 TX) */
+sbit at 0xEB P1IF;     /* Port1 interrupt flag */
+sbit at 0xEC WDTIF;    /* Watchdog timer interrupt flag */
+
+# define UxCSR_MODE_UART               (1 << 7)
+# define UxCSR_MODE_SPI                        (0 << 7)
+# define UxCSR_RE                      (1 << 6)
+# define UxCSR_SLAVE                   (1 << 5)
+# define UxCSR_MASTER                  (0 << 5)
+# define UxCSR_FE                      (1 << 4)
+# define UxCSR_ERR                     (1 << 3)
+# define UxCSR_RX_BYTE                 (1 << 2)
+# define UxCSR_TX_BYTE                 (1 << 1)
+# define UxCSR_ACTIVE                  (1 << 0)
+
+sfr at 0xc4 U0UCR;
+sfr at 0xfb U1UCR;
+
+# define UxUCR_FLUSH                   (1 << 7)
+# define UxUCR_FLOW_DISABLE            (0 << 6)
+# define UxUCR_FLOW_ENABLE             (1 << 6)
+# define UxUCR_D9_EVEN_PARITY          (0 << 5)
+# define UxUCR_D9_ODD_PARITY           (1 << 5)
+# define UxUCR_BIT9_8_BITS             (0 << 4)
+# define UxUCR_BIT9_9_BITS             (1 << 4)
+# define UxUCR_PARITY_DISABLE          (0 << 3)
+# define UxUCR_PARITY_ENABLE           (1 << 3)
+# define UxUCR_SPB_1_STOP_BIT          (0 << 2)
+# define UxUCR_SPB_2_STOP_BITS         (1 << 2)
+# define UxUCR_STOP_LOW                        (0 << 1)
+# define UxUCR_STOP_HIGH               (1 << 1)
+# define UxUCR_START_LOW               (0 << 0)
+# define UxUCR_START_HIGH              (1 << 0)
+
+sfr at 0xc5 U0GCR;
+sfr at 0xfc U1GCR;
+
+# define UxGCR_CPOL_NEGATIVE           (0 << 7)
+# define UxGCR_CPOL_POSITIVE           (1 << 7)
+# define UxGCR_CPHA_FIRST_EDGE         (0 << 6)
+# define UxGCR_CPHA_SECOND_EDGE                (1 << 6)
+# define UxGCR_ORDER_LSB               (0 << 5)
+# define UxGCR_ORDER_MSB               (1 << 5)
+# define UxGCR_BAUD_E_MASK             (0x1f)
+# define UxGCR_BAUD_E_SHIFT            0
+
+sfr at 0xc1 U0DBUF;
+sfr at 0xf9 U1DBUF;
+sfr at 0xc2 U0BAUD;
+sfr at 0xfa U1BAUD;
+
+#define DEBUG  P1_1
+
+
+# define DMA_LEN_HIGH_VLEN_MASK                (7 << 5)
+# define DMA_LEN_HIGH_VLEN_LEN         (0 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_1      (1 << 5)
+# define DMA_LEN_HIGH_VLEN             (2 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_2      (3 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_3      (4 << 5)
+# define DMA_LEN_HIGH_MASK             (0x1f)
+
+# define DMA_CFG0_WORDSIZE_8           (0 << 7)
+# define DMA_CFG0_WORDSIZE_16          (1 << 7)
+# define DMA_CFG0_TMODE_MASK           (3 << 5)
+# define DMA_CFG0_TMODE_SINGLE         (0 << 5)
+# define DMA_CFG0_TMODE_BLOCK          (1 << 5)
+# define DMA_CFG0_TMODE_REPEATED_SINGLE        (2 << 5)
+# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5)
+
+/*
+ * DMA triggers
+ */
+# define DMA_CFG0_TRIGGER_NONE         0
+# define DMA_CFG0_TRIGGER_PREV         1
+# define DMA_CFG0_TRIGGER_T1_CH0       2
+# define DMA_CFG0_TRIGGER_T1_CH1       3
+# define DMA_CFG0_TRIGGER_T1_CH2       4
+# define DMA_CFG0_TRIGGER_T2_OVFL      6
+# define DMA_CFG0_TRIGGER_T3_CH0       7
+# define DMA_CFG0_TRIGGER_T3_CH1       8
+# define DMA_CFG0_TRIGGER_T4_CH0       9
+# define DMA_CFG0_TRIGGER_T4_CH1       10
+# define DMA_CFG0_TRIGGER_IOC_0                12
+# define DMA_CFG0_TRIGGER_IOC_1                13
+# define DMA_CFG0_TRIGGER_URX0         14
+# define DMA_CFG0_TRIGGER_UTX0         15
+# define DMA_CFG0_TRIGGER_URX1         16
+# define DMA_CFG0_TRIGGER_UTX1         17
+# define DMA_CFG0_TRIGGER_FLASH                18
+# define DMA_CFG0_TRIGGER_RADIO                19
+# define DMA_CFG0_TRIGGER_ADC_CHALL    20
+# define DMA_CFG0_TRIGGER_ADC_CH0      21
+# define DMA_CFG0_TRIGGER_ADC_CH1      22
+# define DMA_CFG0_TRIGGER_ADC_CH2      23
+# define DMA_CFG0_TRIGGER_ADC_CH3      24
+# define DMA_CFG0_TRIGGER_ADC_CH4      25
+# define DMA_CFG0_TRIGGER_ADC_CH5      26
+# define DMA_CFG0_TRIGGER_ADC_CH6      27
+# define DMA_CFG0_TRIGGER_I2SRX                27
+# define DMA_CFG0_TRIGGER_ADC_CH7      28
+# define DMA_CFG0_TRIGGER_I2STX                28
+# define DMA_CFG0_TRIGGER_ENC_DW       29
+# define DMA_CFG0_TRIGGER_DNC_UP       30
+
+# define DMA_CFG1_SRCINC_MASK          (3 << 6)
+# define DMA_CFG1_SRCINC_0             (0 << 6)
+# define DMA_CFG1_SRCINC_1             (1 << 6)
+# define DMA_CFG1_SRCINC_2             (2 << 6)
+# define DMA_CFG1_SRCINC_MINUS_1       (3 << 6)
+
+# define DMA_CFG1_DESTINC_MASK         (3 << 4)
+# define DMA_CFG1_DESTINC_0            (0 << 4)
+# define DMA_CFG1_DESTINC_1            (1 << 4)
+# define DMA_CFG1_DESTINC_2            (2 << 4)
+# define DMA_CFG1_DESTINC_MINUS_1      (3 << 4)
+
+# define DMA_CFG1_IRQMASK              (1 << 3)
+# define DMA_CFG1_M8                   (1 << 2)
+
+# define DMA_CFG1_PRIORITY_MASK                (3 << 0)
+# define DMA_CFG1_PRIORITY_LOW         (0 << 0)
+# define DMA_CFG1_PRIORITY_NORMAL      (1 << 0)
+# define DMA_CFG1_PRIORITY_HIGH                (2 << 0)
+
+/*
+ * DMAARM - DMA Channel Arm
+ */
+
+sfr at 0xD6 DMAARM;
+
+# define DMAARM_ABORT                  (1 << 7)
+# define DMAARM_DMAARM4                        (1 << 4)
+# define DMAARM_DMAARM3                        (1 << 3)
+# define DMAARM_DMAARM2                        (1 << 2)
+# define DMAARM_DMAARM1                        (1 << 1)
+# define DMAARM_DMAARM0                        (1 << 0)
+
+/*
+ * DMAREQ - DMA Channel Start Request and Status
+ */
+
+sfr at 0xD7 DMAREQ;
+
+# define DMAREQ_DMAREQ4                        (1 << 4)
+# define DMAREQ_DMAREQ3                        (1 << 3)
+# define DMAREQ_DMAREQ2                        (1 << 2)
+# define DMAREQ_DMAREQ1                        (1 << 1)
+# define DMAREQ_DMAREQ0                        (1 << 0)
+
+/*
+ * DMA configuration 0 address
+ */
+
+sfr at 0xD5 DMA0CFGH;
+sfr at 0xD4 DMA0CFGL;
+
+/*
+ * DMA configuration 1-4 address
+ */
+
+sfr at 0xD3 DMA1CFGH;
+sfr at 0xD2 DMA1CFGL;
+
+/*
+ * DMAIRQ - DMA Interrupt Flag
+ */
+
+sfr at 0xD1 DMAIRQ;
+
+# define DMAIRQ_DMAIF4                 (1 << 4)
+# define DMAIRQ_DMAIF3                 (1 << 3)
+# define DMAIRQ_DMAIF2                 (1 << 2)
+# define DMAIRQ_DMAIF1                 (1 << 1)
+# define DMAIRQ_DMAIF0                 (1 << 0)
+
+struct cc_dma_channel {
+       uint8_t src_high;
+       uint8_t src_low;
+       uint8_t dst_high;
+       uint8_t dst_low;
+       uint8_t len_high;
+       uint8_t len_low;
+       uint8_t cfg0;
+       uint8_t cfg1;
+};
+
+#define nop()  _asm nop _endasm;
+
+void
+delay (unsigned char n)
+{
+       unsigned char i = 0;
+       unsigned char j = 0;
+
+       n++;
+       while (--n != 0)
+               while (--i != 0)
+                       while (--j != 0)
+                               nop();
+}
+
+void
+debug_byte(uint8_t byte)
+{
+       uint8_t s;
+
+       for (s = 0; s < 8; s++) {
+               DEBUG = byte & 1;
+               delay(5);
+               byte >>= 1;
+       }
+}
+
+struct cc_dma_channel __xdata config;
+
+#define DMA_LEN        8
+
+uint8_t __xdata dma_input[DMA_LEN];
+uint8_t __xdata dma_output[DMA_LEN];
+
+#define ADDRH(a)       (((uint16_t) (a)) >> 8)
+#define ADDRL(a)       (((uint16_t) (a)))
+
+void
+dma_init(void)
+{
+       int i;
+       config.cfg0 = (DMA_CFG0_WORDSIZE_8 |
+                      DMA_CFG0_TMODE_BLOCK |
+                      DMA_CFG0_TRIGGER_NONE);
+       config.cfg1 = (DMA_CFG1_SRCINC_1 |
+                      DMA_CFG1_DESTINC_1 |
+                      DMA_CFG1_PRIORITY_NORMAL);
+
+       config.src_high = ADDRH(dma_input);
+       config.src_low = ADDRL(dma_input);
+       config.dst_high = ADDRH(dma_output);
+       config.dst_low = ADDRL(dma_output);
+       config.len_high = 0;
+       config.len_low = DMA_LEN;
+       DMA0CFGH = ADDRH(&config);
+       DMA0CFGL = ADDRL(&config);
+       for (i = 0; i < DMA_LEN; i++)
+               dma_input[i] = i + 1;
+}
+
+void
+dma_run(void)
+{
+       DMAREQ |= 1;
+       DMAARM |= 1;
+       while (DMAARM & 1)
+               ;
+}
+
+main ()
+{
+       int i;
+       P1DIR |= 2;
+       CLKCON = 0;
+       while (!(SLEEP & SLEEP_XOSC_STB))
+               ;
+
+       dma_init();
+       dma_run();
+       for (;;) {
+               for (i = 0; i < DMA_LEN; i++)
+                       debug_byte(dma_output[i]);
+       }
+}