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