K22 DMA UART Circular Buffer

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K22 DMA UART Circular Buffer

Jump to solution
2,523 Views
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

Labels (1)
0 Kudos
1 Solution
1,009 Views
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.

View solution in original post

0 Kudos
5 Replies
1,010 Views
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 Kudos
1,009 Views
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 Kudos
1,009 Views
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 Kudos
1,009 Views
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 Kudos
1,009 Views
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 Kudos