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.

AM2431: MCSPI can't send zero data

Part Number: AM2431


Hi all TI experts,

I attempted to use MCSPI to read and write to a flash peripheral, but I encountered an issue. When I need to read or write to address 0x000000 of this flash, I first send a read command. Using the Logic Analyzer (LA), I can see that the command is correctly issued. However, when I subsequently send the address 0x00 0x00 0x00, I notice that the MCSPI does not respond at all.

Here is the part where I initialize the MCSPI:

uint32_t    chCtrlRegVal, chConfRegVal;

    panel_flash_chNum = gConfigMcspi0ChCfg[0U].chNum;
    panel_flash_baseAddr = MCSPI_getBaseAddr(gMcspiHandle[CONFIG_MCSPI0]);

    dataWidth  = 8;
    MCSPI_setDataWidth(panel_flash_baseAddr, panel_flash_chNum, dataWidth);

    MCSPI_enableTxFIFO(panel_flash_baseAddr, panel_flash_chNum, MCSPI_TX_FIFO_ENABLE);
    MCSPI_enableRxFIFO(panel_flash_baseAddr, panel_flash_chNum, MCSPI_RX_FIFO_ENABLE);

    chCtrlRegVal     = MCSPI_readChCtrlReg(panel_flash_baseAddr, panel_flash_chNum);
    gChEnableRegVal  = chCtrlRegVal | CSL_MCSPI_CH0CTRL_EN_MASK;
    gChDisableRegVal = chCtrlRegVal & (~CSL_MCSPI_CH0CTRL_EN_MASK);

    chConfRegVal      = MCSPI_readChConf(panel_flash_baseAddr, panel_flash_chNum);
    gCsAssertRegVal   = chConfRegVal | CSL_MCSPI_CH0CONF_FORCE_MASK;
    gCsDeAssertRegVal = chConfRegVal & (~CSL_MCSPI_CH0CONF_FORCE_MASK);

    bitRate    = gConfigMcspi0ChCfg[0U].bitRate;

Here is the part where MCSPI sends bytes:

uint8_t ret = 0;

    vTaskDelay(1);
    for(int i=0;i<len;i++)
    {
        if(0 != (MCSPI_readChStatusReg(panel_flash_baseAddr, panel_flash_chNum) & CSL_MCSPI_CH0STAT_TXFFE_MASK))
        {
            MCSPI_writeTxDataReg(panel_flash_baseAddr, (uint8_t) (*data+i), panel_flash_chNum);
            vTaskDelay(1);
            if(0 != (MCSPI_readChStatusReg(panel_flash_baseAddr, panel_flash_chNum) & CSL_MCSPI_CH0STAT_TXFFE_MASK))
            {
                ret = 1;
            }
            else
            {
                ret = 0;
            }
        }
        else
        {
            ret = 0;
            break;
        }
        vTaskDelay(1);
    }

    return ret;

Here is the part where MCSPI receive bytes:

uint8_t ret = 0;

    vTaskDelay(1);
    for(int i=0;i<len;i++)
    {
        MCSPI_writeTxDataReg(panel_flash_baseAddr, 0x00, panel_flash_chNum);
        if(0 != (MCSPI_readChStatusReg(panel_flash_baseAddr, panel_flash_chNum) & CSL_MCSPI_CH1STAT_RXS_FULL)){
            data[i] = MCSPI_readRxDataReg(panel_flash_baseAddr, panel_flash_chNum);
            ret = 1;
        }
        else{
            ret = 0;
            break;
        }
        vTaskDelay(1);
    }
    return ret;

Could you please let me know if there is any mistake on my part that caused this issue?

Best,

