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