RTC - DLPS
当系统处于 IDLE 状态时,会自动进入 DLPS 状态。当 RTC 定时结束后会将系统从 DLPS 唤醒,同时触发 RTC 中断。
RTC 的 Tick 中断,溢出中断,4 路比较器中断和分频比较器中断均可以唤醒系统。
该示例以 Tick 定时唤醒进行说明举例。
环境需求
该示例支持以下开发套件:
Hardware Platforms |
Board Name |
---|---|
RTL8752H HDK |
RTL8752H EVB |
更多信息请参考 快速入门。
编译和下载
该示例的工程路径如下:
Project file: board\evb\io_sample\RTC\Dlps\mdk
Project file: board\evb\io_sample\RTC\Dlps\gcc
请按照以下步骤操作构建并运行该示例:
打开工程文件。
按照 快速入门 中 编译 APP Image 给出的步骤构建目标文件。
编译成功后,在路径
mdk\bin
或gcc\bin
下会生成 app binapp_MP_xxx.bin
文件。按下 reset 按键,开始运行。
测试验证
当 EVB 复位后,系统进入 DLPS 状态。在 Debug Analyzer 工具内打印相应信息。
DLPS ENTER
当 Tick 定时结束后(1s),系统被唤醒,退出 DLPS 状态。在 Debug Analyzer 工具内打印相应信息。
DLPS EXIT, wake up reason 0x200
系统被唤醒的同时会触发 RTC 中断,在 Debug Analyzer 工具内打印相应信息。
RTC_Handler RTC_INT_TICK
退出中断处理函数后,系统会重新进入 DLPS 状态,循环往复。
代码介绍
该章节分为以下几个部分:
源码路径
工程路径:
sdk\board\evb\io_sample\RTC\Dlps
源码路径:
sdk\src\sample\io_sample\RTC\Dlps
该工程的工程文件代码结构如下:
└── Project: rtc_dlps
└── secure_only_app
└── include
├── app_define.h
└── rom_uuid.h
├── cmsis includes CMSIS header files and startup files
├── overlay_mgr.c
├── system_rtl876x.c
└── startup_rtl876x.s
├── lib includes all binary symbol files that user application is built on
├── rtl8752h_sdk.lib
├── gap_utils.lib
└── ROM.lib
├── peripheral includes all peripheral drivers and module code used by the application
├── rtl876x_rcc.c
├── rtl876x_nvic.c
├── rtl876x_io_dlps.c
└── rtl876x_rtc.c
├── profile
└── app includes the ble_peripheral user application implementation
├── main.c
└── io_rtc.c
初始化
当 EVB 复位启动时,调用 main()
函数,将执行以下流程:
int main(void)
{
extern uint32_t random_seed_value;
srand(random_seed_value);
board_init();
driver_init();
pwr_mgr_init();
os_sched_start();
return 0;
}
其中与外设相关的初始化流程如下:
在
driver_init
中执行driver_rtc_init
,该函数为 RTC 外设的初始化,包含如下流程:复位 RTC 外设。
设置 RTC 分频系数为(3200-1),RTC 时钟频率为 10Hz。
使能 RTC 滴答中断
RTC_INT_TICK
。配置并使能 RTC 的 IRQ 通道,开启 CPU 的 NVIC 中断。
执行
RTC_SystemWakeupConfig()
,使能 RTC 唤醒功能。复位 RTC 计数值,使能 RTC 外设。
void driver_rtc_init(void) { RTC_DeInit(); RTC_SetPrescaler(RTC_PRESCALER_VALUE); RTC_SetPreCompValue(0); RTC_INTConfig(RTC_INT_TICK, ENABLE); ... /* Config RTC interrupt */ NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn; NVIC_InitStruct.NVIC_IRQChannelPriority = 2; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); RTC_NvCmd(ENABLE); RTC_SystemWakeupConfig(ENABLE); /* Start RTC */ RTC_ResetCounter(); RTC_Cmd(ENABLE); }
执行
pwr_mgr_init
,该函数为 DLPS 的电压模式设置,包含如下流程:注册用户进入 DLPS 回调函数
app_enter_dlps_config
,注册用户退出 DLPS 回调函数app_exit_dlps_config
。在
app_enter_dlps_config
内打印进入 DLPS 信息。void app_enter_dlps_config(void) { DBG_DIRECT("DLPS ENTER"); }
在
app_exit_dlps_config
内打印 DLPS 唤醒信息,记录唤醒次数 +1。void app_exit_dlps_config(void) { allow_count ++; DBG_DIRECT("DLPS EXIT, wake up reason 0x%x", platform_pm_get_wakeup_reason()); }
注册硬件控制回调函数
DLPS_IO_EnterDlpsCb
和DLPS_IO_ExitDlpsCb
,进入 DLPS 会保存 CPU、PINMUX、Peripheral 等,退出 DLPS 会恢复 CPU、PINMUX、Peripheral 等。设置电源模式为 DLPS 模式。
void pwr_mgr_init(void) { dlps_check_cb_reg(app_dlps_check_cb); DLPS_IORegUserDlpsEnterCb(app_enter_dlps_config); DLPS_IORegUserDlpsExitCb(app_exit_dlps_config); DLPS_IORegister(); lps_mode_set(PLATFORM_DLPS_PFM); }
功能实现
执行
os_sched_start()
,开启任务调度。TICK 设定时间到,唤醒 DLPS,并触发 RTC 中断,进入中断处理函数
RTC_Handler
,清除滴答中断,打印相关信息。void RTC_Handler(void) { DBG_DIRECT("RTC_Handler"); /* RTC tick interrupt handle */ if (RTC_GetINTStatus(RTC_INT_TICK) == SET) { DBG_DIRECT("RTC_INT_TICK"); RTC_ClearINTPendingBit(RTC_INT_TICK); } ... }