K22 DMA UART Circular Buffer

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

K22 DMA UART Circular Buffer

跳至解决方案
2,626 次查看
guitardenver
Contributor IV

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

标签 (1)
0 项奖励
1 解答
1,112 次查看
guitardenver
Contributor IV

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.

在原帖中查看解决方案

0 项奖励
5 回复数
1,113 次查看
guitardenver
Contributor IV

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.

0 项奖励
1,112 次查看
jinxin_cn
Contributor I

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

0 项奖励
1,112 次查看
guitardenver
Contributor IV

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)));

0 项奖励
1,112 次查看
Alice_Yang
NXP TechSupport
NXP TechSupport

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? "(

0 项奖励
1,112 次查看
guitardenver
Contributor IV

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] ;

0 项奖励