1 /**
2 * \file
3 *
4 * \brief SAM System Interrupt Driver
5 *
6 * Copyright (C) 2012-2016 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 SYSTEM_INTERRUPT_H_INCLUDED
47 #define SYSTEM_INTERRUPT_H_INCLUDED
48
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52
53 /**
54 * \defgroup asfdoc_sam0_system_interrupt_group SAM System Interrupt (SYSTEM INTERRUPT) Driver
55 *
56 * This driver for Atmel® | SMART ARM®-based microcontrollers provides
57 * an interface for the configuration and management of internal software and
58 * hardware interrupts/exceptions.
59 *
60 * The following peripheral is used by this module:
61 * - NVIC (Nested Vector Interrupt Controller)
62 *
63 * The following devices can use this module:
64 * - Atmel | SMART SAM D20/D21
65 * - Atmel | SMART SAM R21
66 * - Atmel | SMART SAM D09/D10/D11
67 * - Atmel | SMART SAM L21/L22
68 * - Atmel | SMART SAM DA1
69 * - Atmel | SMART SAM C20/C21
70 * - Atmel | SMART SAM HA1
71 *
72 * The outline of this documentation is as follows:
73 * - \ref asfdoc_sam0_system_interrupt_prerequisites
74 * - \ref asfdoc_sam0_system_interrupt_module_overview
75 * - \ref asfdoc_sam0_system_interrupt_special_considerations
76 * - \ref asfdoc_sam0_system_interrupt_extra_info
77 * - \ref asfdoc_sam0_system_interrupt_examples
78 * - \ref asfdoc_sam0_system_interrupt_api_overview
79 *
80 *
81 * \section asfdoc_sam0_system_interrupt_prerequisites Prerequisites
82 *
83 * There are no prerequisites for this module.
84 *
85 *
86 * \section asfdoc_sam0_system_interrupt_module_overview Module Overview
87 *
88 * The ARM® Cortex® M0+ core contains an interrupt and exception vector table, which
89 * can be used to configure the device's interrupt handlers; individual
90 * interrupts and exceptions can be enabled and disabled, as well as configured
91 * with a variable priority.
92 *
93 * This driver provides a set of wrappers around the core interrupt functions,
94 * to expose a simple API for the management of global and individual interrupts
95 * within the device.
96 *
97 * \subsection asfdoc_sam0_system_interrupt_module_overview_criticalsec Critical Sections
98 * In some applications it is important to ensure that no interrupts may be
99 * executed by the system whilst a critical portion of code is being run; for
100 * example, a buffer may be copied from one context to another - during which
101 * interrupts must be disabled to avoid corruption of the source buffer contents
102 * until the copy has completed. This driver provides a basic API to enter and
103 * exit nested critical sections, so that global interrupts can be kept disabled
104 * for as long as necessary to complete a critical application code section.
105 *
106 * \subsection asfdoc_sam0_system_interrupt_module_overview_softints Software Interrupts
107 * For some applications, it may be desirable to raise a module or core
108 * interrupt via software. For this reason, a set of APIs to set an interrupt or
109 * exception as pending are provided to the user application.
110 *
111 * \section asfdoc_sam0_system_interrupt_special_considerations Special Considerations
112 *
113 * Interrupts from peripherals in the SAM devices are on a per-module basis;
114 * an interrupt raised from any source within a module will cause a single,
115 * module-common handler to execute. It is the user application or driver's
116 * responsibility to de-multiplex the module-common interrupt to determine the
117 * exact interrupt cause.
118 *
119 * \section asfdoc_sam0_system_interrupt_extra_info Extra Information
120 *
121 * For extra information, see \ref asfdoc_sam0_system_interrupt_extra. This includes:
122 * - \ref asfdoc_sam0_system_interrupt_extra_acronyms
123 * - \ref asfdoc_sam0_system_interrupt_extra_dependencies
124 * - \ref asfdoc_sam0_system_interrupt_extra_errata
125 * - \ref asfdoc_sam0_system_interrupt_extra_history
126 *
127 *
128 * \section asfdoc_sam0_system_interrupt_examples Examples
129 *
130 * For a list of examples related to this driver, see
131 * \ref asfdoc_sam0_system_interrupt_exqsg.
132 *
133 * \section asfdoc_sam0_system_interrupt_api_overview API Overview
134 * @{
135 */
136
137 #include <compiler.h>
138 #include <core_cm0plus.h>
139 #include "system_interrupt_features.h"
140
141 /**
142 * \brief Table of possible system interrupt/exception vector priorities.
143 *
144 * Table of all possible interrupt and exception vector priorities within the
145 * device.
146 */
147 enum system_interrupt_priority_level {
148 /** Priority level 0, the highest possible interrupt priority */
149 SYSTEM_INTERRUPT_PRIORITY_LEVEL_0 = 0,
150 /** Priority level 1 */
151 SYSTEM_INTERRUPT_PRIORITY_LEVEL_1 = 1,
152 /** Priority level 2 */
153 SYSTEM_INTERRUPT_PRIORITY_LEVEL_2 = 2,
154 /** Priority level 3, the lowest possible interrupt priority */
155 SYSTEM_INTERRUPT_PRIORITY_LEVEL_3 = 3,
156 };
157
158 /**
159 * \name Critical Section Management
160 * @{
161 */
162
163 /**
164 * \brief Enters a critical section.
165 *
166 * Disables global interrupts. To support nested critical sections, an internal
167 * count of the critical section nesting will be kept, so that global interrupts
168 * are only re-enabled upon leaving the outermost nested critical section.
169 *
170 */
system_interrupt_enter_critical_section(void)171 static inline void system_interrupt_enter_critical_section(void)
172 {
173 cpu_irq_enter_critical();
174 }
175
176 /**
177 * \brief Leaves a critical section.
178 *
179 * Enables global interrupts. To support nested critical sections, an internal
180 * count of the critical section nesting will be kept, so that global interrupts
181 * are only re-enabled upon leaving the outermost nested critical section.
182 *
183 */
system_interrupt_leave_critical_section(void)184 static inline void system_interrupt_leave_critical_section(void)
185 {
186 cpu_irq_leave_critical();
187 }
188
189 /** @} */
190
191 /**
192 * \name Interrupt Enabling/Disabling
193 * @{
194 */
195
196 /**
197 * \brief Check if global interrupts are enabled.
198 *
199 * Checks if global interrupts are currently enabled.
200 *
201 * \returns A boolean that identifies if the global interrupts are enabled or not.
202 *
203 * \retval true Global interrupts are currently enabled
204 * \retval false Global interrupts are currently disabled
205 *
206 */
system_interrupt_is_global_enabled(void)207 static inline bool system_interrupt_is_global_enabled(void)
208 {
209 return cpu_irq_is_enabled();
210 }
211
212 /**
213 * \brief Enables global interrupts.
214 *
215 * Enables global interrupts in the device to fire any enabled interrupt handlers.
216 */
system_interrupt_enable_global(void)217 static inline void system_interrupt_enable_global(void)
218 {
219 cpu_irq_enable();
220 }
221
222 /**
223 * \brief Disables global interrupts.
224 *
225 * Disabled global interrupts in the device, preventing any enabled interrupt
226 * handlers from executing.
227 */
system_interrupt_disable_global(void)228 static inline void system_interrupt_disable_global(void)
229 {
230 cpu_irq_disable();
231 }
232
233 /**
234 * \brief Checks if an interrupt vector is enabled or not.
235 *
236 * Checks if a specific interrupt vector is currently enabled.
237 *
238 * \param[in] vector Interrupt vector number to check
239 *
240 * \returns A variable identifying if the requested interrupt vector is enabled.
241 *
242 * \retval true Specified interrupt vector is currently enabled
243 * \retval false Specified interrupt vector is currently disabled
244 *
245 */
system_interrupt_is_enabled(const enum system_interrupt_vector vector)246 static inline bool system_interrupt_is_enabled(
247 const enum system_interrupt_vector vector)
248 {
249 return (bool)((NVIC->ISER[0] >> (uint32_t)vector) & 0x00000001);
250 }
251
252 /**
253 * \brief Enable interrupt vector.
254 *
255 * Enables execution of the software handler for the requested interrupt vector.
256 *
257 * \param[in] vector Interrupt vector to enable
258 */
system_interrupt_enable(const enum system_interrupt_vector vector)259 static inline void system_interrupt_enable(
260 const enum system_interrupt_vector vector)
261 {
262 NVIC->ISER[0] = (uint32_t)(1 << ((uint32_t)vector & 0x0000001f));
263 }
264
265 /**
266 * \brief Disable interrupt vector.
267 *
268 * Disables execution of the software handler for the requested interrupt vector.
269 *
270 * \param[in] vector Interrupt vector to disable
271 */
system_interrupt_disable(const enum system_interrupt_vector vector)272 static inline void system_interrupt_disable(
273 const enum system_interrupt_vector vector)
274 {
275 NVIC->ICER[0] = (uint32_t)(1 << ((uint32_t)vector & 0x0000001f));
276 }
277
278 /** @} */
279
280 /**
281 * \name Interrupt State Management
282 * @{
283 */
284
285 /**
286 * \brief Get active interrupt (if any).
287 *
288 * Return the vector number for the current executing software handler, if any.
289 *
290 * \return Interrupt number that is currently executing.
291 */
system_interrupt_get_active(void)292 static inline enum system_interrupt_vector system_interrupt_get_active(void)
293 {
294 uint32_t IPSR = __get_IPSR();
295 /* The IPSR returns the Exception number, which with an offset 16 to IRQ number. */
296 return (enum system_interrupt_vector)((IPSR & _SYSTEM_INTERRUPT_IPSR_MASK) - 16);
297 }
298
299 bool system_interrupt_is_pending(
300 const enum system_interrupt_vector vector);
301
302 enum status_code system_interrupt_set_pending(
303 const enum system_interrupt_vector vector);
304
305 enum status_code system_interrupt_clear_pending(
306 const enum system_interrupt_vector vector);
307
308 /** @} */
309
310 /**
311 * \name Interrupt Priority Management
312 * @{
313 */
314
315 enum status_code system_interrupt_set_priority(
316 const enum system_interrupt_vector vector,
317 const enum system_interrupt_priority_level priority_level);
318
319 enum system_interrupt_priority_level system_interrupt_get_priority(
320 const enum system_interrupt_vector vector);
321
322 /** @} */
323
324 /** @} */
325
326 /**
327 * \page asfdoc_sam0_system_interrupt_extra Extra Information for SYSTEM INTERRUPT Driver
328 *
329 * \section asfdoc_sam0_system_interrupt_extra_acronyms Acronyms
330 * The table below presents the acronyms used in this module:
331 *
332 * <table>
333 * <tr>
334 * <th>Acronym</th>
335 * <th>Description</th>
336 * </tr>
337 * <tr>
338 * <td>ISR</td>
339 * <td>Interrupt Service Routine</td>
340 * </tr>
341 * <tr>
342 * <td>NMI</td>
343 * <td>Non-maskable Interrupt</td>
344 * </tr>
345 * <tr>
346 * <td>SERCOM</td>
347 * <td>Serial Communication Interface</td>
348 * </tr>
349 * </table>
350 *
351 *
352 * \section asfdoc_sam0_system_interrupt_extra_dependencies Dependencies
353 * This driver has the following dependencies:
354 *
355 * - None
356 *
357 *
358 * \section asfdoc_sam0_system_interrupt_extra_errata Errata
359 * There are no errata related to this driver.
360 *
361 *
362 * \section asfdoc_sam0_system_interrupt_extra_history Module History
363 * An overview of the module history is presented in the table below, with
364 * details on the enhancements and fixes made to the module since its first
365 * release. The current version of this corresponds to the newest version in
366 * the table.
367 *
368 * <table>
369 * <tr>
370 * <th>Changelog</th>
371 * </tr>
372 * <tr>
373 * <td>Initial Release</td>
374 * </tr>
375 * </table>
376 */
377
378 /**
379 * \page asfdoc_sam0_system_interrupt_exqsg Examples for SYSTEM INTERRUPT Driver
380 *
381 * This is a list of the available Quick Start guides (QSGs) and example
382 * applications for \ref asfdoc_sam0_system_interrupt_group. QSGs are simple examples with
383 * step-by-step instructions to configure and use this driver in a selection of
384 * use cases. Note that a QSG can be compiled as a standalone application or be
385 * added to the user application.
386 *
387 * - \subpage asfdoc_sam0_system_interrupt_critsec_use_case
388 * - \subpage asfdoc_sam0_system_interrupt_enablemodint_use_case
389 *
390 * \page asfdoc_sam0_system_interrupt_document_revision_history Document Revision History
391 *
392 * <table>
393 * <tr>
394 * <th>Doc. Rev.</th>
395 * <th>Date</th>
396 * <th>Comments</th>
397 * </tr>
398 * <tr>
399 * <td>42122E</td>
400 * <td>12/2015</td>
401 * <td>Added support for SAM L21/L22, SAM DA1, SAM D09, and SAM C20/C21</td>
402 * </tr>
403 * <tr>
404 * <td>42122D</td>
405 * <td>12/2014</td>
406 * <td>Added support for SAM R21 and SAM D10/D11</td>
407 * </tr>
408 * <tr>
409 * <td>42122C</td>
410 * <td>01/2014</td>
411 * <td>Added support for SAM D21</td>
412 * </tr>
413 * <tr>
414 * <td>42122B</td>
415 * <td>06/2013</td>
416 * <td>Corrected documentation typos</td>
417 * </tr>
418 * <tr>
419 * <td>42122A</td>
420 * <td>06/2013</td>
421 * <td>Initial release</td>
422 * </tr>
423 * </table>
424 */
425
426 #ifdef __cplusplus
427 }
428 #endif
429
430 #endif // #ifndef SYSTEM_INTERRUPT_H_INCLUDED
431