CyU3PSpiTransmitWords bug (SDK library 1.34)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hi,

After we updated SDK version from 1.3.3 to 1.3.4, our SPI flash read code sometimes works incorrectly.

With FX3SDKVERSION="1_3_4" , I suspect that CyU3PSpiTransmitWords() has a bug: it may abort in the middle of transmission and return success.

The implementation is changed at 1.3.4 and it can be summarized as:

  1. Parameter check and setup.
  2. LOOP_A: For each words to be transmitted:
    1. Wait for FIFO empty status (TX_SPACE) with polling.
    2. Write a word to the register.
  3. Wait for transmit done interrupt bit (TX_DONE) with polling.
  4. Disable the TX.

Consider the following scenario:

  1. Preempted in the middle of the transmittion loop. (LOOP_A)
  2. Normally write from CPU is fast and consuming by SPI H/W block is slow, but in this case CPU write is stopped and only SPI block is active.
  3. It is possible that SPI block completes the transmission of all data in the FIFO and raises TX_DONE interrupt.
  4. CPU returns, write the rest data, and exits the loop.
  5. Wait for TX_DONE interrupt, but it is already asserted at (3.) timing for the first half of data. Exits immediately, mistakenly.
  6. Disable the TX. Transmission aborts and returns success.

Although I cannot fully confirmed yet, it seems that disabling interrupts is effective during the loop with CyU3PVicDisableAllInterrupts() - CyU3PVicEnableInterrupts() .

Could anyone review it?

0 Likes
1 Solution

Hi,

We have changed the CyU3PSpiTransmitWords() API so as to speed up the transmission but if it is creating issues then you can revert the change and use the old API which will wait for TX buffer to become empty in every iteration of the loop.

Thanks & Regards

Abhinav

View solution in original post

0 Likes
6 Replies
lock attach
Attachments are accessible only for community members.
abhinavg_21
Moderator
Moderator
Moderator
50 likes received 25 likes received 10 likes received

Hi,

Yes this scenario may happen, so here is the fix suggested (see the bold line)

for (i = 0; i < byteCount; i += wordLen)

    {

        /* Copy data to be written into local variable. The padding required is to nearest byte.

          Do fallthrough switch instead of using a loop.

        */

        temp = 0;

        switch (wordLen)

        {

            case 4:

                temp |= (data[i + 3] << 24);

            case 3:

                temp |= (data[i + 2] << 16);

            case 2:

                temp |= (data[i + 1] << 8);

            default:

                temp |= data;

                break;

        }

        /* Wait for the tx_space bit in status register */

        while ((SPI->lpp_spi_status & CY_U3P_LPP_SPI_TX_SPACE) == 0)

        {

            if (timeout-- == 0)

            {

                status = CY_U3P_ERROR_TIMEOUT;

                break;

            }

        }

        if (status != CY_U3P_SUCCESS)

        {

            break;

        }

        SPI->lpp_spi_egress_data = temp;

    }

    /* Wait for the transmit FIFO to become empty. */

    while ((SPI->lpp_spi_status & CY_U3P_LPP_SPI_TX_DONE) == 0)

    {

        if (timeout-- == 0)

        {

            status = CY_U3P_ERROR_TIMEOUT;

            break;

        }

    }

Instead of checking for TX_DONE interrupt now we are checking for TX_DONE status which will fix the issue. I am attaching the modified library please replace it with the old one in in the following path

C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\fw_lib\1_3_4\fx3_debug

Please make a copy of the old library before replacing.

Try and let me know if you are still facing the issue.

Thanks & Regards

Abhinav Garg

0 Likes
Anonymous
Not applicable

With the attached library, CyU3PSpiTransmitWords() always returns CY_U3P_ERROR_TIMEOUT.  I have already tried your idea and it did not work.  TX_DONE status bit is never asserted.  (or may be asstered only for one cycle, etc.)

The idea seems to be correct if the status bit is implemented as our expectation.  Is it possible to confirm the status bit spec and implementation with H/W team?

0 Likes
Anonymous
Not applicable

I have one more question.

CyBootProgrammer.img in SDK 1.4.4 uses this library and function?

0 Likes
lock attach
Attachments are accessible only for community members.

Hi,

Try with this new modified firmware library. In this library TX_Done interrupt bit is cleared blindly after writing the data in the egress register. Try to reproduce the issue with this modified library.

Thanks & Regards

Abhinav

0 Likes
Anonymous
Not applicable

I have already tried the same idea and it was effective.  The issue cannot be reproduced with attached library and our application.

However, the following senario can still be considered.

  1. (n - 1) words write loop
  2. The LAST write loop
    1. Clear TX_DONE interrupt bit.
    2. !!! CPU Interrupted at this timing.  (n - 1) words are transmitted and TX_DONE interrupt bit is asserted.
    3. Write the LAST word to the egress register.
  3. Wait for TX_DONE interrupt bit.  !!! break this loop mistakenly.

Is it possible to guarantee that all words will be transmitted correctly even in that case?

If not, this fix is not acceptable for production level.

0 Likes

Hi,

We have changed the CyU3PSpiTransmitWords() API so as to speed up the transmission but if it is creating issues then you can revert the change and use the old API which will wait for TX buffer to become empty in every iteration of the loop.

Thanks & Regards

Abhinav

0 Likes