/***********************************************************************
 * Copyright (c)  2017 - 2022, Unicmicro Co.,Ltd .
 * All rights reserved.
 * Filename    : wdt.c
 * Description : wdt driver source file
 * Author(s)   : Sissi
 * version     : V1.0
 * Modify date : 2022-08-08
 ***********************************************************************/
#include "wdt.h"

void (*wdt_callback)(void) = { 0 };

/*******************************************************************
* Function		: WDT_IRQHandler
* Description	: WDT_IRQHandler
* Input			: none
* Output		: none
* Return		: none
********************************************************************/
void WDT_IRQHandler(void)											
{ 	
	if(REG_WDT_INTRAW & 0x1)
	{
		REG_WDT_LOCK = WDT_UNLOCK_VALUE;

		REG_WDT_CLR = 0x1;							//清除中断标志
		
		REG_WDT_LOCK = WDT_LOCK_VALUE;	
		if(wdt_callback != NULL)
		{
			((void(*)())(wdt_callback))(); 
		}
	}	
}

/*******************************************************************
* Function		: wdt_init
* Description	: wdt_init	          WDT初始化
* Input			: uint16_t clock_div  WDT计数器分频
* Output		: none
* Return		: none
********************************************************************/
void wdt_init(uint16_t clock_div)
{	
	REG_SCU_PERICLKEN |= (1<<12);					//开启WDT时钟使能 
	REG_SCU_PERIRESET |= (1<<12);					//WDT正常工作 
	
	REG_WDT_LOCK = WDT_UNLOCK_VALUE;				//解锁寄存器 
	
	REG_WDT_STALL = (REG_WDT_STALL & ~((uint32_t)0xFFFF<<16)) | (clock_div<<16) ;      	
	                                                //计数器分频  Time = ((clkdiv + 1 )*load)/32k (s) 
			
	REG_WDT_LOCK = WDT_LOCK_VALUE;					//加锁寄存器 
}

/*******************************************************************
* Function		: wdt_irq_init
* Description	: wdt_irq_init	     WDT中断初始化
* Input			: uint8_t irq_enable WDT中断开关
*                 void (*pfunc)()    WDT中断回调函数
* Output		: none
* Return		: none
********************************************************************/
void wdt_irq_init(uint8_t irq_enable,void (*pfunc)())
{
	REG_WDT_LOCK = WDT_UNLOCK_VALUE;					//解锁寄存器

	if(irq_enable)
	{
		wdt_callback = pfunc;
		REG_WDT_CTRL |= (0x01<<0);						//使能WDT中断
		NVIC_ClearPendingIRQ(WDT_IRQn); 
		NVIC_EnableIRQ(WDT_IRQn);
	}
	else
	{
		wdt_callback = NULL;
		REG_WDT_CTRL &= ~(0x01<<0);		    			//关闭WDT中断
	}
	
	while((REG_WDT_CTRL & ((uint32_t)1<<31)) == 0);		//等待设置位生效

	REG_WDT_LOCK = WDT_LOCK_VALUE;						//加锁寄存器
}

/*******************************************************************
* Function		: wdt_reset_set
* Description	: wdt_reset_set	     WDT复位使能设置
* Input			: uint8_t rst_enable WDT复位开关
* Output		: none
* Return		: none
********************************************************************/
void wdt_reset_set(uint8_t rst_enable)
{
	REG_WDT_LOCK = WDT_UNLOCK_VALUE;					//解锁寄存器

	if(rst_enable)
	{
		REG_WDT_CTRL |= (1<<1);						    //使能WDT复位
	}
	else
	{
		REG_WDT_CTRL &= ~(1<<1);					    //关闭WDT复位
	}
	
	while((REG_WDT_CTRL & ((uint32_t)1<<31)) == 0);		//等待设置位生效
	
	REG_WDT_LOCK = WDT_LOCK_VALUE;						//加锁寄存器
}

/*******************************************************************
* Function		: wdt_load_set
* Description	: wdt_load_set	      写入WDT装载值后会开始计数(喂狗)
* Input			: uint32_t load_value WDT装载值
* Output		: none
* Return		: none
********************************************************************/
void wdt_load_set(uint32_t load_value)
{
	REG_WDT_LOCK = WDT_UNLOCK_VALUE;					// 解锁寄存器 
	
	REG_WDT_LOAD = load_value;							// 写WDT装载值
	
	while((REG_WDT_CTRL & ((uint32_t)1<<31)) == 0);
	
	REG_WDT_LOCK = WDT_LOCK_VALUE;						// 加锁寄存器 
}

/*******************************************************************
* Function		: wdt_stall_set
* Description	: 芯片处于halt状态时计数功能停止使能设置
* Input			: uint8_t stall_enable 使能计数停止功能
* Output		: none
* Return		: none
********************************************************************/
void wdt_stall_set(uint8_t stall_enable)
{
	REG_WDT_LOCK = WDT_UNLOCK_VALUE;					//解锁寄存器

	if(stall_enable)
	{
		REG_WDT_STALL |= (1<<8);				    	//使能HALT状态计数器停止工作功能
	}
	else
	{
		REG_WDT_STALL &= ~(1<<8);						//关闭HALT状态计数器停止工作功能
	}
		
	REG_WDT_LOCK = WDT_LOCK_VALUE;						//加锁寄存器
}
