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.

AMIC110: McSPI transfer speed issue

Part Number: AMIC110

Hello Sirs,

We have requirement for fast SPI transfer speed, we want to transfer 128 bytes of data in full duplex as fast as we can

the code below shows how we write and read SPI buffer with 32bit dataSize(4 byte), so there will be 32 sets of 4 bytes to be transfer (total 128 bytes)

the code works well but we found that waiting for McSPIChannelStatusGet() and McSPIReceiveData() will cause delay for approximate 2us 

mcspi_chstat_txs_mask = MCSPI_CH0STAT_TXS_MASK;
mcspi_chstat_rxs_mask = MCSPI_CH0STAT_RXS_MASK;
for(i = 0; i < len; i++)
{
    loop = 1000;
    /* Wait for transmit empty */
    while(((McSPIChannelStatusGet(pCfgMcspi->instAddr,
                                          pCfgMcspi->channelNum) & mcspi_chstat_txs_mask) == 0)
                    && (loop--));    /* check if TX buffer is empty */

    if(loop == -1)
    {
        return;
    }

    TmpBuff[1] = tbuff[TxIdx];
    TmpBuff[0] = tbuff[TxIdx+1];
    TxIdx+=2;
    /* Program the data to be transmitted. */
    McSPITransmitData(pCfgMcspi->instAddr,
                      *(uint32_t*)TmpBuff,
                      pCfgMcspi->channelNum);
    loop = 1000;
    /* check if RX buffer */
    //GPIO_write(GPIO_TIMING_MEASURE, 1);
    while(((McSPIChannelStatusGet(pCfgMcspi->instAddr,
                                          pCfgMcspi->channelNum) & mcspi_chstat_rxs_mask) == 0)
                    && (loop--));    /* check if RX buffer is full */
    if(loop == -1)
    {
        return;
    }
    //GPIO_write(GPIO_TIMING_MEASURE, 0);
    *(uint32_t*)TmpBuff = McSPIReceiveData(pCfgMcspi->instAddr,
                                                    pCfgMcspi->channelNum);//HW_RD_REG32();
    //GPIO_write(GPIO_TIMING_MEASURE, 0);
    /**/
    rbuff[RxIdx] = TmpBuff[1];
    rbuff[RxIdx+1] = TmpBuff[0];
    RxIdx+=2;

}

This will cause a "hole" between the transmission, for 32 sets it will cause ~60us overhead, this is too much for us

Are there any solution to reduce the process time, so the "hole" can get shorter? So that we don't wasted that much time?

*This pic shows McSPIChannelStatusGet() + McSPIReceiveData() took about 1.3us to proceed

Thank you

  • Hello Kevincw,

    I assume the McSPIxxx functions are from the CSL of the AM335x PDK. If that's the case, both McSPIChannelStatusGet() and McSPIReceiveData() are just register reads. The register read itself should only take a few cycles at most.

    I noticed that the function call of McSPIChannelStatusGet() is in a while loop. Is 2us the time taken by a single call or multiple calls of this function?

    Regards

    Jianzhong

  • Hi Jianzhong,

    Thanks for reply

    This is the folder the header file come from ----> ti\pdk_am335x_1_0_17\packages\ti\csl\src\ip\mcspi\V0\mcspi.h

    I think it is taken by single call on McSPIChannelStatusGet() function, I clip it with GPIO toggle and the time measured is 1.260us

    Do you have any idea why the function took long time?

    while(1)
    {
        GPIO_write(GPIO_TIMING_MEASURE, 1);
        ret = (McSPIChannelStatusGet(pCfgMcspi->instAddr, pCfgMcspi->channelNum) & mcspi_chstat_rxs_mask);
        GPIO_write(GPIO_TIMING_MEASURE, 0);
        if(ret != 0)
        {
            break;
        }
    }

  • Hello Kevincw,

    Function McSPIChannelStatusGet() is defined in pdk_am335x_1_0_17\packages\ti\csl\src\ip\mcspi\V0\priv\mcspi.c:

    uint32_t McSPIChannelStatusGet(uint32_t baseAddr, uint32_t chNum)
    {
        /* Return the status from MCSPI_CHSTAT register. */
        return (HW_RD_REG32(baseAddr + MCSPI_CHSTAT(chNum)));
    }
    

    I would recommend you to try to directly use HW_RD_REG32 in your code, for example,

    while(1)
    {
        GPIO_write(GPIO_TIMING_MEASURE, 1);
        ret = (HW_RD_REG32(pCfgMcspi->instAddr + MCSPI_CHSTAT(pCfgMcspi->channelNum)) & mcspi_chstat_rxs_mask);
        GPIO_write(GPIO_TIMING_MEASURE, 0);
        if(ret != 0)
        {
            break;
        }
    }

    Then place all your code and data in internal memory. See if this can reduce the read time. If it still takes close to 1.26us, I'll loop in our HW team for help.

    Regards,

    Jianzhong

  • Hi Jianzhong,

    Sorry for late reply.

    using HW_RD_REG32 still took me approximate 2us, I think this is because the code is loaded in external memory (DDR), but I didn't do experiment to prove it

    However, I've changed the way transfer by using TI-RTOS SPI driver, using interrupt + callback mode

    and found the overhead has reduced to 800us, its good enough for me

      

     

    The problem is solved, thanks for your help!