#include "drv_clk.h" #include "drv_misc.h" #include "kit_debug.h" #define EXTI_Line16 ((uint32_t)0x10000) #define PWR_FLAG_PVDO ((uint32_t)0x00000004) #define PWR_CR_PVDE_POS ((uint32_t)0x00000010) #define PWR_PVDLevel_2V9 ((uint32_t)0x000000E0) void drv_misc_set_nvic(int8_t irq_channel, uint8_t priority) { KIT_ASSERT_PARAM((irq_channel > -15) && (irq_channel < 90) && (priority < 16)); priority = (priority & 0x0F) << 4; if(irq_channel > 0) { NVIC->IP[irq_channel] = priority; /* Enable the Selected IRQ Channels */ NVIC->ISER[irq_channel >> 0x05] = (uint32_t)0x01 << (irq_channel & (uint8_t)0x1F); } else { SCB->SHP[((uint32_t)(irq_channel) & 0xF)-4] = priority; } } //只复位内核,外围设备状态不变 void drv_misc_reset_core(void) { __set_FAULTMASK(1); // 关闭所有中断 SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | /* Keep priority group unchanged */ SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); /* Ensure completion of memory access */ while(1); /* wait until reset */ } //复位内核及MCU所有外设 void drv_misc_reset_mcu(void) { __set_FAULTMASK(1); // 关闭所有中断 NVIC_SystemReset(); // 复位 } NoArgCall pwr_off_call; void drv_misc_cfg_pwr_off_interrupt(uint8_t priority, PwrOffVolt volt, NoArgCall int_call) { KIT_ASSERT_PARAM(int_call != NULL); if(int_call != NULL) { pwr_off_call = int_call; drv_misc_set_nvic(PVD_IRQn, priority); RCC->APB1ENR |= RCC_APB1Periph_PWR; PWR->CR |= ((volt << 5) | PWR_CR_PVDE_POS); //clears the pending bits EXTI->PR |= EXTI_Line16; EXTI->RTSR |= EXTI_Line16; //上升沿促发,PVDO输出与上下电相反 EXTI->IMR |= EXTI_Line16; } } void PVD_IRQHandler(void) { EXTI->PR |= EXTI_Line16; //VDD/VDDA低于由PLS[2:0]选定的PVD阀值 if((PWR->CSR & PWR_FLAG_PVDO) != 0) { __disable_irq(); //关闭时钟减小功耗 RCC->APB2ENR = 0; RCC->APB1ENR = 0; pwr_off_call(); // KIT_DEBUG_PRINTF("%s\r\n", "Poweroff"); } } #define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) void drv_mist_set_priority_group(uint16_t pri_group) { /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ SCB->AIRCR = AIRCR_VECTKEY_MASK | pri_group; }