Hello, I'm running the TIVA dma_example (ping pong uart receive) and I want to know how many bytes were transfered when I receive the DMA interrupt. I need to know if it's a single or burst transfer, in order to process the DMA data buffers A and B.
In the TIVA dma code example interrupt handler:
//*****************************************************************************
//
// The interrupt handler for UART1. This interrupt will occur when a DMA
// transfer is complete using the UART1 uDMA channel. It will also be
// triggered if the peripheral signals an error. This interrupt handler will
// switch between receive ping-pong buffers A and B. It will also restart a TX
// uDMA transfer if the prior transfer is complete. This will keep the UART
// running continuously (looping TX data back to RX).
//
//*****************************************************************************
void
UART1IntHandler(void)
{
uint32_t ui32Status;
uint32_t ui32Mode;
//
// Read the interrupt status of the UART.
//
ui32Status = ROM_UARTIntStatus(UART1_BASE, 1);
//
// Clear any pending status, even though there should be none since no UART
// interrupts were enabled. If UART error interrupts were enabled, then
// those interrupts could occur here and should be handled. Since uDMA is
// used for both the RX and TX, then neither of those interrupts should be
// enabled.
//
ROM_UARTIntClear(UART1_BASE, ui32Status);
//
// Check the DMA control table to see if the ping-pong "A" transfer is
// complete. The "A" transfer uses receive buffer "A", and the primary
// control structure.
//
ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT);
//
// If the primary control structure indicates stop, that means the "A"
// receive buffer is done. The uDMA controller should still be receiving
// data into the "B" buffer.
//
if(ui32Mode == UDMA_MODE_STOP)
{
//
// Increment a counter to indicate data was received into buffer A. In
// a real application this would be used to signal the main thread that
// data was received so the main thread can process the data.
//
g_ui32RxBufACount++;
// I don't know if the data is single or burst...
//
// Set up the next transfer for the "A" buffer, using the primary
// control structure. When the ongoing receive into the "B" buffer is
// done, the uDMA controller will switch back to this one. This
// example re-uses buffer A, but a more sophisticated application could
// use a rotating set of buffers to increase the amount of time that
// the main thread has to process the data in the buffer before it is
// reused.
//
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART1_BASE + UART_O_DR),
g_ui8RxBufA, sizeof(g_ui8RxBufA));
}
//
// Check the DMA control table to see if the ping-pong "B" transfer is
// complete. The "B" transfer uses receive buffer "B", and the alternate
// control structure.
//
ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT);
//
// If the alternate control structure indicates stop, that means the "B"
// receive buffer is done. The uDMA controller should still be receiving
// data into the "A" buffer.
//
if(ui32Mode == UDMA_MODE_STOP)
{
//
// Increment a counter to indicate data was received into buffer A. In
// a real application this would be used to signal the main thread that
// data was received so the main thread can process the data.
//
g_ui32RxBufBCount++;
//
// Set up the next transfer for the "B" buffer, using the alternate
// control structure. When the ongoing receive into the "A" buffer is
// done, the uDMA controller will switch back to this one. This
// example re-uses buffer B, but a more sophisticated application could
// use a rotating set of buffers to increase the amount of time that
// the main thread has to process the data in the buffer before it is
// reused.
//
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART1_BASE + UART_O_DR),
g_ui8RxBufB, sizeof(g_ui8RxBufB));
}
//
// If the UART1 DMA TX channel is disabled, that means the TX DMA transfer
// is done.
//
if(!ROM_uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX))
{
//
// Start another DMA transfer to UART1 TX.
//
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, g_ui8TxBuf,
(void *)(UART1_BASE + UART_O_DR),
sizeof(g_ui8TxBuf));
//
// The uDMA TX channel must be re-enabled.
//
ROM_uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
}
}
On the datasheet:
Request Types
The μDMA controller responds to two types of requests from a peripheral: single or burst. Each
peripheral may support either or both types of requests. A single request means that the peripheral
is ready to transfer one item, while a burst request means that the peripheral is ready to transfer
multiple items.
The μDMA controller responds differently depending on whether the peripheral is making a single
request or a burst request. If both are asserted, and the μDMA channel has been set up for a burst
transfer, then the burst request takes precedence.
Datasheet page 708:
Note: In this example, it is not important if the peripheral makes a single request or a burst request. - but for me it's important!
Because the peripheral has a FIFO that triggers at a level of 8, the arbitration size is set to
8. If the peripheral does make a burst request, then 8 bytes are transferred, which is what
the FIFO can accommodate. If the peripheral makes a single request (if there is any data
in the FIFO), then one byte is transferred at a time. If it is important to the application that
transfers only be made in bursts, then the Channel Useburst SET[8] bit should be set in
the DMA Channel Useburst Set (DMAUSEBURSTSET) register.
I thought about pooling the XFERSIZE (transfer size) register, but it seems that it contains the outstanding items necessary to complete the DMA cycle (should be zero when the interrupt triggers). So it doesn't help me.
Thank you in advance.