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.

TM4C129XNCZAD: Query regarding uDMA and SSI Interrupt

Part Number: TM4C129XNCZAD

I would like some clarification on the uDMA interaction with the TIVA SPI.  I am setting up a slave SPI interface on the TIVA processor and would like to use the uDMA in PingPong mode with the SPI.  

The SPI is configured as 16-bit wide element - SSI1 is used.  

The uDMA is configured in PingPong mode

uDMAChannelControlSet(10 | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_4);

// Set up transfer buffers
uDMAChannelTransferSet(10| UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(SSI1_BASE + SSI_O_DR), &g_dsp_spi_rx_buffer[PRIMARY_BUFFER], 128);

// Configure alternate transfer of ping-pong transfer
uDMAChannelControlSet(10 | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_4);

uDMAChannelTransferSet(10 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG,  (void *)(SSI1_BASE + SSI_O_DR), g_dsp_spi_rx_buffer[ALT_BUFFER],128);

While trying to get the DMA to work, I find that I need to enable the SPI RX DMA interrupt in order for the the DMA to work: SSIIntEnable(SSI1_BASE, SSI_DMARX).  In addition, in the interrupt handler for SSI1, I need to clear the SSI_DMARX interrupt mask in order for more packets to get DMA'ed.  This means that to receive a 128 element packet, the SSI ISR needs to run about 30 times else data is missed.  Isn't the whole point of using a DMA to avoid having an interrupt to service transfer?  I'm thinking I missed something in the datasheet and am hoping that someone can point me in the right direction.

Thank you

-Yan

  • Hi Yan,

    First of all the SSI's FIFO is only 8 entries deep. By design it generates a burst RX DMA request whenever half of the FIFO is full. The request is needed and used by the uDMA as a trigger to start the transfer. The SSI does not know how big the ping pong buffer is. As in your case, you have setup 128. Unless the SSI's FIFO is 256 entries deep in which case it can assert burst DMA request whenever there are 128 entries or more are available in the FIFO. Since this is not possible, it will need to generate the DMA request at 4 entries boundary. Upon receiving the request, the uDMA will start the transfer before the SSI's FIFO is full in which case you can run into overrun error situation.
  • Thanks for the reply Charles. So my understanding of the peripheral is correct then. Having an ISR to clear that interrupt status every 4 or 8 elements renders the uDMA not very useful. I ended just copying directly from the FIFO into a receive buffer as the performance was better than using the uDMA. In addition, clearing the uDMA RX is not a one step process as it requires clearing the SSIDMADisable(SSI1_BASE, SSI_DMA_RX), then clearing the interrupt status, then re-enabling the DMA.