Larry

  • Hi Larry,

    Thanks for your question.

    Allow me sometime to provide you a response on your query.

    Regards,

    Vaibhav

  • Hi Larry,

    I am yet to go through your code to understand your flow, but just based on your initial explanation, I have few comments I would like to put out.

    I attempted to use MCSPI to read and write to a flash peripheral, but I encountered an issue. When I need to read or write to address 0x000000 of this flash, I first send a read command. Using the Logic Analyzer (LA), I can see that the command is correctly issued. However, when I subsequently send the address 0x00 0x00 0x00, I notice that the MCSPI does not respond at all.

    As far as I know, since the CS is already connected so we do not need to worry about the slave address, and that being said, if we want to read from a particular register from the Peripheral, we firstly need to set an internal pointer to that register, so the flow should be as follows:

    1. Set an internal pointer to the register(lets say register 0x1), so we do a dummy write, by sending this in the TX Buffer.
    2. Now we simply say, that we need to receive lets say 2 consecutive bytes, so we set read count to 2 and RX Buffer initialized to 0.
    3. Post this you can read the values.

    Should I give you a working code for the same ?

    If yes, then I would need to know which register you want to access? And how many values you want to read from that particular register?

    Looking forward to your response.

    Regards,

    Vaibhav

  • Hi Vaibhav,

    Thanks for your replay, 

    Let me provide more details. When controlling the flash peripheral, you need to issue an action command first, followed by the address to be operated on (which requires three bytes). Finally, based on whether you want to read or write data, for example, if you want to write the data 0x1234 to the address 0x000000, you need to send the following content:

    0x02 0x00 0x00 0x00 0x12 0x34. The first 0x02 is the program data command, followed by the three 0x00 bytes which represent the address you want to write to, and finally, 0x12 0x34 is the data you want to write.

    I found that with my current procedure, when attempting to send the address 0x00 0x00 0x00, there is no activity on the SPI bus. Theoretically, SCLK should be signaling, and MOSI should be completely low, but I see nothing on the LA (logic analyzer).

    Then, for reading data, if I want to read 16 bytes starting from the address 0x000000, the SPI output should be 0x03 0x00 0x00 0x00, followed by reading 16 bytes of data. However, just like with the write operation, the three bytes 0x00 0x00 0x00 are not being output on the SPI bus at all.

    If possible, could you please provide me with runnable code based on the two scenarios I described above so that I can test it? By the way, it seems that I have no issues with the SPI initialization, right?

    Best,

    Larry

  • Hi Larry,

    Let me provide more details. When controlling the flash peripheral, you need to issue an action command first, followed by the address to be operated on (which requires three bytes). Finally, based on whether you want to read or write data, for example, if you want to write the data 0x1234 to the address 0x000000, you need to send the following content:

    0x02 0x00 0x00 0x00 0x12 0x34. The first 0x02 is the program data command, followed by the three 0x00 bytes which represent the address you want to write to, and finally, 0x12 0x34 is the data you want to write.

    Allow me sometime to go through your response.

    Please expect me to follow up within few business days.

    Regards,

    Vaibhav

  • Hi Vaibhav,

    Have any update?

    Best,

    Larry

  • Hi Larry,

    I am going to write a sample application based out of an MCU PLUS SDK example MCSPI Loopback.

    gMcspiTxBuffer[0] = 0x2;

    /* Initiate transfer */
    MCSPI_Transaction_init(&spiTransaction);
    spiTransaction.channel = gConfigMcspi0ChCfg[0].chNum;
    spiTransaction.dataSize = 8;
    spiTransaction.csDisable = TRUE;
    spiTransaction.count = 1;
    spiTransaction.txBuf = (void *)gMcspiTxBuffer;
    spiTransaction.rxBuf = NULL;
    spiTransaction.args = NULL;

    transferOK = MCSPI_transfer(gMcspiHandle[CONFIG_MCSPI0], &spiTransaction);

    gMcspiTxBuffer[0] = 0x0;
    gMcspiTxBuffer[1] = 0x0;
    gMcspiTxBuffer[2] = 0x0;

    /* Initiate transfer */
    MCSPI_Transaction_init(&spiTransaction);
    spiTransaction.channel = gConfigMcspi0ChCfg[0].chNum;
    spiTransaction.dataSize = 8;
    spiTransaction.csDisable = TRUE;
    spiTransaction.count = 3;
    spiTransaction.txBuf = (void *)gMcspiTxBuffer;
    spiTransaction.rxBuf = NULL;
    spiTransaction.args = NULL;

    transferOK = MCSPI_transfer(gMcspiHandle[CONFIG_MCSPI0], &spiTransaction);

    gMcspiTxBuffer[0] = 0x12;
    gMcspiTxBuffer[1] = 0x34;
    gMcspiTxBuffer[2] = 0x0;
    gMcspiTxBuffer[3] = 0x0;


    /* Initiate transfer */
    MCSPI_Transaction_init(&spiTransaction);
    spiTransaction.channel = gConfigMcspi0ChCfg[0].chNum;
    spiTransaction.dataSize = 8;
    spiTransaction.csDisable = TRUE;
    spiTransaction.count = 4;
    spiTransaction.txBuf = (void *)gMcspiTxBuffer;
    spiTransaction.rxBuf = (void *)gMcspiRxBuffer;
    spiTransaction.args = NULL;

    transferOK = MCSPI_transfer(gMcspiHandle[CONFIG_MCSPI0], &spiTransaction);

    // Now print the RX Buffer which is basically gMcspiRxBuffer

    Regards,

    Vaibhav

  • Hi Vaibhav,

    Thank you for the sample program you provided. I can understand the previous program code that simply sends the content of txBuffer, but I have some doubts about the last read and write example. It seems that the last example is trying to send 4 bytes of content and then read the slave side. The content comes back, but how much is read? Is it only 4 bytes? Or can I set it to read more content?

    Best,

    Larry

  • Hi Larry,

    Thank you for the sample program you provided. I can understand the previous program code

    Your feedback is much appreciated. I am glad it helped you out.

    The content comes back, but how much is read? Is it only 4 bytes? Or can I set it to read more content?

    Yes read is only 4 bytes, so what you can do is lets say you want to read 16 bytes you can set 

    spiTransaction.count = 4 to 16;

    And leave your transaction buffer as all 0s except the first few indexes like 0, 1 and 2 with some values to send.

    I hope this explains the thought process, if not please let me know, I will make a detailed FAQ explaining the same.

    Looking forward to your response.

    Regards,

    Vaibhav