AON

HAL AON provides abstract software interface to operate hardware AON (Always On) module, used to control low power modes of various subsystems in the chip. The chip is divided into HPSYS and LPSYS subsystems (power domains), corresponding to HPAON (hwp_hpsys_aon) and LPAON (hwp_lpsys_aon) respectively. The control methods for both power domains are similar, and supported features include:

  • PIN, RTC, LPTIM, MAILBOX and manual wakeup. PIN wakeup can be level-triggered or edge-triggered. Manual wakeup means another core operates specific registers to wake up the designated core. MAILBOX wakeup means waking up the corresponding core by triggering mailbox interrupt, for example, LPSYS can configure #L2H_MAILBOX to trigger MAILBOX interrupt to HPSYS, if HPSYS enables MAILBOX wakeup, it can be automatically awakened by this interrupt.

  • Supported wakeup sources are different among chip series (the LPSYS of some series also supports LPCOMP and BLE/BT wakeup), and the number of wakeup PINs and their mapping are also different, refer to Wakeup PIN to GPIO Pin Mapping

  • Supports LIGHT/DEEP/STANDBY three low power modes. In LIGHT and DEEP modes, digital modules will not power down, all registers and SRAM will be retained. In STANDBY mode, digital modules will power down, all registers will be lost, SRAM can be selectively retained.

Note

Due to delay in PIN edge detection, if woken up by other wakeup sources when there’s a wakeup PIN level change, the PIN wakeup flag in WSR register may still be 0 when AON interrupt occurs, and becomes 1 after a while. Since the corresponding GPIO edge detection is not ready yet, the PIN wakeup status in WSR register won’t be cleared and will keep not sleeping while missing one GPIO interrupt for edge detection. If not using SysTick_Handler implemented in drv_common.c in SDK as SysTick interrupt service routine, it’s recommended to add the following code in custom SysTick interrupt service routine. When edge-triggered wakeup PIN flag is found to be 1, manually trigger GPIO interrupt callback function once.

    /* Trigger GPIO callback manually as GPIO edge detection interrupt may get lost
    and WSR.PIN status is not cleared */
#ifdef SOC_BF0_HCPU
    status = HAL_HPAON_GET_WSR() & HPSYS_AON_WSR_PIN_ALL;
    pin_wsr = status >> HPSYS_AON_WSR_PIN0_Pos;
    HAL_HPAON_CLEAR_WSR(status);
    wake_pin_num = HPSYS_AON_WSR_PIN_NUM;
#else
    status = HAL_LPAON_GET_WSR() & LPSYS_AON_WSR_PIN_ALL;
    pin_wsr = status >> LPSYS_AON_WSR_PIN0_Pos;
    HAL_LPAON_CLEAR_WSR(status);
    wake_pin_num = LPSYS_AON_WSR_PIN_NUM;
#endif

    for (i = 0; (i < wake_pin_num) && pin_wsr; i++)
    {
        if (pin_wsr & 1)
        {

            hal_status = HAL_AON_GetWakePinMode(i, &pin_mode);
            if ((HAL_OK == hal_status) && (pin_mode != AON_PIN_MODE_HIGH)
                    && (pin_mode != AON_PIN_MODE_LOW))
            {
                gpio = HAL_AON_QueryWakeupGpioPin(i, &pin);
                RT_ASSERT(gpio);
                HAL_GPIO_EXTI_Callback(gpio, pin);
            }
        }
        pin_wsr >>= 1;
    }

Wakeup PIN to GPIO Pin Mapping

A wakeup PIN is bound to a fixed GPIO pin, HAL_HPAON_QueryWakeupPin() / HAL_HPAON_QueryWakeupGpioPin() (HAL_LPAON_QueryWakeupPin() / HAL_LPAON_QueryWakeupGpioPin() for LPSYS) can be used to query one from the other, refer to API Reference. Supported wakeup sources and the number of wakeup PINs are different among chip series, they are described below per series. PBRn in the tables means the key pin in RTC domain, refer to PIN device for its numbering.

SF32LB52X

HPSYS and LPSYS each support 15 wakeup PINs, and they are mapped to the same GPIO pins, so HAL_LPAON_QueryWakeupPin() / HAL_LPAON_QueryWakeupGpioPin() in SDK directly reuse the implementations of HPSYS.

  • HPSYS wakeup sources: HPAON_WAKEUP_SRC_RTC, HPAON_WAKEUP_SRC_LPTIM1, HPAON_WAKEUP_SRC_PMUC, HPAON_WAKEUP_SRC_GPIO1, HPAON_WAKEUP_SRC_LP2HP_REQ (manual wakeup), HPAON_WAKEUP_SRC_LP2HP_IRQ (MAILBOX wakeup), and 21 wakeup PINs HPAON_WAKEUP_SRC_PIN0 ~ HPAON_WAKEUP_SRC_PIN20

  • LPSYS wakeup sources: LPAON_WAKEUP_SRC_RTC, LPAON_WAKEUP_SRC_LPTIM3, LPAON_WAKEUP_SRC_GPIO2, LPAON_WAKEUP_SRC_BT, LPAON_WAKEUP_SRC_HP2LP_REQ (manual wakeup), LPAON_WAKEUP_SRC_HP2LP_IRQ (MAILBOX wakeup), and 21 wakeup PINs LPAON_WAKEUP_SRC_PIN0 ~ LPAON_WAKEUP_SRC_PIN20

