V2.31
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
|
||||
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void EXTI0_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NMI_Handler
|
||||
@@ -44,21 +44,6 @@ void HardFault_Handler(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn EXTI0_IRQHandler
|
||||
*
|
||||
* @brief This function handles EXTI0 exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void EXTI0_IRQHandler(void)
|
||||
{
|
||||
if(EXTI_GetITStatus(EXTI_Line0)!=RESET)
|
||||
{
|
||||
SystemInit();
|
||||
printf("EXTI0 Wake_up\r\n");
|
||||
EXTI_ClearITPendingBit(EXTI_Line0); /* Clear Flag */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : main.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2023/12/29
|
||||
* Version : V1.0.1
|
||||
* Date : 2025/09/29
|
||||
* Description : Main program body.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
@@ -12,18 +12,41 @@
|
||||
|
||||
/*
|
||||
*@Note
|
||||
*low power, stop mode routine:
|
||||
*EXTI_Line0(PA0)
|
||||
*This routine demonstrates WFI enters sleep mode, PA0 pin input low level triggers
|
||||
*external interrupt EXTI_Line0 exits stop mode,Program execution continues after wake-up.
|
||||
*
|
||||
* Stop Mode:
|
||||
* The example demonstrates WFI\WFE enter the STOP-Regulator_On mode or the STOP-Regulator_LowPower mode.
|
||||
* The rising edge of PA0 will trigger the EXTI-line0 wake-up system, and the program continues to
|
||||
* execute after waking up.
|
||||
* When using the STOP-Regulator_LowPower mode, The LDO and ULLDO need to be adjusted before the system
|
||||
* enters the stop mode and restored first after waking up.If the program is running in a non-zero wait state,
|
||||
* the sleep part of the program needs to be placed in RAM for execution(add prefix __attribute__((section("highcode")))
|
||||
* before function,printf functions and C function library is not applicable to run in RAM.).
|
||||
*
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
/* Global define */
|
||||
|
||||
/* definition of voltage regulator mode in stop mode */
|
||||
#define STOP_On_Mode 0
|
||||
#define STOP_LowPower_Mode 1
|
||||
#define STOP_Mode STOP_On_Mode
|
||||
// #define STOP_Mode STOP_LowPower_Mode
|
||||
|
||||
/* definition of program operate area */
|
||||
#define RunIn_ZeroWaitArea 0
|
||||
#define RunIn_NonZeroWaitArea 1
|
||||
#define Operating_Area_Type RunIn_ZeroWaitArea
|
||||
// #define Operating_Area_Type RunIn_NonZeroWaitArea
|
||||
|
||||
/* definition of execute with WFI or WFE */
|
||||
#define Enter_WFI_Mode 0
|
||||
#define Enter_WFE_Mode 1
|
||||
// #define Enter_Mode Enter_WFI_Mode
|
||||
#define Enter_Mode Enter_WFE_Mode
|
||||
|
||||
/* Global Variable */
|
||||
volatile uint32_t REGPSC, REGCNT, REGALR = 0;
|
||||
|
||||
/*********************************************************************
|
||||
* @fn EXTI0_INT_INIT
|
||||
@@ -36,28 +59,300 @@ void EXTI0_INT_INIT(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
EXTI_InitTypeDef EXTI_InitStructure = {0};
|
||||
NVIC_InitTypeDef NVIC_InitStructure = {0};
|
||||
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOA.0 ----> EXTI_Line0 */
|
||||
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
|
||||
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
|
||||
#if (Enter_Mode == Enter_WFI_Mode)
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
|
||||
#else
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;
|
||||
#endif
|
||||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
|
||||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
|
||||
#if (Enter_Mode == Enter_WFI_Mode)
|
||||
NVIC_InitTypeDef NVIC_InitStructure = {0};
|
||||
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn GPIO_ALL_IPD
|
||||
*
|
||||
* @brief Set all pins mode to pull-down.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void GPIO_ALL_IPD(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
/* To reduce power consumption, unused GPIOs need to be set as pull-down inputs */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|
|
||||
RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE);
|
||||
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn LDO_Deal
|
||||
*
|
||||
* @brief Deal LDO ULLDO mode.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
#if(Operating_Area_Type == RunIn_NonZeroWaitArea)
|
||||
__attribute__((section(".highcode")))
|
||||
#endif
|
||||
void LDO_Deal(void)
|
||||
{
|
||||
uint32_t tmpreg = 0;
|
||||
|
||||
REGPSC = 0;
|
||||
REGALR = 0;
|
||||
REGCNT = 0;
|
||||
if((uint8_t)((*(vu32*)0x4002203C >> 24) & 0xFF) != 0xAB)
|
||||
{
|
||||
if((RCC->APB1PCENR & (1 << 27)) == RESET)
|
||||
{
|
||||
RCC->APB1PCENR |= (1 << 27);
|
||||
REGPSC |= (1 << 27);
|
||||
}
|
||||
if((PWR->CTLR & (1 << 8)) == RESET)
|
||||
{
|
||||
PWR->CTLR |= (1 << 8);
|
||||
REGPSC |= (1 << 26);
|
||||
}
|
||||
if((EXTI->EVENR & (1 << 17)) == RESET)
|
||||
{
|
||||
EXTI->EVENR |= (1 << 17);
|
||||
REGPSC |= (1 << 25);
|
||||
}
|
||||
if((EXTI->RTENR & (1 << 17)) == RESET)
|
||||
{
|
||||
EXTI->RTENR |= (1 << 17);
|
||||
REGPSC |= (1 << 24);
|
||||
}
|
||||
|
||||
if((RCC->BDCTLR & (1 << 15)) == RESET)
|
||||
{
|
||||
if((RCC->RSTSCKR & (1 << 1)) == RESET) REGPSC |= (1 << 30);
|
||||
|
||||
if((RCC->BDCTLR & (1 << 8)) == RESET)
|
||||
{
|
||||
RCC->RSTSCKR |= (1 << 0);
|
||||
while ((RCC->RSTSCKR & (1 << 1)) == RESET);
|
||||
RCC->BDCTLR |= (1 << 9);
|
||||
}
|
||||
REGPSC |= (1 << 29);
|
||||
}
|
||||
}
|
||||
REGPSC |= (0xF << 20);
|
||||
|
||||
tmpreg = EXTEN->EXTEN_CTR;
|
||||
tmpreg &= ~(0xF << 8);
|
||||
tmpreg |= (0x3 << 8);
|
||||
EXTEN->EXTEN_CTR = tmpreg;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn LDO_Restore
|
||||
*
|
||||
* @brief Restore LDO Value.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
#if(Operating_Area_Type == RunIn_NonZeroWaitArea)
|
||||
__attribute__((section(".highcode")))
|
||||
#endif
|
||||
void LDO_Restore(void)
|
||||
{
|
||||
uint32_t tmpreg = 0, t = 0;
|
||||
uint16_t high1a = 0, high1b = 0, high2a = 0, high2b = 0;
|
||||
uint16_t low1 = 0, low2 = 0;
|
||||
|
||||
if((REGPSC & 0xF00000) == (uint32_t)0xF00000)
|
||||
{
|
||||
tmpreg = EXTEN->EXTEN_CTR;
|
||||
tmpreg &= ~(0xF << 8);
|
||||
tmpreg |= (0xA << 8);
|
||||
EXTEN->EXTEN_CTR = tmpreg;
|
||||
|
||||
if(((*(vu32*)0x4002203C >> 24) & 0xFF) != 0xAB)
|
||||
{
|
||||
RCC->BDCTLR |= (1 << 15);
|
||||
RTC->CTLRL &= (uint16_t)~RTC_FLAG_RSF;
|
||||
while((RTC->CTLRL & RTC_FLAG_RSF) == (uint16_t)RESET);
|
||||
|
||||
REGPSC |= (((RTC->PSCRH & 0xF) << 16) | RTC->PSCRL);
|
||||
REGALR = (RTC->ALRMH << 16 | RTC->ALRML);
|
||||
do{
|
||||
high1a = RTC->CNTH;
|
||||
high1b = RTC->CNTH;
|
||||
}while(high1a != high1b);
|
||||
do{
|
||||
low1 = RTC->CNTL;
|
||||
low2 = RTC->CNTL;
|
||||
}while(low1 != low2);
|
||||
do{
|
||||
high2a = RTC->CNTH;
|
||||
high2b = RTC->CNTH;
|
||||
}while(high2a != high2b);
|
||||
if(high1b != high2b) {
|
||||
do{
|
||||
low1 = RTC->CNTL;
|
||||
low2 = RTC->CNTL;
|
||||
}while(low1 != low2);
|
||||
}
|
||||
REGCNT = (((uint32_t)high2b << 16) | low2);
|
||||
|
||||
RTC->CTLRL |= (1 << 4);
|
||||
RTC->PSCRH = 0;
|
||||
RTC->PSCRL = 1;
|
||||
RTC->CNTH = 0;
|
||||
RTC->CNTL = 0;
|
||||
RTC->ALRMH = 0;
|
||||
RTC->ALRML = 1;
|
||||
RTC->CTLRL &= (uint16_t) ~(1 << 4);
|
||||
while((RTC->CTLRL & RTC_FLAG_RTOFF) == (uint16_t)RESET);
|
||||
|
||||
PWR->CTLR &= ~(3 << 0);
|
||||
NVIC->SCTLR |= (1 << 2);
|
||||
NVIC->SCTLR |= (1 << 5);
|
||||
t = NVIC->SCTLR;
|
||||
t &= ~(1 << 5);
|
||||
t |= (1 << 3);
|
||||
NVIC->SCTLR = t;
|
||||
asm volatile ("wfi");
|
||||
t = NVIC->SCTLR;
|
||||
t &= ~(1 << 5);
|
||||
t |= (1 << 3);
|
||||
NVIC->SCTLR = t;
|
||||
asm volatile ("wfi");
|
||||
if(EXTEN->EXTEN_CTR & (1 << 6))
|
||||
{
|
||||
NVIC->SCTLR |= (1 << 5);
|
||||
}
|
||||
NVIC->SCTLR &= ~(1 << 2);
|
||||
|
||||
RTC->CTLRL |= (1 << 4);
|
||||
RTC->PSCRH = (uint16_t)((REGPSC >> 16) & 0xF);
|
||||
RTC->PSCRL = (uint16_t)(REGPSC & 0xFFFF);
|
||||
RTC->CNTH = (uint16_t)(REGCNT >> 16);
|
||||
RTC->CNTL = (uint16_t)(REGCNT & 0xFFFF);
|
||||
RTC->ALRMH = (uint16_t)(REGALR >> 16);
|
||||
RTC->ALRML = (uint16_t)(REGALR & 0xFFFF);
|
||||
RTC->CTLRL &= (uint16_t) ~(1 << 4);
|
||||
while((RTC->CTLRL & RTC_FLAG_RTOFF) == (uint16_t)RESET);
|
||||
if(((NVIC->ISR[0] & (1 << 19)) == RESET) && ((NVIC->ISR[1] & (1 << 25)) == RESET))
|
||||
{
|
||||
RTC->CTLRL &= (uint16_t) ~(0x3);
|
||||
}
|
||||
if(REGPSC & (1 << 29)) RCC->BDCTLR &= ~(1 << 15);
|
||||
if(REGPSC & (1 << 30)) RCC->RSTSCKR &= ~(1 << 0);
|
||||
if(REGPSC & (1 << 27)) RCC->APB1PCENR &= ~(1 << 27);
|
||||
if(REGPSC & (1 << 26)) PWR->CTLR &= ~(1 << 8);
|
||||
if(REGPSC & (1 << 25)) EXTI->EVENR &= ~(1 << 17);
|
||||
if(REGPSC & (1 << 24)) EXTI->RTENR &= ~(1 << 17);
|
||||
}
|
||||
else
|
||||
{
|
||||
FLASH->CTLR |= (1 << 23);
|
||||
}
|
||||
REGPSC &= ~(0xF << 20);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Enter_StopLowPower
|
||||
*
|
||||
* @brief Enter stop low-power mode.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
#if(Operating_Area_Type == RunIn_NonZeroWaitArea)
|
||||
__attribute__((section(".highcode")))
|
||||
#endif
|
||||
void Enter_StopLowPower(void)
|
||||
{
|
||||
/* The kernel voltage needs to be adjusted before waking up */
|
||||
LDO_Deal();
|
||||
|
||||
#if (Operating_Area_Type == RunIn_NonZeroWaitArea)
|
||||
|
||||
#if (Enter_Mode == Enter_WFI_Mode)
|
||||
{
|
||||
uint32_t tmpreg = 0;
|
||||
tmpreg = PWR->CTLR;
|
||||
tmpreg &= ~(0x3);
|
||||
tmpreg |= 0x1;
|
||||
PWR->CTLR = tmpreg;
|
||||
|
||||
NVIC->SCTLR |= (1 << 2);
|
||||
NVIC->SCTLR &= ~(1 << 3);
|
||||
asm volatile ("wfi");
|
||||
NVIC->SCTLR &= ~(1 << 2);
|
||||
}
|
||||
#else
|
||||
{
|
||||
uint32_t tmpreg = 0, t=0;
|
||||
tmpreg = PWR->CTLR;
|
||||
tmpreg &= ~(0x3);
|
||||
tmpreg |= 0x1;
|
||||
PWR->CTLR = tmpreg;
|
||||
NVIC->SCTLR |= (1 << 2);
|
||||
NVIC->SCTLR |= (1 << 5);
|
||||
t = NVIC->SCTLR;
|
||||
t &= ~(1 << 5);
|
||||
t |= (1 << 3);
|
||||
NVIC->SCTLR = t;
|
||||
asm volatile ("wfi");
|
||||
t = NVIC->SCTLR;
|
||||
t &= ~(1 << 5);
|
||||
t |= (1 << 3);
|
||||
NVIC->SCTLR = t;
|
||||
asm volatile ("wfi");
|
||||
if(EXTEN->EXTEN_CTR & (1 << 6))
|
||||
{
|
||||
NVIC->SCTLR |= (1 << 5);
|
||||
}
|
||||
NVIC->SCTLR &= ~(1 << 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif (Operating_Area_Type == RunIn_ZeroWaitArea)
|
||||
|
||||
#if (Enter_Mode == Enter_WFI_Mode)
|
||||
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
|
||||
#else
|
||||
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (Enter_Mode == Enter_WFE_Mode)
|
||||
/* The kernel voltage must be restored first after waking up */
|
||||
LDO_Restore();
|
||||
SystemInit();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
@@ -69,23 +364,65 @@ void EXTI0_INT_INIT(void)
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
|
||||
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
|
||||
SystemCoreClockUpdate();
|
||||
Delay_Init();
|
||||
Delay_Ms(1000);
|
||||
GPIO_ALL_IPD();
|
||||
USART_Printf_Init(115200);
|
||||
printf("SystemClk:%d\r\n", SystemCoreClock);
|
||||
printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
|
||||
printf("Stop Mode Test\r\n");
|
||||
printf("ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
|
||||
EXTI0_INT_INIT();
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
|
||||
printf("\r\n ********** \r\n");
|
||||
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
|
||||
printf("\r\n ########## \r\n");
|
||||
|
||||
#if (STOP_Mode == STOP_On_Mode)
|
||||
#if (Enter_Mode == Enter_WFI_Mode)
|
||||
printf("stop on mode enter WFI...\r\n");
|
||||
PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);
|
||||
#else
|
||||
printf("stop on mode enter WFE...\r\n");
|
||||
PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFE);
|
||||
SystemInit();
|
||||
#endif
|
||||
|
||||
#else
|
||||
printf("stop low-power mode ...\r\n");
|
||||
Enter_StopLowPower();
|
||||
#endif
|
||||
Delay_Ms(100);
|
||||
printf("\r\n#####################\r\n");
|
||||
printf("wake up !!!\r\n");
|
||||
while(1)
|
||||
{
|
||||
Delay_Ms(1000);
|
||||
printf("Run in main\r\n");
|
||||
printf("run in main\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if (Enter_Mode == Enter_WFI_Mode)
|
||||
void EXTI0_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
/*********************************************************************
|
||||
* @fn EXTI0_IRQHandler
|
||||
*
|
||||
* @brief This function handles EXTI0 exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
#if(Operating_Area_Type == RunIn_NonZeroWaitArea)
|
||||
__attribute__((section(".highcode")))
|
||||
#endif
|
||||
void EXTI0_IRQHandler(void)
|
||||
{
|
||||
#if(STOP_Mode == STOP_LowPower_Mode)
|
||||
/* After waking up, the kernel voltage needs to be restored first */
|
||||
LDO_Restore();
|
||||
#endif
|
||||
SystemInit();
|
||||
if((EXTI->INTFR & EXTI_Line0))
|
||||
{
|
||||
EXTI->INTFR = EXTI_Line0; /* Clear Flag */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Source File.
|
||||
* For HSE = 32Mhz (CH32V208x/CH32V203RBT6)
|
||||
* For HSE = 32Mhz (CH32V208x/CH32V203RBT)
|
||||
* For HSE = 8Mhz (other CH32V203x)
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
|
||||
Reference in New Issue
Block a user