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.

LP-AM243: MCSPI_RX register not updating in time with the next element in FIFO after MCSPI_readRxDataReg() call.

Part Number: LP-AM243

Hello, 

I am trying to read multiple 16bit words over SPI from an external ADC.
I can see the frames I need on a logic analyzer but when I read the MCSPI_RX register I keep getting just the first word multiple times instead of the remaining elements in the RX FIFO.

              

This is my code:

/* SPIEN line is forced to low state.*/
MCSPI_writeChConfReg(baseAddr, chNum, gCsAssertRegVal);

while(transferLength!=0)
{
/* Write Effective RX FIFO depth */
if (transferLength >= effRxFifoDepth)
{
transferLength = effRxFifoDepth;
}

while (0 == (MCSPI_readChStatusReg(baseAddr, chNum) &
CSL_MCSPI_CH0STAT_TXFFE_MASK))
{
/* Wait for Tx FIFO to be empty before writing the data. */
}

/*Loops for retrieving the multiple SPI words*/
for(uint8_t i=0;i<transferLength;i++) //transferLength for this example is 2 (bytes)
{
MCSPI_writeTxDataReg(baseAddr, 0x00000000, chNum); //writing dummy TX data
}

for(uint8_t i=0;i<transferLength;i++)
{
rxBuff[i]=(uint16_t)MCSPI_readRxDataReg(baseAddr, chNum); //rxBuff points to Rxbuffer_16
if(en_Chn_Seq_Idx[i]!=0xAA) //writing relevant data into shared memory
{
shmem.ADC_Buff[en_Chn_Seq_Idx[i]][db_idx][curr_dbuf_dpt]=rxBuff[i]; //write data into shm.mem double buffer
}
}
numWordsRead += transferLength;
transferLength = length - numWordsRead;
}

while (0 == (MCSPI_readChStatusReg(baseAddr, chNum) &
CSL_MCSPI_CH0STAT_TXFFE_MASK))
{
//Wait for Tx FIFO to be empty for the last set of data.
}

while (0 == (MCSPI_readChStatusReg(baseAddr, chNum) &
CSL_MCSPI_CH0STAT_EOT_MASK))
{
/* wait for the end of transfer of last word.*/
}

/* Force SPIEN line to the inactive state.*/
MCSPI_writeChConfReg(baseAddr, chNum, gCsDeAssertRegVal);

I used the mcspi performance 32bit example code as a reference for my code.

And the configuration I am using is :

I also noticed that when I go through the code line by line in debug mode, I see the MCSPI_RX register getting updated as it should after each MCSPI_readRxDataReg() function call.
So, I assumed I might not be giving enough time for the MCSPI_RX buffer to be updated with the next element from the FIFO after reading it.

So I tried the below code:

for(uint8_t i=0;i<transferLength;i++)
{
MCSPI_writeTxDataReg(baseAddr, 0x00000000, chNum);
while(0 == (MCSPI_readChStatusReg(baseAddr, chNum) &
CSL_MCSPI_CH1STAT_RXS_FULL))
{
/*wait till element is read into the fifo*/
}
rxBuff[i]=(uint16_t)MCSPI_readRxDataReg(baseAddr, chNum);
if(en_Chn_Seq_Idx[i]!=0xAA) //writing relevant data into shared memory
{
shmem.ADC_Buff[en_Chn_Seq_Idx[i]][db_idx][curr_dbuf_dpt]=rxBuff[i]; //write data into shm.mem double buffer
}
}

The difference being, Instead of reading the MCSPI_RX register in a loop, I wait for RXS bit of the MCSPI Status register to be FULL before reading the MCSPI_RX register for the next word.

This seems to work, but it introduces additional delay between two words which is undesirable.

Is there anyway to read MCSPI_RX register without having to wait for any status bits?
Am I approaching this issue the right way? 

Thanks and Regards.

  • Hi Bhrarth,

    I assume your ADC input should be connected to the D1 pin of the McSPI. However, your "Input Select" was set to D0 (which is set for the loopback mode). You will need to change it to D1 for normal McSPI operation.

    Best regards,

    Ming

  • Hi Ming,

    No, the input from the ADC to the controller is on D0 (SPI0) , while the MOSI is D1 in this case.
    As you can see the 'D0 Tx Enable' is disabled for this configuration, so it shouldn't be in loopback mode.

    It shouldn't matter which pin is selected as input as long as it is configured as 'Input Select' and the other pin (output) is configured as 'Tx enabled' in Sysconf, right? 

    With regards,

    Bharath

  • Hi Bharath,

    Not according to the following paragraph in TRM:

    When Full-duplex mode is used, it has to be D0 for TX and D1 for RX.

    Best regards,

    Ming

  • Hello Ming, 

    I tried it with D1 for RX and D0 for TX
    The MCSPI_RX register read function MCSPI_readRxDataReg() still gives the "non updated" value when reading in real time using a for loop.
    i.e two consecutive reads from the MCSPI_RX register in a for loop gives the same value.

    But when I try reading the MCSPI_RX Register during debug mode (traversing line by line), I am able to read the next word perfectly. i.e I believe when there is sufficient delay between two reads of MCSPI_RX register, the subsequent value in the FIFO is being shifted into the MCSPI_RX register properly.

    So the behavior is same as before. 

    With Regards,

    Bharath Kartha 

  • Hi Bharath,

    Apparently, the MCSPI_RX register needs time to be filled in. If you do not want to keep on checking the RXS bit of the MCSPI Status register, you can use Callback (instead of Blocking) for Transfer Mode. It will call your designated callback function, when the transfer is completed.

    Best regards,

    Ming