]> git.sur5r.net Git - freertos/blob - Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_watchdog/mss_watchdog.h
Create directory structure to hold the (not yet created) Keil and IAR demo projects...
[freertos] / Demo / CORTEX_A2F200_IAR_and_Keil / MicroSemi_Code / drivers / mss_watchdog / mss_watchdog.h
1 /*******************************************************************************\r
2  * (c) Copyright 2009 Actel Corporation.  All rights reserved.\r
3  * \r
4  * SmartFusion Microcontroller Subsystem (MSS) Watchdog bare metal software\r
5  * driver.\r
6  *\r
7  * SVN $Revision: 1888 $\r
8  * SVN $Date: 2009-12-18 10:58:42 +0000 (Fri, 18 Dec 2009) $\r
9  */\r
10 /*=========================================================================*//**\r
11   @section intro_sec Introduction\r
12   The SmartFusion microcontroller subsystem (MSS) includes a watchdog timer used\r
13   to detect system lockups.\r
14   This driver provides a set of functions for controlling the MSS watchdog as\r
15   part of a bare metal system where no operating system is available. These\r
16   drivers can be adapted for use as part of an operating system but the\r
17   implementation of the adaptation layer between this driver and the operating\r
18   system's driver model is outside the scope of this driver.\r
19     \r
20   @section hw_dependencies Hardware Flow Dependencies\r
21   The configuration of all features of the MSS watchdog is covered by this\r
22   driver. There are no dependencies on the hardware flow for configuring the\r
23   SmartFusion MSS watchdog timer.\r
24     \r
25   @section theory_op Theory of Operation\r
26   The watchdog driver uses the SmartFusion "Cortex Microcontroler Software\r
27   Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access hadware\r
28   registers. You must ensure that the SmartFusion CMSIS-PAL is either included\r
29   in the software toolchain used to build your project or is included in your\r
30   project. The most up-to-date SmartFusion CMSIS-PAL files can be obtained using\r
31   the Actel Firmware Catalog.\r
32   \r
33   The watchdog driver functions are grouped into the following categories:\r
34     - Initialization and cnfiguration\r
35     - Reading the watchdog timer current value and status\r
36     - Refreshing the watchdog timer value\r
37     - Time-out and wake-up interrupts control\r
38   \r
39   The watchdog driver is initialized and configured through a call to the\r
40   MSS_WD_init() function. The parameters passed to MSS_WD_init() function\r
41   specify the watchdog timer configuration. The configuration parameters include\r
42   the value that will be reloaded into the watchdog timer down counter every\r
43   time the watchdog is refreshed. Also included as part of the configuration\r
44   parameters is the optional allowed refresh window. The allowed refresh window\r
45   specifies the maximum allowed current value of the watchdog timer at the time\r
46   of the watchdog is relaoded. Attempting to reload the watchdog timer when its\r
47   value is larger than the allowed refresh window will cause a reset or\r
48   interrupt depending on the watchdog configuration. The allowed refresh window\r
49   can be disabled by specifying an allowed refesh window equal or higher than\r
50   the watchdog reload value.\r
51   The MSS_WD_init() function must be called before any other watchdog driver\r
52   functions can be called with the exception of the MSS_WD_disable() function.\r
53   \r
54   The watchdog timer can be disabled using the MSS_WD_disable() function. Once\r
55   disabled, the watchdog timer can only be reenabled by a power-on reset.\r
56   \r
57   The watchdog timer current value can be read using the MSS_WD_current_value()\r
58   function. The watchdog status can be read using the MSS_WD_status() function.\r
59   These functions are typically required when using the watchdog configured with\r
60   an allowed refresh window to check if a watchdog reload is currently allowed.\r
61   \r
62   The watchdog timer value is reloaded using the MSS_WD_reload() function. The\r
63   value reloaded into the watchdog timer down counter is the value specified as\r
64   parameter to the MSS_WD_init() function.\r
65   \r
66   The watchdog timer can generate interrupts instead of resetting the system\r
67   when its down-counter timer expires. These time-out interrupts are controlled\r
68   using the following functions:\r
69     - MSS_WD_enable_timeout_irq\r
70     - MSS_WD_disable_timeout_irq\r
71     - MSS_WD_clear_timeout_irq\r
72   \r
73   The watchdog timer is external to the Cortex-M3 processor core and operates\r
74   even when the Cortex-M3 is in sleep mode. A wakeup interrupt can be generated\r
75   by the watchdog timer to wakeup the Cortext-M3 when the watchdog timer value\r
76   reaches the allowed refresh window while the Cortex-M3 is in sleep mode. The\r
77   watchdog driver provides the following functions to control wakeup interrupts:\r
78     - MSS_WD_enable_wakeup_irq\r
79     - MSS_WD_disable_wakeup_irq\r
80     - MSS_WD_clear_wakeup_irq\r
81     \r
82  *//*=========================================================================*/\r
83 \r
84 #ifndef MSS_WATCHDOG_H_\r
85 #define MSS_WATCHDOG_H_\r
86 \r
87 #ifdef __cplusplus\r
88 extern "C" {\r
89 #endif \r
90 \r
91 #include "../../CMSIS/a2fxxxm3.h"\r
92 \r
93 /***************************************************************************//**\r
94  * The MSS_WDOG_RESET_ON_TIMEOUT_MODE macro is one of the possible values for the\r
95  * mode parameter of the WD_init() function. It is used to specify that a reset\r
96  * should occur when the watchdog down counter times out.\r
97  */\r
98 #define MSS_WDOG_RESET_ON_TIMEOUT_MODE       (uint32_t)0x00000000U\r
99 \r
100 /***************************************************************************//**\r
101  * The MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE macro is one of the possible values for\r
102  * the  mode parameter of function the WD_init() function. It is used to specify\r
103  * that a time out interrupt should occur when the watchdog down counter expires.\r
104  */\r
105 #define MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE   (uint32_t)0x00000004U\r
106 \r
107 /***************************************************************************//**\r
108  * The MSS_WDOG_NO_WINDOW macro can be used as the value for the reload_window\r
109  * parameter of the WD_init() function. It is used to specify that no forbidden\r
110  * window will exist for the reload of the watchdog down counter.\r
111  */\r
112 #define MSS_WDOG_NO_WINDOW    (uint32_t)0xFFFFFFFFU\r
113 \r
114 /***************************************************************************//**\r
115  * The MSS_WDOG_CTRL_MODE_BIT_MASK macro is a bit mask specifying the bit used to\r
116  * set the watchdog's operating mode within the wathcdog's WDOGCONTROL register.\r
117  */\r
118 #define MSS_WDOG_CTRL_MODE_BIT_MASK           (uint32_t)0x00000004U\r
119 \r
120 /***************************************************************************//**\r
121  * The MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK macro is a bit mask specifying the bit\r
122  * used to enable the time out interrupt within the watchdog's WDOGCONTROL\r
123  * register.\r
124  */\r
125 #define MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK  (uint32_t)0x00000001U\r
126 \r
127 /***************************************************************************//**\r
128   The MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK macro is a bit mask specifying the bit\r
129   used to enable the wake up interrupt within the watchdog's WDOGCONTROL\r
130   register.\r
131  */\r
132 #define MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK   (uint32_t)0x00000002U\r
133 \r
134 /***************************************************************************//**\r
135   The MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK macro is a bit mask specifying the bit\r
136   used to clear the time out interrupt within the watchdog's WDOGRIS register.\r
137  */\r
138 #define MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK   (uint32_t)0x00000001U\r
139 \r
140 /***************************************************************************//**\r
141   The MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK macro is a bit mask specifying the bit\r
142   used to clear the wake up interrupt within the watchdog's WDOGRIS register.\r
143  */\r
144 #define MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK    (uint32_t)0x00000002U\r
145 \r
146 /***************************************************************************//**\r
147   The MSS_WDOG_REFRESH_KEY macro holds the magic value which will cause a reload\r
148   of the watchdog's down counter when written to the watchdog's WDOGREFRESH\r
149   register.\r
150  */\r
151 #define MSS_WDOG_REFRESH_KEY    (uint32_t)0xAC15DE42U\r
152 \r
153 /***************************************************************************//**\r
154   The MSS_WDOG_DISABLE_KEY macro holds the magic value which will disable the\r
155   watchdog if written to the watchdog's WDOGENABLE register.\r
156  */\r
157 #define MSS_WDOG_DISABLE_KEY    (uint32_t)0x4C6E55FAU\r
158 \r
159 /***************************************************************************//**\r
160   The MSS_WD_init() function initializes and configures the watchdog timer.\r
161  \r
162   @param load_value\r
163     The load_value parameter specifies the value that will be loaded into the\r
164     watchdog's down counter when the reload command is issued through a call to\r
165     MSS_WD_reload().\r
166                    \r
167   @param reload_window\r
168     The reload_window parameter specifies the time window during which a reload\r
169     of the watchdog counter is allowed. A reload of the watchdog counter should\r
170     only be performed when the watchdog counter value is below the value of the\r
171     reload_window. Reloading the watchdog down counter value before it has\r
172     reached the reload_window will result in an interrupt or reset depending on\r
173     the watchdog's mode.\r
174     The reload window can be disabled by using WDOG_NO_WINDOW for this parameter.\r
175  \r
176   @param mode\r
177     The mode parameter specifies the watchdog's operating mode. It can be either\r
178     MSS_WDOG_RESET_ON_TIMEOUT_MODE or MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE.\r
179     MSS_WDOG_RESET_ON_TIMEOUT_MODE: a reset will occur if the watchdog timer\r
180     expires.\r
181     MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE: an NMI interrupt will occur if the\r
182     watchdog timer expires.\r
183  \r
184   @return\r
185     This function does not return a value.\r
186  */\r
187 static __INLINE void MSS_WD_init\r
188 (\r
189     uint32_t load_value,\r
190     uint32_t reload_window,\r
191     uint32_t mode\r
192 )\r
193 {\r
194     /* Disable interrupts. */\r
195     WATCHDOG->WDOGCONTROL &= ~(MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK | MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK);\r
196     \r
197     /* Clear any existing interrupts. */\r
198     WATCHDOG->WDOGRIS = MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK | MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK;\r
199     \r
200     /* Configure watchdog with new configuration passed as parameter. */\r
201     WATCHDOG->WDOGMVRP = MSS_WDOG_NO_WINDOW;\r
202     WATCHDOG->WDOGLOAD = load_value;\r
203     WATCHDOG->WDOGCONTROL = (WATCHDOG->WDOGCONTROL & ~MSS_WDOG_CTRL_MODE_BIT_MASK) | (mode & MSS_WDOG_CTRL_MODE_BIT_MASK);\r
204     \r
205     /* Reload watchdog with new load value. */\r
206     WATCHDOG->WDOGREFRESH = MSS_WDOG_REFRESH_KEY;\r
207     \r
208     /* Set allowed window. */\r
209     WATCHDOG->WDOGMVRP = reload_window;\r
210 }\r
211 \r
212 /***************************************************************************//**\r
213   The MSS_WD_reload() function causes the watchdog to reload its down counter timer\r
214   with the load value configured through the call to WD_init(). This function \r
215   must be called regularly to avoid a system reset.\r
216  \r
217   @return\r
218     This function does not return a value.\r
219  */\r
220 static __INLINE void MSS_WD_reload( void )\r
221 {\r
222     WATCHDOG->WDOGREFRESH = MSS_WDOG_REFRESH_KEY;\r
223 }\r
224 \r
225 /***************************************************************************//**\r
226   The MSS_WD_disable() function disables the watchdog.\r
227   Please note that the watchdog can only be reenabled as a result of a power-on\r
228   reset.\r
229  \r
230   @return\r
231     This function does not return a value.\r
232  */\r
233 static __INLINE void MSS_WD_disable( void )\r
234 {\r
235     WATCHDOG->WDOGENABLE = MSS_WDOG_DISABLE_KEY;\r
236 }\r
237 \r
238 /***************************************************************************//**\r
239   The MSS_WD_current_value() function returns the current value of the watchdog's\r
240   down counter.\r
241  \r
242   @return\r
243     This function returns the current value of the watchdog down counter.\r
244  */\r
245 static __INLINE uint32_t MSS_WD_current_value( void )\r
246 {\r
247     return WATCHDOG->WDOGVALUE;\r
248 }\r
249 \r
250 /***************************************************************************//**\r
251   The MSS_WD_status() function returns the status of the watchdog.\r
252  \r
253   @return \r
254     The MSS_WD_status() function returns the status of the watchdog. A value of\r
255     0 indicates that watchdog counter has reached the forbidden window and that\r
256     a reload should not be done. A value of 1 indicates that the watchdog counter\r
257     is within the permitted window and that a reload is allowed.\r
258  */\r
259 static __INLINE uint32_t MSS_WD_status( void )\r
260 {\r
261     return WATCHDOG->WDOGSTATUS;\r
262 }\r
263 \r
264 /***************************************************************************//**\r
265   The MSS_WD_enable_timeout_irq() function enables the watchdog\92s time out\r
266   interrupt which is connected to the Cortex-M3 NMI interrupt.\r
267   The NMI_Handler() function will be called when a watchdog time out occurs. You\r
268   must provide the implementation of the NMI_Handler() function to suit your\r
269   application.\r
270  \r
271   @return\r
272     This function does not return a value.\r
273  \r
274   Example:\r
275   @code\r
276   #include "mss_watchdog.h"\r
277   int main( void )\r
278   {\r
279       MSS_WD_init( 0x10000000, MSS_WDOG_NO_WINDOW, MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE );\r
280       MSS_WD_enable_timeout_irq();\r
281       for (;;)\r
282       {\r
283           main_task();\r
284       }\r
285   }\r
286  \r
287   void NMI_Handler( void )\r
288   {\r
289       process_timeout();\r
290       MSS_WD_clear_timeout_irq();\r
291   }\r
292   @endcode\r
293  */\r
294 static __INLINE void MSS_WD_enable_timeout_irq( void )\r
295 {\r
296     WATCHDOG->WDOGCONTROL |= MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK;\r
297 }\r
298 \r
299 /***************************************************************************//**\r
300   The WD_disable_timeout_irq() function disables the generation of the NMI\r
301   interrupt when the watchdog times out.\r
302  \r
303   @return\r
304     This function does not return a value.\r
305  */\r
306 static __INLINE void MSS_WD_disable_timeout_irq( void )\r
307 {\r
308     WATCHDOG->WDOGCONTROL &= ~MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK;\r
309 }\r
310 \r
311 /***************************************************************************//**\r
312   The MSS_WD_enable_wakeup_irq() function enables the SmartFusion wakeup\r
313   interrupt. The WdogWakeup_IRQHandler() function will be called when a wake up\r
314   interrupt occurs. You must provide the implementation of the WdogWakeup_IRQHandler()\r
315   function to suit your application.\r
316  \r
317   @return\r
318     This function does not return a value.\r
319  \r
320   Example:\r
321   @code\r
322   #include "mss_watchdog.h"\r
323   int main( void )\r
324   {\r
325       MSS_WD_init( 0x10000000, MSS_WDOG_NO_WINDOW, MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE );\r
326       MSS_WD_enable_wakeup_irq();\r
327       for (;;)\r
328       {\r
329           main_task();\r
330           cortex_sleep();\r
331       }\r
332   }\r
333  \r
334   void WdogWakeup_IRQHandler( void )\r
335   {\r
336       process_wakeup();\r
337       MSS_WD_clear_wakeup_irq();\r
338   }\r
339   @endcode\r
340  */\r
341 static __INLINE void MSS_WD_enable_wakeup_irq( void )\r
342 {\r
343     WATCHDOG->WDOGCONTROL |= MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK;\r
344     NVIC_EnableIRQ( WdogWakeup_IRQn );\r
345 }\r
346 \r
347 /***************************************************************************//**\r
348   The MSS_WD_disable_wakeup_irq() function disables the SmartFusion wakeup\r
349   interrupt. \r
350  \r
351   @return\r
352     This function does not return a value.\r
353  */\r
354 static __INLINE void MSS_WD_disable_wakeup_irq( void )\r
355 {\r
356     WATCHDOG->WDOGCONTROL &= ~MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK;\r
357 }\r
358 \r
359 /***************************************************************************//**\r
360   The MSS_WD_clear_timeout_irq() function clears the watchdog\92s time out\r
361   interrupt which is connected to the Cortex-M3 NMI interrupt.\r
362   Calling MSS_WD_clear_timeout_irq() results in clearing the Cortex-M3 NMI interrupt.\r
363   Note: The MSS_WD_clear_timeout_irq() function must be called as part of the\r
364   timeout interrupt service routine (ISR) in order to prevent the same interrupt\r
365   event retriggering a call to the wakeup ISR.\r
366  \r
367   @return\r
368     The example below demonstrates the use of the MSS_WD_clear_timeout_irq()\r
369     function as part of the NMI interrupt service routine.\r
370 \r
371     Example:\r
372   @code\r
373   void NMI_Handler( void )\r
374   {\r
375       process_timeout();\r
376       MSS_WD_clear_timeout_irq();\r
377   }\r
378   @endcode\r
379  */\r
380 static __INLINE void MSS_WD_clear_timeout_irq( void )\r
381 {\r
382     WATCHDOG->WDOGRIS = MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK;\r
383     /*\r
384      * Perform a second write to ensure that the first write completed before \r
385      * returning from this function. This is to account for posted writes across\r
386      * the AHB matrix. The second write ensures that the first write has\r
387      * completed and that the interrupt line has been de-asserted by the time\r
388      * the function returns. Omitting the second write may result in a delay\r
389      * in the de-assertion of the interrupt line going to the Cortex-M3 and a\r
390      * retriggering of the interrupt.\r
391      */\r
392     WATCHDOG->WDOGRIS = MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK;\r
393 }\r
394 \r
395 /***************************************************************************//**\r
396   The MSS_WD_clear_wakeup_irq() function clears the wakeup interrupt.\r
397   Note: The MSS_WD_clear_wakeup_irq() function must be called as part of the\r
398   wakeup interrupt service routine (ISR) in order to prevent the same interrupt\r
399   event retriggering a call to the wakeup ISR. This function also clears the\r
400   interrupt in the Cortex-M3 interrupt controller through a call to\r
401   NVIC_ClearPendingIRQ().\r
402  \r
403   @return\r
404     This function does not return a value.\r
405 \r
406     Example:\r
407     The example below demonstrates the use of the MSS_WD_clear_wakeup_irq() function\r
408     as part of the wakeup interrupt service routine.  \r
409     @code\r
410     void WdogWakeup_IRQHandler( void )\r
411     {\r
412         do_interrupt_processing();\r
413         \r
414         MSS_WD_clear_wakeup_irq();\r
415     }\r
416     @endcode\r
417 */\r
418 static __INLINE void MSS_WD_clear_wakeup_irq( void )\r
419 {\r
420     WATCHDOG->WDOGRIS = MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK;\r
421     NVIC_ClearPendingIRQ( WdogWakeup_IRQn );\r
422 }\r
423 #ifdef __cplusplus\r
424 }\r
425 #endif\r
426 \r
427 #endif /* MSS_WATCHDOG_H_ */\r