CCCPaste

K1921VG015+PowerOFF

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;
}