This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

UART Rx with DMA Example..

Hi,

I have an application that uses a 3MBaud Serial input, and has a burst of 384 bytes per transfer.

I have not been successful getting a DMA / UART system working that will generate only 1 interrupt  for each block that is sent.

I am using Ping Pong Mode.   The data is sent out the WiFi port.

Does anyone have any sample code that i could look at to use?

Thanks!

  • Hi Craig,

    For DMA UART system you can refer to 'uart_dma' SDK example.

    'I have not been successful getting a DMA / UART system working that will generate only 1 interrupt  for each block that is sent.'


    Are you getting multiple DMA done interrupts on UART Tx ? Please note that you will have to mask the DMA request from UART once you get an interrupt and re-enable it after you setup the DMA for next block transfer

    Use MAP_UARTDMAEnable(UARTA0_BASE,UART_DMA_TX) and MAP_UARTDMADisable(UARTA0_BASE,UART_DMA_TX) APIs to enable and disable, respectively, the DMA requests from UART.

    This is because once DMA has transferred configured number of items it will disable the channel, but the UART TX FIFO will keep on requesting for more data as it gets emptied. In such a condition the DMA will continuously raise a DMA done interrupt.

    Let me know if this resolve your issue.

    Thanks and Regards,

    Praveen

  • I started with the UART DMA example. I can't seem to get it to work with just 1 interrupt.

    Also this is the Rx example, I don't need the Tx. I am getting multiple interrupts with the Rx example everytime the FIFO is emptied. So when I set the FIFO to a larger size, then I get less interrupts. Can't seem to figure out how to only get 1.

    -Thanks
  • Praveen,

    One of the problems is that if I leave the DMA incomplete, before I restart with the JTAG, I get an interrupt too early in as the DMA does not seem to be reset by the JTAG gel file. Not sure if there is a simple way to make sure any old DMA setups are flushed on the restart.

    Thanks,
  • Found two things:

    To get rid of the first interrupt that was from a prior execution, or using the UART without DMA prior, I did the following:
    1) Added the following line to the UART.C in the function just before the IntRegister command.
    UARTIntRegister(unsigned long ulBase, void (*pfnHandler)(void))

    // Clear any previous pending Interrupt (Added 1/12/2015).
    IntPendClear(ulInt);

    This clears any interrupt that is not maskable and already pending. The JTAG reload does not flush these it appears.

    2) Added the following at startup, again to make hot restarts with the JTAG work.
    // No Interrupt until we want it.. flush pending..
    MAP_UARTIntUnregister(UARTA1_BASE);
    MAP_UARTDMADisable(UARTA1_BASE,UART_DMA_RX);
    MAP_UARTIntClear(UARTA1_BASE,UART_INT_DMARX);

    To get the last interrupt from the DMA which I was missing, I changed the UDMA_IF.C
    3) In the SetupTransfer function, it has a MAP_uDMAChannelAttributeEnable call which uses the UDMA_ATTR_USEBURST setting.
    This is warned against in the user manual because you fail to get the interrupt from the DMA as the last piece of data can be lost in the FIFO.

    (Section 4.2.7.1 in SWRU367B)
    "If the FIFO peripheral's SETn bit is set in the DMA Channel Useburst Set (DMAUSEBURSTSET) register,
    then the uDMA will only perform transfers defined by the ARBSIZ bit field in the DMACHCTL register for
    better bus utilization. For peripherals that tend to transmit and receive in bursts, such as the UART, we
    recommend against the use of this configuration since it could cause the tail end of transmissions to stick
    in the FIFO."

    It works correctly if you change this to :
    MAP_uDMAChannelAttributeEnable(ulChannel, UDMA_ATTR_HIGH_PRIORITY);

    Thanks.
  • Hi Craig,

    Regarding JTAG your observation is correct, on JTAG connection only core is reset not the peripherals.

    To understand your problem better, when you do fresh run of your code from power off/hard reset, you only get one interrupt but for subsequent JTAG download and run without reset you get into problem of multiple interrupts. Right ?

    After adding above mentions steps does your system works as expected ?


    Thanks and Regards,
    Praveen
  • Praveen,

    That is correct. The initial Interrupt when I did a warm Reset and the lack of the final Interrupt because Burst mode was selected, made it difficult to get the expected results from the sample program. After these updates, I do get consistent results.

    -Craig
  • Hi,

    Thanks for confirming.

    I am closing this thread now. If you have follow up queries please open a new thread and add a link to this for reference.

    Best Regards,
    Praveen