Skip to main content

<alp/power.h> — System Power

System-power-mode control: run, sleep, deep-sleep, standby.

#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.

ModeDescription
ALP_POWER_MODE_RUNNormal running mode (no sleep).
ALP_POWER_MODE_SLEEPCPU clock-gated; peripherals + RAM live.
ALP_POWER_MODE_DEEP_SLEEPClocks gated; RAM retained; vendor wake sources only.
ALP_POWER_MODE_STANDBYLowest 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.

BitMeaning
ALP_POWER_WAKE_RTCRTC alarm / periodic tick.
ALP_POWER_WAKE_GPIOConfigured GPIO IRQ line.
ALP_POWER_WAKE_UART_RXUART RX activity.
ALP_POWER_WAKE_TIMERFree-running timer match.
ALP_POWER_WAKE_USBUSB SOF / VBUS event.
ALP_POWER_WAKE_ETH_LINKEthernet 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:

ValueMeaning
ALP_POWER_PROFILE_RUNThe active operating point.
ALP_POWER_PROFILE_STANDBYThe 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.

FieldTypeNotes
cpu_clk_hzuint32_tCore clock of the calling core's domain, Hz. RUN = active CPU clock; STANDBY = standby-scaled clock.
rail_mvuint32_tCore DC-DC rail, millivolts.
power_domainsuint32_tImplementation-defined bitmask of power domains held on in this profile.
memory_blocksuint32_tImplementation-defined bitmask of memory blocks retained/powered.
wake_eventsuint32_tImplementation-defined wake-event bitmask. Meaningful for STANDBY only; 0 for RUN.
io_mvuint32_tFlexible-IO bank rail, millivolts (e.g. 3300 or 1800); 0 when the SoC has no switchable IO rail.
caution

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.

danger

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

Questions about this page? Discuss in Community Forum