/** * @file watchdog.c * @author chipsea * @brief * @version 0.1 * @date 2020-11-30 * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd. * @note */ #include "rom_sym_def.h" #include "watchdog.h" #include "error.h" #include "pwrmgr.h" #include "clock.h" #include "jump_function.h" #include "watchdog.h" extern volatile uint8 g_clk32K_config; extern uint32_t s_config_swClk1; typedef struct { bool enable; WdtRspMode_t mode; pfnHdlCB_t handleCB; }WdtCtl_t; WdtCtl_t wdtCtl; /** * @fn static void __attribute__((used)) hal_WATCHDOG_IRQHandler(void) * @brief WDT interrupt handler funtion. wdt clock source is 32KHz low speed clock. * @param[in] none * @return none. */ void __attribute__((used)) hal_WATCHDOG_IRQHandler(void) { // volatile uint32_t a; // a = AP_WDT->EOI; // AP_WDT->CRR = 0x76; if(wdtCtl.handleCB) { wdtCtl.handleCB(); } } /** * @fn void HalWdtFeed(void) * @brief wdt feed * @param[in] none * @return none. */ void HalWdtFeed(void) { AP_WDT->CRR = 0x76; } /** * @fn static bool watchdog_init(WDG_CYCLE_Type_e cycle) * @brief wdt initialize config * @param[in] cycle: WDG_CYCLE_Type_e * @return boot SUCCESS/. */ static bool watchdog_init(void) { volatile uint32_t a; uint8_t delay; if(g_clk32K_config == CLK_32K_XTAL)//rtc use 32K XOSC,watchdog use the same { AP_PCRM->CLKSEL |= (1UL<<16); } else { AP_PCRM->CLKSEL &= ~(1UL<<16); //rtc use 32K RCOSC,watchdog use the same } hal_clk_gate_enable(MOD_WDT); s_config_swClk1|=_CLK_WDT; //add watchdog clk in pwrmg wakeup restore clk; if((AP_PCR->SW_RESET0 & 0x04)==0) { AP_PCR->SW_RESET0 |= 0x04; delay = 20; while(delay-->0); } if((AP_PCR->SW_RESET2 & 0x04)==0) { AP_PCR->SW_RESET2 |= 0x04; delay=20; while(delay-->0); } AP_PCR->SW_RESET2 &= ~0x20; delay=20; while(delay-->0); AP_PCR->SW_RESET2 |= 0x20; delay=20; while(delay-->0); a = AP_WDT->EOI; AP_WDT->TORR = HAL_WDG_CFG_CYCLE; //config wdt cycle if(wdtCtl.mode == WDG_USE_INT_MODE) { JUMP_FUNCTION(V10_IRQ_HANDLER) = (uint32_t)&hal_WATCHDOG_IRQHandler; AP_WDT->CR = 0x1F; //use intteruct mode NVIC_SetPriority((IRQn_Type)WDT_IRQn, IRQ_PRIO_HAL); NVIC_EnableIRQ((IRQn_Type)WDT_IRQn); } else if(wdtCtl.mode == WDG_USE_POLLING_MODE) { JUMP_FUNCTION(V10_IRQ_HANDLER) = 0; AP_WDT->CR = 0x1D; //no use intteruct mode NVIC_DisableIRQ((IRQn_Type)WDT_IRQn); } AP_WDT->CRR = 0x76; return SUCCESS; } /** * @fn void HalWdtInit(FunctionalState_t newState, WdtRspMode_t mode, pfnHdlCB_t irqHdlCallback) * @brief wdt initialize * @param[in] newState: ENABLE or DISABLE * @param[in] mode: WDT_RSP_MODE_NO_INT or WDT_RSP_MODE_INT * @param[in] irqHdlCallback: interrupt handle callback * @return none. */ void HalWdtInit(FunctionalState_t newState, WdtRspMode_t mode,pfnHdlCB_t irqHdlCallback) { wdtCtl.mode = mode; wdtCtl.handleCB = irqHdlCallback; if(newState == ENABLE) { watchdog_init(); JUMP_FUNCTION(HAL_WATCHDOG_INIT) = (uint32_t)&watchdog_init; } else{ JUMP_FUNCTION(HAL_WATCHDOG_INIT) = NULL; } }