aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers')
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_clock.cmake17
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_inputmux_connections.cmake15
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_reset.cmake16
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_clock.c1679
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_clock.h835
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_fro_calib.h47
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_inputmux_connections.h151
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_power.c20
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_power.h225
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_reset.c132
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_reset.h182
11 files changed, 3319 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_clock.cmake b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_clock.cmake
new file mode 100644
index 000000000..1e7674739
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_clock.cmake
@@ -0,0 +1,17 @@
1if(NOT DRIVER_CLOCK_INCLUDED)
2
3 set(DRIVER_CLOCK_INCLUDED true CACHE BOOL "driver_clock component is included.")
4
5 target_sources(${MCUX_SDK_PROJECT_NAME} PRIVATE
6 ${CMAKE_CURRENT_LIST_DIR}/fsl_clock.c
7 )
8
9 target_include_directories(${MCUX_SDK_PROJECT_NAME} PRIVATE
10 ${CMAKE_CURRENT_LIST_DIR}/.
11 )
12
13
14 include(driver_power)
15 include(driver_common)
16
17endif() \ No newline at end of file
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_inputmux_connections.cmake b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_inputmux_connections.cmake
new file mode 100644
index 000000000..2ac921c5d
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_inputmux_connections.cmake
@@ -0,0 +1,15 @@
1if(NOT DRIVER_INPUTMUX_CONNECTIONS_INCLUDED)
2
3 set(DRIVER_INPUTMUX_CONNECTIONS_INCLUDED true CACHE BOOL "driver_inputmux_connections component is included.")
4
5 target_sources(${MCUX_SDK_PROJECT_NAME} PRIVATE
6 )
7
8 target_include_directories(${MCUX_SDK_PROJECT_NAME} PRIVATE
9 ${CMAKE_CURRENT_LIST_DIR}/.
10 )
11
12
13 include(driver_common)
14
15endif() \ No newline at end of file
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_reset.cmake b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_reset.cmake
new file mode 100644
index 000000000..a0a7acf16
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/driver_reset.cmake
@@ -0,0 +1,16 @@
1if(NOT DRIVER_RESET_INCLUDED)
2
3 set(DRIVER_RESET_INCLUDED true CACHE BOOL "driver_reset component is included.")
4
5 target_sources(${MCUX_SDK_PROJECT_NAME} PRIVATE
6 ${CMAKE_CURRENT_LIST_DIR}/fsl_reset.c
7 )
8
9 target_include_directories(${MCUX_SDK_PROJECT_NAME} PRIVATE
10 ${CMAKE_CURRENT_LIST_DIR}/.
11 )
12
13
14 include(driver_common)
15
16endif() \ No newline at end of file
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_clock.c b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_clock.c
new file mode 100644
index 000000000..85b87a97d
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_clock.c
@@ -0,0 +1,1679 @@
1/*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2019 , NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10#include "fsl_clock.h"
11#include "fsl_power.h"
12/*******************************************************************************
13 * Definitions
14 ******************************************************************************/
15/* Component ID definition, used by tools. */
16#ifndef FSL_COMPONENT_ID
17#define FSL_COMPONENT_ID "platform.drivers.clock"
18#endif
19#define NVALMAX (0x100U)
20#define PVALMAX (0x20U)
21#define MVALMAX (0x8000U)
22
23#define PLL_MAX_N_DIV 0x100U
24
25#define INDEX_SECTOR_TRIM48 ((uint32_t *)0x01000444U)
26#define INDEX_SECTOR_TRIM96 ((uint32_t *)0x01000430U)
27/*--------------------------------------------------------------------------
28!!! If required these #defines can be moved to chip library file
29----------------------------------------------------------------------------*/
30
31#define PLL_SSCG0_MDEC_VAL_P (0U) /* MDEC is in bits 16 downto 0 */
32#define PLL_SSCG0_MDEC_VAL_M (0x1FFFFUL << PLL_SSCG0_MDEC_VAL_P) /* NDEC is in bits 9 downto 0 */
33#define PLL_NDEC_VAL_P (0U) /* NDEC is in bits 9:0 */
34#define PLL_NDEC_VAL_M (0x3FFUL << PLL_NDEC_VAL_P)
35#define PLL_PDEC_VAL_P (0U) /* PDEC is in bits 6:0 */
36#define PLL_PDEC_VAL_M (0x7FUL << PLL_PDEC_VAL_P)
37
38#define PLL_MIN_CCO_FREQ_MHZ (75000000U)
39#define PLL_MAX_CCO_FREQ_MHZ (150000000U)
40#define PLL_LOWER_IN_LIMIT (4000U) /*!< Minimum PLL input rate */
41#define PLL_MIN_IN_SSMODE (2000000U)
42#define PLL_MAX_IN_SSMODE (4000000U)
43
44/* Middle of the range values for spread-spectrum */
45#define PLL_SSCG_MF_FREQ_VALUE 4U
46#define PLL_SSCG_MC_COMP_VALUE 2U
47#define PLL_SSCG_MR_DEPTH_VALUE 4U
48#define PLL_SSCG_DITHER_VALUE 0U
49
50/* PLL NDEC reg */
51#define PLL_NDEC_VAL_SET(value) (((unsigned long)(value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M)
52/* PLL PDEC reg */
53#define PLL_PDEC_VAL_SET(value) (((unsigned long)(value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M)
54/* SSCG control0 */
55#define PLL_SSCG0_MDEC_VAL_SET(value) (((unsigned long)(value) << PLL_SSCG0_MDEC_VAL_P) & PLL_SSCG0_MDEC_VAL_M)
56
57/* SSCG control1 */
58#define PLL_SSCG1_MD_FRACT_P 0U
59#define PLL_SSCG1_MD_INT_P 11U
60#define PLL_SSCG1_MD_FRACT_M (0x7FFUL << PLL_SSCG1_MD_FRACT_P)
61#define PLL_SSCG1_MD_INT_M (0xFFUL << PLL_SSCG1_MD_INT_P)
62
63#define PLL_SSCG1_MD_FRACT_SET(value) (((unsigned long)(value) << PLL_SSCG1_MD_FRACT_P) & PLL_SSCG1_MD_FRACT_M)
64#define PLL_SSCG1_MD_INT_SET(value) (((unsigned long)(value) << PLL_SSCG1_MD_INT_P) & PLL_SSCG1_MD_INT_M)
65
66/* Saved value of PLL output rate, computed whenever needed to save run-time
67 computation on each call to retrive the PLL rate. */
68static uint32_t s_Pll_Freq;
69
70static uint32_t g_I2S_Mclk_Freq = 0U;
71
72/** External clock rate on the CLKIN pin in Hz. If not used,
73 set this to 0. Otherwise, set it to the exact rate in Hz this pin is
74 being driven at. */
75static const uint32_t g_Ext_Clk_Freq = 0U;
76
77/*******************************************************************************
78 * Variables
79 ******************************************************************************/
80
81/*******************************************************************************
82 * Prototypes
83 ******************************************************************************/
84/* Find encoded NDEC value for raw N value, max N = NVALMAX */
85static uint32_t pllEncodeN(uint32_t N);
86/* Find decoded N value for raw NDEC value */
87static uint32_t pllDecodeN(uint32_t NDEC);
88/* Find encoded PDEC value for raw P value, max P = PVALMAX */
89static uint32_t pllEncodeP(uint32_t P);
90/* Find decoded P value for raw PDEC value */
91static uint32_t pllDecodeP(uint32_t PDEC);
92/* Find encoded MDEC value for raw M value, max M = MVALMAX */
93static uint32_t pllEncodeM(uint32_t M);
94/* Find decoded M value for raw MDEC value */
95static uint32_t pllDecodeM(uint32_t MDEC);
96/* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
97static void pllFindSel(uint32_t M, bool bypassFBDIV2, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR);
98/* Get predivider (N) from PLL NDEC setting */
99static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg);
100/* Get postdivider (P) from PLL PDEC setting */
101static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg);
102/* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */
103static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg);
104/* Get the greatest common divisor */
105static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n);
106/* Set PLL output based on desired output rate */
107static pll_error_t CLOCK_GetPllConfig(
108 uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS);
109/* Update local PLL rate variable */
110static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup);
111
112static const uint8_t wdtFreqLookup[32] = {0, 8, 12, 15, 18, 20, 24, 26, 28, 30, 32, 34, 36, 38, 40, 41,
113 42, 44, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58, 59, 60, 61};
114/*******************************************************************************
115 * Code
116 ******************************************************************************/
117
118/**
119 * brief Configure the clock selection muxes.
120 * param connection : Clock to be configured.
121 * return Nothing
122 */
123void CLOCK_AttachClk(clock_attach_id_t connection)
124{
125 uint8_t mux;
126 uint8_t sel;
127 uint16_t item;
128 uint32_t tmp32 = (uint32_t)connection;
129 uint32_t i;
130 volatile uint32_t *pClkSel;
131
132 pClkSel = &(SYSCON->MAINCLKSELA);
133
134 if (kNONE_to_NONE != connection)
135 {
136 for (i = 0U; i < 2U; i++)
137 {
138 if (tmp32 == 0U)
139 {
140 break;
141 }
142 item = (uint16_t)GET_ID_ITEM(tmp32);
143 if (item != (uint16_t)0U)
144 {
145 mux = GET_ID_ITEM_MUX(item);
146 sel = GET_ID_ITEM_SEL(item);
147 if (mux == CM_ASYNCAPB)
148 {
149 ASYNC_SYSCON->ASYNCAPBCLKSELA = sel;
150 }
151 else
152 {
153 ((volatile uint32_t *)pClkSel)[mux] = sel;
154 }
155 }
156 tmp32 = GET_ID_NEXT_ITEM(tmp32); /* pick up next descriptor */
157 }
158 }
159}
160
161/* Return the actual clock attach id */
162/**
163 * brief Get the actual clock attach id.
164 * This fuction uses the offset in input attach id, then it reads the actual source value in
165 * the register and combine the offset to obtain an actual attach id.
166 * param attachId : Clock attach id to get.
167 * return Clock source value.
168 */
169clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId)
170{
171 uint8_t mux;
172 uint8_t actualSel;
173 uint32_t tmp32 = (uint32_t)attachId;
174 uint32_t i;
175 uint32_t actualAttachId = 0U;
176 uint32_t selector = GET_ID_SELECTOR(tmp32);
177 volatile uint32_t *pClkSel;
178
179 pClkSel = &(SYSCON->MAINCLKSELA);
180
181 if (kNONE_to_NONE == attachId)
182 {
183 return kNONE_to_NONE;
184 }
185
186 for (i = 0U; i < 2U; i++)
187 {
188 mux = GET_ID_ITEM_MUX(tmp32);
189 if (tmp32 != 0UL)
190 {
191 if (mux == CM_ASYNCAPB)
192 {
193 actualSel = (uint8_t)(ASYNC_SYSCON->ASYNCAPBCLKSELA);
194 }
195 else
196 {
197 actualSel = (uint8_t)((volatile uint32_t *)pClkSel)[mux];
198 }
199
200 /* Consider the combination of two registers */
201 actualAttachId |= CLK_ATTACH_ID(mux, actualSel, i);
202 }
203 tmp32 = GET_ID_NEXT_ITEM(tmp32); /*!< pick up next descriptor */
204 }
205
206 actualAttachId |= selector;
207
208 return (clock_attach_id_t)actualAttachId;
209}
210
211/**
212 * brief Setup peripheral clock dividers.
213 * param div_name : Clock divider name
214 * param divided_by_value: Value to be divided
215 * param reset : Whether to reset the divider counter.
216 * return Nothing
217 */
218void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset)
219{
220 volatile uint32_t *pClkDiv;
221
222 pClkDiv = &(SYSCON->SYSTICKCLKDIV);
223 if (reset)
224 {
225 ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 29U;
226 }
227 if (divided_by_value == 0UL) /* halt */
228 {
229 ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 30U;
230 }
231 else
232 {
233 ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = (divided_by_value - 1UL);
234 }
235}
236
237/* Set FRO Clocking */
238/**
239 * brief Initialize the Core clock to given frequency (12, 48 or 96 MHz).
240 * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed output is
241 * enabled.
242 * param iFreq : Desired frequency (must be one of CLK_FRO_12MHZ or CLK_FRO_48MHZ or CLK_FRO_96MHZ)
243 * return returns success or fail status.
244 */
245status_t CLOCK_SetupFROClocking(uint32_t iFreq)
246{
247 uint32_t usb_adj;
248 if ((iFreq != 12000000U) && (iFreq != 48000000U) && (iFreq != 96000000U))
249 {
250 return kStatus_Fail;
251 }
252 /* Power up the FRO and set this as the base clock */
253 POWER_DisablePD(kPDRUNCFG_PD_FRO_EN);
254 /* back up the value of whether USB adj is selected, in which case we will have a value of 1 else 0 */
255 usb_adj = ((SYSCON->FROCTRL) & SYSCON_FROCTRL_USBCLKADJ_MASK) >> SYSCON_FROCTRL_USBCLKADJ_SHIFT;
256 if (iFreq > 12000000U)
257 {
258 if (iFreq == 96000000U)
259 {
260 SYSCON->FROCTRL = ((SYSCON_FROCTRL_TRIM_MASK | SYSCON_FROCTRL_FREQTRIM_MASK) & *INDEX_SECTOR_TRIM96) |
261 SYSCON_FROCTRL_SEL(1) | SYSCON_FROCTRL_WRTRIM(1) | SYSCON_FROCTRL_USBCLKADJ(usb_adj) |
262 SYSCON_FROCTRL_HSPDCLK(1);
263 }
264 else
265 {
266 SYSCON->FROCTRL = ((SYSCON_FROCTRL_TRIM_MASK | SYSCON_FROCTRL_FREQTRIM_MASK) & *INDEX_SECTOR_TRIM48) |
267 SYSCON_FROCTRL_SEL(0) | SYSCON_FROCTRL_WRTRIM(1) | SYSCON_FROCTRL_USBCLKADJ(usb_adj) |
268 SYSCON_FROCTRL_HSPDCLK(1);
269 }
270 }
271 else
272 {
273 SYSCON->FROCTRL &= ~SYSCON_FROCTRL_HSPDCLK(1);
274 }
275
276 return kStatus_Success;
277}
278
279/* Get CLOCK OUT Clk */
280/*! brief Return Frequency of ClockOut
281 * return Frequency of ClockOut
282 */
283uint32_t CLOCK_GetClockOutClkFreq(void)
284{
285 uint32_t freq = 0U;
286
287 switch (SYSCON->CLKOUTSELA)
288 {
289 case 0U:
290 freq = CLOCK_GetCoreSysClkFreq();
291 break;
292
293 case 1U:
294 freq = CLOCK_GetExtClkFreq();
295 break;
296
297 case 2U:
298 freq = CLOCK_GetWdtOscFreq();
299 break;
300
301 case 3U:
302 freq = CLOCK_GetFroHfFreq();
303 break;
304
305 case 4U:
306 freq = CLOCK_GetPllOutFreq();
307 break;
308
309 case 5U:
310 freq = CLOCK_GetFro12MFreq();
311 break;
312 case 6U:
313 freq = CLOCK_GetOsc32KFreq();
314 break;
315
316 default:
317 freq = 0U;
318 break;
319 }
320 return freq / ((SYSCON->CLKOUTDIV & 0xffU) + 1U);
321}
322/*! brief Return Frequency of FRO 12MHz
323 * return Frequency of FRO 12MHz
324 */
325uint32_t CLOCK_GetFro12MFreq(void)
326{
327 return ((SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_FRO_MASK) != 0UL) ? 0U : 12000000U;
328}
329
330/*! brief Return Frequency of External Clock
331 * return Frequency of External Clock. If no external clock is used returns 0.
332 */
333uint32_t CLOCK_GetExtClkFreq(void)
334{
335 return (g_Ext_Clk_Freq);
336}
337/*! brief Return Frequency of Watchdog Oscillator
338 * return Frequency of Watchdog Oscillator
339 */
340uint32_t CLOCK_GetWdtOscFreq(void)
341{
342 uint8_t freq_sel, div_sel;
343 if ((SYSCON->PDRUNCFG[0] & (1UL << ((uint8_t)kPDRUNCFG_PD_WDT_OSC & 0xffU))) != 0UL)
344 {
345 return 0U;
346 }
347 else
348 {
349 div_sel = (uint8_t)(((SYSCON->WDTOSCCTRL & 0x1fUL) + 1UL) << 1U);
350 freq_sel =
351 wdtFreqLookup[((SYSCON->WDTOSCCTRL & SYSCON_WDTOSCCTRL_FREQSEL_MASK) >> SYSCON_WDTOSCCTRL_FREQSEL_SHIFT)];
352 return ((uint32_t)freq_sel * 50000U) / ((uint32_t)div_sel);
353 }
354}
355
356/*! brief Return Frequency of High-Freq output of FRO
357 * return Frequency of High-Freq output of FRO
358 */
359uint32_t CLOCK_GetFroHfFreq(void)
360{
361 return ((SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_FRO_MASK) != 0UL) ?
362 0U :
363 (0UL == (SYSCON->FROCTRL & SYSCON_FROCTRL_HSPDCLK_MASK)) ?
364 0U :
365 ((SYSCON->FROCTRL & SYSCON_FROCTRL_SEL_MASK) != 0UL) ? 96000000U : 48000000U;
366}
367
368/*! brief Return Frequency of PLL
369 * return Frequency of PLL
370 */
371uint32_t CLOCK_GetPllOutFreq(void)
372{
373 return s_Pll_Freq;
374}
375
376/*! brief Return Frequency of 32kHz osc
377 * return Frequency of 32kHz osc
378 */
379uint32_t CLOCK_GetOsc32KFreq(void)
380{
381 return CLK_RTC_32K_CLK; /* Needs to be corrected to check that RTC Clock is enabled */
382}
383/*! brief Return Frequency of Core System
384 * return Frequency of Core System
385 */
386uint32_t CLOCK_GetCoreSysClkFreq(void)
387{
388 return ((SYSCON->MAINCLKSELB == 0U) && (SYSCON->MAINCLKSELA == 0U)) ?
389 CLOCK_GetFro12MFreq() :
390 ((SYSCON->MAINCLKSELB == 0U) && (SYSCON->MAINCLKSELA == 1U)) ?
391 CLOCK_GetExtClkFreq() :
392 ((SYSCON->MAINCLKSELB == 0U) && (SYSCON->MAINCLKSELA == 2U)) ?
393 CLOCK_GetWdtOscFreq() :
394 ((SYSCON->MAINCLKSELB == 0U) && (SYSCON->MAINCLKSELA == 3U)) ?
395 CLOCK_GetFroHfFreq() :
396 (SYSCON->MAINCLKSELB == 2U) ? CLOCK_GetPllOutFreq() :
397 (SYSCON->MAINCLKSELB == 3U) ? CLOCK_GetOsc32KFreq() : 0U;
398}
399/*! brief Return Frequency of I2S MCLK Clock
400 * return Frequency of I2S MCLK Clock
401 */
402uint32_t CLOCK_GetI2SMClkFreq(void)
403{
404 return g_I2S_Mclk_Freq;
405}
406
407/*! brief Return Frequency of Asynchronous APB Clock
408 * return Frequency of Asynchronous APB Clock Clock
409 */
410uint32_t CLOCK_GetAsyncApbClkFreq(void)
411{
412 async_clock_src_t clkSrc;
413 uint32_t clkRate;
414
415 clkSrc = CLOCK_GetAsyncApbClkSrc();
416
417 switch (clkSrc)
418 {
419 case kCLOCK_AsyncMainClk:
420 clkRate = CLOCK_GetCoreSysClkFreq();
421 break;
422 case kCLOCK_AsyncFro12Mhz:
423 clkRate = CLK_FRO_12MHZ;
424 break;
425 default:
426 clkRate = 0U;
427 break;
428 }
429
430 return clkRate;
431}
432
433/*! brief Return Frequency of Flexcomm functional Clock
434 * return Frequency of Flexcomm functional Clock
435 */
436uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id)
437{
438 return (SYSCON->FXCOMCLKSEL[id] == 0U) ?
439 CLOCK_GetFro12MFreq() :
440 (SYSCON->FXCOMCLKSEL[id] == 1U) ?
441 CLOCK_GetFroHfFreq() :
442 (SYSCON->FXCOMCLKSEL[id] == 2U) ?
443 CLOCK_GetPllOutFreq() :
444 (SYSCON->FXCOMCLKSEL[id] == 3U) ? CLOCK_GetI2SMClkFreq() :
445 (SYSCON->FXCOMCLKSEL[id] == 4U) ? CLOCK_GetFreq(kCLOCK_Frg) : 0U;
446}
447/* Get USB Clk */
448/*! brief Return Frequency of Usb Clock
449 * return Frequency of Usb Clock.
450 */
451uint32_t CLOCK_GetUsbClkFreq(void)
452{
453 uint32_t freq = 0U;
454
455 freq = (SYSCON->USBCLKSEL == 0U) ? CLOCK_GetFroHfFreq() : (SYSCON->USBCLKSEL == 1UL) ? CLOCK_GetPllOutFreq() : 0U;
456 freq = freq / ((SYSCON->USBCLKDIV & 0xffU) + 1U);
457
458 return freq;
459}
460
461/* Get ADC Clk */
462/*! brief Return Frequency of Adc Clock
463 * return Frequency of Adc Clock.
464 */
465uint32_t CLOCK_GetAdcClkFreq(void)
466{
467 uint32_t freq = 0U;
468
469 switch (SYSCON->ADCCLKSEL)
470 {
471 case 0U:
472 freq = CLOCK_GetCoreSysClkFreq();
473 break;
474 case 1U:
475 freq = CLOCK_GetPllOutFreq();
476 break;
477 case 2U:
478 freq = CLOCK_GetFroHfFreq();
479 break;
480 case 7U:
481 freq = 0U;
482 break;
483 default:
484 freq = 0U;
485 break;
486 }
487
488 return freq / ((SYSCON->ADCCLKDIV & 0xffU) + 1U);
489}
490
491/*! brief Return Input frequency for the Fractional baud rate generator
492 * return Input Frequency for FRG
493 */
494uint32_t CLOCK_GetFRGInputClock(void)
495{
496 return (SYSCON->FRGCLKSEL == 0U) ?
497 CLOCK_GetCoreSysClkFreq() :
498 (SYSCON->FRGCLKSEL == 1U) ?
499 CLOCK_GetPllOutFreq() :
500 (SYSCON->FRGCLKSEL == 2U) ? CLOCK_GetFro12MFreq() :
501 (SYSCON->FRGCLKSEL == 3U) ? CLOCK_GetFroHfFreq() : 0U;
502}
503
504/*! brief Set output of the Fractional baud rate generator
505 * param freq : Desired output frequency
506 * return Error Code 0 - fail 1 - success
507 */
508uint32_t CLOCK_SetFRGClock(uint32_t freq)
509{
510 uint32_t input = CLOCK_GetFRGInputClock();
511 uint32_t mul;
512
513 if ((freq > 48000000UL) || (freq > input) || (input / freq >= 2UL))
514 {
515 /* FRG output frequency should be less than equal to 48MHz */
516 return 0UL;
517 }
518 else
519 {
520 mul = (uint32_t)((((uint64_t)input - freq) * 256U) / ((uint64_t)freq));
521 SYSCON->FRGCTRL = (mul << SYSCON_FRGCTRL_MULT_SHIFT) | SYSCON_FRGCTRL_DIV_MASK;
522 return 1UL;
523 }
524}
525
526/*! brief Return Frequency of selected clock
527 * return Frequency of selected clock
528 */
529uint32_t CLOCK_GetFreq(clock_name_t clockName)
530{
531 uint32_t freq;
532 switch (clockName)
533 {
534 case kCLOCK_CoreSysClk:
535 freq = CLOCK_GetCoreSysClkFreq();
536 break;
537 case kCLOCK_BusClk:
538 freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->AHBCLKDIV & 0xffU) + 1U);
539 break;
540 case kCLOCK_ClockOut:
541 freq = CLOCK_GetClockOutClkFreq();
542 break;
543 case kCLOCK_FroHf:
544 freq = CLOCK_GetFroHfFreq();
545 break;
546 case kCLOCK_Fro12M:
547 freq = CLOCK_GetFro12MFreq();
548 break;
549 case kCLOCK_PllOut:
550 freq = CLOCK_GetPllOutFreq();
551 break;
552 case kCLOCK_WdtOsc:
553 freq = CLOCK_GetWdtOscFreq();
554 break;
555 case kCLOCK_Frg:
556 freq = (uint32_t)(((SYSCON->FRGCTRL & SYSCON_FRGCTRL_DIV_MASK) == SYSCON_FRGCTRL_DIV_MASK) ?
557 ((uint64_t)CLOCK_GetFRGInputClock() * (SYSCON_FRGCTRL_DIV_MASK + 1U)) /
558 ((SYSCON_FRGCTRL_DIV_MASK + 1U) +
559 ((SYSCON->FRGCTRL & SYSCON_FRGCTRL_MULT_MASK) >> SYSCON_FRGCTRL_MULT_SHIFT)) :
560 0U);
561 break;
562
563 case kCLOCK_AsyncApbClk:
564 freq = CLOCK_GetAsyncApbClkFreq();
565 break;
566
567 case kCLOCK_FlexI2S:
568 freq = CLOCK_GetI2SMClkFreq();
569 break;
570 default:
571 freq = 0U;
572 break;
573 }
574
575 return freq;
576}
577
578/* Set the FLASH wait states for the passed frequency */
579/**
580 * brief Set the flash wait states for the input freuqency.
581 * param iFreq : Input frequency
582 * return Nothing
583 */
584void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq)
585{
586 if (iFreq <= 12000000U)
587 {
588 CLOCK_SetFLASHAccessCycles(kCLOCK_Flash1Cycle);
589 }
590 else if (iFreq <= 24000000U)
591 {
592 CLOCK_SetFLASHAccessCycles(kCLOCK_Flash2Cycle);
593 }
594 else if (iFreq <= 48000000U)
595 {
596 CLOCK_SetFLASHAccessCycles(kCLOCK_Flash3Cycle);
597 }
598 else if (iFreq <= 72000000U)
599 {
600 CLOCK_SetFLASHAccessCycles(kCLOCK_Flash4Cycle);
601 }
602 else if (iFreq <= 84000000U)
603 {
604 CLOCK_SetFLASHAccessCycles(kCLOCK_Flash5Cycle);
605 }
606 else if (iFreq <= 100000000U)
607 {
608 CLOCK_SetFLASHAccessCycles(kCLOCK_Flash6Cycle);
609 }
610 else
611 {
612 CLOCK_SetFLASHAccessCycles(kCLOCK_Flash7Cycle);
613 }
614}
615
616/* Find encoded NDEC value for raw N value, max N = NVALMAX */
617static uint32_t pllEncodeN(uint32_t N)
618{
619 uint32_t x, i;
620
621 /* Find NDec */
622 switch (N)
623 {
624 case 0U:
625 x = 0x3FFU;
626 break;
627
628 case 1U:
629 x = 0x302U;
630 break;
631
632 case 2U:
633 x = 0x202U;
634 break;
635
636 default:
637 x = 0x080U;
638 for (i = N; i <= NVALMAX; i++)
639 {
640 x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU);
641 }
642 break;
643 }
644
645 return x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P);
646}
647
648/* Find decoded N value for raw NDEC value */
649static uint32_t pllDecodeN(uint32_t NDEC)
650{
651 uint32_t n, x, i;
652
653 /* Find NDec */
654 switch (NDEC)
655 {
656 case 0x3FFU:
657 n = 0U;
658 break;
659
660 case 0x302U:
661 n = 1U;
662 break;
663
664 case 0x202U:
665 n = 2U;
666 break;
667
668 default:
669 x = 0x080U;
670 n = 0xFFFFFFFFU;
671 for (i = NVALMAX; i >= 3U; i--)
672 {
673 x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU);
674 if ((x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P)) == NDEC)
675 {
676 /* Decoded value of NDEC */
677 n = i;
678 break;
679 }
680 }
681 break;
682 }
683
684 return n;
685}
686
687/* Find encoded PDEC value for raw P value, max P = PVALMAX */
688static uint32_t pllEncodeP(uint32_t P)
689{
690 uint32_t x, i;
691
692 /* Find PDec */
693 switch (P)
694 {
695 case 0U:
696 x = 0x7FU;
697 break;
698
699 case 1U:
700 x = 0x62U;
701 break;
702
703 case 2U:
704 x = 0x42U;
705 break;
706
707 default:
708 x = 0x10U;
709 for (i = P; i <= PVALMAX; i++)
710 {
711 x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU);
712 }
713 break;
714 }
715
716 return x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P);
717}
718
719/* Find decoded P value for raw PDEC value */
720static uint32_t pllDecodeP(uint32_t PDEC)
721{
722 uint32_t p, x, i;
723
724 /* Find PDec */
725 switch (PDEC)
726 {
727 case 0x7FU:
728 p = 0U;
729 break;
730
731 case 0x62U:
732 p = 1U;
733 break;
734
735 case 0x42U:
736 p = 2U;
737 break;
738
739 default:
740 x = 0x10U;
741 p = 0xFFFFFFFFU;
742 for (i = PVALMAX; i >= 3U; i--)
743 {
744 x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU);
745 if ((x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P)) == PDEC)
746 {
747 /* Decoded value of PDEC */
748 p = i;
749 break;
750 }
751 }
752 break;
753 }
754
755 return p;
756}
757
758/* Find encoded MDEC value for raw M value, max M = MVALMAX */
759static uint32_t pllEncodeM(uint32_t M)
760{
761 uint32_t i, x;
762
763 /* Find MDec */
764 switch (M)
765 {
766 case 0U:
767 x = 0x1FFFFU;
768 break;
769
770 case 1U:
771 x = 0x18003U;
772 break;
773
774 case 2U:
775 x = 0x10003U;
776 break;
777
778 default:
779 x = 0x04000U;
780 for (i = M; i <= MVALMAX; i++)
781 {
782 x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU);
783 }
784 break;
785 }
786
787 return x & (PLL_SSCG0_MDEC_VAL_M >> PLL_SSCG0_MDEC_VAL_P);
788}
789
790/* Find decoded M value for raw MDEC value */
791static uint32_t pllDecodeM(uint32_t MDEC)
792{
793 uint32_t m, i, x;
794
795 /* Find MDec */
796 switch (MDEC)
797 {
798 case 0x1FFFFU:
799 m = 0U;
800 break;
801
802 case 0x18003U:
803 m = 1U;
804 break;
805
806 case 0x10003U:
807 m = 2U;
808 break;
809
810 default:
811 x = 0x04000U;
812 m = 0xFFFFFFFFU;
813 for (i = MVALMAX; i >= 3U; i--)
814 {
815 x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU);
816 if ((x & (PLL_SSCG0_MDEC_VAL_M >> PLL_SSCG0_MDEC_VAL_P)) == MDEC)
817 {
818 /* Decoded value of MDEC */
819 m = i;
820 break;
821 }
822 }
823 break;
824 }
825
826 return m;
827}
828
829/* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
830static void pllFindSel(uint32_t M, bool bypassFBDIV2, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR)
831{
832 /* bandwidth: compute selP from Multiplier */
833 if (M < 60U)
834 {
835 *pSelP = (M >> 1U) + 1U;
836 }
837 else
838 {
839 *pSelP = PVALMAX - 1U;
840 }
841
842 /* bandwidth: compute selI from Multiplier */
843 if (M > 16384U)
844 {
845 *pSelI = 1U;
846 }
847 else if (M > 8192U)
848 {
849 *pSelI = 2U;
850 }
851 else if (M > 2048U)
852 {
853 *pSelI = 4U;
854 }
855 else if (M >= 501U)
856 {
857 *pSelI = 8U;
858 }
859 else if (M >= 60U)
860 {
861 *pSelI = 4U * (1024U / (M + 9U));
862 }
863 else
864 {
865 *pSelI = (M & 0x3CU) + 4U;
866 }
867
868 if (*pSelI > ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT))
869 {
870 *pSelI = ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT);
871 }
872
873 *pSelR = 0U;
874}
875
876/* Get predivider (N) from PLL NDEC setting */
877static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg)
878{
879 uint32_t preDiv = 1;
880
881 /* Direct input is not used? */
882 if ((ctrlReg & (1UL << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT)) == 0U)
883 {
884 /* Decode NDEC value to get (N) pre divider */
885 preDiv = pllDecodeN(nDecReg & 0x3FFU);
886 if (preDiv == 0U)
887 {
888 preDiv = 1U;
889 }
890 }
891
892 /* Adjusted by 1, directi is used to bypass */
893 return preDiv;
894}
895
896/* Get postdivider (P) from PLL PDEC setting */
897static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg)
898{
899 uint32_t postDiv = 1U;
900
901 /* Direct input is not used? */
902 if ((ctrlReg & SYSCON_SYSPLLCTRL_DIRECTO_MASK) == 0U)
903 {
904 /* Decode PDEC value to get (P) post divider */
905 postDiv = 2U * pllDecodeP(pDecReg & 0x7FU);
906 if (postDiv == 0U)
907 {
908 postDiv = 2U;
909 }
910 }
911
912 /* Adjusted by 1, directo is used to bypass */
913 return postDiv;
914}
915
916/* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */
917static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg)
918{
919 uint32_t mMult = 1U;
920
921 /* Decode MDEC value to get (M) multiplier */
922 mMult = pllDecodeM(mDecReg & 0x1FFFFU);
923
924 /* Extra multiply by 2 needed? */
925 if ((ctrlReg & (SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK)) == 0U)
926 {
927 mMult = mMult << 1U;
928 }
929
930 if (mMult == 0U)
931 {
932 mMult = 1U;
933 }
934
935 return mMult;
936}
937
938static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n)
939{
940 uint32_t tmp;
941
942 while (n != 0U)
943 {
944 tmp = n;
945 n = m % n;
946 m = tmp;
947 }
948
949 return m;
950}
951
952/*
953 * Set PLL output based on desired output rate.
954 * In this function, the it calculates the PLL setting for output frequency from input clock
955 * frequency. The calculation would cost a few time. So it is not recommaned to use it frequently.
956 * the "pllctrl", "pllndec", "pllpdec", "pllmdec" would updated in this function.
957 */
958static pll_error_t CLOCK_GetPllConfigInternal(
959 uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS)
960{
961 uint32_t nDivOutHz, fccoHz, multFccoDiv;
962 uint32_t pllPreDivider, pllMultiplier, pllBypassFBDIV2, pllPostDivider;
963 uint32_t pllDirectInput, pllDirectOutput;
964 uint32_t pllSelP, pllSelI, pllSelR, bandsel, uplimoff;
965
966 /* Baseline parameters (no input or output dividers) */
967 pllPreDivider = 1U; /* 1 implies pre-divider will be disabled */
968 pllPostDivider = 0U; /* 0 implies post-divider will be disabled */
969 pllDirectOutput = 1U;
970 if (useFeedbackDiv2)
971 {
972 /* Using feedback divider for M, so disable bypass */
973 pllBypassFBDIV2 = 0U;
974 }
975 else
976 {
977 pllBypassFBDIV2 = 1U;
978 }
979 multFccoDiv = (2U - pllBypassFBDIV2);
980
981 /* Verify output rate parameter */
982 if (foutHz > PLL_MAX_CCO_FREQ_MHZ)
983 {
984 /* Maximum PLL output with post divider=1 cannot go above this frequency */
985 return kStatus_PLL_OutputTooHigh;
986 }
987 if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1U)))
988 {
989 /* Minmum PLL output with maximum post divider cannot go below this frequency */
990 return kStatus_PLL_OutputTooLow;
991 }
992
993 /* If using SS mode, input clock needs to be between 2MHz and 4MHz */
994 if (useSS)
995 {
996 /* Verify input rate parameter */
997 if (finHz < PLL_MIN_IN_SSMODE)
998 {
999 /* Input clock into the PLL cannot be lower than this */
1000 return kStatus_PLL_InputTooLow;
1001 }
1002 /* PLL input in SS mode must be under 4MHz */
1003 pllPreDivider = finHz / ((PLL_MIN_IN_SSMODE + PLL_MAX_IN_SSMODE) / 2U);
1004 if (pllPreDivider > NVALMAX)
1005 {
1006 return kStatus_PLL_InputTooHigh;
1007 }
1008 }
1009 else
1010 {
1011 /* Verify input rate parameter */
1012 if (finHz < PLL_LOWER_IN_LIMIT)
1013 {
1014 /* Input clock into the PLL cannot be lower than this */
1015 return kStatus_PLL_InputTooLow;
1016 }
1017 }
1018
1019 /* Find the optimal CCO frequency for the output and input that
1020 will keep it inside the PLL CCO range. This may require
1021 tweaking the post-divider for the PLL. */
1022 fccoHz = foutHz;
1023 while (fccoHz < PLL_MIN_CCO_FREQ_MHZ)
1024 {
1025 /* CCO output is less than minimum CCO range, so the CCO output
1026 needs to be bumped up and the post-divider is used to bring
1027 the PLL output back down. */
1028 pllPostDivider++;
1029 if (pllPostDivider > PVALMAX)
1030 {
1031 return kStatus_PLL_OutsideIntLimit;
1032 }
1033
1034 /* Target CCO goes up, PLL output goes down */
1035 fccoHz = foutHz * (pllPostDivider * 2U);
1036 pllDirectOutput = 0U;
1037 }
1038
1039 /* Determine if a pre-divider is needed to get the best frequency */
1040 if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz) && (useSS == false))
1041 {
1042 uint32_t a = FindGreatestCommonDivisor(fccoHz, (multFccoDiv * finHz));
1043
1044 if (a > 20000U)
1045 {
1046 a = (multFccoDiv * finHz) / a;
1047 if ((a != 0U) && (a < PLL_MAX_N_DIV))
1048 {
1049 pllPreDivider = a;
1050 }
1051 }
1052 }
1053
1054 /* Bypass pre-divider hardware if pre-divider is 1 */
1055 if (pllPreDivider > 1U)
1056 {
1057 pllDirectInput = 0U;
1058 }
1059 else
1060 {
1061 pllDirectInput = 1U;
1062 }
1063
1064 /* Determine PLL multipler */
1065 nDivOutHz = (finHz / pllPreDivider);
1066 pllMultiplier = (fccoHz / nDivOutHz) / multFccoDiv;
1067
1068 /* Find optimal values for filter */
1069 if (useSS == false)
1070 {
1071 /* Will bumping up M by 1 get us closer to the desired CCO frequency? */
1072 if ((nDivOutHz * ((multFccoDiv * pllMultiplier * 2U) + 1U)) < (fccoHz * 2U))
1073 {
1074 pllMultiplier++;
1075 }
1076
1077 /* Setup filtering */
1078 pllFindSel(pllMultiplier, (bool)pllBypassFBDIV2, &pllSelP, &pllSelI, &pllSelR);
1079 bandsel = 1U;
1080 uplimoff = 0U;
1081
1082 /* Get encoded value for M (mult) and use manual filter, disable SS mode */
1083 pSetup->syspllssctrl[0] =
1084 (PLL_SSCG0_MDEC_VAL_SET(pllEncodeM(pllMultiplier)) | (1UL << SYSCON_SYSPLLSSCTRL0_SEL_EXT_SHIFT));
1085
1086 /* Power down SSC, not used */
1087 pSetup->syspllssctrl[1] = (1UL << SYSCON_SYSPLLSSCTRL1_PD_SHIFT);
1088 }
1089 else
1090 {
1091 uint64_t fc;
1092
1093 /* Filtering will be handled by SSC */
1094 pllSelR = 0UL;
1095 pllSelI = 0UL;
1096 pllSelP = 0UL;
1097 bandsel = 0U;
1098 uplimoff = 1U;
1099
1100 /* The PLL multiplier will get very close and slightly under the
1101 desired target frequency. A small fractional component can be
1102 added to fine tune the frequency upwards to the target. */
1103 fc = (uint32_t)((((uint64_t)fccoHz % ((uint64_t)multFccoDiv * nDivOutHz)) << 11U) / (multFccoDiv * nDivOutHz));
1104
1105 /* MDEC set by SSC */
1106 pSetup->syspllssctrl[0U] = 0U;
1107
1108 /* Set multiplier */
1109 pSetup->syspllssctrl[1] = PLL_SSCG1_MD_INT_SET(pllMultiplier) | PLL_SSCG1_MD_FRACT_SET((uint32_t)fc);
1110 }
1111
1112 /* Get encoded values for N (prediv) and P (postdiv) */
1113 pSetup->syspllndec = PLL_NDEC_VAL_SET(pllEncodeN(pllPreDivider));
1114 pSetup->syspllpdec = PLL_PDEC_VAL_SET(pllEncodeP(pllPostDivider));
1115
1116 /* PLL control */
1117 pSetup->syspllctrl = (pllSelR << SYSCON_SYSPLLCTRL_SELR_SHIFT) | /* Filter coefficient */
1118 (pllSelI << SYSCON_SYSPLLCTRL_SELI_SHIFT) | /* Filter coefficient */
1119 (pllSelP << SYSCON_SYSPLLCTRL_SELP_SHIFT) | /* Filter coefficient */
1120 (0UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT) | /* PLL bypass mode disabled */
1121 (pllBypassFBDIV2 << SYSCON_SYSPLLCTRL_BYPASSCCODIV2_SHIFT) | /* Extra M / 2 divider? */
1122 (uplimoff << SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT) | /* SS/fractional mode disabled */
1123 (bandsel << SYSCON_SYSPLLCTRL_BANDSEL_SHIFT) | /* Manual bandwidth selection enabled */
1124 (pllDirectInput << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT) | /* Bypass pre-divider? */
1125 (pllDirectOutput << SYSCON_SYSPLLCTRL_DIRECTO_SHIFT); /* Bypass post-divider? */
1126
1127 return kStatus_PLL_Success;
1128}
1129
1130#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1131/* Alloct the static buffer for cache. */
1132static pll_setup_t gPllSetupCacheStruct[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT];
1133static uint32_t gFinHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
1134static uint32_t gFoutHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
1135static bool gUseFeedbackDiv2Cache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {false};
1136static bool gUseSSCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {false};
1137static uint32_t gPllSetupCacheIdx = 0U;
1138#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1139
1140/*
1141 * Calculate the PLL setting values from input clock freq to output freq.
1142 */
1143static pll_error_t CLOCK_GetPllConfig(
1144 uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS)
1145{
1146 pll_error_t retErr;
1147#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1148 uint32_t i;
1149
1150 for (i = 0U; i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; i++)
1151 {
1152 if ((finHz == gFinHzCache[i]) && (foutHz == gFoutHzCache[i]) && (useFeedbackDiv2 == gUseFeedbackDiv2Cache[i]) &&
1153 (useSS == gUseSSCache[i]))
1154 {
1155 /* Hit the target in cache buffer. */
1156 pSetup->syspllctrl = gPllSetupCacheStruct[i].syspllctrl;
1157 pSetup->syspllndec = gPllSetupCacheStruct[i].syspllndec;
1158 pSetup->syspllpdec = gPllSetupCacheStruct[i].syspllpdec;
1159 pSetup->syspllssctrl[0] = gPllSetupCacheStruct[i].syspllssctrl[0];
1160 pSetup->syspllssctrl[1] = gPllSetupCacheStruct[i].syspllssctrl[1];
1161 retErr = kStatus_PLL_Success;
1162 break;
1163 }
1164 }
1165
1166 if (i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1167 {
1168 return retErr;
1169 }
1170#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1171
1172 retErr = CLOCK_GetPllConfigInternal(finHz, foutHz, pSetup, useFeedbackDiv2, useSS);
1173
1174#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1175 /* Cache the most recent calulation result into buffer. */
1176 gFinHzCache[gPllSetupCacheIdx] = finHz;
1177 gFoutHzCache[gPllSetupCacheIdx] = foutHz;
1178 gUseFeedbackDiv2Cache[gPllSetupCacheIdx] = useFeedbackDiv2;
1179 gUseSSCache[gPllSetupCacheIdx] = useSS;
1180
1181 gPllSetupCacheStruct[gPllSetupCacheIdx].syspllctrl = pSetup->syspllctrl;
1182 gPllSetupCacheStruct[gPllSetupCacheIdx].syspllndec = pSetup->syspllndec;
1183 gPllSetupCacheStruct[gPllSetupCacheIdx].syspllpdec = pSetup->syspllpdec;
1184 gPllSetupCacheStruct[gPllSetupCacheIdx].syspllssctrl[0] = pSetup->syspllssctrl[0];
1185 gPllSetupCacheStruct[gPllSetupCacheIdx].syspllssctrl[1] = pSetup->syspllssctrl[1];
1186 /* Update the index for next available buffer. */
1187 gPllSetupCacheIdx = (gPllSetupCacheIdx + 1U) % CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT;
1188#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1189
1190 return retErr;
1191}
1192
1193/* Update local PLL rate variable */
1194static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup)
1195{
1196 s_Pll_Freq = CLOCK_GetSystemPLLOutFromSetup(pSetup);
1197}
1198
1199/* Return System PLL input clock rate */
1200/*! brief Return System PLL input clock rate
1201 * return System PLL input clock rate
1202 */
1203uint32_t CLOCK_GetSystemPLLInClockRate(void)
1204{
1205 uint32_t clkRate = 0U;
1206
1207 switch ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK))
1208 {
1209 case 0x00U:
1210 clkRate = CLK_FRO_12MHZ;
1211 break;
1212
1213 case 0x01U:
1214 clkRate = CLOCK_GetExtClkFreq();
1215 break;
1216
1217 case 0x02U:
1218 clkRate = CLOCK_GetWdtOscFreq();
1219 break;
1220
1221 case 0x03U:
1222 clkRate = CLOCK_GetOsc32KFreq();
1223 break;
1224
1225 default:
1226 clkRate = 0U;
1227 break;
1228 }
1229
1230 return clkRate;
1231}
1232
1233/* Return System PLL output clock rate from setup structure */
1234/*! brief Return System PLL output clock rate from setup structure
1235 * param pSetup : Pointer to a PLL setup structure
1236 * return System PLL output clock rate calculated from the setup structure
1237 */
1238uint32_t CLOCK_GetSystemPLLOutFromSetup(pll_setup_t *pSetup)
1239{
1240 uint32_t prediv, postdiv, mMult, inPllRate;
1241 uint64_t workRate;
1242
1243 /* Get the input clock frequency of PLL. */
1244 inPllRate = CLOCK_GetSystemPLLInClockRate();
1245
1246 /*
1247 * If the PLL is bypassed, PLL would not be used and the output of PLL module would just be the input clock.
1248 */
1249 if ((pSetup->syspllctrl & (SYSCON_SYSPLLCTRL_BYPASS_MASK)) == 0U)
1250 {
1251 /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
1252 /*
1253 * 1. Pre-divider
1254 * Pre-divider is only available when the DIRECTI is disabled.
1255 */
1256 if (0U == (pSetup->syspllctrl & SYSCON_SYSPLLCTRL_DIRECTI_MASK))
1257 {
1258 prediv = findPllPreDiv(pSetup->syspllctrl, pSetup->syspllndec);
1259 }
1260 else
1261 {
1262 prediv = 1U; /* The pre-divider is bypassed. */
1263 }
1264 /* Adjust input clock */
1265 inPllRate = inPllRate / prediv;
1266
1267 /*
1268 * 2. M divider
1269 * If using the SS, use the multiplier.
1270 */
1271 if ((pSetup->syspllssctrl[1] & (SYSCON_SYSPLLSSCTRL1_PD_MASK)) != 0UL)
1272 {
1273 /* MDEC used for rate */
1274 mMult = findPllMMult(pSetup->syspllctrl, pSetup->syspllssctrl[0]);
1275 workRate = (uint64_t)inPllRate * (uint64_t)mMult;
1276 }
1277 else
1278 {
1279 uint64_t fract;
1280
1281 /* SS multipler used for rate */
1282 mMult = (pSetup->syspllssctrl[1] & PLL_SSCG1_MD_INT_M) >> PLL_SSCG1_MD_INT_P;
1283 workRate = (uint64_t)inPllRate * (uint64_t)mMult;
1284
1285 /* Adjust by fractional */
1286 fract = (uint32_t)(((uint64_t)(pSetup->syspllssctrl[1]) & PLL_SSCG1_MD_FRACT_M) >> PLL_SSCG1_MD_FRACT_P);
1287 workRate = workRate + ((inPllRate * fract) / 0x800U);
1288 }
1289
1290 /*
1291 * 3. Post-divider
1292 * Post-divider is only available when the DIRECTO is disabled.
1293 */
1294 if (0U == (pSetup->syspllctrl & SYSCON_SYSPLLCTRL_DIRECTO_MASK))
1295 {
1296 postdiv = findPllPostDiv(pSetup->syspllctrl, pSetup->syspllpdec);
1297 }
1298 else
1299 {
1300 postdiv = 1U; /* The post-divider is bypassed. */
1301 }
1302 workRate = workRate / ((uint64_t)postdiv);
1303 }
1304 else
1305 {
1306 /* In bypass mode */
1307 workRate = (uint64_t)inPllRate;
1308 }
1309
1310 return (uint32_t)workRate;
1311}
1312
1313/* Set the current PLL Rate */
1314/*! brief Store the current PLL rate
1315 * param rate: Current rate of the PLL
1316 * return Nothing
1317 **/
1318void CLOCK_SetStoredPLLClockRate(uint32_t rate)
1319{
1320 s_Pll_Freq = rate;
1321}
1322
1323/* Return System PLL output clock rate */
1324/*! brief Return System PLL output clock rate
1325 * param recompute : Forces a PLL rate recomputation if true
1326 * return System PLL output clock rate
1327 * note The PLL rate is cached in the driver in a variable as
1328 * the rate computation function can take some time to perform. It
1329 * is recommended to use 'false' with the 'recompute' parameter.
1330 */
1331uint32_t CLOCK_GetSystemPLLOutClockRate(bool recompute)
1332{
1333 pll_setup_t Setup;
1334 uint32_t rate;
1335
1336 if ((recompute) || (s_Pll_Freq == 0U))
1337 {
1338 Setup.syspllctrl = SYSCON->SYSPLLCTRL;
1339 Setup.syspllndec = SYSCON->SYSPLLNDEC;
1340 Setup.syspllpdec = SYSCON->SYSPLLPDEC;
1341 Setup.syspllssctrl[0] = SYSCON->SYSPLLSSCTRL0;
1342 Setup.syspllssctrl[1] = SYSCON->SYSPLLSSCTRL1;
1343
1344 CLOCK_GetSystemPLLOutFromSetupUpdate(&Setup);
1345 }
1346
1347 rate = s_Pll_Freq;
1348
1349 return rate;
1350}
1351
1352/* Set PLL output based on the passed PLL setup data */
1353/*! brief Set PLL output based on the passed PLL setup data
1354 * param pControl : Pointer to populated PLL control structure to generate setup with
1355 * param pSetup : Pointer to PLL setup structure to be filled
1356 * return PLL_ERROR_SUCCESS on success, or PLL setup error code
1357 * note Actual frequency for setup may vary from the desired frequency based on the
1358 * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
1359 */
1360pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup)
1361{
1362 uint32_t inRate;
1363 bool useSS = (bool)((pControl->flags & PLL_CONFIGFLAG_FORCENOFRACT) == 0U);
1364 bool useFbDiv2;
1365
1366 pll_error_t pllError;
1367
1368 /* Determine input rate for the PLL */
1369 if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U)
1370 {
1371 inRate = pControl->inputRate;
1372 }
1373 else
1374 {
1375 inRate = CLOCK_GetSystemPLLInClockRate();
1376 }
1377
1378 if ((pSetup->flags & PLL_SETUPFLAG_USEFEEDBACKDIV2) != 0U)
1379 {
1380 useFbDiv2 = true;
1381 }
1382 else
1383 {
1384 useFbDiv2 = false;
1385 }
1386
1387 /* PLL flag options */
1388 pllError = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup, useFbDiv2, useSS);
1389 if ((useSS) && (pllError == kStatus_PLL_Success))
1390 {
1391 /* If using SS mode, then some tweaks are made to the generated setup */
1392 pSetup->syspllssctrl[1] |= (uint32_t)pControl->ss_mf | (uint32_t)pControl->ss_mr | (uint32_t)pControl->ss_mc;
1393 if (pControl->mfDither)
1394 {
1395 pSetup->syspllssctrl[1] |= (1UL << SYSCON_SYSPLLSSCTRL1_DITHER_SHIFT);
1396 }
1397 }
1398
1399 return pllError;
1400}
1401
1402/* Set PLL output from PLL setup structure */
1403/*! brief Set PLL output from PLL setup structure (precise frequency)
1404 * param pSetup : Pointer to populated PLL setup structure
1405 * param flagcfg : Flag configuration for PLL config structure
1406 * return PLL_ERROR_SUCCESS on success, or PLL setup error code
1407 * note This function will power off the PLL, setup the PLL with the
1408 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
1409 * and adjust system voltages to the new PLL rate. The function will not
1410 * alter any source clocks (ie, main systen clock) that may use the PLL,
1411 * so these should be setup prior to and after exiting the function.
1412 */
1413pll_error_t CLOCK_SetupSystemPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg)
1414{
1415 /* Power off PLL during setup changes */
1416 POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0);
1417
1418 pSetup->flags = flagcfg;
1419
1420 /* Write PLL setup data */
1421 SYSCON->SYSPLLCTRL = pSetup->syspllctrl;
1422 SYSCON->SYSPLLNDEC = pSetup->syspllndec;
1423 SYSCON->SYSPLLNDEC = pSetup->syspllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
1424 SYSCON->SYSPLLPDEC = pSetup->syspllpdec;
1425 SYSCON->SYSPLLPDEC = pSetup->syspllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
1426 SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0];
1427 SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0] | (1UL << SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT); /* latch */
1428 SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1];
1429 SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1] | (1UL << SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT); /* latch */
1430
1431 /* Flags for lock or power on */
1432 if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
1433 {
1434 /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
1435 uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
1436 uint32_t curSSCTRL = SYSCON->SYSPLLSSCTRL0 & ~(1UL << 17U);
1437
1438 /* Initialize and power up PLL */
1439 SYSCON->SYSPLLSSCTRL0 = maxCCO;
1440 POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
1441
1442 /* Set mreq to activate */
1443 SYSCON->SYSPLLSSCTRL0 = maxCCO | (1UL << 17U);
1444
1445 /* Delay for 72 uSec @ 12Mhz */
1446 SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1447
1448 /* clear mreq to prepare for restoring mreq */
1449 SYSCON->SYSPLLSSCTRL0 = curSSCTRL;
1450
1451 /* set original value back and activate */
1452 SYSCON->SYSPLLSSCTRL0 = curSSCTRL | (1UL << 17U);
1453
1454 /* Enable peripheral states by setting low */
1455 POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
1456 }
1457 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
1458 {
1459 while (CLOCK_IsSystemPLLLocked() == false)
1460 {
1461 }
1462 }
1463
1464 /* Update current programmed PLL rate var */
1465 CLOCK_GetSystemPLLOutFromSetupUpdate(pSetup);
1466
1467 /* System voltage adjustment, occurs prior to setting main system clock */
1468 if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0U)
1469 {
1470 POWER_SetVoltageForFreq(s_Pll_Freq);
1471 }
1472
1473 return kStatus_PLL_Success;
1474}
1475
1476/* Setup PLL Frequency from pre-calculated value */
1477/**
1478 * brief Set PLL output from PLL setup structure (precise frequency)
1479 * param pSetup : Pointer to populated PLL setup structure
1480 * return kStatus_PLL_Success on success, or PLL setup error code
1481 * note This function will power off the PLL, setup the PLL with the
1482 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
1483 * and adjust system voltages to the new PLL rate. The function will not
1484 * alter any source clocks (ie, main systen clock) that may use the PLL,
1485 * so these should be setup prior to and after exiting the function.
1486 */
1487pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup)
1488{
1489 /* Power off PLL during setup changes */
1490 POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0);
1491
1492 /* Write PLL setup data */
1493 SYSCON->SYSPLLCTRL = pSetup->syspllctrl;
1494 SYSCON->SYSPLLNDEC = pSetup->syspllndec;
1495 SYSCON->SYSPLLNDEC = pSetup->syspllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
1496 SYSCON->SYSPLLPDEC = pSetup->syspllpdec;
1497 SYSCON->SYSPLLPDEC = pSetup->syspllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
1498 SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0];
1499 SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0] | (1UL << SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT); /* latch */
1500 SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1];
1501 SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1] | (1UL << SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT); /* latch */
1502
1503 /* Flags for lock or power on */
1504 if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
1505 {
1506 /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
1507 uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
1508 uint32_t curSSCTRL = SYSCON->SYSPLLSSCTRL0 & ~(1UL << 17U);
1509
1510 /* Initialize and power up PLL */
1511 SYSCON->SYSPLLSSCTRL0 = maxCCO;
1512 POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
1513
1514 /* Set mreq to activate */
1515 SYSCON->SYSPLLSSCTRL0 = maxCCO | (1UL << 17U);
1516
1517 /* Delay for 72 uSec @ 12Mhz */
1518 SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1519
1520 /* clear mreq to prepare for restoring mreq */
1521 SYSCON->SYSPLLSSCTRL0 = curSSCTRL;
1522
1523 /* set original value back and activate */
1524 SYSCON->SYSPLLSSCTRL0 = curSSCTRL | (1UL << 17U);
1525
1526 /* Enable peripheral states by setting low */
1527 POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
1528 }
1529 if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
1530 {
1531 while (CLOCK_IsSystemPLLLocked() == false)
1532 {
1533 }
1534 }
1535
1536 /* Update current programmed PLL rate var */
1537 s_Pll_Freq = pSetup->pllRate;
1538
1539 return kStatus_PLL_Success;
1540}
1541
1542/* Set System PLL clock based on the input frequency and multiplier */
1543/*! brief Set PLL output based on the multiplier and input frequency
1544 * param multiply_by : multiplier
1545 * param input_freq : Clock input frequency of the PLL
1546 * return Nothing
1547 * note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
1548 * function does not disable or enable PLL power, wait for PLL lock,
1549 * or adjust system voltages. These must be done in the application.
1550 * The function will not alter any source clocks (ie, main systen clock)
1551 * that may use the PLL, so these should be setup prior to and after
1552 * exiting the function.
1553 */
1554void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq)
1555{
1556 uint32_t cco_freq = input_freq * multiply_by;
1557 uint32_t pdec = 1U;
1558 uint32_t selr;
1559 uint32_t seli;
1560 uint32_t selp;
1561 uint32_t mdec, ndec;
1562
1563 uint32_t directo = SYSCON_SYSPLLCTRL_DIRECTO(1);
1564
1565 while (cco_freq < 75000000U)
1566 {
1567 multiply_by <<= 1U; /* double value in each iteration */
1568 pdec <<= 1U; /* correspondingly double pdec to cancel effect of double msel */
1569 cco_freq = input_freq * multiply_by;
1570 }
1571 selr = 0U;
1572 if (multiply_by < 60U)
1573 {
1574 seli = (multiply_by & 0x3cU) + 4U;
1575 selp = (multiply_by >> 1U) + 1U;
1576 }
1577 else
1578 {
1579 selp = 31U;
1580 if (multiply_by > 16384U)
1581 {
1582 seli = 1U;
1583 }
1584 else if (multiply_by > 8192U)
1585 {
1586 seli = 2U;
1587 }
1588 else if (multiply_by > 2048U)
1589 {
1590 seli = 4U;
1591 }
1592 else if (multiply_by >= 501U)
1593 {
1594 seli = 8U;
1595 }
1596 else
1597 {
1598 seli = 4U * (1024U / (multiply_by + 9U));
1599 }
1600 }
1601
1602 if (pdec > 1U)
1603 {
1604 directo = 0U; /* use post divider */
1605 pdec = pdec / 2U; /* Account for minus 1 encoding */
1606 /* Translate P value */
1607 switch (pdec)
1608 {
1609 case 1U:
1610 pdec = 0x62U; /* 1 * 2 */
1611 break;
1612 case 2U:
1613 pdec = 0x42U; /* 2 * 2 */
1614 break;
1615 case 4U:
1616 pdec = 0x02U; /* 4 * 2 */
1617 break;
1618 case 8U:
1619 pdec = 0x0bU; /* 8 * 2 */
1620 break;
1621 case 16U:
1622 pdec = 0x11U; /* 16 * 2 */
1623 break;
1624 case 32U:
1625 pdec = 0x08U; /* 32 * 2 */
1626 break;
1627 default:
1628 pdec = 0x08U;
1629 break;
1630 }
1631 }
1632
1633 mdec = PLL_SSCG0_MDEC_VAL_SET(pllEncodeM(multiply_by));
1634 ndec = 0x302U; /* pre divide by 1 (hardcoded) */
1635
1636 SYSCON->SYSPLLCTRL = SYSCON_SYSPLLCTRL_BANDSEL(1) | directo | SYSCON_SYSPLLCTRL_BYPASSCCODIV2(1) |
1637 (selr << SYSCON_SYSPLLCTRL_SELR_SHIFT) | (seli << SYSCON_SYSPLLCTRL_SELI_SHIFT) |
1638 (selp << SYSCON_SYSPLLCTRL_SELP_SHIFT);
1639 SYSCON->SYSPLLPDEC = pdec | (1U << 7U); /* set Pdec value and assert preq */
1640 SYSCON->SYSPLLNDEC = ndec | (1UL << 10U); /* set Pdec value and assert preq */
1641 SYSCON->SYSPLLSSCTRL0 =
1642 (1UL << 18U) | (1UL << 17U) | mdec; /* select non sscg MDEC value, assert mreq and select mdec value */
1643}
1644bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq)
1645{
1646 bool ret = true;
1647
1648 CLOCK_DisableClock(kCLOCK_Usbd0);
1649
1650 if (kCLOCK_UsbSrcFro == src)
1651 {
1652 switch (freq)
1653 {
1654 case 96000000U:
1655 CLOCK_SetClkDiv(kCLOCK_DivUsbClk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
1656 break;
1657 case 48000000U:
1658 CLOCK_SetClkDiv(kCLOCK_DivUsbClk, 1, false); /*!< Div by 1 to get 48MHz, no divider reset */
1659 break;
1660 default:
1661 ret = false;
1662 break;
1663 }
1664 /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
1665 SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
1666 SYSCON_FROCTRL_USBCLKADJ_MASK;
1667 /* select FRO 96 or 48 MHz */
1668 CLOCK_AttachClk(kFRO_HF_to_USB_CLK);
1669 }
1670 else
1671 {
1672 /*TODO , we only implement FRO as usb clock source*/
1673 ret = false;
1674 }
1675
1676 CLOCK_EnableClock(kCLOCK_Usbd0);
1677
1678 return ret;
1679}
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_clock.h b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_clock.h
new file mode 100644
index 000000000..12c9936c4
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_clock.h
@@ -0,0 +1,835 @@
1/*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2019 , NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10#ifndef _FSL_CLOCK_H_
11#define _FSL_CLOCK_H_
12
13#include "fsl_common.h"
14
15/*! @addtogroup clock */
16/*! @{ */
17
18/*! @file */
19
20/*******************************************************************************
21 * Definitions
22 *****************************************************************************/
23
24/*! @name Driver version */
25/*@{*/
26/*! @brief CLOCK driver version 2.4.1. */
27#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 4, 1))
28/*@}*/
29
30/* Definition for delay API in clock driver, users can redefine it to the real application. */
31#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
32#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (150000000UL)
33#endif
34
35/*!
36 * @brief User-defined the size of cache for CLOCK_PllGetConfig() function.
37 *
38 * Once define this MACRO to be non-zero value, CLOCK_PllGetConfig() function
39 * would cache the recent calulation and accelerate the execution to get the
40 * right settings.
41 */
42#ifndef CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT
43#define CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT 2U
44#endif
45
46/*! @brief Clock ip name array for FLEXCOMM. */
47#define FLEXCOMM_CLOCKS \
48 { \
49 kCLOCK_FlexComm0, kCLOCK_FlexComm1, kCLOCK_FlexComm2, kCLOCK_FlexComm3, kCLOCK_FlexComm4, kCLOCK_FlexComm5, \
50 kCLOCK_FlexComm6, kCLOCK_FlexComm7 \
51 }
52/*! @brief Clock ip name array for LPUART. */
53#define LPUART_CLOCKS \
54 { \
55 kCLOCK_MinUart0, kCLOCK_MinUart1, kCLOCK_MinUart2, kCLOCK_MinUart3, kCLOCK_MinUart4, kCLOCK_MinUart5, \
56 kCLOCK_MinUart6, kCLOCK_MinUart7 \
57 }
58
59/*! @brief Clock ip name array for BI2C. */
60#define BI2C_CLOCKS \
61 { \
62 kCLOCK_BI2c0, kCLOCK_BI2c1, kCLOCK_BI2c2, kCLOCK_BI2c3, kCLOCK_BI2c4, kCLOCK_BI2c5, kCLOCK_BI2c6, kCLOCK_BI2c7 \
63 }
64/*! @brief Clock ip name array for LSPI. */
65#define LPSI_CLOCKS \
66 { \
67 kCLOCK_LSpi0, kCLOCK_LSpi1, kCLOCK_LSpi2, kCLOCK_LSpi3, kCLOCK_LSpi4, kCLOCK_LSpi5, kCLOCK_LSpi6, kCLOCK_LSpi7 \
68 }
69/*! @brief Clock ip name array for FLEXI2S. */
70#define FLEXI2S_CLOCKS \
71 { \
72 kCLOCK_FlexI2s0, kCLOCK_FlexI2s1, kCLOCK_FlexI2s2, kCLOCK_FlexI2s3, kCLOCK_FlexI2s4, kCLOCK_FlexI2s5, \
73 kCLOCK_FlexI2s6, kCLOCK_FlexI2s7 \
74 }
75/*! @brief Clock ip name array for UTICK. */
76#define UTICK_CLOCKS \
77 { \
78 kCLOCK_Utick \
79 }
80/*! @brief Clock ip name array for DMA. */
81#define DMA_CLOCKS \
82 { \
83 kCLOCK_Dma \
84 }
85/*! @brief Clock ip name array for CT32B. */
86#define CTIMER_CLOCKS \
87 { \
88 kCLOCK_Ctimer0, kCLOCK_Ctimer1, kCLOCK_Ctimer3 \
89 }
90
91/*! @brief Clock ip name array for GPIO. */
92#define GPIO_CLOCKS \
93 { \
94 kCLOCK_Gpio0, kCLOCK_Gpio1 \
95 }
96/*! @brief Clock ip name array for ADC. */
97#define ADC_CLOCKS \
98 { \
99 kCLOCK_Adc0 \
100 }
101/*! @brief Clock ip name array for MRT. */
102#define MRT_CLOCKS \
103 { \
104 kCLOCK_Mrt \
105 }
106/*! @brief Clock ip name array for MRT. */
107#define SCT_CLOCKS \
108 { \
109 kCLOCK_Sct0 \
110 }
111/*! @brief Clock ip name array for RTC. */
112#define RTC_CLOCKS \
113 { \
114 kCLOCK_Rtc \
115 }
116/*! @brief Clock ip name array for WWDT. */
117#define WWDT_CLOCKS \
118 { \
119 kCLOCK_Wwdt \
120 }
121/*! @brief Clock ip name array for CRC. */
122#define CRC_CLOCKS \
123 { \
124 kCLOCK_Crc \
125 }
126/*! @brief Clock ip name array for USBD. */
127#define USBD_CLOCKS \
128 { \
129 kCLOCK_Usbd0 \
130 }
131
132/*! @brief Clock ip name array for GINT. GINT0 & GINT1 share same slot */
133#define GINT_CLOCKS \
134 { \
135 kCLOCK_Gint, kCLOCK_Gint \
136 }
137
138/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
139/*------------------------------------------------------------------------------
140 clock_ip_name_t definition:
141------------------------------------------------------------------------------*/
142
143#define CLK_GATE_REG_OFFSET_SHIFT 8U
144#define CLK_GATE_REG_OFFSET_MASK 0xFFFFFF00U
145#define CLK_GATE_BIT_SHIFT_SHIFT 0U
146#define CLK_GATE_BIT_SHIFT_MASK 0x000000FFU
147
148#define CLK_GATE_DEFINE(reg_offset, bit_shift) \
149 ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \
150 (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK))
151
152#define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((uint32_t)(x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT)
153#define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((uint32_t)(x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT)
154
155#define AHB_CLK_CTRL0 0
156#define AHB_CLK_CTRL1 1
157#define ASYNC_CLK_CTRL0 2
158
159/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
160typedef enum _clock_ip_name
161{
162 kCLOCK_IpInvalid = 0U,
163 kCLOCK_Rom = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 1),
164 kCLOCK_Flash = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 7),
165 kCLOCK_Fmc = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 8),
166 kCLOCK_InputMux = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 11),
167 kCLOCK_Iocon = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 13),
168 kCLOCK_Gpio0 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 14),
169 kCLOCK_Gpio1 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 15),
170 kCLOCK_Pint = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 18),
171 kCLOCK_Gint = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 19), /* GPIO_GLOBALINT0 and GPIO_GLOBALINT1 share the same slot */
172 kCLOCK_Dma = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 20),
173 kCLOCK_Crc = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 21),
174 kCLOCK_Wwdt = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 22),
175 kCLOCK_Rtc = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 23),
176 kCLOCK_Adc0 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 27),
177 kCLOCK_Mrt = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 0),
178 kCLOCK_Sct0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 2),
179 kCLOCK_Utick = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 10),
180 kCLOCK_FlexComm0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11),
181 kCLOCK_FlexComm1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12),
182 kCLOCK_FlexComm2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13),
183 kCLOCK_FlexComm3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14),
184 kCLOCK_FlexComm4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15),
185 kCLOCK_FlexComm5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16),
186 kCLOCK_FlexComm6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17),
187 kCLOCK_FlexComm7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18),
188 kCLOCK_MinUart0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11),
189 kCLOCK_MinUart1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12),
190 kCLOCK_MinUart2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13),
191 kCLOCK_MinUart3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14),
192 kCLOCK_MinUart4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15),
193 kCLOCK_MinUart5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16),
194 kCLOCK_MinUart6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17),
195 kCLOCK_MinUart7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18),
196 kCLOCK_LSpi0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11),
197 kCLOCK_LSpi1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12),
198 kCLOCK_LSpi2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13),
199 kCLOCK_LSpi3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14),
200 kCLOCK_LSpi4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15),
201 kCLOCK_LSpi5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16),
202 kCLOCK_LSpi6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17),
203 kCLOCK_LSpi7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18),
204 kCLOCK_BI2c0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11),
205 kCLOCK_BI2c1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12),
206 kCLOCK_BI2c2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13),
207 kCLOCK_BI2c3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14),
208 kCLOCK_BI2c4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15),
209 kCLOCK_BI2c5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16),
210 kCLOCK_BI2c6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17),
211 kCLOCK_BI2c7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18),
212 kCLOCK_FlexI2s0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11),
213 kCLOCK_FlexI2s1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12),
214 kCLOCK_FlexI2s2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13),
215 kCLOCK_FlexI2s3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14),
216 kCLOCK_FlexI2s4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15),
217 kCLOCK_FlexI2s5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16),
218 kCLOCK_FlexI2s6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17),
219 kCLOCK_FlexI2s7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18),
220 kCLOCK_Ct32b2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 22),
221 kCLOCK_Usbd0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 25),
222 kCLOCK_Ctimer0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 26),
223 kCLOCK_Ctimer1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 27),
224
225 kCLOCK_Ctimer3 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 13),
226} clock_ip_name_t;
227
228/*! @brief Clock name used to get clock frequency. */
229typedef enum _clock_name
230{
231 kCLOCK_CoreSysClk, /*!< Core/system clock (aka MAIN_CLK) */
232 kCLOCK_BusClk, /*!< Bus clock (AHB clock) */
233 kCLOCK_ClockOut, /*!< CLOCKOUT */
234 kCLOCK_FroHf, /*!< FRO48/96 */
235 kCLOCK_Fro12M, /*!< FRO12M */
236 kCLOCK_ExtClk, /*!< External Clock */
237 kCLOCK_PllOut, /*!< PLL Output */
238 kCLOCK_WdtOsc, /*!< Watchdog Oscillator */
239 kCLOCK_Frg, /*!< Frg Clock */
240 kCLOCK_AsyncApbClk, /*!< Async APB clock */
241 kCLOCK_FlexI2S, /*!< FlexI2S clock */
242} clock_name_t;
243
244/**
245 * Clock source selections for the asynchronous APB clock
246 */
247typedef enum _async_clock_src
248{
249 kCLOCK_AsyncMainClk = 0, /*!< Main System clock */
250 kCLOCK_AsyncFro12Mhz, /*!< 12MHz FRO */
251} async_clock_src_t;
252
253/*! @brief Clock Mux Switches
254 * The encoding is as follows each connection identified is 32bits wide while 24bits are valuable
255 * starting from LSB upwards
256 *
257 * [4 bits for choice, 0 means invalid choice] [8 bits mux ID]*
258 *
259 */
260
261#define CLK_ATTACH_ID(mux, sel, pos) ((((uint32_t)(mux) << 0U) | (((uint32_t)(sel) + 1U) & 0xFU) << 8U) << ((pos)*12U))
262#define MUX_A(mux, sel) CLK_ATTACH_ID((mux), (sel), 0U)
263#define MUX_B(mux, sel, selector) (CLK_ATTACH_ID((mux), (sel), 1U) | ((selector) << 24U))
264
265#define GET_ID_ITEM(connection) ((connection)&0xFFFU)
266#define GET_ID_NEXT_ITEM(connection) ((connection) >> 12U)
267#define GET_ID_ITEM_MUX(connection) ((uint8_t)((connection)&0xFFU))
268#define GET_ID_ITEM_SEL(connection) ((uint8_t)(((connection)&0xF00U) >> 8U) - 1U)
269#define GET_ID_SELECTOR(connection) ((connection)&0xF000000U)
270
271#define CM_MAINCLKSELA 0
272#define CM_MAINCLKSELB 1
273#define CM_CLKOUTCLKSELA 2
274#define CM_CLKOUTCLKSELB 3
275#define CM_SYSPLLCLKSEL 4
276#define CM_USBPLLCLKSEL 5
277#define CM_AUDPLLCLKSEL 6
278#define CM_SCTPLLCLKSEL 7
279#define CM_ADCASYNCCLKSEL 9
280#define CM_USBCLKSEL 10
281#define CM_USB1CLKSEL 11
282#define CM_FXCOMCLKSEL0 12
283#define CM_FXCOMCLKSEL1 13
284#define CM_FXCOMCLKSEL2 14
285#define CM_FXCOMCLKSEL3 15
286#define CM_FXCOMCLKSEL4 16
287#define CM_FXCOMCLKSEL5 17
288#define CM_FXCOMCLKSEL6 18
289#define CM_FXCOMCLKSEL7 19
290#define CM_FXCOMCLKSEL8 20
291#define CM_FXCOMCLKSEL9 21
292#define CM_FXCOMCLKSEL10 22
293#define CM_FXCOMCLKSEL11 23
294#define CM_FXI2S0MCLKCLKSEL 24
295#define CM_FXI2S1MCLKCLKSEL 25
296#define CM_FRGCLKSEL 26
297
298#define CM_ASYNCAPB 28U
299
300typedef enum _clock_attach_id
301{
302
303 kFRO12M_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 0, 0),
304 kEXT_CLK_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 1) | MUX_B(CM_MAINCLKSELB, 0, 0),
305 kWDT_OSC_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 2) | MUX_B(CM_MAINCLKSELB, 0, 0),
306 kFRO_HF_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 3) | MUX_B(CM_MAINCLKSELB, 0, 0),
307 kSYS_PLL_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 2, 0),
308 kOSC32K_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 3, 0),
309
310 kFRO12M_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 0),
311 kEXT_CLK_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 1),
312 kWDT_OSC_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 2),
313 kOSC32K_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 3),
314 kNONE_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 7),
315
316 kMAIN_CLK_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 0),
317 kFRO12M_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 1),
318
319 kMAIN_CLK_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 0),
320 kSYS_PLL_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 1),
321 kFRO_HF_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 2),
322 kNONE_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 7),
323
324 kFRO12M_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 0),
325 kFRO_HF_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 1),
326 kSYS_PLL_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 2),
327 kMCLK_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 3),
328 kFRG_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 4),
329 kNONE_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 7),
330
331 kFRO12M_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 0),
332 kFRO_HF_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 1),
333 kSYS_PLL_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 2),
334 kMCLK_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 3),
335 kFRG_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 4),
336 kNONE_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 7),
337
338 kFRO12M_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 0),
339 kFRO_HF_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 1),
340 kSYS_PLL_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 2),
341 kMCLK_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 3),
342 kFRG_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 4),
343 kNONE_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 7),
344
345 kFRO12M_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 0),
346 kFRO_HF_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 1),
347 kSYS_PLL_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 2),
348 kMCLK_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 3),
349 kFRG_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 4),
350 kNONE_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 7),
351
352 kFRO12M_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 0),
353 kFRO_HF_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 1),
354 kSYS_PLL_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 2),
355 kMCLK_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 3),
356 kFRG_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 4),
357 kNONE_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 7),
358
359 kFRO12M_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 0),
360 kFRO_HF_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 1),
361 kSYS_PLL_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 2),
362 kMCLK_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 3),
363 kFRG_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 4),
364 kNONE_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 7),
365
366 kFRO12M_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 0),
367 kFRO_HF_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 1),
368 kSYS_PLL_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 2),
369 kMCLK_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 3),
370 kFRG_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 4),
371 kNONE_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 7),
372
373 kFRO12M_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 0),
374 kFRO_HF_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 1),
375 kSYS_PLL_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 2),
376 kMCLK_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 3),
377 kFRG_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 4),
378 kNONE_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 7),
379
380 kMAIN_CLK_to_FRG = MUX_A(CM_FRGCLKSEL, 0),
381 kSYS_PLL_to_FRG = MUX_A(CM_FRGCLKSEL, 1),
382 kFRO12M_to_FRG = MUX_A(CM_FRGCLKSEL, 2),
383 kFRO_HF_to_FRG = MUX_A(CM_FRGCLKSEL, 3),
384 kNONE_to_FRG = MUX_A(CM_FRGCLKSEL, 7),
385
386 kFRO_HF_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 0),
387 kSYS_PLL_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 1),
388 kMAIN_CLK_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 2),
389 kNONE_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 7),
390
391 kFRO_HF_to_USB_CLK = MUX_A(CM_USBCLKSEL, 0),
392 kSYS_PLL_to_USB_CLK = MUX_A(CM_USBCLKSEL, 1),
393 kMAIN_CLK_to_USB_CLK = MUX_A(CM_USBCLKSEL, 2),
394 kNONE_to_USB_CLK = MUX_A(CM_USBCLKSEL, 7),
395
396 kMAIN_CLK_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 0),
397 kEXT_CLK_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 1),
398 kWDT_OSC_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 2),
399 kFRO_HF_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 3),
400 kSYS_PLL_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 4),
401 kFRO12M_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 5),
402 kOSC32K_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 6),
403 kNONE_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 7),
404 kNONE_to_NONE = (int)0x80000000U,
405} clock_attach_id_t;
406
407/* Clock dividers */
408typedef enum _clock_div_name
409{
410 kCLOCK_DivSystickClk = 0,
411 kCLOCK_DivTraceClk = 1,
412 kCLOCK_DivAhbClk = 32,
413 kCLOCK_DivClkOut = 33,
414 kCLOCK_DivAdcAsyncClk = 37,
415 kCLOCK_DivUsbClk = 38,
416 kCLOCK_DivFrg = 40,
417 kCLOCK_DivFxI2s0MClk = 43
418} clock_div_name_t;
419
420/*******************************************************************************
421 * API
422 ******************************************************************************/
423
424#if defined(__cplusplus)
425extern "C" {
426#endif /* __cplusplus */
427
428static inline void CLOCK_EnableClock(clock_ip_name_t clk)
429{
430 uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
431 if (index < 2UL)
432 {
433 SYSCON->AHBCLKCTRLSET[index] = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
434 }
435 else
436 {
437 ASYNC_SYSCON->ASYNCAPBCLKCTRLSET = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
438 }
439}
440
441static inline void CLOCK_DisableClock(clock_ip_name_t clk)
442{
443 uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
444 if (index < 2UL)
445 {
446 SYSCON->AHBCLKCTRLCLR[index] = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
447 }
448 else
449 {
450 ASYNC_SYSCON->ASYNCAPBCLKCTRLCLR = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
451 }
452}
453/**
454 * @brief FLASH Access time definitions
455 */
456typedef enum _clock_flashtim
457{
458 kCLOCK_Flash1Cycle = 0, /*!< Flash accesses use 1 CPU clock */
459 kCLOCK_Flash2Cycle, /*!< Flash accesses use 2 CPU clocks */
460 kCLOCK_Flash3Cycle, /*!< Flash accesses use 3 CPU clocks */
461 kCLOCK_Flash4Cycle, /*!< Flash accesses use 4 CPU clocks */
462 kCLOCK_Flash5Cycle, /*!< Flash accesses use 5 CPU clocks */
463 kCLOCK_Flash6Cycle, /*!< Flash accesses use 6 CPU clocks */
464 kCLOCK_Flash7Cycle, /*!< Flash accesses use 7 CPU clocks */
465} clock_flashtim_t;
466
467/**
468 * @brief Set FLASH memory access time in clocks
469 * @param clks : Clock cycles for FLASH access
470 * @return Nothing
471 */
472static inline void CLOCK_SetFLASHAccessCycles(clock_flashtim_t clks)
473{
474 uint32_t tmp;
475
476 tmp = SYSCON->FLASHCFG & ~(SYSCON_FLASHCFG_FLASHTIM_MASK);
477
478 /* Don't alter lower bits */
479 SYSCON->FLASHCFG = tmp | ((uint32_t)clks << SYSCON_FLASHCFG_FLASHTIM_SHIFT);
480}
481
482/**
483 * @brief Initialize the Core clock to given frequency (12, 48 or 96 MHz).
484 * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed output is
485 * enabled.
486 * @param iFreq : Desired frequency (must be one of CLK_FRO_12MHZ or CLK_FRO_48MHZ or CLK_FRO_96MHZ)
487 * @return returns success or fail status.
488 */
489status_t CLOCK_SetupFROClocking(uint32_t iFreq);
490/**
491 * @brief Configure the clock selection muxes.
492 * @param connection : Clock to be configured.
493 * @return Nothing
494 */
495void CLOCK_AttachClk(clock_attach_id_t connection);
496/**
497 * @brief Get the actual clock attach id.
498 * This fuction uses the offset in input attach id, then it reads the actual source value in
499 * the register and combine the offset to obtain an actual attach id.
500 * @param attachId : Clock attach id to get.
501 * @return Clock source value.
502 */
503clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId);
504/**
505 * @brief Setup peripheral clock dividers.
506 * @param div_name : Clock divider name
507 * @param divided_by_value: Value to be divided
508 * @param reset : Whether to reset the divider counter.
509 * @return Nothing
510 */
511void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset);
512/**
513 * @brief Set the flash wait states for the input freuqency.
514 * @param iFreq : Input frequency
515 * @return Nothing
516 */
517void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq);
518/*! @brief Return Frequency of selected clock
519 * @return Frequency of selected clock
520 */
521uint32_t CLOCK_GetFreq(clock_name_t clockName);
522
523/*! @brief Return Input frequency for the Fractional baud rate generator
524 * @return Input Frequency for FRG
525 */
526uint32_t CLOCK_GetFRGInputClock(void);
527
528/*! @brief Set output of the Fractional baud rate generator
529 * @param freq : Desired output frequency
530 * @return Error Code 0 - fail 1 - success
531 */
532uint32_t CLOCK_SetFRGClock(uint32_t freq);
533
534/*! @brief Return Frequency of FRO 12MHz
535 * @return Frequency of FRO 12MHz
536 */
537uint32_t CLOCK_GetFro12MFreq(void);
538/*! @brief Return Frequency of External Clock
539 * @return Frequency of External Clock. If no external clock is used returns 0.
540 */
541uint32_t CLOCK_GetExtClkFreq(void);
542/*! @brief Return Frequency of Watchdog Oscillator
543 * @return Frequency of Watchdog Oscillator
544 */
545uint32_t CLOCK_GetWdtOscFreq(void);
546/*! @brief Return Frequency of High-Freq output of FRO
547 * @return Frequency of High-Freq output of FRO
548 */
549uint32_t CLOCK_GetFroHfFreq(void);
550/*! @brief Return Frequency of PLL
551 * @return Frequency of PLL
552 */
553uint32_t CLOCK_GetPllOutFreq(void);
554/*! @brief Return Frequency of 32kHz osc
555 * @return Frequency of 32kHz osc
556 */
557uint32_t CLOCK_GetOsc32KFreq(void);
558/*! @brief Return Frequency of Core System
559 * @return Frequency of Core System
560 */
561uint32_t CLOCK_GetCoreSysClkFreq(void);
562/*! @brief Return Frequency of I2S MCLK Clock
563 * @return Frequency of I2S MCLK Clock
564 */
565uint32_t CLOCK_GetI2SMClkFreq(void);
566/*! @brief Return Frequency of Flexcomm functional Clock
567 * @return Frequency of Flexcomm functional Clock
568 */
569uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id);
570/*! brief Return Frequency of Usb Clock
571 * return Frequency of Usb Clock.
572 */
573uint32_t CLOCK_GetUsbClkFreq(void);
574/*! @brief Return Frequency of Adc Clock
575 * @return Frequency of Adc Clock.
576 */
577uint32_t CLOCK_GetAdcClkFreq(void);
578/*! @brief Return Frequency of ClockOut
579 * @return Frequency of ClockOut
580 */
581uint32_t CLOCK_GetClockOutClkFreq(void);
582/*! @brief Return Asynchronous APB Clock source
583 * @return Asynchronous APB CLock source
584 */
585__STATIC_INLINE async_clock_src_t CLOCK_GetAsyncApbClkSrc(void)
586{
587 return (async_clock_src_t)(uint32_t)(ASYNC_SYSCON->ASYNCAPBCLKSELA & 0x3UL);
588}
589/*! @brief Return Frequency of Asynchronous APB Clock
590 * @return Frequency of Asynchronous APB Clock Clock
591 */
592uint32_t CLOCK_GetAsyncApbClkFreq(void);
593/*! @brief Return System PLL input clock rate
594 * @return System PLL input clock rate
595 */
596uint32_t CLOCK_GetSystemPLLInClockRate(void);
597
598/*! @brief Return System PLL output clock rate
599 * @param recompute : Forces a PLL rate recomputation if true
600 * @return System PLL output clock rate
601 * @note The PLL rate is cached in the driver in a variable as
602 * the rate computation function can take some time to perform. It
603 * is recommended to use 'false' with the 'recompute' parameter.
604 */
605uint32_t CLOCK_GetSystemPLLOutClockRate(bool recompute);
606
607/*! @brief Enables and disables PLL bypass mode
608 * @brief bypass : true to bypass PLL (PLL output = PLL input, false to disable bypass
609 * @return System PLL output clock rate
610 */
611__STATIC_INLINE void CLOCK_SetBypassPLL(bool bypass)
612{
613 if (bypass)
614 {
615 SYSCON->SYSPLLCTRL |= (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT);
616 }
617 else
618 {
619 SYSCON->SYSPLLCTRL &= ~(1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT);
620 }
621}
622
623/*! @brief Check if PLL is locked or not
624 * @return true if the PLL is locked, false if not locked
625 */
626__STATIC_INLINE bool CLOCK_IsSystemPLLLocked(void)
627{
628 return (bool)((SYSCON->SYSPLLSTAT & SYSCON_SYSPLLSTAT_LOCK_MASK) != 0UL);
629}
630
631/*! @brief Store the current PLL rate
632 * @param rate: Current rate of the PLL
633 * @return Nothing
634 **/
635void CLOCK_SetStoredPLLClockRate(uint32_t rate);
636
637/*! @brief PLL configuration structure flags for 'flags' field
638 * These flags control how the PLL configuration function sets up the PLL setup structure.<br>
639 *
640 * When the PLL_CONFIGFLAG_USEINRATE flag is selected, the 'InputRate' field in the
641 * configuration structure must be assigned with the expected PLL frequency. If the
642 * PLL_CONFIGFLAG_USEINRATE is not used, 'InputRate' is ignored in the configuration
643 * function and the driver will determine the PLL rate from the currently selected
644 * PLL source. This flag might be used to configure the PLL input clock more accurately
645 * when using the WDT oscillator or a more dyanmic CLKIN source.<br>
646 *
647 * When the PLL_CONFIGFLAG_FORCENOFRACT flag is selected, the PLL hardware for the
648 * automatic bandwidth selection, Spread Spectrum (SS) support, and fractional M-divider
649 * are not used.<br>
650 */
651#define PLL_CONFIGFLAG_USEINRATE (1U << 0U) /*!< Flag to use InputRate in PLL configuration structure for setup */
652#define PLL_CONFIGFLAG_FORCENOFRACT \
653 (1U << 2U) /*!< Force non-fractional output mode, PLL output will not use the fractional, automatic bandwidth, or \
654 SS hardware */
655
656/*! @brief PLL Spread Spectrum (SS) Programmable modulation frequency
657 * See (MF) field in the SYSPLLSSCTRL1 register in the UM.
658 */
659typedef enum _ss_progmodfm
660{
661 kSS_MF_512 = (0 << 20), /*!< Nss = 512 (fm ? 3.9 - 7.8 kHz) */
662 kSS_MF_384 = (1 << 20), /*!< Nss ?= 384 (fm ? 5.2 - 10.4 kHz) */
663 kSS_MF_256 = (2 << 20), /*!< Nss = 256 (fm ? 7.8 - 15.6 kHz) */
664 kSS_MF_128 = (3 << 20), /*!< Nss = 128 (fm ? 15.6 - 31.3 kHz) */
665 kSS_MF_64 = (4 << 20), /*!< Nss = 64 (fm ? 32.3 - 64.5 kHz) */
666 kSS_MF_32 = (5 << 20), /*!< Nss = 32 (fm ? 62.5- 125 kHz) */
667 kSS_MF_24 = (6 << 20), /*!< Nss ?= 24 (fm ? 83.3- 166.6 kHz) */
668 kSS_MF_16 = (7 << 20) /*!< Nss = 16 (fm ? 125- 250 kHz) */
669} ss_progmodfm_t;
670
671/*! @brief PLL Spread Spectrum (SS) Programmable frequency modulation depth
672 * See (MR) field in the SYSPLLSSCTRL1 register in the UM.
673 */
674typedef enum _ss_progmoddp
675{
676 kSS_MR_K0 = (0 << 23), /*!< k = 0 (no spread spectrum) */
677 kSS_MR_K1 = (1 << 23), /*!< k = 1 */
678 kSS_MR_K1_5 = (2 << 23), /*!< k = 1.5 */
679 kSS_MR_K2 = (3 << 23), /*!< k = 2 */
680 kSS_MR_K3 = (4 << 23), /*!< k = 3 */
681 kSS_MR_K4 = (5 << 23), /*!< k = 4 */
682 kSS_MR_K6 = (6 << 23), /*!< k = 6 */
683 kSS_MR_K8 = (7 << 23) /*!< k = 8 */
684} ss_progmoddp_t;
685
686/*! @brief PLL Spread Spectrum (SS) Modulation waveform control
687 * See (MC) field in the SYSPLLSSCTRL1 register in the UM.<br>
688 * Compensation for low pass filtering of the PLL to get a triangular
689 * modulation at the output of the PLL, giving a flat frequency spectrum.
690 */
691typedef enum _ss_modwvctrl
692{
693 kSS_MC_NOC = (0 << 26), /*!< no compensation */
694 kSS_MC_RECC = (2 << 26), /*!< recommended setting */
695 kSS_MC_MAXC = (3 << 26), /*!< max. compensation */
696} ss_modwvctrl_t;
697
698/*! @brief PLL configuration structure
699 *
700 * This structure can be used to configure the settings for a PLL
701 * setup structure. Fill in the desired configuration for the PLL
702 * and call the PLL setup function to fill in a PLL setup structure.
703 */
704typedef struct _pll_config
705{
706 uint32_t desiredRate; /*!< Desired PLL rate in Hz */
707 uint32_t inputRate; /*!< PLL input clock in Hz, only used if PLL_CONFIGFLAG_USEINRATE flag is set */
708 uint32_t flags; /*!< PLL configuration flags, Or'ed value of PLL_CONFIGFLAG_* definitions */
709 ss_progmodfm_t ss_mf; /*!< SS Programmable modulation frequency, only applicable when not using
710 PLL_CONFIGFLAG_FORCENOFRACT flag */
711 ss_progmoddp_t ss_mr; /*!< SS Programmable frequency modulation depth, only applicable when not using
712 PLL_CONFIGFLAG_FORCENOFRACT flag */
713 ss_modwvctrl_t
714 ss_mc; /*!< SS Modulation waveform control, only applicable when not using PLL_CONFIGFLAG_FORCENOFRACT flag */
715 bool mfDither; /*!< false for fixed modulation frequency or true for dithering, only applicable when not using
716 PLL_CONFIGFLAG_FORCENOFRACT flag */
717
718} pll_config_t;
719
720/*! @brief PLL setup structure flags for 'flags' field
721 * These flags control how the PLL setup function sets up the PLL
722 */
723#define PLL_SETUPFLAG_POWERUP (1U << 0U) /*!< Setup will power on the PLL after setup */
724#define PLL_SETUPFLAG_WAITLOCK (1U << 1U) /*!< Setup will wait for PLL lock, implies the PLL will be pwoered on */
725#define PLL_SETUPFLAG_ADGVOLT (1U << 2U) /*!< Optimize system voltage for the new PLL rate */
726#define PLL_SETUPFLAG_USEFEEDBACKDIV2 (1U << 3U) /*!< Use feedback divider by 2 in divider path */
727
728/*! @brief PLL setup structure
729 * This structure can be used to pre-build a PLL setup configuration
730 * at run-time and quickly set the PLL to the configuration. It can be
731 * populated with the PLL setup function. If powering up or waiting
732 * for PLL lock, the PLL input clock source should be configured prior
733 * to PLL setup.
734 */
735typedef struct _pll_setup
736{
737 uint32_t syspllctrl; /*!< PLL control register SYSPLLCTRL */
738 uint32_t syspllndec; /*!< PLL NDEC register SYSPLLNDEC */
739 uint32_t syspllpdec; /*!< PLL PDEC register SYSPLLPDEC */
740 uint32_t syspllssctrl[2]; /*!< PLL SSCTL registers SYSPLLSSCTRL */
741 uint32_t pllRate; /*!< Acutal PLL rate */
742 uint32_t flags; /*!< PLL setup flags, Or'ed value of PLL_SETUPFLAG_* definitions */
743} pll_setup_t;
744
745/*! @brief PLL status definitions
746 */
747typedef enum _pll_error
748{
749 kStatus_PLL_Success = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< PLL operation was successful */
750 kStatus_PLL_OutputTooLow = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< PLL output rate request was too low */
751 kStatus_PLL_OutputTooHigh = MAKE_STATUS(kStatusGroup_Generic, 2), /*!< PLL output rate request was too high */
752 kStatus_PLL_InputTooLow = MAKE_STATUS(kStatusGroup_Generic, 3), /*!< PLL input rate is too low */
753 kStatus_PLL_InputTooHigh = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< PLL input rate is too high */
754 kStatus_PLL_OutsideIntLimit = MAKE_STATUS(kStatusGroup_Generic, 5) /*!< Requested output rate isn't possible */
755} pll_error_t;
756
757/*! @brief USB clock source definition. */
758typedef enum _clock_usb_src
759{
760 kCLOCK_UsbSrcFro = (uint32_t)kCLOCK_FroHf, /*!< Use FRO 96 or 48 MHz. */
761 kCLOCK_UsbSrcSystemPll = (uint32_t)kCLOCK_PllOut, /*!< Use System PLL output. */
762 kCLOCK_UsbSrcMainClock = (uint32_t)kCLOCK_CoreSysClk, /*!< Use Main clock. */
763 kCLOCK_UsbSrcNone = SYSCON_USBCLKSEL_SEL(
764 7) /*!< Use None, this may be selected in order to reduce power when no output is needed. */
765} clock_usb_src_t;
766
767/*! @brief Return System PLL output clock rate from setup structure
768 * @param pSetup : Pointer to a PLL setup structure
769 * @return System PLL output clock rate calculated from the setup structure
770 */
771uint32_t CLOCK_GetSystemPLLOutFromSetup(pll_setup_t *pSetup);
772
773/*! @brief Set PLL output based on the passed PLL setup data
774 * @param pControl : Pointer to populated PLL control structure to generate setup with
775 * @param pSetup : Pointer to PLL setup structure to be filled
776 * @return PLL_ERROR_SUCCESS on success, or PLL setup error code
777 * @note Actual frequency for setup may vary from the desired frequency based on the
778 * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
779 */
780pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup);
781
782/*! @brief Set PLL output from PLL setup structure (precise frequency)
783 * @param pSetup : Pointer to populated PLL setup structure
784 * @param flagcfg : Flag configuration for PLL config structure
785 * @return PLL_ERROR_SUCCESS on success, or PLL setup error code
786 * @note This function will power off the PLL, setup the PLL with the
787 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
788 * and adjust system voltages to the new PLL rate. The function will not
789 * alter any source clocks (ie, main systen clock) that may use the PLL,
790 * so these should be setup prior to and after exiting the function.
791 */
792pll_error_t CLOCK_SetupSystemPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg);
793
794/**
795 * @brief Set PLL output from PLL setup structure (precise frequency)
796 * @param pSetup : Pointer to populated PLL setup structure
797 * @return kStatus_PLL_Success on success, or PLL setup error code
798 * @note This function will power off the PLL, setup the PLL with the
799 * new setup data, and then optionally powerup the PLL, wait for PLL lock,
800 * and adjust system voltages to the new PLL rate. The function will not
801 * alter any source clocks (ie, main systen clock) that may use the PLL,
802 * so these should be setup prior to and after exiting the function.
803 */
804pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup);
805
806/*! @brief Set PLL output based on the multiplier and input frequency
807 * @param multiply_by : multiplier
808 * @param input_freq : Clock input frequency of the PLL
809 * @return Nothing
810 * @note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
811 * function does not disable or enable PLL power, wait for PLL lock,
812 * or adjust system voltages. These must be done in the application.
813 * The function will not alter any source clocks (ie, main systen clock)
814 * that may use the PLL, so these should be setup prior to and after
815 * exiting the function.
816 */
817void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq);
818
819/*! @brief Disable USB FS clock.
820 *
821 * Disable USB FS clock.
822 */
823static inline void CLOCK_DisableUsbfs0Clock(void)
824{
825 CLOCK_DisableClock(kCLOCK_Usbd0);
826}
827bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq);
828
829#if defined(__cplusplus)
830}
831#endif /* __cplusplus */
832
833/*! @} */
834
835#endif /* _FSL_CLOCK_H_ */
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_fro_calib.h b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_fro_calib.h
new file mode 100644
index 000000000..49804d07d
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_fro_calib.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2019 , NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10#ifndef __FSL_FRO_CALIB_H_
11#define __FSL_FRO_CALIB_H_
12
13/* Component ID definition, used by tools. */
14#ifndef FSL_COMPONENT_ID
15#define FSL_COMPONENT_ID "platform.drivers.fro_calib"
16#endif
17
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23/** @defgroup FRO_CALIB_LIB_5411X CHIP: LPC5411X FRO CALIBRATION LIBRARY functions
24 * The FRO Calibration library provides functions to control FRO clock frequency.<br>
25 * @ingroup CHIP_5411X_DRIVERS
26 * @{
27 */
28
29/* Returns the version of the FRO Calibration library */
30unsigned int fro_calib_Get_Lib_Ver(void);
31
32/* timer instance */
33/* timer clock frquency in KHz */
34ErrorCode_t Chip_TIMER_Instance_Freq(CTIMER_Type *base, unsigned int timerFreq);
35
36/* USB_SOF_Event */
37ErrorCode_t USB_SOF_Event(USBD_HANDLE_T hUsb);
38
39/**
40 * @}
41 */
42
43#ifdef __cplusplus
44}
45#endif
46
47#endif /* __FSL_FRO_CALIB_H_ */
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_inputmux_connections.h b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_inputmux_connections.h
new file mode 100644
index 000000000..e1eec896a
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_inputmux_connections.h
@@ -0,0 +1,151 @@
1/*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016, NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10#ifndef _FSL_INPUTMUX_CONNECTIONS_
11#define _FSL_INPUTMUX_CONNECTIONS_
12
13/*******************************************************************************
14 * Definitions
15 ******************************************************************************/
16/* Component ID definition, used by tools. */
17#ifndef FSL_COMPONENT_ID
18#define FSL_COMPONENT_ID "platform.drivers.inputmux_connections"
19#endif
20
21/*!
22 * @addtogroup inputmux_driver
23 * @{
24 */
25
26/*! @brief Periphinmux IDs */
27#define PINTSEL_PMUX_ID 0xC0U
28#define DMA_TRIG0_PMUX_ID 0xE0U
29#define DMA_OTRIG_PMUX_ID 0x160U
30#define FREQMEAS_PMUX_ID 0x180U
31#define PMUX_SHIFT 20U
32
33/*! @brief INPUTMUX connections type */
34typedef enum _inputmux_connection_t
35{
36 /*!< Frequency measure. */
37 kINPUTMUX_MainOscToFreqmeas = 0U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
38 kINPUTMUX_Fro12MhzToFreqmeas = 1U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
39 kINPUTMUX_WdtOscToFreqmeas = 2U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
40 kINPUTMUX_32KhzOscToFreqmeas = 3U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
41 kINPUTMUX_MainClkToFreqmeas = 4U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
42 kINPUTMUX_GpioPort0Pin4ToFreqmeas = 5U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
43 kINPUTMUX_GpioPort0Pin20ToFreqmeas = 6U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
44 kINPUTMUX_GpioPort0Pin24ToFreqmeas = 7U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
45 kINPUTMUX_GpioPort1Pin4ToFreqmeas = 8U + (FREQMEAS_PMUX_ID << PMUX_SHIFT),
46 /*!< Pin Interrupt. */
47 kINPUTMUX_GpioPort0Pin0ToPintsel = 0U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
48 kINPUTMUX_GpioPort0Pin1ToPintsel = 1U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
49 kINPUTMUX_GpioPort0Pin2ToPintsel = 2U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
50 kINPUTMUX_GpioPort0Pin3ToPintsel = 3U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
51 kINPUTMUX_GpioPort0Pin4ToPintsel = 4U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
52 kINPUTMUX_GpioPort0Pin5ToPintsel = 5U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
53 kINPUTMUX_GpioPort0Pin6ToPintsel = 6U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
54 kINPUTMUX_GpioPort0Pin7ToPintsel = 7U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
55 kINPUTMUX_GpioPort0Pin8ToPintsel = 8U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
56 kINPUTMUX_GpioPort0Pin9ToPintsel = 9U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
57 kINPUTMUX_GpioPort0Pin10ToPintsel = 10U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
58 kINPUTMUX_GpioPort0Pin11ToPintsel = 11U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
59 kINPUTMUX_GpioPort0Pin12ToPintsel = 12U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
60 kINPUTMUX_GpioPort0Pin13ToPintsel = 13U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
61 kINPUTMUX_GpioPort0Pin14ToPintsel = 14U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
62 kINPUTMUX_GpioPort0Pin15ToPintsel = 15U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
63 kINPUTMUX_GpioPort0Pin16ToPintsel = 16U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
64 kINPUTMUX_GpioPort0Pin17ToPintsel = 17U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
65 kINPUTMUX_GpioPort0Pin18ToPintsel = 18U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
66 kINPUTMUX_GpioPort0Pin19ToPintsel = 19U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
67 kINPUTMUX_GpioPort0Pin20ToPintsel = 20U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
68 kINPUTMUX_GpioPort0Pin21ToPintsel = 21U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
69 kINPUTMUX_GpioPort0Pin22ToPintsel = 22U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
70 kINPUTMUX_GpioPort0Pin23ToPintsel = 23U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
71 kINPUTMUX_GpioPort0Pin24ToPintsel = 24U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
72 kINPUTMUX_GpioPort0Pin25ToPintsel = 25U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
73 kINPUTMUX_GpioPort0Pin26ToPintsel = 26U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
74 kINPUTMUX_GpioPort0Pin27ToPintsel = 27U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
75 kINPUTMUX_GpioPort0Pin28ToPintsel = 28U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
76 kINPUTMUX_GpioPort0Pin29ToPintsel = 29U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
77 kINPUTMUX_GpioPort0Pin30ToPintsel = 30U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
78 kINPUTMUX_GpioPort0Pin31ToPintsel = 31U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
79 kINPUTMUX_GpioPort1Pin0ToPintsel = 32U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
80 kINPUTMUX_GpioPort1Pin1ToPintsel = 33U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
81 kINPUTMUX_GpioPort1Pin2ToPintsel = 34U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
82 kINPUTMUX_GpioPort1Pin3ToPintsel = 35U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
83 kINPUTMUX_GpioPort1Pin4ToPintsel = 36U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
84 kINPUTMUX_GpioPort1Pin5ToPintsel = 37U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
85 kINPUTMUX_GpioPort1Pin6ToPintsel = 38U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
86 kINPUTMUX_GpioPort1Pin7ToPintsel = 39U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
87 kINPUTMUX_GpioPort1Pin8ToPintsel = 40U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
88 kINPUTMUX_GpioPort1Pin9ToPintsel = 41U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
89 kINPUTMUX_GpioPort1Pin10ToPintsel = 42U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
90 kINPUTMUX_GpioPort1Pin11ToPintsel = 43U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
91 kINPUTMUX_GpioPort1Pin12ToPintsel = 44U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
92 kINPUTMUX_GpioPort1Pin13ToPintsel = 45U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
93 kINPUTMUX_GpioPort1Pin14ToPintsel = 46U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
94 kINPUTMUX_GpioPort1Pin15ToPintsel = 47U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
95 kINPUTMUX_GpioPort1Pin16ToPintsel = 48U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
96 kINPUTMUX_GpioPort1Pin17ToPintsel = 49U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
97 kINPUTMUX_GpioPort1Pin18ToPintsel = 50U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
98 kINPUTMUX_GpioPort1Pin19ToPintsel = 51U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
99 kINPUTMUX_GpioPort1Pin20ToPintsel = 52U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
100 kINPUTMUX_GpioPort1Pin21ToPintsel = 53U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
101 kINPUTMUX_GpioPort1Pin22ToPintsel = 54U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
102 kINPUTMUX_GpioPort1Pin23ToPintsel = 55U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
103 kINPUTMUX_GpioPort1Pin24ToPintsel = 56U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
104 kINPUTMUX_GpioPort1Pin25ToPintsel = 57U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
105 kINPUTMUX_GpioPort1Pin26ToPintsel = 58U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
106 kINPUTMUX_GpioPort1Pin27ToPintsel = 59U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
107 kINPUTMUX_GpioPort1Pin28ToPintsel = 60U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
108 kINPUTMUX_GpioPort1Pin29ToPintsel = 61U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
109 kINPUTMUX_GpioPort1Pin30ToPintsel = 62U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
110 kINPUTMUX_GpioPort1Pin31ToPintsel = 63U + (PINTSEL_PMUX_ID << PMUX_SHIFT),
111 /*!< DMA ITRIG. */
112 kINPUTMUX_Adc0SeqaIrqToDma = 0U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
113 kINPUTMUX_ADC0SeqbIrqToDma = 1U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
114 kINPUTMUX_Sct0DmaReq0ToDma = 2U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
115 kINPUTMUX_Sct0DmaReq1ToDma = 3U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
116 kINPUTMUX_Ctimer0M0ToDma = 4U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
117 kINPUTMUX_Ctimer0M1ToDma = 5U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
118 kINPUTMUX_Ctimer1M0ToDma = 6U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
119 kINPUTMUX_Ctimer3M0ToDma = 9U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
120 kINPUTMUX_PinInt0ToDma = 12U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
121 kINPUTMUX_PinInt1ToDma = 13U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
122 kINPUTMUX_PinInt2ToDma = 14U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
123 kINPUTMUX_PinInt3ToDma = 15U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
124 kINPUTMUX_Otrig0ToDma = 16U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
125 kINPUTMUX_Otrig1ToDma = 17U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
126 kINPUTMUX_Otrig2ToDma = 18U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
127 kINPUTMUX_Otrig3ToDma = 19U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT),
128 /*!< DMA OTRIG. */
129 kINPUTMUX_DmaFlexcomm0RxTrigoutToTriginChannels = 0U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
130 kINPUTMUX_DmaFlexcomm0TxTrigoutToTriginChannels = 1U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
131 kINPUTMUX_DmaFlexcomm1RxTrigoutToTriginChannels = 2U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
132 kINPUTMUX_DmaFlexcomm1TxTrigoutToTriginChannels = 3U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
133 kINPUTMUX_DmaFlexcomm2RxTrigoutToTriginChannels = 4U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
134 kINPUTMUX_DmaFlexcomm2TxTrigoutToTriginChannels = 5U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
135 kINPUTMUX_DmaFlexcomm3RxTrigoutToTriginChannels = 6U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
136 kINPUTMUX_DmaFlexcomm3TxTrigoutToTriginChannels = 7U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
137 kINPUTMUX_DmaFlexcomm4RxTrigoutToTriginChannels = 8U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
138 kINPUTMUX_DmaFlexcomm4TxTrigoutToTriginChannels = 9U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
139 kINPUTMUX_DmaFlexcomm5RxTrigoutToTriginChannels = 10U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
140 kINPUTMUX_DmaFlexcomm5TxTrigoutToTriginChannels = 11U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
141 kINPUTMUX_DmaFlexcomm6RxTrigoutToTriginChannels = 12U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
142 kINPUTMUX_DmaFlexcomm6TxTrigoutToTriginChannels = 13U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
143 kINPUTMUX_DmaFlexcomm7RxTrigoutToTriginChannels = 14U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
144 kINPUTMUX_DmaFlexcomm7TxTrigoutToTriginChannels = 15U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
145 kINPUTMUX_DmaChannel18_TrigoutToTriginChannels = 18U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
146 kINPUTMUX_DmaChannel19_TrigoutToTriginChannels = 19U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT),
147} inputmux_connection_t;
148
149/*@}*/
150
151#endif /* _FSL_INPUTMUX_CONNECTIONS_ */
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_power.c b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_power.c
new file mode 100644
index 000000000..6cbd5e1e6
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_power.c
@@ -0,0 +1,20 @@
1/*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016, NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9#include "fsl_common.h"
10#include "fsl_power.h"
11/* Component ID definition, used by tools. */
12#ifndef FSL_COMPONENT_ID
13#define FSL_COMPONENT_ID "platform.drivers.power"
14#endif
15
16/*******************************************************************************
17 * Code
18 ******************************************************************************/
19
20/* Empty file since implementation is in header file and power library */
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_power.h b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_power.h
new file mode 100644
index 000000000..abcd00b83
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_power.h
@@ -0,0 +1,225 @@
1/*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016, NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9#ifndef _FSL_POWER_H_
10#define _FSL_POWER_H_
11
12#include "fsl_common.h"
13
14/*! @addtogroup power */
15/*! @{ */
16
17/*! @file */
18
19/*******************************************************************************
20 * Definitions
21 ******************************************************************************/
22
23/*! @name Driver version */
24/*@{*/
25/*! @brief power driver version 2.0.0. */
26#define FSL_POWER_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
27/*@}*/
28
29#define MAKE_PD_BITS(reg, slot) (((reg) << 8) | (slot))
30#define PDRCFG0 0x0U
31#define PDRCFG1 0x1U
32
33typedef enum pd_bits
34{
35 kPDRUNCFG_PD_FRO_EN = MAKE_PD_BITS(PDRCFG0, 4U),
36 kPDRUNCFG_PD_FLASH = MAKE_PD_BITS(PDRCFG0, 5U),
37 kPDRUNCFG_PD_TEMPS = MAKE_PD_BITS(PDRCFG0, 6U),
38 kPDRUNCFG_PD_BOD_RESET = MAKE_PD_BITS(PDRCFG0, 7U),
39 kPDRUNCFG_PD_BOD_INTR = MAKE_PD_BITS(PDRCFG0, 8U),
40 kPDRUNCFG_PD_ADC0 = MAKE_PD_BITS(PDRCFG0, 10U),
41 kPDRUNCFG_PD_VDDFLASH = MAKE_PD_BITS(PDRCFG0, 11U),
42 kPDRUNCFG_LP_VDDFLASH = MAKE_PD_BITS(PDRCFG0, 12U),
43 kPDRUNCFG_PD_RAM0 = MAKE_PD_BITS(PDRCFG0, 13U),
44 kPDRUNCFG_PD_RAM1 = MAKE_PD_BITS(PDRCFG0, 14U),
45 kPDRUNCFG_PD_RAM2 = MAKE_PD_BITS(PDRCFG0, 15U),
46 kPDRUNCFG_PD_RAMX = MAKE_PD_BITS(PDRCFG0, 16U),
47 kPDRUNCFG_PD_ROM = MAKE_PD_BITS(PDRCFG0, 17U),
48 kPDRUNCFG_PD_VDDHV_ENA = MAKE_PD_BITS(PDRCFG0, 18U),
49 kPDRUNCFG_PD_VD7_ENA = MAKE_PD_BITS(PDRCFG0, 19U),
50 kPDRUNCFG_PD_WDT_OSC = MAKE_PD_BITS(PDRCFG0, 20U),
51 kPDRUNCFG_PD_USB0_PHY = MAKE_PD_BITS(PDRCFG0, 21U),
52 kPDRUNCFG_PD_SYS_PLL0 = MAKE_PD_BITS(PDRCFG0, 22U),
53 kPDRUNCFG_PD_VREFP_SW = MAKE_PD_BITS(PDRCFG0, 23U),
54 kPDRUNCFG_PD_FLASH_BG = MAKE_PD_BITS(PDRCFG0, 25U),
55
56 kPDRUNCFG_PD_ALT_FLASH_IBG = MAKE_PD_BITS(PDRCFG1, 28U),
57 kPDRUNCFG_SEL_ALT_FLASH_IBG = MAKE_PD_BITS(PDRCFG1, 29U),
58
59 kPDRUNCFG_ForceUnsigned = (int)0x80000000U
60} pd_bit_t;
61
62/* Power mode configuration API parameter */
63typedef enum _power_mode_config
64{
65 kPmu_Sleep = 0U,
66 kPmu_Deep_Sleep = 1U,
67 kPmu_Deep_PowerDown = 2U,
68} power_mode_cfg_t;
69
70/*******************************************************************************
71 * API
72 ******************************************************************************/
73
74#ifdef __cplusplus
75extern "C" {
76#endif
77
78/*!
79* @name Power Configuration
80* @{
81*/
82
83/*!
84 * @brief API to enable PDRUNCFG bit in the Syscon. Note that enabling the bit powers down the peripheral
85 *
86 * @param en peripheral for which to enable the PDRUNCFG bit
87 * @return none
88 */
89static inline void POWER_EnablePD(pd_bit_t en)
90{
91 /* PDRUNCFGSET */
92 SYSCON->PDRUNCFGSET[((uint32_t)en >> 8UL)] = (1UL << ((uint32_t)en & 0xffU));
93}
94
95/*!
96 * @brief API to disable PDRUNCFG bit in the Syscon. Note that disabling the bit powers up the peripheral
97 *
98 * @param en peripheral for which to disable the PDRUNCFG bit
99 * @return none
100 */
101static inline void POWER_DisablePD(pd_bit_t en)
102{
103 /* PDRUNCFGCLR */
104 SYSCON->PDRUNCFGCLR[((uint32_t)en >> 8UL)] = (1UL << ((uint32_t)en & 0xffU));
105}
106
107/*!
108 * @brief API to enable deep sleep bit in the ARM Core.
109 *
110 * @return none
111 */
112static inline void POWER_EnableDeepSleep(void)
113{
114 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
115}
116
117/*!
118 * @brief API to disable deep sleep bit in the ARM Core.
119 *
120 * @return none
121 */
122static inline void POWER_DisableDeepSleep(void)
123{
124 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
125}
126
127/*!
128 * @brief API to power down flash controller.
129 *
130 * @return none
131 */
132static inline void POWER_PowerDownFlash(void)
133{
134#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
135 /* TURN OFF clock for Flash Controller (only needed for FLASH programming, will be turned on by ROM API) */
136 CLOCK_DisableClock(kCLOCK_Flash);
137
138 /* TURN OFF clock for Flash Accelerator */
139 CLOCK_DisableClock(kCLOCK_Fmc);
140#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
141}
142
143/*!
144 * @brief API to power up flash controller.
145 *
146 * @return none
147 */
148static inline void POWER_PowerUpFlash(void)
149{
150#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
151 /* TURN ON clock for flash Accelerator */
152 CLOCK_EnableClock(kCLOCK_Fmc);
153
154 /* TURN ON clock for flash Controller */
155 CLOCK_EnableClock(kCLOCK_Flash);
156#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
157}
158
159/*!
160 * @brief Power Library API to enter different power mode.
161 *
162 * @param mode
163 * @param exclude_from_pd Bit mask of the PDRUNCFG bits that needs to be powered on during deep sleep
164 * @return none
165 */
166void POWER_EnterPowerMode(power_mode_cfg_t mode, uint64_t exclude_from_pd);
167
168/*!
169 * @brief Power Library API to enter sleep mode.
170 *
171 * @return none
172 */
173void POWER_EnterSleep(void);
174
175/*!
176 * @brief Power Library API to enter deep sleep mode.
177 *
178 * @param exclude_from_pd Bit mask of the PDRUNCFG bits that needs to be powered on during deep sleep
179 * @return none
180 */
181void POWER_EnterDeepSleep(uint64_t exclude_from_pd);
182
183/*!
184 * @brief Power Library API to enter deep power down mode.
185 *
186 * @param exclude_from_pd Bit mask of the PDRUNCFG bits that needs to be powered on during deep power down mode,
187 * but this is has no effect as the voltages are cut off.
188 * @return none
189 */
190void POWER_EnterDeepPowerDown(uint64_t exclude_from_pd);
191
192/*!
193 * @brief Power Library API to choose normal regulation and set the voltage for the desired operating frequency.
194 *
195 * @param freq - The desired frequency at which the part would like to operate,
196 * note that the voltage and flash wait states should be set before changing frequency
197 * @return none
198 */
199void POWER_SetVoltageForFreq(uint32_t freq);
200
201/*!
202 * @brief Power Library API to choose low power regulation and set the voltage for the desired operating frequency.
203 *
204 * @param freq - The desired frequency at which the part would like to operate,
205 * note only 12MHz and 48Mhz are supported
206 * @return none
207 */
208void POWER_SetLowPowerVoltageForFreq(uint32_t freq);
209
210/*!
211 * @brief Power Library API to return the library version.
212 *
213 * @return version number of the power library
214 */
215uint32_t POWER_GetLibVersion(void);
216
217/* @} */
218
219#ifdef __cplusplus
220}
221#endif
222
223/*! @} */
224
225#endif /* _FSL_POWER_H_ */
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_reset.c b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_reset.c
new file mode 100644
index 000000000..00d8db6da
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_reset.c
@@ -0,0 +1,132 @@
1/*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016, NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10#include "fsl_common.h"
11#include "fsl_reset.h"
12
13/*******************************************************************************
14 * Definitions
15 ******************************************************************************/
16/* Component ID definition, used by tools. */
17#ifndef FSL_COMPONENT_ID
18#define FSL_COMPONENT_ID "platform.drivers.reset"
19#endif
20
21/*******************************************************************************
22 * Variables
23 ******************************************************************************/
24
25/*******************************************************************************
26 * Prototypes
27 ******************************************************************************/
28
29/*******************************************************************************
30 * Code
31 ******************************************************************************/
32
33#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
34 (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
35
36/*!
37 * brief Assert reset to peripheral.
38 *
39 * Asserts reset signal to specified peripheral module.
40 *
41 * param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
42 * and reset bit position in the reset register.
43 */
44void RESET_SetPeripheralReset(reset_ip_name_t peripheral)
45{
46 const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
47 const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu);
48 const uint32_t bitMask = 1UL << bitPos;
49
50 assert(bitPos < 32UL);
51
52 /* ASYNC_SYSCON registers have offset 1024 */
53 if (regIndex >= SYSCON_PRESETCTRL_COUNT)
54 {
55 /* reset register is in ASYNC_SYSCON */
56
57 /* set bit */
58 ASYNC_SYSCON->ASYNCPRESETCTRLSET = bitMask;
59 /* wait until it reads 0b1 */
60 while (0u == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask))
61 {
62 }
63 }
64 else
65 {
66 /* reset register is in SYSCON */
67
68 /* set bit */
69 SYSCON->PRESETCTRLSET[regIndex] = bitMask;
70 /* wait until it reads 0b1 */
71 while (0u == (SYSCON->PRESETCTRL[regIndex] & bitMask))
72 {
73 }
74 }
75}
76
77/*!
78 * brief Clear reset to peripheral.
79 *
80 * Clears reset signal to specified peripheral module, allows it to operate.
81 *
82 * param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
83 * and reset bit position in the reset register.
84 */
85void RESET_ClearPeripheralReset(reset_ip_name_t peripheral)
86{
87 const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
88 const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu);
89 const uint32_t bitMask = 1UL << bitPos;
90
91 assert(bitPos < 32UL);
92
93 /* ASYNC_SYSCON registers have offset 1024 */
94 if (regIndex >= SYSCON_PRESETCTRL_COUNT)
95 {
96 /* reset register is in ASYNC_SYSCON */
97
98 /* clear bit */
99 ASYNC_SYSCON->ASYNCPRESETCTRLCLR = bitMask;
100 /* wait until it reads 0b0 */
101 while (bitMask == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask))
102 {
103 }
104 }
105 else
106 {
107 /* reset register is in SYSCON */
108
109 /* clear bit */
110 SYSCON->PRESETCTRLCLR[regIndex] = bitMask;
111 /* wait until it reads 0b0 */
112 while (bitMask == (SYSCON->PRESETCTRL[regIndex] & bitMask))
113 {
114 }
115 }
116}
117
118/*!
119 * brief Reset peripheral module.
120 *
121 * Reset peripheral module.
122 *
123 * param peripheral Peripheral to reset. The enum argument contains encoding of reset register
124 * and reset bit position in the reset register.
125 */
126void RESET_PeripheralReset(reset_ip_name_t peripheral)
127{
128 RESET_SetPeripheralReset(peripheral);
129 RESET_ClearPeripheralReset(peripheral);
130}
131
132#endif /* FSL_FEATURE_SOC_SYSCON_COUNT || FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT */
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_reset.h b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_reset.h
new file mode 100644
index 000000000..dd1bdffa7
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC51U68/drivers/fsl_reset.h
@@ -0,0 +1,182 @@
1/*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016, NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10#ifndef _FSL_RESET_H_
11#define _FSL_RESET_H_
12
13#include <assert.h>
14#include <stdbool.h>
15#include <stdint.h>
16#include <string.h>
17#include "fsl_device_registers.h"
18
19/*!
20 * @addtogroup reset
21 * @{
22 */
23
24/*******************************************************************************
25 * Definitions
26 ******************************************************************************/
27
28/*! @name Driver version */
29/*@{*/
30/*! @brief reset driver version 2.0.1. */
31#define FSL_RESET_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
32/*@}*/
33
34/*!
35 * @brief Enumeration for peripheral reset control bits
36 *
37 * Defines the enumeration for peripheral reset control bits in PRESETCTRL/ASYNCPRESETCTRL registers
38 */
39typedef enum _SYSCON_RSTn
40{
41 kFLASH_RST_SHIFT_RSTn = 0 | 7U, /**< Flash controller reset control */
42 kFMC_RST_SHIFT_RSTn = 0 | 8U, /**< Flash accelerator reset control */
43 kMUX_RST_SHIFT_RSTn = 0 | 11U, /**< Input mux reset control */
44 kIOCON_RST_SHIFT_RSTn = 0 | 13U, /**< IOCON reset control */
45 kGPIO0_RST_SHIFT_RSTn = 0 | 14U, /**< GPIO0 reset control */
46 kGPIO1_RST_SHIFT_RSTn = 0 | 15U, /**< GPIO1 reset control */
47 kPINT_RST_SHIFT_RSTn = 0 | 18U, /**< Pin interrupt (PINT) reset control */
48 kGINT_RST_SHIFT_RSTn = 0 | 19U, /**< Grouped interrupt (PINT) reset control. */
49 kDMA_RST_SHIFT_RSTn = 0 | 20U, /**< DMA reset control */
50 kCRC_RST_SHIFT_RSTn = 0 | 21U, /**< CRC reset control */
51 kWWDT_RST_SHIFT_RSTn = 0 | 22U, /**< Watchdog timer reset control */
52 kADC0_RST_SHIFT_RSTn = 0 | 27U, /**< ADC0 reset control */
53 kMRT_RST_SHIFT_RSTn = 65536 | 0U, /**< Multi-rate timer (MRT) reset control */
54 kSCT0_RST_SHIFT_RSTn = 65536 | 2U, /**< SCTimer/PWM 0 (SCT0) reset control */
55 kUTICK_RST_SHIFT_RSTn = 65536 | 10U, /**< Micro-tick timer reset control */
56 kFC0_RST_SHIFT_RSTn = 65536 | 11U, /**< Flexcomm Interface 0 reset control */
57 kFC1_RST_SHIFT_RSTn = 65536 | 12U, /**< Flexcomm Interface 1 reset control */
58 kFC2_RST_SHIFT_RSTn = 65536 | 13U, /**< Flexcomm Interface 2 reset control */
59 kFC3_RST_SHIFT_RSTn = 65536 | 14U, /**< Flexcomm Interface 3 reset control */
60 kFC4_RST_SHIFT_RSTn = 65536 | 15U, /**< Flexcomm Interface 4 reset control */
61 kFC5_RST_SHIFT_RSTn = 65536 | 16U, /**< Flexcomm Interface 5 reset control */
62 kFC6_RST_SHIFT_RSTn = 65536 | 17U, /**< Flexcomm Interface 6 reset control */
63 kFC7_RST_SHIFT_RSTn = 65536 | 18U, /**< Flexcomm Interface 7 reset control */
64 kUSB_RST_SHIFT_RSTn = 65536 | 25U, /**< USB reset control */
65 kCTIMER0_RST_SHIFT_RSTn = 65536 | 26U, /**< CTimer0 reset control */
66 kCTIMER1_RST_SHIFT_RSTn = 65536 | 27U, /**< CTimer1 reset control */
67 kCTIMER3_RST_SHIFT_RSTn = 67108864 | 13U, /**< CTimer3 reset control */
68} SYSCON_RSTn_t;
69
70/** Array initializers with peripheral reset bits **/
71#define ADC_RSTS \
72 { \
73 kADC0_RST_SHIFT_RSTn \
74 } /* Reset bits for ADC peripheral */
75#define CRC_RSTS \
76 { \
77 kCRC_RST_SHIFT_RSTn \
78 } /* Reset bits for CRC peripheral */
79#define DMA_RSTS_N \
80 { \
81 kDMA_RST_SHIFT_RSTn \
82 } /* Reset bits for DMA peripheral */
83#define FLEXCOMM_RSTS \
84 { \
85 kFC0_RST_SHIFT_RSTn, kFC1_RST_SHIFT_RSTn, kFC2_RST_SHIFT_RSTn, kFC3_RST_SHIFT_RSTn, kFC4_RST_SHIFT_RSTn, \
86 kFC5_RST_SHIFT_RSTn, kFC6_RST_SHIFT_RSTn, kFC7_RST_SHIFT_RSTn \
87 } /* Reset bits for FLEXCOMM peripheral */
88#define GINT_RSTS \
89 { \
90 kGINT_RST_SHIFT_RSTn, kGINT_RST_SHIFT_RSTn \
91 } /* Reset bits for GINT peripheral. GINT0 & GINT1 share same slot */
92#define GPIO_RSTS_N \
93 { \
94 kGPIO0_RST_SHIFT_RSTn, kGPIO1_RST_SHIFT_RSTn \
95 } /* Reset bits for GPIO peripheral */
96#define INPUTMUX_RSTS \
97 { \
98 kMUX_RST_SHIFT_RSTn \
99 } /* Reset bits for INPUTMUX peripheral */
100#define IOCON_RSTS \
101 { \
102 kIOCON_RST_SHIFT_RSTn \
103 } /* Reset bits for IOCON peripheral */
104#define FLASH_RSTS \
105 { \
106 kFLASH_RST_SHIFT_RSTn, kFMC_RST_SHIFT_RSTn \
107 } /* Reset bits for Flash peripheral */
108#define MRT_RSTS \
109 { \
110 kMRT_RST_SHIFT_RSTn \
111 } /* Reset bits for MRT peripheral */
112#define PINT_RSTS \
113 { \
114 kPINT_RST_SHIFT_RSTn \
115 } /* Reset bits for PINT peripheral */
116#define SCT_RSTS \
117 { \
118 kSCT0_RST_SHIFT_RSTn \
119 } /* Reset bits for SCT peripheral */
120#define CTIMER_RSTS \
121 { \
122 kCTIMER0_RST_SHIFT_RSTn, kCTIMER1_RST_SHIFT_RSTn, kCTIMER3_RST_SHIFT_RSTn \
123 } /* Reset bits for TIMER peripheral */
124#define USB_RSTS \
125 { \
126 kUSB_RST_SHIFT_RSTn \
127 } /* Reset bits for USB peripheral */
128#define UTICK_RSTS \
129 { \
130 kUTICK_RST_SHIFT_RSTn \
131 } /* Reset bits for UTICK peripheral */
132#define WWDT_RSTS \
133 { \
134 kWWDT_RST_SHIFT_RSTn \
135 } /* Reset bits for WWDT peripheral */
136
137typedef SYSCON_RSTn_t reset_ip_name_t;
138
139/*******************************************************************************
140 * API
141 ******************************************************************************/
142#if defined(__cplusplus)
143extern "C" {
144#endif
145
146/*!
147 * @brief Assert reset to peripheral.
148 *
149 * Asserts reset signal to specified peripheral module.
150 *
151 * @param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
152 * and reset bit position in the reset register.
153 */
154void RESET_SetPeripheralReset(reset_ip_name_t peripheral);
155
156/*!
157 * @brief Clear reset to peripheral.
158 *
159 * Clears reset signal to specified peripheral module, allows it to operate.
160 *
161 * @param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
162 * and reset bit position in the reset register.
163 */
164void RESET_ClearPeripheralReset(reset_ip_name_t peripheral);
165
166/*!
167 * @brief Reset peripheral module.
168 *
169 * Reset peripheral module.
170 *
171 * @param peripheral Peripheral to reset. The enum argument contains encoding of reset register
172 * and reset bit position in the reset register.
173 */
174void RESET_PeripheralReset(reset_ip_name_t peripheral);
175
176#if defined(__cplusplus)
177}
178#endif
179
180/*! @} */
181
182#endif /* _FSL_RESET_H_ */