Hardware Abstraction Layer (HAL)

General Description

Interface for changing power states and restricting when they are allowed.

Power management is handled both at a system level and at a peripheral driver level. The system wide API (this) allows the user to interact with the product as a whole. Additionally, each peripheral keeps track of what its state is and whether it can safely move to a new state while still maintaining any current operations.

At the System level, the APIs are intended to allow the application to specify exactly what is happening. It can request changes to both the MCU Power State as well as the System Wide Power State. There are three supported MCU Power States:

Additionally, there are three supported system states:

Any time a power state transition is requested a series of callbacks are invoked. This allows peripherals, or other parts of the application, to confirm they are not currently doing something that would not work in the requested power state. HAL Peripheral drivers automatically register these callbacks when they are initialized. The application also has the option to register a callback function(s) to be called on requested state transitions by callling cyhal_syspm_register_callback. If registered, the application level callbacks are invoked first. This gives the application a chance stop any peripherals, if appropriate, to ensure the power transition can actually happen. Alternatively it can directly reject the transition. Each callback registered can specify the exact set of states ( cyhal_syspm_callback_state_t ) that it should be called for. Each callback is invoked multiple times as part of the transition process as defined by cyhal_syspm_callback_mode_t.

At any point the code can lock the ability to enter deep sleep by calling cyhal_syspm_lock_deepsleep. This should be done in critical blocks that need to continue remain active. When the critical work is complete, and the lock is no longer needed, it can be released by calling cyhal_syspm_unlock_deepsleep. The lock is a counter with a max count of USHRT_MAX. It must be locked/unlocked an equal number of times before the device is actually able to enter deep sleep.

All peripherals are expected to operate in the default Active/Normal power state. Some peripherals (primarily analog) can operate in lower power states as well. These drivers will operate in all power states that the hardware supports.

When power transitions are requested each type of peripheral has a default behavior. Peripherals that can continue to operate in the requested power mode do not interfere. Peripherals that are not currently active allow the transition, but make sure they restore their state if needed for when the device comes back. Peripherals that are active and cannot continue to work in the requested power state will block the transition.

Note
The power management functionality available depends on the availability of the features in the hardware. For detailed information about exactly what is supported on each device, refer to the Device Datasheet or Technical Reference Manual (TRM).

Features

This driver provides control over multiple different types of power management and when those transitions are allowed:

Quick Start

Unlike most HAL drivers this does not require initializing an instance object. The APIs provided here can be called at anytime. See the snippets below for examples of how to use this driver.

Code Snippets

Snippet 1: Simple deep sleep locking

The following snippet shows how to use the deep sleep locking APIs to restrict when the device can enter deep sleep. In between the lock/unlock calls any attempt to change power modes will automatically be canceled.

/* Perform work that should not be interrupted by deepsleep */

Snippet 2: Calling different power state functions

The following snippet shows the different functions that exist to change power states on the device and how they can each be called.

cy_rslt_t rslt;
/* Put the MCU to sleep. Peripherals will continue to operate. */
/* Put the MCU to deep-sleep. Many peripherals will also stop. */
/* Put the system into a hibernate state. Most of the system will stop. */
/* Put the system into a low power state. Peripherals will continue to work,
* but some may have restrictions on operating clock frequency or voltages. */

Snippet 3: Using callbacks for application power management

The following snippet shows how to use the callback mechanisms to manage whether it is safe to enter low power modes.

bool syspm_app_callback(cyhal_syspm_callback_state_t state, cyhal_syspm_callback_mode_t mode, void *callback_arg)
{
(void)callback_arg;
bool allow_transition = true;
switch (mode)
{
/* Check to see if it is OK to change power modes. */
/* If it is OK the change, make sure nothing will invalidate this and return true. */
/* If it is not OK the change, return false. */
/* Example: prevent transition if requested mode is HIBERNATE. */
allow_transition = (state != CYHAL_SYSPM_CB_SYSTEM_HIBERNATE);
break;
/* Undo anything done as part of CHECK_READY since it is not actually chaning. */
break;
/* Do anything necessary to shut things down. */
break;
/* Undo anything done as part of CHECK_READY or BEFORE_TRANSITION since it is coming back up. */
break;
}
return allow_transition;
}
void snippet_cyhal_syspm_app_callback(void)
{
cy_rslt_t rslt;
{
.callback = syspm_app_callback,
.args = NULL,
.next = NULL,
};
/* Attempt to hibernate. This will be rejected by the callback. */
if (CY_RSLT_SUCCESS != rslt)
{
/* If couldn't go to hibernate, try deep sleep. */
}
}

