Making some headway with Zephyr, but I’ve run up against something I don’t quite understand. I’m adding an I2C multiplexer (TCA9548) to my board to switch between a few of the same sensor. I see the device binding for this component already exists (yay?) but I don’t see a driver for it anywhere. I can talk to it just using the I2C device successfully, but there is a problem. The drivers for my sensor exist, and when I add the sensor to my overlay, Zephyr tries to communicate with it during initialization - however, since the mux isn’t in the overlay (since there is no driver) none of the sensor channels are open (it hasn’t been initialized yet) so they aren’t initialized and they aren’t found later when I try to use them.

This seems to leave me with two possible routes. The first is just to take the sensor out of the overlay and use it as a raw I2C device, writing my own driver for it. Not bad, but messy. The second is to figure out how to get the system to initialize the mux first so that the sensor(s) are found during initialization. Could anyone give me some advice for getting this going?

There is a chance that there is already some way to do this since the device binding exists and I just don’t understand what I should be looking for.

    TrivialSolution ahh this is tricky. If you look deep into the driver implementation, you’ll eventually come across DEVICE_DT_INST_DEFINE

    	DEVICE_DT_INST_DEFINE(inst,					\
    			    lis2dh_init,				\
    			    NULL,					\
    			    &lis2dh_data_##inst,			\
    			    &lis2dh_config_##inst,			\
    			    POST_KERNEL,				\
    			    CONFIG_SENSOR_INIT_PRIORITY,		\
    			    &lis2dh_driver_api);

    It basically sets the init function above to run at CONFIG_SENSOR_INIT_PRIORITY. So depending on your drivers and what their priorities are, you can set your own init function wherever in your code. Make sure that it’s initialized with a higher priority. That way it will be done before you try to talk to any of your other drivers.

    I’ll try to do a live session on this tomorrow since it’s an important topic.

    Hope that helps!

      jaredwolff Funny, I just was editing my post to talk about this. So I’ll add it here instead.

      I have been trying to build my own driver similar to the PCF85063A driver you have in the nfed. It’s all pretty straightforward I think (probably not :-P). My idea is to set its priority to something like PRE_KERNEL_2 since my sensor is POST_KERNEL and it will initialize the mux first, but I’m happy for any tips or corrections.

      My bigger issue is that I don’t see any __subsystem APIs that seem appropriate for the device. The device only has one register, so you send a write to the address then set the one byte register, or you send a read to the address and it sends back the one byte register. That’s it. The API sounds like it should just be something like

      __subsystem struct some_api {
        some_api_set set;
        some_api_get get;
      };

      but I’m not seeing one that looks like this. Any ideas? Is there some way to make your own API? Do I just make it up myself then pass the pointer to DEVICE_DT_INST_DEFINE and I’m all set?

        You can also try

        SYS_INIT(your_init_function, POST_KERNEL, CONFIG_YOUR_PRIORITY);

        Which does the same thing but doesn’t tie you to a specific device API.

        Terms and Conditions | Privacy Policy