1. I want to write code, in which when I have 512 bytes ready, need to send them to uart0 & with every byte transmitted, 1 byte is received. So in the end 512 bytes tx & 512 rx. Want to do it using DMA. 2. Written below code for it, but don't undetstand how to start the sequence to start transferring data? 3. Using TM4C123gxl, keil 5.13 & driverlib 2.1.2.111 /* controlt able used by udma , must always be 1024 bytes */ /* Query: waht is its purpose? */ #if defined(ewarm) #pragma data_alignment=1024 uint8_t dmaControlTable[1024]; #elif defined(ccs) #pragma DATA_ALIGN(ui8ControlTable, 1024) uint8_t dmaControlTable[1024]; #else uint8_t dmaControlTable[1024] __attribute__ ((aligned(1024))); #endif /* source & destination buffers */ #define BUFFER_SIZE 512 uint8_t source_buffer[512]; uint8_t destination_buffer[512]; volatile uint8_t g_dma_err; volatile uint8_t g_dma_unknown_err; volatile uint8_t g_dma_complete; void isr_dma_sw(void) { uint32_t mode; /* Check for the primary control structure to indicate complete. */ mode = uDMAChannelModeGet(UDMA_CHANNEL_SW); /* query: suppose I have 2 or more dma enabled, how to know which has caused this error,or only one has to enabled at one time */ if(mode == UDMA_MODE_STOP) { /* Increment the count of completed transfers. */ g_dma_complete = 1U; } /* If the channel is not stopped, then something is wrong. */ else { g_dma_unknown_err = 1U; /* query: what to do in this case */ } } void isr_dma_err(void) { uint32_t status; /* check for err status */ /* query: suppose I have 2 or more dma enabled, how to know which has caused this error,or only one has to enabled at one time */ status = uDMAErrorStatusGet(); /* if err has occured */ if(status) { uDMAErrorStatusClear(); g_dma_err = 1U; } } void isr_uart_dma(void) { } void start_trnasfer(void) { uint32_t ready_count; /* configure DMA uart */ uart_configure_dma(); /* enable udma clock */ /* only disable & reset it once */ SysCtlPeripheralDisable(SYSCTL_PERIPH_UDMA); SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA); /* enable periphral */ SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); /* while not ready */ ready_count = 2000U; while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA))) && (--ready_count)); if(0U == ready_count) /* if periph not ready take action */ { } /* enable udma */ uDMAEnable(); /* set base for channel control table */ uDMAControlBaseSet(&dmaControlTable[0]); /* assign the channel */ uDMAChannelAssign(UDMA_CH30_SW); /* Tx DMA setting */ /* clear any previous defined attribute */ uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0TX , UDMA_ATTR_ALL); /* set the control pars */ uDMAChannelControlSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT , UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1); /* transfer set */ uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT, UDMA_MODE_AUTO, source_buffer, (void *)(UART_BASE + UART_O_DR), BUFFER_SIZE); /* Rx DMA setting */ /* clear any previous defined attribute */ uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0RX , UDMA_ATTR_ALL); /* set the control pars */ uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT , UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1); /* transfer set */ uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT, UDMA_MODE_AUTO, (void *)(UART_BASE + UART_O_DR) , destination_buffer , BUFFER_SIZE); /* clear any previous pending int */ uDMAIntClear(UDMA_CHANNEL_UART0RX); uDMAIntClear(UDMA_CHANNEL_UART0TX); uDMAErrorStatusClear(); uDMAIntRegister(INT_UDMA , isr_dma_sw); uDMAIntRegister(INT_UDMAERR , isr_dma_err); /* enable channel */ uDMAChannelEnable(UDMA_CHANNEL_UART0TX); uDMAChannelEnable(UDMA_CHANNEL_UART0RX); while(1); } /* function ends here */ void uart_configure_dma(void) { uint32_t ready_count; /* enable uart0 */ ready_count = 2000U; SysCtlPeripheralDisable(UART_PERIPH); SysCtlPeripheralReset(UART_PERIPH); SysCtlPeripheralEnable(UART_PERIPH); while( (!(SysCtlPeripheralReady(UART_PERIPH))) && (--ready_count)); if(0U == ready_count) /* if periph not ready take action */ { } /* diable uart */ UARTDisable(UART_BASE); /* enable gpioa */ ready_count = 2000U; SysCtlGPIOAHBEnable(UART_RX_PIN_PERIPH); SysCtlPeripheralEnable(UART_RX_PIN_PERIPH); while( (!(SysCtlPeripheralReady(UART_RX_PIN_PERIPH))) && (--ready_count)); if(0U == ready_count) /* if periph not ready take action */ { } GPIOPinConfigure(UART_RX_PIN_CONFIG); GPIOPinTypeUART(UART_RX_PIN_BASE, UART_RX_PIN); /* mix muxing */ ready_count = 2000U; SysCtlGPIOAHBEnable(UART_RX_PIN_PERIPH); SysCtlPeripheralEnable(UART_TX_PIN_PERIPH); while( (!(SysCtlPeripheralReady(UART_TX_PIN_PERIPH))) && (--ready_count)); if(0U == ready_count) /* if periph not ready take action */ { } GPIOPinConfigure(UART_TX_PIN_CONFIG); GPIOPinTypeUART(UART_TX_PIN_BASE, UART_TX_PIN); /* configure uart */ UARTClockSourceSet(UART_BASE , UART_CLOCK_SYSTEM); UARTConfigSetExpClk(UART_BASE, SysCtlClockGet(), 115200U, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE)); UARTFlowControlSet(UART_BASE , UART_FLOWCONTROL_NONE); /* disable all int, whatever enabled earlier */ UARTIntDisable(UART_BASE , UART_INT_9BIT | UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RT | UART_INT_TX | UART_INT_RX | UART_INT_DSR | UART_INT_DCD | UART_INT_CTS | UART_INT_RI); /* clear all int flags whatever set earlier */ UARTIntClear(UART_BASE , UART_INT_9BIT | UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RT | UART_INT_TX | UART_INT_RX | UART_INT_DSR | UART_INT_DCD | UART_INT_CTS | UART_INT_RI); /* register interrupts */ UARTIntRegister(UART_BASE , isr_uart_dma); /* enable required ints i.e overrun, break, parity & framing */ //UARTIntEnable(UART_BASE , UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RX); /* disable fifo */ UARTFIFODisable(UART_BASE); /* DMA */ UARTDMADisable(UART_BASE , UART_DMA_RX | UART_DMA_TX); UARTDMAEnable(UART_BASE , UART_DMA_RX | UART_DMA_TX); /* enable uart */ UART_ENABLE(); }
↧