API Reference

 SYSPM HAL Results
 SYSPM specific return codes.
 

Data Structures

struct  cyhal_syspm_callback_data_t
 Power management callback data object. More...
 

Macros

#define CYHAL_SYSPM_CALLBACK_STATE_ALL
 Define for enabling all system and MCU state callbacks . More...
 

Typedefs

typedef bool(* cyhal_syspm_callback_t) (cyhal_syspm_callback_state_t state, cyhal_syspm_callback_mode_t mode, void *callback_arg)
 The system wide custom action power callback type. More...
 

Enumerations

enum  cyhal_syspm_callback_state_t {
  CYHAL_SYSPM_CB_CPU_SLEEP = 0x01U,
  CYHAL_SYSPM_CB_CPU_DEEPSLEEP = 0x02U,
  CYHAL_SYSPM_CB_SYSTEM_HIBERNATE = 0x04U,
  CYHAL_SYSPM_CB_SYSTEM_NORMAL = 0x08U,
  CYHAL_SYSPM_CB_SYSTEM_LOW = 0x10U
}
 Flags enum for the cpu state in a custom callback. More...
 
enum  cyhal_syspm_callback_mode_t {
  CYHAL_SYSPM_CHECK_READY = 0x01U,
  CYHAL_SYSPM_CHECK_FAIL = 0x02U,
  CYHAL_SYSPM_BEFORE_TRANSITION = 0x04U,
  CYHAL_SYSPM_AFTER_TRANSITION = 0x08U
}
 Enumeration of the transition modes in custom callback. More...
 
enum  cyhal_syspm_system_state_t {
  CYHAL_SYSPM_SYSTEM_NORMAL,
  CYHAL_SYSPM_SYSTEM_LOW
}
 Enumeration of the system wide power modes. More...
 
enum  cyhal_syspm_hibernate_source_t {
  CYHAL_SYSPM_HIBERNATE_LPCOMP0_LOW = 0x01U,
  CYHAL_SYSPM_HIBERNATE_LPCOMP0_HIGH = 0x02U,
  CYHAL_SYSPM_HIBERNATE_LPCOMP1_LOW = 0x04U,
  CYHAL_SYSPM_HIBERNATE_LPCOMP1_HIGH = 0x08U,
  CYHAL_SYSPM_HIBERNATE_RTC_ALARM = 0x10U,
  CYHAL_SYSPM_HIBERNATE_WDT = 0x20U,
  CYHAL_SYSPM_HIBERNATE_PINA_LOW = 0x40U,
  CYHAL_SYSPM_HIBERNATE_PINA_HIGH = 0x80U,
  CYHAL_SYSPM_HIBERNATE_PINB_LOW = 0x100U,
  CYHAL_SYSPM_HIBERNATE_PINB_HIGH = 0x200U
}
 Flags enum for the hibernate wakeup sources. More...
 
enum  cyhal_syspm_voltage_supply_t {
  CYHAL_VOLTAGE_SUPPLY_VDDA = 0u,
  CYHAL_VOLTAGE_SUPPLY_MAX = CYHAL_VOLTAGE_SUPPLY_VDDA
}
 Supply voltages whose levels can be specified and queried via cyhal_syspm_set_supply_voltage and cyhal_syspm_get_supply_voltage, respectively. More...
 

Functions

cy_rslt_t cyhal_syspm_hibernate (cyhal_syspm_hibernate_source_t wakeup_source)
 Sets the system mode to hibernate. More...
 
cy_rslt_t cyhal_syspm_set_system_state (cyhal_syspm_system_state_t state)
 Set the system-wide state of the device. More...
 
cyhal_syspm_system_state_t cyhal_syspm_get_system_state ()
 Gets the system-wide state of the device. More...
 
