I am using SSI0 on our TM4C123 in Slave mode with uDMA. When the system gets loaded, heavy CPU to RAM activity specifically, it becomes evident that the DMA transfers are not happening in time and the transfer is corrupted. We are trying to receive a packet of 34 bytes from an external Master SPI so there is no flow control to slow it down and we overrun our SSI0 Rx FIFO. Since our DMA transfer is set to complete after 34 bytes are received, any missing data in the current packet gets replaced with data from the next packet. Obviously, this isn’t what we want. When a bad packet is received (CRC check always detects this) then I’d like to be able to resync the DMA receive with the end of the packet so the DMA is enabled and ready on the first byte of the next packet. My need is to resync as soon as possible to minimize the loss of packets. In our system, we cannot suffer the loss of more than 3 packets in a row or we declare a fault in our system.
Before trying the DMA, I used interrupt driven mode. Unfortunately, we could not meet the hard real time deadline for keeping up with the Rx buffer so we went with the DMA. However, in the interrupt driven scheme without the DMA, I found that I could resync with the packets because the Rx Timeout interrupt would indicate the end of the packet. I’ve tried to enable this in my DMA scheme but it doesn’t seem to work. Does anyone know if this is possible? The Rev E datasheet for the TM4CBH6ZRB micro, section 9.2.10, says in the last line of the second paragraph:
Unmasked peripheral error interrupts continue to be sent to the interrupt controller.
This would seem to indicate the Rx timeout interrupt could be used to detect the end of a packet and resync the DMA transfers after a bad packet is received.
if using the Rx Timeout interrupt isn't an option for detecting the end of a packet, does anyone have an idea how we might do this without sitting in a tight loop watching some register bit? Our 34 byte packets are about 184 us and we can't sit in an interrupt handler for that long holding everything else off.