This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to Use SPI Interface in a Zephyr sample example?

Hi,

I am trying to understand how to enable SPI in blinky application provided by Nordic. My intention is to transfer data between the two Nordic development kit running blinky application over SPI. I have enabled SPI with the following details in the prj.conf file.

CONFIG_GPIO=y
CONFIG_SPI=y

CONFIG_SPI_NRFX=y
CONFIG_SPI_SLAVE=y
CONFIG_SPI_ASYNC=y
CONFIG_SPI_1=y

I see that DEVICE_INIT() in main.c and  DEVICE_AND_API_INIT(1) in spi_nrfx_spi.c do all the initialization based on the board dts file. And, I could use spi_read(), spi_write(), spi_transceive() as appropriate to send/receive data thru SPI interface.

Is my understanding correct? 

Please add if I am missing anything.

Thanks,

Ram

Parents
  • Hi Hakon,

    Thanks for your detailed reply! I really appreciate it! I have the following details from other Nordic posts.

    1. In https://devzone.nordicsemi.com/f/nordic-q-a/69269/issues-with-implementing-spi-slave-on-nrf9160dk/285345#285345

    you have replied that "The problem is that the nrfx_spis and zephyr's spi slave do not play well together, so you have to only have one of these enabled to be able to use the SPIS properly.

     As your project is setup now, the zephyr spi driver will be initialized "post kernel" (see here: https://github.com/nrfconnect/sdk-zephyr/blob/master/drivers/spi/spi_nrfx_spis.c#L290-L297), and before main() is called.

    This means that the spis_nrfx_spis.c implementation will then claim the SPIS3 peripheral before you can via the nrfx_spis API in main."

    2. Also, you have written in https://devzone.nordicsemi.com/f/nordic-q-a/69034/nrf52840-spi-slave-configuration-event_handler

    "The zephyr spis driver assumes that you use a dedicated thread, and use the k_poll functionality (signalled from the evt handler)", and

    "If you use nrfx_spis (CONFIG_NRFX_SPIS=y) directly; you can do this using the approach with a event_handler."

    3. And, Torbjorn has written in https://devzone.nordicsemi.com/f/nordic-q-a/56857/understanding-spi-with-easy-dma

    There is no need to enable NRFX_SPIM_ENABLED or NRFX_SPI_ENABLED. As long as you enable SPI_ENABLED, and enable SPIx_USE_EASY_DMA for any instance that you use, the nrfx_spim driver will be enabled automatically, and DMA will be used.

    If you want SPI slave you should enable SPIS_ENABLED

    Please note that there is no choice of DMA or not when using SPI slave, as the SPI slave peripheral had DMA from the start.

    Note: I am not sure if this is applicable to SPI in nRF Connect or not.

    My questions:

    So, if I want to use easyDMA without a dedicated thread, I should set

    CONFIG_NRFX_SPIS=y

    CONFIG_NRFX_SPIS3=y

    Form the documentation, CONFIG_SPI_0_NRF_SPIS enables nRF SPI slave with EasyDMA on port-0. It is indirectly enabled with SPI_SLAVE && SPI_NRFX && SPI. It means that all the 3 shall be set to y in my configuration. 

    Do I need to set CONFIG_SPI_0_NRF_SPIS=y?

    There are so many configuration available to use SPI.

    Could you please throw some light on the configuration for the SPI master and SPI slave with DMA and without DMA without a dedicated thread?

    Thanks,

    Ram

Reply
  • Hi Hakon,

    Thanks for your detailed reply! I really appreciate it! I have the following details from other Nordic posts.

    1. In https://devzone.nordicsemi.com/f/nordic-q-a/69269/issues-with-implementing-spi-slave-on-nrf9160dk/285345#285345

    you have replied that "The problem is that the nrfx_spis and zephyr's spi slave do not play well together, so you have to only have one of these enabled to be able to use the SPIS properly.

     As your project is setup now, the zephyr spi driver will be initialized "post kernel" (see here: https://github.com/nrfconnect/sdk-zephyr/blob/master/drivers/spi/spi_nrfx_spis.c#L290-L297), and before main() is called.

    This means that the spis_nrfx_spis.c implementation will then claim the SPIS3 peripheral before you can via the nrfx_spis API in main."

    2. Also, you have written in https://devzone.nordicsemi.com/f/nordic-q-a/69034/nrf52840-spi-slave-configuration-event_handler

    "The zephyr spis driver assumes that you use a dedicated thread, and use the k_poll functionality (signalled from the evt handler)", and

    "If you use nrfx_spis (CONFIG_NRFX_SPIS=y) directly; you can do this using the approach with a event_handler."

    3. And, Torbjorn has written in https://devzone.nordicsemi.com/f/nordic-q-a/56857/understanding-spi-with-easy-dma

    There is no need to enable NRFX_SPIM_ENABLED or NRFX_SPI_ENABLED. As long as you enable SPI_ENABLED, and enable SPIx_USE_EASY_DMA for any instance that you use, the nrfx_spim driver will be enabled automatically, and DMA will be used.

    If you want SPI slave you should enable SPIS_ENABLED

    Please note that there is no choice of DMA or not when using SPI slave, as the SPI slave peripheral had DMA from the start.

    Note: I am not sure if this is applicable to SPI in nRF Connect or not.

    My questions:

    So, if I want to use easyDMA without a dedicated thread, I should set

    CONFIG_NRFX_SPIS=y

    CONFIG_NRFX_SPIS3=y

    Form the documentation, CONFIG_SPI_0_NRF_SPIS enables nRF SPI slave with EasyDMA on port-0. It is indirectly enabled with SPI_SLAVE && SPI_NRFX && SPI. It means that all the 3 shall be set to y in my configuration. 

    Do I need to set CONFIG_SPI_0_NRF_SPIS=y?

    There are so many configuration available to use SPI.

    Could you please throw some light on the configuration for the SPI master and SPI slave with DMA and without DMA without a dedicated thread?

    Thanks,

    Ram

Children
  • Hi Ram,

     

    RAS_ID said:

    Thanks for your detailed reply! I really appreciate it! I have the following details from other Nordic posts.

    1. In https://devzone.nordicsemi.com/f/nordic-q-a/69269/issues-with-implementing-spi-slave-on-nrf9160dk/285345#285345

    you have replied that "The problem is that the nrfx_spis and zephyr's spi slave do not play well together, so you have to only have one of these enabled to be able to use the SPIS properly.

     As your project is setup now, the zephyr spi driver will be initialized "post kernel" (see here: https://github.com/nrfconnect/sdk-zephyr/blob/master/drivers/spi/spi_nrfx_spis.c#L290-L297), and before main() is called.

    This means that the spis_nrfx_spis.c implementation will then claim the SPIS3 peripheral before you can via the nrfx_spis API in main."

    2. Also, you have written in https://devzone.nordicsemi.com/f/nordic-q-a/69034/nrf52840-spi-slave-configuration-event_handler

    "The zephyr spis driver assumes that you use a dedicated thread, and use the k_poll functionality (signalled from the evt handler)", and

    "If you use nrfx_spis (CONFIG_NRFX_SPIS=y) directly; you can do this using the approach with a event_handler."

    3. And, Torbjorn has written in https://devzone.nordicsemi.com/f/nordic-q-a/56857/understanding-spi-with-easy-dma

    There is no need to enable NRFX_SPIM_ENABLED or NRFX_SPI_ENABLED. As long as you enable SPI_ENABLED, and enable SPIx_USE_EASY_DMA for any instance that you use, the nrfx_spim driver will be enabled automatically, and DMA will be used.

    If you want SPI slave you should enable SPIS_ENABLED

    Please note that there is no choice of DMA or not when using SPI slave, as the SPI slave peripheral had DMA from the start.

    Note: I am not sure if this is applicable to SPI in nRF Connect or not.

     Torbjørn is talking about the nrfx integration in the nRF5 SDK, by configuring the SPI/SPIM module using the sdk_config.h.

    On the nRF52-series devices, in addition to the NRF_SPIM (DMA capable) module, there's a legacy NRF_SPI module, which is not DMA capable. The DMA mentions here are towards backwards compatibility.

     

    nRF9160 does not have the legacy NRF_SPI module, so you'll have to use a DMA capable one here.  

    RAS_ID said:

    So, if I want to use easyDMA without a dedicated thread, I should set

    CONFIG_NRFX_SPIS=y

    CONFIG_NRFX_SPIS3=y

    Form the documentation, CONFIG_SPI_0_NRF_SPIS enables nRF SPI slave with EasyDMA on port-0. It is indirectly enabled with SPI_SLAVE && SPI_NRFX && SPI. It means that all the 3 shall be set to y in my configuration. 

     The CONFIG_NRFX_* configs allow you to directly access the nrfx driver. This then omits DTS and other configs towards the zephyr SPI component. You should then set CONFIG_SPI=n to avoid zephyr potentially "grabbing" your NRF_SPIx interrupt vector, which it will do if you enable the same instance as you try to use with nrfx_spi*.

    If you do not plant to use any of the sensor drivers or other functions related to zephyrs driver, you can set CONFIG_NRFX_SPIS=y and include nrfx_spis.h in your application, and setup the driver directly, similar to how its done in the nRF5 SDK example examples/peripheral/spis.

     

    Note: when using NRFX drivers, you have to manually link the interrupt vector, similar to this:

    https://github.com/Rallare/fw-nrfconnect-nrf/blob/nrf9160_samples/samples/nrf9160/nrfx_timed_signal/src/main.c#L128-L132

     

    Kind regards,

    Håkon

     

    RAS_ID said:
    Could you please throw some light on the configuration for the SPI master and SPI slave with DMA and without DMA without a dedicated thread?

     You have to use DMA on a hardware level.

    If you want to use the SPI modules with any of the drivers/sensors in the zephyr tree, you should look at using the zephyr spi driver. However, if not, you can choose freely between the zephyr SPI or use nrfx directly.

     

Related