1 /***************************************************************************//**
2 * @file
3 * @brief System Real Time Counter (SYSRTC) 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_SYSRTC_H
32 #define SL_HAL_SYSRTC_H
33
34 #include "em_device.h"
35
36 #if defined(SYSRTC_COUNT) && (SYSRTC_COUNT > 0)
37 #include <stdbool.h>
38 #include "sl_code_classification.h"
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 #include <stdbool.h>
45 #include "sl_hal_sysrtc_compat.h"
46 #include "sl_enum.h"
47
48 /***************************************************************************//**
49 * @addtogroup sysrtc
50 * @{
51 ******************************************************************************/
52
53 /*******************************************************************************
54 ******************************* DEFINES ***********************************
55 ******************************************************************************/
56
57 /// Minimum compare channels for SYSRTC group.
58 #define SYSRTC_GROUP_MIN_CHANNEL_COMPARE 1u
59 /// Maximum compare channels for SYSRTC group.
60 #define SYSRTC_GROUP_MAX_CHANNEL_COMPARE 2u
61
62 /// Minimum capture channels for SYSRTC group.
63 #define SYSRTC_GROUP_MIN_CHANNEL_CAPTURE 0u
64 /// Maximum capture channels for SYSRTC group.
65 #define SYSRTC_GROUP_MAX_CHANNEL_CAPTURE 1u
66
67 /// Sysrtc group number.
68 #if !defined(SYSRTC_GROUP_NUMBER)
69 #define SYSRTC_GROUP_NUMBER 1u
70 #endif
71
72 /// Validation of valid SYSRTC group for assert statements.
73 #define SYSRTC_GROUP_VALID(group) ((unsigned)(group) < SYSRTC_GROUP_NUMBER)
74
75 /*******************************************************************************
76 ********************************* ENUM ************************************
77 ******************************************************************************/
78
79 /// Capture input edge select.
SL_ENUM(sl_hal_sysrtc_capture_edge_t)80 SL_ENUM(sl_hal_sysrtc_capture_edge_t) {
81 SL_HAL_SYSRTC_CAPTURE_EDGE_RISING = 0, ///< Rising edges detected.
82 SL_HAL_SYSRTC_CAPTURE_EDGE_FALLING, ///< Falling edges detected.
83 SL_HAL_SYSRTC_CAPTURE_EDGE_BOTH ///< Both edges detected.
84 };
85
86 /// Compare match output action mode.
SL_ENUM(sl_hal_sysrtc_compare_match_out_action_t)87 SL_ENUM(sl_hal_sysrtc_compare_match_out_action_t) {
88 SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CLEAR = 0, ///< Clear output.
89 SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_SET, ///< Set output.
90 SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_PULSE, ///< Generate a pulse.
91 SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_TOGGLE, ///< Toggle output.
92 SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CMPIF ///< Export CMPIF.
93 };
94
95 /*******************************************************************************
96 ******************************* STRUCTS ***********************************
97 ******************************************************************************/
98
99 /// SYSRTC configuration structure.
100 typedef struct {
101 bool enable_debug_run; ///< Counter shall keep running during debug halt.
102 } sl_hal_sysrtc_config_t;
103
104 /// Suggested default values for SYSRTC configuration structure.
105 #define SYSRTC_CONFIG_DEFAULT \
106 { \
107 false, /* Disable updating during debug halt. */ \
108 }
109
110 /// Compare channel configuration structure.
111 typedef struct {
112 sl_hal_sysrtc_compare_match_out_action_t compare_match_out_action; ///< Compare mode channel match output action.
113 } sl_hal_sysrtc_group_channel_compare_config_t;
114
115 /// Capture channel configuration structure.
116 typedef struct {
117 sl_hal_sysrtc_capture_edge_t capture_input_edge; ///< Capture mode channel input edge.
118 } sl_hal_sysrtc_group_channel_capture_config_t;
119
120 /// Group configuration structure.
121 typedef struct {
122 bool compare_channel0_enable; ///< Enable/Disable compare channel 0
123 bool compare_channel1_enable; ///< Enable/Disable compare channel 1
124 bool capture_channel0_enable; ///< Enable/Disable capture channel 0
125 sl_hal_sysrtc_group_channel_compare_config_t const *p_compare_channel0_config; ///< Pointer to compare channel 0 config
126 sl_hal_sysrtc_group_channel_compare_config_t const *p_compare_channel1_config; ///< Pointer to compare channel 1 config
127 sl_hal_sysrtc_group_channel_capture_config_t const *p_capture_channel0_config; ///< Pointer to capture channel 0 config
128 } sl_hal_sysrtc_group_config_t;
129
130 /// Suggested default values for compare channel configuration structure.
131 #define SYSRTC_GROUP_CHANNEL_COMPARE_CONFIG_DEFAULT \
132 { \
133 SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_PULSE \
134 }
135
136 /// Compare channel configuration for starting HFXO using PRS.
137 #define SYSRTC_GROUP_CHANNEL_COMPARE_CONFIG_EARLY_WAKEUP \
138 { \
139 SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CMPIF \
140 }
141
142 /// Suggested default values for capture channel configuration structure.
143 #define SYSRTC_GROUP_CHANNEL_CAPTURE_CONFIG_DEFAULT \
144 { \
145 SL_HAL_SYSRTC_CAPTURE_EDGE_RISING \
146 }
147
148 /// Suggested default values for SYSRTC group configuration structure.
149 #define SYSRTC_GROUP_CONFIG_DEFAULT \
150 { \
151 true, /* Enable compare channel 0. */ \
152 false, /* Disable compare channel 1. */ \
153 false, /* Disable capture channel 0. */ \
154 NULL, /* NULL Pointer to configuration structure for compare channel 0*/ \
155 NULL, /* NULL Pointer to configuration structure for compare channel 1*/ \
156 NULL /* NULL Pointer to configuration structure for capture channel 0*/ \
157 }
158
159 /*******************************************************************************
160 ***************************** PROTOTYPES **********************************
161 ******************************************************************************/
162
163 /***************************************************************************//**
164 * Initializes SYSRTC module.
165 *
166 * Note that the compare values must be set separately with
167 * (sl_hal_sysrtc_set_group_compare_channel_value()), which should probably be
168 * done prior to the use of this function if configuring the SYSRTC to start
169 * when initialization is completed.
170 *
171 * @param[in] p_config A pointer to the SYSRTC initialization structure
172 * variable.
173 ******************************************************************************/
174 void sl_hal_sysrtc_init(const sl_hal_sysrtc_config_t *p_config);
175
176 /***************************************************************************//**
177 * Enables SYSRTC counting.
178 ******************************************************************************/
179 void sl_hal_sysrtc_enable(void);
180
181 /***************************************************************************//**
182 * Disables SYSRTC counting.
183 ******************************************************************************/
184 void sl_hal_sysrtc_disable(void);
185
186 /***************************************************************************//**
187 * Waits for the SYSRTC to complete all synchronization of register changes
188 * and commands.
189 ******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC,SL_CODE_CLASS_TIME_CRITICAL)190 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
191 __INLINE void sl_hal_sysrtc_wait_sync(void)
192 {
193 while ((SYSRTC0->EN & SYSRTC_EN_EN) && (SYSRTC0->SYNCBUSY != 0U)) {
194 // Wait for all synchronizations to finish
195 }
196 }
197
198 /***************************************************************************//**
199 * Waits for the SYSRTC to complete reseting or disabling procedure.
200 ******************************************************************************/
sl_hal_sysrtc_wait_ready(void)201 __INLINE void sl_hal_sysrtc_wait_ready(void)
202 {
203 while ((SYSRTC0->SWRST & _SYSRTC_SWRST_RESETTING_MASK) || (SYSRTC0->EN & _SYSRTC_EN_DISABLING_MASK) || (SYSRTC0->SYNCBUSY != 0U)) {
204 // Wait for all synchronizations to finish
205 }
206 }
207
208 /***************************************************************************//**
209 * Starts SYSRTC counter.
210 *
211 * This function will send a start command to the SYSRTC peripheral. The SYSRTC
212 * peripheral will use some LF clock ticks before the command is executed.
213 * The sl_hal_sysrtc_wait_sync() function can be used to wait for the start
214 * command to be executed.
215 *
216 * @note This function requires the SYSRTC to be enabled.
217 ******************************************************************************/
sl_hal_sysrtc_start(void)218 __INLINE void sl_hal_sysrtc_start(void)
219 {
220 sl_hal_sysrtc_wait_sync();
221 SYSRTC0->CMD = SYSRTC_CMD_START;
222 }
223
224 /***************************************************************************//**
225 * Stops the SYSRTC counter.
226 *
227 * This function will send a stop command to the SYSRTC peripheral. The SYSRTC
228 * peripheral will use some LF clock ticks before the command is executed.
229 * The sl_hal_sysrtc_wait_sync() function can be used to wait for the stop
230 * command to be executed.
231 *
232 * @note This function requires the SYSRTC to be enabled.
233 ******************************************************************************/
sl_hal_sysrtc_stop(void)234 __INLINE void sl_hal_sysrtc_stop(void)
235 {
236 sl_hal_sysrtc_wait_sync();
237 SYSRTC0->CMD = SYSRTC_CMD_STOP;
238 }
239
240 /***************************************************************************//**
241 * Restores SYSRTC to its reset state.
242 ******************************************************************************/
243 void sl_hal_sysrtc_reset(void);
244
245 /***************************************************************************//**
246 * Gets SYSRTC STATUS register value.
247 *
248 * @return Current STATUS register value.
249 ******************************************************************************/
sl_hal_sysrtc_get_status(void)250 __INLINE uint32_t sl_hal_sysrtc_get_status(void)
251 {
252 return SYSRTC0->STATUS;
253 }
254
255 /***************************************************************************//**
256 * Locks SYSRTC registers.
257 *
258 * @note When SYSRTC registers are locked SYSRTC_EN, SYSRTC_CFG, SYSRTC_CMD,
259 * SYSRTC_SWRST, SYSRTC_CNT and SYSRTC_TOPCNT registers cannot be written
260 * to.
261 ******************************************************************************/
sl_hal_sysrtc_lock(void)262 __INLINE void sl_hal_sysrtc_lock(void)
263 {
264 SYSRTC0->LOCK = ~SYSRTC_LOCK_LOCKKEY_UNLOCK;
265 }
266
267 /***************************************************************************//**
268 * Unlocks SYSRTC registers.
269 *
270 * @note When SYSRTC registers are locked SYSRTC_EN, SYSRTC_CFG, SYSRTC_CMD,
271 * SYSRTC_SWRST, SYSRTC_CNT and SYSRTC_TOPCNT registers cannot be written
272 * to.
273 ******************************************************************************/
sl_hal_sysrtc_unlock(void)274 __INLINE void sl_hal_sysrtc_unlock(void)
275 {
276 SYSRTC0->LOCK = SYSRTC_LOCK_LOCKKEY_UNLOCK;
277 }
278
279 /***************************************************************************//**
280 * Gets SYSRTC counter value.
281 *
282 * @return Current SYSRTC counter value.
283 ******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC,SL_CODE_CLASS_TIME_CRITICAL)284 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
285 __INLINE uint32_t sl_hal_sysrtc_get_counter(void)
286 {
287 // Wait for Counter to synchronize before getting value
288 sl_hal_sysrtc_wait_sync();
289
290 return SYSRTC0->CNT;
291 }
292
293 /***************************************************************************//**
294 * Sets the SYSRTC counter value.
295 *
296 * @param[in] value The new SYSRTC counter value.
297 ******************************************************************************/
sl_hal_sysrtc_set_counter(uint32_t value)298 __INLINE void sl_hal_sysrtc_set_counter(uint32_t value)
299 {
300 // Wait for Counter to synchronize before getting value
301 sl_hal_sysrtc_wait_sync();
302
303 SYSRTC0->CNT = value;
304 }
305
306 /***************************************************************************//**
307 * Initializes the selected SYSRTC group.
308 *
309 * @param[in] group_number SYSRTC group number to use.
310 *
311 * @param[in] p_group_config Pointer to group configuration structure
312 * variable.
313 ******************************************************************************/
314 void sl_hal_sysrtc_init_group(uint8_t group_number,
315 sl_hal_sysrtc_group_config_t const *p_group_config);
316
317 /***************************************************************************//**
318 * Enables one or more SYSRTC interrupts for the given group.
319 *
320 * @note Depending on the use, a pending interrupt may already be set prior to
321 * enabling the interrupt. To ignore a pending interrupt, consider using
322 * sl_hal_sysrtc_clear_group_interrupts() prior to enabling the interrupt.
323 *
324 * @param[in] group_number SYSRTC group number to use.
325 *
326 * @param[in] flags SYSRTC interrupt sources to enable.
327 * Use a set of interrupt flags OR-ed together to set
328 * multiple interrupt sources for the given SYSRTC group.
329 ******************************************************************************/
330 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
331 void sl_hal_sysrtc_enable_group_interrupts(uint8_t group_number,
332 uint32_t flags);
333
334 /***************************************************************************//**
335 * Disables one or more SYSRTC interrupts for the given group.
336 *
337 * @param[in] group_number SYSRTC group number to use.
338 *
339 * @param[in] flags SYSRTC interrupt sources to disable.
340 * Use a set of interrupt flags OR-ed together to disable
341 * multiple interrupt sources for the given SYSRTC group.
342 ******************************************************************************/
343 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
344 void sl_hal_sysrtc_disable_group_interrupts(uint8_t group_number,
345 uint32_t flags);
346
347 /***************************************************************************//**
348 * Clears one or more pending SYSRTC interrupts for the given group.
349 *
350 * @param[in] group_number SYSRTC group number to use.
351 *
352 * @param[in] flags SYSRTC interrupt sources to clear.
353 * Use a set of interrupt flags OR-ed together to clear
354 * multiple interrupt sources for the given SYSRTC group.
355 ******************************************************************************/
356 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
357 void sl_hal_sysrtc_clear_group_interrupts(uint8_t group_number,
358 uint32_t flags);
359
360 /***************************************************************************//**
361 * Gets pending SYSRTC interrupt flags for the given group.
362 *
363 * @note Event bits are not cleared by using this function.
364 *
365 * @param[in] group_number SYSRTC group number to use.
366 *
367 * @return Pending SYSRTC interrupt sources.
368 * Returns a set of interrupt flags OR-ed together for multiple
369 * interrupt sources in the SYSRTC group.
370 ******************************************************************************/
371 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
372 uint32_t sl_hal_sysrtc_get_group_interrupts(uint8_t group_number);
373
374 /***************************************************************************//**
375 * Gets enabled and pending SYSRTC interrupt flags.
376 * Useful for handling more interrupt sources in the same interrupt handler.
377 *
378 * @note Interrupt flags are not cleared by using this function.
379 *
380 * @param[in] group_number SYSRTC group number to use.
381 *
382 * @return Pending and enabled SYSRTC interrupt sources.
383 * The return value is the bitwise AND of
384 * - the enabled interrupt sources in SYSRTC_GRPx_IEN and
385 * - the pending interrupt flags SYSRTC_GRPx_IF.
386 ******************************************************************************/
387 uint32_t sl_hal_sysrtc_get_group_enabled_interrupts(uint8_t group_number);
388
389 /***************************************************************************//**
390 * Sets one or more pending SYSRTC interrupts for the given group from Software.
391 *
392 * @param[in] group_number SYSRTC group number to use.
393 *
394 * @param[in] flags SYSRTC interrupt sources to set to pending.
395 * Use a set of interrupt flags OR-ed together to set
396 * multiple interrupt sources for the SYSRTC group.
397 ******************************************************************************/
398 void sl_hal_sysrtc_set_group_interrupts(uint8_t group_number,
399 uint32_t flags);
400
401 /***************************************************************************//**
402 * Gets SYSRTC compare register value for selected channel of given group.
403 *
404 * @param[in] group_number SYSRTC group number to use.
405 *
406 * @param[in] channel Channel selector.
407 *
408 * @return Compare register value.
409 ******************************************************************************/
410 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
411 uint32_t sl_hal_sysrtc_get_group_compare_channel_value(uint8_t group_number,
412 uint8_t channel);
413
414 /***************************************************************************//**
415 * Sets SYSRTC compare register value for selected channel of given group.
416 *
417 * @param[in] group_number SYSRTC group number to use.
418 *
419 * @param[in] channel Channel selector.
420 *
421 * @param[in] value Compare register value.
422 ******************************************************************************/
423 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
424 void sl_hal_sysrtc_set_group_compare_channel_value(uint8_t group_number,
425 uint8_t channel,
426 uint32_t value);
427
428 /***************************************************************************//**
429 * Gets SYSRTC input capture register value for capture channel of given group.
430 *
431 * @param[in] group_number SYSRTC group number to use.
432 *
433 * @return Capture register value.
434 ******************************************************************************/
435 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
436 uint32_t sl_hal_sysrtc_get_group_capture_channel_value(uint8_t group_number);
437
438 /** @} (end addtogroup sysrtc) */
439
440 #ifdef __cplusplus
441 }
442 #endif
443
444 #endif /* defined(SYSRTC_COUNT) && (SYSRTC_COUNT > 0) */
445 #endif /* SL_HAL_SYSRTC_H */
446