Power Architecture๏
SoC has an advanced Power Management Controller (PMC), which can flexibly power up different power domains of the chip, to achieve the best balance between chip performance and power consumption.
There are generally three main power domains in the digital system of the SoC: AON, SYSON, and SOC.
Functions in different power domains will be turned off differently in different power-saving modes.
Power-Saving Mode๏
Ameba SoC supports two low power modes:
Sleep mode
Clock Gating (CG): Shuts off the clock to the SOC domain while retaining its power supply.
Power Gating (PG): Shuts off the power supply to the SOC domain.
Deep-Sleep mode
Shuts off the power supply to both the SYSON domain and SOC domain. Compared to sleep mode, deep-sleep mode turns off more power domains, resulting in lower power consumption.
Tickless is a low power feature of FreeRTOS. When the system is idle, the CPU will be paused (without disabling clock and power). Both sleep mode and deep sleep mode workflows are based on Tickless.
The following table explains power-saving related terms.
Mode |
AON domain |
SYSON domain |
SOC domain |
Description |
|---|---|---|---|---|
Tickless |
ON |
ON |
ON |
|
Sleep |
ON |
ON |
|
|
Deep-Sleep |
ON |
OFF |
OFF |
|
Tickless for FreeRTOS๏
The FreeRTOS supports a low-power feature called Tickless. It is implemented in an idle task which has the lowest priority. That is, it is invoked when there is no other task under running.
Note
configUSE_TICKLESS_IDLE must be enabled for power-saving application because sleep mode flow is based on Tickless.
Unlike the original FreeRTOS, We donโt wake up based on the xEpectedIdleTime.
FreeRTOS Tickless in an idle task๏
The figure above shows idle task code flow. In idle task, it will check sleep conditions (wakelock, sysactive_time, details in Section Wakelock APIs and pmu_set_sysactive_time) to determine whether needs to enter sleep mode or not.
If not, the CPU will execute an ARM instruction WFI (wait for interrupt) which makes the CPU suspend until the interrupt happens. Normally systick interrupt resumes it. This is the software Tickless.
If yes, it will execute the function
freertos_pre_sleep_processing()to enter sleep mode or deep-sleep mode.
Note
Even FreeRTOS time control like software timer or vTaskDelay is set, it still enters the sleep mode if meeting the requirement as long as the idle task is executed.
Wi-Fi Power Saving๏
Please reference Wi-Fi Power Saving chapter for detailed information.
Wakeup Source๏
The following table lists the wakeup sources that can be used to wake up the system under different power modes.
Wakeup source |
Sleep CG |
Sleep PG |
Deep-Sleep |
Restriction |
|---|---|---|---|---|
WLAN |
โ |
โ |
X |
|
BT |
โ |
โ |
X |
|
IPC |
โ |
โ |
X |
Only KM0 can use the IPC to wake up KM4. |
Basic Timer4~7 |
โ |
โ |
X |
|
PMC Timer |
โ |
โ |
X |
For internal usage |
UART0~2 |
โ |
โ |
X |
|
LOGUART |
โ |
โ |
X |
When using LOGUART as a wakeup source:
|
GPIO |
โ |
โ |
X |
|
I2C |
โ |
โ |
X |
|
CAP_TOUCH |
โ |
โ |
X |
|
ADC |
โ |
โ |
X |
|
SDIO |
โ |
โ |
X |
|
Key-Scan |
โ |
โ |
X |
|
BOR |
โ |
โ |
โ |
|
PWR_DOWN |
โ |
โ |
โ |
|
AON_TIMER |
โ |
โ |
โ |
|
AON_WAKEPIN |
โ |
โ |
โ |
|
RTC |
โ |
โ |
โ |
The following table lists the wakeup sources that can be used to wake up the system under different power modes.
Wakeup source |
Sleep CG |
Sleep PG |
Deep-Sleep |
Restriction |
|---|---|---|---|---|
WLAN |
โ |
โ |
X |
|
BT |
โ |
โ |
X |
|
IWDG |
โ |
โ |
X |
|
IPC |
โ |
โ |
X |
|
Basic Timer |
โ |
โ |
X |
|
UART |
โ |
โ |
X |
|
LOGUART |
โ |
โ |
X |
|
GPIO |
โ |
โ |
X |
|
SPI |
โ |
X |
X |
|
CAP_TOUCH |
โ |
โ |
X |
|
ADC |
โ |
โ |
X |
|
VAD |
โ |
X |
X |
|
BOR |
โ |
โ |
โ |
|
PWR_DOWN |
โ |
โ |
โ |
|
AON_TIMER |
โ |
โ |
โ |
|
AON_WAKEPIN |
โ |
โ |
โ |
|
RTC |
โ |
โ |
โ |
The following table lists the wakeup sources that can be used to wake up the system under different power modes.
Wakeup source |
Sleep CG |
Sleep PG |
Deep-Sleep |
Restriction |
|---|---|---|---|---|
WLAN |
โ |
โ |
X |
|
BT |
โ |
โ |
X |
|
IWDG |
โ |
โ |
X |
|
IPC |
โ |
โ |
X |
|
Basic Timer |
โ |
โ |
X |
|
UART |
โ |
โ |
X |
|
LOGUART |
โ |
โ |
X |
|
GPIO |
โ |
โ |
X |
|
SPI |
โ |
X |
X |
|
CAP_TOUCH |
โ |
โ |
X |
|
ADC |
โ |
โ |
X |
|
VAD |
โ |
X |
X |
|
BOR |
โ |
โ |
โ |
|
PWR_DOWN |
โ |
โ |
โ |
|
AON_TIMER |
โ |
โ |
โ |
|
AON_WAKEPIN |
โ |
โ |
โ |
|
RTC |
โ |
โ |
โ |
The following table lists the wakeup sources that can be used to wake up the system under different power modes.
Wakeup source |
Sleep CG |
Sleep PG |
Deep-Sleep |
Restriction |
|---|---|---|---|---|
WLAN |
โ |
โ |
X |
|
BT |
โ |
โ |
X |
|
IWDG |
โ |
โ |
X |
|
IPC |
โ |
โ |
X |
|
Basic Timer |
โ |
โ |
X |
|
UART |
โ |
โ |
X |
|
LOGUART |
โ |
โ |
X |
|
GPIO |
โ |
โ |
X |
|
SPI |
โ |
X |
X |
|
CAP_TOUCH |
โ |
โ |
X |
|
ADC |
โ |
โ |
X |
|
VAD |
โ |
X |
X |
|
BOR |
โ |
โ |
โ |
|
PWR_DOWN |
โ |
โ |
โ |
|
AON_TIMER |
โ |
โ |
โ |
|
AON_WAKEPIN |
โ |
โ |
โ |
|
RTC |
โ |
โ |
โ |
The following table lists the wakeup sources that can be used to wake up the system under different power modes.
Wakeup source |
Sleep CG |
Sleep PG |
Deep-Sleep |
Restriction |
|---|---|---|---|---|
WLAN |
โ |
โ |
X |
|
BT |
โ |
โ |
X |
|
AON_WAKEPIN |
โ |
โ |
โ |
|
UART |
โ |
โ |
X |
|
IPC |
โ |
โ |
X |
The IPC can only wake up CA32 and KM4, but not KM0. |
SPI |
โ |
X |
X |
Do not turn off SOC domain clock and power when using SPI as wakeup source |
USB |
โ |
X |
X |
|
VAD |
โ |
โ |
X |
|
BOR |
โ |
โ |
โ |
|
PWR_DOWN |
โ |
โ |
โ |
|
CAP_TOUCH |
โ |
โ |
X |
|
ADC |
โ |
โ |
X |
|
RTC |
โ |
โ |
โ |
|
GPIO |
โ |
โ |
X |
|
LOGUART |
โ |
โ |
X |
|
Basic Timer |
โ |
โ |
X |
|
IWDG |
โ |
โ |
X |
|
AON_TIMER |
โ |
โ |
โ |
A hardware SYSON power management control module (SYSON PMC) is designed to control the clock and power of LP, and then LP controls the clock and power of NP and AP. When the system enters sleep mode, CPUs can select to enter clock-gating (CG) or power-gating (PG) mode, while SYSON PMC maintained active to wake up LP when wakeup sources are triggered.
Entering Sleep Mode๏
Sleep mode is based on FreeRTOS Tickless, thus it is recommended to enter sleep mode by releasing the wakelock.
Initialize the specific peripheral.
Enable and register the peripheralโs interrupt.
Set
sleep_wevent_config[]inambea_sleepcfg.c, and the interrupt should be registered on the same CPU selected bysleep_wevent_config[].For peripherals that need special clock settings, set
ps_config[]inameba_sleepcfg.cif needed.Register sleep/wakeup callback if needed.
Enter sleep mode by releasing the wakelock in application core (AP) (PMU_OS needs to be released since it is acquired by default when boot).
Clear the peripheralโs interrupt when wakeup.
Entering Deep-Sleep Mode๏
Deep-Sleep can also be entered from FreeRTOS Tickless flow.
When the system boots, AP holds the deepwakelock PMU_OS,
thus freertos_ready_to_dsleep() will be checked fail and the system does not enter deep-sleep mode in idle task by default.
Since freertos_ready_to_dsleep() will be checked only after freertos_ready_to_sleep() is checked pass,
both the wakelock and deepwakelock need to be released for entering deep-sleep mode.
Configuration:
Initialize the related peripheral and enable its interrupt.
Set
sleep_wakepin_config[]inameba_sleepcfg.cwhen using AON wakepin as a wakeup source.Enter deep-sleep mode by releasing the deepwakelock and wakelock in AP.
Power-Saving Configuration๏
github source code
Wakeup Mask Setup
For sleep mode, only one CPU is required to wake up to execute the program in some situations. The wakeup mask module is designed to implement this function. In general, in addition to configuring the wakeup mask, it is also necessary to register the wakeup source interrupt so that the specific CPU can handle it upon wakeup.
By setting a wakeup mask, you can choose to wake up only one CPU core. If KM4 is chosen, KM0 will be waked up first and then KM0 will resume KM4.
Users can set the wakeup attribute in sleep_wevent_config[] in ameba_sleepcfg.c to choose which CPU you want to wake up.
The wakeup attribute of each wakeup source can be set to WAKEUP_KM4 or WAKEUP_KM0 or WAKEUP_NULL,
respectively indicating that this wakeup source is only to wake up KM4, or wake up KM0, or not used as a wakeup source.
/* Wakeup entry can be set to WAKEUP_NULL/WAKEUP_KM4/WAKEUP_KM0 */
WakeEvent_TypeDef sleep_wevent_config[] = {
// Module Wakeup
{WAKE_SRC_SDIO, WAKEUP_NULL},
{WAKE_SRC_AON_WAKEPIN, WAKEUP_NULL},
{WAKE_SRC_AON_TIM, WAKEUP_NULL},
{WAKE_SRC_Keyscan, WAKEUP_NULL},
{WAKE_SRC_PWR_DOWN, WAKEUP_NULL},
{WAKE_SRC_BOR, WAKEUP_NULL},
{WAKE_SRC_ADC, WAKEUP_NULL},
{WAKE_SRC_RTC, WAKEUP_NULL},
{WAKE_SRC_CTOUCH, WAKEUP_NULL},
{WAKE_SRC_I2C1, WAKEUP_NULL},
{WAKE_SRC_I2C0, WAKEUP_NULL},
{WAKE_SRC_GPIOB, WAKEUP_NULL},
{WAKE_SRC_GPIOA, WAKEUP_NULL},
{WAKE_SRC_UART_LOG, WAKEUP_NULL},
{WAKE_SRC_UART2_BT, WAKEUP_NULL},
{WAKE_SRC_UART1, WAKEUP_NULL},
{WAKE_SRC_UART0, WAKEUP_NULL},
{WAKE_SRC_pmc_timer1, WAKEUP_KM0}, /* Internal use, do not change it */
{WAKE_SRC_pmc_timer0, WAKEUP_KM4}, /* Internal use, do not change it */
{WAKE_SRC_Timer7, WAKEUP_NULL},
{WAKE_SRC_Timer6, WAKEUP_NULL},
{WAKE_SRC_Timer5, WAKEUP_NULL},
{WAKE_SRC_Timer4, WAKEUP_NULL},
{WAKE_SRC_IPC_KM4, WAKEUP_KM4}, /* IPC can only wake up KM4, do not change it */
{WAKE_SRC_BT_WAKE_HOST, WAKEUP_NULL},
{WAKE_SRC_KM4_WAKE_IRQ, WAKEUP_KM0}, /* Internal use, do not change it */
{WAKE_SRC_WIFI_FTSR_MAILBOX, WAKEUP_KM0}, /* Wi-Fi wakeup, do not change it */
{WAKE_SRC_WIFI_FISR_FESR_IRQ, WAKEUP_KM0}, /* Wi-Fi wakeup, do not change it */
{0xFFFFFFFF, WAKEUP_NULL},
};
AON Wakepin Configuration
AON wakepin is one of the peripherals that can be set as a wakeup source.
SoC has two AON wakepins (PB30 and PB31), which can be configured in sleep_wakepin_config[] in ameba_sleepcfg.c.
The config attribute can be set to DISABLE_WAKEPIN or HIGH_LEVEL_WAKEUP or LOW_LEVEL_WAKEUP, meaning not wake up, or GPIO level high will wake up, or GPIO level low will wake up respectively.
/* can be used by sleep mode & deep sleep mode */
/* config can be set to DISABLE_WAKEPIN/HIGH_LEVEL_WAKEUP/LOW_LEVEL_WAKEUP */
WAKEPIN_TypeDef sleep_wakepin_config[] = {
// wakepin config
{WAKEPIN_0, DISABLE_WAKEPIN}, /* WAKEPIN_0 corresponding to _PB_30 */
{WAKEPIN_1, DISABLE_WAKEPIN}, /* WAKEPIN_1 corresponding to _PB_31 */
{0xFFFFFFFF, DISABLE_WAKEPIN},
};
Note
By default, AON_WAKEPIN_IRQ will not be enabled in
sleep_wakepin_config[], and users need to enable it by themselves.The wakeup mask will not be set in
sleep_wakepin_config[]. If wakepin is used for sleep mode, WAKE_SRC_AON_WAKEPIN entry needs to be set insleep_wevent_config[].
Clock and Voltage Configuration
The XTAL, OSC4M state, and sleep mode voltage are configurable in ps_config[] in ameba_sleepcfg.c.
Users can use this configuration for peripherals that need XTAL or OSC4M on in sleep mode.
PSCFG_TypeDef ps_config = {
.keep_OSC4M_on = FALSE, /* Keep OSC4M on or off for sleep */
.xtal_mode_in_sleep = XTAL_OFF, /* Set XTAL mode during sleep mode, see enum xtal_mode_sleep for details */
.sleep_to_08V = FALSE, /* Default sleep to 0.7V, setting this option to TRUE will sleep to 0.8V */
};
Sleep mode Configuration
Application software can set sleep mode to CG or PG by calling
pmu_set_sleep_type(uint32_t type)().Users can get CPUโs sleep mode by calling
pmu_get_sleep_type().
Note
KM0 and KM4 are in the same power domain, so they will have the same sleep type, thus
pmu_set_sleep_type()should be set to KM4, and KM0 will follow KM4โs sleep mode type.Sleep mode is set to PG by default. If users want to change the sleep type,
pmu_set_sleep_type()needs to be called before sleep.
github source code
Wakeup Mask Setup
For sleep mode, only one CPU is required to wake up to execute the program in some situations. The wakeup mask module is designed to implement this function. In general, in addition to configuring the wakeup mask, it is also necessary to register the wakeup source interrupt so that the specific CPU can handle it upon wakeup.
To enable a specific wakeup source, the corresponding status in array sleep_wevent_config[] in ameba_sleepcfg.c should be set. Each module can be set to WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP. For example, if the WAKE_SRC_AON_WAKEPIN module is set to WAKEUP_NP, it means that when the system is in sleep mode, KR4 will be woken up at the time that an aon_wakepin interrupt happens.
/*wakeup attribute can be set to WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP/WAKEUP_DSP*/
WakeEvent_TypeDef sleep_wevent_config[] = {
// Module wakeup
{WAKE_SRC_VAD, WAKEUP_NULL},
{WAKE_SRC_AON_WAKEPIN, WAKEUP_NULL},
{WAKE_SRC_AON_TIM, WAKEUP_NULL},
{WAKE_SRC_PWR_DOWN, WAKEUP_NULL},
{WAKE_SRC_BOR, WAKEUP_NULL},
{WAKE_SRC_ADC, WAKEUP_NULL},
{WAKE_SRC_AON_RTC, WAKEUP_NULL},
{WAKE_SRC_SPI1, WAKEUP_NULL},
{WAKE_SRC_SPI0, WAKEUP_NULL},
{WAKE_SRC_CTOUCH, WAKEUP_NULL},
{WAKE_SRC_GPIOB, WAKEUP_NULL},
{WAKE_SRC_GPIOA, WAKEUP_NULL},
{WAKE_SRC_UART_LOG, WAKEUP_AP},
{WAKE_SRC_UART3, WAKEUP_NULL},
{WAKE_SRC_UART2, WAKEUP_NULL},
{WAKE_SRC_UART1, WAKEUP_NULL},
{WAKE_SRC_UART0, WAKEUP_NULL},
{WAKE_SRC_Timer7, WAKEUP_NULL},
{WAKE_SRC_Timer6, WAKEUP_NULL},
{WAKE_SRC_Timer5, WAKEUP_NULL},
{WAKE_SRC_Timer4, WAKEUP_NULL},
{WAKE_SRC_Timer3, WAKEUP_NULL},
{WAKE_SRC_Timer2, WAKEUP_NULL},
{WAKE_SRC_Timer1, WAKEUP_NULL},
{WAKE_SRC_Timer0, WAKEUP_NULL},
{WAKE_SRC_WDG0, WAKEUP_NULL},
{WAKE_SRC_BT_WAKE_HOST, WAKEUP_NULL},
{WAKE_SRC_AP_WAKE, WAKEUP_NULL},
{WAKE_SRC_WIFI_FTSR_MAILBOX, WAKEUP_NP},
{WAKE_SRC_WIFI_FISR_FESR, WAKEUP_NP},
{0xFFFFFFFF, WAKEUP_NULL},
};
AON Wakepin Configuration
AON wakepin is one of the peripherals that can be set as a wakeup source. SoC has two AON wakepins (PA0 and PA1), which can be configured in sleep_wakepin_config[] in ameba_sleepcfg.c.
The config attribute can be set to DISABLE_WAKEPIN or HIGH_LEVEL_WAKEUP or LOW_LEVEL_WAKEUP, meaning not wake up, or GPIO level high will wake up, or GPIO level low will wake up respectively.
/* can be used by sleep mode & deep sleep mode */
/* config can be set to DISABLE_WAKEPIN/HIGH_LEVEL_WAKEUP/LOW_LEVEL_WAKEUP */
WAKEPIN_TypeDef sleep_wakepin_config[] = {
// wakepin config
{WAKEPIN_0, DISABLE_WAKEPIN}, /* WAKEPIN_0 corresponding to _PA_0 */
{WAKEPIN_1, DISABLE_WAKEPIN}, /* WAKEPIN_1 corresponding to _PA_1 */
{0xFFFFFFFF, DISABLE_WAKEPIN},
};
Note
By default, AON_WAKEPIN_IRQ will not be enabled in
sleep_wakepin_config[], and users need to enable it by themselves.The wakeup mask will not be set in
sleep_wakepin_config[]. If wakepin is used for sleep mode, WAKE_SRC_AON_WAKEPIN entry needs to be set insleep_wevent_config[].
Clock and Voltage Configuration
The XTAL, OSC4M state, and sleep mode voltage are configurable in ps_config[] in ameba_sleepcfg.c.
Users can use this configuration for peripherals that need XTAL or OSC4M on in sleep mode.
PSCFG_TypeDef ps_config = {
.keep_OSC4M_on = FALSE, /* keep OSC4M on or off for sleep */
.xtal_mode_in_sleep = XTAL_OFF, /* set xtal mode during sleep mode, see enum xtal_mode_sleep for detail */
};
Sleep Type Configuration
Application software can set sleep mode to CG or PG by calling pmu_set_sleep_type(uint32_t type)(), and users can get CPUโs sleep mode by calling pmu_get_sleep_type().
Note
KR4 and KM4 are in the same power domain, so they will have the same sleep type, thus
pmu_set_sleep_type()should be set to AP, and NP will follow APโs sleep mode type.Sleep mode is set to PG by default. If users want to change the sleep type,
pmu_set_sleep_type()needs to be called before sleep.
github source code
Wakeup Mask Setup
For sleep mode, only one CPU is required to wake up to execute the program in some situations. The wakeup mask module is designed to implement this function. In general, in addition to configuring the wakeup mask, it is also necessary to register the wakeup source interrupt so that the specific CPU can handle it upon wakeup.
To enable a specific wakeup source, the corresponding status in array sleep_wevent_config[] in ameba_sleepcfg.c should be set. Each module can be set to WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP/WAKEUP_DSP. For example, if the WAKE_SRC_AON_WAKEPIN module is set to WAKEUP_NP, it means that when the system is in sleep mode, KR4 will be woken up at the time that an aon_wakepin interrupt happens.
/*wakeup attribute can be set to WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP/WAKEUP_DSP*/
WakeEvent_TypeDef sleep_wevent_config[] = {
// Module wakeup
{WAKE_SRC_VAD, WAKEUP_NULL},
{WAKE_SRC_AON_WAKEPIN, WAKEUP_NULL},
{WAKE_SRC_AON_TIM, WAKEUP_NULL},
{WAKE_SRC_PWR_DOWN, WAKEUP_NULL},
{WAKE_SRC_BOR, WAKEUP_NULL},
{WAKE_SRC_ADC, WAKEUP_NULL},
{WAKE_SRC_AON_RTC, WAKEUP_NULL},
{WAKE_SRC_SPI1, WAKEUP_NULL},
{WAKE_SRC_SPI0, WAKEUP_NULL},
{WAKE_SRC_CTOUCH, WAKEUP_NULL},
{WAKE_SRC_GPIOB, WAKEUP_NULL},
{WAKE_SRC_GPIOA, WAKEUP_NULL},
{WAKE_SRC_UART_LOG, WAKEUP_AP},
{WAKE_SRC_UART3, WAKEUP_NULL},
{WAKE_SRC_UART2, WAKEUP_NULL},
{WAKE_SRC_UART1, WAKEUP_NULL},
{WAKE_SRC_UART0, WAKEUP_NULL},
{WAKE_SRC_Timer7, WAKEUP_NULL},
{WAKE_SRC_Timer6, WAKEUP_NULL},
{WAKE_SRC_Timer5, WAKEUP_NULL},
{WAKE_SRC_Timer4, WAKEUP_NULL},
{WAKE_SRC_Timer3, WAKEUP_NULL},
{WAKE_SRC_Timer2, WAKEUP_NULL},
{WAKE_SRC_Timer1, WAKEUP_NULL},
{WAKE_SRC_Timer0, WAKEUP_NULL},
{WAKE_SRC_WDG0, WAKEUP_NULL},
{WAKE_SRC_BT_WAKE_HOST, WAKEUP_NULL},
{WAKE_SRC_AP_WAKE, WAKEUP_NULL},
{WAKE_SRC_WIFI_FTSR_MAILBOX, WAKEUP_NP},
{WAKE_SRC_WIFI_FISR_FESR, WAKEUP_NP},
{0xFFFFFFFF, WAKEUP_NULL},
};
AON Wakepin Configuration
AON wakepin is one of the peripherals that can be set as a wakeup source. SoC has two AON wakepins (PA0 and PA1), which can be configured in sleep_wakepin_config[] in ameba_sleepcfg.c.
The config attribute can be set to DISABLE_WAKEPIN or HIGH_LEVEL_WAKEUP or LOW_LEVEL_WAKEUP, meaning not wake up, or GPIO level high will wake up, or GPIO level low will wake up respectively.
/* can be used by sleep mode & deep sleep mode */
/* config can be set to DISABLE_WAKEPIN/HIGH_LEVEL_WAKEUP/LOW_LEVEL_WAKEUP */
WAKEPIN_TypeDef sleep_wakepin_config[] = {
// wakepin config
{WAKEPIN_0, DISABLE_WAKEPIN}, /* WAKEPIN_0 corresponding to _PA_0 */
{WAKEPIN_1, DISABLE_WAKEPIN}, /* WAKEPIN_1 corresponding to _PA_1 */
{0xFFFFFFFF, DISABLE_WAKEPIN},
};
Note
By default, AON_WAKEPIN_IRQ will not be enabled in
sleep_wakepin_config[], and users need to enable it by themselves.The wakeup mask will not be set in
sleep_wakepin_config[]. If wakepin is used for sleep mode, WAKE_SRC_AON_WAKEPIN entry needs to be set insleep_wevent_config[].
Clock and Voltage Configuration
The XTAL, OSC4M state, and sleep mode voltage are configurable in ps_config[] in ameba_sleepcfg.c.
Users can use this configuration for peripherals that need XTAL or OSC4M on in sleep mode.
PSCFG_TypeDef ps_config = {
.keep_OSC4M_on = FALSE, /* keep OSC4M on or off for sleep */
.xtal_mode_in_sleep = XTAL_OFF, /* set xtal mode during sleep mode, see enum xtal_mode_sleep for detail */
};
Sleep Type Configuration
Application software can set sleep mode to CG or PG by calling pmu_set_sleep_type(uint32_t type)(), and users can get CPUโs sleep mode by calling pmu_get_sleep_type().
Note
KR4 and KM4 are in the same power domain, so they will have the same sleep type, thus
pmu_set_sleep_type()should be set to AP, and NP will follow APโs sleep mode type.Sleep mode is set to PG by default. If users want to change the sleep type,
pmu_set_sleep_type()needs to be called before sleep.
github source code
Wakeup Mask Setup
For sleep mode, only one CPU is required to wake up to execute the program in some situations. The wakeup mask module is designed to implement this function. In general, in addition to configuring the wakeup mask, it is also necessary to register the wakeup source interrupt so that the specific CPU can handle it upon wakeup.
To enable a specific wakeup source, the corresponding status in array sleep_wevent_config[] in ameba_sleepcfg.c should be set. Each module can be set to WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP/WAKEUP_DSP. For example, if the WAKE_SRC_AON_WAKEPIN module is set to WAKEUP_NP, it means that when the system is in sleep mode, KR4 will be woken up at the time that an aon_wakepin interrupt happens.
/*wakeup attribute can be set to WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP/WAKEUP_DSP*/
WakeEvent_TypeDef sleep_wevent_config[] = {
// Module wakeup
{WAKE_SRC_VAD, WAKEUP_NULL},
{WAKE_SRC_AON_WAKEPIN, WAKEUP_NULL},
{WAKE_SRC_AON_TIM, WAKEUP_NULL},
{WAKE_SRC_PWR_DOWN, WAKEUP_NULL},
{WAKE_SRC_BOR, WAKEUP_NULL},
{WAKE_SRC_ADC, WAKEUP_NULL},
{WAKE_SRC_AON_RTC, WAKEUP_NULL},
{WAKE_SRC_SPI1, WAKEUP_NULL},
{WAKE_SRC_SPI0, WAKEUP_NULL},
{WAKE_SRC_CTOUCH, WAKEUP_NULL},
{WAKE_SRC_GPIOB, WAKEUP_NULL},
{WAKE_SRC_GPIOA, WAKEUP_NULL},
{WAKE_SRC_UART_LOG, WAKEUP_AP},
{WAKE_SRC_UART3, WAKEUP_NULL},
{WAKE_SRC_UART2, WAKEUP_NULL},
{WAKE_SRC_UART1, WAKEUP_NULL},
{WAKE_SRC_UART0, WAKEUP_NULL},
{WAKE_SRC_Timer7, WAKEUP_NULL},
{WAKE_SRC_Timer6, WAKEUP_NULL},
{WAKE_SRC_Timer5, WAKEUP_NULL},
{WAKE_SRC_Timer4, WAKEUP_NULL},
{WAKE_SRC_Timer3, WAKEUP_NULL},
{WAKE_SRC_Timer2, WAKEUP_NULL},
{WAKE_SRC_Timer1, WAKEUP_NULL},
{WAKE_SRC_Timer0, WAKEUP_NULL},
{WAKE_SRC_WDG0, WAKEUP_NULL},
{WAKE_SRC_BT_WAKE_HOST, WAKEUP_NULL},
{WAKE_SRC_AP_WAKE, WAKEUP_NULL},
{WAKE_SRC_WIFI_FTSR_MAILBOX, WAKEUP_NP},
{WAKE_SRC_WIFI_FISR_FESR, WAKEUP_NP},
{0xFFFFFFFF, WAKEUP_NULL},
};
AON Wakepin Configuration
AON wakepin is one of the peripherals that can be set as a wakeup source. SoC has two AON wakepins (PA0 and PA1), which can be configured in sleep_wakepin_config[] in ameba_sleepcfg.c.
The config attribute can be set to DISABLE_WAKEPIN or HIGH_LEVEL_WAKEUP or LOW_LEVEL_WAKEUP, meaning not wake up, or GPIO level high will wake up, or GPIO level low will wake up respectively.
/* can be used by sleep mode & deep sleep mode */
/* config can be set to DISABLE_WAKEPIN/HIGH_LEVEL_WAKEUP/LOW_LEVEL_WAKEUP */
WAKEPIN_TypeDef sleep_wakepin_config[] = {
// wakepin config
{WAKEPIN_0, DISABLE_WAKEPIN}, /* WAKEPIN_0 corresponding to _PA_0 */
{WAKEPIN_1, DISABLE_WAKEPIN}, /* WAKEPIN_1 corresponding to _PA_1 */
{0xFFFFFFFF, DISABLE_WAKEPIN},
};
Note
By default, AON_WAKEPIN_IRQ will not be enabled in
sleep_wakepin_config[], and users need to enable it by themselves.The wakeup mask will not be set in
sleep_wakepin_config[]. If wakepin is used for sleep mode, WAKE_SRC_AON_WAKEPIN entry needs to be set insleep_wevent_config[].
Clock and Voltage Configuration
The XTAL, OSC4M state, and sleep mode voltage are configurable in ps_config[] in ameba_sleepcfg.c.
Users can use this configuration for peripherals that need XTAL or OSC4M on in sleep mode.
PSCFG_TypeDef ps_config = {
.keep_OSC4M_on = FALSE, /* keep OSC4M on or off for sleep */
.xtal_mode_in_sleep = XTAL_OFF, /* set xtal mode during sleep mode, see enum xtal_mode_sleep for detail */
};
Sleep Type Configuration
Application software can set sleep mode to CG or PG by calling pmu_set_sleep_type(uint32_t type)(), and users can get CPUโs sleep mode by calling pmu_get_sleep_type().
Note
KR4 and KM4 are in the same power domain, so they will have the same sleep type, thus
pmu_set_sleep_type()should be set to AP, and NP will follow APโs sleep mode type.Sleep mode is set to PG by default. If users want to change the sleep type,
pmu_set_sleep_type()needs to be called before sleep.
github source code
Wakeup Mask Setup
For sleep mode, only one CPU is required to wake up to execute the program in some situations. The wakeup mask module is designed to implement this function. In general, in addition to configuring the wakeup mask, it is also necessary to register the wakeup source interrupt so that the specific CPU can handle it upon wakeup.
By setting a wakeup mask, you can choose to wake up only one CPU core. If KM4 is chosen, KM0 will be waked up first and then KM0 will resume KM4. And if CA32 is chosen, KM0 will be waked up first and then KM0 will resume KM4, and CA32 will be resumed at last.
Users can set the wakeup attribute in sleep_wevent_config[] in ameba_sleepcfg.c to choose which CPU you want to wake up.
The wakeup attribute of each wakeup source can be set to WAKEUP_KM4 or WAKEUP_KM0 or WAKEUP_NULL,
respectively indicating that this wakeup source is only to wake up KM4, or wake up KM0, or not used as a wakeup source.
/*wakeup attribute can be set to WAKEUP_NULL/WAKEUP_LP/WAKEUP_NP/WAKEUP_AP*/
WakeEvent_TypeDef sleep_wevent_config[] = {
// Module wakeup
{WAKE_SRC_nFIQOUT1_OR_nIRQOUT1, WAKEUP_NULL},
{WAKE_SRC_nFIQOUT0_OR_nIRQOUT0, WAKEUP_NULL},
{WAKE_SRC_BT_WAKE_HOST, WAKEUP_NULL},
{WAKE_SRC_AON_WAKEPIN, WAKEUP_NULL},
{WAKE_SRC_UART2, WAKEUP_NULL},
{WAKE_SRC_UART1, WAKEUP_NULL},
{WAKE_SRC_UART0, WAKEUP_NULL},
{WAKE_SRC_SPI1, WAKEUP_NULL},
{WAKE_SRC_SPI0, WAKEUP_NULL},
{WAKE_SRC_IPC_AP, WAKEUP_AP}, /* do not change it */
{WAKE_SRC_IPC_NP, WAKEUP_NP}, /* do not change it */
{WAKE_SRC_VADBT_OR_VADPC, WAKEUP_NULL},
{WAKE_SRC_PWR_DOWN, WAKEUP_LP},
{WAKE_SRC_BOR, WAKEUP_NULL},
{WAKE_SRC_ADC, WAKEUP_NULL},
{WAKE_SRC_CTOUCH, WAKEUP_NULL},
{WAKE_SRC_RTC, WAKEUP_NULL},
{WAKE_SRC_GPIOC, WAKEUP_NULL},
{WAKE_SRC_GPIOB, WAKEUP_NULL},
{WAKE_SRC_GPIOA, WAKEUP_NULL},
{WAKE_SRC_UART_LOG, WAKEUP_NULL},
{WAKE_SRC_Timer7, WAKEUP_NULL},
{WAKE_SRC_Timer6, WAKEUP_NP},
{WAKE_SRC_Timer5, WAKEUP_NULL},
{WAKE_SRC_Timer4, WAKEUP_NULL},
{WAKE_SRC_Timer3, WAKEUP_NULL},
{WAKE_SRC_Timer2, WAKEUP_NULL},
{WAKE_SRC_Timer1, WAKEUP_NULL},
{WAKE_SRC_Timer0, WAKEUP_NULL},
{WAKE_SRC_WDG0, WAKEUP_NULL},
{WAKE_SRC_AP_WAKE, WAKEUP_NULL},
{WAKE_SRC_NP_WAKE, WAKEUP_NULL},
{WAKE_SRC_AON_TIM, WAKEUP_NULL},
{WAKE_SRC_WIFI_FTSR_MAILBOX, WAKEUP_LP}, /* Wi-Fi wakeup, do not change it */
{WAKE_SRC_WIFI_FISR_FESR, WAKEUP_LP}, /* Wi-Fi wakeup, do not change it */
{0xFFFFFFFF, WAKEUP_NULL}, /* Table end */
};
AON Wakepin Configuration
AON wakepin is one of the peripherals that can be set as a wakeup source.
SoC has four AON wakepins (PB21, PB22, PB23 and PB24), which can be configured in sleep_wakepin_config[] in ameba_sleepcfg.c.
The config attribute can be set to DISABLE_WAKEPIN or HIGH_LEVEL_WAKEUP or LOW_LEVEL_WAKEUP, meaning not wake up, or GPIO positive pulse will wake up, or GPIO negative pulse will wake up respectively.
/* can be used by sleep mode & deep sleep mode */
/* config can be set to DISABLE_WAKEPIN/HIGH_LEVEL_WAKEUP/LOW_LEVEL_WAKEUP */
WAKEPIN_TypeDef sleep_wakepin_config[] = {
// wakepin config
{WAKEPIN_0, DISABLE_WAKEPIN}, /* WAKEPIN_0 corresponding to _PB_21 */
{WAKEPIN_1, DISABLE_WAKEPIN}, /* WAKEPIN_1 corresponding to _PB_22 */
{WAKEPIN_2, DISABLE_WAKEPIN}, /* WAKEPIN_2 corresponding to _PB_23 */
{WAKEPIN_3, DISABLE_WAKEPIN}, /* WAKEPIN_3 corresponding to _PB_24 */
{0xFFFFFFFF, DISABLE_WAKEPIN}, /* Table end */
}
Note
PB23andPB24is for loguart trx by default, ifPB23andPB24is needed to wake up system from deep-sleep, contact realtek for help. Active and sleep mode of pin is controlled by pinmap config, changepmap_func[]inameba_pinmapcfg.cif needed.By default, AON_WAKEPIN_IRQ will not be enabled in
sleep_wakepin_config[], and users need to enable it by themselves.The wakeup mask will not be set in
sleep_wakepin_config[]. If wakepin is used for sleep mode, WAKE_SRC_AON_WAKEPIN entry needs to be set insleep_wevent_config[].
Clock and Voltage Configuration
The XTAL, OSC4M state are configurable in ps_config[] in ameba_sleepcfg.c. Users can use this configuration for peripherals that need XTAL or OSC4M on in sleep mode.
PSCFG_TypeDef ps_config = {
.km0_tickles_debug = TRUE,/* if open WIFI FW, should close it, or beacon will lost in WOWLAN */
.km0_pll_off = TRUE,
.km0_audio_vad_on = FALSE,
#if defined(CONFIG_CLINTWOOD ) && CONFIG_CLINTWOOD
.km0_config_psram = FALSE, /* if device enter sleep mode or not, false for keep active */
.km0_sleep_withM4 = FALSE,
#else
.km0_config_psram = TRUE, /* if device enter sleep mode or not, false for keep active */
.km0_sleep_withM4 = TRUE,
#endif
.keep_OSC4M_on = FALSE,
.xtal_mode_in_sleep = XTAL_OFF,
.swr_mode_in_sleep = SWR_PFM,
};
UART and LOGUART๏
For peripherals that require specific clock settings, such as UART and LOGUART, the configuration procedures are described in the following sections.
Initialize UART/LOGUART and enable their interrupts.
Set the wake-up source: In
sleep_wevent_config[], configure the wake-up source (UART0/UART1/UART2_BT/UART_LOG) and specify the CPU to be woken up (WAKEUP_KM4 or WAKEUP_KM0). Ensure the interrupt is registered on the CPU to be woken up.Select the clock source:
XTAL: In
ps_config[], set xtal_mode_in_sleep to XTAL_Normal and set keep_OSC4M_on to TRUE.OSC2M: In
ps_config[], set keep_OSC4M_on to TRUE.
Set the operating voltage: In
ps_config[], setsleep_to_08Vto TRUE.Enter sleep mode by releasing the wake lock on KM4 (PMU_OS needs to be released because it is acquired by default at system startup).
Clear the UART/LOGUART interrupt after waking up.
Note
When using UART as a wake-up source, the following limitations apply:
The Rx clock source can only be OSC2M, and OSC4M must not be turned off during sleep. It is not recommended to use UART as a wake-up source when the baud rate is greater than 115200.
Before sleep, you need to call the API
RCC_PeriphClockSource_UART(UARTx_DEV, UART_RX_CLK_OSC_LP)to switch the clock to OSC2M.If higher baud rate is required after waking up, you can use the API
RCC_PeriphClockSource_UART(UARTx_DEV, UART_RX_CLK_XTAL_40M)to switch to XTAL40M Rx clock.
Any part of commands used for wake-up that exceed the FIFO depth (64 bytes) will be lost.
When using LOGUART as a wake-up source, the following limitations apply:
If the Rx clock source is OSC2M, OSC4M must not be turned off during sleep.
Before sleep, you need to call the API
RCC_PeriphClockSource_LOGUART(LOGUART_CLK_OSC_LP)to switch the clock to OSC2M.If higher baud rate is required after waking up, you can use the API
RCC_PeriphClockSource_LOGUART(LOGUART_CLK_XTAL_40M)to switch to XTAL40M Rx clock.
If the Rx clock source is XTAL40M, XTAL must not be turned off during sleep.
Any part of commands used for wake-up that exceed the FIFO depth (16 bytes) will be lost.
For peripherals that require specific clock settings, such as UART and LOGUART, the configuration procedures are described in the following sections.
Initialize UART/LOGUART and enable their interrupts.
Set the wake-up source: In
sleep_wevent_config[], set the wake-up source (UART0/UART1/UART2/UART3/UART_LOG) and specify the CPU to be woken up (WAKEUP_AP or WAKEUP_NP). Ensure the interrupt is registered on the CPU to be woken up.Set the clock source: In
ps_config[], set xtal_mode_in_sleep to XTAL_Normal.Enter sleep mode by releasing the wake lock on KM4 (PMU_OS needs to be released because it is acquired by default at system startup).
Clear the UART/LOGUART interrupt upon waking up.
Note
When using UART as a wake-up source, the following limitations exist:
When the Rx clock source is XTAL40M, do not turn off XTAL during sleep.
Any part of a wake-up command exceeding the FIFO depth (64 bytes) will be lost.
When using LOGUART as a wake-up source, the following limitations exist:
When the Rx clock source is XTAL40M, do not turn off XTAL during sleep.
Any part of a wake-up command exceeding the FIFO depth (16 bytes) will be lost.
For peripherals that require specific clock settings, such as UART and LOGUART, the configuration procedures are described in the following sections.
Initialize UART/LOGUART and enable their interrupts.
Set the wake-up source: In
sleep_wevent_config[], set the wake-up source (UART0/UART1/UART2/UART3/UART_LOG) and specify the CPU to be woken up (WAKEUP_AP or WAKEUP_NP). Ensure the interrupt is registered on the CPU to be woken up.Set the clock source: In
ps_config[], set xtal_mode_in_sleep to XTAL_Normal.Enter sleep mode by releasing the wake lock on KM4 (PMU_OS needs to be released because it is acquired by default at system startup).
Clear the UART/LOGUART interrupt upon waking up.
Note
When using UART as a wake-up source, the following limitations exist:
When the Rx clock source is XTAL40M, do not turn off XTAL during sleep.
Any part of a wake-up command exceeding the FIFO depth (64 bytes) will be lost.
When using LOGUART as a wake-up source, the following limitations exist:
When the Rx clock source is XTAL40M, do not turn off XTAL during sleep.
Any part of a wake-up command exceeding the FIFO depth (16 bytes) will be lost.
For peripherals that require specific clock settings, such as UART and LOGUART, the configuration procedures are described in the following sections.
Initialize UART/LOGUART and enable their interrupts.
Set the wake-up source: In
sleep_wevent_config[], set the wake-up source (UART0/UART1/UART2/UART3/UART_LOG) and specify the CPU to be woken up (WAKEUP_AP or WAKEUP_NP). Ensure the interrupt is registered on the CPU to be woken up.Set the clock source: In
ps_config[], set xtal_mode_in_sleep to XTAL_Normal.Enter sleep mode by releasing the wake lock on KM4 (PMU_OS needs to be released because it is acquired by default at system startup).
Clear the UART/LOGUART interrupt upon waking up.
Note
When using UART as a wake-up source, the following limitations exist:
When the Rx clock source is XTAL40M, do not turn off XTAL during sleep.
Any part of a wake-up command exceeding the FIFO depth (64 bytes) will be lost.
When using LOGUART as a wake-up source, the following limitations exist:
When the Rx clock source is XTAL40M, do not turn off XTAL during sleep.
Any part of a wake-up command exceeding the FIFO depth (16 bytes) will be lost.
For peripherals that require specific clock settings, such as UART and LOGUART, the configuration procedures are described in the following sections.
Initialize UART/LOGUART and enable their interrupts.
Set the wake-up source: In
sleep_wevent_config[], set the relevant wake-up source (UART0/UART1/UART2/UART_LOG) and specify the CPU to be woken up (WAKEUP_AP/WAKEUP_NP/WAKEUP_LP). Ensure the interrupt is registered on the corresponding CPU.Select the clock source:
XTAL: In
ps_config[], set xtal_mode_in_sleep to XTAL_Normal and set keep_OSC4M_on to TRUE.OSC2M: In
ps_config[], set keep_OSC4M_on to TRUE.
Enter sleep mode by releasing the wake lock on KM4 (PMU_OS needs to be released because it is acquired by default at system startup).
Clear the UART/LOGUART interrupt upon wake-up.
Note
When using UART as a wake-up source, the following limitations apply:
If the Rx clock source is XTAL40M, do not turn off XTAL during sleep.
If the Rx clock source is OSC2M, do not turn off OSC4M during sleep.
Before sleep, call the API
RCC_PeriphClockSource_UART(UARTx_DEV, UART_RX_CLK_OSC_LP)to switch the clock to OSC2M.If a higher baud rate is needed after waking up, call
RCC_PeriphClockSource_UART(UARTx_DEV, UART_RX_CLK_XTAL_40M)to switch to XTAL40M Rx clock.
Any part of a wake-up command exceeding the FIFO depth (64 bytes) will be lost.
When using LOGUART as a wake-up source, the following limitations apply:
If the Rx clock source is XTAL40M, do not turn off XTAL during sleep.
If the Rx clock source is OSC2M, do not turn off OSC4M during sleep.
Before sleep, call the API
RCC_PeriphClockSource_LOGUART(UARTLOG_CLK_OSC_LP)to switch the clock to OSC2M.If a higher baud rate is needed after waking up, call
RCC_PeriphClockSource_LOGUART(UARTLOG_CLK_XTAL_40M)to switch to XTAL40M Rx clock.
Any part of a wake-up command exceeding the FIFO depth (16 bytes) will be lost.