w1 device works but device_is_ready(w1_dev) always returns false.

I'm porting code from Zepyr 3.5 to 3.7 and am having errors in my ds2484 1-wire device. It was working fine but now reports an init error unless I add deferred-init into my dts file and device_is_ready(w1) always returns false.

The 1
-wire bus actually works fine and reads good data but will never return ready. Any ideas on what to look for?

myboard.dts
&i2c1 {
   w1a: w1@18 {
   status = "okay";
   compatible = "maxim,ds2484";
   reg = <0x18>;
   active-pullup;
   zephyr,deferred-init;
};

failing code snip

static const struct device *const w1_dev = DEVICE_DT_GET(DT_NODELABEL(w1a));
while (!device_is_ready(w1_dev)) { 
     LOG_ERR("1Wire device \"%s\" is not ready (line %i)", w1_dev->name, __LINE__);
     k_msleep(250);
}

  • Hello,

    Could you try removing zephyr,deferred-init and check if device_is_ready() returns true? This will help determine if deferred initialization is the root cause of the issue. Additionally, please check the log, as it may contain an error message explaining why the device is still not ready.

    Kind regards,
    Abhijith

  • I only added the deferred-init as part of my debugging. It does not affect the device_is_ready*() and returns an error when it tries to initialize the bus.

    [00:00:00.254,699] <err> ds2484: Device reset failed: -5
    *** Booting SM-IOT-GEN5 v0.1.16-wip-e6d5aab19ef9 ***
    *** Using nRF Connect SDK v2.7.0-5cb85570ca43 ***
    *** Using Zephyr OS v3.6.99-100befc70c74 ***

  • This reminded me that I do have a GPIO power control on the 1Wire power segment that includes the DS2484. Checking with a scope and the power is not turned on so that is my issue!
    I didn't change anything in my device tree but i did not explicitly turn it on before so I might just have gotten lucky.

    I added this pin to my board.c as described in  Zephyr GPIO initialization before HW drivers to turn on the GPIO before driver load and the errors went away.
    I don't want to turn on the power that early so I now explicitly turn it on before init and off after init and it works as well.  Note that this required leaving deferred-init enabled. If I let it try and initialize early and then re-initialize once power was on it fails.

    In case it helps others. here is my code segment

    if(!device_is_ready(sensor_ctrl.port) ||
    gpio_pin_configure_dt(&sensor_ctrl, GPIO_OUTPUT_ACTIVE) ||
    gpio_pin_set_dt(&sensor_ctrl, 1)) {
    LOG_ERR("Unable to Initialize 1W power control GPIO");
    err = -1;
    }

    k_msleep(3);
    if(device_init(w1_dev) || !device_is_ready(w1_dev)) {
    LOG_ERR("1Wire device \"%s\" not found or not ready (line %i)", w1_dev->name, __LINE__);
    err = -1;
    }
    k_msleep(1);
    gpio_pin_set_dt(&sensor_ctrl, 0); // turn 1W power off to save battery

    This issue can be closed. Thanks for your help.

  • Hello,

    Glad to hear that your issue has been resolved.

    Kind Regards,

    Abhijith

Related