⚠️
Hi there.. thanks for coming to the forums. Exciting news! we’re now in the process of moving to our new forum platform that will offer better functionality and is contained within the main Dialog website. All posts and accounts have been migrated. We’re now accepting traffic on the new forum only - please POST any new threads at https://www.dialog-semiconductor.com/support . We’ll be fixing bugs / optimising the searching and tagging over the coming days.
9 posts / 0 new
Last post
matthieuW
Offline
Last seen: 4 months 2 weeks ago
Joined: 2015-11-20 14:55
SPI latency

We have implemented dialog DA14681 on a custom board operating as a slave device.

Our system main purpose is to drive a peripheral through SPI when receiving commands through BLE SPS or USB CDC

We implemented the spi adapter and manly use the SDK ad_write_function.

We have different problems :

- when we send multiple SPI write commands, some are incompletes. We have a use case where we need to send 256 times  a 152 bytes data message(all 0xFF for instance), some of the data messages are randomly not complete as below :

1111111111... << complete
1111001111... << incomplete
0001111111... << incomplete
1111111111... << complete
...1111111111... << complete
1111110000... << incomplete

- we monitored the SPI bus with an oscilloscope, we have checked that the latency of the chip select can be quite long (up to a 100 ms). This latency can seen on the scope screen shot attached.

- when the usb is attached (USB CDC interface), the SPI latency is increased (up to 500ms). I know that 3 additionnal tasks are running when the usb is connected, can we tune something to improve these timings?

We tried to implement SDK SPI async transaction with a dedicated task and queue following the documentation down below but the improvment is not significant :

https://www.dialog-semiconductor.com/sites/default/files/da1468x_spi_adapter_tutorial_v2_1.pdf

We tried to tune the SPI parameters defined in ad_spi.h but with no significant result.

We think that this latency can be improve with SDK parameter tuning.

Best Regards

Matthieu

Attachment: 
Device: 
PM_Dialog
Offline
Last seen: 5 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi Matthieu,

Hi Matthieu,

I will check your question internally and let you know.

Thanks, PM_Dialog

PM_Dialog
Offline
Last seen: 5 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi matthieuW,

Hi matthieuW,

I asked the Team internally, and SPI Slave is supported in our hardware, but it is not fully implemented in our SDK. In the attached tutorial, the DA1468x is configured as SPI master.

Thanks, PM_Dialog

matthieuW
Offline
Last seen: 4 months 2 weeks ago
Joined: 2015-11-20 14:55
Dear Dialog,

Dear Dialog,

the spi interface implemented in my project is acting as a master (DA14681 controls an external peripheral).  Thus the problem is somewhere else.

Regards

Matthieu

PM_Dialog
Offline
Last seen: 5 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi matthieuW,

Hi matthieuW,

Would it be possible to use a Logic Analyzer, probe the signals and provide an SPI trace? This would be very helpful..

Also, can you please share some code snippets about how using the SPI adapter? Not all your project, only some code snippets.

Thanks, PM_Dialog

cpela
Offline
Last seen: 2 years 1 month ago
Joined: 2019-12-18 12:37
Dear Dialog,

Dear Dialog,

I'm cpela and I'm working with matthieuW on the project,

I've investigated about SPI and there is something wrong ...

About the problem of data not complete, its seems to be only the end of some message as :

1111111111... << complete
1111110000... << incomplete
1111111100... << incomplete
1111111111... << complete
1111111111... << complete
1111110000... << incomplete

As SPI command was not in task, we created a dedicated task spi_task to send our command

Our spi commands are put in a queue and are poped from the queue in spi task.

And lastly, we decoralated SPI communication from the others functions and we observe incomplete data...

Here is our principal functions in spi.c file

SPI Init :


// Test comm
uint8_t graySim[155];
bool flagGraySim = 0;


void SPI_init(void )
{
#if dg_configSPI_ADAPTER
        OS_MUTEX_CREATE(SPI1_mutex);
        ad_spi_init();
        SPI_BUS_INIT(SPI1);
        SPI_DEVICE_INIT(Ulli);
        MDP05_dev = ad_spi_open(Ulli);
#endif
}

Spi task :

