This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to enter System ON sleep in zephyr

Hi,
I wanna enter the system on sleep to save the power up to 10uA(about tens of A). I am using nrf52840-dk with SPI LCD and some GPIOs in zephyr. Also I want to do DEVICE_POWER_MANAGEMENT. I can turn off the power of LCD when calls device_set_power_state with DEVICE_PM_SUSPEND_STATE, but if I call the device_set_power_state(data->spi_dev, DEVICE_PM_SUSPEND_STATE, NULL, NULL) in lcd driver, i got the os error. Is there any special way to enter/wake system on sleep safely?

Parents
  • I found that Zephyr doesn't support the SLEEP state for nrf52.
    These are the supported SoC list for SYS_POWER_STATE_SLEEP_1 in zephyr.

    SOC_SERIES_EFM32GG11B
    SOC_SERIES_EFM32JG12B
    SOC_SERIES_EFM32PG12B
    SOC_SERIES_EFR32BG13P
    SOC_SERIES_EFR32FG1P
    SOC_SERIES_EFR32MG12P
    SOC_SERIES_EFR32MG21
    SOC_SERIES_STM32L4X
    SOC_SERIES_STM32WBX
    SOC_SERIES_CC13X2_CC26X2

    I am weird how to enter sleep mode in nrf52840. I saw the function _sys_suspend(), but have no idea.

  • You dont need to do anything to put the nRF52840 into System ON sleep, this will happen by default. Take a look at System Threads in the Zephyr documentation and read about the idle thread:

    "If possible, the idle thread activates the board’s power management support to save power"

    The idle thread has the lowest priority and will run when nothing else is happening. Just make sure you're not using a loop in main(), or calling k_cpu_idle() directly (read this text). The idle thread will put the system to sleep here.

    Bes regards,

    Simon

  • Thanks, Simon
    I got the correct intend from you. I really didn't understand that I haven't to use the main loop to save power. After created a thread for me, I've checked that the idle thread is working.

    Followed question: I am using the SPI LCD on my board and want to sleep or power off the SPI if needed. I thought it can be called device_set_power_state(dev->spi_dev, DEVICE_PM_OFF_STATE, NULL, NULL) in display_lcdname.c. But I got the OS thread error. Do you have any idea to power off/on the SPI safely in the LCD driver? or any special way(example)?

    Best regards.

  • You could use the Nordic layer directly. If you look inside the driver zephyr\drivers\spi\spi_nrfx_spim.c and in the case DEVICE_PM_OFF_STATE, the following will happen:

    static int spim_nrfx_pm_control(struct device *dev, u32_t ctrl_command,
    				void *context, device_pm_cb cb, void *arg)
    {
        .
        .
        if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
            .
            .
            case DEVICE_PM_OFF_STATE:
    				if (data->pm_state == DEVICE_PM_ACTIVE_STATE) {
    					nrfx_spim_uninit(&config->spim);
    				}
    				break;
        .
        .
    }

    Try calling nrfx_spim_uninit directly. If you're using nordic,nrf-spi instead of nordic,nrf-spim in the overlay file, call spi_nrfx_pm_control(..) instead.

    Best regards,

    Simon

Reply
  • You could use the Nordic layer directly. If you look inside the driver zephyr\drivers\spi\spi_nrfx_spim.c and in the case DEVICE_PM_OFF_STATE, the following will happen:

    static int spim_nrfx_pm_control(struct device *dev, u32_t ctrl_command,
    				void *context, device_pm_cb cb, void *arg)
    {
        .
        .
        if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
            .
            .
            case DEVICE_PM_OFF_STATE:
    				if (data->pm_state == DEVICE_PM_ACTIVE_STATE) {
    					nrfx_spim_uninit(&config->spim);
    				}
    				break;
        .
        .
    }

    Try calling nrfx_spim_uninit directly. If you're using nordic,nrf-spi instead of nordic,nrf-spim in the overlay file, call spi_nrfx_pm_control(..) instead.

    Best regards,

    Simon

Children
Related