SPIS with nRF54L15 with the current Development Kit

Hello ! 
I'm trying to adapt the code from the master-slave SPI example (https://github.com/too1/ncs-spi-master-slave-example) for my nRF54L15 development kit.

The master part runs smoothly, but when it comes to the slave, I get a linking error on build (undefined reference to `__device_dts_ord_72' ).

When I look in build/zephyr/include/generated.devicetree_generated.h, I have Node 72 =  /soc/peripheral@50000000/spi@c8000

When I look in build/zephyr/zephyr.dts, I have : 

			spi22: spi_slave: spi@c8000 {
				compatible = "nordic,nrf-spis";
				#address-cells = < 0x1 >;
				#size-cells = < 0x0 >;
				reg = < 0xc8000 0x1000 >;
				interrupts = < 0xc8 0x1 >;
				max-frequency = < 0x7a1200 >;
				easydma-maxcnt-bits = < 0x10 >;
				status = "okay";
				pinctrl-0 = < &spi_slave_default >;
				pinctrl-1 = < &spi_slave_sleep >;
				pinctrl-names = "default", "sleep";
				cs-gpios = < &gpio1 0x0 0x1 >;
				def-char = < 0x0 >;
			};

My .overlay file look like this : 

//Disable everything that could collide, test only
&spi20 {
    status = "disabled";
};

&spi21 {
    status = "disabled";
};

&spi30 {
    status = "disabled";
};

&i2c20 {
    status = "disabled";
};

&i2c21 {
    status = "disabled";
};

&i2c22 {
    status = "disabled";
};

&i2c30 {
    status = "disabled";
};

&uart30 {
    status = "disabled";
};

&uart22 {
    status = "disabled";
};

&spi22{
    status = "okay";
};


&pinctrl {
    spi_slave_default: spi_slave_default {
        group1 {
            psels = <NRF_PSEL(SPIS_MOSI, 1, 2)>,
                    <NRF_PSEL(SPIS_SCK, 1, 1)>,
                    <NRF_PSEL(SPIS_MISO, 1, 3)>;
        };
    };

    spi_slave_sleep: spi_slave_sleep {
        group1 {
            psels = <NRF_PSEL(SPIS_MOSI, 1, 2)>,
                    <NRF_PSEL(SPIS_SCK, 1, 1)>,
                    <NRF_PSEL(SPIS_MISO, 1, 3)>;
            low-power-enable;
        };
    };
};

spi_slave: &spi22 {
	compatible = "nordic,nrf-spis";
    status = "okay";
	max-frequency = <DT_FREQ_M(8)>;
    pinctrl-0 = <&spi_slave_default>;
    pinctrl-1 = <&spi_slave_sleep>;
    pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
	def-char = <0>;
};

In my .conf file, I have enabled CONFIG_SPI and CONFIG_SPI_SLAVE.

the simplified main.c looks like this : 

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/spi.h>

#include <zephyr/logging/log.h>

#define SPI_SLAVE DT_NODELABEL(spi_slave)
const struct device *my_spi_slave;

static void spi_slave_init(void)
{
	my_spi_slave = DEVICE_DT_GET(SPI_SLAVE);
	if(!device_is_ready(my_spi_slave)){
		LOG_ERR("SPI master device not ready!");
	}
}

...

int main(void){
spi_slave_init();
}

Whenever I call spi_slave_init(), I have the error on build.
I tried using :

#if !DT_NODE_EXISTS(DT_NODELABEL(spi_slave))
#error "Invalid Node Identifier !"
#endif

But it builds correctly (without the spi_slave_init() line).

I also tried to build the same main.c with a nRF52 config by adapting the .overlay file, and it runs smoothly.

If anyone has a clue, I would appreciate this !
Have a good day,
Hugo

Parents
  • Hi Hugo

    Do you have access to logic analyzer just to verify there is traffic on the pins?  I will try to replicate it on my side

    Regards

    Runar

  • I have plugged an oscilloscope and I can't see any traffic either. Still I know my logic is running because led1 blinks correctly.

  • Hi thank you for your patience 

    I'm testing right now, I wonder if maybe the different domains are causing us a bit of confusion. I don't see anything wrong 

    As long as mx25r64: mx25r6435f@0 is disabled there should not be anything on P2 from what I can see. 

    Edit: I think this might be the issue since we did not see anything on the clk pin. 

    P1.03, P1.04 and P1.08 can be used for SPICLK.

    I will do another test tomorrow morning

    Regards

    Runar

  • Thanks for you answer !  
    I already tried with explicitly mx25r64: mx25r6435f@0  disabled, it didn't change much for me. When I read the documentation, I don't see any pinout for my N54L15QFAAAB, but I assume it's the same as N54L15QFN48 pinout. On this pinout I read that both P2.01 and P2.06 could be used as SPICLK, that's why I chose P2.01 (to ensure that the data signals associated are close as recommended p.844). I just ran a test with P2.06 instead, not much change. When I run in debug mode, I still can see the PSEL CLK change (screen below), but nothing on my CS.

    I wonder if it's the good way to initialise it in my code ? It might be the issue but it's surprising because everything happens before the debugger breaks for the first time and I assume that the spi_config is only used when transceiving messages.

    #define SPI_MASTER DT_NODELABEL(spi_master)
    #define MY_SPI_MASTER_CS_DT_SPEC SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(reg_my_spi_master))
    
    const struct device *my_spi_master;
    
    static void spi_master_init(void)
    {
    	my_spi_master = DEVICE_DT_GET(SPI_MASTER);
    	if(!device_is_ready(my_spi_master)){
    		LOG_ERR("SPI master device not ready!");
    	}
    	struct gpio_dt_spec spim_cs_gpio = MY_SPI_MASTER_CS_DT_SPEC;
    	if(!device_is_ready(spim_cs_gpio.port)){
    		LOG_ERR("SPI master chip select device not ready!");
    	}
    }
    
    //SPI configs
    static struct spi_config spi_master_cfg = {
    	.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_OP_MODE_MASTER,
    	.frequency = 4000000,
    	.slave = 0,
    	.cs = {.gpio = MY_SPI_MASTER_CS_DT_SPEC, .delay = 0},
    };

  • Hi, 

    I spent more time to get this up and running then what I would expect. I did not pay attention to the small letters on the pdk where it states that the pin number with parentheses can not be used without modification to the pdk. Your setup looks fine to me. I was able to get it up and running with the following overlay

    // To get started, press Ctrl+Space to bring up the completion menu and view the available nodes.
    
    // You can also use the buttons in the sidebar to perform actions on nodes.
    // Actions currently available include:
    
    // * Enabling / disabling the node
    // * Adding the bus to a bus
    // * Removing the node
    // * Connecting ADC channels
    
    // For more help, browse the DeviceTree documentation at https://docs.zephyrproject.org/latest/guides/dts/index.html
    // You can also visit the nRF DeviceTree extension documentation at https://docs.nordicsemi.com/bundle/nrf-connect-vscode/page/guides/ncs_configure_app.html#devicetree-support-in-the-extension
    &pinctrl {
        spi_master_default: spi_master_default {
            
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 2, 6)>,
                        <NRF_PSEL(SPIM_MOSI, 2, 8)>,
                        <NRF_PSEL(SPIM_MISO, 2, 9)>;
            };
        };
    
        spi_master_sleep: spi_master_sleep {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 2, 6)>,
                        <NRF_PSEL(SPIM_MOSI, 2, 8)>,
                        <NRF_PSEL(SPIM_MISO, 2, 9)>;
                low-power-enable;
            };
        };
    
        spi_slave_default: spi_slave_default {
            group1 {
                psels = <NRF_PSEL(SPIS_CSN, 1, 13)>,
                        <NRF_PSEL(SPIS_MOSI, 1, 0)>,
                        <NRF_PSEL(SPIS_MISO, 1, 4)>,
                        <NRF_PSEL(SPIS_SCK, 1, 11)>;
            };
        };
    
        spi_slave_sleep: spi_slave_sleep {
            group1 {
                psels = <NRF_PSEL(SPIS_CSN, 1, 13)>,
                        <NRF_PSEL(SPIS_MOSI, 1, 0)>,
                        <NRF_PSEL(SPIS_MISO, 1, 4)>,
                        <NRF_PSEL(SPIS_SCK, 1, 11)>;
                low-power-enable;
            };
        };
    };
    
    my_spi_master: &spi00 {
        compatible = "nordic,nrf-spim";
        status = "okay";
        pinctrl-0 = <&spi_master_default>;
        pinctrl-1 = <&spi_master_sleep>;
        pinctrl-names = "default", "sleep";
        cs-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
        /delete-node/ mx25r64;
        reg_my_spi_master: spi-dev-a@0 {
            reg = <0>;
            
        };
    };
    
    my_spi_slave: &spi20 {
        compatible = "nordic,nrf-spis";
        status = "okay";
        pinctrl-0 = <&spi_slave_default>;
        pinctrl-1 = <&spi_slave_sleep>;
        pinctrl-names = "default", "sleep";
        def-char = <0x00>;
        /delete-property/ rx-delay;
        /delete-property/ rx-delay-supported;
    };
    
    &uart20 {
        status = "disabled";
    };
    
    
    

    Note I had to disable uart20 as it uses some of the same pins, so I printed out the data over RTT. To output the data over RTT add the following Kconfig. I selected nrf52840 as target for RTT to see any text

    CONFIG_USE_SEGGER_RTT=y
    CONFIG_LOG=y
    CONFIG_LOG_BACKEND_RTT=y
    
    CONFIG_RTT_CONSOLE=y
    CONFIG_UART_CONSOLE=n

    Regards

    Runar

  • Thanks, I managed to get it works on nrf54l15. I thought that the small letters meant that defining the pins in the DT was enough, I guess not.
    This will help a lot.
    By the way, on the many examples I've seen, people were using nrfx drivers to get interrupts event for the slave part (to fill the buffer or call transceive function for example). 
    Does the new API have a similar system ? 
    I've understood that EasyDMA can access to the registers pretty easily if the master sends something but it's still quite blury on how to fill the exact register or access to the good part of the memory.
    I've thought on using kevent() on some events raised by the SPI transfer that I've seen on the datasheet. Any thoughts on this ? Thanks again for the help so far !
    Regards,

    Hugo

  • Hi Hugo,

    Good to know that the issue regarding spsi on nrf54l15 is resolved.

    Runar is away, and I did not get your question fully.

    If that is unrelated or different from the main query, may I ask you to create a new ticket for that.

    If your query is regarding the use of zephyr spi api, then we do have lesson on zephyr+ncs on devacademy.

    Thank you and regards,

    Naeem

Reply Children
No Data
Related