void spi_task(){


#if dg_configUSE_WDOG
        int8_t wdog_id = sys_watchdog_register(false);/* register task to be monitored by watchdog */
#endif
        uint32_t notif;

        // init SPI bus & SPI communication
        SPI_init();

        // queue creation
        if (tx_spi_queue==NULL)
        {
                tx_spi_queue = user_queue_new(TX_SPI_QUEUE_SIZE);
        }

        graySim[0] = CMD_WRITE;
        graySim[2] = 0;
        memset(&graySim[3], 0xFF, 152);

        for (;;) {


#if dg_configUSE_WDOG
                /* notify watchdog on each loop */
                sys_watchdog_notify(wdog_id);
                /* suspend watchdog while waiting for commands */
                sys_watchdog_suspend(wdog_id);
#endif

                OS_TASK_NOTIFY_WAIT(0, OS_TASK_NOTIFY_ALL_BITS, &notif, OS_TASK_NOTIFY_FOREVER);

                if (user_queue_item_count(tx_spi_queue)) // analyse data only if queue is not empty
                {
                        spiProcessing();
                }


#if dg_configUSE_WDOG
                /* resume watchdog */
                sys_watchdog_notify_and_resume(wdog_id);
#endif
        }

}

#endif

Spi processing function :

__RETAINED_CODE static void spiProcessing(void)
{
        msg txSpiToSend;
        bool ret = 0;

        // Pop itemps
        ret = user_queue_pop_items(tx_spi_queue, &txSpiToSend);

        if (ret)
        {

            if (flagGraySim == 0)
            {
                    ad_spi_write(MDP05_dev, CMD_CLEAR, 1); // memory reset to 0
                    flagGraySim = 1;
            }
            else
            {
                    uint16_t i= 100;
                    for (i = 0; i < 255; i++)
                    {
                          graySim[1] = i; // line address increment
                          ad_spi_write(MDP05_dev, graySim, 155); // memory reset to 1
                    }
                    flagGraySim = 0;
              }


        }

        // Release message after pop
        msg_release(&txSpiToSend);

        // Call again task if queue is not empty
        if (user_queue_item_count(tx_spi_queue))
                {
                OS_TASK_NOTIFY(spi_task_handle, 1, OS_NOTIFY_SET_BITS);
        }
}

We are working to get some scope capture of our problem,

Thanks for your answer,

cpela

PM_Dialog
Offline
Last seen: 5 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi cpela and matthieuW,

Hi cpela and matthieuW,

Thanks for your inputs. I will go through the provided code snippets and let you know. Probably, I’ll need to escalate it to the Team internally.

Thanks, PM_Dialog

cpela
Offline
Last seen: 2 years 1 month ago
Joined: 2019-12-18 12:37
Dear Dialog,

Dear Dialog,

Our problem seems to be resolved about our incomplete data, but I noticed an other problem when I investigated ...

In picture enclosed, you can see scope capture of the problem,

I don't know why delays are too long,

When chip select goes to 0, it takes between 30 µs and 80 µs until spi clock is activated ... Same problem at end of frame, it takes between 30 µs and 80 µs until chip select goes to 1. And between 2 frame, we have between 100 µs and 130 µs delay.

In our SPI task, we call ad_spi_write of SDK and it would be great if we coul reduce delays but I don't have any idea from where delay could come...

 

Thanks for your help,

 

Regards

Attachment: 
PM_Dialog
Offline
Last seen: 5 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi cpela and matthieuW,

Hi cpela and matthieuW,

My apologies for the delay. I was trying to replicate your issue, but I was failed to reproduce it as it is custom code. This latest SPI capture really helps me to understand better the issue. According to your provided code snippet, you are using synchronous SPI write (ad_spi_write()). When the CS goes from 1 to 0, this means that any other master cannot take the SPI bus until the CS goes again to 1. However, when putting the CS to 0, the transaction will not start immediately, and this is the delay you see. Please check the ad_spi_write() source code. The CS is set to 0 by executing the ad_spi_bus_activate_cs(), but the transaction has not started yet. The then hw_spi_write_buf() is triggered in order to start the SPI transaction. The start writing happens in the end of the this function call by calling the hw_spi_transfer_write(id);. The delay you get is absolutely expected because between the time that the CS is set to 0 and the call of hw_spi_transfer_write(id), there is code execution!

Thanks, PM_Dialog