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