void cyhal_syspm_register_callback (cyhal_syspm_callback_data_t *callback_data)
 Register the specified handler with the power manager to be notified of power state changes. More...
 
void cyhal_syspm_unregister_callback (cyhal_syspm_callback_data_t *callback_data)
 Removes the registered handler from the power manager so no future notifications are made. More...
 
cy_rslt_t cyhal_syspm_sleep (void)
 Set CPU to sleep mode. More...
 
cy_rslt_t cyhal_syspm_deepsleep (void)
 Set CPU to deep sleep mode. More...
 
void cyhal_syspm_lock_deepsleep (void)
 Lock deep sleep. More...
 
void cyhal_syspm_unlock_deepsleep (void)
 Unlock deep sleep. More...
 
cy_rslt_t cyhal_syspm_tickless_deepsleep (cyhal_lptimer_t *obj, uint32_t desired_ms, uint32_t *actual_ms)
 Timed deep-sleep without system timer. More...
 
cy_rslt_t cyhal_syspm_tickless_sleep (cyhal_lptimer_t *obj, uint32_t desired_ms, uint32_t *actual_ms)
 Timed sleep without system timer. More...
 
void cyhal_syspm_set_supply_voltage (cyhal_syspm_voltage_supply_t supply, uint32_t mvolts)
 Informs the system of the current voltage level on the specified supply. More...
 
uint32_t cyhal_syspm_get_supply_voltage (cyhal_syspm_voltage_supply_t supply)
 Retrieves the current voltage level on the specified supply, as set in cyhal_syspm_set_supply_voltage. More...
 

Data Structure Documentation

◆ cyhal_syspm_callback_data_t

struct cyhal_syspm_callback_data_t
Data Fields
cyhal_syspm_callback_t callback Callback to run on power state change.
cyhal_syspm_callback_state_t states Power states that should trigger calling the callback.

Multiple cyhal_syspm_callback_state_t values can be ored together.

cyhal_syspm_callback_mode_t ignore_modes Modes to ignore invoking the callback for.

Multiple cyhal_syspm_callback_mode_t values can be ored together.

void * args Argument value to provide to the callback.
struct cyhal_syspm_callback_data * next Pointer to the next callback strucure.

This should be initialized to NULL.

Macro Definition Documentation

◆ CYHAL_SYSPM_CALLBACK_STATE_ALL

#define CYHAL_SYSPM_CALLBACK_STATE_ALL
Value:
Flag for MCU sleep callback.
Definition: cyhal_general_types.h:169
Flag for Normal mode callback.
Definition: cyhal_general_types.h:172
Flag for Hibernate callback.
Definition: cyhal_general_types.h:171
Flag for Low power mode callback.
Definition: cyhal_general_types.h:173
Flag for MCU deep sleep callback.
Definition: cyhal_general_types.h:170

Define for enabling all system and MCU state callbacks .

Typedef Documentation

◆ cyhal_syspm_callback_t

typedef bool(* cyhal_syspm_callback_t) (cyhal_syspm_callback_state_t state, cyhal_syspm_callback_mode_t mode, void *callback_arg)

The system wide custom action power callback type.

Parameters
[in]stateState the system or CPU is being transitioned into.
[in]modeCallback mode.
[in]callback_argUser argument passed as part of registering callback in cyhal_syspm_register_callback.
Returns
If mode is CYHAL_SYSPM_CHECK_READY, then this indicates whether the low power mode should be allowed (true) or not (false). Otherwise the return value is ignored.

Enumeration Type Documentation

◆ cyhal_syspm_callback_state_t

Flags enum for the cpu state in a custom callback.

This is used to indicate what states a callback should be called in. When a callback is called, only one of these will be set at a time.

Enumerator
CYHAL_SYSPM_CB_CPU_SLEEP 

Flag for MCU sleep callback.

CYHAL_SYSPM_CB_CPU_DEEPSLEEP 

Flag for MCU deep sleep callback.

CYHAL_SYSPM_CB_SYSTEM_HIBERNATE 

Flag for Hibernate callback.

