Devicetree: SPI device

Hello,

I wanted to create an SPI shell, similar to what is available for I²C.
I am therefore trying to create a generic SPI device in the devicetree:

sensor_spi: &spi1 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	pinctrl-0 = <&spi1_default_alt>;
	pinctrl-1 = <&spi1_sleep_alt>;
	pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
	spi_sensor: spi-device@0 {
		compatible = "spi-device";
		reg = <0>;
		spi-max-frequency = <10000000>;
		label = "SPI dummy";
	};
};

flash_spi: &spi3 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	pinctrl-0 = <&spi3_default_alt>;
	pinctrl-1 = <&spi3_sleep_alt>;
	pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
	mx25r64: mx25r6435f@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <80000000>;
		label = "MX25R64";
		jedec-id = [c2 28 17];
		size = <67108864>;
	};
};

Somehow I am not able to access the label "spi_sensor":

static struct spi_config config = {
	.frequency = DT_PROP(DT_NODELABEL(spi_sensor), spi_max_frequency),

devicetree_unfixed.h:12312:35: error: 'DT_N_S_soc_S_peripheral_40000000_S_spi_9000_S_spi_device_0_P_spi_max_frequency' undeclared here (not in a function); did you mean 'DT_N_S_soc_S_peripheral_40000000_S_spi_b000_S_mx25r6435f_0_P_spi_max_frequency'?

If I change the label to "mx25r64" it is working, although both entries are almost the same.

I have the feeling that using compatible = "spi-device"; is somehow not permitted, but I don't really understand why, also I wasn't able to find a better 'generic device'.

Could you give me some hint why it is not working?

Thank you!

  • Hi,

    You are correct that you cannot use compatible = "spi-device"; directly. If you want to create your custom SPI device and not use an existing one, you must create bindings for it. Typically the compatible property is on the form "company,device". I will use "company-name" here.

    What you must to is to create a binding file for the device. The binding file must be located inside the dts/bindings subdirectory of your chosen location (application directory, board directory, module directory, etc.). In the example of company-name and spi-device, the name of the file will be "company-name,spi-device.yaml". Here you see an example file structure:

    my_app
     |___ src
     |___ prj.conf
     |___ CMakeLists.txt
     |___ dts
           |___ bindings
                |___ company-name,spi-device.yaml

    If you do not want to add anything extra to the SPI device, then all you need to add to company-name,spi-device.yaml is the following:

    description: Company-name SPI device
    
    compatible: "company-name,spi-device"
    
    include: spi-device.yaml

    Then you must change the compatible property in your overlay file:

    compatible = "company-name,spi-device";

    Best regards,

    Marte

  • It seems I still have problems with SPI and the devicetree.

    I want to use SPI1 and SPI3, each of them is working fine but if I include them both together in the devicetree than the application is not starting up and just keeps reseting at startup.

    flash_spi: &spi1 {
    	compatible = "nordic,nrf-spim";
    	status = "okay";
    	pinctrl-0 = <&spi1_default_alt>;
    	pinctrl-1 = <&spi1_sleep_alt>;
    	pinctrl-names = "default", "sleep";
    	cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
    	mx25r64: mx25r6435f@0 {
    		compatible = "jedec,spi-nor";
    		reg = <0>;
    		spi-max-frequency = <80000000>;
    		label = "MX25R64";
    		jedec-id = [c2 28 17];
    		size = <67108864>;        // 0x4000000
    	};
    	
    };
    
    sensor_spi: &spi3 {                         // do not use spi0 or spi2, as is has shared resources (with uart0, i2c2)
    	compatible = "nordic,nrf-spim";
    	status = "okay";
    	pinctrl-0 = <&spi3_default_alt>;
    	pinctrl-1 = <&spi3_sleep_alt>;
    	pinctrl-names = "default", "sleep";
    	cs-gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
     	spi_sensor: spi-device@0 {
    		compatible = "undock,spi-device";
    		reg = <0>;
    		spi-max-frequency = <10000000>;
    		label = "SPI dummy";
    	};
    };

    Any ideas on that topic?

    Thank you a lot!

  • Hi,

    You need to make sure that UART1/SPI1 is not taken by TF-M. However, I do not see how that should cause it to reset only when both SPI1 and SPI3 are used. Which pins are you using for SPI1 and SPI3?

    Best regards,

    Marte

Related