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