Using NRFX SPIS in nRF Connect SDK

Hello,

I'm trying to use a SPIS peripheral from the NRFX library in a nRF Connect SDK 2.7.0 project. The reason for using the NRFX library is to clear a GPIO pin in the SPI ISR when the transfer is finished.

The prj.conf contains the following options (i'm using the SPIS1 peripheral):

CONFIG_SPI=y
CONFIG_SPI_NRFX=y
CONFIG_NRFX_SPIS1=y

The device tree overlay contains the following SPI slave peripheral:

&spi1 {
    compatible = "nordic,nrf-spis";
    status = "disabled";  // tried "okay" but nrfx_spis_init returns NRFX_ERROR_ALREADY
    def-char = <0xff>;
};

I followed the code in modules/hal/nordic/nrfx/samples/src/nrfx_spim_spis/advanced_non_blocking/main.c in the NCS root directory. I didn't use the line IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_SPIS_INST_GET(SPIS_INST_IDX)...) because it didn't compile. Maybe this line isn't necessary when SPI is enabled in the prj.conf file.

The SPI is initialized with nrfx_spis_init() as follows. Then the nrfx_spis_init_check() function returns true.

    nrfx_spis_config_t spis_config = {
        .miso_pin     = 38,
        .mosi_pin     = 37,
        .sck_pin      = 36,
        .csn_pin      = 35,
        .mode         = NRF_SPIS_MODE_0,
        .bit_order    = NRF_SPIS_BIT_ORDER_LSB_FIRST,
        .csn_pullup   = NRF_GPIO_PIN_NOPULL,
        .miso_drive   = NRF_GPIO_PIN_S0S1,
        .def          = 0xFF, 
        .orc          = 0xFF, 
        .irq_priority = 6, 
    };
    nrfx_err_t err = nrfx_spis_init(&spis, &spis_config, &nrfx_spis_event_handler, NULL);

The problem is that `nrfx_spis_buffers_set()` never returns:

err = nrfx_spis_buffers_set(&spis, m_tx_buf, m_tx_len, m_rx_buf, m_rx_len); // Stays blocked here

Would you have an idea of what could be the problem ?

  • The status property must be set to "okay". Might fix the IRQ_CONNECT() problem.

    Not sure if you needed more changes in the device tree - look at the combined tree files in the build/zephyr directory.

  • Thank you for you answer.

    I tried to set the `status` field of the SPIS1 peripheral to "okay" in the device tree.
    When I put the line with IRQ_CONNECT(...), the following compile error occurs:

    C:/ncs/v2.7.0/zephyr/include/zephyr/arch/arm/irq.h:117:1: error: expected identifier or '(' before '{' token
      117 | { \
          | ^
    C:/ncs/v2.7.0/zephyr/include/zephyr/irq.h:49:9: note: in expansion of macro 'ARCH_IRQ_CONNECT'
       49 |         ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p)
       
    

    where the IRQ_CONNECT line is as follows :

    #define SPIM_INST_IDX 1
    
    IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_SPIS_INST_GET(SPIS_INST_IDX)), IRQ_PRIO_LOWEST, NRFX_SPIS_INST_HANDLER_GET(SPIS_INST_IDX), 0, 0);
    

    If I remove the IRQ_CONNECT line, the project compiles but nrfx_spis_init() returns NRFX_ERROR_ALREADY.

    I tried several other combinations. I also tried to define the SPI pin numbers in the device tree, but that didn't solve the problem :

    &pinctrl {
        spis_default: spis_default {
            group1 {
                psels = <NRF_PSEL(SPIS_SCK, 1, 04)>,
                    <NRF_PSEL(SPIS_MISO, 1, 06)>,
                    <NRF_PSEL(SPIS_MOSI, 1, 05)>;
            };
        };
    };
    

    This is how the spis1 peripheral appears in the combined device tree in build/zephyr/zephyr.dts :

    		spi1: spi@40004000 {
    			compatible = "nordic,nrf-spis";
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40004000 0x1000 >;
    			interrupts = < 0x4 0x1 >;
    			max-frequency = < 0x7a1200 >;
    			easydma-maxcnt-bits = < 0x10 >;
    			status = "okay";
    			pinctrl-0 = < &spis_default >;
    			pinctrl-1 = < &spi1_sleep >;
    			pinctrl-names = "default", "sleep";
    			def-char = < 0xff >;
    		};

    I also tried to compile the example in modules/hal/nordic/nrfx/samples/src/nrfx_spim_spis/advanced_non_blocking/ using `west build -b nrf52840dk_nrf52840`, but the compilation fails (CMake Error at CMakeLists.txt:11 GET_DEVICE_CONFIG_FILES Macro invoked with incorrect arguments).

    Would you have other ideas that I can try ? I can upload the succinct source file of my project if needed.

  • Any reason why you try to code yourself instead of just using the existing driver in zephyr/drivers/spi/spi_nrfx_spis.c source file? It would get enabled via correct DT automagically.

  • Hi,

     

    If you want to not initialize the zephyr SPI driver, but only use the nrfx driver, you need to:

    1. enable the node in DT

    2. disable the zephyr driver component, in this case: CONFIG_SPI=n

     

    Now the subsys will not enable nrfx_spis during boot-up, which is the root-cause of this behavior:

    Anthony said:
    If I remove the IRQ_CONNECT line, the project compiles but nrfx_spis_init() returns NRFX_ERROR_ALREADY.

      

    Anthony said:
    where the IRQ_CONNECT line is as follows :

    It seems that you are defining SPIM_INST_IDX, and not SPIS_INST_IDX. Could you check if this is the problem?

     

    Kind regards,

    Håkon

  • Than you very much for you answers.

    My bad, I was calling IRQ_CONNECT() outside of any function, thinking it operated at compile time.

    The test project with NRFX SPIS works now with the following configuration:

    nrf52840dk_nrf52840.overlay :

    &spi1 {
        // Keep the compatible property otherwise a compile error ('NRFX_SPIS1_INST_IDX' undeclared here) occurs.
        // https://devzone.nordicsemi.com/f/nordic-q-a/93675/nrfx-spi-migration-from-ncs-1-9-to-ncs-2-0
        // https://github.com/nrfconnect/sdk-zephyr/commit/451a6ed6abbf35262bbcf0f926e7941f6c74c632
        compatible = "nordic,nrf-spis";
        status = "disabled";
    };

    prj.conf :

    CONFIG_NRFX_SPIS1=y
    

    With the C code based on modules/hal/nordic/nrfx/samples/src/nrfx_spim_spis/advanced_non_blocking/main.c.

    Regarding Turbo's interrogation, the reason for using (or evaluating the usage of) the nrfx library is to have more flexibility compared to the standard Zephyr way of configuring peripherals (although Zephyr also offers some flexibility: https://github.com/nrfconnect/sdk-zephyr/blob/v3.0.99-ncs1/samples/boards/nrf/dynamic_pinctrl/src/remap.c#L61 ) . For example, we are evaluating the feasibility of detecting the activation of the SPIS CSN pin without linking it physically to another GPIO, enabling/disabling peripherals at runtime, or changing their configuration dynamically, etc.

Related