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