nPM2100 - break-to-wake

Hello everyone,

We are currently working on a project that uses the nPM2100 to power an nRF52840. Our application requires automatic enabling break-to-wake mode each time the SHPHLD pin is shorted (power switch based on the state of the SHPHLD pin)

At the moment, in our firmware (NCS 3.2.3), we are able to configure the controller through the overlay, but we do not see any way to enable this mode.

npm2100_pmic: pmic@74 {
    compatible = "nordic,npm2100";
    reg = <0x74>;


    shiphold-longpress = "ship";
    // shiphold-current = "low";
    // shiphold-hibernate-wakeup;

    npm2100_gpio: gpio-controller {
        compatible = "nordic,npm2100-gpio";
        gpio-controller;
        #gpio-cells = <2>;
        ngpios = <2>;
    };

    npm2100_regulators: regulators {
        compatible = "nordic,npm2100-regulator";

        npm2100_boost: BOOST {
            regulator-always-on;
            regulator-min-microvolt = <1800000>;
            regulator-max-microvolt = <3300000>;

            regulator-init-microvolt = <3300000>;
            regulator-init-microamp = <300000>;
            regulator-initial-mode = <(NPM2100_REG_OPER_AUTO | NPM2100_REG_FORCE_PASS)>;
            mode-gpios = <&npm2100_gpio 0 (GPIO_ACTIVE_LOW  | GPIO_PULL_DOWN | NPM2100_GPIO_DEBOUNCE_OFF)>;
        };


        npm2100_ldosw: LDOSW {
            regulator-min-microvolt = <800000>;
            regulator-max-microvolt = <3000000>;




            regulator-initial-mode = <(NPM2100_REG_OPER_ULP | NPM2100_REG_LDSW_EN)>;
            mode-gpios = <&npm2100_gpio 0 (GPIO_ACTIVE_HIGH  | GPIO_PULL_DOWN | NPM2100_GPIO_DEBOUNCE_OFF)>;
        };

    };

    npm2100_wdt: watchdog {
        compatible = "nordic,npm2100-wdt";
    };

    npm2100_vbat: vbat {
        compatible = "nordic,npm2100-vbat";
    };
};

Is it possible to configure break-to-wake mode using only the devicetree? I reviewed the driver itself and found options such as:

// shiphold-flags = <x>;
// shiphold-current = "low";
// shiphold-hibernate-wakeup;

Unfortunately, these do not seem to allow switching the mode itself.

If not, is there any example code available that enables it over I2C from the microcontroller? If I understand it correctly, I could use a callback from the SHPHLD pin and manually put the controller into break-to-wake mode.

Thank you in advance for any help. Perhaps someone has run into the same problem and managed to solve it.

Best regards,

Paweł

  • Hello,

    I’m not 100% sure, but I think break-to-wake cannot be configured using only the devicetree. The DT options like shiphold-flags and shiphold-current seem to configure the default SHPHLD behavior (such as pull-up and polarity), but they do not actually switch the PMIC into that mode. See SHPHLD register and  WAKEUP register

    Entering break-to-wake requires a runtime step, where the firmware ensures that SHPHLD is in the correct state and then writes to TASKS_SHIP over I2C. Based on this, your approach seems correct, you would need to handle this in firmware, for example by reacting to the SHPHLD pin or your switch logic and then triggering Ship mode manually.  See Ship and break to wake mode

    Kind Regards,

    Abhijith

  • Thank you for your reply. I had read that section of the documentation, but I was hoping there would be some configuration option.

    Today I worked on enabling this mode manually, and I managed to do it by writing the following values to the registers:

    SHPHLD -> 0x15
    WAKEUP -> 0x01
    TASKS_SHIP -> 0x01

    According to the documentation, I should have set SHPHLD to the option “No resistor” | “Low pull-up current”, but unfortunately that did not allow the PMIC to wake up. The “Weak pull-up enabled” option helped.

    dtsi:

    npm2100_pmic: pmic@74 {
            compatible = "nordic,npm2100";
            reg = <0x74>;
    
            shiphold-longpress = "disable";
    
            //shiphold-flags = <5>;
            //shiphold-current = "low";
            //shiphold-hibernate-wakeup;
    
            npm2100_gpio: gpio-controller {
                compatible = "nordic,npm2100-gpio";
                gpio-controller;
                #gpio-cells = <2>;
                ngpios = <2>;
            };
    
            npm2100_regulators: regulators {
                compatible = "nordic,npm2100-regulator";
    
                npm2100_boost: BOOST {
                    regulator-always-on;
                    regulator-min-microvolt = <1800000>;
                    regulator-max-microvolt = <3300000>;
    
    
                    regulator-init-microvolt = <1800000>;
                    regulator-init-microamp = <300000>;
                    
                    
                };
    
    
                npm2100_ldosw: LDOSW {
                    regulator-min-microvolt = <800000>;
                    regulator-max-microvolt = <3000000>;
     
                    
                    
                    
                    regulator-initial-mode = <(NPM2100_REG_OPER_AUTO | NPM2100_REG_LDSW_EN)>;
                    mode-gpios = <&npm2100_gpio 0 (GPIO_ACTIVE_HIGH  | GPIO_PULL_DOWN | NPM2100_GPIO_DEBOUNCE_OFF)>;
                };
    
            };
    
            npm2100_wdt: watchdog {
                compatible = "nordic,npm2100-wdt";
            };
    
            npm2100_vbat: vbat {
                compatible = "nordic,npm2100-vbat";
            };
       };

    I have not checked the current consumption in this configuration yet, but functionally it works as expected.

    Best Regards,

    Paweł

  • Hello,

    s it possible to configure break-to-wake mode using only the devicetree?

    Not fully, no, the application is still responsible for detecting the falling edge of the SHPHLD pin.
    For the Devicetree configuration, the recommendation is to:

     shiphold-flags = <(GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>;
        shiphold-longpress = "disable";
        shiphold-current = "weak";

    • GPIO_ACTIVE_HIGH instructs the PMIC to wake up on rising edge (when the short b/w SHPHLD and GND is removed)
    • GPIO_PULL_UP keeps the SHPHLD pin pulled up during the active state, so that the app can detect the falling edge on shortening
    • shiphold-longpress = "disable"; disables the "power off" functionality of the SHPHLD pin
    • shiphold-current = "weak"; can be adjusted according to the  needs with "weak" meaning the lowest possible quiescent current during ship mode

    As for the application, the best way would be to set up an interrupt on SHPHLD falling edge with a handler to enter ship mode (if there is a PMIC GPIO to spare) using the MFD driver. Otherwise the current SHPHLD state is available in the MAIN.STATUS register.

    Kind Regards,

    Abhijith

  • Hello,

    I can confirm that with this configuration in the DT file, it works the same way. At the moment, apart from this configuration, I only use the command to switch to ship mode.

    Thank you once again for your replies :)

    Best regards,
    Paweł

Related