1 /***************************************************************************//**
2  * @file
3  * @brief Clock Manager API implementations.
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 #include "sl_clock_manager.h"
32 #include "sli_clock_manager_hal.h"
33 #include "sl_assert.h"
34 #include "cmsis_compiler.h"
35 
36 /***************************************************************************//**
37  * Performs Clock Manager runtime initialization.
38  ******************************************************************************/
sl_clock_manager_runtime_init(void)39 sl_status_t sl_clock_manager_runtime_init(void)
40 {
41   return sli_clock_manager_hal_runtime_init();
42 }
43 
44 /***************************************************************************//**
45  * Gets frequency of given oscillator.
46  ******************************************************************************/
sl_clock_manager_get_oscillator_frequency(sl_oscillator_t oscillator,uint32_t * frequency)47 sl_status_t sl_clock_manager_get_oscillator_frequency(sl_oscillator_t oscillator,
48                                                       uint32_t        *frequency)
49 {
50   if (frequency == NULL) {
51     return SL_STATUS_NULL_POINTER;
52   }
53 
54   return sli_clock_manager_hal_get_oscillator_frequency(oscillator, frequency);
55 }
56 
57 /***************************************************************************//**
58  * Gets precision of given oscillator.
59  ******************************************************************************/
sl_clock_manager_get_oscillator_precision(sl_oscillator_t oscillator,uint16_t * precision)60 sl_status_t sl_clock_manager_get_oscillator_precision(sl_oscillator_t oscillator,
61                                                       uint16_t        *precision)
62 {
63   if (precision == NULL) {
64     return SL_STATUS_NULL_POINTER;
65   }
66 
67   return sli_clock_manager_hal_get_oscillator_precision(oscillator, precision);
68 }
69 
70 /***************************************************************************//**
71  * Gets frequency of given clock branch.
72  ******************************************************************************/
sl_clock_manager_get_clock_branch_frequency(sl_clock_branch_t clock_branch,uint32_t * frequency)73 sl_status_t sl_clock_manager_get_clock_branch_frequency(sl_clock_branch_t clock_branch,
74                                                         uint32_t          *frequency)
75 {
76   if (frequency == NULL) {
77     return SL_STATUS_NULL_POINTER;
78   }
79 
80   return sli_clock_manager_hal_get_clock_branch_frequency(clock_branch, frequency);
81 }
82 
83 /***************************************************************************//**
84  * Gets precision of given clock branch.
85  ******************************************************************************/
sl_clock_manager_get_clock_branch_precision(sl_clock_branch_t clock_branch,uint16_t * precision)86 sl_status_t sl_clock_manager_get_clock_branch_precision(sl_clock_branch_t clock_branch,
87                                                         uint16_t          *precision)
88 {
89   if (precision == NULL) {
90     return SL_STATUS_NULL_POINTER;
91   }
92 
93   return sli_clock_manager_hal_get_clock_branch_precision(clock_branch, precision);
94 }
95 
96 /***************************************************************************//**
97  * Enables the given module's bus clock.
98  ******************************************************************************/
sl_clock_manager_enable_bus_clock(sl_bus_clock_t module_bus_clock)99 sl_status_t sl_clock_manager_enable_bus_clock(sl_bus_clock_t module_bus_clock)
100 {
101   return sli_clock_manager_hal_enable_bus_clock(module_bus_clock, true);
102 }
103 
104 /***************************************************************************//**
105  * Disables the given module's bus clock.
106  ******************************************************************************/
sl_clock_manager_disable_bus_clock(sl_bus_clock_t module_bus_clock)107 sl_status_t sl_clock_manager_disable_bus_clock(sl_bus_clock_t module_bus_clock)
108 {
109   return sli_clock_manager_hal_enable_bus_clock(module_bus_clock, false);
110 }
111 
112 /***************************************************************************//**
113  * Configures one clock export output with specified clock source.
114  ******************************************************************************/
sl_clock_manager_set_gpio_clock_output(sl_clock_manager_export_clock_source_t export_clock_source,sl_clock_manager_export_clock_output_select_t output_select,uint16_t hfexp_divider,uint32_t port,uint32_t pin)115 sl_status_t sl_clock_manager_set_gpio_clock_output(sl_clock_manager_export_clock_source_t export_clock_source,
116                                                    sl_clock_manager_export_clock_output_select_t output_select,
117                                                    uint16_t hfexp_divider,
118                                                    uint32_t port,
119                                                    uint32_t pin)
120 {
121   return sli_clock_manager_hal_set_gpio_clock_output(export_clock_source, output_select, hfexp_divider, port, pin);
122 }
123 
124 /***************************************************************************//**
125  * Sets the RC oscillator frequency tuning control.
126  ******************************************************************************/
sl_clock_manager_set_rc_oscillator_calibration(sl_oscillator_t oscillator,uint32_t val)127 sl_status_t sl_clock_manager_set_rc_oscillator_calibration(sl_oscillator_t oscillator,
128                                                            uint32_t        val)
129 {
130   return sli_clock_manager_hal_set_rc_oscillator_calibration(oscillator, val);
131 }
132 
133 /***************************************************************************//**
134  * Gets the RC oscillator frequency tuning setting.
135  ******************************************************************************/
sl_clock_manager_get_rc_oscillator_calibration(sl_oscillator_t oscillator,uint32_t * val)136 sl_status_t sl_clock_manager_get_rc_oscillator_calibration(sl_oscillator_t oscillator,
137                                                            uint32_t        *val)
138 {
139   if (val == NULL) {
140     return SL_STATUS_NULL_POINTER;
141   }
142   return sli_clock_manager_hal_get_rc_oscillator_calibration(oscillator, val);
143 }
144 
145 /***************************************************************************//**
146  * Sets the HFXO calibration value.
147  ******************************************************************************/
sl_clock_manager_set_hfxo_calibration(uint32_t val)148 sl_status_t sl_clock_manager_set_hfxo_calibration(uint32_t val)
149 {
150   return sli_clock_manager_hal_set_hfxo_calibration(val);
151 }
152 
153 /***************************************************************************//**
154  * Gets the HFXO calibration value.
155  ******************************************************************************/
sl_clock_manager_get_hfxo_calibration(uint32_t * val)156 sl_status_t sl_clock_manager_get_hfxo_calibration(uint32_t *val)
157 {
158   if (val == NULL) {
159     return SL_STATUS_NULL_POINTER;
160   }
161   return sli_clock_manager_hal_get_hfxo_calibration(val);
162 }
163 
164 /***************************************************************************//**
165  * Sets the HFXO CTUNE setting.
166  ******************************************************************************/
slx_clock_manager_hfxo_set_ctune(uint32_t ctune)167 sl_status_t slx_clock_manager_hfxo_set_ctune(uint32_t ctune)
168 {
169   return sli_clock_manager_hal_hfxo_set_ctune(ctune);
170 }
171 
172 /***************************************************************************//**
173  * Gets the HFXO CTUNE setting.
174  ******************************************************************************/
slx_clock_manager_hfxo_get_ctune(uint32_t * ctune)175 sl_status_t slx_clock_manager_hfxo_get_ctune(uint32_t *ctune)
176 {
177   if (ctune == NULL) {
178     return SL_STATUS_NULL_POINTER;
179   }
180   return sli_clock_manager_hal_hfxo_get_ctune(ctune);
181 }
182 
183 /***************************************************************************//**
184  * Updates the tuning capacitances and calibrate the Core Bias Current.
185  ******************************************************************************/
slx_clock_manager_hfxo_calibrate_ctune(uint32_t ctune)186 sl_status_t slx_clock_manager_hfxo_calibrate_ctune(uint32_t ctune)
187 {
188   return sli_clock_manager_hal_hfxo_calibrate_ctune(ctune);
189 }
190 
191 /***************************************************************************//**
192  * Sets the LFXO frequency tuning control.
193  ******************************************************************************/
sl_clock_manager_set_lfxo_calibration(uint32_t val)194 sl_status_t sl_clock_manager_set_lfxo_calibration(uint32_t val)
195 {
196   return sli_clock_manager_hal_set_lfxo_calibration(val);
197 }
198 
199 /***************************************************************************//**
200  * Gets the LFXO frequency tuning setting.
201  ******************************************************************************/
sl_clock_manager_get_lfxo_calibration(uint32_t * val)202 sl_status_t sl_clock_manager_get_lfxo_calibration(uint32_t *val)
203 {
204   if (val == NULL) {
205     return SL_STATUS_NULL_POINTER;
206   }
207   return sli_clock_manager_hal_get_lfxo_calibration(val);
208 }
209 
210 /***************************************************************************//**
211  * Configures the RCO calibration.
212  ******************************************************************************/
sl_clock_manager_configure_rco_calibration(uint32_t cycles,sl_clock_manager_clock_calibration_t down_counter_selection,sl_clock_manager_clock_calibration_t up_counter_selection,bool continuous_calibration)213 sl_status_t sl_clock_manager_configure_rco_calibration(uint32_t cycles,
214                                                        sl_clock_manager_clock_calibration_t down_counter_selection,
215                                                        sl_clock_manager_clock_calibration_t up_counter_selection,
216                                                        bool continuous_calibration)
217 {
218   return sli_clock_manager_hal_configure_rco_calibration(cycles, down_counter_selection, up_counter_selection, continuous_calibration);
219 }
220 
221 /***************************************************************************//**
222  * Starts the RCO calibration.
223  ******************************************************************************/
sl_clock_manager_start_rco_calibration(void)224 void sl_clock_manager_start_rco_calibration(void)
225 {
226   sli_clock_manager_hal_start_rco_calibration();
227 }
228 
229 /***************************************************************************//**
230  * Stops the RCO calibration.
231  ******************************************************************************/
sl_clock_manager_stop_rco_calibration(void)232 void sl_clock_manager_stop_rco_calibration(void)
233 {
234   sli_clock_manager_hal_stop_rco_calibration();
235 }
236 
237 /***************************************************************************//**
238  * Waits for the RCO calibration to finish.
239  ******************************************************************************/
sl_clock_manager_wait_rco_calibration(void)240 void sl_clock_manager_wait_rco_calibration(void)
241 {
242   sli_clock_manager_hal_wait_rco_calibration();
243 }
244 
245 /***************************************************************************//**
246  * Gets calibration count value.
247  ******************************************************************************/
sl_clock_manager_get_rco_calibration_count(uint32_t * count)248 sl_status_t sl_clock_manager_get_rco_calibration_count(uint32_t *count)
249 {
250   if (count == NULL) {
251     return SL_STATUS_NULL_POINTER;
252   }
253 
254   return sli_clock_manager_hal_get_rco_calibration_count(count);
255 }
256 
257 /***************************************************************************//**
258  * Sets SYSCLK clock source.
259  ******************************************************************************/
sli_clock_manager_set_sysclk_source(sl_oscillator_t source)260 sl_status_t sli_clock_manager_set_sysclk_source(sl_oscillator_t source)
261 {
262   return sli_clock_manager_hal_set_sysclk_source(source);
263 }
264 
265 /***************************************************************************//**
266  * Gets SYSCLK clock source.
267  ******************************************************************************/
sli_clock_manager_get_sysclk_source(sl_oscillator_t * source)268 sl_status_t sli_clock_manager_get_sysclk_source(sl_oscillator_t *source)
269 {
270   if (source == NULL) {
271     return SL_STATUS_NULL_POINTER;
272   }
273 
274   return sli_clock_manager_hal_get_sysclk_source(source);
275 }
276 
277 /***************************************************************************//**
278  * Waits for USBPLL clock to be ready.
279  ******************************************************************************/
sl_clock_manager_wait_usbpll(void)280 sl_status_t sl_clock_manager_wait_usbpll(void)
281 {
282   return sli_clock_manager_hal_wait_usbpll();
283 }
284 
285 /***************************************************************************//**
286  * When this callback function is called, it means that HFXO failed twice in
287  * a row to start with normal configurations. This may mean that there is a
288  * bad crystal. When getting this callback, HFXO is running but its properties
289  * (frequency, precision) are not guaranteed. This should be considered as an
290  * error situation.
291  ******************************************************************************/
sl_clock_manager_hfxo_notify_consecutive_failed_startups(void)292 __WEAK void sl_clock_manager_hfxo_notify_consecutive_failed_startups(void)
293 {
294   EFM_ASSERT(false);
295 }
296