8 #include "serial_dma.h"
\r
11 #define UART sdma_uart
\r
12 #define DMA (&(DMA0->DMA[sdma_chan]))
\r
13 #define MUX ((dma_mux_t*)&(DMAMUX0->CHCFG[sdma_chan]))
\r
19 typedef struct {uint8_t CHCFG;} dma_mux_t;
\r
22 static UART0_Type *sdma_uart;
\r
23 static int sdma_chan;
\r
26 static int sdma_stuck;
\r
27 static int sdma_full;
\r
29 /* Data buffering */
\r
30 static int sdma_index;
\r
31 static int sdma_length[NUM];
\r
32 static uint8_t sdma_queue[NUM][LEN];
\r
35 void sdma_setup(UART0_Type *uart, int channel)
\r
37 // Save configuration data
\r
39 sdma_chan = channel;
\r
42 SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK;
\r
43 SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;
\r
46 DMA->DSR_BCR = DMA_DSR_BCR_DONE_MASK;
\r
48 // Configure DMA transfer
\r
49 DMA->DAR = (uint32_t)&UART0->D;
\r
50 DMA->DCR = DMA_DCR_CS_MASK |
\r
56 // Configure DMA Mux
\r
57 MUX->CHCFG = DMAMUX_CHCFG_SOURCE(3) |
\r
58 DMAMUX_CHCFG_ENBL_MASK;
\r
60 // Configure UART for DMA Channel 0
\r
61 UART->C5 |= UART0_C5_TDMAE_MASK;
\r
64 /* Write binary data out the DMA output queue */
\r
65 void sdma_write(void *data, int len)
\r
67 if (sdma_length[sdma_index] + len > LEN) {
\r
70 int pos = sdma_length[sdma_index];
\r
71 void *dst = &sdma_queue[sdma_index][pos];
\r
72 memcpy(dst, data, len);
\r
73 sdma_length[sdma_index] += len;
\r
77 /* Write ASCII data to the output queue */
\r
78 void sdma_vprintf(const char *fmt, va_list ap)
\r
80 int pos = sdma_length[sdma_index];
\r
81 void *dst = &sdma_queue[sdma_index][pos];
\r
82 sdma_length[sdma_index] +=
\r
83 vsnprintf((char*)dst, LEN-pos, fmt, ap);
\r
86 void sdma_printf(const char *fmt, ...)
\r
90 sdma_vprintf(fmt, ap);
\r
94 /* Trigger DMA transmit of the current output queue
\r
95 * and swap buffers so we can write into unused space */
\r
96 void sdma_flush(void)
\r
98 if (sdma_length[sdma_index] == 0)
\r
101 // Wait for transmit complete
\r
102 while (DMA->DSR_BCR & DMA_DSR_BCR_BCR_MASK)
\r
106 DMA->DSR_BCR = DMA_DSR_BCR_DONE_MASK;
\r
108 // Set source address and length
\r
109 DMA->SAR = (uint32_t)&sdma_queue[sdma_index];
\r
110 DMA->DSR_BCR = DMA_DSR_BCR_BCR(sdma_length[sdma_index]);
\r
112 // Enable DMA transmit
\r
113 DMA->DCR |= DMA_DCR_ERQ_MASK;
\r
116 sdma_length[sdma_index] = 0;
\r
117 sdma_index = (sdma_index + 1) % NUM;
\r