1 /**
2 * \file
3 *
4 * \brief SAM Peripheral Access Controller Driver
5 *
6 * Copyright (C) 2014-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
47 #include "pac.h"
48
49 /**
50 * \brief Lock a given peripheral's control registers.
51 *
52 * Locks a given peripheral's control registers, to deny write access to the
53 * peripheral to prevent accidental changes to the module's configuration.
54 *
55 * \warning Locking an already locked peripheral will cause a CPU
56 * exception, and terminate program execution.
57 *
58 * \param[in] peripheral_id ID for the peripheral to be locked, sourced via the
59 * \ref SYSTEM_PERIPHERAL_ID macro
60 * \param[in] key Bitwise inverse of peripheral ID, used as key to
61 * reduce the chance of accidental locking. See
62 * \ref asfdoc_sam0_pac_bitwise_code
63 *
64 * \return Status of the peripheral lock procedure.
65 * \retval STATUS_OK If the peripheral was successfully locked
66 * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were supplied
67 */
system_peripheral_lock(const uint32_t peripheral_id,const uint32_t key)68 __no_inline enum status_code system_peripheral_lock(
69 const uint32_t peripheral_id,
70 const uint32_t key)
71 {
72 /* Check if key is correct. */
73 if (~peripheral_id != key) {
74 Assert(false);
75 return STATUS_ERR_INVALID_ARG;
76 }
77
78 PAC->WRCTRL.reg = peripheral_id | PAC_WRCTRL_KEY(PAC_WRCTRL_KEY_SET_Val);
79
80 return STATUS_OK;
81 }
82
83 /**
84 * \brief Lock a given peripheral's control registers until hardware reset.
85 *
86 * Locks a given peripheral's control registers, to deny write access to the
87 * peripheral to prevent accidental changes to the module's configuration.
88 * After lock, the only way to unlock is hardware reset.
89 *
90 * \warning Locking an already locked peripheral will cause a CPU
91 * exception, and terminate program execution.
92 *
93 * \param[in] peripheral_id ID for the peripheral to be locked, sourced via the
94 * \ref SYSTEM_PERIPHERAL_ID macro
95 * \param[in] key Bitwise inverse of peripheral ID, used as key to
96 * reduce the chance of accidental locking. See
97 * \ref asfdoc_sam0_pac_bitwise_code
98 *
99 * \return Status of the peripheral lock procedure.
100 * \retval STATUS_OK If the peripheral was successfully locked
101 * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were supplied
102 */
system_peripheral_lock_always(const uint32_t peripheral_id,const uint32_t key)103 __no_inline enum status_code system_peripheral_lock_always(
104 const uint32_t peripheral_id,
105 const uint32_t key)
106 {
107 /* Check if key is correct. */
108 if (~peripheral_id != key) {
109 Assert(false);
110 return STATUS_ERR_INVALID_ARG;
111 }
112
113 PAC->WRCTRL.reg = peripheral_id | PAC_WRCTRL_KEY(PAC_WRCTRL_KEY_SETLCK_Val);
114
115 return STATUS_OK;
116 }
117
118 /**
119 * \brief Unlock a given peripheral's control registers.
120 *
121 * Unlocks a given peripheral's control registers, allowing write access to the
122 * peripheral so that changes can be made to the module's configuration.
123 *
124 * \warning Unlocking an already locked peripheral will cause a CUP
125 * exception, and terminate program execution.
126 *
127 * \param[in] peripheral_id ID for the peripheral to be unlocked, sourced via the
128 * \ref SYSTEM_PERIPHERAL_ID macro
129 * \param[in] key Bitwise inverse of peripheral ID, used as key to
130 * reduce the chance of accidental unlocking. See
131 * \ref asfdoc_sam0_pac_bitwise_code
132 *
133 * \return Status of the peripheral unlock procedure.
134 * \retval STATUS_OK If the peripheral was successfully locked
135 * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were supplied
136 */
system_peripheral_unlock(const uint32_t peripheral_id,const uint32_t key)137 __no_inline enum status_code system_peripheral_unlock(
138 const uint32_t peripheral_id,
139 const uint32_t key)
140 {
141 /* Check if key is correct. */
142 if (~peripheral_id != key) {
143 Assert(false);
144 return STATUS_ERR_INVALID_ARG;
145 }
146
147 PAC->WRCTRL.reg = peripheral_id | PAC_WRCTRL_KEY(PAC_WRCTRL_KEY_CLR_Val);
148
149 return STATUS_OK;
150 }
151