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.

SSI0 with DMA: trying to use Rx Timeout

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.

  • Hello Bob,

    Let me take this line to say thanks on a very well written post with a lot of background to the issue and research.

    Simply put, Yes, if the Rx Timeout occurs the SSI Interrupt Handler will be fired if the interrupt source is unmasked. The same applies for Rx Overrun as well. The CPU has to check for the RX Timeout Interrupt besides checking if the DMACHIS bit is set or not to distinguish between a successful complete of uDMA or corrupted data in SRAM due to Rx Timeout or Rx Overrun.

    Regards

    Amit

  • In our system, we send 34 byte packets every 5 ms.  Each packet is transferred in about 200 us.  Is it wrong-headed of me to think that the Rx Timeout, if properly configured, should cause a Rx timeout after each one of these packets?   It works this way in the non-DMA interrupt mode but not when I try it with the DMA scheme.   I've put the code in my interrupt handler to look for the Rx timeout bit and tried both the masked and raw status registers with no luck.  I must be doing something wrong.  Do you have any example code that might illuminate my mistake?

  • Hello Bob,

    We do have some example code of how to configure the uDMA, it’s interfacing with the UART instead of the SSI. If you download the SW-TM4C-2.1.0.12573 software support package in the default location you will be able to find the example at  C:\TI\TivaWare_C_Series-2.1.0.12573\examples\boards\dk-tm4c123g\udma_demo.

    At the moment im not to sure if the RX timeout can trigger an uDMA transfer.

    Regards

    -Jason

  • Hello Bob,

    The Receive Timeout is based on the RXFIFO. If the RXFIFO is not empty for 32 SSIClk cycles the RX Timeout interrupt will be asserted.

    The SSI does not know the packet size, so from the SSI perspective even 1 byte in the RX FIFO could be a packet. I would be more concerned that in a loaded system, the RXFIFO overrun interrupt bit may be getting set.

    The uDMA has very limited example code. If possible, can you send the following data

    1. System Clock Frequency

    2. SSI Peripheral Configuration

    3. uDMA configuration for SSI and the interrupt handler.

    We can try checking the same.

    Regards

    Amit

  • You two are far, "out of this reporter's league" this uDMA -> SSI subject.  And - as Amit well noted - simply terrific forum composition.  (Amit's quite good - as well)

    So - minus real knowledge - I'm reduced to, "imagination."  Might either of these 2 (admitted) SWAGs stand a chance?

    a) we know that SSI w/in Slave Mode suffers substantial speed reduction.  Thus - might a faster MCU enable your success w/your interrupt-driven method?   This vendor has such faster MCU.

    b) as your packets are consistent (that's crucial) might you be able to route either SSI_CLK or SSI_FS (which may be a simple gpio) to a, "Timer/Counter" pin - programmed to count to the "end" of your packet?  Upon that event - a timer/counter interrupt could be triggered - and your packet then checked/processed...

    Indirection sometimes succeeds - or blunders into a more fertile path...

  • Thanks for the suggestions but the hardware is non-negotiable at this point in our project.  Since yesterday, we may have come up with a solution.  It's not particularly elegant, but it just may work.  

    We needed a way to detect the end of our packet but just couldn't make the Rx Timeout feature of the FIFO work for this when using the DMA.  Our solution is to use the Systick interrupt to give us a 1 to 2 ms delay after a corrupted packet is detected.  After this delay we simply disable the DMA, reconfigure it just like at Init time, and then re-enable it.  First testing has shown that we recover on the next packet (no consecutive bad packets) which is a crucial point.

    As I said, this isn't very elegant but given our time and hardware constraints it may just work for us.  Truly, I'd like a better solution so I'm still interested, if only for the next project that comes along.

  • Hello Bob,

    If you could send the data I have asked for in the earlier post, we would be able to evaluate a better solution in the "time" you have.

    In the past we have used the forum as an effective mean of working around any known errata on SSI where the user already has the board done and cannot re-do the hardware, but it all depends on the user sending the necessary data.

    Regards

    Amit