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.

RM46L852: MibSPI in Slave Mode - Reading or writing SPI-RAM during transfer corrupts the data transferred

Part Number: RM46L852

Hi !

I'm trying to use the slave mode of the SPI controller (multi-buffer mode).

I observed a strange data corruption on the customer board and so I broke it down to a simple test with the LAUNCHPAD-XL2-RM46 development board.

To me, it seems the SPI only works correctly if you don't touch the SPI-RAM during the transfer.

Reading or writing even to an unused TG will lead to data corruption. It is usually observed in the form of

  1. insertion of one word, often 0x000F or 0x001F
  2. one missing word
  3. one word with wrong MSB, the other 15 bits are ok

You will find a demo project attached to this topic.

To test it, you need to connect SPI1 to SPI3 with 4 wires. I tamed down the speed to 11 MHz and added delays between CS and CLK so that you can use normal short arduino-style wires.

According to the manual, there is an arbitration between the CPU-Core and the SPI-Core to this RAM and the SPI-Core has priority so it should never break the transfer when you access the RAM.

For performance reasons, I want to read from a TG0 while a transfer with TG1 is running, if I ever get TG1 to work.

Most of the code is in sys_main.c and I also added a lot of comments to make it as easy and obvious as possible for you guys.

SPI1 is used as master and SPI3 is the slave. TG0 and TG1 are configured absolutely the same, but only TG0 is used for the transfer.

During the transfer, if you access TG1 data, the corruption occurs and most likely the slave will not complete the transfer because one or more words are missing.

If you turn it around and use TG1 for transferring (see MY_TG define), it won't work at all, even with no accesses during the transfer.

Any explanation? I can't find anything in the errata.

Reliable SPI transfers are absolutely crucial for this project. Corrupted data are unacceptable for safety applications.

Best regards,

 Manuel

