Initializing SPI and TWI drivers on Zephyr

Hi

Followup on this ticket: Enabling SPI and TWI drivers on Zephyr

First the fundamentals, I am using:

  • nRF52840-DK
  • nRF Connect for VS Code: v2024.7.13
  • nRF Connect Ver. 2.5.1

I am trying to create a demonstration project, where I need both SPI and TWI/I2C.

My project now compiles and runs, however I cot some issues.

The SPI is working fine. During initialization I call the nrfx_spim_init to setup the driver and assign the pins to the peripheral. It works. 

But when initilalizing the I2C with the nrfx_twim_init function it returns an error code NRF_WRONG_STATE. It appers that the driver is already initialized during the Zephyr init. (Called from bg_thread_main)

It could be OK that the driver is initialized by Zephyr, I believe that it is the preffered war to do it. But only if it is done properly. By setting a breakpoint in nrfx_spim_init I see that neither the pin configuration nor the speed is set according to the devicetree overlay file I have written.  But how do I do this correctly? 

Right now my overlay file looks like this, but I have tried a lot of things. With no change in behavior at all.

&spi1 {
    status = "okay";
    compatible = "nordic,nrf-spim";
    pinctrl-0 = <&spi1_default>;    
};


&i2c0 {
    status = "okay";
    compatible = "nordic,nrf-twim";
    pinctrl-0 = <&i2c0_tempDEF>;
    pinctrl-1 = <&i2c0_tempSLP>;
    pinctrl-names = "default", "sleep";
    clock-frequency = <100000>;
};

&pinctrl{
    i2c0_tempDEF: i2c0_tempDEF {
        group1 {
            psels = <NRF_PSEL(TWIM_SDA, 0, 26)>,
                <NRF_PSEL(TWIM_SCL, 0, 27)>;
        };
    };

    i2c0_tempSLP: i2c0_tempSLP {
        group1 {
            psels = <NRF_PSEL(TWIM_SDA, 0, 26)>,
                <NRF_PSEL(TWIM_SCL, 0, 27)>;
            low-power-enable;
        };
    };
};

Using the default configuration gives the same result. No matter what: speed is set to 100000 and SCL is set to 0 and SDA is set to 0. So it will never work.

How do I control the initialization from Zephyr?

Or can I disable the I2C initialization from Zephyr and do it my self, which I originally tried to do?

By the way: I tried to omit the i2c0 section in the overlay file to verify that it was read. And it was, as the project did not compile with out it. 

Any help would be appreciated.

Kasper

Parents
  • I just realized that there are two categories of peripheral drivers.

    1. Zephyr devicetree drivers. (Included by e.g. #include <zephyr/drivers/i2c.h>)
    2. Zephyr independent drivers. (Included by e.g #include <nrfx_twim.h>

    All the peripheral examples seems to be using "Zephyr independent drivers.", so there is no help here if you want to use the Zephyr Devicetree.

    Is this correct?

  • That is also my understanding.  The idea with the Zephyr devicetree drivers is that you can port your code to another processor easy.  Which I think is kind of crazy in the embedded space, but that is what the Zephyr creators dream of.  

    The thing that might help is looking at the zephyr driver source code, this help me once I understood that device trees just create a header file.  The driver source code should help you understand the zephyr drivers better.  


Reply
  • That is also my understanding.  The idea with the Zephyr devicetree drivers is that you can port your code to another processor easy.  Which I think is kind of crazy in the embedded space, but that is what the Zephyr creators dream of.  

    The thing that might help is looking at the zephyr driver source code, this help me once I understood that device trees just create a header file.  The driver source code should help you understand the zephyr drivers better.  


Children
No Data
Related