while using k_sleep(K_FOREVER) for deep sleep mode, system is not waking up

Implementing deep sleep in nRF54L15

Using sys_poweroff()

System gets reset upon wake up by button press


Using k_sleep(K_FOREVER)

System is not waking up by button press


Is there any other way to implement deep sleep?
---------------------------- Or else ----------------------------------------------------------------------
Is there any wakeup concept that would help to wake up the system?

Below I have attached gatt write code using deep sleep, check & tell what's wrong in deep sleep (k_sleep(K_FOREVER) & wake up buttondeep_sleep.zip

  • Can you please try this project as a template and do measurements to see if you get the same as that github project_ If yes, then start to take its logic for idling into your projects.

  •  I don't want the system to get reset / restart while waking up from deep sleep. I want that it should continue the operation while waking up without resetting the code

  • Hello,

    In your project, your system is entering the wakeup_handler you defined, your console is just suspended when you re-enter, so you aren't seeing the print statements.

    If you move your ptr for cons to a larger scope and run pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME) in your wakeup handler, you'll see the printfs in that callback. You'll also probably want to change how you configure the interrupt unless you want that callback to fire for the duration you hold down the button.

    There are varying power consumption levels depending on how you configure the wake-up pins as well, you can find more details in the btnsleep and btnsleep_5340 branches. Your sleep also plays a factor, whether your system is actually off and how much memory you retain. https://docs.nordicsemi.com/bundle/ps_nrf54L15/page/chapters/current_consumption/doc/current_consumption.html#ariaid-title3

     

    I modified your overlay and main application to have it go to sleep when you press the sleep buttons, wake when you press the wake buttons.

    main.c

    #include <stdio.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/kernel.h>
    #include <zephyr/pm/device.h>
    #include <zephyr/sys/poweroff.h>
    #include <zephyr/sys/util.h>
    
    #if defined(CONFIG_GPIO_WAKEUP_ENABLE)
    static const struct gpio_dt_spec buttons[] = {
        GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios), // Button 0 - deep sleep
        GPIO_DT_SPEC_GET(DT_ALIAS(sw1), gpios), // Button 1 - deep sleep
        GPIO_DT_SPEC_GET(DT_ALIAS(sw2), gpios), // Button 2 - wake up
        GPIO_DT_SPEC_GET(DT_ALIAS(sw3), gpios), // Button 3 - wake up
    };
    #define NUM_BUTTONS ARRAY_SIZE(buttons)
    #endif
    
    const struct device *const cons = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
    
    void enter_deep_sleep(void)
    {
        int rc;
    
        printf("Entering sleep...\n");
    
        // Suspend the console device before power-off
        rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND);
        if (rc < 0)
        {
            printf("Could not suspend console (%d)\n", rc);
            return;
        }
        printf("Console suspended successfully\n");
    
        k_sleep(K_FOREVER);
    }
    
    // Wake-up handler, called after the system wakes up from deep sleep
    void wakeup_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
    {
    
        // Check which button was pressed
        if (pins == BIT(buttons[2].pin) || pins == BIT(buttons[3].pin))
        {
            pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME);
            printf("System woke up!\n");
            // printf("Entering deep sleep .\n");
            // enter_deep_sleep();
        }
    }
    
    // Deep sleep handler for buttons 0 and 1
    void deep_sleep_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
    {
        if (pins == BIT(buttons[0].pin) || pins == BIT(buttons[1].pin))
        {
            printf("Deep sleep triggered by button press\n");
    
            // Enter deep sleep directly
            enter_deep_sleep();
        }
    }
    
    static struct gpio_callback button_cb_data[NUM_BUTTONS]; // To hold the callback data
    
    int main(void)
    {
        int rc;
    
        // Initialize GPIOs for wake-up and deep sleep buttons
        for (int i = 0; i < NUM_BUTTONS; i++)
        {
            rc = gpio_pin_configure_dt(&buttons[i], GPIO_INPUT | GPIO_PULL_UP);
            if (rc < 0)
            {
                printf("Could not configure button %d GPIO (%d)\n", i, rc);
                return 0;
            }
    
            // Configure the GPIO pin interrupt for level active (button press)
            rc = gpio_pin_interrupt_configure_dt(&buttons[i], GPIO_INT_EDGE_TO_ACTIVE);
            if (rc < 0)
            {
                printf("Could not set interrupt on button %d GPIO (%d)\n", i, rc);
                return 0;
            }
    
            // Initialize GPIO callback for each button (based on button function)
            if (i == 0 || i == 1)
            {
                // Buttons 0 and 1 for deep sleep
                gpio_init_callback(&button_cb_data[i], deep_sleep_handler, BIT(buttons[i].pin));
            }
            else if (i == 2 || i == 3)
            {
                // Buttons 2 and 3 for wake-up (active for 10 seconds)
                gpio_init_callback(&button_cb_data[i], wakeup_handler, BIT(buttons[i].pin));
            }
    
            // Add the callback to the GPIO driver
            rc = gpio_add_callback(buttons[i].port, &button_cb_data[i]);
            if (rc < 0)
            {
                printf("Could not add callback to GPIO pin %d (%d)\n", buttons[i].pin, rc);
                return 0;
            }
        }
    
        // Notify the user that the system is ready to enter deep sleep
        printf("Button 0 or 1 to trigger deep sleep, or button 2 or 3 to wake up \n");
        //enter_deep_sleep(); // Start with deep sleep
    
        return 0;
    }

    nrf54l15dk_nrf54l15_cpuapp.overlay

    / {
    	cpuapp_sram@2002e000 {
    		compatible = "zephyr,memory-region", "mmio-sram";
    		reg = <0x2002e000 DT_SIZE_K(4)>;
    		zephyr,memory-region = "RetainedMem";
    		status = "okay";
    
    		retainedmem0: retainedmem {
    			compatible = "zephyr,retained-ram";
    			status = "okay";
    		};
    	};
    
    	aliases {
    		retainedmemdevice = &retainedmem0;
    		sw0 = &button0;
            sw1 = &button1;
            sw2 = &button2;
            sw3 = &button3;
    	};
    	
    	buttons {
            compatible = "gpio-keys";
            button0: button_0 {
                gpios = <&gpio1 0xd 0x11>;
                label = "Push button 0";
                zephyr,code = <0xb>;
            };
            button1: button_1 {
                gpios = <&gpio1 0x9 0x11>;
                label = "Push button 1";
                zephyr,code = <0x2>;
            };
            button2: button_2 {
                gpios = <&gpio1 0x8 0x11>;
                label = "Push button 2";
                zephyr,code = <0x3>;
            };
            button3: button_3 {
                gpios = <&gpio0 0x4 0x11>;
                label = "Push button 3";
                zephyr,code = <0x4>;
        };
    };
    
    };
    
    
    &cpuapp_sram {
    	/* Shrink SRAM size to avoid overlap with retained memory region */
    	reg = <0x20000000 DT_SIZE_K(184)>;
    	ranges = <0x0 0x20000000 0x2e000>;
    };
    
    // SW2 P1.08
    // SW3 P0.04
    &gpio1 {
        sense-edge-mask = <0x00000100>; /* 1<<8 */
    };
    
    &gpio0 {
        sense-edge-mask = <0x00000010>; /* 1<<4 */
    };

    output result

    Button 0 or 1 to trigger deep sleep, or button 2 or 3 to wake up 
    Deep sleep triggered by button press
    Entering sleep...
    System woke up!
    Deep sleep triggered by button press
    Entering sleep...
    System woke up!

    Best regards,

Related