CYHAL_SYSPM_CB_SYSTEM_NORMAL 

Flag for Normal mode callback.

CYHAL_SYSPM_CB_SYSTEM_LOW 

Flag for Low power mode callback.

◆ cyhal_syspm_callback_mode_t

Enumeration of the transition modes in custom callback.

The general sequence is: CHECK_READY, BEFORE_TRANSITION, AFTER_TRANSITION. If any callback indicates that it is not able to change state as part of CHECK_READY, CHECK_FAIL will be run instead of the BEFORE/AFTER_TRANSITION.

Enumerator
CYHAL_SYSPM_CHECK_READY 

Callbacks with this mode are executed before entering into the low power mode.

The purpose of this transition state is to check if the device is ready to enter the low power mode. The application must not perform any actions that would prevent transition after returning true for this mode.

CYHAL_SYSPM_CHECK_FAIL 

Callbacks with this mode are only executed if the callback returned true for CYHAL_SYSPM_CHECK_READY and a later callback returns false for CYHAL_SYSPM_CHECK_READY.

This mode should roll back any changes made to avoid blocking transition made in CYHAL_SYSPM_CHECK_READY mode

CYHAL_SYSPM_BEFORE_TRANSITION 

Callbacks with this mode are executed after the CYHAL_SYSPM_CHECK_READY callbacks' execution returns true.

In this mode, the application must perform the actions to be done before entering into the low power mode.

CYHAL_SYSPM_AFTER_TRANSITION 

In this mode, the application must perform the actions to be done after exiting the low power mode.

◆ cyhal_syspm_system_state_t

Enumeration of the system wide power modes.

These modes are device specifc and may not be supported on all devices. Refer to the device specific documentation or the Data Sheet to determine what is allowed. Devices that do support these modes may have requirements for adjusting system settings such as clocks or voltage levels before transition.

Enumerator
CYHAL_SYSPM_SYSTEM_NORMAL 

Normal Mode.

CYHAL_SYSPM_SYSTEM_LOW 

Low Power Mode.

◆ cyhal_syspm_hibernate_source_t

Flags enum for the hibernate wakeup sources.

Note
Not all wakeup sources are valid on devices. Refer to the datasheet for device specifics.
Enumerator
CYHAL_SYSPM_HIBERNATE_LPCOMP0_LOW 

Wake on a low logic level for the LPComp0.

CYHAL_SYSPM_HIBERNATE_LPCOMP0_HIGH 

Wake on a high logic level for the LPComp0.

CYHAL_SYSPM_HIBERNATE_LPCOMP1_LOW 

Wake on a low logic level for the LPComp1.

CYHAL_SYSPM_HIBERNATE_LPCOMP1_HIGH 

Wake on a high logic level for the LPComp1.

CYHAL_SYSPM_HIBERNATE_RTC_ALARM 

Configure the RTC alarm as wakeup source.

CYHAL_SYSPM_HIBERNATE_WDT 

Configure the WDT interrupt as wakeup source.

CYHAL_SYSPM_HIBERNATE_PINA_LOW 

Configure a low logic level for the first wakeup-pin.

See device datasheet for specific pin.

CYHAL_SYSPM_HIBERNATE_PINA_HIGH 

Configure a high logic level for the first wakeup-pin.

See device datasheet for specific pin.

CYHAL_SYSPM_HIBERNATE_PINB_LOW 

Configure a low logic level for the second wakeup-pin.

See device datasheet for specific pin.

CYHAL_SYSPM_HIBERNATE_PINB_HIGH 

Configure a high logic level for the second wakeup-pin.

See device datasheet for specific pin.

◆ cyhal_syspm_voltage_supply_t

Supply voltages whose levels can be specified and queried via cyhal_syspm_set_supply_voltage and cyhal_syspm_get_supply_voltage, respectively.

Note
Not all supplies which are present are included here. This enum only contains the voltage supplies whose values are relevant to the operation of one or more HAL drivers.
Enumerator
CYHAL_VOLTAGE_SUPPLY_VDDA 

VDDA - Analog supply voltage.

CYHAL_VOLTAGE_SUPPLY_MAX 

Alias for the highest value in this enum.

