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