1 /***************************************************************************//**
2 * @file
3 * @brief Clock Manager APIs.
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2023 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_CLOCK_MANAGER_H
32 #define SL_CLOCK_MANAGER_H
33
34 #include <stdbool.h>
35 #include <stdlib.h>
36 #include "sl_status.h"
37 #include "sl_enum.h"
38 #include "sl_device_clock.h"
39 #include "sl_code_classification.h"
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 /***************************************************************************//**
46 * @addtogroup clock_manager Clock Manager
47 *
48 * @details
49 * ## Overview
50 *
51 * Clock Manager is a platform-level software module that manages
52 * the device's oscillators and clock tree.
53 * The Clock Manager module is split into two main parts: The Initialization part
54 * and the Runtime part. The runtime part has its component
55 * \a clock_manager_runtime and can be used independently from the initialization
56 * part. The \a clock_manager component includes both the initialization part and the
57 * runtime part and it should be the component added to your project slcp file.
58 *
59 * ## Initialization
60 * The initialization part includes the configuration files
61 * \a sl_clock_manager_oscillator_config.h and \a sl_clock_manager_tree_config.h.
62 * As their name indicates, those C header files are used to configure the different
63 * device oscillators and the device clock tree. Those header files use the CMSIS
64 * Configuration Wizard Annotations and are specific to each device.
65 * The API function sl_clock_manager_init() is used to initialize the Clock Manager
66 * module based on the configuration values specified in the two configuration files.
67 * This function must be called early during your initialization sequence.
68 * If the SL System component (@ref system) is used by your application, the
69 * sl_clock_manager_init() call will be added automatically to your initialization
70 * sequence.
71 *
72 * ### Oscillators Configuration
73 * Oscillators' configurations are all grouped in the \a sl_clock_manager_oscillator_config.h
74 * file. Crystal-based oscillators, HFXO and LFXO, have an enable/disable configuration to
75 * indicate if the required crystal is present or not. In the absence of the required
76 * crystal, the configuration must be disabled and the associated oscillator will
77 * not be initialized.
78 *
79 * The HFXO configuration also provides the configuration for the Crystal Sharing
80 * feature when supported by the device. This feature allows to use the dedicated
81 * HFCLKOUT pin to output a sinusoidal clock that can be used as the HFXO
82 * input for another EFR device. In the configuration, you need to specify if your
83 * device is the leader or the follower. The leader will be the one outputting the
84 * clock and the follower, the one receiving the clock signal. In the leader configuration,
85 * the GPIO pin is used to receive the request from the follower. You can refer to your
86 * device datasheet to know the available location for the HFXO BUFOUT_REQ pin.
87 * In the follower mode, the pin configuration can be used to send an HFXO request
88 * signal to the leader. The "High Frequency Clock Ouput" section of your device
89 * reference manual also provides more details about this feature.
90 *
91 * The first HFRCO module, whose output clock is called HFRCODPLL, can be connected to
92 * the DPLL module to have a better precision clock. When the DPLL is enabled through
93 * the configuration define \a SL_CLOCK_MANAGER_HFRCO_DPLL_EN, the DPLL settings
94 * take precedence over the HFRCO band configuration.
95 *
96 * ### Clock Tree Configuration
97 * The device clock tree configurations are all grouped in the
98 * \a sl_clock_manager_tree_config.h file. Refer to your device's reference manual for
99 * the clock tree diagram and see which peripherals are connected to which clock branches.
100 * In the configuration file, each clock branch can be independently configured.
101 * However, to facilitate the clock setup for users, two additional configurations
102 * were added: \a SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE and
103 * \a SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE. Those configurations allow the selection
104 * of the default high-frequency and low-frequency oscillators to be used inside the clock
105 * tree. Every clock branch that can benefit from those default selections will use them
106 * by default.
107 * On certain devices, the @ref power_manager module offers an Execution Modes feature
108 * with the \a SL_POWER_MANAGER_EXECUTION_MODES_FEATURE_EN configuration. When this feature
109 * is enabled, the \a SL_CLOCK_MANAGER_SYSCLK_SOURCE configuration could be overriden by the
110 * Execution Modes feature. Refer to the description of \a SL_CLOCK_MANAGER_SYSCLK_SOURCE in
111 * \a sl_clock_manager_tree_config.h file to know if this is the case.
112 *
113 * Some peripherals have an internal clock divider. Those are not handled by the
114 * Clock Manager configuration. The peripheral driver will usually expose the divider
115 * configuration when such a divider is present inside the peripheral module.
116 *
117 * The Clock tree configuration is available at compile-time only. The Clock Manager
118 * module does not offer API functions to manipulate the clock tree at runtime.
119 *
120 * The more oscillators are used by different clock branches the more power
121 * consumption you will have. To limit your power consumption, you can try to limit the
122 * number of oscillators used. So for example, only use one High-frequency oscillator
123 * and one Low-frequency oscillator across the clock tree. However, if the
124 * application is radio-based, the HFXO oscillator is mandatory for the Radio
125 * clock branch and if the Radio clock branch is connected to the SYSCLK branch,
126 * this will limit you to use HFXO for SYSCLK as well. In this specific case, SYSCLK
127 * could also be configured to use HFRCO with DPLL, but the chosen frequency must be two
128 * times the HFXO frequency so that the Radio module can retrieve the HF crystal frequency
129 * with its divider. This will also come with an increase in power consumption since both
130 * HFXO and HFRCO oscillators will be used. Refer to your device reference manual to know
131 * if your Radio clock is connected to the SYSCLK clock branch or not.
132 *
133 * @note The Clock Manager Initialization is incompatible with the \a device_init_clocks
134 * (@ref device_init_clocks), \a device_init_hfxo (@ref device_init_hfxo),
135 * \a device_init_hfrco (@ref device_init_hfrco) \a device_init_dpll (@ref device_init_dpll),
136 * \a device_init_rffpll (@ref device_init_rffpll), \a device_init_usbpll (@ref device_init_usbpll),
137 * \a device_init_lfxo (@ref device_init_lfxo) and \a device_init_lfrco (@ref device_init_lfrco)
138 * components.
139 * This does not mean that the \a device_init component (@ref device_init) is incompatible with the
140 * \a clock_manager component. The \a device_init component can pull other initialization
141 * modules like EMU and DCDC that are not related to clocks. Therefore, both
142 * \a device_init and \a clock_manager should be present in your project file. SLC will
143 * take care of pulling only the sub \a device_init_xxx components that are needed.
144 *
145 * The runtime part, which is associated with the \a clock_manager_runtime component,
146 * has also an initialization function of its own, sl_clock_manager_runtime_init().
147 * This function must also be part of the initialization sequence. If the SL System
148 * component (@ref system) is used by your application, the
149 * sl_clock_manager_runtime_init() call will be added automatically to your
150 * initialization sequence.
151 *
152 * ## Functionalities
153 * The Runtime part includes functionalities related to oscillators, clock tree
154 * and the CMU hardware module features. The main functionalities are:
155 * - Retrieving the frequency or precision of an oscillator or clock branch
156 * - Enabling/Disabling modules' bus clock
157 * - Retrieving or setting calibration values for oscillators
158 * - Exporting clocks to GPIO
159 * - Starting an RCO Calibration process based on a reference clock source
160 *
161 * ### Retrieve the frequency or precision of an oscillator or clock branch
162 * API functions sl_clock_manager_get_oscillator_frequency() and
163 * sl_clock_manager_get_oscillator_precision() allow retrieving respectively
164 * the frequency and precision of a given oscillator. Similar functions
165 * exist for clock branches: sl_clock_manager_get_clock_branch_frequency() and
166 * sl_clock_manager_get_clock_branch_precision().
167 *
168 * To retrieve the frequency or precision of a specific peripheral, you will
169 * first need to retrieve to which clock branch this peripheral is connected.
170 * To do so, the Device Manager and its @ref device_peripheral
171 * can be used. The below code example shows how to retrieve the clock branch
172 * of the TIMER0 peripheral.
173 *
174 * @code{.c}
175 * #include "sl_clock_manager.h"
176 * #include "sl_device_peripheral.h"
177 *
178 * sl_status_t status;
179 * uint32_t freq;
180 * sl_clock_branch_t clock_branch;
181 *
182 * clock_branch = sl_device_peripheral_get_clock_branch(SL_PERIPHERAL_TIMER0);
183 * status = sl_clock_manager_get_clock_branch_frequency(clock_branch, &freq);
184 * @endcode
185 *
186 * ### Enable/Disable modules' bus clock
187 * Before accessing a peripheral's register interface, its bus clock must be enabled,
188 * or else a bus fault exception will be triggered. API functions
189 * sl_clock_manager_enable_bus_clock() and sl_clock_manager_disable_bus_clock()
190 * allow to perform such operations.
191 *
192 * Note that the peripheral clock will automatically be enabled when a peripheral
193 * is enabled with the clock on-demand feature.
194 *
195 * ### Oscillator Calibration
196 * The Clock Manager initialization, if present, will calibrate the different
197 * oscillators during the initialization sequence, but sometimes calibration
198 * values must be updated during runtime in certain conditions, for example, if
199 * the device temperature changes too much. This is considered an advanced
200 * functionality and users must be careful as to when to use this functionality.
201 *
202 * API functions sl_clock_manager_set_rc_oscillator_calibration() and
203 * sl_clock_manager_get_rc_oscillator_calibration() allow to set or get the
204 * CAL register of HFRCO and LFRCO oscillators. Not all devices have an LFRCO
205 * module with a CAL register. Some LFRCO modules will have a high-precision
206 * configuration allowing to use the HFXO to auto-calibrate the LFRCO. Refer
207 * to your device reference manual to retrieve oscillator specifications.
208 *
209 * API functions sl_clock_manager_set_hfxo_calibration() and
210 * sl_clock_manager_get_hfxo_calibration() allow to set or get the \a COREBIASANA
211 * inside the HFXO \a XTALCTRL register. The HFXO module has a Core Bias Optimization
212 * stage at the end of the oscillator startup sequence that allows to further
213 * optimize current consumption. This optimization will automatically set the
214 * \a COREBIASANA bitfield when finished. Upon reset, this optimization will run
215 * the first time HFXO is started and afterwards, the \a XTALCTRL->SKIPCOREBIASOPT
216 * bit will automatically be set so that next time HFXO is started during the
217 * application lifetime, the optimization stage will be skipped. This optimization
218 * stage takes a while to run, in the order of hundreds of milliseconds, therefore
219 * we don't want it to run each time HFXO is started.
220 * With the function sl_clock_manager_set_hfxo_calibration() it is possible to
221 * manually set the \a COREBIASANA bitfield and set the \a SKIPCOREBIASOPT bit.
222 * This function will usually be used in the context of an EM4 wake-up where to
223 * save on the initialization sequence time, we want to skip the Core Bias Optimization
224 * stage and manually set the value that would have previously been retrieved with
225 * sl_clock_manager_get_hfxo_calibration() and saved in an EM4 retained memory.
226 * In this context, sl_clock_manager_set_hfxo_calibration() will need to be called
227 * early in the initialization sequence, before the usual clock initialization
228 * function.
229 *
230 * slx_clock_manager_hfxo_set_ctune(), slx_clock_manager_hfxo_get_ctune() and
231 * slx_clock_manager_hfxo_calibrate_ctune() functions allow to manipulate the
232 * HFXO tuning capacitances. Changing the CTUNE value while HFXO is running
233 * can result in significant clock glitches for one clock period. Therefore,
234 * those functions should be used with caution. The difference between the
235 * slx_clock_manager_hfxo_set_ctune() and slx_clock_manager_hfxo_calibrate_ctune()
236 * functions is that the calibration one will also start and wait for the HFXO
237 * Core Bias Optimization stage to complete.
238 *
239 * API functions sl_clock_manager_set_lfxo_calibration() and
240 * sl_clock_manager_get_lfxo_calibration() allow to set and get the LFXO CTUNE
241 * value.
242 *
243 * ### Export clocks to GPIO
244 * The CMU module offers the functionality to export a given clock source to a
245 * GPIO pin. Refer to function sl_clock_manager_set_gpio_clock_output() for more
246 * details and the #sl_clock_manager_export_clock_source_t enum for a list of
247 * acceptable clock sources. Note that there is a specific clock branch named
248 * EXPCLK that is usually connected to the SYSCLK and offers an additional divider.
249 *
250 * ### RCO Calibration
251 * The CMU module also offers RCO Calibration hardware support. This can be
252 * used to calibrate at runtime HFRCO and LFRCO oscillators using a high-precision
253 * reference clock. Refer to your device reference manual for more
254 * details about this functionality. API function
255 * sl_clock_manager_configure_rco_calibration() can be used to configure the
256 * calibration process. Then sl_clock_manager_start_rco_calibration() and
257 * sl_clock_manager_stop_rco_calibration() can be called to start/stop the
258 * process. sl_clock_manager_wait_rco_calibration() function can be called to
259 * actively wait for the process to finish. And finally,
260 * sl_clock_manager_get_rco_calibration_count() can be called to retrieve the
261 * calibration process result.
262 *
263 * @{
264 ******************************************************************************/
265
266 /// Export clock source.
267 /// This is to be used with the sl_clock_manager_set_gpio_clock_output() API function.
SL_ENUM(sl_clock_manager_export_clock_source_t)268 SL_ENUM(sl_clock_manager_export_clock_source_t) {
269 SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_DISABLED, ///< Export Clock Source Disabled
270 SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_FSRCO, ///< Export Clock Source FSRCO
271 SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_HFXO, ///< Export Clock Source HFXO
272 SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_HFRCODPLL, ///< Export Clock Source HFRCODPLL
273 SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_HFRCOEM23, ///< Export Clock Source HFRCOEM23
274 SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_HFEXPCLK, ///< Export Clock Source HFEXPCLK
275 SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_LFXO, ///< Export Clock Source LFXO
276 SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_PLFRCO, ///< Export Clock Source PLFRCO
277 SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_LFRCO, ///< Export Clock Source LFRCO
278 SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_ULFRCO, ///< Export Clock Source ULFRCO
279 SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_HCLK, ///< Export Clock Source HCLK
280 };
281
282 /// Export clock output selection.
283 /// This is to be used with the sl_clock_manager_set_gpio_clock_output() API function.
SL_ENUM(sl_clock_manager_export_clock_output_select_t)284 SL_ENUM(sl_clock_manager_export_clock_output_select_t) {
285 SL_CLOCK_MANAGER_EXPORT_CLOCK_OUTPUT_SELECT_0 = 0, ///< Export Clock Output #0
286 SL_CLOCK_MANAGER_EXPORT_CLOCK_OUTPUT_SELECT_1, ///< Export Clock Output #1
287 SL_CLOCK_MANAGER_EXPORT_CLOCK_OUTPUT_SELECT_2, ///< Export Clock Output #2
288 };
289
290 /// Clocks available for Calibration.
291 /// This is to be used with the sl_clock_manager_configure_rco_calibration() API function.
SL_ENUM(sl_clock_manager_clock_calibration_t)292 SL_ENUM(sl_clock_manager_clock_calibration_t) {
293 SL_CLOCK_MANAGER_CLOCK_CALIBRATION_HCLK, ///< Clock Calibration HCLK
294 SL_CLOCK_MANAGER_CLOCK_CALIBRATION_PRS, ///< Clock Calibration PRS
295 SL_CLOCK_MANAGER_CLOCK_CALIBRATION_HFXO, ///< Clock Calibration HFXO
296 SL_CLOCK_MANAGER_CLOCK_CALIBRATION_LFXO, ///< Clock Calibration LFXO
297 SL_CLOCK_MANAGER_CLOCK_CALIBRATION_HFRCODPLL, ///< Clock Calibration HFRCODPLL
298 SL_CLOCK_MANAGER_CLOCK_CALIBRATION_HFRCOEM23, ///< Clock Calibration HFRCOEM23
299 SL_CLOCK_MANAGER_CLOCK_CALIBRATION_FSRCO, ///< Clock Calibration FSRCO
300 SL_CLOCK_MANAGER_CLOCK_CALIBRATION_LFRCO, ///< Clock Calibration LFRCO
301 SL_CLOCK_MANAGER_CLOCK_CALIBRATION_ULFRCO ///< Clock Calibration ULFRCO
302 };
303
304 // -----------------------------------------------------------------------------
305 // Prototypes
306
307 /***************************************************************************//**
308 * Performs Clock Manager runtime initialization.
309 *
310 * @return Status code.
311 * SL_STATUS_OK if successful. Error code otherwise.
312 ******************************************************************************/
313 sl_status_t sl_clock_manager_runtime_init(void);
314
315 /***************************************************************************//**
316 * Gets frequency of given oscillator.
317 *
318 * @param[in] oscillator Oscillator
319 *
320 * @param[out] frequency Oscillator's frequency in Hertz
321 *
322 * @return Status code.
323 * SL_STATUS_OK if successful. Error code otherwise.
324 ******************************************************************************/
325 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
326 sl_status_t sl_clock_manager_get_oscillator_frequency(sl_oscillator_t oscillator,
327 uint32_t *frequency);
328
329 /***************************************************************************//**
330 * Gets precision of given oscillator.
331 *
332 * @param[in] oscillator Oscillator
333 *
334 * @param[out] precision Oscillator's precision in PPM
335 *
336 * @return Status code.
337 * SL_STATUS_OK if successful. Error code otherwise.
338 ******************************************************************************/
339 sl_status_t sl_clock_manager_get_oscillator_precision(sl_oscillator_t oscillator,
340 uint16_t *precision);
341
342 /***************************************************************************//**
343 * Gets frequency of given clock branch.
344 *
345 * @param[in] clock_branch Clock Branch
346 *
347 * @param[out] frequency Clock Branch's frequency in Hertz
348 *
349 * @return Status code.
350 * SL_STATUS_OK if successful. Error code otherwise.
351 ******************************************************************************/
352 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
353 sl_status_t sl_clock_manager_get_clock_branch_frequency(sl_clock_branch_t clock_branch,
354 uint32_t *frequency);
355
356 /***************************************************************************//**
357 * Gets precision of given clock branch.
358 *
359 * @param[in] clock_branch Clock Branch
360 *
361 * @param[out] precision Clock Branch's precision in PPM
362 *
363 * @return Status code.
364 * SL_STATUS_OK if successful. Error code otherwise.
365 ******************************************************************************/
366 sl_status_t sl_clock_manager_get_clock_branch_precision(sl_clock_branch_t clock_branch,
367 uint16_t *precision);
368
369 /***************************************************************************//**
370 * Enables the given module's bus clock.
371 *
372 * @param[in] module_bus_clock module's bus clock to enable.
373 *
374 * @return Status code.
375 * SL_STATUS_OK if successful. Error code otherwise.
376 *
377 * @note modules' bus clocks are defined in the
378 * @ref device_clock in the Bus Clock Defines section.
379 ******************************************************************************/
380 sl_status_t sl_clock_manager_enable_bus_clock(sl_bus_clock_t module_bus_clock);
381
382 /***************************************************************************//**
383 * Disables the given module's bus clock.
384 *
385 * @param[in] module_bus_clock module's bus clock to disable.
386 *
387 * @return Status code.
388 * SL_STATUS_OK if successful. Error code otherwise.
389 *
390 * @note modules' bus clocks are defined in the
391 * @ref device_clock in the Bus Clock Defines section.
392 ******************************************************************************/
393 sl_status_t sl_clock_manager_disable_bus_clock(sl_bus_clock_t module_bus_clock);
394
395 /***************************************************************************//**
396 * Configures one clock export output with specified clock source.
397 *
398 * @param[in] export_clock_source One of the exportable clock source.
399 *
400 * @param[in] output_select Selected export clock output channel.
401 *
402 * @param[in] hfexp_divider HFEXP clock divider (1 to 32).
403 * Note: This parameter only affects the EXPCLK
404 * branch frequency.
405 *
406 * @param[in] port GPIO port to output exported clock.
407 *
408 * @param[in] pin GPIO pin number to output exported clock.
409 *
410 * @return Status code.
411 * SL_STATUS_OK if successful. Error code otherwise.
412 ******************************************************************************/
413 sl_status_t sl_clock_manager_set_gpio_clock_output(sl_clock_manager_export_clock_source_t export_clock_source,
414 sl_clock_manager_export_clock_output_select_t output_select,
415 uint16_t hfexp_divider,
416 uint32_t port,
417 uint32_t pin);
418
419 /***************************************************************************//**
420 * Sets the RC oscillator frequency tuning control.
421 *
422 * @param[in] oscillator RC Oscillator to set tuning value for.
423 *
424 * @param[in] val The RC oscillator frequency tuning setting to use.
425 *
426 * @return Status code.
427 * SL_STATUS_OK if successful. Error code otherwise.
428 *
429 * @note RC Oscillator tuning is done during production, and the tuning value is
430 * loaded after a reset by the Clock Manager initialization code.
431 * Changing the tuning value from the calibrated value is for more advanced
432 * use. Certain oscillators also have build-in tuning optimization.
433 *
434 * @note Supported RC oscillators include:
435 * - SL_OSCILLATOR_HFRCODPLL
436 * - SL_OSCILLATOR_HFRCOEM23
437 * - SL_OSCILLATOR_LFRCO
438 ******************************************************************************/
439 sl_status_t sl_clock_manager_set_rc_oscillator_calibration(sl_oscillator_t oscillator,
440 uint32_t val);
441
442 /***************************************************************************//**
443 * Gets the RC oscillator frequency tuning setting.
444 *
445 * @param[in] oscillator An RC oscillator to get tuning value for.
446 *
447 * @param[out] val The RC oscillator frequency tuning setting in use.
448 *
449 * @return Status code.
450 * SL_STATUS_OK if successful. Error code otherwise.
451 *
452 * @note Supported RC oscillators include:
453 * - SL_OSCILLATOR_HFRCODPLL
454 * - SL_OSCILLATOR_HFRCOEM23
455 * - SL_OSCILLATOR_LFRCO
456 ******************************************************************************/
457 sl_status_t sl_clock_manager_get_rc_oscillator_calibration(sl_oscillator_t oscillator,
458 uint32_t *val);
459
460 /***************************************************************************//**
461 * Sets the HFXO calibration value.
462 *
463 * @param[in] val
464 * The HFXO calibration setting to use.
465 *
466 * @return Status code.
467 * SL_STATUS_OK if successful. Error code otherwise.
468 ******************************************************************************/
469 sl_status_t sl_clock_manager_set_hfxo_calibration(uint32_t val);
470
471 /***************************************************************************//**
472 * Gets the HFXO calibration value.
473 *
474 * @param[out] val The current HFXO calibration value.
475 *
476 * @return Status code.
477 * SL_STATUS_OK if successful. Error code otherwise.
478 ******************************************************************************/
479 sl_status_t sl_clock_manager_get_hfxo_calibration(uint32_t *val);
480
481 /***************************************************************************//**
482 * Sets the HFXO's CTUNE.
483 *
484 * @param[in] ctune The HFXO's CTUNE value.
485 *
486 * @return Status code.
487 * SL_STATUS_OK if successful. Error code otherwise.
488 *
489 * @note Sets the XI value to the given ctune value and sets the XO value based
490 * on that same value, but with an offset that is hardware dependent.
491 * Updating CTune while the crystal oscillator is running can
492 * result in significant clock glitches for one XO clock period.
493 * Should be used with caution.
494 ******************************************************************************/
495 sl_status_t slx_clock_manager_hfxo_set_ctune(uint32_t ctune);
496
497 /***************************************************************************//**
498 * Gets the HFXO's CTUNE.
499 *
500 * @param[out] ctune The returned HFXO's CTUNE value.
501 *
502 * @return Status code.
503 * SL_STATUS_OK if successful. Error code otherwise.
504 *
505 * @note This function only returns the CTUNE XI value.
506 * The XO value follows the XI value with a fixed delta that is
507 * hardware dependent.
508 ******************************************************************************/
509 sl_status_t slx_clock_manager_hfxo_get_ctune(uint32_t *ctune);
510
511 /***************************************************************************//**
512 * Updates the tuning capacitances and calibrate the Core Bias Current.
513 *
514 * @param[in] ctune The HFXO's CTUNE value.
515 *
516 * @return Status code.
517 * SL_STATUS_OK if successful. Error code otherwise.
518 *
519 * @note Calibrating the CTUNE is time consuming and will cause glitches on the
520 * HFXO's clock. Care and caution should be taken when using this API.
521 ******************************************************************************/
522 sl_status_t slx_clock_manager_hfxo_calibrate_ctune(uint32_t ctune);
523
524 /***************************************************************************//**
525 * Sets the LFXO frequency tuning control.
526 *
527 * @param[in] val The LFXO frequency tuning setting to use.
528 *
529 * @return Status code.
530 * SL_STATUS_OK if successful. Error code otherwise.
531 ******************************************************************************/
532 sl_status_t sl_clock_manager_set_lfxo_calibration(uint32_t val);
533
534 /***************************************************************************//**
535 * Gets the LFXO frequency tuning setting.
536 *
537 * @param[out] val The LFXO frequency tuning setting to use.
538 *
539 * @return Status code.
540 * SL_STATUS_OK if successful. Error code otherwise.
541 ******************************************************************************/
542 sl_status_t sl_clock_manager_get_lfxo_calibration(uint32_t *val);
543
544 /***************************************************************************//**
545 * Configures the RCO calibration.
546 *
547 * @param[in] cycles Number of cycles to run calibration. Increasing this
548 * number increases precision, but the calibration will
549 * take more time.
550 *
551 * @param[in] down_counter_selection
552 * The clock which will be counted down cycles.
553 *
554 * @param[in] up_counter_selection
555 * The number of cycles generated by this clock will be counted and
556 * added up, the result can be given with
557 * sl_clock_manager_get_rco_calibration_count().
558 *
559 * @param[in] continuous_calibration
560 * Flag when true configures continuous calibration.
561 *
562 * @return Status code.
563 * SL_STATUS_OK if successful. Error code otherwise.
564 *
565 * @note RCO calibration related functions are not thread-safe and should
566 * therefore not be called across multiple tasks.
567 ******************************************************************************/
568 sl_status_t sl_clock_manager_configure_rco_calibration(uint32_t cycles,
569 sl_clock_manager_clock_calibration_t down_counter_selection,
570 sl_clock_manager_clock_calibration_t up_counter_selection,
571 bool continuous_calibration);
572
573 /***************************************************************************//**
574 * Starts the RCO calibration.
575 *
576 * @note RCO calibration related functions are not thread-safe and should
577 * therefore not be called across multiple tasks.
578 ******************************************************************************/
579 void sl_clock_manager_start_rco_calibration(void);
580
581 /***************************************************************************//**
582 * Stops the RCO calibration.
583 *
584 * @note RCO calibration related functions are not thread-safe and should
585 * therefore not be called across multiple tasks.
586 ******************************************************************************/
587 void sl_clock_manager_stop_rco_calibration(void);
588
589 /***************************************************************************//**
590 * Waits for the RCO calibration to finish.
591 *
592 * @note RCO calibration related functions are not thread-safe and should
593 * therefore not be called across multiple tasks.
594 ******************************************************************************/
595 void sl_clock_manager_wait_rco_calibration(void);
596
597 /***************************************************************************//**
598 * Gets calibration count value, returns the value of the up counter.
599 *
600 * @param[out] count Calibration count value.
601 *
602 * @return Status code.
603 * SL_STATUS_OK if successful. Error code otherwise.
604 *
605 * @note RCO calibration related functions are not thread-safe and should
606 * therefore not be called across multiple tasks.
607 ******************************************************************************/
608 sl_status_t sl_clock_manager_get_rco_calibration_count(uint32_t *count);
609
610 /***************************************************************************//**
611 * Waits for USBPLL clock to be ready.
612 *
613 * @return Status code.
614 * SL_STATUS_OK if successful. Error code otherwise.
615 ******************************************************************************/
616 sl_status_t sl_clock_manager_wait_usbpll(void);
617
618 /***************************************************************************//**
619 * When this callback function is called, it means that HFXO failed twice in
620 * a row to start with normal configurations. This may mean that there is a
621 * bad crystal. When getting this callback, HFXO is running but its properties
622 * (frequency, precision) are not guaranteed. This should be considered as an
623 * error situation.
624 *
625 * @note This callback will be called only when the
626 * SL_CLOCK_MANAGER_HFXO_SLEEPY_CRYSTAL_SUPPORT config is enabled
627 ******************************************************************************/
628 void sl_clock_manager_hfxo_notify_consecutive_failed_startups(void);
629
630 /** @} (end addtogroup clock_manager) */
631
632 #ifdef __cplusplus
633 }
634 #endif
635
636 #endif // SL_CLOCK_MANAGER_H
637