HPSYS/LPSYS wakeup PIN mapping table:

Wakeup PIN

GPIO pin

PIN0

GPIO_A24

PIN1

GPIO_A25

PIN2

GPIO_A26

PIN3

GPIO_A27

PIN10

GPIO_A34

PIN11

GPIO_A35

PIN12

GPIO_A36

PIN13

GPIO_A37

PIN14

GPIO_A38

PIN15

GPIO_A39

PIN16

GPIO_A40

PIN17

GPIO_A41

PIN18

GPIO_A42

PIN19

GPIO_A43

PIN20

GPIO_A44

Note

  • PIN4 ~ PIN9 (PA28 ~ PA33) are shared with ADC and their wakeup function has been removed, they can’t be used as wakeup sources, so they are not listed in the table above. The numbering of wakeup PINs is still continuous, that is, PIN10 is mapped to PA34.

  • 52X has no dedicated PBR pin like 56X and 58X, PBR0 ~ PBR3 share the pad with PA24 ~ PA27 (that is, PIN0 ~ PIN3), and AON PIN wakeup detection is done by PBR module, so SDK also enables the input of the corresponding PBR when PIN0 ~ PIN3 are enabled as wakeup sources.

  • Sleep in DEEPSLEEP mode doesn’t need extra wakeup PIN configuration, the wakeup source is HPAON_WAKEUP_SRC_GPIO1, which is enabled by PM framework by default.

Using HAL HPAON

Configure Sleep

void example(void)
{
    /* Enable LPTIM1 as wakeup source */
    HAL_HPAON_EnableWakeupSrc(HPAON_WAKEUP_SRC_LPTIM1, AON_PIN_MODE_HIGH);
    /* Enable MAILBOX interrupt triggered by LPSYS as wakeup source */
    HAL_HPAON_EnableWakeupSrc(HPAON_WAKEUP_SRC_LP2HP_IRQ, AON_PIN_MODE_HIGH);
    /* Enable manual wakeup triggered by LPSYS */
    HAL_HPAON_EnableWakeupSrc(HPAON_WAKEUP_SRC_LP2HP_REQ, AON_PIN_MODE_HIGH);
    /* Enable PIN0 low level wakeup, PIN0 is bound to a fixed gpio pin,
       refer to the wakeup pin mapping table of the target chip series */
    HAL_HPAON_EnableWakeupSrc(HPAON_WAKEUP_SRC_PIN0, AON_PIN_MODE_LOW);

    ...

    /* Configure HPSYS enter LIGHT mode */
    HAL_HPAON_EnterLightSleep(0);
}

Query Wakeup PIN and Corresponding GPIO Pin

void example(void)
{
    int8_t wakeup_pin;
    uint16_t gpio_pin;
    GPIO_TypeDef *gpio;

    /* Query which wakeup pin is mapping to the gpio pin, take GPIO_A80 of
       SF32LB55X as an example, if found return value >=0, otherwise, return -1 */
    wakeup_pin = HAL_HPAON_QueryWakeupPin(hwp_gpio1, 80);

    /* Query which GPIO PIN is mapping to wakeup pin0,
       if found, return GPIO instance and pin id, otherwise return NULL */
    gpio = HAL_HPAON_QueryWakeupGpioPin(0, &gpio_pin);
}

Using HAL LPAON

Configure Sleep

void example(void)
{
    /* Enable LPTIM2 as wakeup source */
    HAL_LPAON_EnableWakeupSrc(LPAON_WAKEUP_SRC_LPTIM2, AON_PIN_MODE_HIGH);
    /* Enable MAILBOX interrupt triggered by HPSYS as wakeup source */
    HAL_LPAON_EnableWakeupSrc(LPAON_WAKEUP_SRC_HP2LP_IRQ, AON_PIN_MODE_HIGH);
    /* Enable manual wakeup triggered by HPSYS */
    HAL_LPAON_EnableWakeupSrc(LPAON_WAKEUP_SRC_HP2LP_REQ, AON_PIN_MODE_HIGH);
    /* Enable PIN0 low level wakeup, PIN0 is bound to a fixed gpio pin,
       refer to the wakeup pin mapping table of the target chip series */
    HAL_LPAON_EnableWakeupSrc(LPAON_WAKEUP_SRC_PIN0, AON_PIN_MODE_LOW);

    ...

    /* Configure LPSYS enter LIGHT mode */
    HAL_LPAON_EnterLightSleep(0);
}

Query Wakeup PIN and Corresponding GPIO Pin

void example(void)
{
    int8_t wakeup_pin;
    uint16_t gpio_pin;
    GPIO_TypeDef *gpio;

    /* Query which wakeup pin is mapping to the gpio pin, take GPIO_B43 of
       SF32LB55X as an example, if found return value >=0, otherwise, return -1 */
    wakeup_pin = HAL_LPAON_QueryWakeupPin(hwp_gpio2, 43);

    /* Query which GPIO PIN is mapping to wakeup pin0,
       if found, return GPIO instance and pin id, otherwise return NULL */
    gpio = HAL_LPAON_QueryWakeupGpioPin(0, &gpio_pin);
}

API Reference

bf0_hal_aon.h