NCS v3.0.0 async SPI slave: How to get pin numbers from .overlay to C file for SPI slave configuration?

Working on the nRF52833DK board and based off the nrfx_spim_spis advanced non-blocking example sample.  I've already converted the SPI master to use the Zephyr driver instead of using the NRFX driver directly.  (My understanding is the NRFX driver is still used by the Zephyr SPI driver under the covers.)  Unfortunately I cannot convert the SPI slave to use the Zephyr driver because the Zephyr driver does not support asynchronous SPI slave, and I want the asynchronous feature.  So I'm stuck using the NRFX driver for SPI slave.

I'm trying to do things "properly" regarding Zephyr and the devicetree, so I want to define the pins in the .overlay file since I will eventually want this firmware to run on multiple boards (each defining their own pin configuration via a .overlay or the base .dts).  Thus I need the NRFX SPI slave driver to get the SPI slave pin configuration from the devicetree directly OR my C code needs a way to pull the pin settings from the devicetree.

Unfortunately, even though the nrfx_spim_spis advanced non-blocking example DOES define pins in the .overlay files, it does NOT actually use those in the C file.  Instead it pulls the pin definitions from common/nrfx_example.h via a series of "LOOPBACK_PIN_xxx" defines, which defeats the purpose of having a devicetree specify pin configurations.  (This would be an example of not doing things "properly" regarding Zephyr and NCS.)

My question is this:  For the NRFX SPI slave, using NCS v3.0.0 (or later if needed), how do I define the SPI slave pins in the .overlay so they can be used for NRFX SPI slave configuration in the C file?  And how do I access them in the C file?

Or an even shorter and more generic version of the question:  How do I define pin numbers in a .overlay and then get those pin numbers in a C file?

For reference, following the advanced non-blocking example I currently have the pins defined like this in the .overlay:

&pinctrl {
    spis_default: spis_default {
        group1 {
            psels = <NRF_PSEL(SPIS_SCK, 0, 29)>,
                    <NRF_PSEL(SPIS_MOSI, 0, 31)>,
                    <NRF_PSEL(SPIS_MISO, 0, 30)>,
                    <NRF_PSEL(SPIS_CSN, 0, 27)>;
        };
    };
    spis_sleep: spis_sleep {
        group1 {
            psels = <NRF_PSEL(SPIS_SCK, 0, 29)>,
                    <NRF_PSEL(SPIS_MOSI, 0, 31)>,
                    <NRF_PSEL(SPIS_MISO, 0, 30)>,
                    <NRF_PSEL(SPIS_CSN, 0, 27)>;
            low-power-enable;
        };
    };
};

&spi2 {
    status = "okay";
    compatible = "nordic,nrf-spis";
    pinctrl-names = "default","sleep";
    pinctrl-0 = <&spis_default>;
    pinctrl-1 = <&spis_sleep>;
    def-char = <0xFF>;
};

Unfortunately there does not appear to be an easy way to get those values from the pinctrl into the C code.

Parents
  • Its a two liner, but you have to read through a lot of source code to figure it out:

    #include <zephyr/drivers/pinctrl.h>

    void foo(){

    const struct pinctrl_dev_config *pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_NODELABEL(spi2));
    pinctrl_apply_state(pcfg, 0);

    }

  • Unfortunately this isn't working for me.  The new source:

        /* Apply the pinctrl to the config */
        {
            const struct pinctrl_dev_config *pcfg;

            pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_NODELABEL(spi2));
            pinctrl_apply_state(pcfg, 0);
        }

    The error:

    C:/nord/trble/trble.git/ble_rework/src/spis.c: In function 'spis_thread':
    C:/nord/trble/trble.git/ble_rework/src/spis.c:557:17: error: '__pinctrl_dev_config__device_dts_ord_102' undeclared (first use in this function)
      557 |         pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_NODELABEL(spi2));
          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  • You may miss the conig (in prj.conf):

    CONFIG_SPI=y

  • I appreciate the effort but still no luck.  I tried adding CONFIG_SPI, CONFIG_SPI_SLAVE, CONFIG_ASYNC, and CONFIG_SPI_NRFX to prj.conf and __pinctrl_dev_config__device_dts_ord_102 still fails to resolve.

    Important reminder that I'm not using the Zephyr SPI driver for the SPI slave (described in original post).  I'm stuck using the NRFX driver directly .  Not sure if that is related.

  • Hi,

    how do I define the SPI slave pins in the .overlay so they can be used for NRFX SPI slave configuration in the C file?  And how do I access them in the C file?

     Using NRFX SPIS in nRF Connect SDK  CONFIG_NRFX_SPIM1 was assigned the value y, but got the value n. Missing dependencies:n and  How to setup SPIS on net core using nrfx in nRF7002-DK Discusses enabling the nrfx spim, but as far as I can see neither discusses how to use Zephyr for SPIM and nRFX for SPIS.

    To me it looks like this reply might contain what you need https://devzone.nordicsemi.com/support-private/support/334541#permalink=1009111. I've not tested this, but I assume the following would work

    1. Initialize the SPIM in dts as you would do for a zephyr SPIM peripheral
    2. Initialize the SPIS in dts with status=disabled and set it up as a nRFX SPIS. 
    For example, to define an SPI peripheral for use with nrfx (e.g., SPIM1), your overlay might look like this:

    &spi1 {
    status = "disabled"; // or "okay" if you want Zephyr to manage it
    compatible = "nordic,nrf-spim";
    pinctrl-0 = <&spi1_default>;
    // Additional configuration as needed
    };

    • If you set status = "disabled", Zephyr will not initialize this instance, allowing you to use it directly with the nrfx driver in your application code. This is a common approach when you want to avoid conflicts between Zephyr and nrfx drivers and use the peripheral exclusively with nrfx APIs.
    • If you set status = "okay", Zephyr will manage the peripheral, and you should use the Zephyr SPI API.

    Let me know if this furthers your progress.

    Kind regards,
    Andreas

  • Hi Andreas.  I'm afraid the replies have gone into the weeds on this one.  Ignoring anything about compatibility between SPIM and SPIS, I want to focus on the initial question:

    My question is this:  For the NRFX SPI slave, using NCS v3.0.0 (or later if needed), how do I define the SPI slave pins in the .overlay so they can be used for NRFX SPI slave configuration in the C file?  And how do I access them in the C file?

    Or an even shorter and more generic version of the question:  How do I define pin numbers in a .overlay and then get those pin numbers in a C file?

Reply
  • Hi Andreas.  I'm afraid the replies have gone into the weeds on this one.  Ignoring anything about compatibility between SPIM and SPIS, I want to focus on the initial question:

    My question is this:  For the NRFX SPI slave, using NCS v3.0.0 (or later if needed), how do I define the SPI slave pins in the .overlay so they can be used for NRFX SPI slave configuration in the C file?  And how do I access them in the C file?

    Or an even shorter and more generic version of the question:  How do I define pin numbers in a .overlay and then get those pin numbers in a C file?

Children
No Data
Related