1 /**
2 *********************************************************************************
3 *
4 * @file ald_cmu.c
5 * @brief CMU module driver.
6 *
7 * @version V1.0
8 * @date 22 Nov 2019
9 * @author AE Team
10 * @note
11 * Change Logs:
12 * Date Author Notes
13 * 22 Nov 2019 AE Team The first version
14 *
15 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 *
19 * Licensed under the Apache License, Version 2.0 (the License); you may
20 * not use this file except in compliance with the License.
21 * You may obtain a copy of the License at
22 *
23 * www.apache.org/licenses/LICENSE-2.0
24 *
25 * Unless required by applicable law or agreed to in writing, software
26 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
27 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28 * See the License for the specific language governing permissions and
29 * limitations under the License.
30 **********************************************************************************
31 * @verbatim
32 ==============================================================================
33 ##### How to use this driver #####
34 ==============================================================================
35 [..]
36 *** System clock configure ***
37 =================================
38 [..]
39 (+) If you don't change system clock, you can using ald_cmu_clock_config_default() API.
40 It will select HRC as system clock. The system clock is 24MHz.
41 (+) If you want to change system clock, you can using ald_cmu_clock_config() API.
42 You can select one of the following as system clock:
43 @ref CMU_CLOCK_HRC 2MHz or 24MHz
44 @ref CMU_CLOCK_LRC 32768Hz
45 @ref CMU_CLOCK_LOSC 32768Hz
46 @ref CMU_CLOCK_PLL1 36MHz/48MHz/72MHz/96MHz
47 @ref CMU_CLOCK_HOSC 1MHz -- 24MHz
48 (+) If you select CMU_CLOCK_PLL1 as system clock, it must config the PLL1
49 using ald_cmu_pll1_config() API. The input of clock must be 4MHz.
50 (+) If you get current clock, you can using ald_cmu_get_clock() API.
51
52 *** BUS division control ***
53 ===================================
54
55 MCLK sys_clk
56 -------DIV_SYS-----------+--------------------------System(Core, DMA, Systick ... etc.)
57 |
58 | hclk1
59 +------DIV_AHB1------------Peripheral(GPIO, CRC, ... etc.)
60 |
61 | hclk2
62 +------DIV_AHB2------------Peripheral(EBI, QSPI, ... etc.)
63 |
64 | pclk1
65 +------DIV_APB1------------Peripheral(TIM, UART, ... etc.)
66 |
67 | pclk2
68 +------DIV_APB2------------Peripheral(ADC, WWDT, ... etc.)
69
70 [..]
71 (+) Configure the division using ald_cmu_div_config() API.
72 (+) Get sys_clk using ald_cmu_get_sys_clock() API.
73 (+) Get hclk1 using ald_cmu_get_hclk1_clock() API.
74 (+) Get pclk1 using ald_cmu_get_pclk1_clock() API.
75 (+) Get pclk2 using ald_cmu_get_pclk2_clock() API.
76
77 *** Clock safe configure ***
78 ===================================
79 [..]
80 (+) If you select CMU_CLOCK_HOSC as system clock, you need enable
81 clock safe using ald_cmu_hosc_safe_config() API. It will change
82 CMU_CLOCK_HRC as system clock, when the outer crystal stoped.
83 (+) If you select CMU_CLOCK_LOSC as system clock, you need enable
84 clock safe using ald_cmu_losc_safe_config() API. It will change
85 CMU_CLOCK_LRC as system clock, when the outer crystal stoped.
86 (+) If you select CMU_CLOCK_PLL1 as system clock, you need enable
87 clock safe using ald_cmu_pll_safe_config() API. It will change
88 CMU_CLOCK_HRC as system clock, when the pll1 is lose.
89 (+) The ald_cmu_irq_cbk() will be invoked, when CMU interrupt has
90 been occurred. You can overwrite this function in application.
91
92 *** Clock output configure ***
93 ===================================
94 [..]
95 (+) Output high-speed clock using ald_cmu_output_high_clock_config() API.
96 (+) Output low-speed clock using ald_cmu_output_low_clock_config() API.
97
98 *** Peripheral clock configure ***
99 ===================================
100 [..]
101 (+) Configure buzz clock using ald_cmu_buzz_config() API.
102 (+) Selected lptim0 clock using ald_cmu_lptim0_clock_select() API.
103 (+) Selected lpuart clock using ald_cmu_lpuart0_clock_select() API.
104 (+) Selected lcd clock using ald_cmu_lcd_clock_select() API.
105 (+) Selected qspi clock using ald_cmu_qspi_clock_select() API.
106 (+) Configure usb clock using ald_cmu_usb_clock_config() API.
107 (+) Enable/Disable peripheral clock using ald_cmu_perh_clock_config() API.
108 (+) Selected stop1 clock using ald_cmu_stop1_clock_sel() API.
109
110 *** CMU ALD driver macros list ***
111 =============================================
112 [..]
113 Below the list of most used macros in CMU driver.
114
115 (+) CMU_HRC_SEL_BY_SW(): HRC clock config by software.
116 (+) CMU_HRC_SEL_BY_CFGW(): HRC clock config by CFG Word.
117 (+) CMU_HRC_DIV_1MHZ_ENABLE(): Enable HRC divider to 1MHz.
118 (+) CMU_HRC_DIV_1MHZ_DISABLE(): Disable HRC divider to 1MHz.
119 (+) CMU_HOSC_DIV_1MHZ_ENABLE(): Enable HOSC divider to 1MHz.
120 (+) CMU_HOSC_DIV_1MHZ_DISABLE(): Disable HOSC divider to 1MHz.
121 (+) CMU_LOSC_ENABLE(): Enable outer low crystal(32768Hz).
122 (+) CMU_LOSC_DISABLE(): Disable outer low crystal(32768Hz).
123 (+) CMU_LRC_ENABLE(): Enable LRC(32768Hz).
124 (+) CMU_LRC_DISABLE(): Disable LRC(32768Hz).
125 (+) CMU_ULRC_ENABLE(): Enable ULRC(10KHz).
126 (+) CMU_ULRC_DISABLE(): Disable ULRC(10KHz).
127 (+) CMU_LP_LRC_ENABLE(): Enable low power LRC(32768Hz).
128 (+) CMU_LP_LRC_DISABLE(): Disable low power LRC(32768Hz).
129 (+) CMU_LP_LOSC_ENABLE(): Enable low power LOSC(32768Hz).
130 (+) CMU_LP_LOSC_DISABLE(): Disable low power LOSC(32768Hz).
131 (+) CMU_LP_HRC_ENABLE(): Enable low power HRC(2MHz or 24MHz).
132 (+) CMU_LP_HRC_DISABLE(): Disable low power HRC(2MHz OR 24MHz).
133 (+) CMU_LP_HOSC_ENABLE(): Enable low power HOSC(1MHz -- 24MHz).
134 (+) CMU_LP_HOSC_DISABLE(): Disable low power HOSC(1MHz -- 24MHz).
135
136 [..]
137 (@) You can refer to the CMU driver header file for used the macros
138
139 @endverbatim
140 ******************************************************************************
141 */
142
143 #include "ald_conf.h"
144
145 /** @addtogroup ES32FXXX_ALD
146 * @{
147 */
148
149 /** @defgroup CMU CMU
150 * @brief CMU module driver
151 * @{
152 */
153
154 /**
155 * @defgroup CMU_Private_Variables CMU Private Variables
156 * @{
157 */
158 uint32_t __system_clock = 24000000U;
159 /**
160 * @}
161 */
162
163 /** @defgroup CMU_Private_Functions CMU Private Functions
164 * @{
165 */
166
167 /**
168 * @brief Update the current system clock. This function
169 * will be invoked, when system clock has changed.
170 * @param clock: The new clock.
171 * @retval None
172 */
173
cmu_clock_update(uint32_t clock)174 static void cmu_clock_update(uint32_t clock)
175 {
176 __system_clock = clock;
177
178 if (clock > 1000000)
179 ald_tick_init(TICK_INT_PRIORITY);
180
181 return;
182 }
183
184 /**
185 * @brief CMU module interrupt handler
186 * @retval None
187 */
ald_cmu_irq_handler(void)188 void ald_cmu_irq_handler(void)
189 {
190 /* HOSC stop */
191 if (READ_BIT(CMU->HOSMCR, CMU_HOSMCR_STPIF_MSK) && READ_BIT(CMU->HOSMCR, CMU_HOSMCR_STPIE_MSK)) {
192 SYSCFG_UNLOCK();
193 SET_BIT(CMU->HOSMCR, CMU_HOSMCR_STPIF_MSK);
194 SYSCFG_LOCK();
195
196 if ((READ_BIT(CMU->HOSMCR, CMU_HOSMCR_CLKS_MSK))
197 && ((READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) == 1)
198 || ((READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) == 5))))
199 cmu_clock_update(READ_BIT(CMU->CFGR, CMU_CFGR_HRCFST_MSK) ? 2000000 : 24000000);
200 ald_cmu_irq_cbk(CMU_HOSC_STOP);
201 }
202
203 /* HOSC start */
204 if (READ_BIT(CMU->HOSMCR, CMU_HOSMCR_STRIF_MSK) && READ_BIT(CMU->HOSMCR, CMU_HOSMCR_STRIE_MSK)) {
205 SYSCFG_UNLOCK();
206 SET_BIT(CMU->HOSMCR, CMU_HOSMCR_STRIF_MSK);
207 SYSCFG_LOCK();
208
209 if (!(READ_BIT(CMU->HOSMCR, CMU_HOSMCR_CLKS_MSK))
210 && ((READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) == 5)))
211 cmu_clock_update((READ_BITS(CMU->HOSCCFG, CMU_HOSCCFG_FREQ_MSK, CMU_HOSCCFG_FREQ_POSS) + 1) * 1000000);
212 ald_cmu_irq_cbk(CMU_HOSC_START);
213 }
214
215 /* LOSC stop */
216 if (READ_BIT(CMU->LOSMCR, CMU_LOSMCR_STPIF_MSK) && READ_BIT(CMU->LOSMCR, CMU_LOSMCR_STPIE_MSK)) {
217 SYSCFG_UNLOCK();
218 SET_BIT(CMU->LOSMCR, CMU_LOSMCR_STPIF_MSK);
219 SYSCFG_LOCK();
220 ald_cmu_irq_cbk(CMU_LOSC_STOP);
221 }
222
223 /* LOSC start */
224 if (READ_BIT(CMU->LOSMCR, CMU_LOSMCR_STRIF_MSK) && READ_BIT(CMU->LOSMCR, CMU_LOSMCR_STRIE_MSK)) {
225 SYSCFG_UNLOCK();
226 SET_BIT(CMU->LOSMCR, CMU_LOSMCR_STRIF_MSK);
227 SYSCFG_LOCK();
228 ald_cmu_irq_cbk(CMU_LOSC_START);
229 }
230
231 /* PLL1 lose */
232 if (READ_BIT(CMU->PULMCR, CMU_PULMCR_ULKIF_MSK) && READ_BIT(CMU->PULMCR, CMU_PULMCR_ULKIE_MSK)) {
233 SYSCFG_UNLOCK();
234 SET_BIT(CMU->PULMCR, CMU_PULMCR_ULKIF_MSK);
235 SYSCFG_LOCK();
236
237 if (READ_BIT(CMU->PULMCR, CMU_PULMCR_CLKS_MSK)
238 && ((READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) == 1)
239 || ((READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) == 5))))
240 cmu_clock_update(READ_BIT(CMU->CFGR, CMU_CFGR_HRCFST_MSK) ? 2000000 : 24000000);
241 ald_cmu_irq_cbk(CMU_PLL1_UNLOCK);
242 }
243
244 return;
245 }
246 /**
247 * @}
248 */
249
250 /** @defgroup CMU_Public_Functions CMU Public Functions
251 * @{
252 */
253
254 /** @defgroup CMU_Public_Functions_Group1 System clock configuration
255 * @brief System clock configuration functions
256 *
257 * @verbatim
258 ==============================================================================
259 ##### System clock Configuration functions #####
260 ==============================================================================
261 [..] This section provides functions allowing to:
262 (+) Configure system clock using default parameters.
263 (+) Configure system clock using specified parameters.
264 (+) Configure PLL1 using specified parameters.
265 (+) Get system clock.
266
267 @endverbatim
268 * @{
269 */
270
271 /**
272 * @brief Configure system clock using default.
273 * Select CMU_CLOCK_HRC(24MHz) as system clock and
274 * enable CMU_CLOCK_LRC(32768Hz).
275 * @retval The status of ALD.
276 */
ald_cmu_clock_config_default(void)277 ald_status_t ald_cmu_clock_config_default(void)
278 {
279 uint32_t cnt = 4000, tmp;
280
281 SYSCFG_UNLOCK();
282
283 /* Select HRC */
284 MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_HRC << CMU_CSR_SYS_CMD_POSS);
285
286 while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt));
287
288 if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_HRC) {
289 SYSCFG_LOCK();
290 return ERROR;
291 }
292
293 WRITE_REG(CMU->CFGR, 0x4000000); /* Select 24MHz */
294
295 tmp = READ_REG(CMU->CLKENR);
296 /* Enable HRC/LRC */
297 SET_BIT(tmp, CMU_CLKENR_HRCEN_MSK | CMU_CLKENR_LRCEN_MSK);
298 WRITE_REG(CMU->CLKENR, tmp);
299 /* Reset LRC */
300 for (cnt = 0; cnt < 10000; ++cnt);
301 CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK);
302 SET_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK);
303
304 SYSCFG_LOCK();
305 return OK;
306 }
307
308 /**
309 * @brief Configure system clock using specified parameters
310 * @param clk: The parameter can be one of the following:
311 * @arg @ref CMU_CLOCK_HRC 2MHz or 24MHz
312 * @arg @ref CMU_CLOCK_LRC 32768Hz
313 * @arg @ref CMU_CLOCK_LOSC 32768Hz
314 * @arg @ref CMU_CLOCK_PLL1 One of @ref cmu_pll1_output_t
315 * @arg @ref CMU_CLOCK_HOSC 1MHz -- 24MHz
316 * @param clock: The clock which will be set. the value depends
317 * on the parameter of clk.
318 * @retval The status of ALD.
319 */
ald_cmu_clock_config(cmu_clock_t clk,uint32_t clock)320 ald_status_t ald_cmu_clock_config(cmu_clock_t clk, uint32_t clock)
321 {
322 uint32_t cnt = 4000;
323
324 assert_param(IS_CMU_CLOCK(clk));
325 SYSCFG_UNLOCK();
326
327 switch (clk) {
328 case CMU_CLOCK_HRC:
329 assert_param(clock == 24000000 || clock == 2000000);
330
331 MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_HRC << CMU_CSR_SYS_CMD_POSS);
332 while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt));
333
334 if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_HRC) {
335 SYSCFG_LOCK();
336 return ERROR;
337 }
338
339 if (clock == 24000000)
340 CLEAR_BIT(CMU->CFGR, CMU_CFGR_HRCFSW_MSK);
341 else
342 SET_BIT(CMU->CFGR, CMU_CFGR_HRCFSW_MSK);
343
344 SET_BIT(CMU->CLKENR, CMU_CLKENR_HRCEN_MSK);
345
346 for (cnt = 4000; cnt; --cnt);
347 cnt = 4000;
348 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HRCACT_MSK))) && (--cnt));
349 cnt = 4000;
350 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HRCRDY_MSK))) && (--cnt));
351
352 cmu_clock_update(clock);
353 break;
354
355 case CMU_CLOCK_LRC:
356 /* Close SysTick interrupt in lower clock */
357 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
358
359 MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_LRC << CMU_CSR_SYS_CMD_POSS);
360 while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt));
361
362 if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_LRC) {
363 SYSCFG_LOCK();
364 return ERROR;
365 }
366
367 SET_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK);
368
369 cnt = 4000;
370 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LRCACT_MSK))) && (--cnt));
371 cnt = 4000;
372 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LRCRDY_MSK))) && (--cnt));
373
374 cmu_clock_update(32768);
375 break;
376
377 case CMU_CLOCK_LOSC:
378 /* Close SysTick interrupt in lower clock */
379 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
380
381 MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_LOSC << CMU_CSR_SYS_CMD_POSS);
382 while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt));
383
384 if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_LOSC) {
385 SYSCFG_LOCK();
386 return ERROR;
387 }
388
389 SET_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK);
390
391 cnt = 4000;
392 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LOSCACT_MSK))) && (--cnt));
393 cnt = 4000;
394 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LOSCRDY_MSK))) && (--cnt));
395
396 cmu_clock_update(32768);
397 break;
398
399 case CMU_CLOCK_PLL1:
400 for (cnt = 0; cnt < 5000; ++cnt);
401 MODIFY_REG(CMU->CSR, CMU_CSR_CFT_CMD_MSK, 0xAA << CMU_CSR_CFT_CMD_POSS);
402 MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_PLL1 << CMU_CSR_SYS_CMD_POSS);
403 while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt));
404
405 if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_PLL1) {
406 SYSCFG_LOCK();
407 return ERROR;
408 }
409
410 SET_BIT(CMU->CLKENR, CMU_CLKENR_PLL1EN_MSK);
411
412 for (cnt = 0; cnt < 5000; ++cnt);
413 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_PLL1ACT_MSK))) && (--cnt));
414 cnt = 4000;
415 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_PLL1RDY_MSK))) && (--cnt));
416
417 if (clock == 96000000) {
418 ald_cmu_div_config(CMU_HCLK_1, CMU_DIV_2);
419 ald_cmu_div_config(CMU_HCLK_2, CMU_DIV_2);
420 ald_cmu_div_config(CMU_PCLK_1, CMU_DIV_2);
421 ald_cmu_div_config(CMU_PCLK_2, CMU_DIV_4);
422 for (cnt = 0; cnt < 20000; ++cnt);
423 }
424 if (clock == 72000000) {
425 ald_cmu_div_config(CMU_PCLK_2, CMU_DIV_4);
426 }
427 if ((clock == 48000000) || (clock == 36000000)) {
428 ald_cmu_div_config(CMU_PCLK_2, CMU_DIV_2);
429 }
430
431 cmu_clock_update(clock);
432 break;
433
434 case CMU_CLOCK_HOSC:
435 assert_param(clock <= 24000000);
436
437 MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_HOSC << CMU_CSR_SYS_CMD_POSS);
438 while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt));
439
440 if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_HOSC) {
441 SYSCFG_LOCK();
442 return ERROR;
443 }
444
445 SET_BIT(CMU->CLKENR, CMU_CLKENR_HOSCEN_MSK);
446 MODIFY_REG(CMU->HOSCCFG, CMU_HOSCCFG_FREQ_MSK, clock / 1000000 - 1);
447
448 for (cnt = 8000; cnt; --cnt);
449 cnt = 4000;
450 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HOSCACT_MSK))) && (--cnt));
451 cnt = 4000;
452 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HOSCRDY_MSK))) && (--cnt));
453
454 cmu_clock_update(clock);
455 break;
456
457 default:
458 break;
459 }
460
461 SYSCFG_LOCK();
462 return OK;
463 }
464
465
466
467 /**
468 * @brief Configure PLL1 using specified parameters.
469 * @param input: The input clock type.
470 * @param output: The output clock which can be 36MHz/48MHz/72MHz/96MHz.
471 * When input = CMU_PLL1_INPUT_PLL2; then output must be
472 * CMU_PLL1_OUTPUT_36M, and then the real clock is (32768x1024)Hz.
473 * @retval None
474 */
ald_cmu_pll1_config(cmu_pll1_input_t input,cmu_pll1_output_t output)475 void ald_cmu_pll1_config(cmu_pll1_input_t input, cmu_pll1_output_t output)
476 {
477 uint32_t cnt = 4000;
478
479 assert_param(IS_CMU_PLL1_INPUT(input));
480 assert_param(IS_CMU_PLL1_OUTPUT(output));
481
482 SYSCFG_UNLOCK();
483
484 if (input == CMU_PLL1_INPUT_HRC_6) {
485 SET_BIT(CMU->CLKENR, CMU_CLKENR_HRCEN_MSK);
486 }
487 else if (input == CMU_PLL1_INPUT_PLL2) {
488 SET_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK);
489 CLEAR_BIT(CMU->PLLCFG, CMU_PLLCFG_PLL2RFS_MSK);
490 SET_BIT(CMU->CLKENR, CMU_CLKENR_PLL2EN_MSK);
491 }
492 else {
493 SET_BIT(CMU->CLKENR, CMU_CLKENR_HOSCEN_MSK);
494 for (cnt = 0; cnt < 10000; ++cnt);
495 cnt = 20000;
496 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HOSCRDY_MSK))) && (--cnt));
497 }
498
499 MODIFY_REG(CMU->PLLCFG, CMU_PLLCFG_PLL1RFS_MSK, input << CMU_PLLCFG_PLL1RFS_POSS);
500 MODIFY_REG(CMU->PLLCFG, CMU_PLLCFG_PLL1OS_MSK, output << CMU_PLLCFG_PLL1OS_POSS);
501 SET_BIT(CMU->CLKENR, CMU_CLKENR_PLL1EN_MSK);
502
503 for (cnt = 0; cnt < 4000; ++cnt);
504 while ((READ_BIT(CMU->PLLCFG, CMU_PLLCFG_PLL1LCKN_MSK)) && (--cnt));
505 cnt = 4000;
506 while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_PLL1RDY_MSK))) && (--cnt));
507
508 SET_BIT(CMU->PULMCR, CMU_PULMCR_EN_MSK);
509 MODIFY_REG(CMU->PULMCR, CMU_PULMCR_MODE_MSK, 0x3 << CMU_PULMCR_MODE_POSS);
510
511 SYSCFG_LOCK();
512 return;
513 }
514
515 /**
516 * @brief Gets current system clock.
517 * @retval The value of system clock.
518 */
ald_cmu_get_clock(void)519 uint32_t ald_cmu_get_clock(void)
520 {
521 return __system_clock;
522 }
523
524 /**
525 * @}
526 */
527
528 /** @defgroup CMU_Public_Functions_Group2 BUS division control
529 * @brief BUS division control functions
530 *
531 * @verbatim
532 ==============================================================================
533 ##### BUS division control functions #####
534 ==============================================================================
535 [..] This section provides functions allowing to:
536 (+) Configure the bus division.
537 (+) Get ahb1 clock.
538 (+) Get sys bus clock.
539 (+) Get apb1 clock.
540 (+) Get apb2 clock.
541
542 @endverbatim
543 * @{
544 */
545
546 /**
547 * @brief Configure the bus division.
548 * @param bus: The type of bus:
549 * @arg CMU_HCLK_1
550 * @arg CMU_SYS
551 * @arg CMU_PCLK_1
552 * @arg CMU_PCLK_2
553 * @param div: The value of divider.
554 * @retval None
555 */
ald_cmu_div_config(cmu_bus_t bus,cmu_div_t div)556 void ald_cmu_div_config(cmu_bus_t bus, cmu_div_t div)
557 {
558 assert_param(IS_CMU_BUS(bus));
559 assert_param(IS_CMU_DIV(div));
560
561 SYSCFG_UNLOCK();
562
563 switch (bus) {
564 case CMU_HCLK_1:
565 MODIFY_REG(CMU->CFGR, CMU_CFGR_HCLK1DIV_MSK, div << CMU_CFGR_HCLK1DIV_POSS);
566 break;
567
568 case CMU_HCLK_2:
569 MODIFY_REG(CMU->CFGR, CMU_CFGR_HCLK2DIV_MSK, div << CMU_CFGR_HCLK2DIV_POSS);
570 break;
571
572 case CMU_SYS:
573 MODIFY_REG(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, div << CMU_CFGR_SYSDIV_POSS);
574
575 if ((__system_clock >> div) <= 1000000) {
576 /* Close SysTick interrupt in lower clock */
577 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
578 }
579 else {
580 ald_tick_init(TICK_INT_PRIORITY);
581 }
582
583 break;
584
585 case CMU_PCLK_1:
586 MODIFY_REG(CMU->CFGR, CMU_CFGR_PCLK1DIV_MSK, div << CMU_CFGR_PCLK1DIV_POSS);
587 break;
588
589 case CMU_PCLK_2:
590 MODIFY_REG(CMU->CFGR, CMU_CFGR_PCLK2DIV_MSK, div << CMU_CFGR_PCLK2DIV_POSS);
591 break;
592
593 default:
594 break;
595 }
596
597 SYSCFG_LOCK();
598 return;
599 }
600
601 /**
602 * @brief Get AHB1 clock.
603 * @retval The value of AHB1 clock.
604 */
ald_cmu_get_hclk1_clock(void)605 uint32_t ald_cmu_get_hclk1_clock(void)
606 {
607 uint32_t sys_div = READ_BITS(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, CMU_CFGR_SYSDIV_POSS);
608 uint32_t ahb_div = READ_BITS(CMU->CFGR, CMU_CFGR_HCLK1DIV_MSK, CMU_CFGR_HCLK1DIV_POSS);
609
610 return (__system_clock >> sys_div) >> ahb_div;
611 }
612
613 /**
614 * @brief Get AHB2 clock.
615 * @retval The value of AHB2 clock.
616 */
ald_cmu_get_hclk2_clock(void)617 uint32_t ald_cmu_get_hclk2_clock(void)
618 {
619 uint32_t sys_div = READ_BITS(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, CMU_CFGR_SYSDIV_POSS);
620 uint32_t ahb_div = READ_BITS(CMU->CFGR, CMU_CFGR_HCLK2DIV_MSK, CMU_CFGR_HCLK2DIV_POSS);
621
622 return (__system_clock >> sys_div) >> ahb_div;
623 }
624
625 /**
626 * @brief Get SYS clock
627 * @retval The value of SYS clock
628 */
ald_cmu_get_sys_clock(void)629 uint32_t ald_cmu_get_sys_clock(void)
630 {
631 uint32_t sys_div = READ_BITS(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, CMU_CFGR_SYSDIV_POSS);
632
633 return __system_clock >> sys_div;
634 }
635
636 /**
637 * @brief Get APB1 clock.
638 * @retval The value of APB1 clock.
639 */
ald_cmu_get_pclk1_clock(void)640 uint32_t ald_cmu_get_pclk1_clock(void)
641 {
642 uint32_t sys_div = READ_BITS(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, CMU_CFGR_SYSDIV_POSS);
643 uint32_t apb1_div = READ_BITS(CMU->CFGR, CMU_CFGR_PCLK1DIV_MSK, CMU_CFGR_PCLK1DIV_POSS);
644
645 return (__system_clock >> sys_div) >> apb1_div;
646 }
647
648 /**
649 * @brief Get APB2 clock.
650 * @retval The value of APB2 clock.
651 */
ald_cmu_get_pclk2_clock(void)652 uint32_t ald_cmu_get_pclk2_clock(void)
653 {
654 uint32_t sys_div = READ_BITS(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, CMU_CFGR_SYSDIV_POSS);
655 uint32_t apb2_div = READ_BITS(CMU->CFGR, CMU_CFGR_PCLK2DIV_MSK, CMU_CFGR_PCLK2DIV_POSS);
656
657 return (__system_clock >> sys_div) >> apb2_div;
658 }
659 /**
660 * @}
661 */
662
663 /** @defgroup CMU_Public_Functions_Group3 Clock safe configure
664 * @brief Clock safe configure functions
665 *
666 * @verbatim
667 ==============================================================================
668 ##### Clock safe configure functions #####
669 ==============================================================================
670 [..] This section provides functions allowing to:
671 (+) Enable/Disable outer high crystal safe mode.
672 (+) Enable/Disable outer low crystal safe mode.
673 (+) Enable/Disable PLL1 safe mode.
674 (+) Interrupt callback function.
675
676 @endverbatim
677 * @{
678 */
679
680 /**
681 * @brief Enable/Disable outer high crystal safe mode.
682 * @param clock: the value of outer crystal frequency.
683 * @param status: The new status.
684 * @retval None
685 */
ald_cmu_hosc_safe_config(cmu_hosc_range_t clock,type_func_t status)686 void ald_cmu_hosc_safe_config(cmu_hosc_range_t clock, type_func_t status)
687 {
688 assert_param(IS_CMU_HOSC_RANGE(clock));
689 assert_param(IS_FUNC_STATE(status));
690
691 SYSCFG_UNLOCK();
692
693 if (status) {
694 SET_BIT(CMU->HOSMCR, CMU_HOSMCR_STPIF_MSK);
695 MODIFY_REG(CMU->HOSMCR, CMU_HOSMCR_FRQS_MSK, clock << CMU_HOSMCR_FRQS_POSS);
696 SET_BIT(CMU->HOSMCR, CMU_HOSMCR_EN_MSK);
697 SET_BIT(CMU->HOSMCR, CMU_HOSMCR_STPIE_MSK);
698
699 ald_mcu_irq_config(CMU_IRQn, 3, 3, ENABLE);
700 }
701 else {
702 CLEAR_BIT(CMU->HOSMCR, CMU_HOSMCR_EN_MSK);
703 CLEAR_BIT(CMU->HOSMCR, CMU_HOSMCR_STPIE_MSK);
704
705 if (READ_BIT(CMU->LOSMCR, CMU_LOSMCR_EN_MSK) == 0 && READ_BIT(CMU->PULMCR, CMU_PULMCR_EN_MSK) == 0)
706 ald_mcu_irq_config(CMU_IRQn, 3, 3, DISABLE);
707 }
708
709 SYSCFG_LOCK();
710 return;
711 }
712
713 /**
714 * @brief Enable/Disable outer low crystal safe mode.
715 * @param status: The new status.
716 * @retval None
717 */
ald_cmu_losc_safe_config(type_func_t status)718 void ald_cmu_losc_safe_config(type_func_t status)
719 {
720 assert_param(IS_FUNC_STATE(status));
721 SYSCFG_UNLOCK();
722
723 if (status) {
724 SET_BIT(CMU->LOSMCR, CMU_LOSMCR_STPIF_MSK);
725 SET_BIT(CMU->LOSMCR, CMU_LOSMCR_EN_MSK);
726 SET_BIT(CMU->LOSMCR, CMU_LOSMCR_STPIE_MSK);
727
728 ald_mcu_irq_config(CMU_IRQn, 3, 3, ENABLE);
729 }
730 else {
731 CLEAR_BIT(CMU->LOSMCR, CMU_LOSMCR_EN_MSK);
732 CLEAR_BIT(CMU->LOSMCR, CMU_LOSMCR_STPIE_MSK);
733
734 if (READ_BIT(CMU->HOSMCR, CMU_HOSMCR_EN_MSK) == 0 && READ_BIT(CMU->PULMCR, CMU_PULMCR_EN_MSK) == 0)
735 ald_mcu_irq_config(CMU_IRQn, 3, 3, DISABLE);
736 }
737
738 SYSCFG_LOCK();
739 return;
740 }
741
742 /**
743 * @brief Enable/Disable PLL1 safe mode.
744 * @param status: The new status.
745 * @retval None
746 */
ald_cmu_pll_safe_config(type_func_t status)747 void ald_cmu_pll_safe_config(type_func_t status)
748 {
749 assert_param(IS_FUNC_STATE(status));
750 SYSCFG_UNLOCK();
751
752 if (status) {
753 SET_BIT(CMU->PULMCR, CMU_PULMCR_ULKIF_MSK);
754 MODIFY_REG(CMU->PULMCR, CMU_PULMCR_MODE_MSK, 2 << CMU_PULMCR_MODE_POSS);
755 SET_BIT(CMU->PULMCR, CMU_PULMCR_EN_MSK);
756 SET_BIT(CMU->PULMCR, CMU_PULMCR_ULKIE_MSK);
757
758 ald_mcu_irq_config(CMU_IRQn, 3, 3, ENABLE);
759 }
760 else {
761 CLEAR_BIT(CMU->PULMCR, CMU_PULMCR_EN_MSK);
762 CLEAR_BIT(CMU->PULMCR, CMU_PULMCR_ULKIE_MSK);
763
764 if (READ_BIT(CMU->HOSMCR, CMU_HOSMCR_EN_MSK) == 0 && READ_BIT(CMU->LOSMCR, CMU_LOSMCR_EN_MSK) == 0)
765 ald_mcu_irq_config(CMU_IRQn, 3, 3, DISABLE);
766 }
767
768 SYSCFG_LOCK();
769 return;
770 }
771
772 /**
773 * @brief Get current clock source.
774 * @param type: Type of source: HOSC/LOSC/PLL.
775 * @retval Status:
776 * - 0: Current clock is HOSC, LOSC or PLL
777 * - 1: Current clock is HRC, LRC or HRC
778 */
ald_cmu_current_clock_source_get(cmu_clock_safe_type_t type)779 uint32_t ald_cmu_current_clock_source_get(cmu_clock_safe_type_t type)
780 {
781 assert_param(IS_CMU_SAFE_CLOCK_TYPE(type));
782
783 if (type == CMU_SAFE_CLK_HOSC)
784 return READ_BITS(CMU->HOSMCR, CMU_HOSMCR_CLKS_MSK, CMU_HOSMCR_CLKS_POS);
785 else if (type == CMU_SAFE_CLK_LOSC)
786 return READ_BITS(CMU->LOSMCR, CMU_LOSMCR_CLKS_MSK, CMU_LOSMCR_CLKS_POS);
787 else
788 return READ_BITS(CMU->PULMCR, CMU_PULMCR_CLKS_MSK, CMU_PULMCR_CLKS_POS);
789 }
790
791 /**
792 * @brief Get clock state.
793 * @param sr: The state type, see @ref cmu_clock_state_t.
794 * @retval SET/RESET
795 */
ald_cmu_get_clock_state(cmu_clock_state_t sr)796 flag_status_t ald_cmu_get_clock_state(cmu_clock_state_t sr)
797 {
798 assert_param(IS_CMU_CLOCK_STATE(sr));
799
800 if (READ_BIT(CMU->CLKSR, sr))
801 return SET;
802
803 return RESET;
804 }
805
806 /**
807 * @brief Interrupt callback function.
808 * @note This function is declared as __weak to be overwritten in case of other
809 * implementations in user file.
810 * @retval None
811 */
ald_cmu_irq_cbk(cmu_security_t se)812 __weak void ald_cmu_irq_cbk(cmu_security_t se)
813 {
814 return;
815 }
816 /**
817 * @}
818 */
819
820 /** @defgroup CMU_Public_Functions_Group4 Clock output configure
821 * @brief Clock output configure functions
822 *
823 * @verbatim
824 ==============================================================================
825 ##### Clock output configure functions #####
826 ==============================================================================
827 [..] This section provides functions allowing to:
828 (+) Configure the high-speed clock output.
829 (+) Configure the low-speed clock output.
830
831 @endverbatim
832 * @{
833 */
834
835 /**
836 * @brief Configure the high-speed clock output.
837 * @param sel: Select the source:
838 * @arg CMU_OUTPUT_HIGH_SEL_HOSC
839 * @arg CMU_OUTPUT_HIGH_SEL_LOSC
840 * @arg CMU_OUTPUT_HIGH_SEL_HRC
841 * @arg CMU_OUTPUT_HIGH_SEL_LRC
842 * @arg CMU_OUTPUT_HIGH_SEL_HOSM
843 * @arg CMU_OUTPUT_HIGH_SEL_PLL1
844 * @arg CMU_OUTPUT_HIGH_SEL_PLL2
845 * @arg CMU_OUTPUT_HIGH_SEL_SYSCLK
846 * @param div: The value of divider:
847 * @arg CMU_OUTPUT_DIV_1
848 * @arg CMU_OUTPUT_DIV_2
849 * @arg CMU_OUTPUT_DIV_4
850 * @arg CMU_OUTPUT_DIV_8
851 * @arg CMU_OUTPUT_DIV_16
852 * @arg CMU_OUTPUT_DIV_32
853 * @arg CMU_OUTPUT_DIV_64
854 * @arg CMU_OUTPUT_DIV_128
855 * @param status: The new status.
856 * @retval None
857 */
ald_cmu_output_high_clock_config(cmu_output_high_sel_t sel,cmu_output_high_div_t div,type_func_t status)858 void ald_cmu_output_high_clock_config(cmu_output_high_sel_t sel,
859 cmu_output_high_div_t div, type_func_t status)
860 {
861 assert_param(IS_CMU_OUTPUT_HIGH_SEL(sel));
862 assert_param(IS_CMU_OUTPUT_HIGH_DIV(div));
863 assert_param(IS_FUNC_STATE(status));
864
865 SYSCFG_UNLOCK();
866
867 if (status) {
868 MODIFY_REG(CMU->CLKOCR, CMU_CLKOCR_HSCOS_MSK, sel << CMU_CLKOCR_HSCOS_POSS);
869 MODIFY_REG(CMU->CLKOCR, CMU_CLKOCR_HSCODIV_MSK, div << CMU_CLKOCR_HSCODIV_POSS);
870 SET_BIT(CMU->CLKOCR, CMU_CLKOCR_HSCOEN_MSK);
871 }
872 else {
873 CLEAR_BIT(CMU->CLKOCR, CMU_CLKOCR_HSCOEN_MSK);
874 }
875
876 SYSCFG_LOCK();
877 return;
878 }
879
880 /**
881 * @brief Configure the low-speed clock output.
882 * @param sel: Select the source:
883 * @arg CMU_OUTPUT_LOW_SEL_LOSC
884 * @arg CMU_OUTPUT_LOW_SEL_LRC
885 * @arg CMU_OUTPUT_LOW_SEL_LOSM
886 * @arg CMU_OUTPUT_LOW_SEL_BUZZ
887 * @arg CMU_OUTPUT_LOW_SEL_ULRC
888 * @param status: The new status.
889 * @retval None
890 */
ald_cmu_output_low_clock_config(cmu_output_low_sel_t sel,type_func_t status)891 void ald_cmu_output_low_clock_config(cmu_output_low_sel_t sel, type_func_t status)
892 {
893 assert_param(IS_CMU_OUTPUT_LOW_SEL(sel));
894 assert_param(IS_FUNC_STATE(status));
895
896 SYSCFG_UNLOCK();
897
898 if (status) {
899 MODIFY_REG(CMU->CLKOCR, CMU_CLKOCR_LSCOS_MSK, sel << CMU_CLKOCR_LSCOS_POSS);
900 SET_BIT(CMU->CLKOCR, CMU_CLKOCR_LSCOEN_MSK);
901 }
902 else {
903 CLEAR_BIT(CMU->CLKOCR, CMU_CLKOCR_LSCOEN_MSK);
904 }
905
906 SYSCFG_LOCK();
907 return;
908 }
909 /**
910 * @}
911 */
912
913 /** @defgroup CMU_Public_Functions_Group5 Peripheral Clock configure
914 * @brief Peripheral clock configure functions
915 *
916 * @verbatim
917 ==============================================================================
918 ##### Peripheral clock configure functions #####
919 ==============================================================================
920 [..] This section provides functions allowing to:
921 (+) Configure buzz clock.
922 (+) Select lptim0 clock source.
923 (+) Select lpuart0 clock source.
924 (+) Select lcd clock source.
925 (+) Enable/Disable peripheral clock.
926
927 @endverbatim
928 * @{
929 */
930
931 /**
932 * @brief Configure buzz clock.
933 * freq = sysclk / (2^(div + 1) * (dat + 1))
934 * @param div: The value of divider.
935 * @param dat: The value of coefficient.
936 * @param status: The new status.
937 * @retval None
938 */
ald_cmu_buzz_config(cmu_buzz_div_t div,uint16_t dat,type_func_t status)939 void ald_cmu_buzz_config(cmu_buzz_div_t div, uint16_t dat, type_func_t status)
940 {
941 assert_param(IS_CMU_BUZZ_DIV(div));
942 assert_param(IS_FUNC_STATE(status));
943
944 SYSCFG_UNLOCK();
945
946 if (status) {
947 MODIFY_REG(CMU->BUZZCR, CMU_BUZZCR_DIV_MSK, div << CMU_BUZZCR_DIV_POSS);
948 MODIFY_REG(CMU->BUZZCR, CMU_BUZZCR_DAT_MSK, dat << CMU_BUZZCR_DAT_POSS);
949 SET_BIT(CMU->BUZZCR, CMU_BUZZCR_EN_MSK);
950 }
951 else {
952 CLEAR_BIT(CMU->BUZZCR, CMU_BUZZCR_EN_MSK);
953 }
954
955 SYSCFG_LOCK();
956 return;
957 }
958
959 /**
960 * @brief Select lptim0 clock source.
961 * @param clock: The clock source:
962 * @arg CMU_LP_PERH_CLOCK_SEL_PCLK2
963 * @arg CMU_LP_PERH_CLOCK_SEL_PLL1
964 * @arg CMU_LP_PERH_CLOCK_SEL_PLL2
965 * @arg CMU_LP_PERH_CLOCK_SEL_HRC
966 * @arg CMU_LP_PERH_CLOCK_SEL_HOSC
967 * @arg CMU_LP_PERH_CLOCK_SEL_LRC
968 * @arg CMU_LP_PERH_CLOCK_SEL_LOSC
969 * @arg CMU_LP_PERH_CLOCK_SEL_ULRC
970 * @arg CMU_LP_PERH_CLOCK_SEL_HRC_1M
971 * @arg CMU_LP_PERH_CLOCK_SEL_HOSC_1M
972 * @arg CMU_LP_PERH_CLOCK_SEL_LOSM
973 * @arg CMU_LP_PERH_CLOCK_SEL_HOSM
974 * @retval None
975 */
ald_cmu_lptim0_clock_select(cmu_lp_perh_clock_sel_t clock)976 void ald_cmu_lptim0_clock_select(cmu_lp_perh_clock_sel_t clock)
977 {
978 assert_param(IS_CMU_LP_PERH_CLOCK_SEL(clock));
979
980 SYSCFG_UNLOCK();
981 MODIFY_REG(CMU->PERICR, CMU_PERICR_LPTIM0_MSK, clock << CMU_PERICR_LPTIM0_POSS);
982 SYSCFG_LOCK();
983
984 return;
985 }
986
987 /**
988 * @brief Select lpuart0 clock source.
989 * @param clock: The clock source:
990 * @arg CMU_LP_PERH_CLOCK_SEL_PCLK2
991 * @arg CMU_LP_PERH_CLOCK_SEL_PLL1
992 * @arg CMU_LP_PERH_CLOCK_SEL_PLL2
993 * @arg CMU_LP_PERH_CLOCK_SEL_HRC
994 * @arg CMU_LP_PERH_CLOCK_SEL_HOSC
995 * @arg CMU_LP_PERH_CLOCK_SEL_LRC
996 * @arg CMU_LP_PERH_CLOCK_SEL_LOSC
997 * @arg CMU_LP_PERH_CLOCK_SEL_ULRC
998 * @arg CMU_LP_PERH_CLOCK_SEL_HRC_1M
999 * @arg CMU_LP_PERH_CLOCK_SEL_HOSC_1M
1000 * @arg CMU_LP_PERH_CLOCK_SEL_LOSM
1001 * @arg CMU_LP_PERH_CLOCK_SEL_HOSM
1002 * @retval None
1003 */
ald_cmu_lpuart0_clock_select(cmu_lp_perh_clock_sel_t clock)1004 void ald_cmu_lpuart0_clock_select(cmu_lp_perh_clock_sel_t clock)
1005 {
1006 assert_param(IS_CMU_LP_PERH_CLOCK_SEL(clock));
1007
1008 SYSCFG_UNLOCK();
1009 MODIFY_REG(CMU->PERICR, CMU_PERICR_LPUART0_MSK, clock << CMU_PERICR_LPUART0_POSS);
1010 SYSCFG_LOCK();
1011
1012 return;
1013 }
1014
1015 /**
1016 * @brief Select lcd clock source.
1017 * @param clock: The clock source:
1018 * @arg CMU_LCD_SEL_LOSM
1019 * @arg CMU_LCD_SEL_LOSC
1020 * @arg CMU_LCD_SEL_LRC
1021 * @arg CMU_LCD_SEL_ULRC
1022 * @arg CMU_LCD_SEL_HRC_1M
1023 * @arg CMU_LCD_SEL_HOSC_1M
1024 * @retval None
1025 */
ald_cmu_lcd_clock_select(cmu_lcd_clock_sel_t clock)1026 void ald_cmu_lcd_clock_select(cmu_lcd_clock_sel_t clock)
1027 {
1028 assert_param(IS_CMU_LCD_CLOCK_SEL(clock));
1029
1030 SYSCFG_UNLOCK();
1031 MODIFY_REG(CMU->PERICR, CMU_PERICR_LCD_MSK, clock << CMU_PERICR_LCD_POSS);
1032 SYSCFG_LOCK();
1033
1034 return;
1035 }
1036
1037 /**
1038 * @brief Select QSPI clock source.
1039 * @param clock: The clock source, see @ref cmu_qspi_clock_sel_t.
1040 * @retval None
1041 */
ald_cmu_qspi_clock_select(cmu_qspi_clock_sel_t clock)1042 void ald_cmu_qspi_clock_select(cmu_qspi_clock_sel_t clock)
1043 {
1044 assert_param(IS_CMU_QSPI_CLOCK_SEL(clock));
1045
1046 SYSCFG_UNLOCK();
1047 MODIFY_REG(CMU->PERICR, CMU_PERICR_QSPICS_MSK, clock << CMU_PERICR_QSPICS_POSS);
1048 SYSCFG_LOCK();
1049
1050 return;
1051 }
1052
1053 /**
1054 * @brief Configure USB clock source.
1055 * @param clock: The clock source, see @ref cmu_usb_clock_sel_t.
1056 * @param div: The clock division, see @ref cmu_usb_div_t.
1057 * @retval None
1058 */
ald_cmu_usb_clock_config(cmu_usb_clock_sel_t clock,cmu_usb_div_t div)1059 void ald_cmu_usb_clock_config(cmu_usb_clock_sel_t clock, cmu_usb_div_t div)
1060 {
1061 assert_param(IS_CMU_USB_CLOCK_SEL(clock));
1062 assert_param(IS_CMU_USB_DIV(div));
1063
1064 SYSCFG_UNLOCK();
1065
1066 if (clock == CMU_USB_CLOCK_SEL_HRC)
1067 SET_BIT(SYSCFG->USBCFG, SYSCFG_USBCFG_CLKRDYBP_MSK);
1068 else
1069 CLEAR_BIT(SYSCFG->USBCFG, SYSCFG_USBCFG_CLKRDYBP_MSK);
1070
1071 MODIFY_REG(CMU->PERICR, CMU_PERICR_USBPHYCS_MSK, clock << CMU_PERICR_USBPHYCS_POSS);
1072 MODIFY_REG(CMU->PERIDIVR, CMU_PERIDIVR_USBPHYDIV_MSK, div << CMU_PERIDIVR_USBPHYDIV_POSS);
1073 SYSCFG_LOCK();
1074
1075 return;
1076 }
1077
1078 /**
1079 * @brief Enable/Disable peripheral clock.
1080 * @param perh: The type of peripheral, you can see @ref cmu_perh_t
1081 * @param status: The new status.
1082 * @retval None
1083 */
ald_cmu_perh_clock_config(cmu_perh_t perh,type_func_t status)1084 void ald_cmu_perh_clock_config(cmu_perh_t perh, type_func_t status)
1085 {
1086 uint32_t idx, pos;
1087
1088 assert_param(IS_CMU_PERH(perh));
1089 assert_param(IS_FUNC_STATE(status));
1090
1091 SYSCFG_UNLOCK();
1092
1093 if (perh == CMU_PERH_ALL) {
1094 if (status) {
1095 WRITE_REG(CMU->AHB1ENR, ~0);
1096 WRITE_REG(CMU->APB1ENR, ~0);
1097 WRITE_REG(CMU->APB2ENR, ~0);
1098 }
1099 else {
1100 WRITE_REG(CMU->AHB1ENR, 0);
1101 WRITE_REG(CMU->APB1ENR, 0);
1102 WRITE_REG(CMU->APB2ENR, 0);
1103 }
1104
1105 SYSCFG_LOCK();
1106 return;
1107 }
1108
1109 idx = (uint32_t)(perh >> 27) & 0x3;
1110 pos = perh & ~(0x3 << 27);
1111
1112 if (status) {
1113 switch (idx) {
1114 case 0:
1115 SET_BIT(CMU->AHB1ENR, pos);
1116 break;
1117
1118 case 1:
1119 SET_BIT(CMU->APB1ENR, pos);
1120 break;
1121
1122 case 2:
1123 SET_BIT(CMU->APB2ENR, pos);
1124 break;
1125
1126 default:
1127 break;
1128 }
1129 }
1130 else {
1131 switch (idx) {
1132 case 0:
1133 CLEAR_BIT(CMU->AHB1ENR, pos);
1134 break;
1135
1136 case 1:
1137 CLEAR_BIT(CMU->APB1ENR, pos);
1138 break;
1139
1140 case 2:
1141 CLEAR_BIT(CMU->APB2ENR, pos);
1142 break;
1143
1144 default:
1145 break;
1146 }
1147 }
1148
1149 SYSCFG_LOCK();
1150 return;
1151 }
1152
1153 /**
1154 * @brief Select stop1 clock.
1155 * @param clock: See @ref cmu_stop1_clock_t
1156 * @retval None
1157 */
ald_cmu_stop1_clock_sel(cmu_stop1_clock_t clock)1158 void ald_cmu_stop1_clock_sel(cmu_stop1_clock_t clock)
1159 {
1160 assert_param(IS_CMU_STOP1_CLOCK(clock));
1161
1162 SYSCFG_UNLOCK();
1163 MODIFY_REG(CMU->LPENR, CMU_LPENR_STOP1CS_MSK, clock << CMU_LPENR_STOP1CS_POSS);
1164 SYSCFG_LOCK();
1165 return;
1166 }
1167 /**
1168 * @}
1169 */
1170 /**
1171 * @}
1172 */
1173
1174 /**
1175 * @}
1176 */
1177
1178 /**
1179 * @}
1180 */
1181