My task is to implement the below functionality and shared the below code
Disable peripherals and GPIOs before sleep and enable back after wakeup
#include <zephyr/kernel.h>
#include <zephyr/pm/pm.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/policy.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/hwinfo.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/devicetree.h>
#include <zephyr/dt-bindings/gpio/gpio.h>
#include <zephyr/devicetree/gpio.h>
#include <zephyr/sys/poweroff.h>
#include <zephyr/device.h>
#include <zephyr/toolchain/common.h>
#include "user_gpio_task.h"
#include <zephyr/sys/__assert.h>
#include <nrfx_wdt.h>
#include <string.h>
#include <zephyr/sys/printk.h>
/* Get the node ID for the sw4 button alias */
#define BUTTON_NODE DT_ALIAS(sw4)
// Ensure the button node exists and is ready at compile time
BUILD_ASSERT(DT_NODE_HAS_STATUS(BUTTON_NODE, okay), "sw4 button node is not ready");
static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET(BUTTON_NODE, gpios);
static struct gpio_callback button_cb_data;
//global volatile flag variable
static volatile bool button_pressed = false;
// Use a semaphore to signal a button press event
static K_SEM_DEFINE(button_press_sem, 0, 1);
/* Interrupt callback function for the button pin */
// This function executes when the interrupt is triggered
void button_pressed_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
printk("Button interrupt triggered! Waking up...\n");
// Set the flag to indicate the button was pressed
// button_pressed = true;
k_sem_give(&button_press_sem);
}
void sleep_mode_enable(void)
{
printk("NORA-B2 Button Interrupt Example\n");
printk("Button1 (SW4) is connected to P1.13.\n");
// Check if the GPIO device is ready
if (!gpio_is_ready_dt(&button))
{
printk("GPIO device for button is not ready!\n");
return;
}
// Configure the pin for interrupt and as a wake-up source
int ret = gpio_pin_configure_dt(&button, GPIO_INPUT | GPIO_PULL_UP);
if (ret < 0)
{
printk("Error configuring wake-up pin: %d\n", ret);
return;
}
// Configure the pin interrupt to trigger on a low level (e.g., button press)
ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
if (ret < 0)
{
printk("Error configuring wake-up interrupt: %d\n", ret);
return;
}
// Initialize and add the interrupt callback
gpio_init_callback(&button_cb_data, button_pressed_callback, BIT(button.pin));
ret = gpio_add_callback(button.port, &button_cb_data);
if (ret < 0)
{
printk("Error adding wake-up callback: %d\n", ret);
return;
}
printk("Entering low-power idle state. Press the button to wake up.\n");
// Block the thread until the semaphore is given by the interrupt callback.
// The OS will automatically put the CPU into a low-power idle state.
k_sem_take(&button_press_sem, K_FOREVER);
printk("The main thread was woken up!\n");
// The callback and GPIO config are no longer needed
gpio_remove_callback(button.port, &button_cb_data);
gpio_pin_configure_dt(&button, GPIO_DISCONNECTED);
while (1)
{
printk("Normal application logic running...\n");
k_sleep(K_SECONDS(2));
}
}
int disable_peripheral(const struct device *dev) {
if (dev) {
return pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND);
}
return -ENODEV;
}
int disable_all_peripherals(void) {
// You would add calls to disable all peripherals used in your application
// Example:
//disable_peripheral(DEVICE_DT_GET(DT_NODELABEL(i2c21)));
disable_peripheral(DEVICE_DT_GET(DT_NODELABEL(i2c30)));
disable_peripheral(DEVICE_DT_GET(DT_NODELABEL(spi21)));
disable_peripheral(DEVICE_DT_GET(DT_NODELABEL(spi22)));
disable_peripheral(DEVICE_DT_GET(DT_NODELABEL(uart00)));
disable_peripheral(DEVICE_DT_GET(DT_NODELABEL(uart20)));
disable_peripheral(DEVICE_DT_GET(DT_NODELABEL(uart21)));
disable_peripheral(DEVICE_DT_GET(DT_NODELABEL(gpio0)));
disable_peripheral(DEVICE_DT_GET(DT_NODELABEL(gpio1)));
disable_peripheral(DEVICE_DT_GET(DT_NODELABEL(gpio2)));
printk("Disabling all peripherals...\n");
return 0;
}
int disable_all_gpios(void) {
// This is highly board-specific. For the EVK-NORA-B2, you would need to iterate
// through all GPIOs (e.g., from P0 and P1) and configure them as input with no pull
// to prevent leakage currents on floating pins.
printk("Disabling all non-wakeup GPIOs...\n");
return 0;
}
// --- Deep Sleep Enable Function ---
void deep_sleep_mode_enable(void)
{
int ret;
printk("NORA-B2 Deep Sleep (System OFF) Example\n");
// Step 1: De-initialize all peripherals and turn off LEDs.
disable_all_peripherals();
// AllLedsOff(); // Add a function to turn off all LEDs
// Step 2: Configure the wake-up GPIO.
if (!gpio_is_ready_dt(&button))
{
printk("Error: Wakeup GPIO device is not ready!\n");
return;
}
// We rely on the `zephyr,wakeup-source` property in the DTS to configure the pin.
// This function tells the power management system to enable this device as a wake-up source.
ret = pm_device_wakeup_enable(button.port, true);
if (ret < 0) {
printk("Error enabling device wakeup: %d\n", ret);
return;
}
// Step 3: Disable all other GPIOs to prevent leakage current.
disable_all_gpios();
// Step 4: Enter the deep sleep mode (System OFF).
printk("Entering deep sleep (System OFF). Press the button to reboot.\n");
// This call puts the MCU into the deepest sleep state. Execution stops here.
// The next line of code will only be reached after a full reboot.
pm_device_state_set(button,PM_DEVICE_STATE_OFF);
// This part of the code is unreachable during normal execution of deep sleep.
// It will only be executed if the system fails to enter System OFF.
printk("Failed to enter deep sleep mode.\n");
while(1) { k_sleep(K_FOREVER); }
}
// void wakeup_handler_from_deep_sleep(void)
// {
// // This function should be called at the beginning of your main()
// // to check if the system woke up from deep sleep.
// uint32_t reset_cause = nrf_power_resetreas_get();
// if (reset_cause & NRF_POWER_RESETREAS_SYSOFF_MASK) {
// printk("System woke up from deep sleep!\n");
// }
// // Clear the reset reason flags
// nrf_power_resetreas_clear(reset_cause);
// }
I am getting a below error, am i using the correct function to implement or is there any other function compatible with
C:/Project/HVPP/hvpp_BLE_application/src/drivers/Sleep/SleepMode.c:207: undefined reference to `pm_system_state_set'
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.