SPI variable not updating issue while program runs on SDRAM and cache enabled

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPI variable not updating issue while program runs on SDRAM and cache enabled

1,137 Views
creatorwonny
Contributor III

Hi,

I added a function to set bits per frame like below and I had an issue the base->TCR value wasn't updated to tempTCR variable value. It didn't happen when program running on NOR flash, but happened only when program running on SDRAM. This issue also seems related to the cache (ICache or DCache). If the cache is disabled then base->TCR is always updated to the tempTCR value. Other workaround was to put __NOP() opcode like code below. Does someone have any idea about this issue?

By the way, LPSPI1_BASE seems address of external memory and I think it should have been declared with volatile, not only the macro but also parameter of the LPSPI functions from SPI driver. Is that okay? 

// MIMXRT1062.h
#define LPSPI1_BASE             (0x40394000u)
#define LPSPI1			((LPSPI_Type *)LPSPI1_BASE)

// freertos_lpspi_b2b_master.c
#define EXAMPLE_LPSPI_MASTER_BASEADDR (LPSPI1)

static void LPSPI_MasterSetBitsPerFrame(LPSPI_Type *base, uint32_t bitsPerFrame)
{
    /* Set Transmit Command Register*/
    uint32_t tempTCR = (base->TCR & (~LPSPI_TCR_FRAMESZ_MASK)) | LPSPI_TCR_FRAMESZ(bitsPerFrame - 1);
    base->TCR = tempTCR;

    /*TODO: Uncomment __NOP() to workaround an issue that base->TCR isn't updated to tempTCP*/
    //__NOP();

    if (base->TCR != tempTCR)
    {
        PRINTF("Error occurred in LPSPI set bit per frame. TCR=%x, Temp=%x, BitsPerFrame=%x\r\n",
                base->TCR, tempTCR, LPSPI_TCR_FRAMESZ(bitsPerFrame - 1));
    }
    else
    {
        PRINTF("Succeeded to set bit per frame for LPSPI. TCR=%x, Temp=%x, BitsPerFrame=%x\r\n",
                base->TCR, tempTCR, LPSPI_TCR_FRAMESZ(bitsPerFrame - 1));
    }
}

Information:

- Board: MIMXRT1060-EVK

- SDK: 2.6.2

- Example Project (from SDK): evkmimxrt1060_freertos_lpspi_b2b_master

 

Labels (1)
0 Kudos
4 Replies

1,126 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
It requires at least 3 LPSPI functional clock cycles for the
transmit command register to update after the transmit command register is written (assuming an empty FIFO) and the LPSPI must be enabled (Module Enable CR[MEN] bit is set).
So it's recommended to read the Transmit Command Register more than once and then compare the returned values.
Hope it helps.
Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,119 Views
creatorwonny
Contributor III

HI @jeremyzhou

Thanks for your reply. The reading TCR register right after updating the value is not a problem. I added if statement comparing values to check if the TCR value was updated to tempTCR because it hadn't been updated. the original codes only had first two lines without the if statement. LPSPI_CheckTransferArgument returned false becuase TCR wasn't updated as I set.

 

 

    uint32_t tempTCR = (base->TCR & (~LPSPI_TCR_FRAMESZ_MASK)) | LPSPI_TCR_FRAMESZ(bitsPerFrame - 1);
    base->TCR = tempTCR;

    /*TODO: Uncomment __NOP() to workaround an issue that base->TCR isn't updated to tempTCP*/
    //__NOP();

    if (base->TCR != tempTCR)
    {
        PRINTF("Error occurred in setting bit per frame for LPSPI. TCR=%x, Temp=%x, BitsPerFrame=%x\r\n",
                base->TCR, tempTCR, LPSPI_TCR_FRAMESZ(bitsPerFrame - 1));
    }
    else
    {
        PRINTF("Succeeded to set bit per frame for LPSPI. TCR=%x, Temp=%x, BitsPerFrame=%x\r\n",
                base->TCR, tempTCR, LPSPI_TCR_FRAMESZ(bitsPerFrame - 1));
    }

 

 

I hope this will help you understand the problem I have correctly.

0 Kudos

1,099 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thanks for your reply.
According to your testing conclusion, the TCR register is not updated successfully by executing the below code in QSPI flash unless either disable the cache feature or add a __NOP() opcode below.
In addition, it can update the TCR register successful when running the code on SDRAM, is my understanding correct?
Just a reminder, the TCR and TDR share the FIFO, so command Register writes will be tagged and cause the command register to update, after that entry reaches the top of the FIFO.
Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,090 Views
creatorwonny
Contributor III

Hi Jeremyzhou,

one thing needs to make sure. It can update the TCR register successfully when running the code on NOR Flash but unable to update the TCR register when running code on SDRAM with cache enabled. Anway, what is your recommendation. do we need to add a __NOP() alwayas behind updating TCR or TDR register?

Best Regards,

Wonny

0 Kudos