Slow SPI performance with zephyr

SDK Environment: nRF Connect SDK v1.7.1

Target: Decawave DWM1001-DEV. This uses the nRF52832

A 5 byte SPI transfer is taking about 17us when using the nordic spim drivers and about 56us when using the zephyr spim drivers.

SPI CLK frequency = 8M

Would this be considered normal? The slow speed of the zephyr SPI drivers is causing problems in my application.

The zephyr drivers seem to be stable, but slow.

I set and clear a gpio testpin before and after the SPI transfer so I can measure the timing.

SPI timing with the nordic drivers

SPI timing with the zephyr drivers

"nrfx_spim.zip" uses the nordic drivers

"zephyr_spim.zip" uses the zephyr drivers

6763.nrfx_spim.zipzephyr_spim.zip

Parents
  • Hi

    The main difference can be seen in the above snapshots, is "SS" time (the time used to set chip select).

    How do you set the SS signal?

    In Zephyr, it is implemented by the software (there is no automatic assignment by the hardware), so you have two option, set/clear the the SS pin by your application before/after sending the SPI data, or you can leave it to the Zephyr to control the SS signal by a code similar to this:

    #define SPI_NODE DT_NODELABEL(spi0)
    
    const struct spi_cs_control spi_dev_cs_ctrl = {
    	.gpio_dev = DEVICE_DT_GET(DT_GPIO_CTLR(SPI_NODE, cs_gpios)),
    	.gpio_pin = DT_GPIO_PIN(SPI_NODE, cs_gpios),
    	.gpio_dt_flags = DT_GPIO_FLAGS(SPI_NODE, cs_gpios)
    };
    
    const struct spi_config spi_cfg = {
    	.operation = SPI_WORD_SET(8) | 
    				SPI_TRANSFER_MSB |
    				SPI_OP_MODE_MASTER,
    	.frequency = 8000000,
    	.cs = &spi_dev_cs_ctrl,
    };

    It is what I have measured (around 3 us from when SS has toggled until when clk has switched)

    PS: ensure you are using the last version of the Zephyr, maybe there are some bugs in older versions

Reply
  • Hi

    The main difference can be seen in the above snapshots, is "SS" time (the time used to set chip select).

    How do you set the SS signal?

    In Zephyr, it is implemented by the software (there is no automatic assignment by the hardware), so you have two option, set/clear the the SS pin by your application before/after sending the SPI data, or you can leave it to the Zephyr to control the SS signal by a code similar to this:

    #define SPI_NODE DT_NODELABEL(spi0)
    
    const struct spi_cs_control spi_dev_cs_ctrl = {
    	.gpio_dev = DEVICE_DT_GET(DT_GPIO_CTLR(SPI_NODE, cs_gpios)),
    	.gpio_pin = DT_GPIO_PIN(SPI_NODE, cs_gpios),
    	.gpio_dt_flags = DT_GPIO_FLAGS(SPI_NODE, cs_gpios)
    };
    
    const struct spi_config spi_cfg = {
    	.operation = SPI_WORD_SET(8) | 
    				SPI_TRANSFER_MSB |
    				SPI_OP_MODE_MASTER,
    	.frequency = 8000000,
    	.cs = &spi_dev_cs_ctrl,
    };

    It is what I have measured (around 3 us from when SS has toggled until when clk has switched)

    PS: ensure you are using the last version of the Zephyr, maybe there are some bugs in older versions

Children
No Data
Related