<alp/power.h> — System Power
System-power-mode control: run, sleep, deep-sleep, standby.
Header
#include <alp/power.h>
Quick example
alp_power_t *p = alp_power_open();
// Declare which sources may wake the SoC (bitmap; replaces, not adds).
alp_power_configure_wake_source(p, ALP_POWER_WAKE_RTC | ALP_POWER_WAKE_GPIO);
// Enter deep sleep, waking after 30 s at the latest.
alp_power_wake_info_t info = { 0 };
alp_power_request_sleep(p, ALP_POWER_MODE_DEEP_SLEEP, 30 * 1000u, &info);
// ...wake-up handler: branch on info.wake_source / info.realised_mode...
alp_power_close(p);
Modes
alp_power_mode_t selectors. Backends round to the closest SoC-supported mode; the realised mode is reported back in alp_power_wake_info_t::realised_mode.
| Mode | Description |
|---|---|
ALP_POWER_MODE_RUN | Normal running mode (no sleep). |
ALP_POWER_MODE_SLEEP | CPU clock-gated; peripherals + RAM live. |
ALP_POWER_MODE_DEEP_SLEEP | Clocks gated; RAM retained; vendor wake sources only. |
ALP_POWER_MODE_STANDBY | Lowest power; RAM not retained; vendor wake only. |
Treat the modes as a monotonic ladder (deeper = lower power + longer wake). The exact wake latency and retained-state guarantees are SoC-defined and documented in the per-SoM HW reference.
Wake sources
OR together the ALP_POWER_WAKE_* bits passed to alp_power_configure_wake_source. Backends honour the subset their hardware supports; unsupported bits are silently ignored.
| Bit | Meaning |
|---|---|
ALP_POWER_WAKE_RTC | RTC alarm / periodic tick. |
ALP_POWER_WAKE_GPIO | Configured GPIO IRQ line. |
ALP_POWER_WAKE_UART_RX | UART RX activity. |
ALP_POWER_WAKE_TIMER | Free-running timer match. |
ALP_POWER_WAKE_USB | USB SOF / VBUS event. |
ALP_POWER_WAKE_ETH_LINK | Ethernet link-up / WoL packet. |
A sleep request with no configured wake source returns ALP_ERR_INVAL. When wake_after_ms > 0 a timer wake is implicit even if ALP_POWER_WAKE_RTC was not set.
Operating-point profiles
[ABI-EXPERIMENTAL] · new in v0.9
Some SoCs keep the power/clock tree behind a system-controller firmware: the application core never pokes PLL / DC-DC / power-domain registers directly — it reads and writes a per-core profile instead. This handle-less surface exposes the two profiles every such platform keeps: the active RUN operating point and the STANDBY (off/retention) operating point.
alp_power_profile_t run = { 0 };
if (alp_power_profile_get(ALP_POWER_PROFILE_RUN, &run) == ALP_OK) {
printf("RUN: %u Hz @ %u mV\n", run.cpu_clk_hz, run.rail_mv);
}
// Read-modify-write: only non-zero fields are applied; everything else
// keeps its current value. Drops the core rail to 800 mV, touching nothing else.
alp_power_profile_set(ALP_POWER_PROFILE_RUN, &(alp_power_profile_t){ .rail_mv = 800 });
which selects the profile:
| Value | Meaning |
|---|---|
ALP_POWER_PROFILE_RUN | The active operating point. |
ALP_POWER_PROFILE_STANDBY | The standby/off operating point + wake configuration. |
alp_power_profile_t fields
Frequencies are Hz; rails are millivolts. A zero field means "unknown / not reported" on get and "keep the current value" on set.
| Field | Type | Notes |
|---|---|---|
cpu_clk_hz | uint32_t | Core clock of the calling core's domain, Hz. RUN = active CPU clock; STANDBY = standby-scaled clock. |
rail_mv | uint32_t | Core DC-DC rail, millivolts. |
power_domains | uint32_t | Implementation-defined bitmask of power domains held on in this profile. |
memory_blocks | uint32_t | Implementation-defined bitmask of memory blocks retained/powered. |
wake_events | uint32_t | Implementation-defined wake-event bitmask. Meaningful for STANDBY only; 0 for RUN. |
io_mv | uint32_t | Flexible-IO bank rail, millivolts (e.g. 3300 or 1800); 0 when the SoC has no switchable IO rail. |
The power_domains / memory_blocks / wake_events bitmasks are implementation-defined opaque tokens — their bit legends are SoC-specific and documented in the per-SoM HW reference. Portable code must read-modify-write, log, or compare them; never construct them from portable constants.
alp_power_profile_get(which, out) is read-only — nothing about the live operating point changes. On SoCs whose profiles live behind a system-controller firmware it is a bounded mailbox round-trip that never hangs. Returns ALP_OK / ALP_ERR_INVAL (NULL out or invalid which) / ALP_ERR_NOSUPPORT (no profile-capable backend) / ALP_ERR_NOT_READY (controller asleep, retryable) / ALP_ERR_IO.
alp_power_profile_set(which, profile) is a read-modify-write that changes the live operating point. The backend reads the current profile, overwrites exactly the fields set to a non-zero value, and writes the result back. Frequencies must match a value the silicon supports exactly — the backend never rounds, so a mismatch returns ALP_ERR_INVAL. wake_events is writable only on the STANDBY profile. Returns the same codes as get.
alp_power_profile_set changes the live power/clock operating point. A wrong rail voltage or clock selection can brown out the core or stall the SoC — treat every call like a firmware update: know the target values from the per-SoM HW reference and have a recovery plan before running it on hardware.
See also
<alp/wdt.h>— wake from watchdog<alp/rtc.h>— wake on alarm