XMC4700. USIC.SSC over DMA - underflow of RX

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Hi!

I am using USIC in SSC-mode over DMA.
word size: 8bit;
mode: singe-SPI in master-mode;
I program two DMA channels (receive and transmit) for service of SPI. DMA works with the burst size: BURST_SPI == 4 (GPDMA_CH.CTLL.MSIZE == BURST_SPI).
USIC.SSC FIFO size == 16.
RBCTR.LIMIT = BURST_SPI-1; RBCTR.SRBTM == 0; RBCTR.SRBTEN == 0; RBCTR.RNM == 0; RBCTR.LOF == 1; RBCTR.SRBIEN == 1; RBCTR.RBERIEN == 1.
TBCTR.LIMIT = BURST_SPI; TBCTR.STBTM == 0; TBCTR.STBTEN == 0; TBCTR.LOF == 0; TBCTR.STBIEN == 1; TBCTR.TBERIEN == 1.
I set the priority of the DMA.TX-channel to be lower than the priority DMA.RX-channel (GPDMA_CH.CFGL.CH_PRIOR).
I enabled interrupt from RX-DMA-channel (GPDMA.MASK.TFR) after completing transfer entire block.

I pass a 16-bytes block to the SPI.
If SCLK SPI was <= SYSTEM_CLK/4 - all ok - I received single interrupt, no troubles, all data transmitted/received correctly.
If SCLK SPI was == SYSTEM_CLK/2 - in this case, I get the error state "reading an empty receive buffer" (USIC.TRBSR.RBERI == 1). And I recives invalid data (duplicated bytes).
Trying to correct this error, I reduce the value: TBCTR.LIMIT = 1. This underflow error now occurs less often, but it still happens (not with a block size of 16 bytes, but starting with about ~ 1024 bytes and bigger).
I think the scenario for occuring the error is (for TBCTR.LIMIT = 1):
TX.FIFO RX.FIFO
0 0 ;DMA.TX writes BURST_SPI bytes to TX.FIFO (1-st burst)
4 0
3 0 ;TX.FIFO -> TX.SHIFT register (1-st byte)
3 1 ;was transmitted/received last bit of 1-st byte
2 1 ;TX.FIFO -> TX.SHIFT register (2-nd byte)
2 2 ;was transmitted/received last bit of 2-nd byte
1 2 ;TX.FIFO -> TX.SHIFT register (3-rd byte)
1 3 ;was transmitted/received last bit of 3-rd byte
0 3 ;TX.FIFO -> TX.SHIFT register (4-th byte); DMA.TX event -> DMA.TX writes new BURST_SPI bytes to TX.FIFO (2-nd burst)
4 3
4 4 ;was transmitted/received last bit of 4-th byte;
At this point, the event DMA.RX is generated and DMA.RX-channel starts reading BURST_SPI bytes from RX.FIFO. At the same time, the reception from the MISO is continues.
And, when the first byte from the RX.FIFO was read, the trigger of DMA.RX-event is cleared.
If at that moment was received the new byte to the RX.FIFO is finished, is a new DMA-event is generated (although the RX.FIFO still has too few bytes for the 2-nd burst (FIFO contains only BURST_SPI + 1 bytes)).
Then - the reading from RX.FIFO of 1-st burst is finishes and begins reads the 2-nd burst (according to the second RX.DMA-event). Although data for the second burst is not sufficient.
At this point, an underflow occurs.

How to solve this problem?
I want to start the transfer of the data block once and at the end of the transmission of the whole block get a single interrupt about the completion of the entire transmission.
Maybe I did not consider something or incorrectly programmed the configuration of the USIC.SSC or GPDMA?
Thank you in advance for your help.
0 Likes
0 Replies