1 /*!
2 * @file apm32s10x_rcm.c
3 *
4 * @brief This file provides all the RCM firmware functions
5 *
6 * @version V1.0.1
7 *
8 * @date 2022-12-31
9 *
10 * @attention
11 *
12 * Copyright (C) 2022-2023 Geehy Semiconductor
13 *
14 * You may not use this file except in compliance with the
15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16 *
17 * The program is only for reference, which is distributed in the hope
18 * that it will be usefull and instructional for customers to develop
19 * their software. Unless required by applicable law or agreed to in
20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23 * and limitations under the License.
24 */
25
26 /* Includes */
27 #include "apm32s10x_rcm.h"
28
29 /** @addtogroup APM32S10x_StdPeriphDriver
30 @{
31 */
32
33 /** @addtogroup RCM_Driver RCM Driver
34 @{
35 */
36
37 /** @defgroup RCM_Functions Functions
38 @{
39 */
40
41 /*!
42 * @brief Reset the clock configuration to the default state
43 *
44 * @param None
45 *
46 * @retval None
47 */
RCM_Reset(void)48 void RCM_Reset(void)
49 {
50 /* Open HSI clock */
51 RCM->CTRL_B.HSIEN = BIT_SET;
52 /* Config HSI to system clock and Reset AHBPSC, APB1PSC, APB2PSC, ADCPSC and MCOSEL bits */
53 RCM->CFG &= (uint32_t)0xF8FF0000;
54 /* Reset HSEEN, CSSEN and PLLEN bits */
55 RCM->CTRL &= (uint32_t)0xFEF6FFFF;
56 /* Reset HSEBCFG bit */
57 RCM->CTRL_B.HSEBCFG = BIT_RESET;
58 /* Reset PLLSRCSEL, PLLHSEPSC, PLLMULCFG and USBDIV bits */
59 RCM->CFG &= (uint32_t)0xFF00FFFF;
60 /* Disable all interrupts and clear pending bits */
61 RCM->INT = 0x009F0000;
62 }
63
64 /*!
65 * @brief Configure the HSE oscillator
66 *
67 * @param state: state of the HSE
68 * This parameter can be one of the following values:
69 * @arg RCM_HSE_CLOSE: Turn off the HSE oscillator
70 * @arg RCM_HSE_OPEN: Turn on the HSE oscillator
71 * @arg RCM_HSE_BYPASS: HSE oscillator bypassed with external clock
72 *
73 * @retval None
74 *
75 * @note When HSE is not used directly or through the PLL as system clock, it can be stopped.
76 */
RCM_ConfigHSE(RCM_HSE_T state)77 void RCM_ConfigHSE(RCM_HSE_T state)
78 {
79 /* Reset HSEEN bit */
80 RCM->CTRL_B.HSEEN = BIT_RESET;
81
82 /* Reset HSEBCFG bit */
83 RCM->CTRL_B.HSEBCFG = BIT_RESET;
84
85 if (state == RCM_HSE_OPEN)
86 {
87 RCM->CTRL_B.HSEEN = BIT_SET;
88 }
89 else if (state == RCM_HSE_BYPASS)
90 {
91 RCM->CTRL_B.HSEBCFG = BIT_SET;
92 RCM->CTRL_B.HSEEN = BIT_SET;
93 }
94 }
95
96 /*!
97 * @brief Wait for HSE to be ready
98 *
99 * @param None
100 *
101 * @retval SUCCESS: HSE oscillator is ready
102 * ERROR : HSE oscillator is not ready
103 */
RCM_WaitHSEReady(void)104 uint8_t RCM_WaitHSEReady(void)
105 {
106 __IO uint32_t cnt;
107
108 for (cnt = 0; cnt < HSE_STARTUP_TIMEOUT; cnt++)
109 {
110 if (RCM->CTRL_B.HSERDYFLG == BIT_SET)
111 {
112 return SUCCESS;
113 }
114 }
115
116 return ERROR;
117 }
118
119 /*!
120 * @brief Configure HSI trimming value
121 *
122 * @param HSITrim: HSI trimming value
123 * This parameter must be a number between 0 and 0x1F.
124 *
125 * @retval None
126 */
RCM_ConfigHSITrim(uint8_t HSITrim)127 void RCM_ConfigHSITrim(uint8_t HSITrim)
128 {
129 RCM->CTRL_B.HSITRIM = HSITrim;
130 }
131
132 /*!
133 * @brief Enable the HSI
134 *
135 * @param None
136 *
137 * @retval None
138 */
RCM_EnableHSI(void)139 void RCM_EnableHSI(void)
140 {
141 RCM->CTRL_B.HSIEN = BIT_SET;
142 }
143
144 /*!
145 * @brief Disable the HSI
146 *
147 * @param None
148 *
149 * @retval None
150 *
151 * @note When HSI is not used directly or through the PLL as system clock, it can be stopped.
152 */
153
RCM_DisableHSI(void)154 void RCM_DisableHSI(void)
155 {
156 RCM->CTRL_B.HSIEN = BIT_RESET;
157 }
158
159 /*!
160 * @brief Configure the External Low Speed oscillator (LSE)
161 *
162 * @param state : Specify the new state of the LSE
163 * This parameter can be one of the following values:
164 * @arg RCM_LSE_CLOSE : Close the LSE
165 * @arg RCM_LSE_OPEN : Open the LSE
166 * @arg RCM_LSE_BYPASS : LSE bypass
167 *
168 * @retval None
169 */
RCM_ConfigLSE(RCM_LSE_T state)170 void RCM_ConfigLSE(RCM_LSE_T state)
171 {
172 RCM->BDCTRL_B.LSEEN = BIT_RESET;
173 RCM->BDCTRL_B.LSEBCFG = BIT_RESET;
174
175 if (state == RCM_LSE_OPEN)
176 {
177 RCM->BDCTRL_B.LSEEN = BIT_SET;
178 }
179 else if (state == RCM_LSE_BYPASS)
180 {
181 RCM->BDCTRL_B.LSEBCFG = BIT_SET;
182 RCM->BDCTRL_B.LSEEN = BIT_SET;
183 }
184 }
185
186 /*!
187 * @brief Enable the Internal Low Speed oscillator (LSI)
188 *
189 * @param None
190 *
191 * @retval None
192 */
RCM_EnableLSI(void)193 void RCM_EnableLSI(void)
194 {
195 RCM->CSTS_B.LSIEN = BIT_SET;
196 }
197
198 /*!
199 * @brief Disable the Internal Low Speed oscillator (LSI)
200 *
201 * @param None
202 *
203 * @retval None
204 */
RCM_DisableLSI(void)205 void RCM_DisableLSI(void)
206 {
207 RCM->CSTS_B.LSIEN = BIT_RESET;
208 }
209
210 /*!
211 * @brief Configure the PLL clock source and multiplication factor
212 *
213 * @param pllSelect : PLL entry clock source select
214 * This parameter can be one of the following values:
215 * @arg RCM_PLLSEL_HSI_DIV_2: HSI clock divided by 2 selected as PLL clock source
216 * @arg RCM_PLLSEL_HSE: HSE clock selected as PLL clock source
217 * @arg RCM_PLLSEL_HSE_DIV2: HSE clock divided by 2 selected as PLL clock source
218 *
219 * @param pllMf : PLL multiplication factor
220 * This parameter can be RCM_PLLMF_x where x can be a value from 2 to 16.
221 *
222 * @retval None
223 *
224 * @note PLL should be disabled while use this function.
225 */
RCM_ConfigPLL(RCM_PLLSEL_T pllSelect,RCM_PLLMF_T pllMf)226 void RCM_ConfigPLL(RCM_PLLSEL_T pllSelect, RCM_PLLMF_T pllMf)
227 {
228 RCM->CFG_B.PLLMULCFG = pllMf;
229 RCM->CFG_B.PLLSRCSEL = pllSelect & 0x01;
230 RCM->CFG_B.PLLHSEPSC = (pllSelect >> 1) & 0x01;
231 }
232
233 /*!
234 * @brief Enable the PLL
235 *
236 * @param None
237 *
238 * @retval None
239 */
RCM_EnablePLL(void)240 void RCM_EnablePLL(void)
241 {
242 RCM->CTRL_B.PLLEN = BIT_SET;
243 }
244
245 /*!
246 * @brief Disable the PLL
247 *
248 * @param None
249 *
250 * @retval None
251 *
252 * @note When PLL is not used as system clock, it can be stopped.
253 */
RCM_DisablePLL(void)254 void RCM_DisablePLL(void)
255 {
256 RCM->CTRL_B.PLLEN = BIT_RESET;
257 }
258
259 /*!
260 * @brief Enable the Clock Security System
261 *
262 * @param None
263 *
264 * @retval None
265 */
RCM_EnableCSS(void)266 void RCM_EnableCSS(void)
267 {
268 RCM->CTRL_B.CSSEN = BIT_SET;
269 }
270
271 /*!
272 * @brief Disable the Clock Security System
273 *
274 * @param None
275 *
276 * @retval None
277 */
RCM_DisableCSS(void)278 void RCM_DisableCSS(void)
279 {
280 RCM->CTRL_B.CSSEN = BIT_RESET;
281 }
282
283 /*!
284 * @brief Select the MCO pin clock ouput source
285 *
286 * @param mcoClock: specify the clock source to output
287 * This parameter can be one of the following values:
288 * @arg RCM_MCOCLK_NO_CLOCK : No clock selected.
289 * @arg RCM_MCOCLK_SYSCLK : System clock selected.
290 * @arg RCM_MCOCLK_HSI : HSI oscillator clock selected.
291 * @arg RCM_MCOCLK_HSE : HSE oscillator clock selected.
292 * @arg RCM_MCOCLK_PLLCLK_DIV_2 : PLL clock divided by 2 selected.
293 *
294 * @retval None
295 */
RCM_ConfigMCO(RCM_MCOCLK_T mcoClock)296 void RCM_ConfigMCO(RCM_MCOCLK_T mcoClock)
297 {
298 RCM->CFG_B.MCOSEL = mcoClock;
299 }
300
301 /*!
302 * @brief Configure the system clock source
303 *
304 * @param sysClkSelect: specify the clock source used as system clock
305 * This parameter can be one of the following values:
306 * @arg RCM_SYSCLK_SEL_HSI: HSI is selected as system clock source
307 * @arg RCM_SYSCLK_SEL_HSE: HSE is selected as system clock source
308 * @arg RCM_SYSCLK_SEL_PLL: PLL is selected as system clock source
309 *
310 * @retva None
311 */
RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_T sysClkSelect)312 void RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_T sysClkSelect)
313 {
314 RCM->CFG_B.SCLKSEL = sysClkSelect;
315 }
316
317 /*!
318 * @brief Return the clock source which is used as system clock
319 *
320 * @param None
321 *
322 * @retval The clock source used as system clock
323 */
RCM_ReadSYSCLKSource(void)324 RCM_SYSCLK_SEL_T RCM_ReadSYSCLKSource(void)
325 {
326 return (RCM_SYSCLK_SEL_T)RCM->CFG_B.SCLKSELSTS;
327 }
328
329 /*!
330 * @brief Configure the AHB clock prescaler.
331 *
332 * @param AHBDiv : Specify the AHB clock prescaler from the system clock.
333 * This parameter can be one of the following values:
334 * @arg RCM_AHB_DIV_1 : HCLK = SYSCLK
335 * @arg RCM_AHB_DIV_2 : HCLK = SYSCLK / 2
336 * @arg RCM_AHB_DIV_4 : HCLK = SYSCLK / 4
337 * @arg RCM_AHB_DIV_8 : HCLK = SYSCLK / 8
338 * @arg RCM_AHB_DIV_16 : HCLK = SYSCLK / 16
339 * @arg RCM_AHB_DIV_64 : HCLK = SYSCLK / 64
340 * @arg RCM_AHB_DIV_128 : HCLK = SYSCLK / 128
341 * @arg RCM_AHB_DIV_256 : HCLK = SYSCLK / 256
342 * @arg RCM_AHB_DIV_512 : HCLK = SYSCLK / 512
343 *
344 * @retval None
345 */
RCM_ConfigAHB(RCM_AHB_DIV_T AHBDiv)346 void RCM_ConfigAHB(RCM_AHB_DIV_T AHBDiv)
347 {
348 RCM->CFG_B.AHBPSC = AHBDiv;
349 }
350
351 /*!
352 * @brief Configure the APB1 clock prescaler.
353 *
354 * @param APB1Div: Specify the APB1 clock prescaler from the AHB clock.
355 * This parameter can be one of the following values:
356 * @arg RCM_APB_DIV_1 : PCLK1 = HCLK
357 * @arg RCM_APB_DIV_2 : PCLK1 = HCLK / 2
358 * @arg RCM_APB_DIV_4 : PCLK1 = HCLK / 4
359 * @arg RCM_APB_DIV_8 : PCLK1 = HCLK / 8
360 * @arg RCM_APB_DIV_16 : PCLK1 = HCLK / 16
361 *
362 * @retval None
363 */
RCM_ConfigAPB1(RCM_APB_DIV_T APB1Div)364 void RCM_ConfigAPB1(RCM_APB_DIV_T APB1Div)
365 {
366 RCM->CFG_B.APB1PSC = APB1Div;
367 }
368
369 /*!
370 * @brief Configure the APB2 clock prescaler
371 *
372 * @param APB2Div: Specify the APB2 clock prescaler from the AHB clock.
373 * This parameter can be one of the following values:
374 * @arg RCM_APB_DIV_1 : PCLK2 = HCLK
375 * @arg RCM_APB_DIV_2 : PCLK2 = HCLK / 2
376 * @arg RCM_APB_DIV_4 : PCLK2 = HCLK / 4
377 * @arg RCM_APB_DIV_8 : PCLK2 = HCLK / 8
378 * @arg RCM_APB_DIV_16 : PCLK2 = HCLK / 16
379 *
380 * @retval None
381 */
RCM_ConfigAPB2(RCM_APB_DIV_T APB2Div)382 void RCM_ConfigAPB2(RCM_APB_DIV_T APB2Div)
383 {
384 RCM->CFG_B.APB2PSC = APB2Div;
385 }
386
387 /*!
388 * @brief Configure the USB clock prescaler
389 *
390 * @param USBDiv: Specify the USB clock prescaler from the PLL clock.
391 * This parameter can be one of the following values:
392 * @arg RCM_USB_DIV_1_5 : USBCLK = PLL clock /1.5
393 * @arg RCM_USB_DIV_1 : USBCLK = PLL clock
394 * @arg RCM_USB_DIV_2 : USBCLK = PLL clock / 2
395 *
396 * @retval None
397 */
RCM_ConfigUSBCLK(RCM_USB_DIV_T USBDiv)398 void RCM_ConfigUSBCLK(RCM_USB_DIV_T USBDiv)
399 {
400 RCM->CFG_B.USBDPSC = USBDiv;
401 }
402
403 /*!
404 * @brief Configure the FPU clock prescaler
405 *
406 * @param FPUDiv: Specify the FPU clock prescaler from the AHB clock.
407 * This parameter can be one of the following values:
408 * @arg RCM_FPU_DIV_1 : FPUCLK = HCLK
409 * @arg RCM_FPU_DIV_2 : FPUCLK = HCLK /2
410 *
411 * @retval None
412 */
RCM_ConfigFPUCLK(RCM_FPU_DIV_T FPUDiv)413 void RCM_ConfigFPUCLK(RCM_FPU_DIV_T FPUDiv)
414 {
415 RCM->CFG_B.FPUPSC = FPUDiv;
416 }
417
418 /*!
419 * @brief Configure the ADC clock prescaler
420 *
421 * @param ADCDiv : Specify the ADC clock prescaler from the APB2 clock.
422 * This parameter can be one of the following values:
423 * @arg RCM_PCLK2_DIV_2: ADCCLK = PCLK2 / 2
424 * @arg RCM_PCLK2_DIV_4: ADCCLK = PCLK2 / 4
425 * @arg RCM_PCLK2_DIV_6: ADCCLK = PCLK2 / 6
426 * @arg RCM_PCLK2_DIV_8: ADCCLK = PCLK2 / 8
427 *
428 * @retval None
429 */
RCM_ConfigADCCLK(RCM_PCLK2_DIV_T ADCDiv)430 void RCM_ConfigADCCLK(RCM_PCLK2_DIV_T ADCDiv)
431 {
432 RCM->CFG_B.ADCPSC = ADCDiv;
433 }
434
435 /*!
436 * @brief Configure the RTC clock source
437 *
438 * @param rtcClkSelect : specify the RTC clock source.
439 * This parameter can be one of the following values:
440 * @arg RCM_RTCCLK_LSE : RTCCLK = LSE clock
441 * @arg RCM_RTCCLK_LSI : RTCCLK = LSI clock
442 * @arg RCM_RTCCLK_HSE_DIV_128: RTCCLK = HSE clock / 128
443 *
444 * @retval None
445 *
446 * @note Once the RTC clock is configed it can't be changed unless reset the Backup domain.
447 */
RCM_ConfigRTCCLK(RCM_RTCCLK_T rtcClkSelect)448 void RCM_ConfigRTCCLK(RCM_RTCCLK_T rtcClkSelect)
449 {
450 RCM->BDCTRL_B.RTCSRCSEL = rtcClkSelect;
451 }
452
453 /*!
454 * @brief Enable the RTC clock
455 *
456 * @param None
457 *
458 * @retval None
459 */
RCM_EnableRTCCLK(void)460 void RCM_EnableRTCCLK(void)
461 {
462 RCM->BDCTRL_B.RTCCLKEN = BIT_SET;
463 }
464
465 /*!
466 * @brief Disable the RTC clock
467 *
468 * @param None
469 *
470 * @retval None
471 */
RCM_DisableRTCCLK(void)472 void RCM_DisableRTCCLK(void)
473 {
474 RCM->BDCTRL_B.RTCCLKEN = BIT_RESET;
475 }
476
477 /*!
478 * @brief Reads the frequency of SYSCLK
479 *
480 * @param None
481 *
482 * @retval Return the frequency of SYSCLK
483 */
RCM_ReadSYSCLKFreq(void)484 uint32_t RCM_ReadSYSCLKFreq(void)
485 {
486 uint32_t sysClock, pllMull, pllSource;
487
488 /* get sys clock */
489 sysClock = RCM->CFG_B.SCLKSEL;
490
491 switch (sysClock)
492 {
493 /* sys clock is HSI */
494 case RCM_SYSCLK_SEL_HSI:
495 sysClock = HSI_VALUE;
496 break;
497
498 /* sys clock is HSE */
499 case RCM_SYSCLK_SEL_HSE:
500 sysClock = HSE_VALUE;
501 break;
502
503 /* sys clock is PLL */
504 case RCM_SYSCLK_SEL_PLL:
505 pllMull = RCM->CFG_B.PLLMULCFG + 2;
506 pllSource = RCM->CFG_B.PLLSRCSEL;
507
508 /* PLL entry clock source is HSE */
509 if (pllSource == BIT_SET)
510 {
511 sysClock = HSE_VALUE * pllMull;
512
513 /* HSE clock divided by 2 */
514 if (pllSource == RCM->CFG_B.PLLHSEPSC)
515 {
516 sysClock >>= 1;
517 }
518 }
519 /* PLL entry clock source is HSI/2 */
520 else
521 {
522 sysClock = (HSI_VALUE >> 1) * pllMull;
523 }
524
525 break;
526
527 default:
528 sysClock = HSI_VALUE;
529 break;
530 }
531
532 return sysClock;
533 }
534
535 /*!
536 * @brief Read the frequency of HCLK(AHB)
537 *
538 * @param None
539 *
540 * @retval Return the frequency of HCLK
541 */
RCM_ReadHCLKFreq(void)542 uint32_t RCM_ReadHCLKFreq(void)
543 {
544 uint32_t divider;
545 uint32_t sysClk, hclk;
546 uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
547
548 sysClk = RCM_ReadSYSCLKFreq();
549 divider = AHBPrescTable[RCM->CFG_B.AHBPSC];
550 hclk = sysClk >> divider;
551
552 return hclk;
553 }
554
555 /*!
556 * @brief Read the frequency of PCLK1 And PCLK2
557 *
558 * @param PCLK1 : Return the frequency of PCLK1
559 *
560 * @param PCLK1 : Return the frequency of PCLK2
561 *
562 * @retval None
563 */
RCM_ReadPCLKFreq(uint32_t * PCLK1,uint32_t * PCLK2)564 void RCM_ReadPCLKFreq(uint32_t* PCLK1, uint32_t* PCLK2)
565 {
566 uint32_t hclk, divider;
567 uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
568
569 hclk = RCM_ReadHCLKFreq();
570
571 if (PCLK1)
572 {
573 divider = APBPrescTable[RCM->CFG_B.APB1PSC];
574 *PCLK1 = hclk >> divider;
575 }
576
577 if (PCLK2)
578 {
579 divider = APBPrescTable[RCM->CFG_B.APB2PSC];
580 *PCLK2 = hclk >> divider;
581 }
582 }
583
584 /*!
585 * @brief Read the frequency of ADCCLK
586 *
587 * @param None
588 *
589 * @retval Return the frequency of ADCCLK
590 */
RCM_ReadADCCLKFreq(void)591 uint32_t RCM_ReadADCCLKFreq(void)
592 {
593 uint32_t adcClk, pclk2, divider;
594 uint8_t ADCPrescTable[4] = {2, 4, 6, 8};
595
596 RCM_ReadPCLKFreq(NULL, &pclk2);
597
598 /** Get ADC CLK */
599 divider = ADCPrescTable[RCM->CFG_B.ADCPSC];
600 adcClk = pclk2 / divider;
601
602 return adcClk;
603 }
604
605 /*!
606 * @brief Enables AHB peripheral clock.
607 *
608 * @param AHBPeriph : Enable the specified clock of AHB peripheral.
609 * This parameter can be any combination of the following values:
610 * @arg RCM_AHB_PERIPH_DMA1 : Enable DMA1 clock
611 * @arg RCM_AHB_PERIPH_SRAM : Enable SRAM clock
612 * @arg RCM_AHB_PERIPH_FPU : Enable FPU clock
613 * @arg RCM_AHB_PERIPH_FMC : Enable FMC clock
614 * @arg RCM_AHB_PERIPH_QSPI : Enable QSPI clock
615 * @arg RCM_AHB_PERIPH_CRC : Enable CRC clock
616 *
617 * @retval None
618 */
RCM_EnableAHBPeriphClock(uint32_t AHBPeriph)619 void RCM_EnableAHBPeriphClock(uint32_t AHBPeriph)
620 {
621 RCM->AHBCLKEN |= AHBPeriph;
622 }
623
624 /*!
625 * @brief Disable AHB peripheral clock.
626 *
627 * @param AHBPeriph : Disable the specified clock of AHB peripheral.
628 * This parameter can be any combination of the following values:
629 * @arg RCM_AHB_PERIPH_DMA1 : Disable DMA1 clock
630 * @arg RCM_AHB_PERIPH_SRAM : Disable SRAM clock
631 * @arg RCM_AHB_PERIPH_FPU : Disable FPU clock
632 * @arg RCM_AHB_PERIPH_FMC : Disable FMC clock
633 * @arg RCM_AHB_PERIPH_QSPI : Disable QSPI clock
634 * @arg RCM_AHB_PERIPH_CRC : Disable CRC clock
635 *
636 * @retval None
637 */
RCM_DisableAHBPeriphClock(uint32_t AHBPeriph)638 void RCM_DisableAHBPeriphClock(uint32_t AHBPeriph)
639 {
640 RCM->AHBCLKEN &= (uint32_t)~AHBPeriph;
641 }
642
643 /*!
644 * @brief Enable the High Speed APB (APB2) peripheral clock
645 *
646 * @param APB2Periph : Enable the specified clock of the APB2 peripheral.
647 * This parameter can be any combination of the following values:
648 * @arg RCM_APB2_PERIPH_AFIO : Enable AFIO clock
649 * @arg RCM_APB2_PERIPH_GPIOA : Enable GPIOA clock
650 * @arg RCM_APB2_PERIPH_GPIOB : Enable GPIOB clock
651 * @arg RCM_APB2_PERIPH_GPIOC : Enable GPIOC clock
652 * @arg RCM_APB2_PERIPH_GPIOD : Enable GPIOD clock
653 * @arg RCM_APB2_PERIPH_GPIOE : Enable GPIOE clock
654 * @arg RCM_APB2_PERIPH_ADC1 : Enable ADC1 clock
655 * @arg RCM_APB2_PERIPH_ADC2 : Enable ADC2 clock
656 * @arg RCM_APB2_PERIPH_TMR1 : Enable TMR1 clock
657 * @arg RCM_APB2_PERIPH_SPI1 : Enable SPI1 clock
658 * @arg RCM_APB2_PERIPH_USART1 : Enable USART1 clock
659 *
660 * @retval None
661 */
RCM_EnableAPB2PeriphClock(uint32_t APB2Periph)662 void RCM_EnableAPB2PeriphClock(uint32_t APB2Periph)
663 {
664 RCM->APB2CLKEN |= APB2Periph;
665 }
666
667 /*!
668 * @brief Disable the High Speed APB (APB2) peripheral clock
669 *
670 * @param APB2Periph : Disable the specified clock of the APB2 peripheral.
671 * This parameter can be any combination of the following values:
672 * @arg RCM_APB2_PERIPH_AFIO : Disable AFIO clock
673 * @arg RCM_APB2_PERIPH_GPIOA : Disable GPIOA clock
674 * @arg RCM_APB2_PERIPH_GPIOB : Disable GPIOB clock
675 * @arg RCM_APB2_PERIPH_GPIOC : Disable GPIOC clock
676 * @arg RCM_APB2_PERIPH_GPIOD : Disable GPIOD clock
677 * @arg RCM_APB2_PERIPH_GPIOE : Disable GPIOE clock
678 * @arg RCM_APB2_PERIPH_ADC1 : Disable ADC1 clock
679 * @arg RCM_APB2_PERIPH_ADC2 : Disable ADC2 clock
680 * @arg RCM_APB2_PERIPH_TMR1 : Disable TMR1 clock
681 * @arg RCM_APB2_PERIPH_SPI1 : Disable SPI1 clock
682 * @arg RCM_APB2_PERIPH_USART1 : Disable USART1 clock
683 *
684 * @retval None
685 */
RCM_DisableAPB2PeriphClock(uint32_t APB2Periph)686 void RCM_DisableAPB2PeriphClock(uint32_t APB2Periph)
687 {
688 RCM->APB2CLKEN &= (uint32_t)~APB2Periph;
689 }
690
691 /*!
692 * @brief Enable the Low Speed APB (APB1) peripheral clock
693 *
694 * @param APB1Periph : Enable the specified clock of the APB1 peripheral.
695 * This parameter can be any combination of the following values:
696 * @arg RCM_APB1_PERIPH_TMR2 : Enable TMR2 clock
697 * @arg RCM_APB1_PERIPH_TMR3 : Enable TMR3 clock
698 * @arg RCM_APB1_PERIPH_TMR4 : Enable TMR4 clock
699 * @arg RCM_APB1_PERIPH_WWDT : Enable WWDT clock
700 * @arg RCM_APB1_PERIPH_SPI2 : Enable SPI2 clock
701 * @arg RCM_APB1_PERIPH_USART2 : Enable USART2 clock
702 * @arg RCM_APB1_PERIPH_USART3 : Enable USART3 clock
703 * @arg RCM_APB1_PERIPH_I2C1 : Enable I2C1 clock
704 * @arg RCM_APB1_PERIPH_I2C2 : Enable I2C2 clock
705 * @arg RCM_APB1_PERIPH_USB : Enable USB clock
706 * @arg RCM_APB1_PERIPH_CAN1 : Enable CAN1 clock
707 * @arg RCM_APB1_PERIPH_CAN2 : Enable CAN2 clock
708 * @arg RCM_APB1_PERIPH_BAKR : Enable BAKR clock
709 * @arg RCM_APB1_PERIPH_PMU : Enable PMU clock
710 *
711 * @retval None
712 */
RCM_EnableAPB1PeriphClock(uint32_t APB1Periph)713 void RCM_EnableAPB1PeriphClock(uint32_t APB1Periph)
714 {
715 RCM->APB1CLKEN |= APB1Periph;
716 }
717
718 /*!
719 * @brief Disable the Low Speed APB (APB1) peripheral clock
720 *
721 * @param APB1Periph : Disable the specified clock of the APB1 peripheral.
722 * This parameter can be any combination of the following values:
723 * @arg RCM_APB1_PERIPH_TMR2 : Disable TMR2 clock
724 * @arg RCM_APB1_PERIPH_TMR3 : Disable TMR3 clock
725 * @arg RCM_APB1_PERIPH_TMR4 : Disable TMR4 clock
726 * @arg RCM_APB1_PERIPH_WWDT : Disable WWDT clock
727 * @arg RCM_APB1_PERIPH_SPI2 : Disable SPI2 clock
728 * @arg RCM_APB1_PERIPH_USART2 : Disable USART2 clock
729 * @arg RCM_APB1_PERIPH_USART3 : Disable USART3 clock
730 * @arg RCM_APB1_PERIPH_I2C1 : Disable I2C1 clock
731 * @arg RCM_APB1_PERIPH_I2C2 : Disable I2C2 clock
732 * @arg RCM_APB1_PERIPH_USB : Disable USB clock
733 * @arg RCM_APB1_PERIPH_CAN1 : Disable CAN1 clock
734 * @arg RCM_APB1_PERIPH_CAN2 : Disable CAN2 clock
735 * @arg RCM_APB1_PERIPH_BAKR : Disable BAKR clock
736 * @arg RCM_APB1_PERIPH_PMU : Disable PMU clock
737 *
738 * @retval None
739 */
RCM_DisableAPB1PeriphClock(uint32_t APB1Periph)740 void RCM_DisableAPB1PeriphClock(uint32_t APB1Periph)
741 {
742 RCM->APB1CLKEN &= (uint32_t)~APB1Periph;
743 }
744
745 /*!
746 * @brief Enable High Speed APB (APB2) peripheral reset
747 *
748 * @param APB2Periph : Enable the specified APB2 peripheral reset.
749 * This parameter can be any combination of the following values:
750 * @arg RCM_APB2_PERIPH_AFIO : Enable AFIO reset
751 * @arg RCM_APB2_PERIPH_GPIOA : Enable GPIOA reset
752 * @arg RCM_APB2_PERIPH_GPIOB : Enable GPIOB reset
753 * @arg RCM_APB2_PERIPH_GPIOC : Enable GPIOC reset
754 * @arg RCM_APB2_PERIPH_GPIOD : Enable GPIOD reset
755 * @arg RCM_APB2_PERIPH_GPIOE : Enable GPIOE reset
756 * @arg RCM_APB2_PERIPH_ADC1 : Enable ADC1 reset
757 * @arg RCM_APB2_PERIPH_ADC2 : Enable ADC2 reset
758 * @arg RCM_APB2_PERIPH_TMR1 : Enable TMR1 reset
759 * @arg RCM_APB2_PERIPH_SPI1 : Enable SPI1 reset
760 * @arg RCM_APB2_PERIPH_USART1 : Enable USART1 reset
761 *
762 * @retval None
763 */
RCM_EnableAPB2PeriphReset(uint32_t APB2Periph)764 void RCM_EnableAPB2PeriphReset(uint32_t APB2Periph)
765 {
766 RCM->APB2RST |= APB2Periph;
767 }
768
769 /*!
770 * @brief Disable High Speed APB (APB2) peripheral reset
771 *
772 * @param APB2Periph : Disable the specified APB2 peripheral reset.
773 * This parameter can be any combination of the following values:
774 * @arg RCM_APB2_PERIPH_AFIO : Disable AFIO reset
775 * @arg RCM_APB2_PERIPH_GPIOA : Disable GPIOA reset
776 * @arg RCM_APB2_PERIPH_GPIOB : Disable GPIOB reset
777 * @arg RCM_APB2_PERIPH_GPIOC : Disable GPIOC reset
778 * @arg RCM_APB2_PERIPH_GPIOD : Disable GPIOD reset
779 * @arg RCM_APB2_PERIPH_GPIOE : Disable GPIOE reset
780 * @arg RCM_APB2_PERIPH_ADC1 : Disable ADC1 reset
781 * @arg RCM_APB2_PERIPH_ADC2 : Disable ADC2 reset
782 * @arg RCM_APB2_PERIPH_TMR1 : Disable TMR1 reset
783 * @arg RCM_APB2_PERIPH_SPI1 : Disable SPI1 reset
784 * @arg RCM_APB2_PERIPH_USART1 : Disable USART1 reset
785 *
786 * @retval None
787 */
RCM_DisableAPB2PeriphReset(uint32_t APB2Periph)788 void RCM_DisableAPB2PeriphReset(uint32_t APB2Periph)
789 {
790 RCM->APB2RST &= (uint32_t)~APB2Periph;
791 }
792
793 /*!
794 * @brief Enable Low Speed APB (APB1) peripheral reset
795 *
796 * @param APB1Periph : Enable the specified APB1 peripheral reset.
797 * This parameter can be any combination of the following values:
798 * @arg RCM_APB1_PERIPH_TMR2 : Enable TMR2 reset
799 * @arg RCM_APB1_PERIPH_TMR3 : Enable TMR3 reset
800 * @arg RCM_APB1_PERIPH_TMR4 : Enable TMR4 reset
801 * @arg RCM_APB1_PERIPH_WWDT : Enable WWDT reset
802 * @arg RCM_APB1_PERIPH_SPI2 : Enable SPI2 reset
803 * @arg RCM_APB1_PERIPH_USART2 : Enable USART2 reset
804 * @arg RCM_APB1_PERIPH_USART3 : Enable USART3 reset
805 * @arg RCM_APB1_PERIPH_I2C1 : Enable I2C1 reset
806 * @arg RCM_APB1_PERIPH_I2C2 : Enable I2C2 reset
807 * @arg RCM_APB1_PERIPH_USB : Enable USB reset
808 * @arg RCM_APB1_PERIPH_CAN1 : Enable CAN1 reset
809 * @arg RCM_APB1_PERIPH_CAN2 : Enable CAN2 reset
810 * @arg RCM_APB1_PERIPH_BAKR : Enable BAKR reset
811 * @arg RCM_APB1_PERIPH_PMU : Enable PMU reset
812 *
813 * @retval None
814 */
RCM_EnableAPB1PeriphReset(uint32_t APB1Periph)815 void RCM_EnableAPB1PeriphReset(uint32_t APB1Periph)
816 {
817 RCM->APB1RST |= APB1Periph;
818 }
819
820 /*!
821 * @brief Disable Low Speed APB (APB1) peripheral reset
822 *
823 * @param APB1Periph : Disable the specified APB1 peripheral reset.
824 * This parameter can be any combination of the following values:
825 * @arg RCM_APB1_PERIPH_TMR2 : Disable TMR2 reset
826 * @arg RCM_APB1_PERIPH_TMR3 : Disable TMR3 reset
827 * @arg RCM_APB1_PERIPH_TMR4 : Disable TMR4 reset
828 * @arg RCM_APB1_PERIPH_WWDT : Disable WWDT reset
829 * @arg RCM_APB1_PERIPH_SPI2 : Disable SPI2 reset
830 * @arg RCM_APB1_PERIPH_USART2 : Disable USART2 reset
831 * @arg RCM_APB1_PERIPH_USART3 : Disable USART3 reset
832 * @arg RCM_APB1_PERIPH_I2C1 : Disable I2C1 reset
833 * @arg RCM_APB1_PERIPH_I2C2 : Disable I2C2 reset
834 * @arg RCM_APB1_PERIPH_USB : Disable USB reset
835 * @arg RCM_APB1_PERIPH_CAN1 : Disable CAN1 reset
836 * @arg RCM_APB1_PERIPH_CAN2 : Disable CAN2 reset
837 * @arg RCM_APB1_PERIPH_BAKR : Disable BAKR reset
838 * @arg RCM_APB1_PERIPH_PMU : Disable PMU reset
839 *
840 * @retval None
841 */
RCM_DisableAPB1PeriphReset(uint32_t APB1Periph)842 void RCM_DisableAPB1PeriphReset(uint32_t APB1Periph)
843 {
844 RCM->APB1RST &= (uint32_t)~APB1Periph;
845 }
846
847 /*!
848 * @brief Enable the Backup domain reset
849 *
850 * @param None
851 *
852 * @retval None
853 *
854 */
RCM_EnableBackupReset(void)855 void RCM_EnableBackupReset(void)
856 {
857 RCM->BDCTRL_B.BDRST = BIT_SET;
858 }
859
860 /*!
861 * @brief Disable the Backup domain reset
862 *
863 * @param None
864 *
865 * @retval None
866 */
RCM_DisableBackupReset(void)867 void RCM_DisableBackupReset(void)
868 {
869 RCM->BDCTRL_B.BDRST = BIT_RESET;
870 }
871
872 /*!
873 * @brief Enable RCM interrupts
874 *
875 * @param interrupt : Enable the specified RCM interrupt sources.
876 * This parameter can be any combination of the following values:
877 * @arg RCM_INT_LSIRDY : LSI ready interrupt
878 * @arg RCM_INT_LSERDY : LSE ready interrupt
879 * @arg RCM_INT_HSIRDY : HSI ready interrupt
880 * @arg RCM_INT_HSERDY : HSE ready interrupt
881 * @arg RCM_INT_PLLRDY : PLL ready interrupt
882 *
883 * @retval None
884 */
RCM_EnableInterrupt(uint32_t interrupt)885 void RCM_EnableInterrupt(uint32_t interrupt)
886 {
887 uint32_t temp;
888
889 temp = interrupt << 8;
890
891 RCM->INT |= temp;
892 }
893
894 /*!
895 * @brief Disable RCM interrupts
896 *
897 * @param interrupt : Disable the specified RCM interrupt sources.
898 * This parameter can be any combination of the following values:
899 * @arg RCM_INT_LSIRDY : LSI ready interrupt
900 * @arg RCM_INT_LSERDY : LSE ready interrupt
901 * @arg RCM_INT_HSIRDY : HSI ready interrupt
902 * @arg RCM_INT_HSERDY : HSE ready interrupt
903 * @arg RCM_INT_PLLRDY : PLL ready interrupt
904 *
905 * @retval None
906 */
RCM_DisableInterrupt(uint32_t interrupt)907 void RCM_DisableInterrupt(uint32_t interrupt)
908 {
909 uint32_t temp;
910
911 temp = interrupt << 8;
912
913 RCM->INT &= (uint32_t)~temp;
914 }
915
916 /*!
917 * @brief Read the specified RCM flag status
918 *
919 * @param flag : Return the specified flag status.
920 * This parameter can be one of the following values:
921 * @arg RCM_FLAG_HSIRDY : HSI ready flag
922 * @arg RCM_FLAG_HSERDY : HSE ready flag
923 * @arg RCM_FLAG_PLLRDY : PLL ready flag
924 * @arg RCM_FLAG_LSERDY : LSE ready flag
925 * @arg RCM_FLAG_LSIRDY : LSI ready flag
926 * @arg RCM_FLAG_PINRST : NRST PIN Reset Occur Flag
927 * @arg RCM_FLAG_PORRST : POR/PDR Reset Occur Flag
928 * @arg RCM_FLAG_SWRST : Software Reset Occur Flag
929 * @arg RCM_FLAG_IWDTRST : Independent Watchdog Reset Occur Flag
930 * @arg RCM_FLAG_WWDTRST : Window Watchdog Reset Occur Flag
931 * @arg RCM_FLAG_LPRRST : Low Power Reset Occur Flag
932 *
933 * @retval The new state of flag (SET or RESET)
934 */
RCM_ReadStatusFlag(RCM_FLAG_T flag)935 uint8_t RCM_ReadStatusFlag(RCM_FLAG_T flag)
936 {
937 uint32_t reg, bit;
938
939 bit = (uint32_t)(1 << (flag & 0xff));
940
941 reg = (flag >> 8) & 0xff;
942
943 switch (reg)
944 {
945 case 0:
946 reg = RCM->CTRL;
947 break;
948
949 case 1:
950 reg = RCM->BDCTRL;
951 break;
952
953 case 2:
954 reg = RCM->CSTS;
955 break;
956
957 default:
958 break;
959 }
960
961 if (reg & bit)
962 {
963 return SET;
964 }
965
966 return RESET;
967 }
968
969 /*!
970 * @brief Clear all the RCM reset flags
971 *
972 * @param None
973 *
974 * @retval None
975 *
976 * @note The reset flags are:
977 * RCM_FLAG_PINRST, RCM_FLAG_PWRST, RCM_FLAG_SWRST,
978 * RCM_FLAG_IWDTRST, RCM_FLAG_WWDTRST, RCM_FLAG_LPRRST
979 */
RCM_ClearStatusFlag(void)980 void RCM_ClearStatusFlag(void)
981 {
982 RCM->CSTS_B.RSTFLGCLR = BIT_SET;
983 }
984
985 /*!
986 * @brief Read the specified RCM interrupt Flag
987 *
988 * @param flag : Read the specified RCM interrupt flag.
989 * This parameter can be one of the following values:
990 * @arg RCM_INT_LSIRDY : LSI ready interrupt flag
991 * @arg RCM_INT_LSERDY : LSE ready interrupt flag
992 * @arg RCM_INT_HSIRDY : HSI ready interrupt flag
993 * @arg RCM_INT_HSERDY : HSE ready interrupt flag
994 * @arg RCM_INT_PLLRDY : PLL ready interrupt flag
995 * @arg RCM_INT_CSS : Clock Security System interrupt flag
996 *
997 * @retval The new state of intFlag (SET or RESET)
998 */
RCM_ReadIntFlag(RCM_INT_T flag)999 uint8_t RCM_ReadIntFlag(RCM_INT_T flag)
1000 {
1001 return (RCM->INT& flag) ? SET : RESET;
1002 }
1003
1004 /*!
1005 * @brief Clear the interrupt flag
1006 *
1007 * @param flag : Clear the specified interrupt flag.
1008 * @arg RCM_INT_LSIRDY : Clear LSI ready interrupt flag
1009 * @arg RCM_INT_LSERDY : Clear LSE ready interrupt flag
1010 * @arg RCM_INT_HSIRDY : Clear HSI ready interrupt flag
1011 * @arg RCM_INT_HSERDY : Clear HSE ready interrupt flag
1012 * @arg RCM_INT_PLLRDY : Clear PLL ready interrupt flag
1013 * @arg RCM_INT_CSS : Clear Clock Security System interrupt flag
1014 *
1015 * @retval None
1016 */
RCM_ClearIntFlag(uint32_t flag)1017 void RCM_ClearIntFlag(uint32_t flag)
1018 {
1019 uint32_t temp;
1020
1021 temp = flag << 16;
1022 RCM->INT |= temp;
1023 }
1024
1025 /**@} end of group RCM_Functions */
1026 /**@} end of group RCM_Driver */
1027 /**@} end of group APM32S10x_StdPeriphDriver */
1028