Voltage Detection - DLPS
This example uses LPC for DLPS wake-up.
When the system is in IDLE state, it will automatically enter DLPS state.
When the input voltage at pin P2_4 meets the LPC voltage comparison condition, it will wake up the system from DLPS and simultaneously trigger an LPC interrupt.
Requirements
The sample supports the following development kits:
Hardware Platforms |
Board Name |
---|---|
RTL8752H HDK |
RTL8752H EVB |
For more requirements, please refer to Quick Start.
Wiring
Connect LPC voltage comparator pin P2_4 to the external input voltage.
Building and Downloading
This sample can be found in the SDK folder:
Project file: board\evb\io_sample\LPC\VolatgeDetection_DLPS\mdk
Project file: board\evb\io_sample\LPC\VolatgeDetection_DLPS\gcc
Please follow these steps to build and run the example:
Open sample project file.
To build the target, follow the steps listed on the Generating App Image in Quick Start.
After a successful compilation, the app bin
app_MP_xxx.bin
will be generated in the directorymdk\bin
orgcc\bin
.To download app bin into EVB board, follow the steps listed on the MP Tool Download in Quick Start.
Press reset button on EVB board and it will start running.
Experimental Verification
When the EVB resets, the system enters the DLPS state. Corresponding information is printed in the Debug Analyzer.
DLPS ENTER
When P2_4 detects a voltage input lower than 2000mV, the system wakes up and exits the DLPS state. The relevant information is printed in the Debug Analyzer.
DLPS EXIT, wake up reason 0x200
The system being awakened will trigger an LPC interrupt, and the corresponding information will be printed in the Debug Analyzer.
LPCOMP_Handler LPC AON
Code Overview
This chapter will be introduced according to the following several parts:
Peripheral initialization will be introduced in chapter Initialization.
Functional implementation after initialization will be introduced in chapter Function Implementation.
Source Code Directory
Project directory:
sdk\board\evb\io_sample\LPC\VolatgeDetection_DLPS
Source code directory:
sdk\src\sample\io_sample\LPC\VolatgeDetection_DLPS
Source files are currently categorized into several groups as below.
└── Project: voltage_detect_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
└── adc.lib
├── peripheral includes all peripheral drivers and module code used by the application
├── rtl876x_rcc.c
├── rtl876x_pinmux.c
├── rtl876x_nvic.c
├── rtl876x_io_dlps.c
└── rtl876x_lpc.c
├── profile
└── app includes the ble_peripheral user application implementation
├── main.c
└── io_lpc.c
Initialization
When the EVB reset is initiated, the main()
function will be called, executing the following process:
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;
}
The initialization process related to peripherals is as follows:
In
board_init
, executeboard_lpc_init
, which is responsible for PAD/PINMUX settings and includes the following process:Configure PAD: Set pin, SW mode, PowerOn, internal pull-none, output disabled.
Configure PINMUX: Set pin to IDLE mode.
void board_lpc_init(void) { Pad_Config(LPC_CAPTURE_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pinmux_Config(LPC_CAPTURE_PIN, IDLE_MODE); }
Execute
driver_lpc_init
indriver_init
, which initializes the LPC peripheral and includes the following steps:Set the LPC comparison channel to the P2_4 pin channel.
Set the LPC voltage detection polarity to
LPC_Vin_Below_Vth
, which triggers LPC comparison when the voltage is below the set threshold.Set the voltage threshold to 2000mV.
Enable LPC voltage detection and configure the LPC voltage comparison interrupt
LPC_INT_LPCOMP_VOL
.Execute
LPC_WKCmd()
to enable the LPC wake-up function.Execute
nvic_lpc_init
to configure and enable the LPC IRQ channel.
void driver_lpc_init(void) { DBG_DIRECT("driver_lpc_init"); LPC_DeInit(); LPC_InitTypeDef LPC_InitStruct; LPC_StructInit(&LPC_InitStruct); LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL; LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE; LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD; LPC_Init(&LPC_InitStruct); LPC_INTConfig(LPC_INT_LPCOMP_VOL, ENABLE); LPC_WKCmd(ENABLE); RTC_SystemWakeupConfig(ENABLE); LPC_Cmd(ENABLE); extern void nvic_lpc_init(void); nvic_lpc_init(); } void nvic_lpc_init(void) { /* Config LPC interrupt */ NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = LPCOMP_IRQn; NVIC_InitStruct.NVIC_IRQChannelPriority = 3; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); LPC_INTCmd(ENABLE); }
Execute
pwr_mgr_init
, this function sets the voltage mode for DLPS, including the following processes:Register the user-entering DLPS callback function
app_enter_dlps_config
, and register the user-exiting DLPS callback functionapp_exit_dlps_config
.Enable the LPC voltage comparison interrupt
LPC_INT_LPCOMP_VOL
inapp_enter_dlps_config
.void app_enter_dlps_config(void) { DBG_DIRECT("DLPS ENTER"); LPC_INTConfig(LPC_INT_LPCOMP_VOL, ENABLE); }
In
app_exit_dlps_config
, print DLPS wake-up information and record the count +1.void app_exit_dlps_config(void) { allow_count ++; DBG_DIRECT("DLPS EXIT, wake up reason 0x%x", platform_pm_get_wakeup_reason()); }
Register the hardware control callback functions
DLPS_IO_EnterDlpsCb
andDLPS_IO_ExitDlpsCb
. Entering DLPS will save CPU, PINMUX, Peripheral, etc., and exiting DLPS will restore CPU, PINMUX, Peripheral, etc.Set the power mode to DLPS mode.
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); }
Functional Implementation
Execute
os_sched_start()
to start task scheduling. When P2_4 detects an input voltage lower than 2000mV, it triggers theLPC_INT_LPCOMP_VOL
interrupt and enters the interrupt handler functionLPCOMP_Handler
.Check if the interrupt flag is
LPC_FLAG_LPCOMP_AON
.Disable the LPC interrupt.
void LPCOMP_Handler(void) { DBG_DIRECT("LPCOMP_Handler"); if (LPC_GetFlagStatus(LPC_FLAG_LPCOMP_AON) == SET) { DBG_DIRECT("LPC AON"); } LPC_INTConfig(LPC_INT_LPCOMP_VOL, DISABLE); }