Shoud I set PM_DEVICE_ACTION_SUSPEND on I2C0 before sys_poweroff() ?

Dear Sir :

              We are now developing on nrf52840, with ncs v2.6.1 and zephyr.

We want to put I2C0 to PM_DEVICE_ACTION_SUSPEND before sys_poweroff().

Our code is below :

const struct device *const i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c0));

int rc = pm_device_action_run(i2c_dev, PM_DEVICE_ACTION_SUSPEND);

if (rc < 0) {
   printf("Could not suspend I2C (%d)\n", rc);
   return 0;
}

sys_poweroff();

But it always return "Could not suspend I2C (-120)".

Our I2C connects to an EEPROM and all read/write operations work fine.

We had search Nordic Q&A and someone said: only UART is not handled when using sys_poweroff(), others are handled automatically.

Does it mean that it is not necessary to put I2C to PM_DEVICE_ACTION_SUSPEND, becasue sys_poweroff will turn off I2C automatically?

Just run sys_poweroff() directly is enough or not?

Device tree overlay for reference :


&i2c0 {
compatible = "nordic,nrf-twim";
status = "okay";
clock-frequency = <100000>;
pinctrl-0 = <&i2c0_default>;
pinctrl-1 = <&i2c0_sleep>;
zephyr,concat-buf-size = <64>;
zephyr,flash-buf-max-size = <64>;

};

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

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

Parents
  • Hello,  I think the error code -120 you are receiving when trying to suspend the I2C device indicates that the suspend action failed. This might be due to various reasons such as incorrect configuration or conflicts with other operations.
    While some peripherals might be automatically handled during system shutdown, it's still recommended to properly manage the power state of peripherals like I2C to ensure data integrity and proper power management.

    I think you should test both scenarios - with and without explicitly suspending I2C - to see if there are any differences in power consumption or behavior during system shutdown.
    Code Modification:

    c
    const struct device *const i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c0));
    
    int rc = pm_device_state_set(i2c_dev, PM_DEVICE_STATE_SUSPEND);
    
    if (rc < 0) {
    printf("Could not suspend I2C (%d)\n", rc);
    return 0;
    }
    
    sys_poweroff();


    By explicitly suspending the I2C device before calling sys_poweroff(), you ensure that the I2C peripheral is properly handled before system shutdown. This aligns with best practices for power management and can help avoid potential issues related to data integrity or power consumption.

  • Hi! 

    Thanks for your suggestion. 

    We copy paste your code , but build failed. 

    Error Message : undefined reference to `pm_device_state_set'

    Mabye we need another include file, so we add

    #include <zephyr/pm/pm.h>

    but not works, still get error message undefined reference to `pm_device_state_set' when build code.

    VS code IDE intellisense list all functions starts with "pm_device_state", but only "pm_device_state_get" found, no "pm_device_state_set".

    And we find out that, set 

    CONFIG_PM_DEVICE_RUNTIME=y

    makes rc always return -120 in the following code.

    int rc = pm_device_action_run(i2c_dev, PM_DEVICE_ACTION_SUSPEND);

    After change "CONFIG_PM_DEVICE_RUNTIME=n " to "n", then return value rc become 0, and PM_DEVICE_ACTION_SUSPEND successed.

     

    Does set "CONFIG_PM_DEVICE_RUNTIME" to "n" has any disadvantage ?

Reply
  • Hi! 

    Thanks for your suggestion. 

    We copy paste your code , but build failed. 

    Error Message : undefined reference to `pm_device_state_set'

    Mabye we need another include file, so we add

    #include <zephyr/pm/pm.h>

    but not works, still get error message undefined reference to `pm_device_state_set' when build code.

    VS code IDE intellisense list all functions starts with "pm_device_state", but only "pm_device_state_get" found, no "pm_device_state_set".

    And we find out that, set 

    CONFIG_PM_DEVICE_RUNTIME=y

    makes rc always return -120 in the following code.

    int rc = pm_device_action_run(i2c_dev, PM_DEVICE_ACTION_SUSPEND);

    After change "CONFIG_PM_DEVICE_RUNTIME=n " to "n", then return value rc become 0, and PM_DEVICE_ACTION_SUSPEND successed.

     

    Does set "CONFIG_PM_DEVICE_RUNTIME" to "n" has any disadvantage ?

Children
No Data
Related