1 /**
2 * \file
3 *
4 * \brief SAM RTC Driver (Tamper)
5 *
6 * Copyright (C) 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 #ifndef RTC_TAMPER_H_INCLUDED
48 #define RTC_TAMPER_H_INCLUDED
49
50 /**
51 *
52 * \section asfdoc_sam0_rtc_tamper_detect RTC Tamper Detect
53 * The RTC provides several selectable polarity external inputs (INn) that can be
54 * used for tamper detection. When detect, tamper inputs support the four actions:
55 * - Off
56 * - Wake
57 * - Capture
58 * - Active layer protection
59 *
60 * \note The Active Layer Protection is a means of detecting broken traces on the
61 * PCB provided by RTC. In this mode an RTC output signal is routed over critical
62 * components on the board and fed back to one of the RTC inputs. The input and
63 * output signals are compared and a tamper condition is detected when they do not match.
64 *
65 *
66 * Separate debouncers are embedded for each external input. The detection time
67 * depends on whether the debouncer operates synchronously or asynchronously,
68 * and whether majority detection is enabled or not. For details, refer to the section
69 * "Tamper Detection" of datasheet.
70 * \if RTC_COUNT_CALLBACK_MODE
71 * \addtogroup asfdoc_sam0_rtc_count_group
72 * \else
73 * \if RTC_CALENDAR_CALLBACK_MODE
74 * \addtogroup asfdoc_sam0_rtc_calendar_group
75 * \endif
76 * \endif
77 * @{
78 */
79
80 #if defined(FEATURE_RTC_TAMPER_DETECTION) || defined(__DOXYGEN__)
81
82 /** RTC tamper ID0 detection bitmask. */
83 #define RTC_TAMPER_DETECT_ID0 (1UL << 0)
84 /** RTC tamper ID1 detection bitmask. */
85 #define RTC_TAMPER_DETECT_ID1 (1UL << 1)
86 /** RTC tamper ID2 detection bitmask. */
87 #define RTC_TAMPER_DETECT_ID2 (1UL << 2)
88 /** RTC tamper ID3 detection bitmask. */
89 #define RTC_TAMPER_DETECT_ID3 (1UL << 3)
90 /** RTC tamper ID4 detection bitmask. */
91 #define RTC_TAMPER_DETECT_ID4 (1UL << 4)
92 /** RTC tamper input event detection bitmask. */
93 #define RTC_TAMPER_DETECT_EVT (1UL << 5)
94
95
96
97 /**
98 * \brief RTC tamper active layer frequency divider.
99 *
100 * The available prescaler factor for the RTC clock output used during active
101 * layer protection.
102 */
103 enum rtc_tamper_active_layer_freq_divider {
104 /** RTC active layer frequency is prescaled by a factor of 2 */
105 RTC_TAMPER_ACTIVE_LAYER_FREQ_DIV_2 = RTC_MODE0_CTRLB_ACTF_DIV2,
106 /** RTC active layer frequency is prescaled by a factor of 4 */
107 RTC_TAMPER_ACTIVE_LAYER_FREQ_DIV_4 = RTC_MODE0_CTRLB_ACTF_DIV4,
108 /** RTC active layer frequency is prescaled by a factor of 8 */
109 RTC_TAMPER_ACTIVE_LAYER_FREQ_DIV_8 = RTC_MODE0_CTRLB_ACTF_DIV8,
110 /** RTC active layer frequency is prescaled by a factor of 16 */
111 RTC_TAMPER_ACTIVE_LAYER_FREQ_DIV_16 = RTC_MODE0_CTRLB_ACTF_DIV16,
112 /** RTC active layer frequency is prescaled by a factor of 32 */
113 RTC_TAMPER_ACTIVE_LAYER_FREQ_DIV_32 = RTC_MODE0_CTRLB_ACTF_DIV32,
114 /** RTC active layer frequency is prescaled by a factor of 64 */
115 RTC_TAMPER_ACTIVE_LAYER_FREQ_DIV_64 = RTC_MODE0_CTRLB_ACTF_DIV64,
116 /** RTC active layer frequency is prescaled by a factor of 128 */
117 RTC_TAMPER_ACTIVE_LAYER_FREQ_DIV_128 = RTC_MODE0_CTRLB_ACTF_DIV128,
118 /** RTC active layer frequency is prescaled by a factor of 256 */
119 RTC_TAMPER_ACTIVE_LAYER_FREQ_DIV_256 = RTC_MODE0_CTRLB_ACTF_DIV256,
120 };
121
122 /**
123 * \brief RTC tamper debounce frequency divider.
124 *
125 * The available prescaler factor for the input debouncers.
126 */
127 enum rtc_tamper_debounce_freq_divider {
128 /** RTC debounce frequency is prescaled by a factor of 2 */
129 RTC_TAMPER_DEBOUNCE_FREQ_DIV_2 = RTC_MODE0_CTRLB_DEBF_DIV2,
130 /** RTC debounce frequency is prescaled by a factor of 4 */
131 RTC_TAMPER_DEBOUNCE_FREQ_DIV_4 = RTC_MODE0_CTRLB_DEBF_DIV4,
132 /** RTC debounce frequency is prescaled by a factor of 8 */
133 RTC_TAMPER_DEBOUNCE_FREQ_DIV_8 = RTC_MODE0_CTRLB_DEBF_DIV8,
134 /** RTC debounce frequency is prescaled by a factor of 16 */
135 RTC_TAMPER_DEBOUNCE_FREQ_DIV_16 = RTC_MODE0_CTRLB_DEBF_DIV16,
136 /** RTC debounce frequency is prescaled by a factor of 32 */
137 RTC_TAMPER_DEBOUNCE_FREQ_DIV_32 = RTC_MODE0_CTRLB_DEBF_DIV32,
138 /** RTC debounce frequency is prescaled by a factor of 64 */
139 RTC_TAMPER_DEBOUNCE_FREQ_DIV_64 = RTC_MODE0_CTRLB_DEBF_DIV64,
140 /** RTC debounce frequency is prescaled by a factor of 128 */
141 RTC_TAMPER_DEBOUNCE_FREQ_DIV_128 = RTC_MODE0_CTRLB_DEBF_DIV128,
142 /** RTC debounce frequency is prescaled by a factor of 256 */
143 RTC_TAMPER_DEBOUNCE_FREQ_DIV_256 = RTC_MODE0_CTRLB_DEBF_DIV256,
144 };
145
146 /**
147 * \brief RTC tamper input action.
148 *
149 * The available action taken by the tamper input.
150 */
151 enum rtc_tamper_input_action {
152 /** RTC tamper input action is disabled */
153 RTC_TAMPER_INPUT_ACTION_OFF = RTC_TAMPCTRL_IN0ACT_OFF,
154 /** RTC tamper input action is wake and set tamper flag */
155 RTC_TAMPER_INPUT_ACTION_WAKE = RTC_TAMPCTRL_IN0ACT_WAKE,
156 /** RTC tamper input action is capture timestamp and set tamper flag */
157 RTC_TAMPER_INPUT_ACTION_CAPTURE = RTC_TAMPCTRL_IN0ACT_CAPTURE,
158 /** RTC tamper input action is compare IN to OUT, when a mismatch occurs,
159 * capture timestamp and set tamper flag */
160 RTC_TAMPER_INPUT_ACTION_ACTL = RTC_TAMPCTRL_IN0ACT_ACTL,
161 };
162
163 /**
164 * \brief RTC tamper input level select.
165 *
166 * The available edge condition for tamper INn level select.
167 */
168 enum rtc_tamper_level_sel {
169 /** A falling edge condition will be detected on Tamper input */
170 RTC_TAMPER_LEVEL_FALLING = (0),
171 /** A rising edge condition will be detected on Tamper input */
172 RTC_TAMPER_LEVEL_RISING = (1),
173 };
174
175 /**
176 * \brief RTC tamper debounce sequential.
177 *
178 * The available sequential for tamper debounce.
179 */
180 enum rtc_tamper_debounce_seq {
181 /** Tamper input detect edge with synchronous stability debounce */
182 RTC_TAMPER_DEBOUNCE_SYNC,
183 /** Tamper input detect edge with asynchronous stability debounce */
184 RTC_TAMPER_DEBOUNCE_ASYNC,
185 /** Tamper input detect edge with majority debounce */
186 RTC_TAMPER_DEBOUNCE_MAJORITY,
187 };
188
189 /**
190 * \brief RTC tamper input configuration structure.
191 *
192 * The configuration structure for tamper INn.
193 */
194 struct rtc_tamper_input_config {
195 /** Debounce enable */
196 bool debounce_enable;
197 /** Tamper level select */
198 enum rtc_tamper_level_sel level;
199 /** Tamper input action */
200 enum rtc_tamper_input_action action;
201 };
202
203 /**
204 * \brief RTC Tamper configuration structure.
205 *
206 * The configuration structure for the RTC tamper. This structure should
207 * be initialized using the \ref rtc_tamper_get_config_defaults() before any
208 * user configurations are set.
209 */
210 struct rtc_tamper_config {
211 /** Backup register reset on tamper enable */
212 bool bkup_reset_on_tamper;
213 /** GP register reset on tamper enable */
214 bool gp_reset_on_tamper;
215 /** Active layer frequency */
216 enum rtc_tamper_active_layer_freq_divider actl_freq_div;
217 /** Debounce frequency */
218 enum rtc_tamper_debounce_freq_divider deb_freq_div;
219 /** Debounce sequential */
220 enum rtc_tamper_debounce_seq deb_seq;
221 /** DMA on tamper enable */
222 bool dma_tamper_enable;
223 /** General Purpose 0/1 Enable */
224 bool gp0_enable;
225 /** Tamper IN configuration */
226 struct rtc_tamper_input_config in_cfg[RTC_TAMPER_NUM];
227 };
228
229 /**
230 * \name RTC Tamper Detection
231 * @{
232 */
233
234 /**
235 * \brief Gets the RTC tamper default configurations.
236 *
237 * Initializes the configuration structure to default values.
238 *
239 * The default configuration is as follows:
240 * - Disable backup register reset on tamper
241 * - Disable GP register reset on tamper
242 * - Active layer clock divided by a factor of 8
243 * - Debounce clock divided by a factor of 8
244 * - Detect edge on INn with synchronous stability debouncing
245 * - Disable DMA on tamper
246 * - Enable GP register
247 * - Disable debouce, detect on falling edge and no action on INn
248 *
249 * \param[out] config Configuration structure to be initialized to default values.
250 */
rtc_tamper_get_config_defaults(struct rtc_tamper_config * const config)251 static inline void rtc_tamper_get_config_defaults(
252 struct rtc_tamper_config *const config)
253 {
254 /* Sanity check argument */
255 Assert(config);
256
257 config->bkup_reset_on_tamper= false;
258 config->gp_reset_on_tamper = false;
259 config->actl_freq_div = RTC_TAMPER_ACTIVE_LAYER_FREQ_DIV_8;
260 config->deb_freq_div = RTC_TAMPER_DEBOUNCE_FREQ_DIV_8;
261 config->deb_seq = RTC_TAMPER_DEBOUNCE_SYNC;
262 config->dma_tamper_enable = false;
263 config->gp0_enable = true;
264
265 for (uint8_t id = 0; id < RTC_TAMPER_NUM; id++) {
266 config->in_cfg[id].debounce_enable = false;
267 config->in_cfg[id].level = RTC_TAMPER_LEVEL_FALLING;
268 config->in_cfg[id].action = RTC_TAMPER_INPUT_ACTION_OFF;
269 }
270 }
271 enum status_code rtc_tamper_set_config (struct rtc_module *const module,
272 struct rtc_tamper_config *const tamper_cfg);
273
274 /**
275 * \brief Retrieves the RTC tamper detection status.
276 *
277 * Retrieves the detection status of each input pin and the input event.
278 *
279 * \param[in] module Pointer to the RTC software instance struct
280 *
281 * \return Bitmask of detection flags.
282 *
283 * \retval RTC_TAMPER_DETECT_ID0 Tamper condition on IN0 has been detected
284 * \retval RTC_TAMPER_DETECT_ID1 Tamper condition on IN1 has been detected
285 * \retval RTC_TAMPER_DETECT_ID2 Tamper condition on IN2 has been detected
286 * \retval RTC_TAMPER_DETECT_ID3 Tamper condition on IN3 has been detected
287 * \retval RTC_TAMPER_DETECT_ID4 Tamper condition on IN4 has been detected
288 * \retval RTC_TAMPER_DETECT_EVT Tamper input event has been detected
289 */
rtc_tamper_get_detect_flag(struct rtc_module * const module)290 static inline uint32_t rtc_tamper_get_detect_flag (struct rtc_module *const module)
291 {
292 /* Sanity check arguments */
293 Assert(module);
294 Assert(module->hw);
295
296 uint32_t tamper_id = module->hw->MODE0.TAMPID.reg;
297 uint32_t detect_flags = 0;
298
299 if (tamper_id & RTC_TAMPID_TAMPID0) {
300 detect_flags |= RTC_TAMPER_DETECT_ID0;
301 }
302
303 if (tamper_id & RTC_TAMPID_TAMPID1) {
304 detect_flags |= RTC_TAMPER_DETECT_ID1;
305 }
306
307 if (tamper_id & RTC_TAMPID_TAMPID2) {
308 detect_flags |= RTC_TAMPER_DETECT_ID2;
309 }
310
311 if (tamper_id & RTC_TAMPID_TAMPID3) {
312 detect_flags |= RTC_TAMPER_DETECT_ID3;
313 }
314
315 if (tamper_id & RTC_TAMPID_TAMPID4) {
316 detect_flags |= RTC_TAMPER_DETECT_ID4;
317 }
318
319 if (tamper_id & RTC_TAMPID_TAMPEVT) {
320 detect_flags |= RTC_TAMPER_DETECT_EVT;
321 }
322
323 return detect_flags;
324 }
325
326 /**
327 * \brief Clears RTC tamper detection flag.
328 *
329 * Clears the given detection flag of the module.
330 *
331 * \param[in] module Pointer to the TC software instance struct
332 * \param[in] detect_flags Bitmask of detection flags
333 */
rtc_tamper_clear_detect_flag(struct rtc_module * const module,const uint32_t detect_flags)334 static inline void rtc_tamper_clear_detect_flag(
335 struct rtc_module *const module,
336 const uint32_t detect_flags)
337 {
338 /* Sanity check arguments */
339 Assert(module);
340 Assert(module->hw);
341
342 uint32_t tamper_id = 0;
343
344 if (detect_flags & RTC_TAMPER_DETECT_ID0) {
345 tamper_id |= RTC_TAMPID_TAMPID0;
346 }
347
348 if (detect_flags & RTC_TAMPER_DETECT_ID1) {
349 tamper_id |= RTC_TAMPID_TAMPID1;
350 }
351
352 if (detect_flags & RTC_TAMPER_DETECT_ID2) {
353 tamper_id |= RTC_TAMPID_TAMPID2;
354 }
355
356 if (detect_flags & RTC_TAMPER_DETECT_ID3) {
357 tamper_id |= RTC_TAMPID_TAMPID3;
358 }
359
360 if (detect_flags & RTC_TAMPER_DETECT_ID4) {
361 tamper_id |= RTC_TAMPID_TAMPID4;
362 }
363
364 if (detect_flags & RTC_TAMPER_DETECT_EVT) {
365 tamper_id |= RTC_TAMPID_TAMPEVT;
366 }
367
368 module->hw->MODE0.TAMPID.reg = tamper_id;
369
370 }
371
372 /** @} */
373
374 #endif
375 /** @} */
376
377
378 #endif /* RTC_TAMPER_H_INCLUDED */