I'm trying to make a circular buffer that reads the Rx data from UART0 and triggers a dma request that sticks the data in a buffer that I define. I'm getting confused on the function EDMA_DRV_Init. When I step through the function, it throws an exception when it try to write to the g_edma pointer. Attached is the source file that has the EDMA_DRV_Init in it.
Questions:
How do I use the EDMA_DRV_Init function
Also, is the DMA registers set up correctly in the DMAInit()?
uart_status_t DMAInit(uint32_t instance, uart_edma_state_t * uartEdmaStatePtr);
/* init the dma driver */
edma_state_t *edmaState; |
const edma_user_config_t edmaUserConfig = { | |||
.chnArbitration = kEDMAChnArbitrationRoundrobin, | |||
.notHaltOnError = true, | |||
}; |
//This is where it is currently failing!!
EDMA_DRV_Init(edmaState, &edmaUserConfig); |
uart_edma_state_t uartEdmaState;
DMAInit(0u, &uartEdmaState);
uart_status_t DMAInit(uint32_t instance, uart_edma_state_t * uartEdmaStatePtr) {
assert(uartEdmaStatePtr);
assert(instance < HW_UART_INSTANCE_COUNT);
dma_request_source_t uartTxEdmaRequest = kDmaRequestMux0Disable;
dma_request_source_t uartRxEdmaRequest = kDmaRequestMux0Disable;
uint32_t edmaBaseAddr;
uint32_t edmaChannel;
uint32_t baseAddr = g_uartBaseAddr[instance];
/* Clear the state structure for this instance. */
memset(uartEdmaStatePtr, 0, sizeof(uart_edma_state_t));
switch (instance)
{
case 0:
uartRxEdmaRequest = kDmaRequestMux0UART0Rx;
uartTxEdmaRequest = kDmaRequestMux0UART0Tx;
break;
case 1:
uartRxEdmaRequest = kDmaRequestMux0UART1Rx;
uartTxEdmaRequest = kDmaRequestMux0UART1Tx;
break;
default :
break;
}
/*--------------- Setup RX ------------------*/
/* Request DMA channels for RX FIFO. */
EDMA_DRV_RequestChannel(kEDMAAnyChannel, uartRxEdmaRequest,
&uartEdmaStatePtr->edmaUartRx);
// EDMA_DRV_InstallCallback(&uartEdmaStatePtr->edmaUartRx,
// UART_DRV_EdmaRxCallback, (void *)instance);
edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(uartEdmaStatePtr->edmaUartRx.channel);
edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(uartEdmaStatePtr->edmaUartRx.channel);
/* Setup destination */
EDMA_HAL_HTCDSetDestAddr(edmaBaseAddr, edmaChannel, (uint32_t)blueStreamDmaRxBuffer);
EDMA_HAL_HTCDSetDestOffset(edmaBaseAddr, edmaChannel, 1);
EDMA_HAL_HTCDSetDestLastAdjust(edmaBaseAddr, edmaChannel, 0);
/* Setup source */
EDMA_HAL_HTCDSetSrcAddr(edmaBaseAddr, edmaChannel, UART_HAL_GetDataRegAddr(baseAddr));
EDMA_HAL_HTCDSetSrcOffset(edmaBaseAddr, edmaChannel, 1);
EDMA_HAL_HTCDSetSrcLastAdjust(edmaBaseAddr, edmaChannel, 0);
/* Setup transfer properties */
EDMA_HAL_HTCDSetNbytes(edmaBaseAddr, edmaChannel, 1);
EDMA_HAL_HTCDSetChannelMinorLink(edmaBaseAddr, edmaChannel, 0, false);
EDMA_HAL_HTCDSetAttribute(edmaBaseAddr, edmaChannel, kEDMAModuloDisable, kEDMAModulo128bytes, kEDMATransferSize_1Bytes, kEDMATransferSize_1Bytes);
EDMA_HAL_HTCDSetScatterGatherCmd(edmaBaseAddr, edmaChannel, false);
EDMA_HAL_HTCDSetDisableDmaRequestAfterTCDDoneCmd(edmaBaseAddr, edmaChannel, false);
UART_HAL_SetRxDmaCmd(baseAddr, true);
return kStatus_UART_Success;
}
Original Attachment has been moved to: fsl_edma_driver.zip
Solved! Go to Solution.
Ok I have figured it out. I have attached a project that works and compiles. It uses UART0 with a 128Byte circular buffer. Hope it helps someone.
Thanks Matt. It is useful for me. However, when I configure my eDMA like your shared code. It doesn't work as a circular buffer as expected. Only about 88 bytes of the received buffer are used. Is it work well on your side?
B.R.
Jin Xin
Jin Xin,
The code worked for me when I wrote it yes. The think only thing i've changed since then is the alignment of the dmaRxBuffer. See Below.
volatile uint8_t dmaRxBuffer[RX_BUFF_SIZE] __attribute((aligned(128)));
Hi Matt,
Here is a sample code about init edma use KSDK : "Re: EDMA example code for ADC to buffer transfer using KSDK API calls? "( marcohess reply )
Hope it helps
Alice
Ok, I set up a DMA project to share. I'm using the K22 MCU with KDS.
I have the DMA set up to UART0 Receive and puts it into a global uint8_t buffer. When I receive something from UART0 the MCU goes to the default handler. So something is triggering. But not working. It sounds like the MCU is trying to write to an address that is not there or a peripheral that is not enabled.
The buffer I'm using as the destination for the DMA is declared as this: Maybe that is the issue? data alignment?
volatile uint8_t dmaRxBuffer[RX_BUFF_SIZE] ;