1

On a Pi 4 I have the following lines in /boot/config.txt:

dtoverlay=w1-gpio
gpio=4=op,pu

This should enable 1-wire on the default GPIO pin, which is 4, and then enable the internal pullup resistor.

The 1-wire device that I have is a DS18B20, and it's connected via a short cable with external power. No external pullup resistor is attached (e.g. 4.7k resistor.) Parasitic power is therefore not in use. This is a correctly functioning hardware configuration.

However the following command is required after boot in order to enable the internal pullup:

raspi-gpio set 4 pu

After which, everything works as expected.

Before that command is executed, various phantom devices periodically appear in scans as shown by dmesg:

[   60.240219] w1_master_driver w1_bus_master1: Attaching one wire slave 00.800000000000 crc 8c
[   60.254632] w1_master_driver w1_bus_master1: Family 0 for 00.800000000000.8c is not registered.

In addition the pullup appears as disabled.

The 1-wire device works correctly with the internal pullup, but I haven't been able to configure the pullup on boot. I have tried some minor variations with no success. It seems like a band-aid solution to create a systemd unit just to set GPIO pins after boot, but that may be my only option. Is there something I can do with the device tree or GPIO boot option to obtain the expected behavior?

8
  • GPIO4 defaults to pull-up enabled at boot. Please explain your wiring of the DS18B20. It sounds like you have done something wrong.
    – joan
    Oct 11, 2022 at 20:03
  • Considering adding an appropriate pull up resistor. Later when it is intermittent you will wish you had. Yes you can have both internal and external pull ups as long as they pull up to the same voltage.
    – Gil
    Oct 11, 2022 at 22:14
  • The GPIO4 pull-up isn't enabled on boot. That's what this question is about. Same problem here: forums.raspberrypi.com/viewtopic.php?t=288396
    – okw
    Oct 12, 2022 at 2:36
  • Here's a dump from a fresh reboot: $ raspi-gpio get BANK0 (GPIO 0 to 27): GPIO 0: level=1 fsel=0 func=INPUT pull=UP GPIO 1: level=1 fsel=0 func=INPUT pull=UP GPIO 2: level=1 fsel=4 alt=0 func=SDA1 pull=UP GPIO 3: level=1 fsel=4 alt=0 func=SCL1 pull=UP GPIO 4: level=0 fsel=0 func=INPUT pull=NONE
    – okw
    Oct 12, 2022 at 2:46
  • The GPIO4 pull-up IS ENABLED at boot. It's made quite clear in the post you link.
    – joan
    Oct 12, 2022 at 9:19

1 Answer 1

2

To resolve this minor issue, you need to create a modified devicetree source file. The gpio directive in /boot/config.txt is overridden by devicetree overlays and the default w1-gpio overlay doesn't expose a configurable pullup. As a quick fix I used w1-gpio-overlay.dts from the Linux 5.15.61 source tree and modified the brcm,pull value, and named it w1-gpio-internal-pullup.dts as follows:

// Definitions for w1-gpio module (with internal pullup)
/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2835";

        fragment@0 {
                target-path = "/";
                __overlay__ {

                        w1: onewire@0 {
                                compatible = "w1-gpio";
                                pinctrl-names = "default";
                                pinctrl-0 = <&w1_pins>;
                                gpios = <&gpio 4 0>;
                                status = "okay";
                        };
                };
        };

        fragment@1 {
                target = <&gpio>;
                __overlay__ {
                        w1_pins: w1_pins@0 {
                                brcm,pins = <4>;
                                brcm,function = <0>; // in (initially)
                                brcm,pull = <2>; // up
                        };
                };
        };

        __overrides__ {
                gpiopin =       <&w1>,"gpios:4",
                                <&w1>,"reg:0",
                                <&w1_pins>,"brcm,pins:0",
                                <&w1_pins>,"reg:0";
                pullup;         // Silently ignore unneeded parameter
        };
};

Then I compiled it:

$ dtc -@ -H epapr -O dtb -o w1-gpio-internal-pullup.dtbo -Wno-unit_address_vs_reg w1-gpio-internal-pullup.dts

Then I placed it into the boot partition filesystem:

$ sudo cp w1-gpio-internal-pullup.dtbo /boot/overlays/

Finally, I modified /boot/config.txt so that the only line relating to 1-wire was:

dtoverlay=w1-gpio-internal-pullup

Then reboot:

$ sudo systemctl reboot

Verifying correct operation:

$ dmesg | grep -i w1
[    8.181482] w1_master_driver w1_bus_master1: Attaching one wire slave 28.3ccef649d5a0 crc 94
$ cat /sys/devices/w1_bus_master1/28-3ccef649d5a0/temperature
25875
$ cat /sys/devices/w1_bus_master1/28-3ccef649d5a0/resolution
12
$ cat /sys/devices/w1_bus_master1/28-3ccef649d5a0/ext_power
1

As others have noted, operating in this way does not guarantee stability from an electrical standpoint. However you may find that it works for certain devices, that are externally powered, over extremely short lengths of cable. In brief testing it comes up even with "some" amount of electrical interference being generated nearby, however this isn't a rigorous test and shouldn't be relied upon unless you know what you are doing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.