1 /**
2  * \file
3  *
4  * \brief CPU reset cause functions
5  *
6  * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 #ifndef COMMON_DRIVERS_CPU_RESET_CAUSE_H
47 #define COMMON_DRIVERS_CPU_RESET_CAUSE_H
48 
49 #include <parts.h>
50 #include <stdbool.h>
51 
52 #if XMEGA
53 # include "xmega_reset_cause.h"
54 #elif UC3
55 # include "avr32_reset_cause.h"
56 #elif SAM4L
57 # include "sam4l_reset_cause.h"
58 #else
59 # error Unsupported chip type
60 #endif
61 
62 /**
63  * \defgroup reset_cause_group CPU reset cause
64  *
65  * See \ref reset_cause_quickstart
66  *
67  * This is a generic interface for getting and clearing the chip reset causes.
68  *
69  * \section dependencies Dependencies
70  *
71  * The reset cause interface does not depend on any other modules, as it only
72  * accesses a few registers in the device core.
73  *
74  * On the other hand, the software reset call might depend on \ref sysclk_group
75  * to enable the clock to the debug system, for devices doing software reset
76  * through the on-chip debug system. This applies only to the 32-bit AVR
77  * devices.
78  *
79  * \section Quick start guide
80  * See \ref reset_cause_quickstart
81  *
82  * @{
83  */
84 
85 /*
86  * Sanity check of reset causes, define undefined reset causes to 0. Hence they
87  * will always return false when queried.
88  */
89 #ifndef CHIP_RESET_CAUSE_BOD_CPU
90 /**
91  * \brief Brown-out detected on CPU power domain reset cause not available on
92  * this chip.
93  */
94 # define CHIP_RESET_CAUSE_BOD_CPU       0
95 #endif
96 #ifndef CHIP_RESET_CAUSE_BOD_IO
97 /**
98  * \brief Brown-out detected on I/O power domain reset cause not available on
99  * this chip.
100  */
101 # define CHIP_RESET_CAUSE_BOD_IO        0
102 #endif
103 #ifndef CHIP_RESET_CAUSE_CPU_ERROR
104 //! CPU error reset cause not available on this chip.
105 # define CHIP_RESET_CAUSE_CPU_ERROR     0
106 #endif
107 #ifndef CHIP_RESET_CAUSE_EXTRST
108 //! External reset cause not available on this chip.
109 # define CHIP_RESET_CAUSE_EXTRST        0
110 #endif
111 #ifndef CHIP_RESET_CAUSE_JTAG
112 //! JTAG reset cause not available on this chip.
113 # define CHIP_RESET_CAUSE_JTAG          0
114 #endif
115 #ifndef CHIP_RESET_CAUSE_OCD
116 //! On-chip debug system reset cause not available on this chip.
117 # define CHIP_RESET_CAUSE_OCD           0
118 #endif
119 #ifndef CHIP_RESET_CAUSE_POR
120 //! Power-on-reset reset cause not available on this chip.
121 # define CHIP_RESET_CAUSE_POR           0
122 #endif
123 #ifndef CHIP_RESET_CAUSE_POR_IO
124 //! Power-on-reset on I/O power domain reset cause not available on this chip.
125 # define CHIP_RESET_CAUSE_POR_IO           0
126 #endif
127 #ifndef CHIP_RESET_CAUSE_SLEEP
128 //! Wake from Shutdown sleep mode reset cause not available on this chip.
129 # define CHIP_RESET_CAUSE_SLEEP         0
130 #endif
131 #ifndef CHIP_RESET_CAUSE_SOFT
132 //! Software reset reset cause not available on this chip.
133 # define CHIP_RESET_CAUSE_SOFT          0
134 #endif
135 #ifndef CHIP_RESET_CAUSE_SPIKE
136 //! Spike detected reset cause not available on this chip.
137 # define CHIP_RESET_CAUSE_SPIKE         0
138 #endif
139 #ifndef CHIP_RESET_CAUSE_WDT
140 //! Watchdog timeout reset cause not available on this chip.
141 # define CHIP_RESET_CAUSE_WDT           0
142 #endif
143 
144 /**
145  * \brief List of reset causes in bit-mask format
146  */
147 enum reset_cause {
148 	/** \brief Brown-out detected on CPU power domain reset cause */
149 	RESET_CAUSE_BOD_CPU     = CHIP_RESET_CAUSE_BOD_CPU,
150 	/** \brief Brown-out detected on I/O power domain reset cause */
151 	RESET_CAUSE_BOD_IO      = CHIP_RESET_CAUSE_BOD_IO,
152 	/** \brief CPU error reset cause */
153 	RESET_CAUSE_CPU_ERROR   = CHIP_RESET_CAUSE_CPU_ERROR,
154 	/** \brief External reset cause */
155 	RESET_CAUSE_EXTRST      = CHIP_RESET_CAUSE_EXTRST,
156 	/** \brief JTAG reset cause */
157 	RESET_CAUSE_JTAG        = CHIP_RESET_CAUSE_JTAG,
158 	/** \brief On-chip debug system reset cause */
159 	RESET_CAUSE_OCD         = CHIP_RESET_CAUSE_OCD,
160 	/** \brief Power-on-reset reset cause */
161 	RESET_CAUSE_POR         = CHIP_RESET_CAUSE_POR,
162 	/** \brief Power-on-reset reset cause */
163 	RESET_CAUSE_POR_IO         = CHIP_RESET_CAUSE_POR_IO,
164 	/** \brief Wake from Shutdown sleep mode reset cause */
165 	RESET_CAUSE_SLEEP       = CHIP_RESET_CAUSE_SLEEP,
166 	/** \brief Software reset reset cause */
167 	RESET_CAUSE_SOFT        = CHIP_RESET_CAUSE_SOFT,
168 	/** \brief Spike detected reset cause */
169 	RESET_CAUSE_SPIKE       = CHIP_RESET_CAUSE_SPIKE,
170 	/** \brief Watchdog timeout reset cause */
171 	RESET_CAUSE_WDT         = CHIP_RESET_CAUSE_WDT,
172 };
173 
174 //! \name Management
175 //@{
176 
177 /**
178  * \fn void reset_do_soft_reset(void)
179  * \brief Perform a software reset of the device
180  *
181  * \note This function will never return.
182  * \note This function does not disable interrupts, this is up to the caller to
183  *       handle.
184  */
185 /**
186  * \fn reset_cause_t reset_cause_get_causes(void)
187  * \brief Get all reset causes
188  *
189  * This function will return a value containing the currently triggered reset
190  * cause(s).
191  *
192  * \return Bit-mask with each active reset cause set to 1.
193  */
194 /**
195  * \fn reset_cause_clear_causes(reset_cause_t causes)
196  * \brief Clear a bit-mask of reset causes
197  *
198  * This function will clear the provided reset causes in the reset cause
199  * register.
200  *
201  * \param causes bit-mask of reset causes to clear
202  */
203 
204 //@}
205 
206 //! \name Specific reset cause helper functions
207 //@{
208 
209 /**
210  * \brief Check if chip reset was caused by a CPU power brown-out detection
211  *
212  * \return True if reset was caused by a CPU power brown-out detection
213  */
reset_cause_is_cpu_brown_out_detected(void)214 static inline bool reset_cause_is_cpu_brown_out_detected(void)
215 {
216 	return (reset_cause_get_causes() & RESET_CAUSE_BOD_CPU);
217 }
218 
219 /**
220  * \brief Check if chip reset was caused by an I/O power brown-out detection
221  *
222  * \return True if reset was caused by an I/O power brown-out detection
223  */
reset_cause_is_io_brown_out_detected(void)224 static inline bool reset_cause_is_io_brown_out_detected(void)
225 {
226 	return (reset_cause_get_causes() & RESET_CAUSE_BOD_IO);
227 }
228 
229 /**
230  * \brief Check if chip reset was caused by a brown-out detection on any
231  * power domain.
232  *
233  * \return True if reset was caused by a power brown-out detection
234  */
reset_cause_is_brown_out_detected(void)235 static inline bool reset_cause_is_brown_out_detected(void)
236 {
237 	return (reset_cause_is_cpu_brown_out_detected() ||
238 			reset_cause_is_io_brown_out_detected());
239 }
240 
241 /**
242  * \brief Check if chip reset was caused by a CPU error, illegal access
243  *
244  * \return True if reset was caused by a CPU error, illegal access
245  */
reset_cause_is_cpu_error(void)246 static inline bool reset_cause_is_cpu_error(void)
247 {
248 	return (reset_cause_get_causes() & RESET_CAUSE_CPU_ERROR);
249 }
250 
251 /**
252  * \brief Check if chip reset was caused by an external reset
253  *
254  * \return True if reset was caused by an external reset
255  */
reset_cause_is_external_reset(void)256 static inline bool reset_cause_is_external_reset(void)
257 {
258 	return (reset_cause_get_causes() & RESET_CAUSE_EXTRST);
259 }
260 
261 /**
262  * \brief Check if chip reset was caused by a JTAG reset
263  *
264  * \return True if reset was caused by a JTAG reset
265  */
reset_cause_is_jtag(void)266 static inline bool reset_cause_is_jtag(void)
267 {
268 	return (reset_cause_get_causes() & RESET_CAUSE_JTAG);
269 }
270 
271 /**
272  * \brief Check if chip reset was caused by the on-chip debug system
273  *
274  * \return True if reset was caused by the on-chip debug system
275  */
reset_cause_is_ocd(void)276 static inline bool reset_cause_is_ocd(void)
277 {
278 	return (reset_cause_get_causes() & RESET_CAUSE_OCD);
279 }
280 
281 /**
282  * \brief Check if chip reset was caused by a power-on-reset
283  *
284  * \return True if reset was caused by a power-on-reset
285  */
reset_cause_is_power_on_reset(void)286 static inline bool reset_cause_is_power_on_reset(void)
287 {
288 	return (reset_cause_get_causes() & RESET_CAUSE_POR);
289 }
290 
291 /**
292  * \brief Check if chip reset was caused by an I/O power-on-reset
293  *
294  * \return True if reset was caused by a power-on-reset
295  */
reset_cause_is_io_power_on_reset(void)296 static inline bool reset_cause_is_io_power_on_reset(void)
297 {
298 	return (reset_cause_get_causes() & RESET_CAUSE_POR_IO);
299 }
300 
301 /**
302  * \brief Check if chip reset was caused by a wake up from shutdown sleep mode
303  *
304  * \return True if reset was caused by a wake up from shutdown sleep mode
305  */
reset_cause_is_wake_from_shutdown_sleep(void)306 static inline bool reset_cause_is_wake_from_shutdown_sleep(void)
307 {
308 	return (reset_cause_get_causes() & RESET_CAUSE_SLEEP);
309 }
310 
311 /**
312  * \brief Check if chip reset was caused by a software reset
313  *
314  * \return True if reset was caused by a software reset
315  */
reset_cause_is_software_reset(void)316 static inline bool reset_cause_is_software_reset(void)
317 {
318 	return (reset_cause_get_causes() & RESET_CAUSE_SOFT);
319 }
320 
321 /**
322  * \brief Check if chip reset was caused by a power spike detection
323  *
324  * \return True if reset was caused by a spike detection
325  */
reset_cause_is_spike_detected(void)326 static inline bool reset_cause_is_spike_detected(void)
327 {
328 	return (reset_cause_get_causes() & RESET_CAUSE_SPIKE);
329 }
330 
331 /**
332  * \brief Check if chip reset was caused by a watchdog timeout
333  *
334  * \return True if reset was caused by a watchdog timeout
335  */
reset_cause_is_watchdog(void)336 static inline bool reset_cause_is_watchdog(void)
337 {
338 	return (reset_cause_get_causes() & RESET_CAUSE_WDT);
339 }
340 
341 //@}
342 
343 //! @}
344 
345 /**
346  * \page reset_cause_quickstart Quick start guide for reset cause service
347  *
348  * This is the quick start guide for the \ref reset_cause_group
349  * "Reset Cause service", with step-by-step instructions on how to configure
350  * and use the driver in a selection of use cases.
351  *
352  * The use cases contain several code fragments. The code fragments in the
353  * steps for setup can be copied into a custom initialization function, while
354  * the steps for usage can be copied into, e.g., the main application function.
355  *
356  * \section reset_cause_basic_use_case Basic use case
357  * In this basic use case, the reset cause service is used for checking if the
358  * last reset was a watchdog reset.
359  *
360  * \section reset_cause_basic_use_case_setup Setup steps
361  *
362  * \subsection reset_cause_basic_use_case_setup_code Example code
363  * Add to application C-file:
364  * \code
365 	 if (reset_cause_is_watchdog()) {
366 		// Do action due to last reset being a watchdog reset
367 		reset_cause_clear_causes(RESET_CAUSE_WDT);
368 	 }
369 \endcode
370  *
371  * \subsection reset_cause_basic_use_case_setup_flow Workflow
372  * -# Check for watchdog reset flag:
373  *   - \code if (reset_cause_is_watchdog()) { \endcode
374  *   - \attention Please consult the specific device datasheet on which reset
375  *   causes that are supported.
376  * -# Insert your own code taking action here. E.g.: Increase a watchdog reset
377  * counter.
378  * -# Reset flag if the flag was set to make sure it's not falsely
379  * detected in another reset:
380  *   - \code reset_cause_clear_causes(RESET_CAUSE_WDT); \endcode
381  *
382  * \section reset_cause_use_cases Advanced use cases
383  * For more advanced use of the Reset Cause service, see the following use cases:
384  * - \subpage reset_cause_use_case_1 : Software controlled reset
385  */
386 
387 /**
388  * \page reset_cause_use_case_1 Use case #1
389  * In this use case, the reset cause service is used to perform a software
390  * controlled reset.
391  *
392  * \section reset_cause_use_case_1_setup Setup steps
393  *
394  * \subsection reset_cause_use_case_1_setup_flow Workflow
395  * -# Call soft reset. This call will not return.
396  *   - \code reset_do_soft_reset(); \endcode
397  */
398 
399 #endif /* COMMON_DRIVERS_CPU_RESET_CAUSE_H */
400