TMS570LC4357: SD Card long term issues on TMDX570LC43HDK

Part Number: TMS570LC4357
Other Parts Discussed in Thread: TMDX570LC43HDK,

Hello all,

I am using mibSPI2 (connected to SD card) on the TMDX570LC43HDK. The project uses FatFS to manage filesystems and FreeRTOS OS.

The attached code (sd_card.txt) has all functions that touches the SD card (through mibSPI2). Initialization is done before FreeRTOS scheduler and any further operation is done by only one task. `sd_card_read_block` and `sd_card_write_block` are called by `disk_read` and `disk_write`, respectivaly, in diskio.c. Access to the peripheral is protected by a mutex.

I tested this code with 3 different cards:

  • 32GB Lexar SDHC - Card is initialized, configured and R/W operations works well for around 30 minutes, after a while writing a block times-out and any further operation fails;
  • 32GB SanDisk SDHC - Card is initialized and configured, R/W operations work but data written to disk does not match desired data (filesystem gets corrupted);
  • 1GB no brand SDSC - Works fine for more than 3 days.

After a long time trying to debug my code I noticed that configuring SPI with Polarity=0 and Phase=0 actually configures the peripheral as SPI mode 1 (data latched on falling edge, switched on rising edge). Am I correct in this assumption?

SD card defines that communication through SPI should be done using mode 0 (aka mibSPI configured with Phase=1). However even on the example provided at https://git.ti.com/cgit/hercules_examples/hercules_examples/tree/Application/TMS570LC43x_HDK_SDCard_mibspiDMA/source/HL_mibspi.c the peripheral is configured with Phase=0:

/** - Data Format 0 */
    mibspiREG2->FMT0 = (uint32)((uint32)0U << 24U)  /* wdelay */
                     | (uint32)((uint32)0U << 23U)  /* parity Polarity */
                     | (uint32)((uint32)0U << 22U)  /* parity enable */
                     | (uint32)((uint32)0U << 21U)  /* wait on enable */
                     | (uint32)((uint32)0U << 20U)  /* shift direction */
                     | (uint32)((uint32)0U << 17U)  /* clock polarity */
                     | (uint32)((uint32)0U << 16U)  /* clock phase */
                     | (uint32)((uint32)249U << 8U)  /* baudrate prescale */
                     | (uint32)((uint32)8U << 0U); /* data word length */

    /** - Data Format 1 */
    mibspiREG2->FMT1 = (uint32)((uint32)0U << 24U)  /* wdelay */
                     | (uint32)((uint32)0U << 23U)  /* parity Polarity */
                     | (uint32)((uint32)0U << 22U)  /* parity enable */
                     | (uint32)((uint32)0U << 21U)  /* wait on enable */
                     | (uint32)((uint32)0U << 20U)  /* shift direction */
                     | (uint32)((uint32)0U << 17U)  /* clock polarity */
                     | (uint32)((uint32)0U << 16U)  /* clock phase */
                     | (uint32)((uint32)249U << 8U)  /* baudrate prescale */
                     | (uint32)((uint32)8U << 0U); /* data word length */

Is the example from TI using the wrong SPI format or am I missing something else?
  • Hi Otavio,

    You are right, the SPI modes of this TMS570LC4357 Hercules controller are different from other devices.

    Here are the modes details of this device:

    So, the conclusion of the modes in the device are this:

    Mode CPOL CPHA Shifting Sampling
    0 0 0 Rising Falling
    1 0 1 Falling Rising
    2 1 0 Falling Rising
    3 1 1 Rising Faling

    I don't have Lexar datasheets to compare with its modes, however if i compare with wiki for example:

    Serial Peripheral Interface - Wikipedia

    As you can see those two are not directly matching. So, if your lexar modes are also as per this wiki page then you should need to do the following thing.

    For example, your device is as per Mode-0 of this Wiki then you should use Mode-1 in controller side. Similarly if your device is a per Mode-1 of this Wiki then you should use Mode-0 on controller SPI side.

    --
    Thanks & regards,
    Jagadish.

  • I would  suggest fixing the TI example from the git. SPI configuration in HL_mibspi.c from that example is also configured to SPI mode 1.

  • Hi Otavio,

    I would  suggest fixing the TI example from the git. SPI configuration in HL_mibspi.c from that example is also configured to SPI mode 1.

    I think this would not require because those are tested examples only, maybe they tested with different SD cards than what we are trying to use them.

    --
    Thanks & regards,
    Jagadish.

  • The issue is: it MIGHT work. As I said in my example, using SPI mode 1 worked fine for a small 1GB SDSC card, and worked for a while on another 32GB SDHC. Using this mode, the programmer will be at the mercy of how fast the card reads the data after CLK rising edge and how long the peripheral will take to swap the data, because host and card are expecting different clock edges to latch the data.

    The fact here is, the current example from TI will work for some cards, it might give you borderline positives for others (that just makes debugging much more complex). But, in the end, it's working OUTSIDE the SPI protocol for SD cards specification (this is not a per-card requirement, but rather defined by SD Association). 

  • Hi Otavio,

    Understood, we will consider this and verify thoroughly and modify our reference example accordingly.

    --
    Thanks & regards,
    Jagadish.