1 /**
2   ******************************************************************************
3   * @file    rtl8721d_wdg.c
4   * @author
5   * @version V1.0.0
6   * @date    2016-05-17
7   * @brief   This file provides firmware functions to manage the following
8   *          functionalities of the Watch Dog (WDG) peripheral:
9   *           - Initialization
10   *           - WDG refresh
11   *           - Interrupts and flags management
12   ******************************************************************************
13   * @attention
14   *
15   * This module is a confidential and proprietary property of RealTek and
16   * possession or use of this module requires written permission of RealTek.
17   *
18   * Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
19   ******************************************************************************
20   */
21 
22 #include "ameba_soc.h"
23 
24 /**
25   * @brief  Get WDG dividor parameters based on Period
26   * @param  Period: WDG timeout (ms).
27   * @param  pCountProcess: count id of WDG.
28   *         This parameter can be set: 0 ~ 11, represent count value: 0x001~0xFFF
29   * @note	The relationship between count id and count: Count = ((0x00000001 << (CountId+1))-1)
30   * @param  pDivFacProcess: clock divisor of WDG timeout count.
31   * @note	Minimum dividing factor is 1
32   * @note	The formula to calculate dividing factor: DivFactor = (u16)(( TimeoutMs * 100)/(Count * 3))
33   * @retval None
34   */
WDG_Scalar(u32 Period,u32 * pCountProcess,u32 * pDivFacProcess)35 void WDG_Scalar(u32 Period, u32 *pCountProcess, u32 *pDivFacProcess)
36 {
37 	u8 CountId;
38 	u16 DivFactor;
39 	u32 CountTemp;
40 	u32 PeriodProcess = 100*Period;
41 	u32 MinPeriodTemp = 0xFFFFFFFF;
42 	u32 PeriodTemp = 0;
43 
44 	for (CountId = 0; CountId < 12; CountId++) {
45 		CountTemp = ((0x00000001 << (CountId+1))-1);
46 		DivFactor = (u16)((PeriodProcess)/(CountTemp*3));
47 
48 		if (DivFactor > 0) {
49 			PeriodTemp = 3*(DivFactor+1)*CountTemp;
50 			if (PeriodProcess < PeriodTemp) {
51 				if (MinPeriodTemp > PeriodTemp) {
52 					MinPeriodTemp = PeriodTemp;
53 					*pCountProcess = CountId;
54 					*pDivFacProcess = DivFactor;
55 				}
56 			}
57 		}
58 	}
59 }
60 
61 /**
62   * @brief  Initializes the  WDG registers according to the specified parameters
63   *         get from WDG_Scalar.
64   * @param  WDG_InitStruct: pointer to a WDG_InitTypeDef structure that contains
65   *         the configuration information for the WDG peripheral.
66   * @retval None
67   */
WDG_Init(WDG_InitTypeDef * WDG_InitStruct)68 void WDG_Init(WDG_InitTypeDef *WDG_InitStruct)
69 {
70 	WDG_TypeDef* WDG = ((WDG_TypeDef *) WDG_REG_BASE);
71 	u32 wdg_reg = 0;
72 	u32 temp = 0;
73 
74 	wdg_reg = WDG_InitStruct->DivFacProcess & 0xFFFF; /* WdgScalar */
75 	wdg_reg &= ~(0x00FF0000); /* WdgEnByte */
76 	wdg_reg |= (WDG_InitStruct->CountProcess & 0xF) << 25;
77 	wdg_reg |= WDG_BIT_CLEAR;
78 	wdg_reg |= WDG_BIT_RST_MODE; /* RESET_MODE */
79 	wdg_reg |= WDG_BIT_ISR_CLEAR; /*Clear ISR*/
80 
81 	WDG->VENDOR = wdg_reg;
82 
83 	temp = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_LP_KM0_CTRL);
84 	if (WDG_InitStruct->RstAllPERI == 0)
85 		temp &= ~BIT_LSYS_WDT_RESET_HS_ALL;
86 	else
87 		temp |= BIT_LSYS_WDT_RESET_HS_ALL;
88 	HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_LP_KM0_CTRL, temp);
89 }
90 
91 /**
92   * @brief  Clear WDG interrupt when WDG init use WDG_IrqInit .
93   * @param  None
94   * @note   This function only used in interrupt mode
95   * @retval None
96   */
WDG_IrqClear(void)97 void WDG_IrqClear(void)
98 {
99 	WDG_TypeDef* WDG = ((WDG_TypeDef *) WDG_REG_BASE);
100 	u32 temp = WDG->VENDOR;
101 
102 	/* Clear ISR */
103 	temp |= WDG_BIT_ISR_CLEAR;
104 	WDG->VENDOR = temp;
105 }
106 
107 /**
108   * @brief  init WDG as interrupt mode (close reset mode).
109   * @param  handler: WDG interrupt handler
110   * @param  Id: WDG interrupt handler parameter
111   * @retval None
112   */
WDG_IrqInit(void * handler,u32 Id)113 void WDG_IrqInit(void *handler, u32 Id)
114 {
115 	WDG_TypeDef* WDG = ((WDG_TypeDef *) WDG_REG_BASE);
116 	u32 temp = WDG->VENDOR;
117 
118 	InterruptRegister((IRQ_FUN)handler, WDG_IRQ, Id, 0);
119 	InterruptEn(WDG_IRQ, 0);
120 
121 	temp |= WDG_BIT_ISR_CLEAR;
122 	temp &= ~WDG_BIT_RST_MODE; /* INT_MODE */
123 	WDG->VENDOR = temp;
124 }
125 
126 /**
127   * @brief  Disable/Enable WDG
128   * @param  NewState: new state of the WDG.
129   *          This parameter can be: ENABLE or DISABLE
130   * @note   To enable WDG timer, set 0x1 to WDG register Bit[16]
131   * @retval None
132   */
WDG_Cmd(u32 NewState)133 void WDG_Cmd(u32 NewState)
134 {
135 	WDG_TypeDef* WDG = ((WDG_TypeDef *) WDG_REG_BASE);
136 	u32 temp = WDG->VENDOR;
137 
138 	/* WdgEnBit */
139 	if (NewState == ENABLE)
140 		temp |= WDG_BIT_ENABLE;
141 	else
142 		temp &= ~WDG_BIT_ENABLE;
143 
144 	WDG->VENDOR = temp;
145 
146 	WDG_IrqClear();
147 }
148 
149 /**
150   * @brief  Clear WDG timer
151   * @param  None
152   * @note   If call this function to refresh WDG before timeout period,
153   *			then MCU reset or WDG interrupt won't generate
154   * @retval None
155   */
WDG_Refresh(void)156 void WDG_Refresh(void)
157 {
158 	WDG_TypeDef* WDG = ((WDG_TypeDef *) WDG_REG_BASE);
159 	u32 temp = WDG->VENDOR;
160 
161 	temp |= WDG_BIT_CLEAR;
162 	WDG->VENDOR = temp;
163 }
164 
165 /******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/
166