1 /*!
2  * @file        apm32f0xx_rcm.h
3  *
4  * @brief       This file provides all the RCM firmware functions
5  *
6  * @version     V1.0.3
7  *
8  * @date        2022-09-20
9  *
10  * @attention
11  *
12  *  Copyright (C) 2020-2022 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 useful 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 #include "apm32f0xx_rcm.h"
27 
28 /** @addtogroup APM32F0xx_StdPeriphDriver
29   @{
30 */
31 
32 /** @addtogroup RCM_Driver RCM Driver
33   @{
34 */
35 
36 /** @defgroup RCM_Macros Macros
37   @{
38 */
39 
40 /**@} end of group RCM_Macros*/
41 
42 /** @defgroup RCM_Enumerations Enumerations
43   @{
44 */
45 
46 /**@} end of group RCM_Enumerations*/
47 
48 /** @defgroup RCM_Structures Structures
49   @{
50 */
51 
52 /**@} end of group RCM_Structures*/
53 
54 /** @defgroup RCM_Variables Variables
55   @{
56 */
57 
58 /**@} end of group RCM_Variables*/
59 
60 /** @defgroup RCM_Functions Functions
61   @{
62 */
63 
64 /*!
65  * @brief   Resets the clock configuration
66  *
67  * @param   None
68  *
69  * @retval  None
70  */
RCM_Reset(void)71 void RCM_Reset(void)
72 {
73     /** Set HSIEN bit */
74     RCM->CTRL1_B.HSIEN = BIT_SET;
75     RCM->CFG1 &= (uint32_t)0x08FFB80C;
76     RCM->CTRL1 &= (uint32_t)0xFEF6FFFF;
77     RCM->CTRL1_B.HSEBCFG = BIT_RESET;
78     RCM->CFG1 &= (uint32_t)0xFFC0FFFF;
79     RCM->CFG2 &= (uint32_t)0xFFFFFFF0;
80     RCM->CFG3 &= (uint32_t)0xFFF0FEAC;
81     RCM->CTRL2_B.HSI14EN = BIT_RESET;
82 
83     /** Disable all interrupts and clear pending bits */
84     RCM->INT = 0x00FF0000;
85 }
86 
87 /*!
88  * @brief       Configures HSE
89  *
90  * @param       state:   state of the HSE
91  *                       This parameter can be one of the following values:
92  *                       @arg RCM_HSE_OPEN: turn ON the HSE oscillator
93  *                       @arg RCM_HSE_BYPASS: HSE oscillator bypassed with external clock
94  *
95  * @retval      None
96  *
97  * @note        HSE can not be stopped if it is used directly or through the PLL as system clock
98  */
RCM_ConfigHSE(RCM_HSE_T state)99 void RCM_ConfigHSE(RCM_HSE_T state)
100 {
101     RCM->CTRL1_B.HSEEN = BIT_RESET;
102 
103     RCM->CTRL1_B.HSEBCFG = BIT_RESET;
104 
105     if (state == RCM_HSE_OPEN)
106     {
107         RCM->CTRL1_B.HSEEN = BIT_SET;
108     }
109     else if (state == RCM_HSE_BYPASS)
110     {
111         RCM->CTRL1_B.HSEBCFG = BIT_SET;
112         RCM->CTRL1_B.HSEEN = BIT_SET;
113     }
114 }
115 
116 /*!
117  * @brief       Waits for HSE be ready
118  *
119  * @param       None
120  *
121  * @retval      SUCCESS     HSE oscillator is stable and ready to use
122  *              ERROR       HSE oscillator not yet ready
123  */
RCM_WaitHSEReady(void)124 uint8_t RCM_WaitHSEReady(void)
125 {
126     __IO uint32_t cnt;
127 
128     for (cnt = 0; cnt < HSE_STARTUP_TIMEOUT; cnt++)
129     {
130         if (RCM->CTRL1_B.HSERDYFLG == BIT_SET)
131         {
132             return SUCCESS;
133         }
134     }
135 
136     return ERROR;
137 }
138 
139 /*!
140  * @brief       Set HSI trimming value
141  *
142 * @param        HSITrim:    HSI trimming value
143  *                          This parameter must be a number between 0 and 0x1F.
144  *
145  * @retval      None
146  */
RCM_SetHSITrim(uint8_t HSITrim)147 void RCM_SetHSITrim(uint8_t HSITrim)
148 {
149     RCM->CTRL1_B.HSITRM = HSITrim;
150 }
151 
152 /*!
153  * @brief       Enable HSI
154  *
155  * @param       None
156  *
157  * @retval      None
158  *
159  * @note        HSI can not be stopped if it is used directly or through the PLL as system clock
160  */
RCM_EnableHSI(void)161 void RCM_EnableHSI(void)
162 {
163     RCM->CTRL1_B.HSIEN = BIT_SET;
164 }
165 
166 /*!
167  * @brief       Disable HSI
168  *
169  * @param       None
170  *
171  * @retval      None
172  *
173  * @note        HSI can not be stopped if it is used directly or through the PLL as system clock
174  */
RCM_DisableHSI(void)175 void RCM_DisableHSI(void)
176 {
177     RCM->CTRL1_B.HSIEN = BIT_RESET;
178 }
179 
180 /*!
181  * @brief       Set HSI14 trimming value
182  *
183  * @param        HSI14TRM:  HSI trimming value
184  *                            This parameter must be a number between 0 and 0x1F.
185  *
186  * @retval      None
187  */
RCM_SetHSI14Trim(uint8_t HSI14Trim)188 void RCM_SetHSI14Trim(uint8_t HSI14Trim)
189 {
190     RCM->CTRL2_B.HSI14TRM = HSI14Trim;
191 }
192 
193 /*!
194  * @brief       Enable HSI14
195  *
196  * @param       None
197  *
198  * @retval      None
199  *
200  * @note
201  */
RCM_EnableHSI14(void)202 void RCM_EnableHSI14(void)
203 {
204     RCM->CTRL2_B.HSI14EN = BIT_SET;
205 }
206 
207 /*!
208  * @brief       Disable HSI14
209  *
210  * @param       None
211  *
212  * @retval      None
213  *
214  * @note
215  */
RCM_DisableHSI14(void)216 void RCM_DisableHSI14(void)
217 {
218     RCM->CTRL2_B.HSI14EN = BIT_RESET;
219 }
220 
221 /*!
222  * @brief       Enable HSI14 ADC
223  *
224  * @param       None
225  *
226  * @retval      None
227  *
228  * @note
229  */
RCM_EnableHSI14ADC(void)230 void RCM_EnableHSI14ADC(void)
231 {
232     RCM->CTRL2_B.HSI14TO = BIT_SET;
233 }
234 
235 /*!
236  * @brief       Disable HSI14 ADC
237  *
238  * @param       None
239  *
240  * @retval      None
241  *
242  * @note
243  */
RCM_DisableHSI14ADC(void)244 void RCM_DisableHSI14ADC(void)
245 {
246     RCM->CTRL2_B.HSI14TO = BIT_RESET;
247 }
248 
249 /*!
250  * @brief       Configures LSE
251  *
252  * @param       state:   state of the LSE
253  *                       This parameter can be one of the following values:
254  *                       @arg RCM_LSE_OPEN: turn ON the HSE oscillator
255  *                       @arg RCM_LSE_BYPASS: HSE oscillator bypassed with external clock
256  *
257  * @retval      None
258  *
259  * @note        LSE can not be stopped if it is used directly or through the PLL as system clock
260  */
RCM_ConfigLSE(RCM_LSE_T state)261 void RCM_ConfigLSE(RCM_LSE_T state)
262 {
263     RCM->BDCTRL_B.LSEEN = BIT_RESET;
264 
265     RCM->BDCTRL_B.LSEBCFG = BIT_RESET;
266 
267     if (state == RCM_LSE_OPEN)
268     {
269         RCM->BDCTRL_B.LSEEN = BIT_SET;
270     }
271     else if (state == RCM_LSE_BYPASS)
272     {
273         RCM->BDCTRL_B.LSEBCFG = BIT_SET;
274         RCM->BDCTRL_B.LSEEN = BIT_SET;
275     }
276 }
277 
278 /*!
279  * @brief       Configures LSE drive capability
280  *
281  * @param       state:   State of the LSE Drive
282  *                       This parameter can be one of the following values:
283  *                       @arg RCM_LSE_DRIVE_Low: LSE oscillator low drive capability.
284  *                       @arg RCM_LSE_DRIVE_MediumLow: LSE oscillator medium low drive capability.
285  *                       @arg RCM_LSE_DRIVE_MediumHigh: LSE oscillator medium high drive capability.
286  *                       @arg RCM_LSE_DRIVE_High: LSE oscillator high drive capability.
287  *
288  * @retval      None
289  *
290  * @note        LSE can not be stopped if it is used directly or through the PLL as system clock
291  */
RCM_ConfigDriveLSE(RCM_LSE_DRIVE_T state)292 void RCM_ConfigDriveLSE(RCM_LSE_DRIVE_T state)
293 {
294     RCM->BDCTRL_B.LSEDRVCFG = state;
295 }
296 
297 /*!
298  * @brief       Enable LSI
299  *
300  * @param       None
301  *
302  * @retval      None
303  *
304  * @note        LSI can not be stopped if the IWDT is running
305  */
RCM_EnableLSI(void)306 void RCM_EnableLSI(void)
307 {
308     RCM->CSTS_B.LSIEN = BIT_SET;
309 }
310 
311 /*!
312  * @brief       Disable LSI
313  *
314  * @param       None
315  *
316  * @retval      None
317  *
318  * @note        LSI can not be stopped if the IWDT is running
319  */
RCM_DisableLSI(void)320 void RCM_DisableLSI(void)
321 {
322     RCM->CSTS_B.LSIEN = BIT_RESET;
323 }
324 
325 /*!
326  * @brief       Configures the PLL clock source and multiplication factor
327  *
328  * @param       pllSelect:   PLL entry clock source select
329  *                           This parameter can be one of the following values:
330  *                           @arg RCM_PLL_SEL_HSI_DIV2: HSI clock divided by 2 selected as PLL clock source
331  *                           @arg RCM_PLL_SEL_HSE: HSE/CLKDIV1 selected as PLL clock entry
332  *                           @arg RCM_PLL_SEL_HSI48: HSI48 oscillator clock selected as PLL clock source, It's only for 072 and 091 devices
333  *                           @arg RCM_PLL_SEL_HSI: HSI clock selected as PLL clock entry, It's only for 072 and 091 devices
334  *
335  * @param       pllMf:       PLL multiplication factor
336  *                           This parameter can be RCM_PLLMF_x where x:[2,16]
337  *
338  * @retval      None
339  *
340  * @note
341  */
RCM_ConfigPLL(RCM_PLL_SEL_T pllSelect,RCM_PLLMF_T pllMf)342 void RCM_ConfigPLL(RCM_PLL_SEL_T pllSelect, RCM_PLLMF_T pllMf)
343 {
344     RCM->CFG1_B.PLLMULCFG = pllMf;
345     RCM->CFG1_B.PLLSRCSEL = pllSelect;
346 }
347 
348 /*!
349  * @brief       Enables PLL
350  *
351  * @param       None
352  *
353  * @retval      None
354  *
355  * @note        The PLL can not be disabled if it is used as system clock
356  */
RCM_EnablePLL(void)357 void RCM_EnablePLL(void)
358 {
359     RCM->CTRL1_B.PLLEN = BIT_SET;
360 }
361 
362 /*!
363  * @brief       Disable PLL
364  *
365  * @param       None
366  *
367  * @retval      None
368  *
369  * @note        The PLL can not be disabled if it is used as system clock
370  */
RCM_DisablePLL(void)371 void RCM_DisablePLL(void)
372 {
373     RCM->CTRL1_B.PLLEN = BIT_RESET;
374 }
375 
376 /*!
377  * @brief       Enables HSI48
378  *
379  * @param       None
380  *
381  * @retval      None
382  *
383  * @note        It's only for APM32F072 and APM32F091 devices
384  */
RCM_EnableHSI48(void)385 void RCM_EnableHSI48(void)
386 {
387     RCM->CTRL2_B.HSI48EN = BIT_SET;
388 }
389 
390 /*!
391  * @brief       Enables HSI48
392  *
393  * @param       None
394  *
395  * @retval      None
396  *
397  * @note        It's only for APM32F072 and APM32F091 devices
398  */
RCM_DisableHSI48(void)399 void RCM_DisableHSI48(void)
400 {
401     RCM->CTRL2_B.HSI48EN = BIT_RESET;
402 }
403 
404 /*!
405  * @brief       Read HSI48 Calibration Value
406  *
407  * @param       None
408  *
409  * @retval      Return of HSI48 Value
410  */
RCM_ReadHSI48CalibrationValue(void)411 uint32_t RCM_ReadHSI48CalibrationValue(void)
412 {
413     uint32_t calValue;
414 
415     calValue = RCM->CTRL2_B.HSI48CAL;
416 
417     return calValue;
418 }
419 /*!
420  * @brief       Configures the CLK division factor
421  *
422  * @param       state:   specifies the PLLDIVCFG clock division factor.
423  *                       This parameter can be RCM_CLK_Divx where x:[1,16]
424  *
425  * @retval      None
426  *
427  * @note        This function must be used only when the PLL is disabled
428  */
RCM_ConfigCLKDIV(RCM_CLK_DIV_T state)429 void RCM_ConfigCLKDIV(RCM_CLK_DIV_T state)
430 {
431     RCM->CFG2_B.PLLDIVCFG = state;
432 }
433 
434 /*!
435  * @brief        Enable Clock Security System
436  *
437  * @param        None
438  *
439  * @retval       None
440  */
RCM_EnableCCS(void)441 void RCM_EnableCCS(void)
442 {
443     RCM->CTRL1_B.CSSEN = BIT_SET;
444 }
445 
446 /*!
447  * @brief        Disable Clock Security System
448  *
449  * @param        None
450  *
451  * @retval       None
452  */
RCM_DisableCCS(void)453 void RCM_DisableCCS(void)
454 {
455     RCM->CTRL1_B.CSSEN = BIT_RESET;
456 }
457 
458 #if defined (APM32F030) || defined (APM32F051)
459 /*!
460  * @brief       Selects clock ouput source
461  *
462  * @param       cocClock:  specifies the clock source to output
463  *                         This parameter can be one of the following values:
464  *                         @arg RCM_COC_NO_CLOCK:     No clock selected.
465  *                         @arg RCM_COC_HSI14:        HSI14 oscillator clock selected.
466  *                         @arg RCM_COC_LSI:          LSI oscillator clock selected.
467  *                         @arg RCM_COC_LSE:          LSE oscillator clock selected.
468  *                         @arg RCM_COC_SYSCLK:       System clock selected.
469  *                         @arg RCM_COC_HSI:          HSI oscillator clock selected.
470  *                         @arg RCM_COC_HSE:          HSE oscillator clock selected.
471  *                         @arg RCM_COC_PLLCLK_DIV_2: PLL clock divided by 2 selected.
472  *
473  * @retval      None
474  */
RCM_ConfigCOC(RCM_COCCLK_T cocClock)475 void RCM_ConfigCOC(RCM_COCCLK_T cocClock)
476 {
477     RCM->CFG1_B.MCOSEL = cocClock;
478 }
479 #else
480 
481 /*!
482  * @brief       Selects clock ouput source
483  *
484  * @param       cocClock:  specifies the clock source to output
485  *                         This parameter can be one of the following values:
486  *                         @arg RCM_COC_NO_CLOCK:     No clock selected.
487  *                         @arg RCM_COC_HSI14:        HSI14 oscillator clock selected.
488  *                         @arg RCM_COC_LSI:          LSI oscillator clock selected.
489  *                         @arg RCM_COC_LSE:          LSE oscillator clock selected.
490  *                         @arg RCM_COC_SYSCLK:       System clock selected.
491  *                         @arg RCM_COC_HSI:          HSI oscillator clock selected.
492  *                         @arg RCM_COC_HSE:          HSE oscillator clock selected.
493  *                         @arg RCM_COC_PLLCLK_DIV_2: PLL clock divided by 2 selected.
494  *                         @arg RCM_COC_PLLCLK:       PLL clock divided selected.
495  *                         @arg RCM_COC_HSI48:        HSI48 oscillator clock selected.
496  *
497  * @param       divided:   specifies the prescaler on COC pin.
498  *                         This parameter can only be the following value:
499  *                         @arg RCM_COC_DIV_1:        MCOSEL clock is divided by 1.
500  *                         @arg RCM_COC_DIV_2:        MCOSEL clock is divided by 2.
501  *                         @arg RCM_COC_DIV_4:        MCOSEL clock is divided by 4.
502  *                         @arg RCM_COC_DIV_8:        MCOSEL clock is divided by 8.
503  *                         @arg RCM_COC_DIV_16:       MCOSEL clock is divided by 16.
504  *                         @arg RCM_COC_DIV_32:       MCOSEL clock is divided by 32.
505  *                         @arg RCM_COC_DIV_64:       MCOSEL clock is divided by 64.
506  *                         @arg RCM_COC_DIV_128:      MCOSEL clock is divided by 128.
507  *
508  * @retval      None
509  */
RCM_ConfigCOC(RCM_COCCLK_T cocClock,RCM_COCPRE_T divided)510 void RCM_ConfigCOC(RCM_COCCLK_T cocClock, RCM_COCPRE_T divided)
511 {
512     RCM->CFG1_B.MCOPSC = divided;
513 
514     if (cocClock != RCM_COC_PLLCLK)
515     {
516         RCM->CFG1_B.MCOPLLPSC = BIT_RESET;
517         RCM->CFG1_B.MCOSEL = cocClock;
518     }
519     else
520     {
521         RCM->CFG1_B.MCOPLLPSC = BIT_SET;
522         RCM->CFG1_B.MCOSEL = 0x07;
523     }
524 }
525 #endif /* APM32F072 */
526 
527 /*!
528  * @brief       Configures the system clock
529  *
530  * @param       sysClkSelect:   specifies the clock source used as system clock
531  *                              This parameter can be one of the following values:
532  *                              @arg RCM_SYSCLK_SEL_HSI:    HSI selected as system clock source
533  *                              @arg RCM_SYSCLK_SEL_HSE:    HSE selected as system clock source
534  *                              @arg RCM_SYSCLK_SEL_PLL:    PLL selected as system clock source
535  *                              @arg RCM_SYSCLK_SEL_HSI48:  HSI48 selected as system clock source,It's only for 072 devices
536  *
537  * @retval      None
538  */
RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_T sysClkSelect)539 void RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_T sysClkSelect)
540 {
541     RCM->CFG1_B.SCLKSEL = sysClkSelect;
542 }
543 
544 /*!
545  * @brief       returns the clock source used as system clock
546  *
547  * @param       None
548  *
549  * @retval      The clock source used as system clock
550  */
RCM_ReadSYSCLKSource(void)551 RCM_SYSCLK_SEL_T RCM_ReadSYSCLKSource(void)
552 {
553     RCM_SYSCLK_SEL_T sysClock;
554 
555     sysClock = (RCM_SYSCLK_SEL_T)RCM->CFG1_B.SCLKSWSTS;
556 
557     return sysClock;
558 }
559 
560 /*!
561  * @brief       Configures the AHB clock
562  *
563  * @param       AHBDiv:   AHB divider number. This clock is derived from the system clock (SYSCLK)
564  *                        This parameter can be one of the following values:
565  *                        @arg RCM_SYSCLK_DIV_1:   AHB clock = SYSCLK
566  *                        @arg RCM_SYSCLK_DIV_2:   AHB clock = SYSCLK/2
567  *                        @arg RCM_SYSCLK_DIV_4:   AHB clock = SYSCLK/4
568  *                        @arg RCM_SYSCLK_DIV_8:   AHB clock = SYSCLK/8
569  *                        @arg RCM_SYSCLK_DIV_16:  AHB clock = SYSCLK/16
570  *                        @arg RCM_SYSCLK_DIV_64:  AHB clock = SYSCLK/64
571  *                        @arg RCM_SYSCLK_DIV_128: AHB clock = SYSCLK/128
572  *                        @arg RCM_SYSCLK_DIV_256: AHB clock = SYSCLK/256
573  *                        @arg RCM_SYSCLK_DIV_512: AHB clock = SYSCLK/512
574  *
575  * @retval      None
576  */
RCM_ConfigAHB(RCM_AHBDIV_T AHBDiv)577 void RCM_ConfigAHB(RCM_AHBDIV_T AHBDiv)
578 {
579     RCM->CFG1_B.AHBPSC = AHBDiv;
580 }
581 
582 /*!
583  * @brief       Configures the APB clock
584  *
585  * @param       APBDiv:   defines the APB clock divider. This clock is derived from the AHB clock (HCLK)
586  *                        This parameter can be one of the following values:
587  *                        @arg RCM_HCLK_DIV_1:  APB clock = HCLK
588  *                        @arg RCM_HCLK_DIV_2:  APB clock = HCLK/2
589  *                        @arg RCM_HCLK_DIV_4:  APB clock = HCLK/4
590  *                        @arg RCM_HCLK_DIV_8:  APB clock = HCLK/8
591  *                        @arg RCM_HCLK_DIV_16: APB clock = HCLK/16
592  *
593  * @retval      None
594  */
RCM_ConfigAPB(RCM_APBDIV_T APBDiv)595 void RCM_ConfigAPB(RCM_APBDIV_T APBDiv)
596 {
597     RCM->CFG1_B.APB1PSC = APBDiv;
598 }
599 
600 /*!
601  * @brief       Configures the CEC clock
602  *
603  * @param       CECClk:   defines the CEC clock divider. This clock is derived
604  *                        from the HSI/244 (32768Hz) clock or LSI clock
605  *                        This parameter can be one of the following values:
606  *                        @arg RCM_CECCLK_HSI_DIV_224: CEC clock = HSI/244 (32768Hz)
607  *                        @arg RCM_CECCLK_LSI_DIV: CEC clock = LSI
608  *
609  * @retval      None
610  */
RCM_ConfigCECCLK(RCM_CECCLK_T CECClk)611 void RCM_ConfigCECCLK(RCM_CECCLK_T CECClk)
612 {
613     RCM->CFG3_B.CECSEL = CECClk;
614 }
615 
616 /*!
617  * @brief       Configures the I2C clock
618  *
619  * @param       I2CClk:   defines the I2C1 clock source. This clock is derived
620  *                        from the HSI or System clock.
621  *                        This parameter can be one of the following values:
622  *                        @arg RCM_I2C1CLK_HSI:    I2C1 clock = HSI
623  *                        @arg RCM_I2C1CLK_SYSCLK: I2C1 clock = System Clock
624  *
625  * @retval      None
626  */
RCM_ConfigI2CCLK(RCM_I2CCLK_T I2CClk)627 void RCM_ConfigI2CCLK(RCM_I2CCLK_T I2CClk)
628 {
629     RCM->CFG3_B.I2C1SEL = I2CClk;
630 }
631 
632 /*!
633  * @brief       Configures the USART clock (USARTCLK)
634  *
635  * @param       USARTClk: defines the USART clock source. This clock is derived
636  *                        from the HSI or System clock.
637  *                        This parameter can be one of the following values:
638  *                        @arg RCM_USART1CLK_PCLK:   USART1 clock = APB Clock (PCLK)
639  *                        @arg RCM_USART1CLK_SYSCLK: USART1 clock = System Clock
640  *                        @arg RCM_USART1CLK_LSE:    USART1 clock = LSE Clock
641  *                        @arg RCM_USART1CLK_HSI:    USART1 clock = HSI Clock
642  *                        Under it's only for APM32F072 and APM32F091 devices
643  *                        @arg RCM_USART2CLK_PCLK:   USART2 clock = APB Clock (PCLK)
644  *                        @arg RCM_USART2CLK_SYSCLK: USART2 clock = System Clock
645  *                        @arg RCM_USART2CLK_LSE:    USART2 clock = LSE Clock
646  *                        @arg RCM_USART2CLK_HSI:    USART2 clock = HSI Clock
647  *                        Under it's only for APM32F091 devices
648  *                        @arg RCM_USART3CLK_PCLK:   USART3 clock = APB Clock (PCLK)
649  *                        @arg RCM_USART3CLK_SYSCLK: USART3 clock = System Clock
650  *                        @arg RCM_USART3CLK_LSE:    USART3 clock = LSE Clock
651  *                        @arg RCM_USART3CLK_HSI:    USART3 clock = HSI Clock
652  *
653  * @retval      None
654  */
RCM_ConfigUSARTCLK(RCM_USARTCLK_T USARTClk)655 void RCM_ConfigUSARTCLK(RCM_USARTCLK_T USARTClk)
656 {
657     if (USARTClk >> 16 == 1)
658     {
659         RCM->CFG3_B.USART1SEL = (uint32_t)(USARTClk & 0x00000003);
660     }
661     else if (USARTClk >> 17 == 1)
662     {
663         RCM->CFG3_B.USART2SEL = (uint32_t)(USARTClk & 0x00000003);
664     }
665     else
666     {
667         RCM->CFG3_B.USART3SEL = (uint32_t)(USARTClk & 0x00000003);
668     }
669 }
670 
671 /*!
672  * @brief       Configures the USB clock (USBCLK)
673  *
674  * @param       USBClk: defines the USB clock source. This clock is derived
675  *                      from the HSI48 or System clock.
676  *                      This parameter can be one of the following values:
677  *                      @arg RCM_USBCLK_HSI48:  USB clock = HSI48
678  *                      @arg RCM_USBCLK_PLLCLK: USB clock = PLL Clock
679  *
680  * @retval      None
681  *
682  * @note        It's only for APM32F072 devices
683  */
RCM_ConfigUSBCLK(RCM_USBCLK_T USBClk)684 void RCM_ConfigUSBCLK(RCM_USBCLK_T USBClk)
685 {
686     RCM->CFG3_B.USBDSEL = USBClk;
687 }
688 
689 /*!
690  * @brief       Read frequency of SYSCLK
691  *
692  * @param       None
693  *
694  * @retval      Return frequency of SYSCLK
695  */
RCM_ReadSYSCLKFreq(void)696 uint32_t RCM_ReadSYSCLKFreq(void)
697 {
698     uint32_t sysClock, pllMull, plldiv, pllSource;
699 
700     sysClock = RCM->CFG1_B.SCLKSEL;
701 
702     switch (sysClock)
703     {
704         case RCM_SYSCLK_SEL_HSI:
705             sysClock = HSI_VALUE;
706             break;
707 
708         case RCM_SYSCLK_SEL_HSE:
709             sysClock = HSE_VALUE;
710             break;
711 
712         case RCM_SYSCLK_SEL_PLL:
713             pllMull = RCM->CFG1_B.PLLMULCFG + 2;
714             pllSource = RCM->CFG1_B.PLLSRCSEL;
715             plldiv = RCM->CFG2_B.PLLDIVCFG + 1;
716 
717             if (pllSource == 0x00)
718             {
719                 sysClock = ((HSI_VALUE >> 1) / plldiv) * pllMull;
720             }
721             else if (pllSource == 0x01)
722             {
723                 sysClock = (HSI_VALUE / plldiv) * pllMull;
724             }
725             else if (pllSource == 0x02)
726             {
727                 sysClock = (HSE_VALUE / plldiv) * pllMull;
728             }
729             else
730             {
731                 sysClock = (HSI48_VALUE / plldiv) * pllMull;
732             }
733             break;
734 
735         case RCM_SYSCLK_SEL_HSI48:
736             sysClock  = HSI48_VALUE;
737             break;
738 
739         default:
740             sysClock  = HSI_VALUE;
741             break;
742     }
743 
744     return sysClock;
745 }
746 
747 /*!
748  * @brief       Read frequency of HCLK(AHB)
749  *
750  * @param       None
751  *
752  * @retval      Return frequency of HCLK
753  */
RCM_ReadHCLKFreq(void)754 uint32_t RCM_ReadHCLKFreq(void)
755 {
756     uint32_t divider;
757     uint32_t sysClk, hclk;
758     uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
759 
760     sysClk = RCM_ReadSYSCLKFreq();
761     divider = AHBPrescTable[RCM->CFG1_B.AHBPSC];
762     hclk = sysClk >> divider;
763 
764     return hclk;
765 }
766 
767 /*!
768  * @brief       Read frequency of PCLK
769  *
770  * @param       None
771  *
772  * @retval      PCLK1   return frequency of PCLK
773  */
RCM_ReadPCLKFreq(void)774 uint32_t RCM_ReadPCLKFreq(void)
775 {
776     uint32_t hclk, pclk, divider;
777     uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
778 
779     hclk = RCM_ReadSYSCLKFreq();
780 
781     divider = APBPrescTable[RCM->CFG1_B.APB1PSC];
782     pclk = hclk >> divider;
783 
784     return pclk;
785 
786 }
787 
788 /*!
789  * @brief       Read frequency of ADC CLK
790  *
791  * @param       None
792  *
793  * @retval      Return frequency of ADC CLK
794  */
RCM_ReadADCCLKFreq(void)795 uint32_t RCM_ReadADCCLKFreq(void)
796 {
797     uint32_t adcClk, pclk;
798 
799     pclk = RCM_ReadPCLKFreq();
800 
801     if (RCM->CFG3_B.ADCSEL)
802     {
803         if (RCM->CFG1_B.ADCPSC)
804         {
805             adcClk = pclk >> 2;
806         }
807         else
808         {
809             adcClk = pclk >> 1;
810         }
811     }
812     else
813     {
814         adcClk = HSI14_VALUE;
815     }
816 
817     return adcClk;
818 }
819 
820 /*!
821  * @brief       Read frequency of CEC CLK
822  *
823  * @param       None
824  *
825  * @retval      Return frequency of CEC CLK
826  */
RCM_ReadCECCLKFreq(void)827 uint32_t RCM_ReadCECCLKFreq(void)
828 {
829     uint32_t cecClk;
830 
831     if (RCM->CFG3_B.CECSEL)
832     {
833         cecClk = LSE_VALUE;
834     }
835     else
836     {
837         cecClk = LSI_VALUE / 244;
838     }
839 
840     return cecClk;
841 }
842 
843 /*!
844  * @brief       Read frequency of I2C1 CLK
845  *
846  * @param       None
847  *
848  * @retval      Return frequency of I2C1 CLK
849  */
RCM_ReadI2C1CLKFreq(void)850 uint32_t RCM_ReadI2C1CLKFreq(void)
851 {
852     uint32_t i2c1Clk, sysClk;
853 
854     sysClk = RCM_ReadSYSCLKFreq();
855 
856     if (RCM->CFG3_B.I2C1SEL)
857     {
858         i2c1Clk = sysClk;
859     }
860     else
861     {
862         i2c1Clk = HSI_VALUE;
863     }
864 
865     return i2c1Clk;
866 }
867 
868 /*!
869  * @brief       Read frequency of USART1 CLK
870  *
871  * @param       None
872  *
873  * @retval      Return frequency of USART1 CLK
874  */
RCM_ReadUSART1CLKFreq(void)875 uint32_t RCM_ReadUSART1CLKFreq(void)
876 {
877     uint32_t usart1Clk;
878 
879     if (RCM->CFG3_B.USART1SEL == 0x00)
880     {
881         usart1Clk = RCM_ReadPCLKFreq();
882     }
883     else if (RCM->CFG3_B.USART1SEL == 0x01)
884     {
885         usart1Clk = RCM_ReadSYSCLKFreq();
886     }
887     else if (RCM->CFG3_B.USART1SEL == 0x02)
888     {
889         usart1Clk = LSE_VALUE;
890     }
891     else if (RCM->CFG3_B.USART1SEL == 0x03)
892     {
893         usart1Clk = HSI_VALUE;
894     }
895 
896     return usart1Clk;
897 }
898 
899 /*!
900  * @brief       Read frequency of USB CLK
901  *
902  * @param       None
903  *
904  * @retval      Return frequency of USB CLK
905  */
RCM_ReadUSBCLKFreq(void)906 uint32_t RCM_ReadUSBCLKFreq(void)
907 {
908     uint32_t usbClk, pllClk, pllMull, clkDiv;
909 
910     if (RCM->CFG1_B.SCLKSWSTS & 0x02)
911     {
912         pllMull = RCM->CFG1_B.PLLMULCFG;
913         pllMull = pllMull + 2;
914     }
915 
916     if (RCM->CFG3_B.USBDSEL)
917     {
918         if (RCM->CFG1_B.PLLSRCSEL == 0x00)
919         {
920             pllClk = (HSI_VALUE >> 1) * pllMull;
921         }
922         else
923         {
924             clkDiv = (RCM->CFG2_B.PLLDIVCFG) + 1;
925             pllClk = (HSE_VALUE / clkDiv) * pllMull;
926         }
927         usbClk = pllClk;
928     }
929     else
930     {
931         usbClk = HSI48_VALUE;
932     }
933 
934     return usbClk;
935 }
936 
937 /*!
938  * @brief       Read frequency of USART2 CLK
939  *
940  * @param       None
941  *
942  * @retval      Return frequency of USART2 CLK
943  */
RCM_ReadUSART2CLKFreq(void)944 uint32_t RCM_ReadUSART2CLKFreq(void)
945 {
946     uint32_t usart1Clk;
947 
948     if (RCM->CFG3_B.USART2SEL == 0x00)
949     {
950         usart1Clk = RCM_ReadPCLKFreq();
951     }
952     else if (RCM->CFG3_B.USART2SEL == 0x01)
953     {
954         usart1Clk = RCM_ReadSYSCLKFreq();
955     }
956     else if (RCM->CFG3_B.USART2SEL == 0x02)
957     {
958         usart1Clk = LSE_VALUE;
959     }
960     else if (RCM->CFG3_B.USART2SEL == 0x03)
961     {
962         usart1Clk = HSI_VALUE;
963     }
964 
965     return usart1Clk;
966 }
967 
968 /*!
969  * @brief       Configures the RTC clock (RTCCLK)
970  *
971  * @param       RTCClk:   specifies the RTC clock source
972  *                        This parameter can be one of the following values:
973  *                        @arg RCM_RTCCLK_LSE:       LSE selected as RTC clock
974  *                        @arg RCM_RTCCLK_LSI:       LSI selected as RTC clock
975  *                        @arg RCM_RTCCLK_HSE_DIV_32: HSE divided by 32 selected as RTC clock
976  *
977  * @retval      None
978  *
979  * @note        Once the RTC clock is selected it can't be changed unless the Backup domain is reset
980  */
RCM_ConfigRTCCLK(RCM_RTCCLK_T RTCClk)981 void RCM_ConfigRTCCLK(RCM_RTCCLK_T RTCClk)
982 {
983     RCM->BDCTRL_B.RTCSRCSEL = RTCClk;
984 }
985 
986 /*!
987  * @brief       Enables the RTC clock
988  *
989  * @param       None
990  *
991  * @retval      None
992  */
RCM_EnableRTCCLK(void)993 void RCM_EnableRTCCLK(void)
994 {
995     RCM->BDCTRL_B.RTCCLKEN = BIT_SET;
996 }
997 
998 /*!
999  * @brief       Disables the RTC clock
1000  *
1001  * @param       None
1002  *
1003  * @retval      None
1004  */
RCM_DisableRTCCLK(void)1005 void RCM_DisableRTCCLK(void)
1006 {
1007     RCM->BDCTRL_B.RTCCLKEN = BIT_RESET;
1008 }
1009 
1010 /*!
1011  * @brief       Enable the Backup domain reset
1012  *
1013  * @param       None
1014  *
1015  * @retval      None
1016  */
RCM_EnableBackupReset(void)1017 void RCM_EnableBackupReset(void)
1018 {
1019     RCM->BDCTRL_B.BDRST = BIT_SET;
1020 }
1021 
1022 /*!
1023  * @brief       Disable the Backup domain reset
1024  *
1025  * @param       None
1026  *
1027  * @retval      None
1028  */
RCM_DisableBackupReset(void)1029 void RCM_DisableBackupReset(void)
1030 {
1031     RCM->BDCTRL_B.BDRST = BIT_RESET;
1032 }
1033 
1034 /*!
1035  * @brief       Enables AHB peripheral clock
1036  *
1037  * @param       AHBPeriph:   specifies the AHB peripheral to gates its clock
1038  *                           This parameter can be any combination of the following values:
1039  *                           @arg RCM_AHB_PERIPH_DMA1:  DMA1 clock
1040  *                           @arg RCM_AHB_PERIPH_DMA2:  DMA2 clock
1041  *                           @arg RCM_AHB_PERIPH_SRAM:  SRAM clock
1042  *                           @arg RCM_AHB_PERIPH_FPU:   FPU clock
1043  *                           @arg RCM_AHB_PERIPH_CRC:   CRC clock
1044  *                           @arg RCM_AHB_PERIPH_GPIOA: GPIOA clock
1045  *                           @arg RCM_AHB_PERIPH_GPIOB: GPIOB clock
1046  *                           @arg RCM_AHB_PERIPH_GPIOC: GPIOC clock
1047  *                           @arg RCM_AHB_PERIPH_GPIOD: GPIOD clock
1048  *                           @arg RCM_AHB_PERIPH_GPIOE: GPIOE clock(Only for APM32F072 and APM32F091)
1049  *                           @arg RCM_AHB_PERIPH_GPIOF: GPIOF clock
1050  *                           @arg RCM_AHB_PERIPH_TSC:   TSC clock
1051  *
1052  * @retval      None
1053  */
RCM_EnableAHBPeriphClock(uint32_t AHBPeriph)1054 void RCM_EnableAHBPeriphClock(uint32_t AHBPeriph)
1055 {
1056     RCM->AHBCLKEN |= AHBPeriph;
1057 }
1058 
1059 /*!
1060  * @brief       Disable AHB peripheral clock
1061  *
1062  * @param       AHBPeriph:   specifies the AHB peripheral to gates its clock
1063  *                           This parameter can be any combination of the following values:
1064  *                           @arg RCM_AHB_PERIPH_DMA1:  DMA1 clock
1065  *                           @arg RCM_AHB_PERIPH_DMA2:  DMA2 clock
1066  *                           @arg RCM_AHB_PERIPH_SRAM:  SRAM clock
1067  *                           @arg RCM_AHB_PERIPH_FPU:   FPU clock
1068  *                           @arg RCM_AHB_PERIPH_CRC:   CRC clock
1069  *                           @arg RCM_AHB_PERIPH_GPIOA: GPIOA clock
1070  *                           @arg RCM_AHB_PERIPH_GPIOB: GPIOB clock
1071  *                           @arg RCM_AHB_PERIPH_GPIOC: GPIOC clock
1072  *                           @arg RCM_AHB_PERIPH_GPIOD: GPIOD clock
1073  *                           @arg RCM_AHB_PERIPH_GPIOE: GPIOE clock(Only for APM32F072 and APM32F091)
1074  *                           @arg RCM_AHB_PERIPH_GPIOF: GPIOF clock
1075  *                           @arg RCM_AHB_PERIPH_TSC:   TSC clock
1076  *
1077  * @retval      None
1078  */
RCM_DisableAHBPeriphClock(uint32_t AHBPeriph)1079 void RCM_DisableAHBPeriphClock(uint32_t AHBPeriph)
1080 {
1081     RCM->AHBCLKEN &= (uint32_t)~AHBPeriph;
1082 }
1083 
1084 /*!
1085  * @brief       Enable the High Speed APB (APB2) peripheral clock
1086  *
1087  * @param       APB2Periph:  specifies the APB2 peripheral to gates its clock
1088  *                           This parameter can be any combination of the following values:
1089  *                           @arg RCM_APB2_PERIPH_SYSCFG: SYSCFG clock
1090  *                           @arg RCM_APB2_PERIPH_USART6: USART6 clock(Only for APM32F091)
1091  *                           @arg RCM_APB2_PERIPH_USART7: USART7 clock(Only for APM32F091)
1092  *                           @arg RCM_APB2_PERIPH_USART8: USART8 clock(Only for APM32F091)
1093  *                           @arg RCM_APB2_PERIPH_ADC1:   ADC1 clock
1094  *                           @arg RCM_APB2_PERIPH_TMR1:   TMR1 clock
1095  *                           @arg RCM_APB2_PERIPH_SPI1:   SPI1 clock
1096  *                           @arg RCM_APB2_PERIPH_USART1: USART1 clock
1097  *                           @arg RCM_APB2_PERIPH_TMR15:  TMR15 clock
1098  *                           @arg RCM_APB2_PERIPH_TMR16:  TMR16 clock
1099  *                           @arg RCM_APB2_PERIPH_TMR17:  TMR17 clock
1100  *                           @arg RCM_APB2_PERIPH_DBGMCU: DBGMCU clock
1101  *
1102  * @retval      None
1103  */
RCM_EnableAPB2PeriphClock(uint32_t APB2Periph)1104 void RCM_EnableAPB2PeriphClock(uint32_t APB2Periph)
1105 {
1106     RCM->APBCLKEN2 |= APB2Periph;
1107 }
1108 
1109 /*!
1110  * @brief       Disable the High Speed APB (APB2) peripheral clock
1111  *
1112  * @param       APB2Periph:  specifies the APB2 peripheral to gates its clock
1113  *                           This parameter can be any combination of the following values:
1114  *                           @arg RCM_APB2_PERIPH_SYSCFG: SYSCFG clock
1115  *                           @arg RCM_APB2_PERIPH_USART6: USART6 clock(Only for APM32F091)
1116  *                           @arg RCM_APB2_PERIPH_USART7: USART7 clock(Only for APM32F091)
1117  *                           @arg RCM_APB2_PERIPH_USART8: USART8 clock(Only for APM32F091)
1118  *                           @arg RCM_APB2_PERIPH_ADC1:   ADC1 clock
1119  *                           @arg RCM_APB2_PERIPH_TMR1:   TMR1 clock
1120  *                           @arg RCM_APB2_PERIPH_SPI1:   SPI1 clock
1121  *                           @arg RCM_APB2_PERIPH_USART1: USART1 clock
1122  *                           @arg RCM_APB2_PERIPH_TMR15:  TMR15 clock
1123  *                           @arg RCM_APB2_PERIPH_TMR16:  TMR16 clock
1124  *                           @arg RCM_APB2_PERIPH_TMR17:  TMR17 clock
1125  *                           @arg RCM_APB2_PERIPH_DBGMCU: DBGMCU clock
1126  *
1127  * @retval      None
1128  */
RCM_DisableAPB2PeriphClock(uint32_t APB2Periph)1129 void RCM_DisableAPB2PeriphClock(uint32_t APB2Periph)
1130 {
1131     RCM->APBCLKEN2 &= (uint32_t)~APB2Periph;
1132 }
1133 
1134 /*!
1135  * @brief       Enable the Low Speed APB (APB1) peripheral clock
1136  *
1137  * @param       APB1Periph:  specifies the APB1 peripheral to gates its clock
1138  *                           This parameter can be any combination of the following values:
1139  *                           @arg RCM_APB1_PERIPH_TMR2:   TMR2 clock(Only for APM32F072 and APM32F091)
1140  *                           @arg RCM_APB1_PERIPH_TMR3:   TMR3 clock
1141  *                           @arg RCM_APB1_PERIPH_TMR6:   TMR6 clock
1142  *                           @arg RCM_APB1_PERIPH_TMR7:   TMR7 clock(Only for APM32F072)
1143  *                           @arg RCM_APB1_PERIPH_TMR14:  TMR14 clock
1144  *                           @arg RCM_APB1_PERIPH_WWDT:   WWDG clock
1145  *                           @arg RCM_APB1_PERIPH_SPI2:   SPI2 clock
1146  *                           @arg RCM_APB1_PERIPH_USART2: USART2 clock
1147  *                           @arg RCM_APB1_PERIPH_USART3: USART3 clock(Only for APM32F072 and APM32F091)
1148  *                           @arg RCM_APB1_PERIPH_USART4: USART4 clock(Only for APM32F072 and APM32F091)
1149  *                           @arg RCM_APB1_PERIPH_USART5: USART5 clock(Only for APM32F091)
1150  *                           @arg RCM_APB1_PERIPH_I2C1:   I2C1 clock
1151  *                           @arg RCM_APB1_PERIPH_I2C2:   I2C2 clock
1152  *                           @arg RCM_APB1_PERIPH_USB:    USB clock(Only for APM32F072)
1153  *                           @arg RCM_APB1_PERIPH_CAN:    CAN clock(Only for APM32F072 and APM32F091)
1154  *                           @arg RCM_APB1_PERIPH_CRS:    CRS clock(Only for APM32F072 and APM32F091)
1155  *                           @arg RCM_APB1_PERIPH_PMU:    PMU clock
1156  *                           @arg RCM_APB1_PERIPH_DAC:    DAC clock(Only for APM32F072 and APM32F091)
1157  *                           @arg RCM_APB1_PERIPH_CEC:    CEC clock(Only for APM32F072 and APM32F091)
1158  *
1159  * @retval      None
1160  */
RCM_EnableAPB1PeriphClock(uint32_t APB1Periph)1161 void RCM_EnableAPB1PeriphClock(uint32_t APB1Periph)
1162 {
1163     RCM->APBCLKEN1 |= APB1Periph;
1164 }
1165 
1166 /*!
1167  * @brief       Disable the Low Speed APB (APB1) peripheral clock
1168  *
1169  * @param       APB1Periph:  specifies the APB1 peripheral to gates its clock
1170  *                           This parameter can be any combination of the following values:
1171  *                           @arg RCM_APB1_PERIPH_TMR2:   TMR2 clock(Only for APM32F072 and APM32F091)
1172  *                           @arg RCM_APB1_PERIPH_TMR3:   TMR3 clock
1173  *                           @arg RCM_APB1_PERIPH_TMR6:   TMR6 clock
1174  *                           @arg RCM_APB1_PERIPH_TMR7:   TMR7 clock(Only for APM32F072)
1175  *                           @arg RCM_APB1_PERIPH_TMR14:  TMR14 clock
1176  *                           @arg RCM_APB1_PERIPH_WWDT:   WWDG clock
1177  *                           @arg RCM_APB1_PERIPH_SPI2:   SPI2 clock
1178  *                           @arg RCM_APB1_PERIPH_USART2: USART2 clock
1179  *                           @arg RCM_APB1_PERIPH_USART3: USART3 clock(Only for APM32F072 and APM32F091)
1180  *                           @arg RCM_APB1_PERIPH_USART4: USART4 clock(Only for APM32F072 and APM32F091)
1181  *                           @arg RCM_APB1_PERIPH_USART5: USART5 clock(Only for APM32F091)
1182  *                           @arg RCM_APB1_PERIPH_I2C1:   I2C1 clock
1183  *                           @arg RCM_APB1_PERIPH_I2C2:   I2C2 clock
1184  *                           @arg RCM_APB1_PERIPH_USB:    USB clock(Only for APM32F072)
1185  *                           @arg RCM_APB1_PERIPH_CAN:    CAN clock(Only for APM32F072 and APM32F091)
1186  *                           @arg RCM_APB1_PERIPH_CRS:    CRS clock(Only for APM32F072 and APM32F091)
1187  *                           @arg RCM_APB1_PERIPH_PMU:    PMU clock
1188  *                           @arg RCM_APB1_PERIPH_DAC:    DAC clock(Only for APM32F072 and APM32F091)
1189  *                           @arg RCM_APB1_PERIPH_CEC:    CEC clock(Only for APM32F072 and APM32F091)
1190  *
1191  * @retval      None
1192  */
RCM_DisableAPB1PeriphClock(uint32_t APB1Periph)1193 void RCM_DisableAPB1PeriphClock(uint32_t APB1Periph)
1194 {
1195     RCM->APBCLKEN1 &= (uint32_t)~APB1Periph;
1196 }
1197 
1198 /*!
1199  * @brief       Enable Low Speed AHB peripheral reset
1200  *
1201  * @param       AHBPeriph:   specifies the AHB peripheral to reset
1202  *                           This parameter can be any combination of the following values:
1203  *                           @arg RCM_AHB_PERIPH_GPIOA: GPIOA reset
1204  *                           @arg RCM_AHB_PERIPH_GPIOB: GPIOB reset
1205  *                           @arg RCM_AHB_PERIPH_GPIOC: GPIOC reset
1206  *                           @arg RCM_AHB_PERIPH_GPIOD: GPIOD reset
1207  *                           @arg RCM_AHB_PERIPH_GPIOE: GPIOE clock(Only for APM32F072 and APM32F091)
1208  *                           @arg RCM_AHB_PERIPH_GPIOF: GPIOF reset
1209  *                           @arg RCM_AHB_PERIPH_TSC:   TSC clock
1210  *
1211  * @retval      None
1212  */
RCM_EnableAHBPeriphReset(uint32_t AHBPeriph)1213 void RCM_EnableAHBPeriphReset(uint32_t AHBPeriph)
1214 {
1215     RCM->AHBRST |= AHBPeriph;
1216 }
1217 
1218 /*!
1219  * @brief       Disable Low Speed AHB peripheral reset
1220  *
1221  * @param       AHBPeriph:   specifies the AHB peripheral to reset
1222  *                           This parameter can be any combination of the following values:
1223  *                           @arg RCM_AHB_PERIPH_GPIOA: GPIOA reset
1224  *                           @arg RCM_AHB_PERIPH_GPIOB: GPIOB reset
1225  *                           @arg RCM_AHB_PERIPH_GPIOC: GPIOC reset
1226  *                           @arg RCM_AHB_PERIPH_GPIOD: GPIOD reset
1227  *                           @arg RCM_AHB_PERIPH_GPIOE: GPIOE clock(Only for APM32F072 and APM32F091)
1228  *                           @arg RCM_AHB_PERIPH_GPIOF: GPIOF reset
1229  *                           @arg RCM_AHB_PERIPH_TSC:   TSC clock
1230  *
1231  * @retval      None
1232  */
RCM_DisableAHBPeriphReset(uint32_t AHBPeriph)1233 void RCM_DisableAHBPeriphReset(uint32_t AHBPeriph)
1234 {
1235     RCM->AHBRST &= (uint32_t)~AHBPeriph;
1236 }
1237 
1238 /*!
1239  * @brief       Enable Low Speed APB (APB1) peripheral reset
1240  *
1241  * @param       APB1Periph:  specifies the APB1 peripheral to reset
1242  *                           This parameter can be any combination of the following values:
1243  *                           @arg RCM_APB1_PERIPH_TMR2:   TMR2 clock(Only for APM32F072 and APM32F091)
1244  *                           @arg RCM_APB1_PERIPH_TMR3:   TMR3 clock
1245  *                           @arg RCM_APB1_PERIPH_TMR6:   TMR6 clock
1246  *                           @arg RCM_APB1_PERIPH_TMR7:   TMR7 clock(Only for APM32F072 and APM32F091)
1247  *                           @arg RCM_APB1_PERIPH_TMR14:  TMR14 clock
1248  *                           @arg RCM_APB1_PERIPH_WWDT:   WWDG clock
1249  *                           @arg RCM_APB1_PERIPH_SPI2:   SPI2 clock
1250  *                           @arg RCM_APB1_PERIPH_USART2: USART2 clock
1251  *                           @arg RCM_APB1_PERIPH_USART3: USART3 clock(Only for APM32F072 and APM32F091)
1252  *                           @arg RCM_APB1_PERIPH_USART4: USART4 clock(Only for APM32F072 and APM32F091)
1253  *                           @arg RCM_APB1_PERIPH_USART5: USART5 clock(Only for APM32F091)
1254  *                           @arg RCM_APB1_PERIPH_I2C1:   I2C1 clock
1255  *                           @arg RCM_APB1_PERIPH_I2C2:   I2C2 clock
1256  *                           @arg RCM_APB1_PERIPH_USB:    USB clock(Only for APM32F072)
1257  *                           @arg RCM_APB1_PERIPH_CAN:    CAN clock(Only for APM32F072 and APM32F091)
1258  *                           @arg RCM_APB1_PERIPH_CRS:    CRS clock(Only for APM32F072 and APM32F091)
1259  *                           @arg RCM_APB1_PERIPH_PMU:    PMU clock
1260  *                           @arg RCM_APB1_PERIPH_DAC:    DAC clock(Only for APM32F072 and APM32F091)
1261  *                           @arg RCM_APB1_PERIPH_CEC:    CEC clock(Only for APM32F072 and APM32F091)
1262  *
1263  * @retval      None
1264  */
RCM_EnableAPB1PeriphReset(uint32_t APB1Periph)1265 void RCM_EnableAPB1PeriphReset(uint32_t APB1Periph)
1266 {
1267     RCM->APBRST1 |= APB1Periph;
1268 }
1269 
1270 /*!
1271  * @brief       Disable Low Speed APB (APB1) peripheral reset
1272  *
1273  * @param       APB1Periph:  specifies the APB1 peripheral to reset
1274  *                           This parameter can be any combination of the following values:
1275  *                           @arg RCM_APB1_PERIPH_TMR2:   TMR2 clock(Only for APM32F072 and APM32F091)
1276  *                           @arg RCM_APB1_PERIPH_TMR3:   TMR3 clock
1277  *                           @arg RCM_APB1_PERIPH_TMR6:   TMR6 clock
1278  *                           @arg RCM_APB1_PERIPH_TMR7:   TMR7 clock(Only for APM32F072 and APM32F091)
1279  *                           @arg RCM_APB1_PERIPH_TMR14:  TMR14 clock
1280  *                           @arg RCM_APB1_PERIPH_WWDT:   WWDG clock
1281  *                           @arg RCM_APB1_PERIPH_SPI2:   SPI2 clock
1282  *                           @arg RCM_APB1_PERIPH_USART2: USART2 clock
1283  *                           @arg RCM_APB1_PERIPH_USART3: USART3 clock(Only for APM32F072 and APM32F091)
1284  *                           @arg RCM_APB1_PERIPH_USART4: USART4 clock(Only for APM32F072 and APM32F091)
1285  *                           @arg RCM_APB1_PERIPH_USART5: USART5 clock(Only for APM32F091)
1286  *                           @arg RCM_APB1_PERIPH_I2C1:   I2C1 clock
1287  *                           @arg RCM_APB1_PERIPH_I2C2:   I2C2 clock
1288  *                           @arg RCM_APB1_PERIPH_USB:    USB clock(Only for APM32F072)
1289  *                           @arg RCM_APB1_PERIPH_CAN:    CAN clock(Only for APM32F072 and APM32F091)
1290  *                           @arg RCM_APB1_PERIPH_CRS:    CRS clock(Only for APM32F072 and APM32F091)
1291  *                           @arg RCM_APB1_PERIPH_PMU:    PMU clock
1292  *                           @arg RCM_APB1_PERIPH_DAC:    DAC clock(Only for APM32F072 and APM32F091)
1293  *                           @arg RCM_APB1_PERIPH_CEC:    CEC clock(Only for APM32F072 and APM32F091)
1294  *
1295  * @retval      None
1296  */
RCM_DisableAPB1PeriphReset(uint32_t APB1Periph)1297 void RCM_DisableAPB1PeriphReset(uint32_t APB1Periph)
1298 {
1299     RCM->APBRST1 &= (uint32_t)~APB1Periph;
1300 }
1301 
1302 /*!
1303  * @brief       Enable High Speed APB (APB2) peripheral reset
1304  *
1305  * @param       APB2Periph:  specifies the APB2 peripheral to reset
1306  *                           This parameter can be any combination of the following values:
1307  *                           @arg RCM_APB2_PERIPH_SYSCFG: SYSCFG clock
1308  *                           @arg RCM_APB2_PERIPH_USART6: USART6 clock(Only for APM32F091)
1309  *                           @arg RCM_APB2_PERIPH_USART7: USART7 clock(Only for APM32F091)
1310  *                           @arg RCM_APB2_PERIPH_USART8: USART8 clock(Only for APM32F091)
1311  *                           @arg RCM_APB2_PERIPH_ADC1:   ADC1 clock
1312  *                           @arg RCM_APB2_PERIPH_TMR1:   TMR1 clock
1313  *                           @arg RCM_APB2_PERIPH_SPI1:   SPI1 clock
1314  *                           @arg RCM_APB2_PERIPH_USART1: USART1 clock
1315  *                           @arg RCM_APB2_PERIPH_TMR15:  TMR15 clock
1316  *                           @arg RCM_APB2_PERIPH_TMR16:  TMR16 clock
1317  *                           @arg RCM_APB2_PERIPH_TMR17:  TMR17 clock
1318  *                           @arg RCM_APB2_PERIPH_DBGMCU: DBGMCU clock
1319  *
1320  * @retval      None
1321  */
RCM_EnableAPB2PeriphReset(uint32_t APB2Periph)1322 void RCM_EnableAPB2PeriphReset(uint32_t APB2Periph)
1323 {
1324     RCM->APBRST2 |= APB2Periph;
1325 }
1326 
1327 /*!
1328  * @brief       Disable High Speed APB (APB2) peripheral reset
1329  *
1330  * @param       APB2Periph:  specifies the APB2 peripheral to reset
1331  *                           This parameter can be any combination of the following values:
1332  *                           @arg RCM_APB2_PERIPH_SYSCFG: SYSCFG clock
1333  *                           @arg RCM_APB2_PERIPH_USART6: USART6 clock(Only for APM32F091)
1334  *                           @arg RCM_APB2_PERIPH_USART7: USART7 clock(Only for APM32F091)
1335  *                           @arg RCM_APB2_PERIPH_USART8: USART8 clock(Only for APM32F091)
1336  *                           @arg RCM_APB2_PERIPH_ADC1:   ADC1 clock
1337  *                           @arg RCM_APB2_PERIPH_TMR1:   TMR1 clock
1338  *                           @arg RCM_APB2_PERIPH_SPI1:   SPI1 clock
1339  *                           @arg RCM_APB2_PERIPH_USART1: USART1 clock
1340  *                           @arg RCM_APB2_PERIPH_TMR15:  TMR15 clock
1341  *                           @arg RCM_APB2_PERIPH_TMR16:  TMR16 clock
1342  *                           @arg RCM_APB2_PERIPH_TMR17:  TMR17 clock
1343  *                           @arg RCM_APB2_PERIPH_DBGMCU: DBGMCU clock
1344  *
1345  * @retval      None
1346  */
RCM_DisableAPB2PeriphReset(uint32_t APB2Periph)1347 void RCM_DisableAPB2PeriphReset(uint32_t APB2Periph)
1348 {
1349     RCM->APBRST2 &= (uint32_t)~APB2Periph;
1350 }
1351 
1352 /*!
1353  * @brief       Enable the specified RCM interrupts
1354  *
1355  * @param       interrupt:   specifies the RCM interrupt source to check
1356  *                           This parameter can be any combination of the following values:
1357  *                           @arg RCM_INT_LSIRDY:    LSI ready interrupt
1358  *                           @arg RCM_INT_LSERDY:    LSE ready interrupt
1359  *                           @arg RCM_INT_HSIRDY:    HSI ready interrupt
1360  *                           @arg RCM_INT_HSERDY:    HSE ready interrupt
1361  *                           @arg RCM_INT_PLLRDY:    PLL ready interrupt
1362  *                           @arg RCM_INT_HSI14RDY:  HSI14 ready interrupt
1363  *                           @arg RCM_INT_HSI48RDY:  HSI48 ready interrupt(Only for APM32F072 and APM32F091 devices)
1364  *
1365  * @retval  None
1366  */
RCM_EnableInterrupt(uint8_t interrupt)1367 void RCM_EnableInterrupt(uint8_t interrupt)
1368 {
1369     RCM->INT |= (interrupt << 8);
1370 }
1371 
1372 /*!
1373  * @brief       Disable the specified RCM interrupts
1374  *
1375  * @param       interrupt:   specifies the RCM interrupt source to check
1376  *                           This parameter can be any combination of the following values:
1377  *                           @arg RCM_INT_LSIRDY:    LSI ready interrupt
1378  *                           @arg RCM_INT_LSERDY:    LSE ready interrupt
1379  *                           @arg RCM_INT_HSIRDY:    HSI ready interrupt
1380  *                           @arg RCM_INT_HSERDY:    HSE ready interrupt
1381  *                           @arg RCM_INT_PLLRDY:    PLL ready interrupt
1382  *                           @arg RCM_INT_HSI14RDY:  HSI14 ready interrupt
1383  *                           @arg RCM_INT_HSI48RDY:  HSI48 ready interrupt(Only for APM32F072 and APM32F091 devices)
1384  *
1385  * @retval  None
1386  */
RCM_DisableInterrupt(uint8_t interrupt)1387 void RCM_DisableInterrupt(uint8_t interrupt)
1388 {
1389     RCM->INT &= ~(interrupt << 8);
1390 }
1391 
1392 /*!
1393  * @brief       Read the specified RCM flag status
1394  *
1395  * @param       flag:   specifies the flag to check
1396  *                      This parameter can be one of the following values:
1397  *                      @arg RCM_FLAG_HSIRDY:   HSI oscillator clock ready
1398  *                      @arg RCM_FLAG_HSERDY:   HSE oscillator clock ready
1399  *                      @arg RCM_FLAG_PLLRDY:   PLL clock ready
1400  *                      @arg RCM_FLAG_LSERDY:   LSE oscillator clock ready
1401  *                      @arg RCM_FLAG_LSIRDY:   LSI oscillator clock ready
1402  *                      @arg RCM_FLAG_V18PRRST: V1.8 power domain reset
1403  *                      @arg RCM_FLAG_OBRST:    Option Byte Loader (OBL) reset
1404  *                      @arg RCM_FLAG_PINRST:   Pin reset
1405  *                      @arg RCM_FLAG_PWRRST:   POR/PDR reset
1406  *                      @arg RCM_FLAG_SWRST:    Software reset
1407  *                      @arg RCM_FLAG_IWDTRST:  Independent Watchdog reset
1408  *                      @arg RCM_FLAG_WWDTRST:  Window Watchdog reset
1409  *                      @arg RCM_FLAG_LPRRST:   Low Power reset
1410  *                      @arg RCM_FLAG_HSI14RDY: HSI14 clock ready
1411  *                      @arg RCM_FLAG_HSI48RDY: HSI48 clock ready(Only for APM32F072 and APM32F091)
1412  *
1413  * @retval      The new state of flag (SET or RESET)
1414  */
RCM_ReadStatusFlag(RCM_FLAG_T flag)1415 uint16_t RCM_ReadStatusFlag(RCM_FLAG_T flag)
1416 {
1417     uint32_t reg, bit;
1418 
1419     bit = (uint32_t)(1 << (flag & 0xff));
1420 
1421     reg = (flag >> 8) & 0xff;
1422 
1423     switch (reg)
1424     {
1425         case 0:
1426             reg = RCM->CTRL1;
1427             break;
1428 
1429         case 1:
1430             reg = RCM->BDCTRL;
1431             break;
1432 
1433         case 2:
1434             reg = RCM->CSTS;
1435             break;
1436 
1437         case 3:
1438             reg = RCM->CTRL2;
1439             break;
1440 
1441         default:
1442             break;
1443     }
1444 
1445     if (reg & bit)
1446     {
1447         return SET;
1448     }
1449 
1450     return RESET;
1451 }
1452 
1453 /*!
1454  * @brief       Clears the RCM reset flags
1455  *
1456  * @param       None
1457  *
1458  * @retval      None
1459  *
1460  * @note        The reset flags are:
1461  *              RCM_FLAG_V18PRRST; RCM_FLAG_OBRST; RCM_FLAG_PINRST; RCM_FLAG_PWRRST;
1462  *              RCM_FLAG_SWRST; RCM_FLAG_IWDTRST; RCM_FLAG_WWDTRST; RCM_FLAG_LPRRST;
1463  */
RCM_ClearStatusFlag(void)1464 void RCM_ClearStatusFlag(void)
1465 {
1466     RCM->CSTS_B.RSTFLGCLR = BIT_SET;
1467 }
1468 
1469 /*!
1470  * @brief       Read the specified RCM interrupt Flag
1471  *
1472  * @param       flag:   specifies the RCM interrupt source to check
1473  *                      This parameter can be one of the following values:
1474  *                      @arg RCM_INT_LSIRDY:    LSI ready interrupt
1475  *                      @arg RCM_INT_LSERDY:    LSE ready interrupt
1476  *                      @arg RCM_INT_HSIRDY:    HSI ready interrupt
1477  *                      @arg RCM_INT_HSERDY:    HSE ready interrupt
1478  *                      @arg RCM_INT_PLLRDY:    PLL ready interrupt
1479  *                      @arg RCM_INT_HSI14RDY:  HSI14 ready interrupt
1480  *                      @arg RCM_INT_HSI48RDY:  HSI48 ready interrupt(Only for APM32F072 and APM32F091 devices)
1481  *                      @arg RCC_IT_CSS:        Clock Security System interrupt
1482  *
1483  * @retval      The new state of intFlag (SET or RESET)
1484  */
RCM_ReadIntFlag(RCM_INT_T flag)1485 uint8_t RCM_ReadIntFlag(RCM_INT_T flag)
1486 {
1487     uint8_t ret;
1488 
1489     ret = (RCM->INT& flag) ? SET : RESET;
1490 
1491     return  ret;
1492 }
1493 
1494 /*!
1495  * @brief       Clears the interrupt flag
1496  *
1497  * @param       flag:   specifies the RCM interrupt source to check
1498  *                      This parameter can be any combination of the following values:
1499  *                      @arg RCM_INT_LSIRDY:    LSI ready interrupt
1500  *                      @arg RCM_INT_LSERDY:    LSE ready interrupt
1501  *                      @arg RCM_INT_HSIRDY:    HSI ready interrupt
1502  *                      @arg RCM_INT_HSERDY:    HSE ready interrupt
1503  *                      @arg RCM_INT_PLLRDY:    PLL ready interrupt
1504  *                      @arg RCM_INT_HSI14RDY:  HSI14 ready interrupt
1505  *                      @arg RCM_INT_HSI48RDY:  HSI48 ready interrupt(Only for APM32F072 and APM32F091 devices)
1506  *                      @arg RCC_IT_CSS:        Clock Security System interrupt
1507  *
1508  * @retval      None
1509  */
RCM_ClearIntFlag(uint8_t flag)1510 void RCM_ClearIntFlag(uint8_t flag)
1511 {
1512     uint32_t temp;
1513 
1514     temp = flag << 16;
1515     RCM->INT |= temp;
1516 }
1517 
1518 /**@} end of group RCM_Functions*/
1519 /**@} end of group RCM_Driver*/
1520 /**@} end of group APM32F0xx_StdPeriphDriver*/
1521