1 /*
2 * Copyright 2021-2022 NXP
3 *
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_clock.h"
9
10 /*
11 * $Coverage Justification Reference$
12 *
13 * $Justification clock_c_ref_1$
14 * The platform can select only four clock sources.
15 *
16 * $Justification clock_c_ref_2$
17 * After the board starts, the SIRC clock source is always enable and valid.
18 *
19 * $Justification clock_c_ref_3$
20 * During the init FIRC process, the De-init Firc is first performed.
21 * In this process, the successful De-init will Write One to clear the
22 * FIRCERR bit of the FIRCCSR register.And trim, has only two modes to
23 * choose from, and the setting trim mode is always successful.
24 *
25 * $Justification clock_c_ref_4$
26 * After the board starts, the FRO192M output clock is always valid.
27 *
28 */
29
30 /*******************************************************************************
31 * Definitions
32 ******************************************************************************/
33 /* Component ID definition, used by tools. */
34 #ifndef FSL_COMPONENT_ID
35 #define FSL_COMPONENT_ID "platform.drivers.clock"
36 #endif
37
38 /*! @brief Slow IRC clock frequency. */
39 #define SCG_SIRC_FREQ 6000000U
40 /*! @brief Get the RANGE value of the Fast IRC. */
41 #define SCG_FIRCCFG_RANGE_VAL ((CLOCK_REG(&SCG0->FIRCCFG) & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT)
42 /*! @brief Get the value of each field in MRCC register. */
43 #define MRCC_MUX_VAL(reg) (((reg)&MRCC_MUX_MASK) >> MRCC_MUX_SHIFT)
44 /*! @brief Get the POSTDIV_SEL value of the FRO192M. */
45 #define FRO192M_FROCCSR_POSTDIV_SEL_VAL \
46 ((CLOCK_REG(&FRO192M0->FROCCSR) & FRO192M_FROCCSR_POSTDIV_SEL_MASK) >> FRO192M_FROCCSR_POSTDIV_SEL_SHIFT)
47
48 /*******************************************************************************
49 * Variables
50 ******************************************************************************/
51
52 /*! @brief External XTAL0 (OSC0) clock frequency. */
53 volatile uint32_t g_xtal0Freq;
54 /*! @brief External XTAL32K clock frequency. */
55 volatile uint32_t g_xtal32Freq;
56
57 /*******************************************************************************
58 * Prototypes
59 ******************************************************************************/
60
61 /*******************************************************************************
62 * Code
63 ******************************************************************************/
64
65 /*!
66 * brief Get the flash clock frequency.
67 *
68 * return Clock frequency in Hz.
69 */
CLOCK_GetFlashClkFreq(void)70 uint32_t CLOCK_GetFlashClkFreq(void)
71 {
72 return CLOCK_GetSysClkFreq(kSCG_SysClkSlow);
73 }
74
75 /*!
76 * brief Get the bus clock frequency.
77 *
78 * return Clock frequency in Hz.
79 */
CLOCK_GetBusClkFreq(void)80 uint32_t CLOCK_GetBusClkFreq(void)
81 {
82 return CLOCK_GetSysClkFreq(kSCG_SysClkBus);
83 }
84
85 /*!
86 * brief Get the platform clock frequency.
87 *
88 * return Clock frequency in Hz.
89 */
CLOCK_GetPlatClkFreq(void)90 uint32_t CLOCK_GetPlatClkFreq(void)
91 {
92 return CLOCK_GetSysClkFreq(kSCG_SysClkCore);
93 }
94
95 /*!
96 * brief Get the core clock or system clock frequency.
97 *
98 * return Clock frequency in Hz.
99 */
CLOCK_GetCoreSysClkFreq(void)100 uint32_t CLOCK_GetCoreSysClkFreq(void)
101 {
102 return CLOCK_GetSysClkFreq(kSCG_SysClkCore);
103 }
104
105 /*!
106 * brief Gets the clock frequency for a specific clock name.
107 *
108 * This function checks the current clock configurations and then calculates
109 * the clock frequency for a specific clock name defined in clock_name_t.
110 *
111 * param clockName Clock names defined in clock_name_t
112 * return Clock frequency value in hertz
113 */
CLOCK_GetFreq(clock_name_t clockName)114 uint32_t CLOCK_GetFreq(clock_name_t clockName)
115 {
116 uint32_t freq;
117
118 switch (clockName)
119 {
120 /* System layer clock. */
121 case kCLOCK_CoreSysClk:
122 case kCLOCK_PlatClk:
123 freq = CLOCK_GetSysClkFreq(kSCG_SysClkCore);
124 break;
125 case kCLOCK_BusClk:
126 freq = CLOCK_GetSysClkFreq(kSCG_SysClkBus);
127 break;
128 case kCLOCK_SlowClk:
129 freq = CLOCK_GetSysClkFreq(kSCG_SysClkSlow);
130 break;
131 /* Original clock source. */
132 case kCLOCK_SysClk:
133 case kCLOCK_ScgSysOscClk:
134 freq = CLOCK_GetSysOscFreq();
135 break;
136 case kCLOCK_ScgSircClk:
137 freq = CLOCK_GetSircFreq();
138 break;
139 case kCLOCK_ScgFircClk:
140 freq = CLOCK_GetFircFreq();
141 break;
142 case kCLOCK_RtcOscClk:
143 freq = CLOCK_GetRtcOscFreq();
144 break;
145 default:
146 freq = 0U;
147 break;
148 }
149 return freq;
150 }
151
152 /*!
153 * brief Gets the functional clock frequency for a specific IP module.
154 *
155 * This function gets the IP module's functional clock frequency based on MRCC
156 * registers. It is only used for the IP modules which could select clock source
157 * by MRCC[MUX].
158 *
159 * param name Which peripheral to get, see \ref clock_ip_name_t.
160 * return Clock frequency value in Hz
161 */
CLOCK_GetIpFreq(clock_ip_name_t name)162 uint32_t CLOCK_GetIpFreq(clock_ip_name_t name)
163 {
164 if (kCLOCK_NOGATE == name)
165 {
166 return 0U;
167 }
168
169 uint32_t reg = CLOCK_REG(name);
170 uint32_t freq;
171
172 assert(reg & MRCC_PR_MASK);
173
174 switch (name)
175 {
176 case kCLOCK_Lpi2c0:
177 case kCLOCK_Lpi2c1:
178 case kCLOCK_I3c0:
179 case kCLOCK_Lpspi0:
180 case kCLOCK_Lpspi1:
181 case kCLOCK_Lpit0:
182 case kCLOCK_Lpadc0:
183 case kCLOCK_Flexio0:
184 switch (MRCC_MUX_VAL(reg))
185 {
186 case (uint32_t)kCLOCK_IpSrcFro6M:
187 freq = CLOCK_GetSircFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
188 break;
189 case (uint32_t)kCLOCK_IpSrcFro192M:
190 freq = CLOCK_GetFircFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
191 break;
192 case (uint32_t)kCLOCK_IpSrcSoscClk:
193 freq = CLOCK_GetSysOscFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
194 break;
195 default:
196 freq = 0U;
197 break;
198 }
199 break;
200 case kCLOCK_Lpuart0:
201 case kCLOCK_Lpuart1:
202 case kCLOCK_Tpm0:
203 case kCLOCK_Tpm1:
204 switch (MRCC_MUX_VAL(reg))
205 {
206 case (uint32_t)kCLOCK_IpSrcFro6M:
207 freq = CLOCK_GetSircFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
208 break;
209 case (uint32_t)kCLOCK_IpSrcFro192M:
210 freq = CLOCK_GetFircFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
211 break;
212 case (uint32_t)kCLOCK_IpSrcSoscClk:
213 freq = CLOCK_GetSysOscFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
214 break;
215 case (uint32_t)kCLOCK_IpSrc32kClk:
216 freq = CLOCK_GetRtcOscFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
217 break;
218 default:
219 freq = 0U;
220 break;
221 }
222 break;
223 case kCLOCK_Can0:
224 case kCLOCK_Can1:
225 switch (MRCC_MUX_VAL(reg))
226 {
227 case (uint32_t)kCLOCK_IpSrcFro192M:
228 freq = CLOCK_GetFircFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
229 break;
230 case (uint32_t)kCLOCK_IpSrcSoscClk:
231 freq = CLOCK_GetSysOscFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
232 break;
233 default:
234 freq = 0U;
235 break;
236 }
237 break;
238 default:
239 freq = 0U;
240 break;
241 }
242
243 return freq;
244 }
245
246 /*!
247 * brief Gets the SCG system clock frequency.
248 *
249 * This function gets the SCG system clock frequency. These clocks are used for
250 * core, platform, external, and bus clock domains.
251 *
252 * param type Which type of clock to get, core clock or slow clock.
253 * return Clock frequency.
254 */
CLOCK_GetSysClkFreq(scg_sys_clk_t type)255 uint32_t CLOCK_GetSysClkFreq(scg_sys_clk_t type)
256 {
257 uint32_t freq;
258
259 scg_sys_clk_config_t sysClkConfig;
260
261 CLOCK_GetCurSysClkConfig(&sysClkConfig); /* Get the main clock for SoC platform. */
262
263 /*
264 * $Branch Coverage Justification$
265 * ((sysClkConfig.src) != (kSCG_SysClkSrcSysOsc || kSCG_SysClkSrcSirc ||
266 * kSCG_SysClkSrcFirc || kSCG_SysClkSrcRosc)) not covered.
267 * $ref clock_c_ref_1$.
268 */
269 switch ((scg_sys_clk_src_t)sysClkConfig.src)
270 {
271 case kSCG_SysClkSrcSysOsc:
272 freq = CLOCK_GetSysOscFreq();
273 break;
274 case kSCG_SysClkSrcSirc:
275 freq = CLOCK_GetSircFreq();
276 break;
277 case kSCG_SysClkSrcFirc:
278 freq = CLOCK_GetFircFreq();
279 break;
280 case kSCG_SysClkSrcRosc:
281 freq = CLOCK_GetRtcOscFreq();
282 break;
283 default:
284 freq = 24000000U;
285 break;
286 }
287
288 freq /= (sysClkConfig.divCore + 1U); /* Divided by the DIVCORE firstly. */
289
290 switch (type)
291 {
292 case kSCG_SysClkSlow:
293 freq /= (sysClkConfig.divSlow + 1U);
294 break;
295 case kSCG_SysClkBus:
296 freq /= (sysClkConfig.divBus + 1U);
297 break;
298 case kSCG_SysClkPlatform:
299 case kSCG_SysClkCore:
300 break;
301 default:
302 assert(false);
303 break;
304 }
305
306 return freq;
307 }
308
309 /*!
310 * brief Initializes the SCG system OSC.
311 *
312 * This function enables the SCG system OSC clock according to the
313 * configuration.
314 *
315 * param config Pointer to the configuration structure.
316 * retval kStatus_Success System OSC is initialized.
317 * retval kStatus_SCG_Busy System OSC has been enabled and is used by the system clock.
318 * retval kStatus_ReadOnly System OSC control register is locked.
319 *
320 * note This function can't detect whether the system OSC has been enabled and
321 * used by an IP.
322 */
CLOCK_InitSysOsc(const scg_sosc_config_t * config)323 status_t CLOCK_InitSysOsc(const scg_sosc_config_t *config)
324 {
325 assert(config);
326 status_t status;
327
328 /* De-init the SOSC first. */
329 status = CLOCK_DeinitSysOsc();
330
331 if (kStatus_Success != status)
332 {
333 return status;
334 }
335
336 CLOCK_REG(&SCG0->SOSCCSR) = (uint32_t)config->enableMode | SCG_SOSCCSR_SOSCEN_MASK;
337
338 CLOCK_SetSysOscMonitorMode(config->monitorMode);
339
340 /* Wait for SOSC clock to be valid. */
341 while ((CLOCK_REG(&SCG0->SOSCCSR) & SCG_SOSCCSR_SOSCVLD_MASK) != SCG_SOSCCSR_SOSCVLD_MASK)
342 {
343 }
344
345 return (status_t)kStatus_Success;
346 }
347
348 /*!
349 * brief De-initializes the SCG system OSC.
350 *
351 * This function disables the SCG system OSC clock.
352 *
353 * retval kStatus_Success System OSC is deinitialized.
354 * retval kStatus_SCG_Busy System OSC is used by the system clock.
355 * retval kStatus_ReadOnly System OSC control register is locked.
356 *
357 * note This function can't detect whether the system OSC is used by an IP.
358 */
CLOCK_DeinitSysOsc(void)359 status_t CLOCK_DeinitSysOsc(void)
360 {
361 uint32_t reg = CLOCK_REG(&SCG0->SOSCCSR);
362
363 /* If clock is used by system, return error. */
364 if ((reg & SCG_SOSCCSR_SOSCSEL_MASK) == SCG_SOSCCSR_SOSCSEL_MASK)
365 {
366 return (status_t)kStatus_SCG_Busy;
367 }
368
369 /* If configure register is locked, return error. */
370 if ((reg & SCG_SOSCCSR_LK_MASK) == SCG_SOSCCSR_LK_MASK)
371 {
372 return (status_t)kStatus_ReadOnly;
373 }
374
375 CLOCK_REG(&SCG0->SOSCCSR) = SCG_SOSCCSR_SOSCERR_MASK;
376
377 return (status_t)kStatus_Success;
378 }
379
380 /*!
381 * brief Gets the SCG system oscillator clock frequency (SOSC).
382 *
383 * return Clock frequency; If the clock is invalid, returns 0.
384 */
CLOCK_GetSysOscFreq(void)385 uint32_t CLOCK_GetSysOscFreq(void)
386 {
387 if ((CLOCK_REG(&SCG0->SOSCCSR) & SCG_SOSCCSR_SOSCVLD_MASK) ==
388 SCG_SOSCCSR_SOSCVLD_MASK) /* System OSC clock is valid. */
389 {
390 /* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */
391 assert(g_xtal0Freq);
392 return g_xtal0Freq;
393 }
394 else
395 {
396 return 0U;
397 }
398 }
399
400 /*!
401 * brief Initializes the SCG slow IRC clock.
402 *
403 * This function enables the SCG slow IRC clock according to the
404 * configuration.
405 *
406 * param config Pointer to the configuration structure.
407 * retval kStatus_Success SIRC is initialized.
408 * retval kStatus_SCG_Busy SIRC has been enabled and is used by system clock.
409 * retval kStatus_ReadOnly SIRC control register is locked.
410 *
411 * note This function can't detect whether the system OSC has been enabled and
412 * used by an IP.
413 */
CLOCK_InitSirc(const scg_sirc_config_t * config)414 status_t CLOCK_InitSirc(const scg_sirc_config_t *config)
415 {
416 assert(config);
417
418 status_t status;
419
420 /* De-init the SIRC first. */
421 status = CLOCK_DeinitSirc();
422
423 if (kStatus_Success != status)
424 {
425 return status;
426 }
427
428 CLOCK_REG(&SCG0->SIRCCSR) = (uint32_t)config->enableMode;
429
430 /* Wait for SIRC clock to be valid. */
431
432 /*
433 * $Branch Coverage Justification$
434 * (CLOCK_REG(&SCG0->SIRCCSR) & SCG_SIRCCSR_SIRCVLD_MASK) != SCG_SIRCCSR_SIRCVLD_MASK
435 * not covered.
436 * $ref clock_c_ref_2$.
437 */
438 while ((CLOCK_REG(&SCG0->SIRCCSR) & SCG_SIRCCSR_SIRCVLD_MASK) != SCG_SIRCCSR_SIRCVLD_MASK)
439 {
440 }
441
442 return (status_t)kStatus_Success;
443 }
444
445 /*!
446 * brief De-initializes the SCG slow IRC.
447 *
448 * This function disables the SCG slow IRC.
449 *
450 * retval kStatus_Success SIRC is deinitialized.
451 * retval kStatus_SCG_Busy SIRC is used by system clock.
452 * retval kStatus_ReadOnly SIRC control register is locked.
453 *
454 * note This function can't detect whether the SIRC is used by an IP.
455 */
CLOCK_DeinitSirc(void)456 status_t CLOCK_DeinitSirc(void)
457 {
458 uint32_t reg = CLOCK_REG(&SCG0->SIRCCSR);
459
460 /* If clock is used by system, return error. */
461 if ((reg & SCG_SIRCCSR_SIRCSEL_MASK) == SCG_SIRCCSR_SIRCSEL_MASK)
462 {
463 return (status_t)kStatus_SCG_Busy;
464 }
465
466 /* If configure register is locked, return error. */
467 if ((reg & SCG_SIRCCSR_LK_MASK) == SCG_SIRCCSR_LK_MASK)
468 {
469 return (status_t)kStatus_ReadOnly;
470 }
471
472 CLOCK_REG(&SCG0->SIRCCSR) = 0U;
473
474 return (status_t)kStatus_Success;
475 }
476
477 /*!
478 * brief Gets the SCG SIRC clock frequency.
479 *
480 * return Clock frequency; If the clock is invalid, returns 0.
481 */
CLOCK_GetSircFreq(void)482 uint32_t CLOCK_GetSircFreq(void)
483 {
484 /*
485 * $Branch Coverage Justification$
486 * (CLOCK_REG(&SCG0->SIRCCSR) & SCG_SIRCCSR_SIRCVLD_MASK) != SCG_SIRCCSR_SIRCVLD_MASK
487 * not covered.
488 * $ref clock_c_ref_2$.
489 */
490 if ((CLOCK_REG(&SCG0->SIRCCSR) & SCG_SIRCCSR_SIRCVLD_MASK) == SCG_SIRCCSR_SIRCVLD_MASK) /* SIRC is valid. */
491 {
492 return SCG_SIRC_FREQ;
493 }
494 else
495 {
496 return 0U;
497 }
498 }
499
500 /*!
501 * brief Initializes the SCG fast IRC clock.
502 *
503 * This function enables the SCG fast IRC clock according to the configuration.
504 *
505 * param config Pointer to the configuration structure.
506 * retval kStatus_Success FIRC is initialized.
507 * retval kStatus_SCG_Busy FIRC has been enabled and is used by the system clock.
508 * retval kStatus_ReadOnly FIRC control register is locked.
509 *
510 * note This function can't detect whether the FIRC has been enabled and
511 * used by an IP.
512 */
CLOCK_InitFirc(const scg_firc_config_t * config)513 status_t CLOCK_InitFirc(const scg_firc_config_t *config)
514 {
515 assert(config);
516
517 status_t status;
518
519 /* De-init the FIRC first. */
520 status = CLOCK_DeinitFirc();
521
522 if (kStatus_Success != status)
523 {
524 return status;
525 }
526
527 CLOCK_REG(&SCG0->FIRCCFG) = SCG_FIRCCFG_RANGE(config->range);
528
529 if (config->trimConfig != NULL)
530 {
531 CLOCK_REG(&SCG0->FIRCTCFG) =
532 SCG_FIRCTCFG_TRIMDIV(config->trimConfig->trimDiv) | SCG_FIRCTCFG_TRIMSRC(config->trimConfig->trimSrc);
533
534 if (kSCG_FircTrimNonUpdate == config->trimConfig->trimMode)
535 {
536 CLOCK_REG(&SCG0->FIRCSTAT) = SCG_FIRCSTAT_TRIMFINE(config->trimConfig->trimFine);
537 }
538
539 /* Set trim mode. */
540 CLOCK_REG(&SCG0->FIRCCSR) = (uint32_t)config->trimConfig->trimMode;
541
542 /*
543 * $Branch Coverage Justification$
544 * (CLOCK_REG(&SCG0->FIRCCSR) & SCG_FIRCCSR_FIRCERR_MASK) == SCG_FIRCCSR_FIRCERR_MASK
545 * not covered.
546 * $ref clock_c_ref_3$.
547 */
548 if ((CLOCK_REG(&SCG0->FIRCCSR) & SCG_FIRCCSR_FIRCERR_MASK) == SCG_FIRCCSR_FIRCERR_MASK)
549 {
550 return (status_t)kStatus_Fail;
551 }
552 }
553
554 CLOCK_REG(&SCG0->FIRCCSR) |= (SCG_FIRCCSR_FIRCEN_MASK | (uint32_t)config->enableMode);
555
556 /* Wait for FIRC clock to be valid. */
557 while ((CLOCK_REG(&SCG0->FIRCCSR) & SCG_FIRCCSR_FIRCVLD_MASK) != SCG_FIRCCSR_FIRCVLD_MASK)
558 {
559 }
560
561 return (status_t)kStatus_Success;
562 }
563
564 /*!
565 * brief De-initializes the SCG fast IRC.
566 *
567 * This function disables the SCG fast IRC.
568 *
569 * retval kStatus_Success FIRC is deinitialized.
570 * retval kStatus_SCG_Busy FIRC is used by the system clock.
571 * retval kStatus_ReadOnly FIRC control register is locked.
572 *
573 * note This function can't detect whether the FIRC is used by an IP.
574 */
CLOCK_DeinitFirc(void)575 status_t CLOCK_DeinitFirc(void)
576 {
577 uint32_t reg = CLOCK_REG(&SCG0->FIRCCSR);
578
579 /* If clock is used by system, return error. */
580 if ((reg & SCG_FIRCCSR_FIRCSEL_MASK) == SCG_FIRCCSR_FIRCSEL_MASK)
581 {
582 return (status_t)kStatus_SCG_Busy;
583 }
584
585 /* If configure register is locked, return error. */
586 if ((reg & SCG_FIRCCSR_LK_MASK) == SCG_FIRCCSR_LK_MASK)
587 {
588 return (status_t)kStatus_ReadOnly;
589 }
590
591 CLOCK_REG(&SCG0->FIRCCSR) = SCG_FIRCCSR_FIRCERR_MASK;
592
593 return (status_t)kStatus_Success;
594 }
595
596 /*!
597 * brief Gets the SCG FIRC clock frequency.
598 *
599 * return Clock frequency; If the clock is invalid, returns 0.
600 */
CLOCK_GetFircFreq(void)601 uint32_t CLOCK_GetFircFreq(void)
602 {
603 static const uint32_t fircFreq[] = {48000000U, 64000000U, 96000000U, 192000000U};
604
605 if ((CLOCK_REG(&SCG0->FIRCCSR) & SCG_FIRCCSR_FIRCVLD_MASK) == SCG_FIRCCSR_FIRCVLD_MASK) /* FIRC is valid. */
606 {
607 return fircFreq[SCG_FIRCCFG_RANGE_VAL];
608 }
609 else
610 {
611 return 0U;
612 }
613 }
614
615 /*!
616 * brief Initializes the SCG ROSC.
617 *
618 * This function enables the SCG ROSC clock according to the
619 * configuration.
620 *
621 * param config Pointer to the configuration structure.
622 * retval kStatus_Success ROSC is initialized.
623 * retval kStatus_SCG_Busy ROSC has been enabled and is used by the system clock.
624 * retval kStatus_ReadOnly ROSC control register is locked.
625 *
626 * note This function can't detect whether the system OSC has been enabled and
627 * used by an IP.
628 */
CLOCK_InitRosc(const scg_rosc_config_t * config)629 status_t CLOCK_InitRosc(const scg_rosc_config_t *config)
630 {
631 assert(config);
632 status_t status;
633
634 /* De-init the ROSC first. */
635 status = CLOCK_DeinitRosc();
636
637 if (kStatus_Success != status)
638 {
639 return status;
640 }
641
642 CLOCK_SetRoscMonitorMode(config->monitorMode);
643
644 /* Wait for ROSC clock to be valid. */
645 while ((CLOCK_REG(&SCG0->ROSCCSR) & SCG_ROSCCSR_ROSCVLD_MASK) != SCG_ROSCCSR_ROSCVLD_MASK)
646 {
647 }
648
649 return (status_t)kStatus_Success;
650 }
651
652 /*!
653 * brief De-initializes the SCG ROSC.
654 *
655 * This function disables the SCG ROSC clock.
656 *
657 * retval kStatus_Success System OSC is deinitialized.
658 * retval kStatus_SCG_Busy System OSC is used by the system clock.
659 * retval kStatus_ReadOnly System OSC control register is locked.
660 *
661 * note This function can't detect whether the ROSC is used by an IP.
662 */
CLOCK_DeinitRosc(void)663 status_t CLOCK_DeinitRosc(void)
664 {
665 uint32_t reg = CLOCK_REG(&SCG0->ROSCCSR);
666
667 /* If clock is used by system, return error. */
668 if ((reg & SCG_ROSCCSR_ROSCSEL_MASK) == SCG_ROSCCSR_ROSCSEL_MASK)
669 {
670 return (status_t)kStatus_SCG_Busy;
671 }
672
673 /* If configure register is locked, return error. */
674 if ((reg & SCG_ROSCCSR_LK_MASK) == SCG_ROSCCSR_LK_MASK)
675 {
676 return (status_t)kStatus_ReadOnly;
677 }
678
679 CLOCK_REG(&SCG0->ROSCCSR) = SCG_ROSCCSR_ROSCERR_MASK;
680
681 return (status_t)kStatus_Success;
682 }
683
684 /*!
685 * @brief Gets the SCG RTC OSC clock frequency.
686 *
687 * @return Clock frequency; If the clock is invalid, returns 0.
688 */
CLOCK_GetRtcOscFreq(void)689 uint32_t CLOCK_GetRtcOscFreq(void)
690 {
691 if ((CLOCK_REG(&SCG0->ROSCCSR) & SCG_ROSCCSR_ROSCVLD_MASK) ==
692 SCG_ROSCCSR_ROSCVLD_MASK) /* RTC OSC clock is valid. */
693 {
694 /* Please call CLOCK_SetXtal32Freq base on board setting before using RTC OSC clock. */
695 assert(g_xtal32Freq);
696 return g_xtal32Freq;
697 }
698 else
699 {
700 return 0U;
701 }
702 }
703
704 /*!
705 * @brief Initializes the FRO192M clock for the Radio Mode Controller.
706 *
707 * This function configure the RF FRO192M clock according to the configuration.
708 *
709 * @param config Pointer to the configuration structure.
710 * @retval kStatus_Success RF FRO192M is configured.
711 */
CLOCK_InitRfFro192M(const fro192m_rf_clk_config_t * config)712 status_t CLOCK_InitRfFro192M(const fro192m_rf_clk_config_t *config)
713 {
714 assert(config->range <= kFro192M_Range64M);
715 assert(config->apb_rfcmc_div <= kFro192M_ClkDivBy8);
716
717 CLOCK_REG(&FRO192M0->FROCCSR) = FRO192M_FROCCSR_POSTDIV_SEL(config->range);
718 CLOCK_REG(&FRO192M0->FRODIV) = FRO192M_FRODIV_FRODIV(config->apb_rfcmc_div);
719
720 /* Wait for RF FRO192M clock to be valid. */
721
722 /*
723 * $Branch Coverage Justification$
724 * (CLOCK_REG(&FRO192M0->FROCCSR) & FRO192M_FROCCSR_VALID_MASK) != FRO192M_FROCCSR_VALID_MASK
725 * not covered.
726 * $ref clock_c_ref_4$.
727 */
728 while ((CLOCK_REG(&FRO192M0->FROCCSR) & FRO192M_FROCCSR_VALID_MASK) != FRO192M_FROCCSR_VALID_MASK)
729 {
730 }
731
732 return (status_t)kStatus_Success;
733 }
734
735 /*!
736 * @brief Gets the FRO192M clock frequency.
737 *
738 * @return Clock frequency; If the clock is invalid, returns 0.
739 */
CLOCK_GetRfFro192MFreq(void)740 uint32_t CLOCK_GetRfFro192MFreq(void)
741 {
742 static const uint32_t fro192mFreq[] = {16000000U, 24000000U, 32000000U, 48000000U, 64000000U};
743
744 /*
745 * $Branch Coverage Justification$
746 * (CLOCK_REG(&FRO192M0->FROCCSR) & FRO192M_FROCCSR_VALID_MASK) != FRO192M_FROCCSR_VALID_MASK
747 * not covered.
748 * $ref clock_c_ref_4$.
749 */
750 if ((CLOCK_REG(&FRO192M0->FROCCSR) & FRO192M_FROCCSR_VALID_MASK) == FRO192M_FROCCSR_VALID_MASK)
751 {
752 return fro192mFreq[FRO192M_FROCCSR_POSTDIV_SEL_VAL];
753 }
754 else
755 {
756 return 0U;
757 }
758 }
759