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.

TM4C129ENCPDT: uDMA with SSI seems to corrupt one bit of each 32-bit word on transmit

Part Number: TM4C129ENCPDT

My application is communicating with a SPI Flash Memory chip. I have code working flawlessly when directly accessing the SSI peripheral in a tight, optimized loop. I have attempted to improve performance by changing the data transfer from direct SSI access to uDMA. I've kept the Flash Memory command byte and address bytes (usually 4-Byte address) in direct SSI access, so that only the longer Flash data transfer is handled by uDMA.

I have the uDMA Channel Control set to UDMA_SIZE_8 | UDMA_ARB_4 for efficiency. Channel Transfer is UDMA_MODE_PING_PONG. Channel Attribute has UDMA_ATTR_USEBURST set, and I believe that I am careful to wait for the SSI Busy to be de-asserted and then only program the uDMA size to a multiple of 4 bytes.

The symptom is that my data is being transmitted almost exactly correctly, but at a random point in the transfer a single bit error begins to occur. About 22 bytes in, or in the 5th 32-bit word, it's as if 0x00004000 is being OR'd into my data stream. This bit error is word aligned, not byte aligned, so I first suspect the uDMA setup since the SSI is operating with 8-bit word size. I tried briefly turning off USEBURST, but that seemed to make things worse.

Note that I have Flash Memory read working under most conditions, but it sometimes gets shifted by a single 32-bit word - all the correct data appears, but one word too late in the transfer. This particular bug report, as described above, is happening during Flash Memory write operations. I have confirmed with a logic analyzer that the data is corrupted on the wire when it's written to the external Flash Memory chip. So, when I read back corrupted data, it does match what was actually sent on the wire.

Other than looking for general help, based on the above issues, I'm also wondering whether there is some way to flush or reset the uDMA peripheral that I'm missing. This seems to be particularly important since accessing external SPI Flash Memory involves a mix of single-byte commands, address bytes, and hopefully larger uDMA buffer transfers.

  • Hello Brian,

    This looks to be a duplicate thread of e2e.ti.com/.../738554

    We will reply to that newer thread today and close this one out.
  • It's a very different error (incorrect data rather than correct data at the wrong position), and happens under different conditions, and occurs at a random offset rather than a predictable offset. However, if you can solve both problems with one answer, then I'll mark this one as solved.
  • Hello Brian,

    I see, the bulk of your posts were identical so it wasn't easy for me to understand the issues were completely unrelated. We've many times seen duplicate posts where the second just has an 'edit' done to it, and this one appeared that way, sorry I didn't notice the differences.

    I can work both threads separately, but for this one I need to look into it further before commenting.

    One quick thing to check on your end in the meantime is can you make sure there is no stack overflow occurring? Sometimes data corruption can occur due to that. I doubt you'd have such an issue knowing how thorough you are via our past correspondence but it would be good to verify that is not occurring.
  • Hello Brian,

    Are you using Deep Sleep Mode for your application at all?
  • Ralph Jacobi said:
    One quick thing to check on your end in the meantime is can you make sure there is no stack overflow occurring? Sometimes data corruption can occur due to that. I doubt you'd have such an issue knowing how thorough you are via our past correspondence but it would be good to verify that is not occurring.

    I have the linker allocating 2 KB for stack, and it seems that my firmware is using less than 500 bytes.

    (I modified my 1 ms tick interrupt to track the minimum and maximum SP value. If there is an easier tool to track stack using, please point me in the right direction.)

    p.s. No Sleep Mode usage at all, Deep or other.

  • Hello Brian,

    I have a more scientific method which uses CCS Memory Browser. The steps below I am going to post were done on an MSP430 but the same is achievable with TM4C.

    For TM4C look for the stack location in .map to look like this:

    To test for Stack Overflow, the following steps should be done:

    1. Identify the starting memory location of the Stack in the .map file inside of the Debug folder

    2. Enter debug mode but do not start to run code
    3. Go to “View" -> “Memory Browser”
    4. Enter the address of the stack into the input box
      1. In my example above, that address is 0x0000420c (you need to add the 0x to the front of it!)

    5. This will show you the stack contents
    6. Next, fill the stack contents with known data:
      1. Go to “Tools” -> “Fill Memory”
      2. Input Start Address = Stack Address from .map file
      3. Length = Stack size/2 (In my example this is 500, so 500/2 = 250) – this is because each memory location stores 2 bytes of the Stack
      4. Data Value = 0xAA (or 0x55, or something else that is easily identifiable)

    7. The Memory Browser should now look like:

    8. Since the stack has been overwritten entirely, it is import to restore the initial stack settings before running the code. This can be done by one of two ways:
      1. Use “Soft Reset”
      2. Exit Debug mode and re-enter debug mode
        1. I had to do this for some projects, but usually Soft Reset works
      3. When done correctly, the memory Browser should have non 0xAA bytes at either the top or bottom of the Stack:

    9. Now run the code for a sufficient amount of time based on application
      1. If an overflow occurs, all inputted data (0xAA in my example) would no longer be in the stack

  • Thanks for the scientific method. Your technique confirms that only 480 stack bytes are used out of 2048. My previous technique showed 495 bytes or so, which shows that both methods correlate.

  • Not much progress has been offered for either of these bugs, so I don't want to leave the impression that this one has been resolved in any way.