Function Documentation

◆ cyhal_syspm_hibernate()

cy_rslt_t cyhal_syspm_hibernate ( cyhal_syspm_hibernate_source_t  wakeup_source)

Sets the system mode to hibernate.

This function configures the sources to wake up the device from hibernate mode and then sets the system to hibernate mode.

In hibernate mode, all internal supplies are off and no internal state is retained.

Sources can be wakeup pins, LPComparators, Watchdog (WDT) interrupt, or a Real-Time clock (RTC) alarm (interrupt). Wakeup from system hibernate always results in a device reset and normal boot process.

Wakeup pins:

A wakeup is supported by pins with programmable polarity. These pins are typically connected to the GPIO pins or on-chip peripherals under some conditions. See device datasheet to check if this feature is supported and for specific pin connections. Setting the wakeup pin to this level will cause a wakeup from system hibernate mode.

LPComparators:

A wakeup is supported by LPComps with programmable polarity. Setting the LPComp to this level will cause a wakeup from system hibernate mode.

Watchdog Timer:

A wakeup is performed by a WDT interrupt.

Real-time Clock:

A wakeup is performed by the RTC alarm.

For information about hibernate behavior, wakeup sources and their assignment in specific devices, refer to the appropriate device TRM.

Parameters
[in]wakeup_sourceThe source to be configured as a wakeup source from the system hibernate power mode, see cyhal_syspm_hibernate_source_t. The input parameter values can be ORed. For example, if you want to enable LPComp0 (active high) and WDT, call this function: cyhal_syspm_hibernate(CYHAL_SYSPM_HIBERNATE_LPCOMP0_HIGH | CYHAL_SYSPM_HIBERNATE_WDT).
Warning
Do not call this function with different polarity levels for the same wakeup source. For example, do not call a function like this: cyhal_syspm_hibernate(CYHAL_SYSPM_HIBERNATE_LPCOMP0_LOW | CYHAL_SYSPM_HIBERNATE_LPCOMP0_HIGH);
Returns
Returns CY_RSLT_SUCCESS if the processor successfully entered the hibernate mode, otherwise error.

◆ cyhal_syspm_set_system_state()

cy_rslt_t cyhal_syspm_set_system_state ( cyhal_syspm_system_state_t  state)

Set the system-wide state of the device.

This is used to change the power state within the Active power mode. cyhal_syspm_get_system_state can be used to get the current state.

Note
Not all devices support different states within the Active power mode. If the device does not support changing state, an error will be returned.
Parameters
[in]stateSystem wide state.
Returns
Returns CY_RSLT_SUCCESS if the processor successfully entered the requested system state, otherwise error.

◆ cyhal_syspm_get_system_state()

cyhal_syspm_system_state_t cyhal_syspm_get_system_state ( )

Gets the system-wide state of the device.

States can be changed by calling cyhal_syspm_set_system_state.

Note
Not all devices support different states within the Active power mode. If the device does not support changing state, this will return CYHAL_SYSPM_SYSTEM_NORMAL.
Returns
Returns the current system-wide power state of the device.

◆ cyhal_syspm_register_callback()

void cyhal_syspm_register_callback ( cyhal_syspm_callback_data_t callback_data)

Register the specified handler with the power manager to be notified of power state changes.

This is intended for application wide decisions. Peripherals handle their ability to perform power transitions internally. This callback will be called before any of the peripheral callbacks for CYHAL_SYSPM_CHECK_READY and CYHAL_SYSPM_BEFORE_TRANSITION. This callback will be called after all peripheral callback for CYHAL_SYSPM_CHECK_FAIL and CYHAL_SYSPM_AFTER_TRANSITION.

Note
The callback will be executed from a critical section
Parameters
[in]callback_dataThe data for the callback to register

◆ cyhal_syspm_unregister_callback()

void cyhal_syspm_unregister_callback ( cyhal_syspm_callback_data_t callback_data)

Removes the registered handler from the power manager so no future notifications are made.

  • Parameters
    [in]callback_dataThe data for the callback to unregister

◆ cyhal_syspm_sleep()

cy_rslt_t cyhal_syspm_sleep ( void  )

