1 /*
2 * Copyright 2023, NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_clock.h"
9 /*******************************************************************************
10 * Definitions
11 ******************************************************************************/
12 /* Component ID definition, used by tools. */
13 #ifndef FSL_COMPONENT_ID
14 #define FSL_COMPONENT_ID "platform.drivers.clock"
15 #endif
16
17 /*******************************************************************************
18 * Variables
19 ******************************************************************************/
20 /** External clock rate on the CLKIN pin in Hz. If not used,
21 set this to 0. Otherwise, set it to the exact rate in Hz this pin is
22 being driven at. */
23 volatile static uint32_t s_Ext_Clk_Freq = 16000000U;
24
25 /*******************************************************************************
26 * Prototypes
27 ******************************************************************************/
28 /* Get FRO 12M Clk */
29 static uint32_t CLOCK_GetFro12MFreq(void);
30 /* Get CLK 1M Clk */
31 static uint32_t CLOCK_GetClk1MFreq(void);
32 /* Get HF FRO Clk */
33 static uint32_t CLOCK_GetFroHfFreq(void);
34 /* Get CLK 48M Clk */
35 static uint32_t CLOCK_GetClk48MFreq(void);
36 /* Get CLK 16K Clk */
37 static uint32_t CLOCK_GetClk16KFreq(uint8_t id);
38 /* Get EXT OSC Clk */
39 static uint32_t CLOCK_GetExtClkFreq(void);
40 /* Get Main_Clk */
41 uint32_t CLOCK_GetMainClk(void);
42 /* Get FRO_16K */
43 static uint32_t CLOCK_GetFRO16KFreq(void);
44
45 /* Check if DIV is halt */
CLOCK_IsDivHalt(uint32_t div_value)46 static inline bool CLOCK_IsDivHalt(uint32_t div_value)
47 {
48 if (0U != (div_value & (1UL << 30U)))
49 {
50 return true;
51 }
52 else
53 {
54 return false;
55 }
56 }
57
58 /*******************************************************************************
59 * Code
60 ******************************************************************************/
61
62 /* Clock Selection for IP */
63 /**
64 * brief Configure the clock selection muxes.
65 * param connection : Clock to be configured.
66 * return Nothing
67 */
CLOCK_AttachClk(clock_attach_id_t connection)68 void CLOCK_AttachClk(clock_attach_id_t connection)
69 {
70 const uint32_t reg_offset = CLK_ATTACH_REG_OFFSET(connection);
71 const uint32_t clk_sel = CLK_ATTACH_CLK_SEL(connection);
72
73 if (kNONE_to_NONE != connection)
74 {
75 CLOCK_SetClockSelect((clock_select_name_t)reg_offset, clk_sel);
76 }
77 }
78
79 /* Return the actual clock attach id */
80 /**
81 * brief Get the actual clock attach id.
82 * This fuction uses the offset in input attach id, then it reads the actual source value in
83 * the register and combine the offset to obtain an actual attach id.
84 * param connection : Clock attach id to get.
85 * return Clock source value.
86 */
CLOCK_GetClockAttachId(clock_attach_id_t connection)87 clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t connection)
88 {
89 const uint32_t reg_offset = CLK_ATTACH_REG_OFFSET(connection);
90 uint32_t actual_sel = 0U;
91 uint32_t clock_attach_id = 0U;
92
93 if (kNONE_to_NONE == connection)
94 {
95 return kNONE_to_NONE;
96 }
97
98 actual_sel = CLOCK_GetClockSelect((clock_select_name_t)reg_offset);
99 clock_attach_id = CLK_ATTACH_MUX(reg_offset, actual_sel);
100
101 return (clock_attach_id_t)clock_attach_id;
102 }
103
104 /* Set the clock selection value */
CLOCK_SetClockSelect(clock_select_name_t sel_name,uint32_t value)105 void CLOCK_SetClockSelect(clock_select_name_t sel_name, uint32_t value)
106 {
107 volatile uint32_t *pClkCtrl = (volatile uint32_t *)(MRCC0_BASE + (uint32_t)sel_name);
108 assert(sel_name <= kCLOCK_SelMax);
109
110 if (sel_name == kCLOCK_SelSCGSCS)
111 {
112 SCG0->RCCR = (SCG0->RCCR & ~(SCG_RCCR_SCS_MASK)) | SCG_RCCR_SCS(value);
113 while ((SCG0->CSR & SCG_CSR_SCS_MASK) != SCG_CSR_SCS(value))
114 {
115 }
116 }
117 else
118 {
119 /* Unlock clock configuration */
120 SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK;
121
122 *pClkCtrl = value;
123
124 /* Freeze clock configuration */
125 SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK;
126 }
127 }
128
129 /* Get the clock selection value */
CLOCK_GetClockSelect(clock_select_name_t sel_name)130 uint32_t CLOCK_GetClockSelect(clock_select_name_t sel_name)
131 {
132 volatile uint32_t *pClkCtrl = (volatile uint32_t *)(MRCC0_BASE + (uint32_t)sel_name);
133 uint32_t actual_sel = 0U;
134 assert(sel_name <= kCLOCK_SelMax);
135
136 if (sel_name == kCLOCK_SelSCGSCS)
137 {
138 actual_sel = (uint32_t)((SCG0->RCCR & SCG_RCCR_SCS_MASK) >> SCG_RCCR_SCS_SHIFT);
139 }
140 else
141 {
142 actual_sel = *pClkCtrl;
143 }
144
145 return actual_sel;
146 }
147
148 /* Set the clock divider value */
CLOCK_SetClockDiv(clock_div_name_t div_name,uint32_t value)149 void CLOCK_SetClockDiv(clock_div_name_t div_name, uint32_t value)
150 {
151 volatile uint32_t *pDivCtrl = (volatile uint32_t *)(MRCC0_BASE + (uint32_t)div_name);
152 assert(div_name <= kCLOCK_DivMax);
153
154 /* Unlock clock configuration */
155 SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK;
156
157 /* halt and reset clock dividers */
158 *pDivCtrl = 0x3UL << 29U;
159
160 if (value == 0U) /*!< halt */
161 {
162 *pDivCtrl |= (1UL << 30U);
163 }
164 else
165 {
166 *pDivCtrl = (value - 1U);
167 }
168
169 /* Freeze clock configuration */
170 SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK;
171 }
172
173 /* Get the clock divider value */
CLOCK_GetClockDiv(clock_div_name_t div_name)174 uint32_t CLOCK_GetClockDiv(clock_div_name_t div_name)
175 {
176 volatile uint32_t *pDivCtrl = (volatile uint32_t *)(MRCC0_BASE + (uint32_t)div_name);
177 assert(div_name <= kCLOCK_DivMax);
178
179 if (((*pDivCtrl) & (1UL << 30U)) != 0U)
180 {
181 return 0;
182 }
183 else
184 {
185 return ((*pDivCtrl & 0xFFU) + 1U);
186 }
187 }
188
189 /* Halt the clock divider value */
CLOCK_HaltClockDiv(clock_div_name_t div_name)190 void CLOCK_HaltClockDiv(clock_div_name_t div_name)
191 {
192 volatile uint32_t *pDivCtrl = (volatile uint32_t *)(MRCC0_BASE + (uint32_t)div_name);
193 assert(div_name <= kCLOCK_DivMax);
194
195 /* Unlock clock configuration */
196 SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK;
197
198 *pDivCtrl |= (1UL << 30U);
199
200 /* Freeze clock configuration */
201 SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK;
202 }
203
204 /* Initialize the FROHF to given frequency (48,64,96,192) */
CLOCK_SetupFROHFClocking(uint32_t iFreq)205 status_t CLOCK_SetupFROHFClocking(uint32_t iFreq)
206 {
207 uint8_t freq_select = 0x0U;
208 switch (iFreq)
209 {
210 case 48000000U:
211 freq_select = 1U;
212 break;
213 case 64000000U:
214 freq_select = 3U;
215 break;
216 case 96000000U:
217 freq_select = 5U;
218 break;
219 case 192000000U:
220 freq_select = 7U;
221 break;
222 default:
223 freq_select = 0xFU;
224 break;
225 }
226
227 if (0xFU == freq_select)
228 {
229 return kStatus_Fail;
230 }
231
232 /* Set FIRC frequency */
233 SCG0->FIRCCFG = SCG_FIRCCFG_FREQ_SEL(freq_select);
234
235 /* Unlock FIRCCSR */
236 SCG0->FIRCCSR &= ~SCG_FIRCCSR_LK_MASK;
237
238 /* Enable CLK 48 MHz clock for peripheral use */
239 SCG0->FIRCCSR |= SCG_FIRCCSR_FIRC_SCLK_PERIPH_EN_MASK;
240 /* Enable FIRC HF clock for peripheral use */
241 SCG0->FIRCCSR |= SCG_FIRCCSR_FIRC_FCLK_PERIPH_EN_MASK;
242 /* Enable FIRC */
243 SCG0->FIRCCSR |= SCG_FIRCCSR_FIRCEN_MASK;
244
245 /* Lock FIRCCSR */
246 SCG0->FIRCCSR |= SCG_FIRCCSR_LK_MASK;
247
248 /* Wait for FIRC clock to be valid. */
249 while ((SCG0->FIRCCSR & SCG_FIRCCSR_FIRCVLD_MASK) == 0U)
250 {
251 }
252
253 return kStatus_Success;
254 }
255
256 /* Initialize the FRO12M. */
CLOCK_SetupFRO12MClocking(void)257 status_t CLOCK_SetupFRO12MClocking(void)
258 {
259 /* Unlock SIRCCSR */
260 SCG0->SIRCCSR &= ~SCG_SIRCCSR_LK_MASK;
261
262 /* Enable FRO12M clock for peripheral use */
263 SCG0->SIRCCSR |= SCG_SIRCCSR_SIRC_CLK_PERIPH_EN_MASK;
264
265 /* Lock SIRCCSR */
266 SCG0->SIRCCSR |= SCG_SIRCCSR_LK_MASK;
267
268 /* Wait for SIRC clock to be valid. */
269 while ((SCG0->SIRCCSR & SCG_SIRCCSR_SIRCVLD_MASK) == 0U)
270 {
271 }
272
273 return kStatus_Success;
274 }
275
276 /*!
277 * brief Initialize the FRO16K.
278 * This function turns on FRO16K.
279 * return returns success or fail status.
280 */
CLOCK_SetupFRO16KClocking(uint8_t clk_16k_enable_mask)281 status_t CLOCK_SetupFRO16KClocking(uint8_t clk_16k_enable_mask)
282 {
283 VBAT0->FROCTLA |= VBAT_FROCTLA_FRO_EN_MASK;
284 VBAT0->FROLCKA |= VBAT_FROLCKA_LOCK_MASK;
285
286 /* enable clk_16k output clock to corresponding modules according to the enable_mask. */
287 VBAT0->FROCLKE |= VBAT_FROCLKE_CLKE(((uint32_t)clk_16k_enable_mask));
288
289 return kStatus_Success;
290 }
291
292 /*!
293 * brief Initialize the external osc clock to given frequency.
294 * param iFreq : Desired frequency (must be equal to exact rate in Hz)
295 * return returns success or fail status.
296 */
CLOCK_SetupExtClocking(uint32_t iFreq)297 status_t CLOCK_SetupExtClocking(uint32_t iFreq)
298 {
299 uint8_t range = 0U;
300
301 if ((iFreq >= 8000000U) && (iFreq < 16000000U))
302 {
303 range = 0U;
304 }
305 else if ((iFreq >= 16000000U) && (iFreq < 25000000U))
306 {
307 range = 1U;
308 }
309 else if ((iFreq >= 25000000U) && (iFreq < 40000000U))
310 {
311 range = 2U;
312 }
313 else if ((iFreq >= 40000000U) && (iFreq <= 50000000U))
314 {
315 range = 3U;
316 }
317 else
318 {
319 return kStatus_InvalidArgument;
320 }
321
322 /* If configure register is locked, return error. */
323 if ((SCG0->SOSCCSR & SCG_SOSCCSR_LK_MASK) != 0U)
324 {
325 return kStatus_ReadOnly;
326 }
327
328 /* De-initializes the SCG SOSC */
329 SCG0->SOSCCSR = SCG_SOSCCSR_SOSCERR_MASK;
330
331 /* Select SOSC source (internal crystal oscillator) and Configure SOSC range */
332 SCG0->SOSCCFG = SCG_SOSCCFG_EREFS_MASK | SCG_SOSCCFG_RANGE(range);
333
334 /* Unlock SOSCCSR */
335 SCG0->SOSCCSR &= ~SCG_SOSCCSR_LK_MASK;
336
337 /* Enable SOSC clock monitor and Enable SOSC */
338 SCG0->SOSCCSR |= (SCG_SOSCCSR_SOSCCM_MASK | SCG_SOSCCSR_SOSCEN_MASK);
339
340 /* Wait for SOSC clock to be valid. */
341 while ((SCG0->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) == 0U)
342 {
343 }
344
345 s_Ext_Clk_Freq = iFreq;
346
347 return kStatus_Success;
348 }
349
350 /*!
351 * @brief Initialize the external reference clock to given frequency.
352 * param iFreq : Desired frequency (must be equal to exact rate in Hz)
353 * return returns success or fail status.
354 */
CLOCK_SetupExtRefClocking(uint32_t iFreq)355 status_t CLOCK_SetupExtRefClocking(uint32_t iFreq)
356 {
357
358 if (iFreq > 50000000U)
359 {
360 return kStatus_InvalidArgument;
361 }
362
363 /* If configure register is locked, return error. */
364 if ((SCG0->SOSCCSR & SCG_SOSCCSR_LK_MASK) != 0U)
365 {
366 return kStatus_ReadOnly;
367 }
368
369 /* De-initializes the SCG SOSC */
370 SCG0->SOSCCSR = SCG_SOSCCSR_SOSCERR_MASK;
371
372 /* Select SOSC source (external reference clock)*/
373 SCG0->SOSCCFG &= ~SCG_SOSCCFG_EREFS_MASK;
374
375 /* Unlock SOSCCSR */
376 SCG0->SOSCCSR &= ~SCG_SOSCCSR_LK_MASK;
377
378 /* Enable SOSC clock monitor and Enable SOSC */
379 SCG0->SOSCCSR |= (SCG_SOSCCSR_SOSCCM_MASK | SCG_SOSCCSR_SOSCEN_MASK);
380
381 /* Wait for SOSC clock to be valid. */
382 while ((SCG0->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) == 0U)
383 {
384 }
385
386 s_Ext_Clk_Freq = iFreq;
387
388 return kStatus_Success;
389 }
390
391 /* Get IP Clk */
392 /*! brief Return Frequency of selected clock
393 * return Frequency of selected clock
394 */
CLOCK_GetFreq(clock_name_t clockName)395 uint32_t CLOCK_GetFreq(clock_name_t clockName)
396 {
397 uint32_t freq = 0U;
398
399 switch (clockName)
400 {
401 case kCLOCK_MainClk: /* MAIN_CLK */
402 freq = CLOCK_GetMainClk();
403 break;
404 case kCLOCK_CoreSysClk: /* Core/system clock(CPU_CLK) */
405 freq = CLOCK_GetCoreSysClkFreq();
406 break;
407 case kCLOCK_SYSTEM_CLK: /* AHB clock */
408 freq = CLOCK_GetCoreSysClkFreq();
409 break;
410 case kCLOCK_BusClk: /* Bus clock (AHB clock) */
411 freq = CLOCK_GetCoreSysClkFreq();
412 break;
413 case kCLOCK_ExtClk: /* External Clock */
414 freq = CLOCK_GetExtClkFreq();
415 break;
416 case kCLOCK_FroHf: /* FROHF */
417 freq = CLOCK_GetFroHfFreq();
418 break;
419 case kCLOCK_FroHfDiv: /* Divided by FROHF */
420 freq = CLOCK_GetFroHfFreq() / ((MRCC0->MRCC_FRO_HF_DIV_CLKDIV & 0xfU) + 1U);
421 break;
422 case kCLOCK_Clk48M: /* CLK48M */
423 freq = CLOCK_GetClk48MFreq();
424 break;
425 case kCLOCK_Fro12M: /* FRO12M */
426 freq = CLOCK_GetFro12MFreq();
427 break;
428 case kCLOCK_Clk1M: /* CLK1M */
429 freq = CLOCK_GetClk1MFreq();
430 break;
431 case kCLOCK_Fro16K: /* FRO16K */
432 freq = CLOCK_GetFRO16KFreq();
433 break;
434 case kCLOCK_Clk16K0: /* CLK16K[0] */
435 freq = CLOCK_GetClk16KFreq(0);
436 break;
437 case kCLOCK_Clk16K1: /* CLK16K[1] */
438 freq = CLOCK_GetClk16KFreq(1);
439 break;
440 case kCLOCK_SLOW_CLK: /* SYSTEM_CLK divided by 4 */
441 freq = CLOCK_GetCoreSysClkFreq() >> 2;
442 break;
443 default:
444 freq = 0U;
445 break;
446 }
447 return freq;
448 }
449
450 /* Get FRO 12M Clk */
451 /*! brief Return Frequency of FRO 12MHz
452 * return Frequency of FRO 12MHz
453 */
CLOCK_GetFro12MFreq(void)454 static uint32_t CLOCK_GetFro12MFreq(void)
455 {
456 return ((SCG0->SIRCCSR & SCG_SIRCCSR_SIRC_CLK_PERIPH_EN_MASK) != 0U) ? 12000000U : 0U;
457 }
458
459 /* Get CLK 1M Clk */
460 /*! brief Return Frequency of CLK 1MHz
461 * return Frequency of CLK 1MHz
462 */
CLOCK_GetClk1MFreq(void)463 static uint32_t CLOCK_GetClk1MFreq(void)
464 {
465 return 1000000U;
466 }
467
468 /* Get HF FRO Clk */
469 /*! brief Return Frequency of High-Freq output of FRO
470 * return Frequency of High-Freq output of FRO
471 */
CLOCK_GetFroHfFreq(void)472 static uint32_t CLOCK_GetFroHfFreq(void)
473 {
474 uint32_t freq;
475
476 if (((SCG0->FIRCCSR & SCG_FIRCCSR_FIRCEN_MASK) == 0U) ||
477 ((SCG0->FIRCCSR & SCG_FIRCCSR_FIRC_FCLK_PERIPH_EN_SHIFT) == 0U))
478 {
479 freq = 0U;
480 }
481
482 switch ((SCG0->FIRCCFG & SCG_FIRCCFG_FREQ_SEL_MASK) >> SCG_FIRCCFG_FREQ_SEL_SHIFT)
483 {
484 case 0U:
485 freq = 36000000U;
486 break;
487 case 1U:
488 freq = 48000000U;
489 break;
490 case 2U:
491 freq = 48000000U;
492 break;
493 case 3U:
494 freq = 64000000U;
495 break;
496 case 4U:
497 freq = 72000000U;
498 break;
499 case 5U:
500 freq = 96000000U;
501 break;
502 case 6U:
503 freq = 144000000U;
504 break;
505 case 7U:
506 freq = 192000000U;
507 break;
508 default:
509 freq = 0U;
510 break;
511 }
512
513 return freq;
514 }
515
516 /* Get CLK 48M Clk */
517 /*! brief Return Frequency of CLK 48MHz
518 * return Frequency of CLK 48MHz
519 */
CLOCK_GetClk48MFreq(void)520 static uint32_t CLOCK_GetClk48MFreq(void)
521 {
522 return (((SCG0->FIRCCSR & SCG_FIRCCSR_FIRC_SCLK_PERIPH_EN_MASK) != 0U) ||
523 ((SCG0->FIRCCSR & SCG_FIRCCSR_FIRC_SCLK_PERIPH_EN_SHIFT) == 0U)) ?
524 48000000U :
525 0U;
526 }
527
528 /*! brief Return Frequency of FRO16K
529 * return Frequency of FRO_16K
530 */
CLOCK_GetFRO16KFreq(void)531 static uint32_t CLOCK_GetFRO16KFreq(void)
532 {
533 return ((VBAT0->FROCTLA & VBAT_FROCTLA_FRO_EN_MASK) != 0U) ? 16000U : 0U;
534 }
535 /* Get CLK 16K Clk */
536 /*! brief Return Frequency of CLK 16KHz
537 * return Frequency of CLK 16KHz
538 */
CLOCK_GetClk16KFreq(uint8_t id)539 static uint32_t CLOCK_GetClk16KFreq(uint8_t id)
540 {
541 return (((VBAT0->FROCTLA & VBAT_FROCTLA_FRO_EN_MASK) != 0U) &&
542 ((VBAT0->FROCLKE & VBAT_FROCLKE_CLKE((((uint32_t)id) << 1U))) != 0U)) ?
543 16000U :
544 0U;
545 }
546
547 /* Get EXT OSC Clk */
548 /*! brief Return Frequency of External Clock
549 * return Frequency of External Clock. If no external clock is used returns 0.
550 */
CLOCK_GetExtClkFreq(void)551 static uint32_t CLOCK_GetExtClkFreq(void)
552 {
553 return ((SCG0->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) != 0U) ? s_Ext_Clk_Freq : 0U;
554 }
555
556 /* Get MAIN Clk */
557 /*! brief Return Frequency of Core System
558 * return Frequency of Core System
559 */
CLOCK_GetMainClk(void)560 uint32_t CLOCK_GetMainClk(void)
561 {
562 uint32_t freq = 0U;
563
564 switch ((SCG0->CSR & SCG_CSR_SCS_MASK) >> SCG_CSR_SCS_SHIFT)
565 {
566 case 1U:
567 freq = CLOCK_GetExtClkFreq();
568 break;
569 case 2U:
570 freq = CLOCK_GetFro12MFreq();
571 break;
572 case 3U:
573 freq = CLOCK_GetFroHfFreq();
574 break;
575 case 4U:
576 freq = CLOCK_GetClk16KFreq(1);
577 break;
578 default:
579 freq = 0U;
580 break;
581 }
582
583 return freq;
584 }
585
586 /*! brief Return Frequency of core
587 * return Frequency of the core
588 */
CLOCK_GetCoreSysClkFreq(void)589 uint32_t CLOCK_GetCoreSysClkFreq(void)
590 {
591 return CLOCK_GetMainClk() / ((SYSCON->AHBCLKDIV & 0xFFU) + 1U);
592 }
593
594 /* Get I3C Clk */
595 /*! brief Return Frequency of I3C Clock
596 * return Frequency of I3C Clock
597 */
CLOCK_GetI3CFClkFreq(void)598 uint32_t CLOCK_GetI3CFClkFreq(void)
599 {
600 uint32_t freq = 0U;
601 uint32_t clksel = (MRCC0->MRCC_I3C0_FCLK_CLKSEL);
602 uint32_t clkdiv = (MRCC0->MRCC_I3C0_FCLK_CLKDIV);
603
604 if (true == CLOCK_IsDivHalt(clkdiv))
605 {
606 return 0;
607 }
608
609 switch (clksel)
610 {
611 case 0U:
612 freq = CLOCK_GetFro12MFreq();
613 break;
614 case 2U:
615 freq = CLOCK_GetFroHfFreq() / ((MRCC0->MRCC_FRO_HF_DIV_CLKDIV & 0xfU) + 1U);
616 break;
617 case 3U:
618 freq = CLOCK_GetExtClkFreq();
619 break;
620 case 5U:
621 freq = CLOCK_GetClk1MFreq();
622 break;
623 default:
624 freq = 0U;
625 break;
626 }
627
628 return freq / ((clkdiv & 0xFFU) + 1U);
629 }
630
631 /* Get CTimer Clk */
632 /*! brief Return Frequency of CTimer functional Clock
633 * return Frequency of CTimer functional Clock
634 */
CLOCK_GetCTimerClkFreq(uint32_t id)635 uint32_t CLOCK_GetCTimerClkFreq(uint32_t id)
636 {
637 uint32_t freq = 0U;
638 uint32_t clksel = (0U == id) ? (MRCC0->MRCC_CTIMER0_CLKSEL) :
639 (((1U == id)) ? (MRCC0->MRCC_CTIMER1_CLKSEL) : (MRCC0->MRCC_CTIMER2_CLKSEL));
640 uint32_t clkdiv = (0U == id) ? (MRCC0->MRCC_CTIMER0_CLKDIV) :
641 (((1U == id)) ? (MRCC0->MRCC_CTIMER1_CLKDIV) : (MRCC0->MRCC_CTIMER2_CLKDIV));
642
643 if (true == CLOCK_IsDivHalt(clkdiv))
644 {
645 return 0;
646 }
647
648 switch (clksel)
649 {
650 case 0U:
651 freq = CLOCK_GetFro12MFreq();
652 break;
653 case 1U:
654 freq = CLOCK_GetFroHfFreq();
655 break;
656 case 3U:
657 freq = CLOCK_GetExtClkFreq();
658 break;
659 case 4U:
660 freq = CLOCK_GetClk16KFreq(1);
661 break;
662 case 5U:
663 freq = CLOCK_GetClk1MFreq();
664 break;
665 default:
666 freq = 0U;
667 break;
668 }
669
670 return freq / ((clkdiv & 0xFFU) + 1U);
671 }
672
673 /* Get LPI2C Clk */
674 /*! brief Return Frequency of LPI2C functional Clock
675 * return Frequency of LPI2C functional Clock
676 */
CLOCK_GetLpi2cClkFreq(void)677 uint32_t CLOCK_GetLpi2cClkFreq(void)
678 {
679 uint32_t freq = 0U;
680 uint32_t clksel = (MRCC0->MRCC_LPI2C0_CLKSEL);
681 uint32_t clkdiv = (MRCC0->MRCC_LPI2C0_CLKDIV);
682
683 if (true == CLOCK_IsDivHalt(clkdiv))
684 {
685 return 0;
686 }
687
688 switch (clksel)
689 {
690 case 0U:
691 freq = CLOCK_GetFro12MFreq();
692 break;
693 case 2U:
694 freq = CLOCK_GetFroHfFreq() / ((MRCC0->MRCC_FRO_HF_DIV_CLKDIV & 0xfU) + 1U);
695 break;
696 case 3U:
697 freq = CLOCK_GetExtClkFreq();
698 break;
699 case 5U:
700 freq = CLOCK_GetClk1MFreq();
701 break;
702 default:
703 freq = 0U;
704 break;
705 }
706
707 return freq / ((clkdiv & 0xFFU) + 1U);
708 }
709
710 /*! brief Return Frequency of LPSPI functional Clock
711 * return Frequency of LPSPI functional Clock
712 */
CLOCK_GetLpspiClkFreq(uint32_t id)713 uint32_t CLOCK_GetLpspiClkFreq(uint32_t id)
714 {
715 uint32_t freq = 0U;
716 uint32_t clksel = (0U == id) ? (MRCC0->MRCC_LPSPI0_CLKSEL) : (MRCC0->MRCC_LPSPI1_CLKSEL);
717 uint32_t clkdiv = (0U == id) ? (MRCC0->MRCC_LPSPI0_CLKDIV) : (MRCC0->MRCC_LPSPI1_CLKDIV);
718
719 if (true == CLOCK_IsDivHalt(clkdiv))
720 {
721 return 0;
722 }
723
724 switch (clksel)
725 {
726 case 0U:
727 freq = CLOCK_GetFro12MFreq();
728 break;
729 case 2U:
730 freq = CLOCK_GetFroHfFreq() / ((MRCC0->MRCC_FRO_HF_DIV_CLKDIV & 0xfU) + 1U);
731 break;
732 case 3U:
733 freq = CLOCK_GetExtClkFreq();
734 break;
735 case 5U:
736 freq = CLOCK_GetClk1MFreq();
737 break;
738 default:
739 freq = 0U;
740 break;
741 }
742
743 return freq / ((clkdiv & 0xFFU) + 1U);
744 }
745
746 /*! brief Return Frequency of LPUART functional Clock
747 * return Frequency of LPUART functional Clock
748 */
CLOCK_GetLpuartClkFreq(uint32_t id)749 uint32_t CLOCK_GetLpuartClkFreq(uint32_t id)
750 {
751 uint32_t freq = 0U;
752 uint32_t clksel = (0U == id) ? (MRCC0->MRCC_LPUART0_CLKSEL) :
753 (((1U == id)) ? (MRCC0->MRCC_LPUART1_CLKSEL) : (MRCC0->MRCC_LPUART2_CLKSEL));
754 uint32_t clkdiv = (0U == id) ? (MRCC0->MRCC_LPUART0_CLKDIV) :
755 (((1U == id)) ? (MRCC0->MRCC_LPUART1_CLKDIV) : (MRCC0->MRCC_LPUART2_CLKDIV));
756
757 if (true == CLOCK_IsDivHalt(clkdiv))
758 {
759 return 0;
760 }
761
762 switch (clksel)
763 {
764 case 0U:
765 freq = CLOCK_GetFro12MFreq();
766 break;
767 case 2U:
768 freq = CLOCK_GetFroHfFreq() / ((MRCC0->MRCC_FRO_HF_DIV_CLKDIV & 0xfU) + 1U);
769 break;
770 case 3U:
771 freq = CLOCK_GetExtClkFreq();
772 break;
773 case 4U:
774 freq = CLOCK_GetClk16KFreq(1);
775 break;
776 case 5U:
777 freq = CLOCK_GetClk1MFreq();
778 break;
779 default:
780 freq = 0U;
781 break;
782 }
783
784 return freq / ((clkdiv & 0xFFU) + 1U);
785 }
786
787 /*! brief Return Frequency of LPTMR functional Clock
788 * return Frequency of LPTMR functional Clock
789 */
CLOCK_GetLptmrClkFreq(void)790 uint32_t CLOCK_GetLptmrClkFreq(void)
791 {
792 uint32_t freq = 0U;
793 uint32_t clksel = (MRCC0->MRCC_LPTMR0_CLKSEL);
794 uint32_t clkdiv = (MRCC0->MRCC_LPTMR0_CLKDIV);
795
796 if (true == CLOCK_IsDivHalt(clkdiv))
797 {
798 return 0;
799 }
800
801 switch (clksel)
802 {
803 case 0U:
804 freq = CLOCK_GetFro12MFreq();
805 break;
806 case 2U:
807 freq = CLOCK_GetFroHfFreq() / ((MRCC0->MRCC_FRO_HF_DIV_CLKDIV & 0xfU) + 1U);
808 break;
809 case 3U:
810 freq = CLOCK_GetExtClkFreq();
811 break;
812 case 5U:
813 freq = CLOCK_GetClk1MFreq();
814 break;
815 default:
816 freq = 0U;
817 break;
818 }
819
820 return freq / ((clkdiv & 0xFFU) + 1U);
821 }
822
823 /*! brief Return Frequency of OSTIMER
824 * return Frequency of OSTIMER Clock
825 */
CLOCK_GetOstimerClkFreq(void)826 uint32_t CLOCK_GetOstimerClkFreq(void)
827 {
828 uint32_t freq = 0U;
829 uint32_t clksel = (MRCC0->MRCC_OSTIMER0_CLKSEL);
830
831 switch (clksel)
832 {
833 case 0U:
834 freq = CLOCK_GetClk16KFreq(1);
835 break;
836 case 2U:
837 freq = CLOCK_GetClk1MFreq();
838 break;
839 default:
840 freq = 0U;
841 break;
842 }
843
844 return freq;
845 }
846
847 /*! brief Return Frequency of Adc Clock
848 * return Frequency of Adc.
849 */
CLOCK_GetAdcClkFreq(void)850 uint32_t CLOCK_GetAdcClkFreq(void)
851 {
852 uint32_t freq = 0U;
853 uint32_t clksel = (MRCC0->MRCC_ADC0_CLKSEL);
854 uint32_t clkdiv = (MRCC0->MRCC_ADC0_CLKDIV);
855
856 if (true == CLOCK_IsDivHalt(clkdiv))
857 {
858 return 0;
859 }
860
861 switch (clksel)
862 {
863 case 0U:
864 freq = CLOCK_GetFro12MFreq();
865 break;
866 case 1U:
867 freq = CLOCK_GetFroHfFreq();
868 break;
869 case 3U:
870 freq = CLOCK_GetExtClkFreq();
871 break;
872 case 5U:
873 freq = CLOCK_GetClk1MFreq();
874 break;
875 default:
876 freq = 0U;
877 break;
878 }
879
880 return freq / ((clkdiv & 0xFFU) + 1U);
881 }
882
883 /*! brief Return Frequency of CMP Function Clock
884 * return Frequency of CMP Function.
885 */
CLOCK_GetCmpFClkFreq(uint32_t id)886 uint32_t CLOCK_GetCmpFClkFreq(uint32_t id)
887 {
888 uint32_t freq = 0U;
889 uint32_t clksel = (0U == id) ? (MRCC0->MRCC_CMP0_RR_CLKSEL) : (MRCC0->MRCC_CMP1_RR_CLKSEL);
890 uint32_t clkdiv = (0U == id) ? (MRCC0->MRCC_CMP0_FUNC_CLKDIV) : (MRCC0->MRCC_CMP1_FUNC_CLKDIV);
891
892 if (true == CLOCK_IsDivHalt(clkdiv))
893 {
894 return 0;
895 }
896
897 switch (clksel)
898 {
899 case 0U:
900 freq = CLOCK_GetFro12MFreq();
901 break;
902 case 2U:
903 freq = CLOCK_GetFroHfFreq() / ((MRCC0->MRCC_FRO_HF_DIV_CLKDIV & 0xfU) + 1U);
904 break;
905 case 3U:
906 freq = CLOCK_GetExtClkFreq();
907 break;
908 case 5U:
909 freq = CLOCK_GetClk1MFreq();
910 break;
911 default:
912 freq = 0U;
913 break;
914 }
915
916 return freq / ((clkdiv & 0xFFU) + 1U);
917 }
918
919 /*! brief Return Frequency of CMP Round Robin Clock
920 * return Frequency of CMP Round Robin.
921 */
CLOCK_GetCmpRRClkFreq(uint32_t id)922 uint32_t CLOCK_GetCmpRRClkFreq(uint32_t id)
923 {
924 uint32_t freq = 0U;
925 uint32_t clksel = (0U == id) ? (MRCC0->MRCC_CMP0_RR_CLKSEL) : (MRCC0->MRCC_CMP1_RR_CLKSEL);
926 uint32_t clkdiv = (0U == id) ? (MRCC0->MRCC_CMP0_RR_CLKDIV) : (MRCC0->MRCC_CMP1_RR_CLKDIV);
927
928 if (true == CLOCK_IsDivHalt(clkdiv))
929 {
930 return 0;
931 }
932
933 switch (clksel)
934 {
935 case 0U:
936 freq = CLOCK_GetFro12MFreq();
937 break;
938 case 2U:
939 freq = CLOCK_GetFroHfFreq() / ((MRCC0->MRCC_FRO_HF_DIV_CLKDIV & 0xfU) + 1U);
940 break;
941 case 3U:
942 freq = CLOCK_GetExtClkFreq();
943 break;
944 case 5U:
945 freq = CLOCK_GetClk1MFreq();
946 break;
947 default:
948 freq = 0U;
949 break;
950 }
951
952 return freq / ((clkdiv & 0xFFU) + 1U);
953 }
954
955 /*! brief Return Frequency of Trace Clock
956 * return Frequency of Trace.
957 */
CLOCK_GetTraceClkFreq(void)958 uint32_t CLOCK_GetTraceClkFreq(void)
959 {
960 uint32_t freq = 0U;
961 uint32_t clksel = (MRCC0->MRCC_DBG_TRACE_CLKSEL);
962 uint32_t clkdiv = (MRCC0->MRCC_DBG_TRACE_CLKDIV);
963
964 if (true == CLOCK_IsDivHalt(clkdiv))
965 {
966 return 0;
967 }
968
969 switch (clksel)
970 {
971 case 0U:
972 freq = CLOCK_GetCoreSysClkFreq();
973 break;
974 case 1U:
975 freq = CLOCK_GetClk1MFreq();
976 break;
977 case 2U:
978 freq = CLOCK_GetClk16KFreq(1);
979 break;
980 default:
981 freq = 0U;
982 break;
983 }
984
985 return freq / ((clkdiv & 0xFFU) + 1U);
986 }
987
988 /*! brief Return Frequency of CLKOUT Clock
989 * return Frequency of CLKOUT.
990 */
CLOCK_GetClkoutClkFreq(void)991 uint32_t CLOCK_GetClkoutClkFreq(void)
992 {
993 uint32_t freq = 0U;
994 uint32_t clksel = (MRCC0->MRCC_CLKOUT_CLKSEL);
995 uint32_t clkdiv = (MRCC0->MRCC_CLKOUT_CLKDIV);
996
997 if (true == CLOCK_IsDivHalt(clkdiv))
998 {
999 return 0;
1000 }
1001
1002 switch (clksel)
1003 {
1004 case 0U:
1005 freq = CLOCK_GetFro12MFreq();
1006 break;
1007 case 1U:
1008 freq = CLOCK_GetFroHfFreq() / ((MRCC0->MRCC_FRO_HF_DIV_CLKDIV & 0xfU) + 1U);
1009 break;
1010 case 2U:
1011 freq = CLOCK_GetExtClkFreq();
1012 break;
1013 case 3U:
1014 freq = CLOCK_GetClk16KFreq(1);
1015 break;
1016 case 6U:
1017 freq = CLOCK_GetCoreSysClkFreq() >> 2;
1018 break;
1019 default:
1020 freq = 0U;
1021 break;
1022 }
1023
1024 return freq / ((clkdiv & 0xFFU) + 1U);
1025 }
1026
1027 /*! brief Return Frequency of Systick Clock
1028 * return Frequency of Systick.
1029 */
CLOCK_GetSystickClkFreq(void)1030 uint32_t CLOCK_GetSystickClkFreq(void)
1031 {
1032 uint32_t freq = 0U;
1033 uint32_t clksel = (MRCC0->MRCC_SYSTICK_CLKSEL);
1034 uint32_t clkdiv = (MRCC0->MRCC_SYSTICK_CLKDIV);
1035
1036 if (true == CLOCK_IsDivHalt(clkdiv))
1037 {
1038 return 0;
1039 }
1040
1041 switch (clksel)
1042 {
1043 case 0U:
1044 freq = CLOCK_GetCoreSysClkFreq();
1045 break;
1046 case 1U:
1047 freq = CLOCK_GetClk1MFreq();
1048 break;
1049 case 2U:
1050 freq = CLOCK_GetClk16KFreq(1);
1051 break;
1052 default:
1053 freq = 0U;
1054 break;
1055 }
1056
1057 return freq / ((clkdiv & 0xFFU) + 1U);
1058 }
1059
1060 /*! brief Return Frequency of Systick Clock
1061 * return Frequency of Systick.
1062 */
CLOCK_GetWwdtClkFreq(void)1063 uint32_t CLOCK_GetWwdtClkFreq(void)
1064 {
1065 uint32_t freq = 0U;
1066 uint32_t clkdiv = (MRCC0->MRCC_WWDT0_CLKDIV);
1067
1068 if (true == CLOCK_IsDivHalt(clkdiv))
1069 {
1070 return 0;
1071 }
1072
1073 freq = CLOCK_GetClk1MFreq();
1074
1075 return freq / ((clkdiv & 0xFFU) + 1U);
1076 }
1077
1078 /**
1079 * @brief Setup FROHF trim.
1080 * @param config : FROHF trim value
1081 * @return returns success or fail status.
1082 */
CLOCK_FROHFTrimConfig(firc_trim_config_t config)1083 status_t CLOCK_FROHFTrimConfig(firc_trim_config_t config)
1084 {
1085 SCG0->FIRCTCFG = SCG_FIRCTCFG_TRIMDIV(config.trimDiv) | SCG_FIRCTCFG_TRIMSRC(config.trimSrc);
1086
1087 if (kSCG_FircTrimNonUpdate == config.trimMode)
1088 {
1089 SCG0->FIRCSTAT = SCG_FIRCSTAT_TRIMFINE(config.trimFine);
1090 }
1091
1092 /* Set trim mode. */
1093 SCG0->FIRCCSR = (uint32_t)config.trimMode;
1094
1095 if ((SCG0->FIRCCSR & SCG_FIRCCSR_FIRCERR_MASK) == SCG_FIRCCSR_FIRCERR_MASK)
1096 {
1097 return (status_t)kStatus_Fail;
1098 }
1099
1100 return (status_t)kStatus_Success;
1101 }
1102
1103 /**
1104 * @brief Setup FRO 12M trim.
1105 * @param config : FRO 12M trim value
1106 * @return returns success or fail status.
1107 */
CLOCK_FRO12MTrimConfig(sirc_trim_config_t config)1108 status_t CLOCK_FRO12MTrimConfig(sirc_trim_config_t config)
1109 {
1110 SCG0->SIRCTCFG = SCG_SIRCTCFG_TRIMDIV(config.trimDiv) | SCG_SIRCTCFG_TRIMSRC(config.trimSrc);
1111
1112 if (kSCG_SircTrimNonUpdate == config.trimMode)
1113 {
1114 SCG0->SIRCSTAT = SCG_SIRCSTAT_CCOTRIM(config.cltrim);
1115 SCG0->SIRCSTAT = SCG_SIRCSTAT_CCOTRIM(config.ccotrim);
1116 }
1117
1118 /* Set trim mode. */
1119 SCG0->SIRCCSR = (uint32_t)config.trimMode;
1120
1121 if ((SCG0->SIRCCSR & SCG_SIRCCSR_SIRCERR_MASK) == SCG_SIRCCSR_SIRCERR_MASK)
1122 {
1123 return (status_t)kStatus_Fail;
1124 }
1125
1126 return (status_t)kStatus_Success;
1127 }
1128
1129 /*!
1130 * @brief Sets the system OSC monitor mode.
1131 *
1132 * This function sets the system OSC monitor mode. The mode can be disabled,
1133 * it can generate an interrupt when the error is disabled, or reset when the error is detected.
1134 *
1135 * @param mode Monitor mode to set.
1136 */
CLOCK_SetSysOscMonitorMode(scg_sosc_monitor_mode_t mode)1137 void CLOCK_SetSysOscMonitorMode(scg_sosc_monitor_mode_t mode)
1138 {
1139 uint32_t reg = SCG0->SOSCCSR;
1140
1141 reg &= ~(SCG_SOSCCSR_SOSCCM_MASK | SCG_SOSCCSR_SOSCCMRE_MASK);
1142
1143 reg |= (uint32_t)mode;
1144
1145 SCG0->SOSCCSR = reg;
1146 }
1147
1148 /*! brief Enable USB FS clock.
1149 * Enable USB Full Speed clock.
1150 */
CLOCK_EnableUsbfsClock(void)1151 bool CLOCK_EnableUsbfsClock(void)
1152 {
1153 /* Enable USB clock */
1154 CLOCK_EnableClock(kCLOCK_GateUSB0);
1155
1156 /* Enable FROHF with 48MHZ if it is disabled */
1157 if (0U == (SCG0->FIRCCSR & SCG_FIRCCSR_FIRCEN_MASK))
1158 {
1159 if (kStatus_Success != CLOCK_SetupFROHFClocking(48000000U))
1160 {
1161 return false;
1162 }
1163 }
1164
1165 /* Enable CLK_48 MHz clock for peripheral use */
1166 SCG0->FIRCCSR |= SCG_FIRCCSR_FIRC_SCLK_PERIPH_EN_MASK;
1167
1168 /* Use clk_48M for USB FS */
1169 CLOCK_AttachClk(kCLK_48M_to_USB0);
1170
1171 return true;
1172 }
1173