Concepts First
- Low-power modes: when the chip has nothing to do, it "sleeps" and turns off most circuits to save power. BL616/BL618 mainly provide PDS (light sleep, peripherals powered down) and HBN (hibernate, only the AON domain runs).
- Timed wake-up: the 32K clock keeps running during sleep; the RTC wakes the chip after the configured time. The example wakes every 1 second.
- Wake-up sources: the "alarms" that can wake the chip — RTC timer, GPIO edges/levels, BOD brown-out detection, etc. The example masks all sources with
pm_pds_mask_all_wakeup_src()and enables the RTC timer via the sleep-time argument ofpm_pds_mode_enter. - Sleep-time unit:
pm_pds_mode_enter'ssleep_timeis in 32K clock cycles (32768 cycles = 1 second); the example uses32768 * 1.
Example Overview
This page is based on the pds_rtc example in the official Bouffalo SDK (examples/pmu/bl616/pds_rtc), which demonstrates PDS deep sleep + RTC timed wake-up:
- Before sleeping: disables the USB PHY power switch, masks all wake-up sources, floats the RF LDO15 output, and masks HBN pin wake-ups;
- Prints
enter pds mode, then callspm_pds_mode_enter(PM_PDS_LEVEL_15, 32768 * 1)to enter PDS level 15, the deepest sleep level; - Wakes every 1 second via the RTC timer and re-runs the main flow — a periodic wake-up loop;
- To measure power, put a multimeter in series with the supply and observe the sleep current (far lower than normal operation).
- Sibling examples (
examples/pmu/bl616/):hbn_rtc(HBN deep sleep + RTC wake-up),hbn_io_wakeup(HBN + GPIO wake-up),pds_io_wakeup(PDS + GPIO wake-up).
Note
Serial output pauses during sleep and only appears at the wake-up moment; that is normal. Do not unplug the debug cable while observing, since the debug power may affect current measurements.
Operation Steps
No external wiring is needed for this page. Open a terminal and enter the SDK PDS sleep example directory (prerequisite: set up the environment as in Quick Start (Linux) or Windows):
cd examples/pmu/bl616/pds_rtcRun the build command. The Ai-M62 (BL616) and Ai-M61 (BL618) belong to the same series, so both use bl616:
make CHIP=bl616 BOARD=bl616dkConnect the board with a USB cable, hold the BOOT button (IO2 on the Ai-M61-32S-Kit), briefly press EN/RST to enter download mode, then flash (replace the serial port with the one on your computer):
make flash CHIP=bl616 COMX=/dev/ttyUSB0Open a serial tool (baud rate 2000000). The program prints enter pds mode and enters PDS deep sleep; the RTC timer wakes it 1 second later, it prints the same message, and sleeps again — a 1-second wake-up loop you can observe on the serial port.
Code Execution Flow
The complete flow from startup to sleep and timed wake-up is shown below (loop arrows mean repeated execution):
APIs Used by the Example
BL_RD_REG / BL_CLR_REG_BIT / BL_WR_REG(base, reg / bit / val)
Register bit macros: BL_RD_REG reads a register, BL_CLR_REG_BIT clears a bit, BL_WR_REG writes back. The example uses them to disable the USB PHY power switch bit PDS_REG_PU_USB20_PSW.
Parameters:
base: register base (PDS_BASEin the example)reg: register offset (PDS_USB_PHY_CTRLin the example)val: value / bit number
Return: BL_RD_REG returns the register value; the macros return nothing
pm_pds_mask_all_wakeup_src()
Masks (disables) all PDS wake-up sources to avoid spurious wake-ups. The example then enables RTC timed wake-up only through the sleep-time argument of pm_pds_mode_enter.
Parameters: none
Return: none
AON_Output_Float_LDO15_RF()
Floats the LDO15 output that powers RF, reducing power further during sleep.
Parameters: none
Return: BL_Err_Type (SUCCESS is 0)
HBN_Pin_WakeUp_Mask(0xF)
Masks HBN (AON) pin wake-ups: 0xF masks all four wake-up pins (IO16–IO19).
Parameters:
maskVal: pin mask; bits set to 1 disable wake-up on that pin
Return: BL_Err_Type
pm_pds_mode_enter(pds_level, sleep_time)
Enters PDS sleep. sleep_time is in 32K clock cycles (32768 = 1 second); 0 disables RTC timed wake-up, so another source (e.g. GPIO) must wake the chip.
Parameters:
pds_level: sleep level,PM_PDS_LEVEL_15(deepest) in the examplesleep_time: sleep duration in 32K cycles,32768 * 1(1 second) in the example
Return: none
Complete Code
The complete source below matches the official example (examples/pmu/bl616/pds_rtc) verbatim. Collapsed by default, click to expand:
📜 Click to expand pds_rtc/main.c full code
#include "bflb_mtimer.h"
#include "board.h"
#include "log.h"
#include "bl616_glb.h"
#include "bl616_pds.h"
#include "bl616_hbn.h"
#include "bl616_aon.h"
#include "bl616_pm.h"
int main(void)
{
uint32_t tmpVal = 0;
board_init();
/* rf808_usb20_psw_rref output off */
tmpVal = BL_RD_REG(PDS_BASE, PDS_USB_PHY_CTRL);
tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_REG_PU_USB20_PSW);
BL_WR_REG(PDS_BASE, PDS_USB_PHY_CTRL, tmpVal);
pm_pds_mask_all_wakeup_src();
AON_Output_Float_LDO15_RF();
HBN_Pin_WakeUp_Mask(0xF);
printf("enter pds mode\r\n");
bflb_mtimer_delay_ms(100);
/* Wake up every 1 seconds by pds15 */
pm_pds_mode_enter(PM_PDS_LEVEL_15, 32768 * 1);
while (1) {
}
}FAQ
The chip never wakes up
Check the wake-up configuration: if sleep_time in pm_pds_mode_enter is 0 there is no timed wake-up — you must enable a GPIO or another wake-up source. Also make sure you did not mask everything with pm_pds_mask_all_wakeup_src() and forget to enable the source you need.
The wake-up period is not 1 second
sleep_time is in 32K cycles. If the 32K clock is inaccurate (uncalibrated RC 32K), the interval drifts; for high accuracy use an external 32.768 kHz crystal or calibrate with pm_rc32k_auto_cal().
What is the difference between PDS and HBN
PDS is lighter and wakes faster; peripherals lose power but SRAM contents are kept. HBN (hibernate) keeps only the AON domain and consumes the least power. Battery-powered periodic reporting often combines both: HBN most of the time, waking into PDS to handle tasks.
Have questions?
For any other questions, visit the unified Q&A and discussion board: Ai-Thinker Discussions

