1 /***************************************************************************//**
2  * @file
3  * @brief ETAMPDET (External Tamper Detection) peripheral API
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Zlib
10  *
11  * The licensor of this software is Silicon Laboratories Inc.
12  *
13  * This software is provided 'as-is', without any express or implied
14  * warranty. In no event will the authors be held liable for any damages
15  * arising from the use of this software.
16  *
17  * Permission is granted to anyone to use this software for any purpose,
18  * including commercial applications, and to alter it and redistribute it
19  * freely, subject to the following restrictions:
20  *
21  * 1. The origin of this software must not be misrepresented; you must not
22  *    claim that you wrote the original software. If you use this software
23  *    in a product, an acknowledgment in the product documentation would be
24  *    appreciated but is not required.
25  * 2. Altered source versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.
27  * 3. This notice may not be removed or altered from any source distribution.
28  *
29  ******************************************************************************/
30 
31 #ifndef SL_HAL_ETAMPDET_H
32 #define SL_HAL_ETAMPDET_H
33 
34 #include "em_device.h"
35 
36 #if defined(ETAMPDET_PRESENT)
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 #include <stdbool.h>
43 #include "sl_hal_etampdet_compat.h"
44 #include "sl_enum.h"
45 
46 /***************************************************************************//**
47  * @addtogroup etampdet
48  * @{
49  ******************************************************************************/
50 
51 /*******************************************************************************
52  *********************************   ENUM   ************************************
53  ******************************************************************************/
54 
55 /** ETAMPDET channels. */
SL_ENUM(sl_hal_etampdet_channel_t)56 SL_ENUM(sl_hal_etampdet_channel_t) {
57   /** Channel 0. */
58   channel_0 = 0,
59 
60   /** Channel 1. */
61   channel_1,
62 };
63 
64 /** ETAMPDET filter thresholds. */
SL_ENUM(sl_hal_etampdet_channel_cnt_mismatch_threshold_t)65 SL_ENUM(sl_hal_etampdet_channel_cnt_mismatch_threshold_t) {
66   /** Raise detect flag after seeing 1 event before reset counter expire. */
67   detect_filt_threshold_1 = _ETAMPDET_CNTMISMATCHMAX_CHNLCNTMISMATCHMAX0_DetectFilterThreshold1,
68 
69   /** Raise detect flag after seeing 2 events before reset counter expire. */
70   detect_filt_threshold_2 = _ETAMPDET_CNTMISMATCHMAX_CHNLCNTMISMATCHMAX0_DetectFilterThreshold2,
71 
72   /** Raise detect flag after seeing 3 events before reset counter expire. */
73   detect_filt_threshold_3 = _ETAMPDET_CNTMISMATCHMAX_CHNLCNTMISMATCHMAX0_DetectFilterThreshold3,
74 
75   /** Raise detect flag after seeing 4 events before reset counter expire. */
76   detect_filt_threshold_4 = _ETAMPDET_CNTMISMATCHMAX_CHNLCNTMISMATCHMAX0_DetectFilterThreshold4,
77 
78   /** Raise detect flag after seeing 5 events before reset counter expire. */
79   detect_filt_threshold_5 = _ETAMPDET_CNTMISMATCHMAX_CHNLCNTMISMATCHMAX0_DetectFilterThreshold5,
80 
81   /** Raise detect flag after seeing 6 events before reset counter expire. */
82   detect_filt_threshold_6 = _ETAMPDET_CNTMISMATCHMAX_CHNLCNTMISMATCHMAX0_DetectFilterThreshold6,
83 
84   /** Raise detect flag after seeing 7 events before reset counter expire. */
85   detect_filt_threshold_7 = _ETAMPDET_CNTMISMATCHMAX_CHNLCNTMISMATCHMAX0_DetectFilterThreshold7,
86 
87   /** Raise detect flag after seeing 8 events before reset counter expire. */
88   detect_filt_threshold_8 = _ETAMPDET_CNTMISMATCHMAX_CHNLCNTMISMATCHMAX0_DetectFilterThreshold8,
89 };
90 
91 /** ETAMPDET filter moving window size. */
SL_ENUM(sl_hal_etampdet_channel_filt_win_size_t)92 SL_ENUM(sl_hal_etampdet_channel_filt_win_size_t) {
93   /** Detect filter moving window size 2. */
94   detect_filt_win_size_2 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize2,
95 
96   /** Detect filter moving window size 3. */
97   detect_filt_win_size_3 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize3,
98 
99   /** Detect filter moving window size 4. */
100   detect_filt_win_size_4 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize4,
101 
102   /** Detect filter moving window size 5. */
103   detect_filt_win_size_5 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize5,
104 
105   /** Detect filter moving window size 6. */
106   detect_filt_win_size_6 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize6,
107 
108   /** Detect filter moving window size 7. */
109   detect_filt_win_size_7 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize7,
110 
111   /** Detect filter moving window size 8. */
112   detect_filt_win_size_8 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize8,
113 
114   /** Detect filter moving window size 9. */
115   detect_filt_win_size_9 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize9,
116 
117   /** Detect filter moving window size 10. */
118   detect_filt_win_size_10 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize10,
119 
120   /** Detect filter moving window size 11. */
121   detect_filt_win_size_11 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize11,
122 
123   /** Detect filter moving window size 12. */
124   detect_filt_win_size_12 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize12,
125 
126   /** Detect filter moving window size 13. */
127   detect_filt_win_size_13 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize13,
128 
129   /** Detect filter moving window size 14. */
130   detect_filt_win_size_14 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize14,
131 
132   /** Detect filter moving window size 15. */
133   detect_filt_win_size_15 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize15,
134 
135   /** Detect filter moving window size 16. */
136   detect_filt_win_size_16 = _ETAMPDET_CHNLFILTWINSIZE_CHNLFILTWINSIZE0_DetectFilterMovingWinSize16,
137 };
138 
139 /** ETAMPDET upper part of divider ripple counter. */
SL_ENUM(sl_hal_etampdet_upper_clk_presc_t)140 SL_ENUM(sl_hal_etampdet_upper_clk_presc_t) {
141   /** Ripple counter divider bypassed. */
142   upper_clk_prescaler_bypass = _ETAMPDET_CLKPRESCVAL_UPPERPRESC_Bypass,
143 
144   /** Divide by 2. */
145   upper_clk_prescaler_divide_2 = _ETAMPDET_CLKPRESCVAL_UPPERPRESC_DivideBy2,
146 
147   /** Divide by 4. */
148   upper_clk_prescaler_divide_4 = _ETAMPDET_CLKPRESCVAL_UPPERPRESC_DivideBy4,
149 
150   /** Divide by 8. */
151   upper_clk_prescaler_divide_8 = _ETAMPDET_CLKPRESCVAL_UPPERPRESC_DivideBy8,
152 
153   /** Divide by 16. */
154   upper_clk_prescaler_divide_16 = _ETAMPDET_CLKPRESCVAL_UPPERPRESC_DivideBy16,
155 
156   /** Divide by 32. */
157   upper_clk_prescaler_divide_32 = _ETAMPDET_CLKPRESCVAL_UPPERPRESC_DivideBy32,
158 
159   /** Divide by 64. */
160   upper_clk_prescaler_divide_64 = _ETAMPDET_CLKPRESCVAL_UPPERPRESC_DivideBy64,
161 };
162 
163 /** ETAMPDET lower part of divider binary counter. */
SL_ENUM(sl_hal_etampdet_lower_clk_presc_t)164 SL_ENUM(sl_hal_etampdet_lower_clk_presc_t) {
165   /** Divider is bypassed. */
166   lower_clk_prescaler_bypass = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_Bypass,
167 
168   /** Divide by 2. */
169   lower_clk_prescaler_divide_2 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy2,
170 
171   /** Divide by 3. */
172   lower_clk_prescaler_divide_3 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy3,
173 
174   /** Divide by 4. */
175   lower_clk_prescaler_divide_4 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy4,
176 
177   /** Divide by 5. */
178   lower_clk_prescaler_divide_5 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy5,
179 
180   /** Divide by 6. */
181   lower_clk_prescaler_divide_6 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy6,
182 
183   /** Divide by 7. */
184   lower_clk_prescaler_divide_7 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy7,
185 
186   /** Divide by 8. */
187   lower_clk_prescaler_divide_8 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy8,
188 
189   /** Divide by 9. */
190   lower_clk_prescaler_divide_9 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy9,
191 
192   /** Divide by 10. */
193   lower_clk_prescaler_divide_10 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy10,
194 
195   /** Divide by 11. */
196   lower_clk_prescaler_divide_11 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy11,
197 
198   /** Divide by 12. */
199   lower_clk_prescaler_divide_12 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy12,
200 
201   /** Divide by 13. */
202   lower_clk_prescaler_divide_13 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy13,
203 
204   /** Divide by 14. */
205   lower_clk_prescaler_divide_14 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy14,
206 
207   /** Divide by 15. */
208   lower_clk_prescaler_divide_15 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy15,
209 
210   /** Divide by 16. */
211   lower_clk_prescaler_divide_16 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy16,
212 
213   /** Divide by 17. */
214   lower_clk_prescaler_divide_17 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy17,
215 
216   /** Divide by 18. */
217   lower_clk_prescaler_divide_18 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy18,
218 
219   /** Divide by 19. */
220   lower_clk_prescaler_divide_19 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy19,
221 
222   /** Divide by 20. */
223   lower_clk_prescaler_divide_20 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy20,
224 
225   /** Divide by 21. */
226   lower_clk_prescaler_divide_21 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy21,
227 
228   /** Divide by 22. */
229   lower_clk_prescaler_divide_22 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy22,
230 
231   /** Divide by 23. */
232   lower_clk_prescaler_divide_23 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy23,
233 
234   /** Divide by 24. */
235   lower_clk_prescaler_divide_24 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy24,
236 
237   /** Divide by 25. */
238   lower_clk_prescaler_divide_25 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy25,
239 
240   /** Divide by 26. */
241   lower_clk_prescaler_divide_26 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy26,
242 
243   /** Divide by 27. */
244   lower_clk_prescaler_divide_27 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy27,
245 
246   /** Divide by 28. */
247   lower_clk_prescaler_divide_28 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy28,
248 
249   /** Divide by 29. */
250   lower_clk_prescaler_divide_29 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy29,
251 
252   /** Divide by 30. */
253   lower_clk_prescaler_divide_30 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy30,
254 
255   /** Divide by 31. */
256   lower_clk_prescaler_divide_31 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy31,
257 
258   /** Divide by 32. */
259   lower_clk_prescaler_divide_32 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy32,
260 
261   /** Divide by 33. */
262   lower_clk_prescaler_divide_33 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy33,
263 
264   /** Divide by 34. */
265   lower_clk_prescaler_divide_34 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy34,
266 
267   /** Divide by 35. */
268   lower_clk_prescaler_divide_35 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy35,
269 
270   /** Divide by 36. */
271   lower_clk_prescaler_divide_36 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy36,
272 
273   /** Divide by 37. */
274   lower_clk_prescaler_divide_37 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy37,
275 
276   /** Divide by 38. */
277   lower_clk_prescaler_divide_38 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy38,
278 
279   /** Divide by 39. */
280   lower_clk_prescaler_divide_39 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy39,
281 
282   /** Divide by 40. */
283   lower_clk_prescaler_divide_40 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy40,
284 
285   /** Divide by 41. */
286   lower_clk_prescaler_divide_41 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy41,
287 
288   /** Divide by 42. */
289   lower_clk_prescaler_divide_42 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy42,
290 
291   /** Divide by 43. */
292   lower_clk_prescaler_divide_43 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy43,
293 
294   /** Divide by 44. */
295   lower_clk_prescaler_divide_44 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy44,
296 
297   /** Divide by 45. */
298   lower_clk_prescaler_divide_45 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy45,
299 
300   /** Divide by 46. */
301   lower_clk_prescaler_divide_46 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy46,
302 
303   /** Divide by 47. */
304   lower_clk_prescaler_divide_47 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy47,
305 
306   /** Divide by 48. */
307   lower_clk_prescaler_divide_48 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy48,
308 
309   /** Divide by 49. */
310   lower_clk_prescaler_divide_49 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy49,
311 
312   /** Divide by 50. */
313   lower_clk_prescaler_divide_50 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy50,
314 
315   /** Divide by 51. */
316   lower_clk_prescaler_divide_51 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy51,
317 
318   /** Divide by 52. */
319   lower_clk_prescaler_divide_52 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy52,
320 
321   /** Divide by 53. */
322   lower_clk_prescaler_divide_53 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy53,
323 
324   /** Divide by 54. */
325   lower_clk_prescaler_divide_54 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy54,
326 
327   /** Divide by 55. */
328   lower_clk_prescaler_divide_55 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy55,
329 
330   /** Divide by 56. */
331   lower_clk_prescaler_divide_56 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy56,
332 
333   /** Divide by 57. */
334   lower_clk_prescaler_divide_57 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy57,
335 
336   /** Divide by 58. */
337   lower_clk_prescaler_divide_58 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy58,
338 
339   /** Divide by 59. */
340   lower_clk_prescaler_divide_59 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy59,
341 
342   /** Divide by 60. */
343   lower_clk_prescaler_divide_60 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy60,
344 
345   /** Divide by 61. */
346   lower_clk_prescaler_divide_61 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy61,
347 
348   /** Divide by 62. */
349   lower_clk_prescaler_divide_62 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy62,
350 
351   /** Divide by 63. */
352   lower_clk_prescaler_divide_63 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy63,
353 
354   /** Divide by 64. */
355   lower_clk_prescaler_divide_64 = _ETAMPDET_CLKPRESCVAL_LOWERPRESC_DivideBy64,
356 };
357 
358 /*******************************************************************************
359  *******************************   STRUCTS   ***********************************
360  ******************************************************************************/
361 
362 /** ETAMPDET channel configuration structure. */
363 typedef struct {
364   /** Seed value to load into channel LFSR. */
365   uint32_t channel_seed_val;
366 
367   /** Channel id */
368   sl_hal_etampdet_channel_t channel;
369 
370   /** Channel Filter moving window size. */
371   sl_hal_etampdet_channel_filt_win_size_t channel_filt_win_size;
372 
373   /** Channel filter threshold value where a tamper detect will be triggered. */
374   sl_hal_etampdet_channel_cnt_mismatch_threshold_t channel_cnt_mismatch;
375 
376   /** Enable channel driving pad. */
377   bool channel_pad_en;
378 
379   /** Enable channel tamper detect filtering feature. */
380   bool channel_tampdet_filt_en;
381 
382   /** Enable 1 clock delay to the TX value used for comparison. This is to
383    * support trace propagation delay more than 1 clock cycle. */
384   bool channel_cmp_dly_en;
385 
386   /** Set to enable EM4 wakeup when channel tamper detect is set. */
387   bool em4_wakeup_en;
388 } sl_hal_etampdet_config_channel_t;
389 
390 /** ETAMPDET configuration structure. */
391 typedef struct {
392   /** Upper clock prescaler value. */
393   sl_hal_etampdet_upper_clk_presc_t upper_clk_presc_val;
394 
395   /** Lower clock prescaler value. */
396   sl_hal_etampdet_lower_clk_presc_t lower_clk_presc_val;
397 } sl_hal_etampdet_config_t;
398 
399 /** ETAMPDET default channel configuration. */
400 #define ETAMPDET_CONFIG_CHANNEL_DEFAULT                                            \
401   {                                                                                \
402     0x13579BDF,                                 /* Set default seed value. */      \
403     channel_0,                                  /* Choose channel 0.*/             \
404     detect_filt_win_size_2,                     /* Set default filter win size. */ \
405     detect_filt_threshold_1,                    /* Set Detect filter threshold. */ \
406     false,                                      /* Enable channel driving pad. */  \
407     false,                                      /* Disable channel filtering. */   \
408     false,                                      /* Disable 1 clock delay. */       \
409     false,                                      /* Enable EM4 wakeup. */           \
410   }                                                                                \
411 
412 /** ETAMPDET default configuration. */
413 #define ETAMPDET_CONFIG_DEFAULT                               \
414   {                                                           \
415     upper_clk_prescaler_bypass, /* Bypass upper prescaler. */ \
416     lower_clk_prescaler_bypass, /* Bypass lower prescaler.*/  \
417   }                                                           \
418 
419 /*******************************************************************************
420  *****************************   PROTOTYPES   **********************************
421  ******************************************************************************/
422 
423 /***************************************************************************//**
424  * Initialize ETAMPDET.
425  *
426  * @param[in] config  The pointer to the initialization structure.
427  *
428  * @note User should call @ref sl_hal_etampdet_init_channel() for full initialization.
429  *       This function should be called before @ref sl_hal_etampdet_init_channel()
430  *
431  * @note The control registers setting of the GPIOs to be used by ETAMPDET
432  *       should be at the default values to ensure that other clients
433  *       are not accidentally driving the GPIOs that ETAMPDET is using.
434  ******************************************************************************/
435 void sl_hal_etampdet_init(const sl_hal_etampdet_config_t *config);
436 
437 /***************************************************************************//**
438  * Initialize ETAMPDET channel.
439  *
440  * @param[in] config_channel  The pointer to the  channel initialization structure.
441  *
442  * @note User should call @ref sl_hal_etampdet_init() for full initialization.
443  ******************************************************************************/
444 void sl_hal_etampdet_init_channel(const sl_hal_etampdet_config_channel_t *config_channel);
445 
446 /***************************************************************************//**
447  * Wait for the ETAMPDET to complete all synchronization of register changes
448  * and commands.
449  ******************************************************************************/
sl_hal_etampdet_wait_sync(void)450 __STATIC_INLINE void sl_hal_etampdet_wait_sync(void)
451 {
452   while (ETAMPDET->SYNCBUSY != 0U) {
453     // Wait for all synchronizations to finish
454   }
455 }
456 
457 /***************************************************************************//**
458  * Wait for the ETAMPDET to complete disabling procedure.
459  ******************************************************************************/
sl_hal_etampdet_wait_ready(void)460 __STATIC_INLINE void sl_hal_etampdet_wait_ready(void)
461 {
462 #if defined(ETAMPDET_EN_DISABLING)
463   while ((ETAMPDET->EN & ETAMPDET_EN_DISABLING) || (ETAMPDET->SYNCBUSY != 0U)) {
464     // Wait for disabling to finish
465   }
466 #else
467   while (ETAMPDET->SYNCBUSY != 0U) {
468     // Wait for all synchronizations to finish
469   }
470 #endif
471 }
472 
473 /***************************************************************************//**
474  * Enable ETAMPDET.
475  ******************************************************************************/
sl_hal_etampdet_enable(void)476 __STATIC_INLINE void sl_hal_etampdet_enable(void)
477 {
478   // Wait for synchronization to complete if necessary
479   sl_hal_etampdet_wait_sync();
480 
481   // Enable ETAMPDET
482   ETAMPDET->EN_SET = ETAMPDET_EN_EN;
483 }
484 
485 /***************************************************************************//**
486  * Disable ETAMPDET.
487  ******************************************************************************/
sl_hal_etampdet_disable(void)488 __STATIC_INLINE void sl_hal_etampdet_disable(void)
489 {
490   if (ETAMPDET->EN != ETAMPDET_EN_EN) {
491     return;
492   }
493 
494   // Disable ETAMPDET
495   ETAMPDET->EN_CLR = ETAMPDET_EN_EN;
496 }
497 
498 /***************************************************************************//**
499  * Load seed value into channel LFSR.
500  *
501  * @param[in] channel  The channel number.
502  ******************************************************************************/
sl_hal_etampdet_load(sl_hal_etampdet_channel_t channel)503 __STATIC_INLINE void sl_hal_etampdet_load(sl_hal_etampdet_channel_t channel)
504 {
505   // Wait for synchronization to complete if necessary
506   sl_hal_etampdet_wait_sync();
507 
508   ETAMPDET->CMD |= ETAMPDET_CMD_CHNLLOAD0 << (channel * _ETAMPDET_CMD_CHNLSTART1_SHIFT);
509 }
510 
511 /***************************************************************************//**
512  * Start ETAMPDET channel.
513  *
514  * @param[in] channel  The channel number.
515  ******************************************************************************/
sl_hal_etampdet_start(sl_hal_etampdet_channel_t channel)516 __STATIC_INLINE void sl_hal_etampdet_start(sl_hal_etampdet_channel_t channel)
517 {
518   // Wait for synchronization to complete if necessary
519   sl_hal_etampdet_wait_sync();
520 
521   ETAMPDET->CMD |= ETAMPDET_CMD_CHNLSTART0 << (channel * _ETAMPDET_CMD_CHNLSTART1_SHIFT);
522 }
523 
524 /***************************************************************************//**
525  * Stop ETAMPDET channel.
526  *
527  * @param[in] channel  The channel number.
528  ******************************************************************************/
sl_hal_etampdet_stop(sl_hal_etampdet_channel_t channel)529 __STATIC_INLINE void sl_hal_etampdet_stop(sl_hal_etampdet_channel_t channel)
530 {
531   // Wait for synchronization to complete if necessary
532   sl_hal_etampdet_wait_sync();
533 
534   ETAMPDET->CMD |= ETAMPDET_CMD_CHNLSTOP0 << (channel * _ETAMPDET_CMD_CHNLSTART1_SHIFT);
535 }
536 
537 /***************************************************************************//**
538  * Enable ETAMPDET interrupts.
539  *
540  * @param[in] interrupts  The interrupts flags to enable.
541  ******************************************************************************/
sl_hal_etampdet_enable_interrupts(uint32_t interrupts)542 __STATIC_INLINE void sl_hal_etampdet_enable_interrupts(uint32_t interrupts)
543 {
544   ETAMPDET->IEN_SET = interrupts;
545 }
546 
547 /***************************************************************************//**
548  * Disable ETAMPDET interrupts.
549  *
550  * @param[in] interrupts  The interrupts flags to disable.
551  ******************************************************************************/
sl_hal_etampdet_disable_interrupts(uint32_t interrupts)552 __STATIC_INLINE void sl_hal_etampdet_disable_interrupts(uint32_t interrupts)
553 {
554   ETAMPDET->IEN_CLR = interrupts;
555 }
556 
557 /***************************************************************************//**
558  * Set ETAMPDET interrupts.
559  *
560  * @param[in] interrupts  The interrupts flags to set.
561  ******************************************************************************/
sl_hal_etampdet_set_interrupts(uint32_t interrupts)562 __STATIC_INLINE void sl_hal_etampdet_set_interrupts(uint32_t interrupts)
563 {
564   ETAMPDET->IF_SET = interrupts;
565 }
566 
567 /***************************************************************************//**
568  * Clear ETAMPDET interrupts.
569  *
570  * @param[in] interrupts  The interrupts flags to clear.
571  ******************************************************************************/
sl_hal_etampdet_clear_interrupts(uint32_t interrupts)572 __STATIC_INLINE void sl_hal_etampdet_clear_interrupts(uint32_t interrupts)
573 {
574   ETAMPDET->IF_CLR = interrupts;
575 }
576 
577 /***************************************************************************//**
578  * Gets pending ETAMPDET interrupt flags.
579  *
580  * @note  Event bits are not cleared by using this function.
581  *
582  * @return  Pending ETAMPDET interrupt sources.
583  *          Returns a set of interrupt flags OR-ed together for multiple
584  *          interrupt sources.
585  ******************************************************************************/
sl_hal_etampdet_get_interrupts(void)586 __STATIC_INLINE uint32_t sl_hal_etampdet_get_interrupts(void)
587 {
588   return ETAMPDET->IF;
589 }
590 
591 /***************************************************************************//**
592  * Gets enabled and pending ETAMPDET interrupt flags.
593  * Useful for handling more interrupt sources in the same interrupt handler.
594  *
595  * @note  Interrupt flags are not cleared by using this function.
596  *
597  * @return  Pending and enabled ETAMPDET interrupt sources.
598  *          The return value is the bitwise AND of
599  *          - the enabled interrupt sources in ETAMPDET_IEN and
600  *          - the pending interrupt flags ETAMPDET_IF.
601  ******************************************************************************/
sl_hal_etampdet_get_enabled_interrupts(void)602 __STATIC_INLINE uint32_t sl_hal_etampdet_get_enabled_interrupts(void)
603 {
604   uint32_t ien = 0;
605   ien = ETAMPDET->IEN;
606   return ETAMPDET->IF & ien;
607 }
608 
609 /***************************************************************************//**
610  * Lock ETAMPDET registers.
611  *
612  * @note  When ETAMPDET registers are locked, ETAMPDET_EN, ETAMPDET_CFG, ETAMPDET_CMD,
613  *        ETAMPDET_CHNLSEEDVALx, ETAMPDET_CNTMISMATCHMAX, ETAMPDET_CHNLFILTWINSIZE,
614  *        ETAMPDET_EM4WUEN and ETAMPDET_CLKPRESCVAL registers cannot be written to.
615  ******************************************************************************/
sl_hal_etampdet_lock(void)616 __STATIC_INLINE void sl_hal_etampdet_lock(void)
617 {
618   ETAMPDET->LOCK = ~ETAMPDET_LOCK_LOCKKEY_UNLOCK;
619 }
620 
621 /***************************************************************************//**
622  * Unlock ETAMPDET registers.
623  *
624  * @note  When ETAMPDET registers are unlocked, registers are writable.
625  ******************************************************************************/
sl_hal_etampdet_unlock(void)626 __STATIC_INLINE void sl_hal_etampdet_unlock(void)
627 {
628   ETAMPDET->LOCK = ETAMPDET_LOCK_LOCKKEY_UNLOCK;
629 }
630 
631 /***************************************************************************//**
632  * Gets ETAMPDET STATUS register value.
633  *
634  * @return  Current STATUS register value.
635  ******************************************************************************/
sl_hal_etampdet_get_status(void)636 __STATIC_INLINE uint32_t sl_hal_etampdet_get_status(void)
637 {
638   return ETAMPDET->STATUS;
639 }
640 
641 /***************************************************************************//**
642  * Set ETAMPDET channel seed value.
643  *
644  * @param[in] channel  The channel to set seed value.
645  *
646  * @param[in] seed_value  The seed value to set into LFSR of the channel.
647  *
648  * @note  It is recommended to get the random seed value using TRNG (True random
649  *        Number Generator) peripheral.
650  ******************************************************************************/
sl_hal_etampdet_set_seed_value(uint32_t seed_value,sl_hal_etampdet_channel_t channel)651 __STATIC_INLINE void sl_hal_etampdet_set_seed_value(uint32_t seed_value, sl_hal_etampdet_channel_t channel)
652 {
653   if (channel == channel_0) {
654     ETAMPDET->CHNLSEEDVAL0 = seed_value;
655   } else {
656     ETAMPDET->CHNLSEEDVAL1 = seed_value;
657   }
658 }
659 
660 /***************************************************************************//**
661  * Get ETAMPDET channel seed value.
662  *
663  * @param[in] channel  The channel to get seed value from.
664  *
665  * @return  The seed value of the channel.
666  ******************************************************************************/
sl_hal_etampdet_get_seed_value(sl_hal_etampdet_channel_t channel)667 __STATIC_INLINE uint32_t sl_hal_etampdet_get_seed_value(sl_hal_etampdet_channel_t channel)
668 {
669   if (channel == channel_0) {
670     return ETAMPDET->CHNLSEEDVAL0;
671   } else {
672     return ETAMPDET->CHNLSEEDVAL1;
673   }
674 }
675 
676 /** @} (end addtogroup etampdet) */
677 
678 #ifdef __cplusplus
679 }
680 #endif
681 
682 #endif /* defined(ETAMPDET_PRESENT) */
683 #endif /* SL_HAL_ETAMPDET_H */
684