JT-DT-YD4N02B_4G_RTT_MRS/bsp/src/bsp_wdg.c

197 lines
5.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "bsp_wdg.h"
#define LOG_TAG "bsp_wgd" // 该模块对应的标签。不定义时默认NO_TAG
#define LOG_LVL LOG_LVL_DBG // 该模块对应的日志输出级别。不定义时,默认:调试级别
#include <ulog.h> // 必须在 LOG_TAG 与 LOG_LVL 下面
ALIGN(RT_ALIGN_SIZE)
static char wdg_thread_stack[WDG_THREAD_STACK_SIZE];
static struct rt_thread wdg_thread;
#if USED_WWDG
// This routine demonstrates that the watchdog is fed between the window 0x40(64) and 0x7F(127) to
// prevent the watchdog from being reset.
#define WWDG_CNT 127
uint8_t wwdg_tr, wwdg_wr;
void WWDG_IRQHandler(void) __attribute__((interrupt("")));
#endif
#if USED_IWDG
/*************************************IWDG**********************************************/
/**
* @description: Initializes IWDG.
* @param {uint16_t} prescaler specifies the IWDG Prescaler value.
* IWDG_Prescaler_4: IWDG prescaler set to 4.
* IWDG_Prescaler_8: IWDG prescaler set to 8.
* IWDG_Prescaler_16: IWDG prescaler set to 16.
* IWDG_Prescaler_32: IWDG prescaler set to 32.
* IWDG_Prescaler_64: IWDG prescaler set to 64.
* IWDG_Prescaler_128: IWDG prescaler set to 128.
* IWDG_Prescaler_256: IWDG prescaler set to 256.
* @param {uint16_t} reload specifies the IWDG Reload value.
* This parameter must be a number between 0 and 0x0FFF(4095).
* @return {*}
*/
void IWDG_Init(uint16_t prescaler, uint16_t reload)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
IWDG_SetPrescaler(prescaler);
IWDG_SetReload(reload);
IWDG_ReloadCounter();
IWDG_Enable();
LOG_I("IWDG_Feed_Init");
}
inline void IWDG_Feed(void)
{
// LOG_D("IWDG_Feed!");
IWDG_ReloadCounter(); //Feed dog
}
#elif USED_WWDG
/*************************************WWDG**********************************************/
/*********************************************************************
* @fn WWDG_NVIC_Config
*
* @brief WWDG INT init.
*
* @return none
*/
static void WWDG_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure = {0};
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @description:
* @param {uint32_t} prv 设置预分频器值
* WWDG_Prescaler - specifies the WWDG Prescaler
* WWDG_Prescaler_1 - WWDG counter clock = (PCLK1/4096)/1
* WWDG_Prescaler_2 - WWDG counter clock = (PCLK1/4096)/2
* WWDG_Prescaler_4 - WWDG counter clock = (PCLK1/4096)/4
* WWDG_Prescaler_8 - WWDG counter clock = (PCLK1/4096)/8
* @param {uint8_t} wr 设置上窗口值
* WindowValue - specifies the window value to be compared to the
* downcounter,which must be lower than 0x80
* @param {uint8_t} tr 设置计数器的值
* Counter - specifies the watchdog counter value,which must be a
* number between 0x40(64) and 0x7F(127)
* @return {*}
*/
void WWDG_Init(uint32_t prv, uint8_t wr, uint8_t tr)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
WWDG_SetPrescaler(prv);
WWDG_SetWindowValue(wr);
WWDG_SetCounter(tr);
WWDG_Enable(WWDG_CNT);
WWDG_ClearFlag();
WWDG_NVIC_Config();
WWDG_EnableIT();
wwdg_wr = WWDG->CFGR & 0x7F;
LOG_D("WWDG_Feed_Init");
}
/*********************************************************************
* @fn WWDG_Feed
*
* @brief Feed WWDG.
*
* @return none
*/
void WWDG_Feed(void)
{
WWDG_SetCounter(WWDG_CNT);
// LOG_D("WWDG_Feed");
}
void WWDG_Loop(void)
{
wwdg_tr = WWDG->CTLR & 0x7F;
if(wwdg_tr < wwdg_wr)
{
WWDG_Feed();
}
}
#endif
static void wdg_thread_entry(void *param)
{
while (1)
{
#if USED_IWDG
IWDG_Feed();
rt_thread_mdelay(IWDG_FEED_INTERVAL_MS);
#elif USED_WWDG
WWDG_Loop();
#endif
}
}
int BSP_WDG_Init(void)
{
#if USED_IWDG
// t = 4000 * IWDG计数时基 = LSI / 分频系数 = 40 KHz / 32 = 1250 Hz= 3.2 s
IWDG_Init(IWDG_Prescaler_32, 4000); // 3.2s IWDG reset
#elif USED_WWDG
// WWDG counter clock = (PCLK1 / 4096) / 8 = (SystemCoreClock(96MHz) / 2) / 4096 / 8 ~= 1464 Hz
WWDG_Init(WWDG_Prescaler_8, 80, WWDG_CNT);
#endif
IWDG_Feed();
// /* 设置空闲线程钩子函数 */
// return rt_thread_idle_sethook(BSP_WDG_Loop);
if (RT_EOK == rt_thread_init(&wdg_thread,
"wdg_thread",
wdg_thread_entry,
RT_NULL,
&wdg_thread_stack[0],
sizeof(wdg_thread_stack),
WDG_THREAD_PRIORITY, WDG_THREAD_TIMESLICE))
{
rt_thread_startup(&wdg_thread);
}
return 0;
}
#ifdef RT_USING_COMPONENTS_INIT
// INIT_DEVICE_EXPORT(BSP_WDG_Init);
#endif
#if USED_WWDG
/*********************************************************************
* @fn WWDG_IRQHandler
*
* @brief This function handles WWDG exception.
*
* @return none
*/
void WWDG_IRQHandler(void)
{
GET_INT_SP();
/* enter interrupt */
rt_interrupt_enter();
WWDG_ClearFlag();
// WWDG_SetCounter(WWDG_CNT);
#error "此处加入在复位前需要处理的工作或保存数据"
/* leave interrupt */
rt_interrupt_leave();
FREE_INT_SP();
}
#endif