Merge pull request #93 from zyp/master
[fw/stlink] / example / libs_stm / src / stm32l1xx / stm32l1xx_wwdg.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32l1xx_wwdg.c\r
4   * @author  MCD Application Team\r
5   * @version V1.0.0\r
6   * @date    31-December-2010\r
7   * @brief   This file provides firmware functions to manage the following \r
8   *          functionalities of the Window watchdog (WWDG) peripheral:           \r
9   *           - Prescaler, Refresh window and Counter configuration\r
10   *           - WWDG activation\r
11   *           - Interrupts and flags management\r
12   *             \r
13   *  @verbatim\r
14   *    \r
15   *          ===================================================================\r
16   *                                     WWDG features\r
17   *          ===================================================================\r
18   *                                        \r
19   *          Once enabled the WWDG generates a system reset on expiry of a programmed\r
20   *          time period, unless the program refreshes the counter (downcounter) \r
21   *          before to reach 0x3F value (i.e. a reset is generated when the counter\r
22   *          value rolls over from 0x40 to 0x3F). \r
23   *          An MCU reset is also generated if the counter value is refreshed\r
24   *          before the counter has reached the refresh window value. This \r
25   *          implies that the counter must be refreshed in a limited window.\r
26   *            \r
27   *          Once enabled the WWDG cannot be disabled except by a system reset.                          \r
28   *          \r
29   *          WWDGRST flag in RCC_CSR register can be used to inform when a WWDG\r
30   *          reset occurs.\r
31   *            \r
32   *          The WWDG counter input clock is derived from the APB clock divided \r
33   *          by a programmable prescaler.\r
34   *              \r
35   *          WWDG counter clock = PCLK1 / Prescaler\r
36   *          WWDG timeout = (WWDG counter clock) * (counter value)\r
37   *                      \r
38   *          Min-max timeout value @32MHz (PCLK1): ~128us / ~65.6ms\r
39   *                            \r
40   *          ===================================================================\r
41   *                                 How to use this driver\r
42   *          =================================================================== \r
43   *          1. Enable WWDG clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE) function\r
44   *            \r
45   *          2. Configure the WWDG prescaler using WWDG_SetPrescaler() function\r
46   *                           \r
47   *          3. Configure the WWDG refresh window using WWDG_SetWindowValue() function\r
48   *            \r
49   *          4. Set the WWDG counter value and start it using WWDG_Enable() function.\r
50   *             When the WWDG is enabled the counter value should be configured to \r
51   *             a value greater than 0x40 to prevent generating an immediate reset.     \r
52   *            \r
53   *          5. Optionally you can enable the Early wakeup interrupt which is \r
54   *             generated when the counter reach 0x40.\r
55   *             Once enabled this interrupt cannot be disabled except by a system reset.\r
56   *                 \r
57   *          6. Then the application program must refresh the WWDG counter at regular\r
58   *             intervals during normal operation to prevent an MCU reset, using\r
59   *             WWDG_SetCounter() function. This operation must occur only when\r
60   *             the counter value is lower than the refresh window value, \r
61   *             programmed using WWDG_SetWindowValue().         \r
62   *\r
63   *  @endverbatim  \r
64   *                             \r
65   ******************************************************************************\r
66   * @attention\r
67   *\r
68   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
69   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
70   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
71   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
72   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
73   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
74   *\r
75   * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>\r
76   ******************************************************************************  \r
77   */ \r
78 \r
79 /* Includes ------------------------------------------------------------------*/\r
80 #include "stm32l1xx_wwdg.h"\r
81 #include "stm32l1xx_rcc.h"\r
82 \r
83 /** @addtogroup STM32L1xx_StdPeriph_Driver\r
84   * @{\r
85   */\r
86 \r
87 /** @defgroup WWDG \r
88   * @brief WWDG driver modules\r
89   * @{\r
90   */\r
91 \r
92 /* Private typedef -----------------------------------------------------------*/\r
93 /* Private define ------------------------------------------------------------*/\r
94 \r
95 /* ----------- WWDG registers bit address in the alias region ----------- */\r
96 #define WWDG_OFFSET       (WWDG_BASE - PERIPH_BASE)\r
97 \r
98 /* Alias word address of EWI bit */\r
99 #define CFR_OFFSET        (WWDG_OFFSET + 0x04)\r
100 #define EWI_BitNumber     0x09\r
101 #define CFR_EWI_BB        (PERIPH_BB_BASE + (CFR_OFFSET * 32) + (EWI_BitNumber * 4))\r
102 \r
103 /* --------------------- WWDG registers bit mask ------------------------ */\r
104 \r
105 /* CFR register bit mask */\r
106 #define CFR_WDGTB_MASK    ((uint32_t)0xFFFFFE7F)\r
107 #define CFR_W_MASK        ((uint32_t)0xFFFFFF80)\r
108 #define BIT_MASK          ((uint8_t)0x7F)\r
109 \r
110 /* Private macro -------------------------------------------------------------*/\r
111 /* Private variables ---------------------------------------------------------*/\r
112 /* Private function prototypes -----------------------------------------------*/\r
113 /* Private functions ---------------------------------------------------------*/\r
114 \r
115 /** @defgroup WWDG_Private_Functions\r
116   * @{\r
117   */\r
118 \r
119 /** @defgroup WWDG_Group1 Prescaler, Refresh window and Counter configuration functions\r
120  *  @brief   Prescaler, Refresh window and Counter configuration functions \r
121  *\r
122 @verbatim   \r
123  ===============================================================================\r
124           Prescaler, Refresh window and Counter configuration functions\r
125  ===============================================================================  \r
126 \r
127 @endverbatim\r
128   * @{\r
129   */\r
130 \r
131 /**\r
132   * @brief  Deinitializes the WWDG peripheral registers to their default reset values.\r
133   * @param  None\r
134   * @retval None\r
135   */\r
136 void WWDG_DeInit(void)\r
137 {\r
138   RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, ENABLE);\r
139   RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE);\r
140 }\r
141 \r
142 /**\r
143   * @brief  Sets the WWDG Prescaler.\r
144   * @param  WWDG_Prescaler: specifies the WWDG Prescaler.\r
145   *   This parameter can be one of the following values:\r
146   *     @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1\r
147   *     @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2\r
148   *     @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4\r
149   *     @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8\r
150   * @retval None\r
151   */\r
152 void WWDG_SetPrescaler(uint32_t WWDG_Prescaler)\r
153 {\r
154   uint32_t tmpreg = 0;\r
155   /* Check the parameters */\r
156   assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler));\r
157   /* Clear WDGTB[1:0] bits */\r
158   tmpreg = WWDG->CFR & CFR_WDGTB_MASK;\r
159   /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */\r
160   tmpreg |= WWDG_Prescaler;\r
161   /* Store the new value */\r
162   WWDG->CFR = tmpreg;\r
163 }\r
164 \r
165 /**\r
166   * @brief  Sets the WWDG window value.\r
167   * @param  WindowValue: specifies the window value to be compared to the downcounter.\r
168   *   This parameter value must be lower than 0x80.\r
169   * @retval None\r
170   */\r
171 void WWDG_SetWindowValue(uint8_t WindowValue)\r
172 {\r
173   __IO uint32_t tmpreg = 0;\r
174 \r
175   /* Check the parameters */\r
176   assert_param(IS_WWDG_WINDOW_VALUE(WindowValue));\r
177   /* Clear W[6:0] bits */\r
178 \r
179   tmpreg = WWDG->CFR & CFR_W_MASK;\r
180 \r
181   /* Set W[6:0] bits according to WindowValue value */\r
182   tmpreg |= WindowValue & (uint32_t) BIT_MASK;\r
183 \r
184   /* Store the new value */\r
185   WWDG->CFR = tmpreg;\r
186 }\r
187 \r
188 /**\r
189   * @brief  Enables the WWDG Early Wakeup interrupt(EWI).\r
190   * @note   Once enabled this interrupt cannot be disabled except by a system reset. \r
191   * @param  None\r
192   * @retval None\r
193   */\r
194 void WWDG_EnableIT(void)\r
195 {\r
196   *(__IO uint32_t *) CFR_EWI_BB = (uint32_t)ENABLE;\r
197 }\r
198 \r
199 /**\r
200   * @brief  Sets the WWDG counter value.\r
201   * @param  Counter: specifies the watchdog counter value.\r
202   *   This parameter must be a number between 0x40 and 0x7F (to prevent generating\r
203   *   an immediate reset)  \r
204   * @retval None\r
205   */\r
206 void WWDG_SetCounter(uint8_t Counter)\r
207 {\r
208   /* Check the parameters */\r
209   assert_param(IS_WWDG_COUNTER(Counter));\r
210   /* Write to T[6:0] bits to configure the counter value, no need to do\r
211      a read-modify-write; writing a 0 to WDGA bit does nothing */\r
212   WWDG->CR = Counter & BIT_MASK;\r
213 }\r
214 \r
215 /**\r
216   * @}\r
217   */\r
218 \r
219 /** @defgroup WWDG_Group2 WWDG activation functions\r
220  *  @brief   WWDG activation functions \r
221  *\r
222 @verbatim   \r
223  ===============================================================================\r
224                        WWDG activation functions\r
225  ===============================================================================  \r
226 \r
227 @endverbatim\r
228   * @{\r
229   */\r
230 \r
231 /**\r
232   * @brief  Enables WWDG and load the counter value.                  \r
233   * @param  Counter: specifies the watchdog counter value.\r
234   *   This parameter must be a number between 0x40 and 0x7F (to prevent generating\r
235   *   an immediate reset)\r
236   * @retval None\r
237   */\r
238 void WWDG_Enable(uint8_t Counter)\r
239 {\r
240   /* Check the parameters */\r
241   assert_param(IS_WWDG_COUNTER(Counter));\r
242   WWDG->CR = WWDG_CR_WDGA | Counter;\r
243 }\r
244 \r
245 /**\r
246   * @}\r
247   */\r
248 \r
249 /** @defgroup WWDG_Group3 Interrupts and flags management functions\r
250  *  @brief   Interrupts and flags management functions \r
251  *\r
252 @verbatim   \r
253  ===============================================================================\r
254                  Interrupts and flags management functions\r
255  ===============================================================================  \r
256 \r
257 @endverbatim\r
258   * @{\r
259   */\r
260 \r
261 /**\r
262   * @brief  Checks whether the Early Wakeup interrupt flag is set or not.\r
263   * @param  None\r
264   * @retval The new state of the Early Wakeup interrupt flag (SET or RESET)\r
265   */\r
266 FlagStatus WWDG_GetFlagStatus(void)\r
267 {\r
268   FlagStatus bitstatus = RESET;\r
269     \r
270   if ((WWDG->SR) != (uint32_t)RESET)\r
271   {\r
272     bitstatus = SET;\r
273   }\r
274   else\r
275   {\r
276     bitstatus = RESET;\r
277   }\r
278   return bitstatus;\r
279 }\r
280 \r
281 /**\r
282   * @brief  Clears Early Wakeup interrupt flag.\r
283   * @param  None\r
284   * @retval None\r
285   */\r
286 void WWDG_ClearFlag(void)\r
287 {\r
288   WWDG->SR = (uint32_t)RESET;\r
289 }\r
290 \r
291 /**\r
292   * @}\r
293   */\r
294 \r
295 /**\r
296   * @}\r
297   */\r
298 \r
299 /**\r
300   * @}\r
301   */\r
302 \r
303 /**\r
304   * @}\r
305   */\r
306 \r
307 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/\r