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.

CC2745R10-Q1: Delay from SPI CKL end to next Command

Part Number: CC2745R10-Q1

Tool/software:

Hello expert,

Our customer tried with the following code to check SPI behaivior.

Then the result is as follows.

The issue is, it took 30.214usec after SPI CS becomes high to the next GPIO toggle (DRDY) .

This issue occurs every time, and no interrupt has been occurred between the end of CS to GPIO toggle.

They are using SPI blocking mode now.

Can you please advise what is the cause of this delay and how to fix it?

One idea is to  use Call back mode, but it needs many resources , don't want to change as much as possible.

Regards,

A.Fujinaka

  • Hello,

    I apologize for the delay here. I have assigned this thread to an expert. Please expect a response next week.

    Please provide the following information:

    1. What SDK version are you using?

    Best,

    Nima Behmanesh

  • Hello Nima,

    They uses SDK 8.40.02.01.

    Please check the behavior at your side at first. 

    Regards,

    A.Fujinaka

  • I will check this issue today.

  • Hello Bostancioglu,

    Can you please update the status?

    I need to reply to my customer tomorrow.

    Regards,

    A.Fujinaka

  • Hello,

    After running in SPI_MODE_BLOCKING, it takes 22us in my setup to process GPIO_Toggle. I have tried to change software interrupt priorities[spi uses DMA interrupts] but no success in this path.

    By enabling callback mode, you can execute GPIO_toggle almost at the beginning of the CS activation.

    First option:

    spiParams.transferMode = SPI_MODE_CALLBACK;
    ....
    transferOK = SPI_transfer(controllerSpi, &transaction);
    GPIO_toggle(CONFIG_GPIO_LED_1);

    This will toggle gpio almost in parallel to SPI_Transfer.

    "One idea is to  use Call back mode, but it needs many resources , don't want to change as much as possible"

    I dont think it requires significant resources. Define one more function, pass it into spi as function pointer. If you need to know is spi_transfer is done, you can use rtos mutex-like objects to sync processes. i used volatile bool in this case.

    volatile bool transferComplete = false;
    
    void spiCBFxn(SPI_Handle handle, SPI_Transaction *transaction)
    {
    transferComplete = false;
    if (transaction->status == SPI_TRANSFER_COMPLETED)
    {
    transferComplete = true;
    }
    }
    
    SPI_Params_init(&spiParams);
    spiParams.transferMode = SPI_MODE_CALLBACK;
    spiParams.transferCallbackFxn = spiCBFxn;
    spiParams.frameFormat = SPI_POL0_PHA1;
    /* See device-specific technical reference manual for supported speeds */
    spiParams.bitRate = 1000000;
    
    transferOK = SPI_transfer(controllerSpi, &transaction);
    GPIO_toggle(CONFIG_GPIO_LED_1);
    
    while(!transferComplete); // blocking.

    third option: This option minimizes the GPIO_toggle function JUST AFTER the CS deactivate. Improves the time from 22us to 10us in my case.

    volatile bool transferComplete = false;
    
    void spiCBFxn(SPI_Handle handle, SPI_Transaction *transaction)
    {
        transferComplete = false;
        if (transaction->status == SPI_TRANSFER_COMPLETED)
        {
            transferComplete = true;
            GPIO_toggle(CONFIG_GPIO_LED_1);
        }
    }
    ....
    SPI_Params_init(&spiParams);
            spiParams.transferMode = SPI_MODE_CALLBACK;
            spiParams.transferCallbackFxn = spiCBFxn;
            spiParams.frameFormat = SPI_POL0_PHA1;
            /* See device-specific technical reference manual for supported speeds */
            spiParams.bitRate     = 1000000;
    ....
    transferOK = SPI_transfer(controllerSpi, &transaction);
    while(!transferComplete); // blocking.

    Conculusion:

    - You can decide to run GPIO_toggle in parallel to SPI_Transfer or within the SPI_Callback function, you can decide to toggle GPIO based on spi_transfer status. Below are the status codes you can check against SPI_Transfer status. Best way to handle GPIO based on SPI status is using callback function.

    SPI_TRANSFER_COMPLETED = 0, /*!< SPI transfer completed */
    SPI_TRANSFER_STARTED, /*!< SPI transfer started and in progress */
    SPI_TRANSFER_CANCELED, /*!< SPI transfer was canceled */
    SPI_TRANSFER_FAILED, /*!< SPI transfer failed */
    SPI_TRANSFER_CSN_DEASSERT, /*!< SPI chip select was de-asserted (only
    applicable in return partial mode) */
    SPI_TRANSFER_PEND_CSN_ASSERT, /*!< SPI transfer is pending until the chip
    select is asserted */
    SPI_TRANSFER_QUEUED /*!< SPI transfer added to transaction queue */

    - changing spi interrupt priorities does not improve the execution time.

  • Hello,

    Thanks for your answer. Basically my customer will use the call back function as you recommended.

    They have one question that is , if this delay happen not only for SPI function but for all the peripheral case, for example , UART.

    Because they think something RTOS is working to finalize the function.

    Regards,

    A.Fujinaka

  • Hello , great to hear.

    delay can happen in while waiting for the interrupt to inform the system. When we use callbacks, this happens faster. Since callbacks are being called before end of spitransfer.

    in my setup I only have spi transfer interrupt. They can study their rtos schedular with tools, they can change interrupt priorities and so on.

    interrupt to callback is faster. That’s what we are using. 

  • Any questions left in this thread ? 

  • Hello 

    So , you mean , this kind of delay might happen from any of the peripheral function returning , right?

    Regards,

    A.Fujinaka

  • Yes, if its comm interface. Best method is using callback to minimize it.