1 /**
2  * \file
3  *
4  * \brief SAM Peripheral Access Controller 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 PAC_H_INCLUDED
47 #define PAC_H_INCLUDED
48 
49 /**
50  * \defgroup asfdoc_sam0_pac_group SAM Peripheral Access Controller (PAC) Driver
51  *
52  * This driver for Atmel&reg; | SMART ARM&reg;-based microcontroller provides
53  * an interface for the locking and unlocking of peripheral registers within
54  * the device. When a peripheral is locked, accidental writes to the peripheral
55  * will be blocked and a CPU exception will be raised.
56  *
57  * The following peripherals are used by this module:
58  *  - PAC (Peripheral Access Controller)
59  *
60  * The following devices can use this module:
61  *  - Atmel | SMART SAM D20/D21
62  *  - Atmel | SMART SAM R21
63  *  - Atmel | SMART SAM D09/D10/D11
64  *  - Atmel | SMART SAM L21/L22
65  *  - Atmel | SMART SAM DA1
66  *  - Atmel | SMART SAM C20/C21
67  *  - Atmel | SMART SAM HA1
68  *
69  * The outline of this documentation is as follows:
70  *  - \ref asfdoc_sam0_pac_prerequisites
71  *  - \ref asfdoc_sam0_pac_module_overview
72  *  - \ref asfdoc_sam0_pac_special_considerations
73  *  - \ref asfdoc_sam0_pac_extra_info
74  *  - \ref asfdoc_sam0_pac_examples
75  *  - \ref asfdoc_sam0_pac_api_overview
76  *
77  *
78  * \section asfdoc_sam0_pac_prerequisites Prerequisites
79  *
80  * There are no prerequisites for this module.
81  *
82  *
83  * \section asfdoc_sam0_pac_module_overview Module Overview
84  *
85  * The SAM devices are fitted with a Peripheral Access Controller (PAC)
86  * that can be used to lock and unlock write access to a peripheral's
87  * registers (see \ref asfdoc_sam0_pac_non_write_protected). Locking a
88  * peripheral minimizes the risk of unintended configuration changes to a
89  * peripheral as a consequence of \ref asfdoc_sam0_pac_code_run_away
90  * or use of a \ref asfdoc_sam0_pac_module_pointer.
91  *
92  * Physically, the PAC restricts write access through the AHB bus to registers
93  * used by the peripheral, making the register non-writable. PAC locking of
94  * modules should be implemented in configuration critical applications where
95  * avoiding unintended peripheral configuration changes are to be regarded in
96  * the highest of priorities.
97  *
98  * All interrupt must be disabled while a peripheral is unlocked to make sure
99  * correct lock/unlock scheme is upheld.
100  *
101  * \subsection asfdoc_sam0_pac_locking_scheme Locking Scheme
102  * The module has a built in safety feature requiring that an already locked
103  * peripheral is not relocked, and that already unlocked peripherals are not
104  * unlocked again. Attempting to unlock and already unlocked peripheral, or
105  * attempting to lock a peripheral that is currently locked will generate a
106  * CPU exception. This implies that the implementer must keep
107  * strict control over the peripheral's lock-state before modifying them. With
108  * this added safety, the probability of stopping runaway code increases as
109  * the program pointer can be caught inside the exception handler, and necessary
110  * countermeasures can be initiated. The implementer should also consider using
111  * sanity checks after an unlock has been performed to further increase the
112  * security.
113  *
114  * \subsection asfdoc_sam0_pac_correct_implementation Recommended Implementation
115  * A recommended implementation of the PAC can be seen in
116  * \ref asfdoc_sam0_pac_rec_imp_diagram "the figure below".
117  *
118  * \anchor asfdoc_sam0_pac_rec_imp_diagram
119  * \dot
120  *	digraph correct {
121  *		subgraph cluster_a {
122  *			style="filled, dotted";
123  *			coler=lightgray;
124  *			init [label="Initialize Peripheral", shape=box];
125  *			lock [label="Lock peripheral", shape=box];
126  *			label="Initialization and code";
127  *			init -> lock;
128  *		}
129  *		subgraph cluster_b {
130  *			cli [label="Disable global interrupts", shape=box,
131  *				style=dotted];
132  *			unlock [label="Unlock peripheral", shape=box];
133  *			sanity [label="Sanity Check", shape=box, style=dotted];
134  *			modify [label="Modify peripheral", shape=box];
135  *			lock2 [label="Lock peripheral", shape=box];
136  *			sei [label="Enable global interrupts", shape=box
137  *				style=dotted];
138 *
139  *			label="Peripheral Modification";
140  *			cli -> unlock;
141  *			unlock -> sanity
142  *			sanity -> modify;
143  *			modify -> lock2;
144  *			lock2 -> sei;
145  *		}
146  *		lock -> cli [label=
147  *			"Other initialization\n and enable interrupts if applicable"
148  *				, style=dotted];
149  *	}
150  * \enddot
151  *
152  * \subsection asfdoc_sam0_pac_enabled_interrupt Why Disable Interrupts
153  * Global interrupts must be disabled while a peripheral is unlocked as an
154  * interrupt handler would not know the current state of the peripheral lock. If
155  * the interrupt tries to alter the lock state, it can cause an exception as it
156  * potentially tries to unlock an already unlocked peripheral. Reading current
157  * lock state is to be avoided as it removes the security provided by the PAC
158  * (\ref asfdoc_sam0_pac_check_lock).
159  *
160  * \note Global interrupts should also be disabled when a peripheral is unlocked
161  *       inside an interrupt handler.
162  *
163  * An example to illustrate the potential hazard of not disabling interrupts is
164  * shown in \ref asfdoc_sam0_pac_int_hazard_diagram "the diagram below".
165  *
166  * \anchor asfdoc_sam0_pac_int_hazard_diagram
167  * \dot
168  *	digraph enabled_interrupt {
169  *		subgraph cluster_0{
170  *			label="Main routine";
171  *			{node [style="filled", color=black, fillcolor=white]
172  *			init [label="Initialize and lock peripherals", shape=box];
173  *			main_unlock [label="Unlock peripheral",	shape=box,
174  *				fillcolor=green];
175  *			main_modify [label="Modify peripheral", shape=box];}
176  *			main_lock [label="Lock peripheral", shape=box];
177  *			init -> main_unlock [label="User code"];
178  *			main_unlock -> main_modify;
179  *			main_modify -> main_lock [style=dotted];
180  *		}
181  *		subgraph cluster_1 {
182  *			label="Interrupt handler";
183  *			int_unlock [label="Unlock peripheral", shape=box,
184  *				style=filled, fillcolor=red];
185  *			int_modify [label="Modify peripheral", shape=box];
186  *			int_lock [label="Lock peripheral", shape=box];
187  *			int_unlock -> int_modify [style=dotted];
188  *			int_modify -> int_lock [style=dotted];
189  *		}
190  *		exception [label="Exception", shape=box, style=filled, fillcolor=red];
191  *		main_modify -> int_unlock [label=" Interrupt"];
192  *		int_unlock -> exception;
193  *		exception -> exception;
194  *	}
195  * \enddot
196  *
197  * \subsection asfdoc_sam0_pac_code_run_away Run-away Code
198  * Run-away code can be caused by the MCU being operated outside its
199  * specification, faulty code, or EMI issues. If a runaway code occurs, it is
200  * favorable to catch the issue as soon as possible. With a correct
201  * implementation of the PAC, the runaway code can potentially be stopped.
202  *
203  * A graphical example showing how a PAC implementation will behave for
204  * different circumstances of runaway code in shown in
205  * \ref asfdoc_sam0_pac_code_runaway_diagram "the first" and
206  * \ref asfdoc_sam0_pac_code_runaway_diagram2 "second figures below".
207  *
208  * \anchor asfdoc_sam0_pac_code_runaway_diagram
209  * \dot
210  *	digraph run_away {
211  *	   subgraph cluster_away1{
212  *		rankdir=TB;
213  *		color=white;
214  *		runaway1 [label="Run-away code", shape=box];
215  *		node [shape=plaintext];
216  *		program1 [label=<
217  *			<table>
218  *				<tr>
219  *					<td>PC#</td>
220  *					<td>Code</td>
221  *				</tr>
222  *				<tr>
223  *					<td>0x0020</td>
224  *					<td>initialize peripheral</td>
225  *				</tr>
226  *				<tr>
227  *					<td>0x0025</td>
228  *					<td>lock peripheral</td>
229  *				</tr>
230  *				<tr>
231  *					<td>...</td>
232  *					<td>...</td>
233  *				</tr>
234  *				<tr>
235  *					<td>0x0080</td>
236  *					<td>set sanity argument</td>
237  *				</tr>
238  *				<tr>
239  *					<td port="f0" BGCOLOR="green">...</td>
240  *					<td BGCOLOR="green">...</td>
241  *				</tr>
242  *				<tr>
243  *					<td BGCOLOR="green">0x0115</td>
244  *					<td BGCOLOR="green">disable interrupts</td>
245  *				</tr>
246  *				<tr>
247  *					<td BGCOLOR="green">0x0120</td>
248  *					<td BGCOLOR="green">unlock peripheral</td>
249  *				</tr>
250  *				<tr>
251  *					<td BGCOLOR="red">0x0125</td>
252  *					<td BGCOLOR="red">check sanity argument</td>
253  *				</tr>
254  *				<tr>
255  *					<td>0x0130</td>
256  *					<td>modify peripheral</td>
257  *				</tr>
258  *				<tr>
259  *					<td>0x0140</td>
260  *					<td>lock peripheral</td>
261  *				</tr>
262  *				<tr>
263  *					<td>0x0145</td>
264  *					<td>disable interrupts</td>
265  *				</tr>
266  *			</table>
267  *			>]
268  *			runaway1 -> program1:f0;
269  *			label="1. Run-away code is caught in sanity check.\nA CPU exception is executed."
270  *		}
271  *	   subgraph cluster_away2{
272  *		rankdir=TB;
273  *		runaway2 [label="Run-away code", shape=box];
274  *		color=white;
275  *		node [shape=plaintext];
276  *		program2 [label=<
277  *			<table>
278  *				<tr>
279  *					<td>PC#</td>
280  *					<td>Code</td>
281  *				</tr>
282  *				<tr>
283  *					<td>0x0020</td>
284  *					<td>initialize peripheral</td>
285  *				</tr>
286  *				<tr>
287  *					<td>0x0025</td>
288  *					<td>lock peripheral</td>
289  *				</tr>
290  *				<tr>
291  *					<td>...</td>
292  *					<td>...</td>
293  *				</tr>
294  *				<tr>
295  *					<td>0x0080</td>
296  *					<td>set sanity argument</td>
297  *				</tr>
298  *				<tr>
299  *					<td >...</td>
300  *					<td >...</td>
301  *				</tr>
302  *				<tr>
303  *					<td >0x0115</td>
304  *					<td >disable interrupts</td>
305  *				</tr>
306  *				<tr>
307  *					<td >0x0120</td>
308  *					<td >unlock peripheral</td>
309  *				</tr>
310  *				<tr>
311  *					<td >0x0125</td>
312  *					<td >check sanity argument</td>
313  *				</tr>
314  *				<tr>
315  *					<td port="f0" BGCOLOR="red">0x0130</td>
316  *					<td BGCOLOR="red">modify peripheral</td>
317  *				</tr>
318  *				<tr>
319  *					<td>0x0140</td>
320  *					<td>lock peripheral</td>
321  *				</tr>
322  *				<tr>
323  *					<td>0x0145</td>
324  *					<td>disable interrupts</td>
325  *				</tr>
326  *			</table>
327  *			>]
328  *			runaway2 -> program2:f0;
329  *			label="2. Run-away code is caught when modifying\nlocked peripheral. A CPU exception is executed."
330  *		}
331  *	}
332  * \enddot
333  *
334  * \anchor asfdoc_sam0_pac_code_runaway_diagram2
335  * \dot
336  *	digraph run_away2 {
337  *	   subgraph cluster_away3{
338  *		rankdir=TB;
339  *		runaway3 [label="Run-away code", shape=box];
340  *		color=white;
341  *		node [shape=plaintext];
342  *		program3 [label=<
343  *			<table>
344  *				<tr>
345  *					<td>PC#</td>
346  *					<td>Code</td>
347  *				</tr>
348  *				<tr>
349  *					<td>0x0020</td>
350  *					<td>initialize peripheral</td>
351  *				</tr>
352  *				<tr>
353  *					<td>0x0025</td>
354  *					<td>lock peripheral</td>
355  *				</tr>
356  *				<tr>
357  *					<td>...</td>
358  *					<td>...</td>
359  *				</tr>
360  *				<tr>
361  *					<td>0x0080</td>
362  *					<td>set sanity argument</td>
363  *				</tr>
364  *				<tr>
365  *					<td >...</td>
366  *					<td >...</td>
367  *				</tr>
368  *				<tr>
369  *					<td >0x0115</td>
370  *					<td >disable interrupts</td>
371  *				</tr>
372  *				<tr>
373  *					<td >0x0120</td>
374  *					<td >unlock peripheral</td>
375  *				</tr>
376  *				<tr>
377  *					<td >0x0125</td>
378  *					<td >check sanity argument</td>
379  *				</tr>
380  *				<tr>
381  *					<td >0x0130</td>
382  *					<td >modify peripheral</td>
383  *				</tr>
384  *				<tr>
385  *					<td port="f0" BGCOLOR="red">0x0140</td>
386  *					<td BGCOLOR="red">lock peripheral</td>
387  *				</tr>
388  *				<tr>
389  *					<td>0x0145</td>
390  *					<td>disable interrupts</td>
391  *				</tr>
392  *			</table>
393  *			>]
394  *			runaway3 -> program3:f0;
395  *			label="3. Run-away code is caught when locking\nlocked peripheral. A CPU exception is executed."
396  *		}
397  *	subgraph cluster_away4 {
398  *		rankdir=TB;
399  *		runaway4 [label="Run-away code", shape=box];
400  *		color=white;
401  *		node [shape=plaintext];
402  *		program4 [label=<
403  *			<table>
404  *				<tr>
405  *					<td>PC#</td>
406  *					<td>Code</td>
407  *				</tr>
408  *				<tr>
409  *					<td>0x0020</td>
410  *					<td>initialize peripheral</td>
411  *				</tr>
412  *				<tr>
413  *					<td>0x0025</td>
414  *					<td>lock peripheral</td>
415  *				</tr>
416  *				<tr>
417  *					<td port="f0" BGCOLOR="green">...</td>
418  *					<td BGCOLOR="green">...</td>
419  *				</tr>
420  *				<tr>
421  *					<td BGCOLOR="green">0x0080</td>
422  *					<td BGCOLOR="green">set sanity argument</td>
423  *				</tr>
424  *				<tr>
425  *					<td BGCOLOR="green">...</td>
426  *					<td BGCOLOR="green">...</td>
427  *				</tr>
428  *				<tr>
429  *					<td BGCOLOR="green">0x0115</td>
430  *					<td BGCOLOR="green">disable interrupts</td>
431  *				</tr>
432  *				<tr>
433  *					<td BGCOLOR="green">0x0120</td>
434  *					<td BGCOLOR="green">unlock peripheral</td>
435  *				</tr>
436  *				<tr>
437  *					<td BGCOLOR="green">0x0125</td>
438  *					<td BGCOLOR="green">check sanity argument</td>
439  *				</tr>
440  *				<tr>
441  *					<td BGCOLOR="green">0x0130</td>
442  *					<td BGCOLOR="green">modify peripheral</td>
443  *				</tr>
444  *				<tr>
445  *					<td BGCOLOR="green">0x0140</td>
446  *					<td BGCOLOR="green">lock peripheral</td>
447  *				</tr>
448  *				<tr>
449  *					<td BGCOLOR="green">0x0145</td>
450  *					<td BGCOLOR="green">disable interrupts</td>
451  *				</tr>
452  *			</table>
453  *			>]
454  *			runaway4 -> program4:f0;
455  *			label="4. Run-away code is not caught.\n "
456  *		}
457  *	}
458  * \enddot
459  *
460  * In the example, green indicates that the command is allowed, red indicates
461  * where the runaway code will be caught, and the arrow where the runaway
462  * code enters the application. In special circumstances, like example 4
463  * above, the runaway code will not be caught. However, the protection scheme
464  * will greatly enhance peripheral configuration security from being affected by
465  * runaway code.
466  *
467  * \subsubsection asfdoc_sam0_pac_bitwise_code Key-Argument
468  * To protect the module functions against runaway code themselves, a key
469  * is required as one of the input arguments. The key-argument will make sure
470  * that runaway code entering the function without a function call will be
471  * rejected before inflicting any damage. The argument is simply set to be
472  * the bitwise inverse of the module flag, i.e.
473  *
474  * \code
475 	system_peripheral_<lock_state>(SYSTEM_PERIPHERAL_<module>,
476 			~SYSTEM_PERIPHERAL_<module>);
477 \endcode
478  *
479  * Where the lock state can be either lock or unlock, and module refer to the
480  * peripheral that is to be locked/unlocked.
481  *
482  * \subsection asfdoc_sam0_pac_module_pointer Faulty Module Pointer
483  * The PAC also protects the application from user errors such as the use of
484  * incorrect module pointers in function arguments, given that the module is
485  * locked. It is therefore recommended that any unused peripheral is locked
486  * during application initialization.
487  *
488  * \subsection asfdoc_sam0_pac_no_inline Use of __no_inline
489  * Using the function attribute \c __no_inline will ensure that there will only be
490  * one copy of each functions in the PAC driver API in the application. This will
491  * lower the likelihood that runaway code will hit any of these functions.
492  *
493  * \subsection asfdoc_sam0_pac_module_overview_physical Physical Connection
494  *
495  * \ref asfdoc_sam0_pac_int_connections "The diagram below" shows how this
496  * module is interconnected within the device.
497  *
498  * \anchor asfdoc_sam0_pac_int_connections
499  * \dot
500  * digraph overview {
501  *	nodesep = .05;
502  *	rankdir=LR;
503  *
504  *	ahb [label="Peripheral bus", shape=ellipse, style=filled, fillcolor=lightgray];
505  *	pac [label="<f0>PAC|<f1>Lock|<f2>Open|<f3>Open",
506  *		 height=2.5, shape=record, width=.1];
507  *	per1 [label="Peripheral1", shape=ellipse, style=filled, fillcolor=lightgray];
508  *	per2 [label="Peripheral2", shape=ellipse, style=filled, fillcolor=lightgray];
509  *	per3 [label="Peripheral3", shape=ellipse, style=filled, fillcolor=lightgray];
510  *	edge [dir="both"];
511  *	ahb -> pac:f1 [label="Read/Write"];
512  *	ahb -> pac:f2 [label="Read/Write"];
513  *	ahb -> pac:f3 [label="Read/Write"];
514  *	edge [dir="back"];
515  *	pac:f1 -> per1 [label="Read"];
516  *	edge [dir="both"];
517  *	pac:f2 -> per2 [label="Read/Write"];
518  *	pac:f3 -> per3 [label="Read/Write"];
519  *	{rank=same; per1 per2 per3 }
520  * }
521  * \enddot
522  *
523  *
524  * \section asfdoc_sam0_pac_special_considerations Special Considerations
525  *
526  * \subsection asfdoc_sam0_pac_non_write_protected Non-Writable Registers
527  * Not all registers in a given peripheral can be set non-writable. Which
528  * registers this applies to is showed in \ref asfdoc_sam0_pac_non_write_list
529  * and the peripheral's subsection "Register Access Protection" in the device
530  * datasheet.
531  *
532  * \subsection asfdoc_sam0_pac_check_lock Reading Lock State
533  * Reading the state of the peripheral lock is to be avoided as it greatly
534  * compromises the protection initially provided by the PAC. If a lock/unlock
535  * is implemented conditionally, there is a risk that eventual errors are not
536  * caught in the protection scheme. Examples indicating the issue are shown
537  * in \ref asfdoc_sam0_pac_lock_errors_diagram "the diagram below".
538  *
539  * \anchor asfdoc_sam0_pac_lock_errors_diagram
540  * \dot
541  *	digraph read_lock {
542  *	   subgraph cluster_read1{
543  *		rankdir=TB;
544  *		color=white;
545  *		runaway1 [label="Run-away code\nwith peripheral unlocked", shape=box];
546  *		node [shape=plaintext];
547  *		program1 [label=<
548  *			<table>
549  *				<tr>
550  *					<td>PC#</td>
551  *					<td>Code</td>
552  *				</tr>
553  *				<tr>
554  *					<td port="f0" BGCOLOR="green">...</td>
555  *					<td BGCOLOR="green">...</td>
556  *				</tr>
557  *				<tr>
558  *					<td BGCOLOR="green">0x0100</td>
559  *					<td BGCOLOR="green">check if locked</td>
560  *				</tr>
561  *				<tr>
562  *					<td BGCOLOR="green">0x0102</td>
563  *					<td BGCOLOR="green">disable interrupts</td>
564  *				</tr>
565  *				<tr>
566  *					<td BGCOLOR="green">0x0105</td>
567  *					<td BGCOLOR="green">unlock if locked</td>
568  *				</tr>
569  *				<tr>
570  *					<td BGCOLOR="green">0x0110</td>
571  *					<td BGCOLOR="green">check sanity</td>
572  *				</tr>
573  *				<tr>
574  *					<td BGCOLOR="green">0x0115</td>
575  *					<td BGCOLOR="green">modify peripheral</td>
576  *				</tr>
577  *				<tr>
578  *					<td BGCOLOR="green">0x0120</td>
579  *					<td BGCOLOR="green">lock if previously locked</td>
580  *				</tr>
581  *				<tr>
582  *					<td BGCOLOR="green">0x0125</td>
583  *					<td BGCOLOR="green">enable interrupts</td>
584  *				</tr>
585  *			</table>
586  *			>]
587  *			runaway1 -> program1:f0;
588  *			label="1. Wrong implementation.\n "
589  *		}
590  *	   subgraph cluster_read2{
591  *		rankdir=TB;
592  *		color=white;
593  *		runaway2 [label="Run-away code\nwith peripheral unlocked", shape=box];
594  *		node [shape=plaintext];
595  *		program2 [label=<
596  *			<table>
597  *				<tr>
598  *					<td>PC#</td>
599  *					<td>Code</td>
600  *				</tr>
601  *				<tr>
602  *					<td port="f0" BGCOLOR="green">...</td>
603  *					<td BGCOLOR="green">...</td>
604  *				</tr>
605  *				<tr>
606  *					<td BGCOLOR="green">0x0100</td>
607  *					<td BGCOLOR="green">disable interrupts</td>
608  *				</tr>
609  *				<tr>
610  *					<td BGCOLOR="red">0x0120</td>
611  *					<td BGCOLOR="red">unlock peripheral</td>
612  *				</tr>
613  *				<tr>
614  *					<td>0x0125</td>
615  *					<td>check sanity argument</td>
616  *				</tr>
617  *				<tr>
618  *					<td>0x0130</td>
619  *					<td>modify peripheral</td>
620  *				</tr>
621  *				<tr>
622  *					<td>0x0140</td>
623  *					<td>lock peripheral</td>
624  *				</tr>
625  *				<tr>
626  *					<td>0x0145</td>
627  *					<td>disable interrupts</td>
628  *				</tr>
629  *			</table>
630  *			>]
631  *			runaway2 -> program2:f0;
632  *
633  *			label="2. Correct implementation.\n "
634  *		}
635  *	}
636  * \enddot
637  *
638  * In the left figure above, one can see the runaway code continues as all
639  * illegal operations are conditional. On the right side figure, the runaway
640  * code is caught as it tries to unlock the peripheral.
641  *
642  * \section asfdoc_sam0_pac_extra_info Extra Information
643  *
644  * For extra information, see \ref asfdoc_sam0_pac_extra. This includes:
645  *  - \ref asfdoc_sam0_pac_extra_acronyms
646  *  - \ref asfdoc_sam0_pac_extra_dependencies
647  *  - \ref asfdoc_sam0_pac_extra_errata
648  *  - \ref asfdoc_sam0_pac_extra_history
649  *
650  *
651  * \section asfdoc_sam0_pac_examples Examples
652  *
653  * For a list of examples related to this driver, see
654  * \ref asfdoc_sam0_pac_exqsg.
655  *
656  *
657  * \section asfdoc_sam0_pac_api_overview API Overview
658  * @{
659  */
660 
661 #include <compiler.h>
662 #include <system.h>
663 
664 #ifdef __cplusplus
665 extern "C" {
666 #endif
667 
668 /**
669  * Retrieves the ID of a specified peripheral name, giving its peripheral bus
670  * location.
671  *
672  * \param[in] peripheral  Name of the peripheral instance
673  *
674  * \returns Bus ID of the specified peripheral instance.
675  */
676 #define SYSTEM_PERIPHERAL_ID(peripheral)    ID_##peripheral
677 
678 /** \name Peripheral Lock and Unlock
679  * @{
680  */
681 __no_inline enum status_code system_peripheral_lock(
682 		const uint32_t peripheral_id,
683 		const uint32_t key);
684 
685 __no_inline enum status_code system_peripheral_unlock(
686 		const uint32_t peripheral_id,
687 		const uint32_t key);
688 /** @}  */
689 
690 #if (SAML21) || (SAML22) || (SAMC20) || (SAMC21) || (SAMR30) || defined(__DOXYGEN__)
691 /** \name APIs available for SAM L21/L22/C20/C21.
692  * @{
693  */
694 __no_inline enum status_code system_peripheral_lock_always(
695 		const uint32_t peripheral_id,
696 		const uint32_t key);
697 
698 /**
699  * \brief Enable PAC interrupt.
700  *
701  * Enable PAC interrupt so can trigger execution on peripheral access error,
702  * see \ref SYSTEM_Handler().
703  *
704  */
system_pac_enable_interrupt(void)705 static inline void system_pac_enable_interrupt(void)
706 {
707 	PAC->INTENSET.reg = PAC_INTENSET_ERR;
708 }
709 
710 /**
711  * \brief Disable PAC interrupt.
712  *
713  * Disable PAC interrupt on peripheral access error.
714  *
715  */
system_pac_disable_interrupt(void)716 static inline void system_pac_disable_interrupt(void)
717 {
718 	PAC->INTENCLR.reg = PAC_INTENCLR_ERR;
719 }
720 
721 /**
722  * \brief Enable PAC event output.
723  *
724  * Enable PAC event output on peripheral access error.
725  *
726  */
system_pac_enable_event(void)727 static inline void system_pac_enable_event(void)
728 {
729 	PAC->EVCTRL.reg = PAC_EVCTRL_ERREO;
730 }
731 
732 /**
733  * \brief Disable PAC event output.
734  *
735  * Disable PAC event output on peripheral access error.
736  *
737  */
system_pac_disable_event(void)738 static inline void system_pac_disable_event(void)
739 {
740 	PAC->EVCTRL.reg &= (~PAC_EVCTRL_ERREO);
741 }
742 
743 /** @}  */
744 #endif
745 
746 #ifdef __cplusplus
747 }
748 #endif
749 
750 /** @}  */
751 
752 /**
753  * \page asfdoc_sam0_pac_extra Extra Information for PAC Driver
754  *
755  * \section asfdoc_sam0_pac_extra_acronyms Acronyms
756  * Below is a table listing the acronyms used in this module, along with their
757  * intended meanings.
758  *
759  * <table>
760  *	<tr>
761  *		<th>Acronym</td>
762  *		<th>Description</td>
763  *	</tr>
764  *  <tr>
765  *		<td>AC</td>
766  *		<td>Analog Comparator</td>
767  *	</tr>
768  *	<tr>
769  *		<td>ADC</td>
770  *		<td>Analog-to-Digital Converter</td>
771  *	</tr>
772  *	<tr>
773  *		<td>EVSYS</td>
774  *		<td>Event System</td>
775  *	</tr>
776  *	<tr>
777  *		<td>NMI</td>
778  *		<td>Non-Maskable Interrupt</td>
779  *	</tr>
780  *	<tr>
781  *		<td>NVMCTRL</td>
782  *		<td>Non-Volatile Memory Controller</td>
783  *	</tr>
784  *	<tr>
785  *		<td>PAC</td>
786  *		<td>Peripheral Access Controller</td>
787  *	</tr>
788   *	<tr>
789  *		<td>PM</td>
790  *		<td>Power Manager</td>
791  *	</tr>
792  *	<tr>
793  *		<td>RTC</td>
794  *		<td>Real-Time Counter</td>
795  *	</tr>
796  *	<tr>
797  *		<td>SERCOM</td>
798  *		<td>Serial Communication Interface</td>
799  *	</tr>
800  *	<tr>
801  *		<td>SYSCTRL</td>
802  *		<td>System Controller</td>
803  *	</tr>
804  *	<tr>
805  *		<td>TC</td>
806  *		<td>Timer/Counter</td>
807  *	</tr>
808  *	<tr>
809  *		<td>WDT</td>
810  *		<td>Watch Dog Timer</td>
811  *	</tr>
812  * </table>
813  *
814  *
815  * \section asfdoc_sam0_pac_extra_dependencies Dependencies
816  * This driver has the following dependencies:
817  *
818  *  - None
819  *
820  *
821  * \section asfdoc_sam0_pac_extra_errata Errata
822  * There are no errata related to this driver.
823  *
824  *
825  * \section asfdoc_sam0_pac_extra_history Module History
826  * An overview of the module history is presented in the table below, with
827  * details on the enhancements and fixes made to the module since its first
828  * release. The current version of this corresponds to the newest version in
829  * the table.
830  *
831  * <table>
832  *	<tr>
833  *		<th>Changelog</th>
834  *	</tr>
835  *	<tr>
836  *		<td>Initial Release</td>
837  *	</tr>
838  * </table>
839  */
840 
841 /**
842  * \page asfdoc_sam0_pac_exqsg Examples for PAC Driver
843  *
844  * This is a list of the available Quick Start guides (QSGs) and example
845  * applications for \ref asfdoc_sam0_pac_group. QSGs are simple examples with
846  * step-by-step instructions to configure and use this driver in a selection of
847  * use cases. Note that a QSG can be compiled as a standalone application or be
848  * added to the user application.
849  *
850  *  - \subpage asfdoc_sam0_pac_basic_use_case
851  */
852 
853 /**
854  * \page asfdoc_sam0_pac_non_write_list List of Non-Write Protected Registers
855  *
856  * Look in device datasheet peripheral's subsection "Register Access
857  * Protection" to see which is actually available for your device.
858  * <table>
859  *	<tr>
860  *		<th>Module</th>
861  *		<th>Non-write protected register</th>
862  *	</tr>
863  *	<tr>
864  *		<td>AC</td>
865  *		<td>INTFLAG</td>
866  *	</tr>
867  *	<tr>
868  *		<td></td>
869  *		<td>STATUSA</td>
870  *	</tr>
871  *	<tr>
872  *		<td></td>
873  *		<td>STATUSB</td>
874  *	</tr>
875  *	<tr>
876  *		<td></td>
877  *		<td>STATUSC</td>
878  *	</tr>
879  *	<tr><td colspan="2"/></tr>
880  *	<tr>
881  *		<td>ADC</td>
882  *		<td>INTFLAG</td>
883  *	</tr>
884  *	<tr>
885  *		<td></td>
886  *		<td>STATUS</td>
887  *	</tr>
888  *	<tr>
889  *		<td></td>
890  *		<td>RESULT</td>
891  *	</tr>
892  *	<tr><td colspan="2"/></tr>
893  *	<tr>
894  *		<td>EVSYS</td>
895  *		<td>INTFLAG</td>
896  *	</tr>
897  *	<tr>
898  *		<td></td>
899  *		<td>CHSTATUS</td>
900  *	</tr>
901  *	<tr><td colspan="2"/></tr>
902  *	<tr>
903  *		<td>NVMCTRL</td>
904  *		<td>INTFLAG</td>
905  *	</tr>
906  *	<tr>
907  *		<td></td>
908  *		<td>STATUS</td>
909  *	</tr>
910  *	<tr><td colspan="2"/></tr>
911  *	<tr>
912  *		<td>PM</td>
913  *		<td>INTFLAG</td>
914  *	</tr>
915  *	<tr><td colspan="2"/></tr>
916  *	<tr>
917  *		<td>PORT</td>
918  *		<td>N/A</td>
919  *	</tr>
920  *	<tr><td colspan="2"/></tr>
921  *	<tr>
922  *		<td>RTC</td>
923  *		<td>INTFLAG</td>
924  *	</tr>
925  *	<tr>
926  *		<td></td>
927  *		<td>READREQ</td>
928  *	</tr>
929  *	<tr>
930  *		<td></td>
931  *		<td>STATUS</td>
932  *	</tr>
933  *	<tr><td colspan="2"/></tr>
934  *	<tr>
935  *		<td>SYSCTRL</td>
936  *		<td>INTFLAG</td>
937  *	</tr>
938  *	<tr><td colspan="2"/></tr>
939  *	<tr>
940  *		<td>SERCOM</td>
941  *		<td>INTFALG</td>
942  *	</tr>
943  *	<tr>
944  *		<td></td>
945  *		<td>STATUS</td>
946  *	</tr>
947  *	<tr>
948  *		<td></td>
949  *		<td>DATA</td>
950  *	</tr>
951  *	<tr><td colspan="2"/></tr>
952  *	<tr>
953  *		<td>TC</td>
954  *		<td>INTFLAG</td>
955  *	</tr>
956  *	<tr>
957  *		<td></td>
958  *		<td>STATUS</td>
959  *	</tr>
960  *	<tr><td colspan="2"/></tr>
961  *	<tr>
962  *		<td>WDT</td>
963  *		<td>INTFLAG</td>
964  *	</tr>
965  *	<tr>
966  *		<td></td>
967  *		<td>STATUS</td>
968  *	</tr>
969  *	<tr>
970  *		<td></td>
971  *		<td>(CLEAR)</td>
972  *	</tr>
973  * </table>
974  *
975  * \page asfdoc_sam0_pac_document_revision_history Document Revision History
976  *
977  * <table>
978  *	<tr>
979  *		<th>Doc. Rev.</td>
980  *		<th>Date</td>
981  *		<th>Comments</td>
982  *	</tr>
983  *	<tr>
984  *		<td>42107F</td>
985  *		<td>12/2015</td>
986  *		<td>Added support for SAM L21/L22, SAM C20/C21, SAM D09, and SAM DA1</td>
987  *	</tr>
988  *	<tr>
989  *		<td>42107E</td>
990  *		<td>12/2014</td>
991  *		<td>Added support for SAM R21 and SAM D10/D11</td>
992  *	</tr>
993  *	<tr>
994  *		<td>42107D</td>
995  *		<td>01/2014</td>
996  *		<td>Added support for SAM D21</td>
997  *	</tr>
998  *	<tr>
999  *		<td>42107C</td>
1000  *		<td>10/2013</td>
1001  *		<td>Extended acronyms list</td>
1002  *	</tr>
1003  *	<tr>
1004  *		<td>42107B</td>
1005  *		<td>06/2013</td>
1006  *		<td>Corrected documentation typos</td>
1007  *	</tr>
1008  *	<tr>
1009  *		<td>42107A</td>
1010  *		<td>06/2013</td>
1011  *		<td>Initial document release</td>
1012  *	</tr>
1013  * </table>
1014  */
1015 
1016 #endif /* PAC_H_INCLUDED */
1017 
1018