void main(){
................
RTC_init();
Wake_Vcc1_Off_config();
..............
for(;;){
........
}
}
/***********************************************************************************************************************************/
void RTC_init()
{
PMURTC->RTC_CFG0_bit.EXTOSC = 1;
PLIC_SetIrqHandler(Plic_Mach_Target, IsrVect_IRQ_PMURTC, RTC_IRQHandler);
PLIC_SetPriority(IsrVect_IRQ_PMURTC, 0x1);
PLIC_IntEnable(Plic_Mach_Target, IsrVect_IRQ_PMURTC);
PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_REGEN_Msk;
}
/***********************************************************************************************************************************/
/* Функция настройки Wake5 на событие "VBAT > VCC1" при отключении VCC1 */
void Wake_Vcc1_Off_config()
{
PMURTC->RTC_WAKECFG &= ~(0x20); // сброс WAKEUP5
PMURTC->RTC_HISTORY = 0x0;
PMURTC->RTC_WAKECFG &= ~(0x20 << PMURTC_RTC_WAKECFG_WAKEPOL_Pos); // Устанавливаем полярность для WAKEUP5 - высокий уровень (VBAT > VCC1)
PMURTC->RTC_WAKECFG |= 0x20; // Разрешаем событие WAKEUP5
PMURTC->RTC_HISTORY = 0x0; // СБрасываем регистр событий
}
/***********************************************************************************************************************************/
/* Функция настройки Wake5 на событие "VBAT < VCC1" при включении VCC1 */
void Wake_Vсс1_On_config()
{
PMURTC->RTC_WAKECFG &= ~(0x20); // сброс WAKEUP5
PMURTC->RTC_HISTORY = 0x0;
PMURTC->RTC_WAKECFG |= (0x20 << PMURTC_RTC_WAKECFG_WAKEPOL_Pos); // Устанавливаем полярность для WAKEUP5 - низкий уровень (VBAT < VCC1)
PMURTC->RTC_WAKECFG_bit.WAKEEN = 0x20; // Разрешаем событие WAKEUP5
PMURTC->RTC_HISTORY = 0x0; // СБрасываем регистр событий
}
/***********************************************************************************************************************************/
void RTC_IRQHandler()
{
uint32_t tmp_history;
tmp_history = PMURTC->RTC_HISTORY;
PMURTC->RTC_HISTORY = 0;
if (tmp_history & PMURTC_RTC_HISTORY_WKVFVBAK_Msk) {
// Если сработало событие (VBAT > VCC1) или (VBAT < VCC1)
if(PMURTC->RTC_WAKECFG_bit.WAKEPOL & 0x20) {
// VBAT < VCC1 — включилось питание VCC1
Wake_Vcc1_Off_config(); //настройка Wake5 на событие "VBAT > VCC1" при отключении VCC1,
//которое произойдет в случае выключения питания
} else {
// VBAT > VCC1 — отключилось питание VCC1, нужно работать от Vbat, чтобы работали часики
Wake_Vсс1_On_config(); //настройка Wake5 на событие "VBAT < VCC1" при включении VCC1,
//которое произойдет в случае включения питания
// Отключаем лишние функции для минимального тока
PMURTC->PMU_VBATPER_WFI = 0xFFFFFFFF;
PMURTC->RTC_REG[1].RTC_REG++;
PMURTC->RTC_CFG1_bit.ALARMEN = 0;
PMURTC->RTC_CFG1_bit.REGEN = 0;
PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk;
PMURTC->WFI_PDEN_bit.EN = 1;
PMURTC->WFI_ENTR_bit.LDO0EN = 0;
PMURTC->WFI_ENTR_bit.LDO1EN = 0;
GPIOA->DATAOUTSET = (0b1) << 13;
for(;;);
// Уходим в WFI и ждем появления VCC1
while (1) {
__asm("WFI");
}
}
}
PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk;
PMURTC->PMU_IRQEVT = 1;
}