https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/312/8865.spi_5F00_test_5F00_2020_2D00_10_2D00_20.7z

  • Hi Manuel,

    I am running your code, but I noticed that the data is not copied to TXRAM correctly.

    In slave mode, the MibSPI uses the chip-select pin (0~3) to trigger the transfer group. If CS0 is used, only TG0 will be triggered.

  • > I am running your code, but I noticed that the data is not copied to TXRAM correctly.

    What exactly are you referring to? The data is copied to TXRAM before the transfer even starts, using your API calls, and I think that works.

    Then, during the transfer I copy data to the other TG that is not involved in the transfer. This leads to the data from the SPI hardware line not being correctly copied to the RXRAM and the data from the TXRAM not being output correctly on the SPI hardware line.

    I didn't check, but it is quite possible that the data copied to the unused TXRAM is also not copied correctly. Is that what you are talking about?

    Or are you telling me I am doing something wrong in the code, then please correct me!

    >In slave mode, the MibSPI uses the chip-select pin (0~3) to trigger the transfer group. If CS0 is used, only TG0 will be triggered.

    Are you saying that in slave mode CS0 triggers TG0, CS1 triggers TG1, CS2 triggers TG2 and CS3 triggers TG3, and that is hardcoded and the CS-setting for each TG is ignored? There is nothing like that in the manual.

    Best regards,

    Manuel

  • Hello Manuel,

    1. I run the code on my RM46 launchpad, and produced the issue you reported. The CPU has the priority over the MibSPI when accessing to the buffers RAM.

    2. Please refer to "28.2.6.7 MibSPI Slave in Multi-buffer Configuration" of SPNU563A.

  • Hi!

    >1. I run the code on my RM46 launchpad, and produced the issue you reported. The CPU has the priority over the MibSPI when accessing to the buffers RAM.

    So what are you suggesting to do as a workaround? Never access the SPI-RAM during a transfer? The problem is that as a slave, you never know when a transfer starts, so this makes using more than 1 TG impossible.

    >2. Please refer to "28.2.6.7 MibSPI Slave in Multi-buffer Configuration" of SPNU563A.

    This is really interesting and explains a lot, thanks. I didn't have the idea of reading the TMS570LC43x manual when using a RM46x, I only ever looked in SPNU514C where there is no such chapter.

    But it also raises more questions. Does the whole chapter 28.2.6.7 apply to the RM46x ?

    I would never have expected such a CS "decoder" where you put the TG number as binary on the CS3..0 lines. As these signals are asynchronous, I am not sure how this can even work so that always the correct TG number is decoded. Does the SPI wait until the CS3..0 lines are stable for n VCLKs?

    I need to use the 3-Pin mode, so this chapter also explains why I can only get it to work with TG0.

    But this note is troubling me:

    NOTE: The maximum input frequency on the SPICLK pin when in slave mode is VCLK frequency /2.
    If the Slave is configured in either 3-pin or 4-pin (without SPIENA) modes, then, between end
    of last SPICLK and the start of SPICLK for next buffer, there should be at least 6 VCLK
    cycles of delay.

    Is the "end of last SPICLK" the last CLK edge that caused the sampling of the input?

    Is the "start of SPICLK for next buffer" the very next edge on CLK or the next sampling edge?

    In other words does this limit the SPICLK frequency to VCLK / 6 or VCLK / 12 (if you cannot add a delay between every n-th clock) ??

    Or does "there should be at least 6 VCLK cycles of delay" mean "additional" delay in addition to the minimum 1 VCLK ? (or 2 VCLK pedending on how to interpret start of SPICLK)

    Best regards,

    Manuel Köppen

  • Hello Manuel,

    1. I don't have any workaround so far.

    2. yes. this also applies to RM46 device. CS0 is used to trigger TG0, CS1 for TG1, and CS2 for TG2, etc. When 3-pin mode is used, only one transfer group can be triggered and it is restricted to Transfer Group 0 (TG0).

    3. "end of last clock" is the end of the last clock cycle. "start of SPICLK for next buffer" is the first edge of next clock cycle". 

    WDEL can be used to insert the delay between each transfer. The SPI master should insert at least 6 VCLK cycles before sending the clock to begin the transaction. My understanding is 6 cycles in total.

  • QJ Wang said:

    2. yes. this also applies to RM46 device. CS0 is used to trigger TG0, CS1 for TG1, and CS2 for TG2, etc. When 3-pin mode is used, only one transfer group can be triggered and it is restricted to Transfer Group 0 (TG0).

    A-ha so this is different from SPNU563A, no 4-to-16 "CS decoder" like  the TMS570LC43x  seems to have, but instead the CS0..CS3 directly select TG0..TG3. So TG4..15 cannot be used. Can you confirm that? I like that much more than a decoder because of the possible timing problems of such a decoder.

    QJ Wang said:

    3. "end of last clock" is the end of the last clock cycle. "start of SPICLK for next buffer" is the first edge of next clock cycle". 

    It's still no clear between which edges the "delay" is needed or better the minimum time must be followed. I can do this only by slowing down SCLK so what is the maximum SCLK frequency in relation to VCLK when SCLK is a simple 50/50 rectangular waveform without additional delays at certain points?

    In your picture, your arrow points to the "same" edge. In a longer transfer the last rising edge of the picture is the same edge as the first rising. Can you clearly mark 2 edges between which the CPU needs at least 6 VCLK total?

    The master is not a hercules CPU, I have no WDEL.

    Best regards,

    Manuel Köppen

  • Hi Mamuel,

    I want to correct #2 in my previous post.

    In MIBSPI Slave mode, the CS lines are used to specify which Transfer Group in the slave MIBSPI has to be used. To do so, depending on how many transfer group you want to use in your slave MIBSPI, 1 to 4 CS have to be used to trigger TG0 to TG14. (TG15 cannot be used in slave mode, see the table)

    If only 1 TG is necessary, CS0 has to be defined as functional pins, CS1, CS2 and CS3 as GIO. If more than 1 TG are used in an application, than the following table has to be used.

    I tested CS[2:0] and MibSPI slave:

    MibSPI1 CS[2:0] are connected to MibSPI3 CS[2:0]. MibSPI1 transfers data 4 transfer groups of MibSPI3, each TG has 16 buffers.

    CS3 CS2 CS1 CS0 (if all defined as functional)

       0       0       0      0        Trigger TG0
       0       0       0      1        Trigger TG1
       0       0       1      0        Trigger TG2
       0       0       1      1        Trigger TG3
       0       1       0      0        Trigger TG4
       0       1       0      1        Trigger TG5
       0       1       1      0        Trigger TG6
       0       1       1      1        Trigger TG7
       1       0       0      0        Trigger TG8
       1       0       0      1        Trigger TG9
       1       0       1      0        Trigger TG10
       1       0       1      1        Trigger TG11
       1       1       0      0        Trigger TG12
       1       1       0      1        Trigger TG13
       1       1       1      0        Trigger TG14
       1       1       1      1        No TG selected   (TG15 cannot be used)

  • Hi!

    That is a nice colorful explanation of how the "CS Decoder" works, although you didn't answer the question of how the 4 asynchronous CS lines are synchronized, that is for example within how may VCLK the CS must stabilize for a correct TG to be selected. Say for example CS0 becomes active just before the VCLK edge and CS1 just after, will TG3 be correctly selected? What if there are 2 VCLK edges between the CS0/CS1 edges?

    But this is not my main problem. It helps me to understand how the MibSpi works and why I wasn't able to get more than one TG working though.

    You didn't answer the main questions yet:

    How to avoid data corruption? (See my first post).

    And how fast can the SCLK really be? (See my last post).

    Best regards,

    Manuel

  • Hi Manuel,

    As stated in datasheet, the input SPI clock should be <= 25MHz and <= VCLK/2, where VCLK is the peripheral clock frequency in slave device. If the slave doesn't use SPIENA handshaking signal, at least 6 VCLKs delay should be inserted between two buffers transfer. The delay is between the subsequent rising edge (for clock mode 0) of last SPI clock to the first rising edge for next buffer transfer.

    I am sorry, I haven't found the workaround for data corruption caused by accessing TG while transferring data).

  • Hi!

    QJ Wang said:
    The delay is between the subsequent rising edge (for clock mode 0) of last SPI clock to the first rising edge for next buffer transfer.

    So when I cannot insert delays, I need at least 6 VCLK between two rising edges, that means SPI clock must be <VCLK/6.

    In my case, VCLK is 110 MHz, so my SPI needs to be below 18.3 MHz - I am currently using 16 MHz because 24 MHz did not work properly.

    Will this be added to the RM46X manual (spnu514c)? There is no mention of this limitation there, only in the TMS570LC43x manual (spnu563a) it is mentioned.

    QJ Wang said:
    I am sorry, I haven't found the workaround for data corruption caused by accessing TG while transferring data).

    So the only possibility to avoid data corruption is to not access any TG RAM while transferring data.

    Will this be added to the RM46X errata?

    Best regards,

    Manuel Köppen

  • Hello Manuel,

    We will add note to TRM. For data corruption issue, more test should be done before putting it to errata. Thanks Manuel!

  • Hi!

    It has been almost 4 weeks now since I last heard from you. Are you still working on it?

    To prevent auto-close of the topic, I'm asking again:

    Is my calculation correct (SPICLK with no delays must be <18.3 MHz for VCLK=110 MHz) and will this limitation be added to the manual?

    EDIT: I just read your last answer, it wasn't displayed properly. So thanks for adding it to the TRM. Just to confirm, the calculation is correct?

    Will the corruption problem be added to the errata? Did you find any workaround in the meantime?

    Data corruption is a serious problem and because the ONESHOT flag is not working either, it's not even easy to securely prevent an access to the TG RAM while a transfer is running.

    Best regards,

     Manuel Köppen

  • Dodging the auto-close again...

    QJ Wang said:
    I will check

    Any update on when you will check?

    Best regards,

    Manuel

  • Hi Manuel,

    I am sorry I haven't got chance to do more investigation. Will do it.