Set CPU to sleep mode.

Returns
Returns CY_RSLT_SUCCESS if the processor successfully entered the sleep mode , otherwise error.

◆ cyhal_syspm_deepsleep()

cy_rslt_t cyhal_syspm_deepsleep ( void  )

Set CPU to deep sleep mode.

Returns
Returns CY_RSLT_SUCCESS if the processor successfully entered the deep sleep mode, otherwise error.

◆ cyhal_syspm_lock_deepsleep()

void cyhal_syspm_lock_deepsleep ( void  )

Lock deep sleep.

This function prevents the CPU from going to deep sleep. The lock is implemented as a counter from 0 to USHRT_MAX. Each call to this function increments the counter by 1. cyhal_syspm_unlock_deepsleep must be called an equal number of times to fully unlock. Deepsleep will only be allowed when the counter is equal to 0.

◆ cyhal_syspm_unlock_deepsleep()

void cyhal_syspm_unlock_deepsleep ( void  )

Unlock deep sleep.

This function decrements the lock counter by 1 and must be called an equal number of times as cyhal_syspm_lock_deepsleep is called to fully unlock. Deepsleep will only be allowed when the counter is equal to 0.

◆ cyhal_syspm_tickless_deepsleep()

cy_rslt_t cyhal_syspm_tickless_deepsleep ( cyhal_lptimer_t obj,
uint32_t  desired_ms,
uint32_t *  actual_ms 
)

Timed deep-sleep without system timer.

Provides a way to deep-sleep for a desired number of milliseconds(ms) with the system timer disabled. The system timer is disabled before sleeping and a low power timer is setup to wake the device from deep-sleep after the desired number of ms have elapsed.

Note
The actual ms in the best case will be 1 ms less than the desired time to prevent the device from over-sleeping due to low clock accuracy.
Parameters
[in]objPre-Initialized LPTimer object.
[in]desired_msDesired number of ms to deep-sleep.
[out]actual_msActual number of ms that was spent in deep-sleep. This value can range from 0 to desired_ms - 1 depending on how long the device was able to deep-sleep.
Returns
The status of the deep-sleep request.

◆ cyhal_syspm_tickless_sleep()

cy_rslt_t cyhal_syspm_tickless_sleep ( cyhal_lptimer_t obj,
uint32_t  desired_ms,
uint32_t *  actual_ms 
)

Timed sleep without system timer.

Provides a way to sleep for a desired number of milliseconds(ms) with the system timer disabled. The system timer is disabled before sleeping and a low power timer is setup to wake the device from sleep after the desired number of ms have elapsed.

Note
The actual ms in the best case will be 1 ms less than the desired time to prevent the device from over-sleeping due to low clock accuracy.
Parameters
[in]objPre-Initialized LPTimer object.
[in]desired_msDesired number of ms to sleep.
[out]actual_msActual number of ms that was spent in sleep. This value can range from 0 to desired_ms - 1 depending on how long the device was able to sleep.
Returns
The status of the sleep request.

◆ cyhal_syspm_set_supply_voltage()

void cyhal_syspm_set_supply_voltage ( cyhal_syspm_voltage_supply_t  supply,
uint32_t  mvolts 
)

Informs the system of the current voltage level on the specified supply.

This is generally expected to be set once at system startup, but it may be set repeatedly during runtime if operating conditions change. Once set, this value can be queried via cyhal_syspm_get_supply_voltage.

Note
This only informs the system of the voltage level. It does not alter any of the device operating conditions.
Parameters
supplyThe supply whose voltage is being specified.
mvoltsThe voltage level on the specified supply, in millivolts.

◆ cyhal_syspm_get_supply_voltage()

uint32_t cyhal_syspm_get_supply_voltage ( cyhal_syspm_voltage_supply_t  supply)

Retrieves the current voltage level on the specified supply, as set in cyhal_syspm_set_supply_voltage.

Note
This only returns the value provided to cyhal_syspm_set_supply_voltage. It does not perform any measurements of the current supply level.
Parameters
supplyThe supply whose voltage is being specified.
Returns
The voltage level on the specified supply, in millivolts. If the voltage has not been specified, returns 0.