#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/pm.h>
#include <zephyr/pm/state.h>
#define INTPIN DT_NODELABEL(intpin)
static const struct gpio_dt_spec interruptPin = GPIO_DT_SPEC_GET_OR(INTPIN, gpios, { 0 });
static struct k_sem semaphore;
void onInterrupt(const struct device *port,
struct gpio_callback *cb,
gpio_port_pins_t pins)
{
k_sem_give(&semaphore);
}
int main()
{
k_sem_init(&semaphore, 0, 1);
gpio_pin_configure_dt(&interruptPin, GPIO_INPUT);
gpio_pin_interrupt_configure_dt(&interruptPin, GPIO_INT_EDGE_TO_ACTIVE);
NRF_GPIOTE->LATENCY = 0;
gpio_callback intCb{};
gpio_init_callback(&intCb, onInterrupt, BIT(interruptPin.pin));
gpio_add_callback(interruptPin.port, &intCb);
const struct device *uartDevice = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
printk("Started at: %u\n", k_uptime_get_32());
while (true) {
pm_device_action_run(uartDevice, PM_DEVICE_ACTION_SUSPEND);
const auto ret = k_sem_take(&semaphore, K_MSEC(3 * 1000));
pm_device_action_run(uartDevice, PM_DEVICE_ACTION_RESUME);
if (ret) {
printk("Timed out: %u\n", k_uptime_get_32());
return -1;
} else {
printk("Int: %u\n", k_uptime_get_32());
}
}
}
The above code is unable to wakeup CPU on interrupt. For it to work, either the latency should be left at the default value of LowLatency
or the call to pm_device_action_run
to suspend UART be commented. If the latency is not set to LowPower current shoots up from 10uA to 300uA.