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 */