1 /*!
2  * @file        apm32f10x_rcm.c
3  *
4  * @brief       This file provides all the RCM firmware functions
5  *
6  * @version     V1.0.4
7  *
8  * @date        2022-12-01
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 "apm32f10x_rcm.h"
27 
28 /** @addtogroup APM32F10x_StdPeriphDriver
29   @{
30 */
31 
32 /** @addtogroup RCM_Driver RCM Driver
33   * @brief RCM driver modules
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     /* Configures HSI to system clock and Reset AHBPSC, APB1PSC, APB2PSC, ADCPSC and MCOSEL bits */
53 #if defined(APM32F10X_CL)
54     RCM->CFG &= (uint32_t)0xF0FF0000;
55 #else
56     RCM->CFG &= (uint32_t)0xF8FF0000;
57 #endif
58 
59     /* Reset HSEEN, CSSEN and PLLEN bits */
60     RCM->CTRL &= (uint32_t)0xFEF6FFFF;
61     /* Reset HSEBCFG bit */
62     RCM->CTRL_B.HSEBCFG = BIT_RESET;
63     /* Reset PLLSRCSEL, PLLHSEPSC, PLLMULCFG and USBDIV bits */
64     RCM->CFG &= (uint32_t)0xFF00FFFF;
65 
66 #if defined(APM32F10X_CL)
67     /* Reset PLL2EN and PLL3EN bits */
68     RCM->CTRL_B.PLL2EN = BIT_RESET;
69     RCM->CTRL_B.PLL3EN = BIT_RESET;
70 
71     /* Disable all interrupts and clear pending bits  */
72     RCM->INT = 0x00FF0000;
73 
74     /* Reset CFG2 register */
75     RCM->CFG2 = 0x00000000;
76 #else
77     /* Disable all interrupts and clear pending bits */
78     RCM->INT = 0x009F0000;
79 #endif
80 }
81 
82 /*!
83  * @brief     Configures the HSE oscillator
84  *
85  * @param     state: state of the HSE
86  *                   This parameter can be one of the following values:
87  *                   @arg RCM_HSE_CLOSE:  Turn off the HSE oscillator
88  *                   @arg RCM_HSE_OPEN:   Turn on the HSE oscillator
89  *                   @arg RCM_HSE_BYPASS: HSE oscillator bypassed with external clock
90  *
91  * @retval    None
92  *
93  * @note      When HSE is not used directly or through the PLL as system clock, it can be stopped.
94  */
RCM_ConfigHSE(RCM_HSE_T state)95 void RCM_ConfigHSE(RCM_HSE_T state)
96 {
97     /* Reset HSEEN bit */
98     RCM->CTRL_B.HSEEN = BIT_RESET;
99 
100     /* Reset HSEBCFG bit */
101     RCM->CTRL_B.HSEBCFG = BIT_RESET;
102 
103     if (state == RCM_HSE_OPEN)
104     {
105         RCM->CTRL_B.HSEEN = BIT_SET;
106     }
107     else if (state == RCM_HSE_BYPASS)
108     {
109         RCM->CTRL_B.HSEBCFG = BIT_SET;
110         RCM->CTRL_B.HSEEN = BIT_SET;
111     }
112 }
113 
114 /*!
115  * @brief     Wait for HSE to be ready
116  *
117  * @param     None
118  *
119  * @retval    SUCCESS: HSE oscillator is ready
120  *            ERROR  : HSE oscillator is not ready
121  */
RCM_WaitHSEReady(void)122 uint8_t RCM_WaitHSEReady(void)
123 {
124     __IO uint32_t cnt;
125 
126     for (cnt = 0; cnt < HSE_STARTUP_TIMEOUT; cnt++)
127     {
128         if (RCM->CTRL_B.HSERDYFLG == BIT_SET)
129         {
130             return SUCCESS;
131         }
132     }
133 
134     return ERROR;
135 }
136 
137 /*!
138  * @brief     Configures HSI trimming value
139  *
140  * @param     HSITrim: HSI trimming value
141  *                     This parameter must be a number between 0 and 0x1F.
142  *
143  * @retval    None
144  */
RCM_ConfigHSITrim(uint8_t HSITrim)145 void RCM_ConfigHSITrim(uint8_t HSITrim)
146 {
147     RCM->CTRL_B.HSITRIM = HSITrim;
148 }
149 
150 /*!
151  * @brief     Enable the HSI
152  *
153  * @param     None
154  *
155  * @retval    None
156  */
RCM_EnableHSI(void)157 void RCM_EnableHSI(void)
158 {
159     RCM->CTRL_B.HSIEN = BIT_SET;
160 }
161 
162 /*!
163  * @brief     Disable the HSI
164  *
165  * @param     None
166  *
167  * @retval    None
168  *
169  * @note      When HSI is not used directly or through the PLL as system clock, it can be stopped.
170  */
171 
RCM_DisableHSI(void)172 void RCM_DisableHSI(void)
173 {
174     RCM->CTRL_B.HSIEN = BIT_RESET;
175 }
176 
177 /*!
178  * @brief     Configures the External Low Speed oscillator (LSE)
179  *
180  * @param     state : Specifies the new state of the LSE
181  *                    This parameter can be one of the following values:
182  *                    @arg RCM_LSE_CLOSE  : Close the LSE
183  *                    @arg RCM_LSE_OPEN   : Open the LSE
184  *                    @arg RCM_LSE_BYPASS : LSE bypass
185  *
186  * @retval    None
187  */
RCM_ConfigLSE(RCM_LSE_T state)188 void RCM_ConfigLSE(RCM_LSE_T state)
189 {
190     RCM->BDCTRL_B.LSEEN = BIT_RESET;
191     RCM->BDCTRL_B.LSEBCFG = BIT_RESET;
192 
193     if (state == RCM_LSE_OPEN)
194     {
195         RCM->BDCTRL_B.LSEEN = BIT_SET;
196     }
197     else if (state == RCM_LSE_BYPASS)
198     {
199         RCM->BDCTRL_B.LSEBCFG = BIT_SET;
200         RCM->BDCTRL_B.LSEEN = BIT_SET;
201     }
202 }
203 
204 /*!
205  * @brief     Enable the Internal Low Speed oscillator (LSI)
206  *
207  * @param     None
208  *
209  * @retval    None
210  */
RCM_EnableLSI(void)211 void RCM_EnableLSI(void)
212 {
213     RCM->CSTS_B.LSIEN = BIT_SET;
214 }
215 
216 /*!
217  * @brief     Disable the Internal Low Speed oscillator (LSI)
218  *
219  * @param     None
220  *
221  * @retval    None
222  */
RCM_DisableLSI(void)223 void RCM_DisableLSI(void)
224 {
225     RCM->CSTS_B.LSIEN = BIT_RESET;
226 }
227 
228 /*!
229  * @brief     Configures the PLL clock source and multiplication factor
230  *
231  * @param     pllSelect: PLL entry clock source select
232  *                       This parameter can be one of the following values:
233  *                       For APM32F105xx and APM32F107xx devices:
234  *                        @arg RCM_PLLSEL_HSI_DIV_2: HSI clock divided by 2 selected as PLL clock source
235  *                        @arg RCM_PLLSEL_PREDIV1  : PLL prescaler 1 clock selected as PLL clock source
236  *                       For other devices:
237  *                        @arg RCM_PLLSEL_HSI_DIV_2: HSI clock divided by 2 selected as PLL clock source
238  *                        @arg RCM_PLLSEL_HSE      : HSE clock selected as PLL clock source
239  *                        @arg RCM_PLLSEL_HSE_DIV2 : HSE clock divided by 2 selected as PLL clock source
240  *
241  * @param     pllMf:     PLL multiplication factor
242  *                       For APM32F105xx and APM32F107xx devices:
243  *                        This parameter can be one of the following values:
244  *                        @arg RCM_PLLMF_4  : PLL Multiplication Factor Configures to 4
245  *                        @arg RCM_PLLMF_5  : PLL Multiplication Factor Configures to 5
246  *                        @arg RCM_PLLMF_6  : PLL Multiplication Factor Configures to 6
247  *                        @arg RCM_PLLMF_7  : PLL Multiplication Factor Configures to 7
248  *                        @arg RCM_PLLMF_8  : PLL Multiplication Factor Configures to 8
249  *                        @arg RCM_PLLMF_9  : PLL Multiplication Factor Configures to 9
250  *                        @arg RCM_PLLMF_6_5: PLL Multiplication Factor Configures to 6.5
251  *                       For other devices:
252  *                        This parameter can be RCM_PLLMF_x where x can be a value from 2 to 16.
253  *
254  * @retval    None
255  *
256  * @note      PLL should be disabled while use this function.
257  */
RCM_ConfigPLL(RCM_PLLSEL_T pllSelect,RCM_PLLMF_T pllMf)258 void RCM_ConfigPLL(RCM_PLLSEL_T pllSelect, RCM_PLLMF_T pllMf)
259 {
260     RCM->CFG_B.PLL1MULCFG = pllMf;
261     RCM->CFG_B.PLL1SRCSEL = pllSelect & 0x01;
262 
263 #ifndef APM32F10X_CL
264     RCM->CFG_B.PLLHSEPSC = (pllSelect >> 1) & 0x01;
265 #endif
266 }
267 
268 /*!
269  * @brief      Enable the PLL
270  *
271  * @param      None
272  *
273  * @retval     None
274  */
RCM_EnablePLL(void)275 void RCM_EnablePLL(void)
276 {
277     RCM->CTRL_B.PLL1EN = BIT_SET;
278 }
279 
280 /*!
281  * @brief      Disable the PLL
282  *
283  * @param      None
284  *
285  * @retval     None
286  *
287  * @note       When PLL is not used as system clock, it can be stopped.
288  */
RCM_DisablePLL(void)289 void RCM_DisablePLL(void)
290 {
291     RCM->CTRL_B.PLL1EN = BIT_RESET;
292 }
293 
294 #if defined(APM32F10X_CL)
295 /*!
296  * @brief      Enable the PLL2
297  *
298  * @param      None
299  *
300  * @retval     None
301  */
RCM_EnablePLL2(void)302 void RCM_EnablePLL2(void)
303 {
304     RCM->CTRL_B.PLL2EN = BIT_SET;
305 }
306 
307 /*!
308  * @brief      Disable the PLL2
309  *
310  * @param      None
311  *
312  * @retval     None
313  */
RCM_DisablePLL2(void)314 void RCM_DisablePLL2(void)
315 {
316     RCM->CTRL_B.PLL2EN = BIT_RESET;
317 }
318 
319 /*!
320  * @brief      Enable the PLL3
321  *
322  * @param      None
323  *
324  * @retval     None
325  */
RCM_EnablePLL3(void)326 void RCM_EnablePLL3(void)
327 {
328     RCM->CTRL_B.PLL3EN = BIT_SET;
329 }
330 
331 /*!
332  * @brief      Disable the PLL3
333  *
334  * @param      None
335  *
336  * @retval     None
337  */
RCM_DisablePLL3(void)338 void RCM_DisablePLL3(void)
339 {
340     RCM->CTRL_B.PLL3EN = BIT_RESET;
341 }
342 
343 /*!
344  * @brief     Configures the PLL prescaler 1 factor.
345  *
346  * @param     pllPsc1Src: PLL prescaler 1 source select
347  *                        This parameter can be one of the following values:
348  *                        @arg RCM_PLLPSC1_SRC_HSE : HSE clock selected as PLL prescaler 1 clock source
349  *                        @arg RCM_PLLPSC1_SRC_PLL2: PLL2 clock selected as PLL prescaler 1 clock source
350  *
351  * @param     pllPsc1: PLL prescaler 1 factor
352  *                     This parameter can be RCM_PLLPSC1_DIV_x where x can be a value from 1 to 16.
353  *
354  * @retval    None
355  *
356  * @note      PLL should be disabled while use this function.
357  */
RCM_ConfigPLLPSC1(RCM_PLLPSC1_SRC_T pllPsc1Src,RCM_PLLPSC1_DIV_T pllPsc1)358 void RCM_ConfigPLLPSC1(RCM_PLLPSC1_SRC_T pllPsc1Src,  RCM_PLLPSC1_DIV_T pllPsc1)
359 {
360     RCM->CFG2_B.PLLPSC1SRC = pllPsc1Src;
361     RCM->CFG2_B.PLLPSC1 = pllPsc1;
362 }
363 
364 /*!
365  * @brief     Configures the PLL prescaler 2 factor.
366  *
367  * @param     pllpsc2: PLL prescaler 2 factor
368  *                     This parameter can be RCM_PLLPSC2_DIV_x where x can be a value from 1 to 16.
369  *
370  * @retval    None
371  *
372  * @note      PLL2 and PLL3 should be disabled while use this function.
373  */
RCM_ConfigPLLPSC2(RCM_PLLPSC2_DIV_T pllpsc2)374 void RCM_ConfigPLLPSC2(RCM_PLLPSC2_DIV_T pllpsc2)
375 {
376     RCM->CFG2_B.PLLPSC2 = pllpsc2;
377 }
378 
379 /*!
380  * @brief     Configures the PLL2 clock multiplication factor
381  *
382  * @param     pll2Mf:  PLL2 multiplication factor
383  *                     This parameter can be RCM_PLL2MF_x where x can be a value from 8 to 14, and 16, 20.
384  *
385  * @retval    None
386  *
387  * @note      PLL2 should be disabled while use this function.
388  */
RCM_ConfigPLL2(RCM_PLL2MF_T pll2Mf)389 void RCM_ConfigPLL2(RCM_PLL2MF_T pll2Mf)
390 {
391     RCM->CFG2_B.PLL2MUL = pll2Mf;
392 }
393 
394 /*!
395  * @brief     Configures the PLL3 clock multiplication factor
396  *
397  * @param     pll3Mf:  PLL3 multiplication factor
398  *                     This parameter can be RCM_PLL3MF_x where x can be a value from 8 to 14, and 16, 20.
399  *
400  * @retval    None
401  *
402  * @note      PLL3 should be disabled while use this function.
403  */
RCM_ConfigPLL3(RCM_PLL3MF_T pll3Mf)404 void RCM_ConfigPLL3(RCM_PLL3MF_T pll3Mf)
405 {
406     RCM->CFG2_B.PLL3MUL = pll3Mf;
407 }
408 #endif
409 
410 /*!
411  * @brief     Enable the Clock Security System
412  *
413  * @param     None
414  *
415  * @retval    None
416  */
RCM_EnableCSS(void)417 void RCM_EnableCSS(void)
418 {
419     RCM->CTRL_B.CSSEN = BIT_SET;
420 }
421 
422 /*!
423  * @brief     Disable the Clock Security System
424  *
425  * @param     None
426  *
427  * @retval    None
428  */
RCM_DisableCSS(void)429 void RCM_DisableCSS(void)
430 {
431     RCM->CTRL_B.CSSEN = BIT_RESET;
432 }
433 
434 /*!
435  * @brief     Select the MCO pin clock output source
436  *
437  * @param     mcoClock: specifies the clock source to output
438  *                      This parameter can be one of the following values:
439  *                       @arg RCM_MCOCLK_NO_CLOCK     : No clock selected.
440  *                       @arg RCM_MCOCLK_SYSCLK       : System clock selected.
441  *                       @arg RCM_MCOCLK_HSI          : HSI oscillator clock selected.
442  *                       @arg RCM_MCOCLK_HSE          : HSE oscillator clock selected.
443  *                       @arg RCM_MCOCLK_PLLCLK_DIV_2 : PLL clock divided by 2 selected.
444  *                      The following values is only for APM32F105xx or APM32F107xx:
445  *                       @arg RCM_MCOCLK_PLL2CLK       : PLL2 clock selected.
446  *                       @arg RCM_MCOCLK_PLL3CLK_DIV_2 : PLL3 clock divided by 2 selected.
447  *                       @arg RCM_MCOCLK_OSCCLK        : OSC clock selected.
448  *                       @arg RCM_MCOCLK_PLL3CLK       : PLL3 clock selected.
449  *
450  * @retval    None
451  */
RCM_ConfigMCO(RCM_MCOCLK_T mcoClock)452 void RCM_ConfigMCO(RCM_MCOCLK_T mcoClock)
453 {
454     RCM->CFG_B.MCOSEL = mcoClock;
455 }
456 
457 /*!
458  * @brief    Configures the system clock source
459  *
460  * @param    sysClkSelect: specifies the clock source used as system clock
461  *                         This parameter can be one of the following values:
462  *                         @arg RCM_SYSCLK_SEL_HSI: HSI is selected as system clock source
463  *                         @arg RCM_SYSCLK_SEL_HSE: HSE is selected as system clock source
464  *                         @arg RCM_SYSCLK_SEL_PLL: PLL is selected as system clock source
465  *
466  * @retval    None
467  */
RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_T sysClkSelect)468 void RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_T sysClkSelect)
469 {
470     RCM->CFG_B.SCLKSEL = sysClkSelect;
471 }
472 
473 /*!
474  * @brief     Return the clock source which is used as system clock
475  *
476  * @param     None
477  *
478  * @retval    The clock source used as system clock
479  */
RCM_ReadSYSCLKSource(void)480 RCM_SYSCLK_SEL_T RCM_ReadSYSCLKSource(void)
481 {
482     return (RCM_SYSCLK_SEL_T)RCM->CFG_B.SCLKSELSTS;
483 }
484 
485 /*!
486  * @brief     Configures the AHB clock prescaler.
487  *
488  * @param     AHBDiv : Specifies the AHB clock prescaler from the system clock.
489  *                     This parameter can be one of the following values:
490  *                     @arg RCM_AHB_DIV_1   : HCLK = SYSCLK
491  *                     @arg RCM_AHB_DIV_2   : HCLK = SYSCLK / 2
492  *                     @arg RCM_AHB_DIV_4   : HCLK = SYSCLK / 4
493  *                     @arg RCM_AHB_DIV_8   : HCLK = SYSCLK / 8
494  *                     @arg RCM_AHB_DIV_16  : HCLK = SYSCLK / 16
495  *                     @arg RCM_AHB_DIV_64  : HCLK = SYSCLK / 64
496  *                     @arg RCM_AHB_DIV_128 : HCLK = SYSCLK / 128
497  *                     @arg RCM_AHB_DIV_256 : HCLK = SYSCLK / 256
498  *                     @arg RCM_AHB_DIV_512 : HCLK = SYSCLK / 512
499  *
500  * @retval    None
501  */
RCM_ConfigAHB(RCM_AHB_DIV_T AHBDiv)502 void RCM_ConfigAHB(RCM_AHB_DIV_T AHBDiv)
503 {
504     RCM->CFG_B.AHBPSC = AHBDiv;
505 }
506 
507 /*!
508  * @brief     Configures the APB1 clock prescaler.
509  *
510  * @param     APB1Div: Specifies the APB1 clock prescaler from the AHB clock.
511  *                     This parameter can be one of the following values:
512  *                     @arg RCM_APB_DIV_1  : PCLK1 = HCLK
513  *                     @arg RCM_APB_DIV_2  : PCLK1 = HCLK / 2
514  *                     @arg RCM_APB_DIV_4  : PCLK1 = HCLK / 4
515  *                     @arg RCM_APB_DIV_8  : PCLK1 = HCLK / 8
516  *                     @arg RCM_APB_DIV_16 : PCLK1 = HCLK / 16
517  *
518  * @retval    None
519  */
RCM_ConfigAPB1(RCM_APB_DIV_T APB1Div)520 void RCM_ConfigAPB1(RCM_APB_DIV_T APB1Div)
521 {
522     RCM->CFG_B.APB1PSC = APB1Div;
523 }
524 
525 /*!
526  * @brief     Configures the APB2 clock prescaler
527  *
528  * @param     APB2Div: Specifies the APB2 clock prescaler from the AHB clock.
529  *                     This parameter can be one of the following values:
530  *                     @arg RCM_APB_DIV_1  : PCLK2 = HCLK
531  *                     @arg RCM_APB_DIV_2  : PCLK2 = HCLK / 2
532  *                     @arg RCM_APB_DIV_4  : PCLK2 = HCLK / 4
533  *                     @arg RCM_APB_DIV_8  : PCLK2 = HCLK / 8
534  *                     @arg RCM_APB_DIV_16 : PCLK2 = HCLK / 16
535  *
536  * @retval    None
537  */
RCM_ConfigAPB2(RCM_APB_DIV_T APB2Div)538 void RCM_ConfigAPB2(RCM_APB_DIV_T APB2Div)
539 {
540     RCM->CFG_B.APB2PSC = APB2Div;
541 }
542 
543 #if defined(APM32F10X_CL)
544 /*!
545  * @brief     Configures the I2S2 clock source.
546  *
547  * @param     i2s2ClkSelect: specifies the I2S2 clock source.
548  *                           This parameter can be one of the following values:
549  *                           @arg RCM_I2S2CLK_SYSCLK     : I2S2CLK = System clock
550  *                           @arg RCM_I2S2CLK_DOUBLE_PLL3: I2S2CLK = Double PLL3 clock
551  *
552  * @retval    None
553  *
554  * @note      I2S2 clock source should be changed when I2S2 Clock is disabled.
555  */
RCM_ConfigI2S2CLK(RCM_I2S2CLK_T i2s2ClkSelect)556 void RCM_ConfigI2S2CLK(RCM_I2S2CLK_T i2s2ClkSelect)
557 {
558     RCM->CFG2_B.I2S2SRCSEL = i2s2ClkSelect;
559 }
560 
561 /*!
562  * @brief     Configures the I2S3 clock source.
563  *
564  * @param     i2s3ClkSelect: specifies the I2S3 clock source.
565  *                           This parameter can be one of the following values:
566  *                           @arg RCM_I2S3CLK_SYSCLK     : I2S3CLK = System clock
567  *                           @arg RCM_I2S3CLK_DOUBLE_PLL3: I2S3CLK = Double PLL3 clock
568  *
569  * @retval    None
570  *
571  * @note      I2S3 clock source should be changed when I2S3 Clock is disabled.
572  */
RCM_ConfigI2S3CLK(RCM_I2S2CLK_T i2s3ClkSelect)573 void RCM_ConfigI2S3CLK(RCM_I2S2CLK_T i2s3ClkSelect)
574 {
575     RCM->CFG2_B.I2S3SRCSEL = i2s3ClkSelect;
576 }
577 
578 /*!
579  * @brief     Configures the OTG FS clock prescaler
580  *
581  * @param     OTGDiv: Specifies the OTG FS clock prescaler from the PLL clock.
582  *                     This parameter can be one of the following values:
583  *                     @arg RCM_OTGFS_DIV_1_5 : OTGFSCLK = PLL clock /1.5
584  *                     @arg RCM_OTGFS_DIV_1   : OTGFSCLK = PLL clock
585  *
586  * @retval    None
587  */
RCM_ConfigOTGFSCLK(RCM_OTGFS_DIV_T OTGDiv)588 void RCM_ConfigOTGFSCLK(RCM_OTGFS_DIV_T OTGDiv)
589 {
590     RCM->CFG_B.OTGFSPSC = OTGDiv;
591 }
592 #else
593 /*!
594  * @brief     Configures the USB clock prescaler
595  *
596  * @param     USBDiv: Specifies the USB clock prescaler from the PLL clock.
597  *                     This parameter can be one of the following values:
598  *                     @arg RCM_USB_DIV_1_5 : USBCLK = PLL clock /1.5
599  *                     @arg RCM_USB_DIV_1   : USBCLK = PLL clock
600  *                     @arg RCM_USB_DIV_2   : USBCLK = PLL clock / 2
601  *                     @arg RCM_USB_DIV_2_5 : USBCLK = PLL clock / 2.5 (Only for High-density devices for APM32F103xx)
602  *
603  * @retval    None
604  */
RCM_ConfigUSBCLK(RCM_USB_DIV_T USBDiv)605 void RCM_ConfigUSBCLK(RCM_USB_DIV_T USBDiv)
606 {
607     RCM->CFG_B.USBDPSC = USBDiv;
608 }
609 
610 /*!
611  * @brief     Configures the FPU clock prescaler
612  *
613  * @param     FPUDiv: Specifies the FPU clock prescaler from the AHB clock.
614  *                     This parameter can be one of the following values:
615  *                     @arg RCM_FPU_DIV_1 : FPUCLK = HCLK
616  *                     @arg RCM_FPU_DIV_2 : FPUCLK = HCLK /2
617  *
618  * @retval    None
619  */
RCM_ConfigFPUCLK(RCM_FPU_DIV_T FPUDiv)620 void RCM_ConfigFPUCLK(RCM_FPU_DIV_T FPUDiv)
621 {
622     RCM->CFG_B.FPUPSC = FPUDiv;
623 }
624 #endif
625 
626 
627 /*!
628  * @brief     Configures the ADC clock prescaler
629  *
630  * @param     ADCDiv : Specifies the ADC clock prescaler from the APB2 clock.
631  *                     This parameter can be one of the following values:
632  *                     @arg RCM_PCLK2_DIV_2: ADCCLK = PCLK2 / 2
633  *                     @arg RCM_PCLK2_DIV_4: ADCCLK = PCLK2 / 4
634  *                     @arg RCM_PCLK2_DIV_6: ADCCLK = PCLK2 / 6
635  *                     @arg RCM_PCLK2_DIV_8: ADCCLK = PCLK2 / 8
636  *
637  * @retval    None
638  */
RCM_ConfigADCCLK(RCM_PCLK2_DIV_T ADCDiv)639 void RCM_ConfigADCCLK(RCM_PCLK2_DIV_T ADCDiv)
640 {
641     RCM->CFG_B.ADCPSC = ADCDiv;
642 }
643 
644 /*!
645  * @brief     Configures the RTC clock source
646  *
647  * @param     rtcClkSelect : specifies the RTC clock source.
648  *                           This parameter can be one of the following values:
649  *                           @arg RCM_RTCCLK_LSE        : RTCCLK = LSE clock
650  *                           @arg RCM_RTCCLK_LSI        : RTCCLK = LSI clock
651  *                           @arg RCM_RTCCLK_HSE_DIV_128: RTCCLK = HSE clock / 128
652  *
653  * @retval    None
654  *
655  * @note      Once the RTC clock is configured it can't be changed unless reset the Backup domain.
656  */
RCM_ConfigRTCCLK(RCM_RTCCLK_T rtcClkSelect)657 void RCM_ConfigRTCCLK(RCM_RTCCLK_T rtcClkSelect)
658 {
659     RCM->BDCTRL_B.RTCSRCSEL = rtcClkSelect;
660 }
661 
662 /*!
663  * @brief     Enable the RTC clock
664  *
665  * @param     None
666  *
667  * @retval    None
668  */
RCM_EnableRTCCLK(void)669 void RCM_EnableRTCCLK(void)
670 {
671     RCM->BDCTRL_B.RTCCLKEN = BIT_SET;
672 }
673 
674 /*!
675  * @brief     Disable the RTC clock
676  *
677  * @param     None
678  *
679  * @retval    None
680  */
RCM_DisableRTCCLK(void)681 void RCM_DisableRTCCLK(void)
682 {
683     RCM->BDCTRL_B.RTCCLKEN = BIT_RESET;
684 }
685 
686 /*!
687  * @brief     Read the frequency of SYSCLK
688  *
689  * @param     None
690  *
691  * @retval    Return the frequency of SYSCLK
692  */
RCM_ReadSYSCLKFreq(void)693 uint32_t RCM_ReadSYSCLKFreq(void)
694 {
695 #ifdef APM32F10X_CL
696     uint32_t sysClock, pllMull, pllSource, pll2Mull, pllPsc1, pllPsc2;
697 #else
698     uint32_t sysClock, pllMull, pllSource;
699 #endif
700 
701     /* get sys clock */
702     sysClock = RCM->CFG_B.SCLKSEL;
703 
704     switch (sysClock)
705     {
706         /* sys clock is HSI */
707         case RCM_SYSCLK_SEL_HSI:
708             sysClock = HSI_VALUE;
709             break;
710 
711         /* sys clock is HSE */
712         case RCM_SYSCLK_SEL_HSE:
713             sysClock = HSE_VALUE;
714             break;
715 
716         /* sys clock is PLL */
717         case RCM_SYSCLK_SEL_PLL:
718 #ifdef APM32F10X_CL
719             /* NOTE : PLL is the same as PLL1 */
720             pllSource = RCM->CFG_B.PLL1SRCSEL;
721 
722             /* PLL entry clock source is HSE */
723             if (pllSource)
724             {
725                 /* PLLPSC1 prescaler factor */
726                 pllPsc1 = (RCM->CFG2_B.PLLPSC1 + 1);
727 
728                 /* PLL entry clock source is PLL2 */
729                 if (RCM->CFG2_B.PLLPSC1SRC)
730                 {
731                     pll2Mull = (RCM->CFG2_B.PLL2MUL != 15) ? (RCM->CFG2_B.PLL2MUL + 2) : 20;
732                     pllPsc2 = RCM->CFG2_B.PLLPSC2 + 1;
733 
734                     pllSource = ((HSE_VALUE / pllPsc2) * pll2Mull) / pllPsc1;
735                 }
736                 /* PLL entry clock source is HSE */
737                 else
738                 {
739                     pllSource = HSE_VALUE / pllPsc1;
740                 }
741             }
742             /* PLL entry clock source is HSI/2 */
743             else
744             {
745                 pllSource = HSI_VALUE >> 1;
746             }
747 
748             pllMull = RCM->CFG_B.PLL1MULCFG;
749             if (pllMull == 13)
750             {
751                 /* For 6.5 multiplication factor */
752                 sysClock = pllSource * pllMull / 2;
753             }
754             else
755             {
756                 sysClock = pllSource * (pllMull + 2);
757             }
758 #else
759             pllMull = RCM->CFG_B.PLL1MULCFG + 2;
760             pllSource = RCM->CFG_B.PLL1SRCSEL;
761 
762             /* PLL entry clock source is HSE */
763             if (pllSource == BIT_SET)
764             {
765                 sysClock = HSE_VALUE * pllMull;
766 
767                 /* HSE clock divided by 2 */
768                 if (pllSource == RCM->CFG_B.PLLHSEPSC)
769                 {
770                     sysClock >>= 1;
771                 }
772             }
773             /* PLL entry clock source is HSI/2 */
774             else
775             {
776                 sysClock = (HSI_VALUE >> 1) * pllMull;
777             }
778 #endif
779             break;
780 
781         default:
782             sysClock  = HSI_VALUE;
783             break;
784     }
785 
786     return sysClock;
787 }
788 
789 /*!
790  * @brief     Read the frequency of HCLK(AHB)
791  *
792  * @param     None
793  *
794  * @retval    Return the frequency of HCLK
795  */
RCM_ReadHCLKFreq(void)796 uint32_t RCM_ReadHCLKFreq(void)
797 {
798     uint32_t divider;
799     uint32_t sysClk, hclk;
800     uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
801 
802     sysClk = RCM_ReadSYSCLKFreq();
803     divider = AHBPrescTable[RCM->CFG_B.AHBPSC];
804     hclk = sysClk >> divider;
805 
806     return hclk;
807 }
808 
809 /*!
810  * @brief     Read the frequency of PCLK1 And PCLK2
811  *
812  * @param     PCLK1 : Return the frequency of PCLK1
813  *
814  * @param     PCLK1 : Return the frequency of PCLK2
815  *
816  * @retval    None
817  */
RCM_ReadPCLKFreq(uint32_t * PCLK1,uint32_t * PCLK2)818 void RCM_ReadPCLKFreq(uint32_t* PCLK1, uint32_t* PCLK2)
819 {
820     uint32_t hclk, divider;
821     uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
822 
823     hclk = RCM_ReadHCLKFreq();
824 
825     if (PCLK1)
826     {
827         divider = APBPrescTable[RCM->CFG_B.APB1PSC];
828         *PCLK1 = hclk >> divider;
829     }
830 
831     if (PCLK2)
832     {
833         divider = APBPrescTable[RCM->CFG_B.APB2PSC];
834         *PCLK2 = hclk >> divider;
835     }
836 }
837 
838 /*!
839  * @brief     Read the frequency of ADCCLK
840  *
841  * @param     None
842  *
843  * @retval    Return the frequency of ADCCLK
844  */
RCM_ReadADCCLKFreq(void)845 uint32_t RCM_ReadADCCLKFreq(void)
846 {
847     uint32_t adcClk, pclk2, divider;
848     uint8_t ADCPrescTable[4] = {2, 4, 6, 8};
849 
850     RCM_ReadPCLKFreq(NULL, &pclk2);
851 
852     /* Get ADC CLK */
853     divider = ADCPrescTable[RCM->CFG_B.ADCPSC];
854     adcClk = pclk2 / divider;
855 
856     return adcClk;
857 }
858 
859 /*!
860  * @brief    Enable AHB peripheral clock.
861  *
862  * @param    AHBPeriph : Enable the specifies clock of AHB peripheral.
863  *                       This parameter can be any combination of the following values:
864  *                       @arg RCM_AHB_PERIPH_DMA1       : Enable DMA1 clock
865  *                       @arg RCM_AHB_PERIPH_DMA2       : Enable DMA2 clock (Only for High-density devices for APM32F103xx)
866  *                       @arg RCM_AHB_PERIPH_SRAM       : Enable SRAM clock
867  *                       @arg RCM_AHB_PERIPH_FPU        : Enable FPU clock
868  *                       @arg RCM_AHB_PERIPH_FMC        : Enable FMC clock
869  *                       @arg RCM_AHB_PERIPH_QSPI       : Enable QSPI clock
870  *                       @arg RCM_AHB_PERIPH_CRC        : Enable CRC clock
871  *                       @arg RCM_AHB_PERIPH_EMMC       : Enable EMMC clock (Only for High-density devices for APM32F103xx)
872  *                       @arg RCM_AHB_PERIPH_SDIO       : Enable SDIO clock (Only for High-density devices for APM32F103xx)
873  *                       @arg RCM_AHB_PERIPH_OTG_FS     : Enable OTG FS clock (Only for APM32F105xx or APM32F107xx)
874  *                       @arg RCM_AHB_PERIPH_ETH_MAC    : Enable Ethernet MAC clock (Only for APM32F105xx or APM32F107xx)
875  *                       @arg RCM_AHB_PERIPH_ETH_MAC_TX : Enable Ethernet MAC TX clock (Only for APM32F105xx or APM32F107xx)
876  *                       @arg RCM_AHB_PERIPH_ETH_MAC_RX : Enable Ethernet MAC RX clock (Only for APM32F105xx or APM32F107xx)
877  *
878  * @retval   None
879  */
RCM_EnableAHBPeriphClock(uint32_t AHBPeriph)880 void RCM_EnableAHBPeriphClock(uint32_t AHBPeriph)
881 {
882     RCM->AHBCLKEN |= AHBPeriph;
883 }
884 
885 /*!
886  * @brief    Disable AHB peripheral clock.
887  *
888  * @param    AHBPeriph : Enable the specifies clock of AHB peripheral.
889  *                       This parameter can be any combination of the following values:
890  *                       @arg RCM_AHB_PERIPH_DMA1       : Disable DMA1 clock
891  *                       @arg RCM_AHB_PERIPH_DMA2       : Disable DMA2 clock (Only for High-density devices for APM32F103xx)
892  *                       @arg RCM_AHB_PERIPH_SRAM       : Disable SRAM clock
893  *                       @arg RCM_AHB_PERIPH_FPU        : Disable FPU clock
894  *                       @arg RCM_AHB_PERIPH_FMC        : Disable FMC clock
895  *                       @arg RCM_AHB_PERIPH_QSPI       : Disable QSPI clock
896  *                       @arg RCM_AHB_PERIPH_CRC        : Disable CRC clock
897  *                       @arg RCM_AHB_PERIPH_EMMC       : Disable EMMC clock (Only for High-density devices for APM32F103xx)
898  *                       @arg RCM_AHB_PERIPH_SDIO       : Disable SDIO clock (Only for High-density devices for APM32F103xx)
899  *                       @arg RCM_AHB_PERIPH_OTG_FS     : Disable OTG FS clock (Only for APM32F105xx or APM32F107xx)
900  *                       @arg RCM_AHB_PERIPH_ETH_MAC    : Disable Ethernet MAC clock (Only for APM32F105xx or APM32F107xx)
901  *                       @arg RCM_AHB_PERIPH_ETH_MAC_TX : Disable Ethernet MAC TX clock (Only for APM32F105xx or APM32F107xx)
902  *                       @arg RCM_AHB_PERIPH_ETH_MAC_RX : Disable Ethernet MAC RX clock (Only for APM32F105xx or APM32F107xx)
903  *
904  * @retval   None
905  */
RCM_DisableAHBPeriphClock(uint32_t AHBPeriph)906 void RCM_DisableAHBPeriphClock(uint32_t AHBPeriph)
907 {
908     RCM->AHBCLKEN &= (uint32_t)~AHBPeriph;
909 }
910 
911 /*!
912  * @brief    Enable the High Speed APB (APB2) peripheral clock
913  *
914  * @param    APB2Periph : Enable specifies clock of the APB2 peripheral.
915  *                        This parameter can be any combination of the following values:
916  *                        @arg RCM_APB2_PERIPH_AFIO   : Enable AFIO clock
917  *                        @arg RCM_APB2_PERIPH_GPIOA  : Enable GPIOA clock
918  *                        @arg RCM_APB2_PERIPH_GPIOB  : Enable GPIOB clock
919  *                        @arg RCM_APB2_PERIPH_GPIOC  : Enable GPIOC clock
920  *                        @arg RCM_APB2_PERIPH_GPIOD  : Enable GPIOD clock
921  *                        @arg RCM_APB2_PERIPH_GPIOE  : Enable GPIOE clock
922  *                        @arg RCM_APB2_PERIPH_GPIOF  : Enable GPIOF clock (Only for High-density devices for APM32F103xx)
923  *                        @arg RCM_APB2_PERIPH_GPIOG  : Enable GPIOG clock (Only for High-density devices for APM32F103xx)
924  *                        @arg RCM_APB2_PERIPH_ADC1   : Enable ADC1 clock
925  *                        @arg RCM_APB2_PERIPH_ADC2   : Enable ADC2 clock
926  *                        @arg RCM_APB2_PERIPH_TMR1   : Enable TMR1 clock
927  *                        @arg RCM_APB2_PERIPH_SPI1   : Enable SPI1 clock
928  *                        @arg RCM_APB2_PERIPH_TMR8   : Enable TMR8 clock (Only for High-density devices for APM32F103xx)
929  *                        @arg RCM_APB2_PERIPH_USART1 : Enable USART1 clock
930  *                        @arg RCM_APB2_PERIPH_ADC3   : Enable ADC3 clock (Only for High-density devices for APM32F103xx)
931  *
932  * @retval   None
933  */
RCM_EnableAPB2PeriphClock(uint32_t APB2Periph)934 void RCM_EnableAPB2PeriphClock(uint32_t APB2Periph)
935 {
936     RCM->APB2CLKEN |= APB2Periph;
937 }
938 
939 /*!
940  * @brief    Disable the High Speed APB (APB2) peripheral clock
941  *
942  * @param    APB2Periph : Disable specifies clock of the APB2 peripheral.
943  *                        This parameter can be any combination of the following values:
944  *                        @arg RCM_APB2_PERIPH_AFIO   : Disable AFIO clock
945  *                        @arg RCM_APB2_PERIPH_GPIOA  : Disable GPIOA clock
946  *                        @arg RCM_APB2_PERIPH_GPIOB  : Disable GPIOB clock
947  *                        @arg RCM_APB2_PERIPH_GPIOC  : Disable GPIOC clock
948  *                        @arg RCM_APB2_PERIPH_GPIOD  : Disable GPIOD clock
949  *                        @arg RCM_APB2_PERIPH_GPIOE  : Disable GPIOE clock
950  *                        @arg RCM_APB2_PERIPH_GPIOF  : Disable GPIOF clock (Only for High-density devices for APM32F103xx)
951  *                        @arg RCM_APB2_PERIPH_GPIOG  : Disable GPIOG clock (Only for High-density devices for APM32F103xx)
952  *                        @arg RCM_APB2_PERIPH_ADC1   : Disable ADC1 clock
953  *                        @arg RCM_APB2_PERIPH_ADC2   : Disable ADC2 clock
954  *                        @arg RCM_APB2_PERIPH_TMR1   : Disable TMR1 clock
955  *                        @arg RCM_APB2_PERIPH_SPI1   : Disable SPI1 clock
956  *                        @arg RCM_APB2_PERIPH_TMR8   : Disable TMR8 clock (Only for High-density devices for APM32F103xx)
957  *                        @arg RCM_APB2_PERIPH_USART1 : Disable USART1 clock
958  *                        @arg RCM_APB2_PERIPH_ADC3   : Disable ADC3 clock (Only for High-density devices for APM32F103xx)
959  *
960  * @retval   None
961  */
RCM_DisableAPB2PeriphClock(uint32_t APB2Periph)962 void RCM_DisableAPB2PeriphClock(uint32_t APB2Periph)
963 {
964     RCM->APB2CLKEN &= (uint32_t)~APB2Periph;
965 }
966 
967 /*!
968  * @brief    Enable the Low Speed APB (APB1) peripheral clock
969  *
970  * @param    APB1Periph : Enable specifies clock of the APB1 peripheral.
971  *                        This parameter can be any combination of the following values:
972  *                        @arg RCM_APB1_PERIPH_TMR2   : Enable TMR2 clock
973  *                        @arg RCM_APB1_PERIPH_TMR3   : Enable TMR3 clock
974  *                        @arg RCM_APB1_PERIPH_TMR4   : Enable TMR4 clock
975  *                        @arg RCM_APB1_PERIPH_TMR5   : Enable TMR5 clock (Only for High-density devices for APM32F103xx)
976  *                        @arg RCM_APB1_PERIPH_TMR6   : Enable TMR6 clock (Only for High-density devices for APM32F103xx)
977  *                        @arg RCM_APB1_PERIPH_TMR7   : Enable TMR7 clock (Only for High-density devices for APM32F103xx)
978  *                        @arg RCM_APB1_PERIPH_WWDT   : Enable WWDT clock
979  *                        @arg RCM_APB1_PERIPH_SPI2   : Enable SPI2 clock
980  *                        @arg RCM_APB1_PERIPH_SPI3   : Enable SPI3 clock (Only for High-density devices for APM32F103xx)
981  *                        @arg RCM_APB1_PERIPH_USART2 : Enable USART2 clock
982  *                        @arg RCM_APB1_PERIPH_USART3 : Enable USART3 clock
983  *                        @arg RCM_APB1_PERIPH_UART4  : Enable UART4 clock (Only for High-density devices for APM32F103xx)
984  *                        @arg RCM_APB1_PERIPH_UART5  : Enable UART5 clock (Only for High-density devices for APM32F103xx)
985  *                        @arg RCM_APB1_PERIPH_I2C1   : Enable I2C1 clock
986  *                        @arg RCM_APB1_PERIPH_I2C2   : Enable I2C2 clock
987  *                        @arg RCM_APB1_PERIPH_USB    : Enable USB clock
988  *                        @arg RCM_APB1_PERIPH_CAN1   : Enable CAN1 clock
989  *                        @arg RCM_APB1_PERIPH_CAN2   : Enable CAN2 clock (only for APM32F103xC device)
990  *                        @arg RCM_APB1_PERIPH_BAKR   : Enable BAKR clock
991  *                        @arg RCM_APB1_PERIPH_PMU    : Enable PMU clock
992  *                        @arg RCM_APB1_PERIPH_DAC    : Enable DAC clock (Only for High-density devices for APM32F103xx)
993  *
994  * @retval   None
995  */
RCM_EnableAPB1PeriphClock(uint32_t APB1Periph)996 void RCM_EnableAPB1PeriphClock(uint32_t APB1Periph)
997 {
998     RCM->APB1CLKEN |= APB1Periph;
999 }
1000 
1001 /*!
1002  * @brief    Disable the Low Speed APB (APB1) peripheral clock
1003  *
1004  * @param    APB1Periph : Disable specifies clock of the APB1 peripheral.
1005  *                        This parameter can be any combination of the following values:
1006  *                        @arg RCM_APB1_PERIPH_TMR2   : Disable TMR2 clock
1007  *                        @arg RCM_APB1_PERIPH_TMR3   : Disable TMR3 clock
1008  *                        @arg RCM_APB1_PERIPH_TMR4   : Disable TMR4 clock
1009  *                        @arg RCM_APB1_PERIPH_TMR5   : Disable TMR5 clock (Only for High-density devices for APM32F103xx)
1010  *                        @arg RCM_APB1_PERIPH_TMR6   : Disable TMR6 clock (Only for High-density devices for APM32F103xx)
1011  *                        @arg RCM_APB1_PERIPH_TMR7   : Disable TMR7 clock (Only for High-density devices for APM32F103xx)
1012  *                        @arg RCM_APB1_PERIPH_WWDT   : Disable WWDT clock
1013  *                        @arg RCM_APB1_PERIPH_SPI2   : Disable SPI2 clock
1014  *                        @arg RCM_APB1_PERIPH_SPI3   : Disable SPI3 clock (Only for High-density devices for APM32F103xx)
1015  *                        @arg RCM_APB1_PERIPH_USART2 : Disable USART2 clock
1016  *                        @arg RCM_APB1_PERIPH_USART3 : Disable USART3 clock
1017  *                        @arg RCM_APB1_PERIPH_UART4  : Disable UART4 clock (Only for High-density devices for APM32F103xx)
1018  *                        @arg RCM_APB1_PERIPH_UART5  : Disable UART5 clock (Only for High-density devices for APM32F103xx)
1019  *                        @arg RCM_APB1_PERIPH_I2C1   : Disable I2C1 clock
1020  *                        @arg RCM_APB1_PERIPH_I2C2   : Disable I2C2 clock
1021  *                        @arg RCM_APB1_PERIPH_USB    : Disable USB clock
1022  *                        @arg RCM_APB1_PERIPH_CAN1   : Disable CAN1 clock
1023  *                        @arg RCM_APB1_PERIPH_CAN2   : Disable CAN2 clock (only for APM32F103xC device)
1024  *                        @arg RCM_APB1_PERIPH_BAKR   : Disable BAKR clock
1025  *                        @arg RCM_APB1_PERIPH_PMU    : Disable PMU clock
1026  *                        @arg RCM_APB1_PERIPH_DAC    : Disable DAC clock (Only for High-density devices for APM32F103xx)
1027  *
1028  * @retval   None
1029  */
RCM_DisableAPB1PeriphClock(uint32_t APB1Periph)1030 void RCM_DisableAPB1PeriphClock(uint32_t APB1Periph)
1031 {
1032     RCM->APB1CLKEN &= (uint32_t)~APB1Periph;
1033 }
1034 
1035 #if defined(APM32F10X_CL)
1036 /*!
1037  * @brief    Enable AHB peripheral reset
1038  *
1039  * @param    AHBPeriph : Enable specifies AHB peripheral reset.
1040  *                       This parameter can be any combination of the following values:
1041  *                       @arg RCM_AHB_PERIPH_OTG_FS  : Enable OTG FS reset
1042  *                       @arg RCM_AHB_PERIPH_ETH_MAC : Enable ETH MAC reset *
1043  * @retval   None
1044  */
RCM_EnableAHBPeriphReset(uint32_t AHBPeriph)1045 void RCM_EnableAHBPeriphReset(uint32_t AHBPeriph)
1046 {
1047     RCM->AHBRST |= AHBPeriph;
1048 }
1049 
1050 /*!
1051  * @brief    Disable AHB peripheral reset
1052  *
1053  * @param    AHBPeriph : Disable specifies AHB peripheral reset.
1054  *                       This parameter can be any combination of the following values:
1055  *                       @arg RCM_AHB_PERIPH_OTG_FS  : Disable OTG FS reset
1056  *                       @arg RCM_AHB_PERIPH_ETH_MAC : Disable ETH MAC reset *
1057  * @retval   None
1058  */
RCM_DisableAHBPeriphReset(uint32_t AHBPeriph)1059 void RCM_DisableAHBPeriphReset(uint32_t AHBPeriph)
1060 {
1061     RCM->AHBRST &= (uint32_t)~AHBPeriph;
1062 }
1063 #endif
1064 
1065 /*!
1066  * @brief    Enable High Speed APB (APB2) peripheral reset
1067  *
1068  * @param    APB2Periph : Enable specifies APB2 peripheral reset.
1069  *                        This parameter can be any combination of the following values:
1070  *                        @arg RCM_APB2_PERIPH_AFIO   : Enable AFIO reset
1071  *                        @arg RCM_APB2_PERIPH_GPIOA  : Enable GPIOA reset
1072  *                        @arg RCM_APB2_PERIPH_GPIOB  : Enable GPIOB reset
1073  *                        @arg RCM_APB2_PERIPH_GPIOC  : Enable GPIOC reset
1074  *                        @arg RCM_APB2_PERIPH_GPIOD  : Enable GPIOD reset
1075  *                        @arg RCM_APB2_PERIPH_GPIOE  : Enable GPIOE reset
1076  *                        @arg RCM_APB2_PERIPH_GPIOF  : Enable GPIOF reset (Only for High-density devices for APM32F103xx)
1077  *                        @arg RCM_APB2_PERIPH_GPIOG  : Enable GPIOG reset (Only for High-density devices for APM32F103xx)
1078  *                        @arg RCM_APB2_PERIPH_ADC1   : Enable ADC1 reset
1079  *                        @arg RCM_APB2_PERIPH_ADC2   : Enable ADC2 reset
1080  *                        @arg RCM_APB2_PERIPH_TMR1   : Enable TMR1 reset
1081  *                        @arg RCM_APB2_PERIPH_SPI1   : Enable SPI1 reset
1082  *                        @arg RCM_APB2_PERIPH_TMR8   : Enable TMR8 reset (Only for High-density devices for APM32F103xx)
1083  *                        @arg RCM_APB2_PERIPH_USART1 : Enable USART1 reset
1084  *                        @arg RCM_APB2_PERIPH_ADC3   : Enable ADC3 reset (Only for High-density devices for APM32F103xx)
1085  *
1086  * @retval   None
1087  */
RCM_EnableAPB2PeriphReset(uint32_t APB2Periph)1088 void RCM_EnableAPB2PeriphReset(uint32_t APB2Periph)
1089 {
1090     RCM->APB2RST |= APB2Periph;
1091 }
1092 
1093 /*!
1094  * @brief    Disable High Speed APB (APB2) peripheral reset
1095  *
1096  * @param    APB2Periph : Disable specifies APB2 peripheral reset.
1097  *                        This parameter can be any combination of the following values:
1098  *                        @arg RCM_APB2_PERIPH_AFIO   : Disable AFIO reset
1099  *                        @arg RCM_APB2_PERIPH_GPIOA  : Disable GPIOA reset
1100  *                        @arg RCM_APB2_PERIPH_GPIOB  : Disable GPIOB reset
1101  *                        @arg RCM_APB2_PERIPH_GPIOC  : Disable GPIOC reset
1102  *                        @arg RCM_APB2_PERIPH_GPIOD  : Disable GPIOD reset
1103  *                        @arg RCM_APB2_PERIPH_GPIOE  : Disable GPIOE reset
1104  *                        @arg RCM_APB2_PERIPH_GPIOF  : Disable GPIOF reset (Only for High-density devices for APM32F103xx)
1105  *                        @arg RCM_APB2_PERIPH_GPIOG  : Disable GPIOG reset (Only for High-density devices for APM32F103xx)
1106  *                        @arg RCM_APB2_PERIPH_ADC1   : Disable ADC1 reset
1107  *                        @arg RCM_APB2_PERIPH_ADC2   : Disable ADC2 reset
1108  *                        @arg RCM_APB2_PERIPH_TMR1   : Disable TMR1 reset
1109  *                        @arg RCM_APB2_PERIPH_SPI1   : Disable SPI1 reset
1110  *                        @arg RCM_APB2_PERIPH_TMR8   : Disable TMR8 reset (Only for High-density devices for APM32F103xx)
1111  *                        @arg RCM_APB2_PERIPH_USART1 : Disable USART1 reset
1112  *                        @arg RCM_APB2_PERIPH_ADC3   : Disable ADC3 reset (Only for High-density devices for APM32F103xx)
1113  *
1114  * @retval   None
1115  */
RCM_DisableAPB2PeriphReset(uint32_t APB2Periph)1116 void RCM_DisableAPB2PeriphReset(uint32_t APB2Periph)
1117 {
1118     RCM->APB2RST &= (uint32_t)~APB2Periph;
1119 }
1120 
1121 /*!
1122  * @brief    Enable Low Speed APB (APB1) peripheral reset
1123  *
1124  * @param    APB1Periph : Enable specifies APB1 peripheral reset.
1125  *                        This parameter can be any combination of the following values:
1126  *                        @arg RCM_APB1_PERIPH_TMR2   : Enable TMR2 reset
1127  *                        @arg RCM_APB1_PERIPH_TMR3   : Enable TMR3 reset
1128  *                        @arg RCM_APB1_PERIPH_TMR4   : Enable TMR4 reset
1129  *                        @arg RCM_APB1_PERIPH_TMR5   : Enable TMR5 reset (Only for High-density devices for APM32F103xx)
1130  *                        @arg RCM_APB1_PERIPH_TMR6   : Enable TMR6 reset (Only for High-density devices for APM32F103xx)
1131  *                        @arg RCM_APB1_PERIPH_TMR7   : Enable TMR7 reset (Only for High-density devices for APM32F103xx)
1132  *                        @arg RCM_APB1_PERIPH_WWDT   : Enable WWDT reset
1133  *                        @arg RCM_APB1_PERIPH_SPI2   : Enable SPI2 reset
1134  *                        @arg RCM_APB1_PERIPH_SPI3   : Enable SPI3 reset (Only for High-density devices for APM32F103xx)
1135  *                        @arg RCM_APB1_PERIPH_USART2 : Enable USART2 reset
1136  *                        @arg RCM_APB1_PERIPH_USART3 : Enable USART3 reset
1137  *                        @arg RCM_APB1_PERIPH_UART4  : Enable UART4 reset (Only for High-density devices for APM32F103xx)
1138  *                        @arg RCM_APB1_PERIPH_UART5  : Enable UART5 reset (Only for High-density devices for APM32F103xx)
1139  *                        @arg RCM_APB1_PERIPH_I2C1   : Enable I2C1 reset
1140  *                        @arg RCM_APB1_PERIPH_I2C2   : Enable I2C2 reset
1141  *                        @arg RCM_APB1_PERIPH_USB    : Enable USB reset
1142  *                        @arg RCM_APB1_PERIPH_CAN1   : Enable CAN1 reset
1143  *                        @arg RCM_APB1_PERIPH_CAN2   : Enable CAN2 reset (only for APM32F103xC device)
1144  *                        @arg RCM_APB1_PERIPH_BAKR   : Enable BAKR reset
1145  *                        @arg RCM_APB1_PERIPH_PMU    : Enable PMU reset
1146  *                        @arg RCM_APB1_PERIPH_DAC    : Enable DAC reset
1147  *
1148  * @retval   None
1149  */
RCM_EnableAPB1PeriphReset(uint32_t APB1Periph)1150 void RCM_EnableAPB1PeriphReset(uint32_t APB1Periph)
1151 {
1152     RCM->APB1RST |= APB1Periph;
1153 }
1154 
1155 /*!
1156  * @brief    Disable Low Speed APB (APB1) peripheral reset
1157  *
1158  * @param    APB1Periph : Disable specifies APB1 peripheral reset.
1159  *                        This parameter can be any combination of the following values:
1160  *                        @arg RCM_APB1_PERIPH_TMR2   : Disable TMR2 reset
1161  *                        @arg RCM_APB1_PERIPH_TMR3   : Disable TMR3 reset
1162  *                        @arg RCM_APB1_PERIPH_TMR4   : Disable TMR4 reset
1163  *                        @arg RCM_APB1_PERIPH_TMR5   : Disable TMR5 reset (Only for High-density devices for APM32F103xx)
1164  *                        @arg RCM_APB1_PERIPH_TMR6   : Disable TMR6 reset (Only for High-density devices for APM32F103xx)
1165  *                        @arg RCM_APB1_PERIPH_TMR7   : Disable TMR7 reset (Only for High-density devices for APM32F103xx)
1166  *                        @arg RCM_APB1_PERIPH_WWDT   : Disable WWDT reset
1167  *                        @arg RCM_APB1_PERIPH_SPI2   : Disable SPI2 reset
1168  *                        @arg RCM_APB1_PERIPH_SPI3   : Disable SPI3 reset (Only for High-density devices for APM32F103xx)
1169  *                        @arg RCM_APB1_PERIPH_USART2 : Disable USART2 reset
1170  *                        @arg RCM_APB1_PERIPH_USART3 : Disable USART3 reset
1171  *                        @arg RCM_APB1_PERIPH_UART4  : Disable UART4 reset (Only for High-density devices for APM32F103xx)
1172  *                        @arg RCM_APB1_PERIPH_UART5  : Disable UART5 reset (Only for High-density devices for APM32F103xx)
1173  *                        @arg RCM_APB1_PERIPH_I2C1   : Disable I2C1 reset
1174  *                        @arg RCM_APB1_PERIPH_I2C2   : Disable I2C2 reset
1175  *                        @arg RCM_APB1_PERIPH_USB    : Disable USB reset
1176  *                        @arg RCM_APB1_PERIPH_CAN1   : Disable CAN1 reset
1177  *                        @arg RCM_APB1_PERIPH_CAN2   : Disable CAN2 reset (only for APM32F103xC device)
1178  *                        @arg RCM_APB1_PERIPH_BAKR   : Disable BAKR reset
1179  *                        @arg RCM_APB1_PERIPH_PMU    : Disable PMU reset
1180  *                        @arg RCM_APB1_PERIPH_DAC    : Disable DAC reset
1181  *
1182  * @retval   None
1183  */
RCM_DisableAPB1PeriphReset(uint32_t APB1Periph)1184 void RCM_DisableAPB1PeriphReset(uint32_t APB1Periph)
1185 {
1186     RCM->APB1RST &= (uint32_t)~APB1Periph;
1187 }
1188 
1189 /*!
1190  * @brief     Enable the Backup domain reset
1191  *
1192  * @param     None
1193  *
1194  * @retval    None
1195  *
1196  */
RCM_EnableBackupReset(void)1197 void RCM_EnableBackupReset(void)
1198 {
1199     RCM->BDCTRL_B.BDRST = BIT_SET;
1200 }
1201 
1202 /*!
1203  * @brief     Disable the Backup domain reset
1204  *
1205  * @param     None
1206  *
1207  * @retval    None
1208  */
RCM_DisableBackupReset(void)1209 void RCM_DisableBackupReset(void)
1210 {
1211     RCM->BDCTRL_B.BDRST = BIT_RESET;
1212 }
1213 
1214 /*!
1215  * @brief     Enable RCM interrupts
1216  *
1217  * @param     interrupt : Enable specifies RCM interrupt sources.
1218  *                        This parameter can be any combination of the following values:
1219  *                        @arg RCM_INT_LSIRDY : LSI ready interrupt
1220  *                        @arg RCM_INT_LSERDY : LSE ready interrupt
1221  *                        @arg RCM_INT_HSIRDY : HSI ready interrupt
1222  *                        @arg RCM_INT_HSERDY : HSE ready interrupt
1223  *                        @arg RCM_INT_PLLRDY : PLL ready interrupt
1224  *                        @arg RCM_INT_PLL2RDY: PLL2 ready interrupt
1225  *                        @arg RCM_INT_PLL3RDY: PLL3 ready interrupt
1226  *
1227  * @retval    None
1228  */
RCM_EnableInterrupt(uint32_t interrupt)1229 void RCM_EnableInterrupt(uint32_t interrupt)
1230 {
1231     uint32_t temp;
1232 
1233     temp = interrupt << 8;
1234 
1235     RCM->INT |= temp;
1236 }
1237 
1238 /*!
1239  * @brief     Disable RCM interrupts
1240  *
1241  * @param     interrupt : Disable specifies RCM interrupt sources.
1242  *                        This parameter can be any combination of the following values:
1243  *                        @arg RCM_INT_LSIRDY : LSI ready interrupt
1244  *                        @arg RCM_INT_LSERDY : LSE ready interrupt
1245  *                        @arg RCM_INT_HSIRDY : HSI ready interrupt
1246  *                        @arg RCM_INT_HSERDY : HSE ready interrupt
1247  *                        @arg RCM_INT_PLLRDY : PLL ready interrupt
1248  *
1249  * @retval    None
1250  */
RCM_DisableInterrupt(uint32_t interrupt)1251 void RCM_DisableInterrupt(uint32_t interrupt)
1252 {
1253     uint32_t temp;
1254 
1255     temp = interrupt << 8;
1256 
1257     RCM->INT &= (uint32_t)~temp;
1258 }
1259 
1260 /*!
1261  * @brief     Read the specified RCM flag status
1262  *
1263  * @param     flag : Return specifies the flag status.
1264  *                   This parameter can be one of the following values:
1265  *                   @arg RCM_FLAG_HSIRDY  : HSI ready flag
1266  *                   @arg RCM_FLAG_HSERDY  : HSE ready flag
1267  *                   @arg RCM_FLAG_PLLRDY  : PLL ready flag
1268  *                   @arg RCM_FLAG_PLL2RDY : PLL2 ready flag (Only for APM32F105xx or APM32F107xx)
1269  *                   @arg RCM_FLAG_PLL3RDY : PLL3 ready flag (Only for APM32F105xx or APM32F107xx)
1270  *                   @arg RCM_FLAG_LSERDY  : LSE ready flag
1271  *                   @arg RCM_FLAG_LSIRDY  : LSI ready flag
1272  *                   @arg RCM_FLAG_PINRST  : NRST PIN Reset Occur Flag
1273  *                   @arg RCM_FLAG_PORRST  : POR/PDR Reset Occur Flag
1274  *                   @arg RCM_FLAG_SWRST   : Software Reset Occur Flag
1275  *                   @arg RCM_FLAG_IWDTRST : Independent Watchdog Reset Occur Flag
1276  *                   @arg RCM_FLAG_WWDTRST : Window Watchdog Reset Occur Flag
1277  *                   @arg RCM_FLAG_LPRRST  : Low Power Reset Occur Flag
1278  *
1279  * @retval    The new state of flag (SET or RESET)
1280  */
RCM_ReadStatusFlag(RCM_FLAG_T flag)1281 uint8_t RCM_ReadStatusFlag(RCM_FLAG_T flag)
1282 {
1283     uint32_t reg, bit;
1284 
1285     bit = (uint32_t)(1 << (flag & 0xff));
1286 
1287     reg = (flag >> 8) & 0xff;
1288 
1289     switch (reg)
1290     {
1291         case 0:
1292             reg = RCM->CTRL;
1293             break;
1294 
1295         case 1:
1296             reg = RCM->BDCTRL;
1297             break;
1298 
1299         case 2:
1300             reg = RCM->CSTS;
1301             break;
1302 
1303         default:
1304             break;
1305     }
1306 
1307     if (reg & bit)
1308     {
1309         return SET;
1310     }
1311 
1312     return RESET;
1313 }
1314 
1315 /*!
1316  * @brief     Clear all the RCM reset flags
1317  *
1318  * @param     None
1319  *
1320  * @retval    None
1321  *
1322  * @note      The reset flags are:
1323  *            RCM_FLAG_PINRST, RCM_FLAG_PWRST, RCM_FLAG_SWRST
1324  *            RCM_FLAG_IWDTRST, RCM_FLAG_WWDTRST, RCM_FLAG_LPRRST
1325  */
RCM_ClearStatusFlag(void)1326 void RCM_ClearStatusFlag(void)
1327 {
1328     RCM->CSTS_B.RSTFLGCLR = BIT_SET;
1329 }
1330 
1331 /*!
1332  * @brief     Read the specified RCM interrupt Flag
1333  *
1334  * @param     flag : Reads specifies RCM interrupt flag.
1335  *                   This parameter can be one of the following values:
1336  *                   @arg RCM_INT_LSIRDY : LSI ready interrupt flag
1337  *                   @arg RCM_INT_LSERDY : LSE ready interrupt flag
1338  *                   @arg RCM_INT_HSIRDY : HSI ready interrupt flag
1339  *                   @arg RCM_INT_HSERDY : HSE ready interrupt flag
1340  *                   @arg RCM_INT_PLLRDY : PLL ready interrupt flag
1341  *                   @arg RCM_INT_PLL2RDY: PLL2 ready interrupt flag
1342  *                   @arg RCM_INT_PLL3RDY: PLL3 ready interrupt flag
1343  *                   @arg RCM_INT_CSS    : Clock Security System interrupt flag
1344  *
1345  * @retval    The new state of intFlag (SET or RESET)
1346  */
RCM_ReadIntFlag(RCM_INT_T flag)1347 uint8_t RCM_ReadIntFlag(RCM_INT_T flag)
1348 {
1349     return (RCM->INT& flag) ? SET : RESET;
1350 }
1351 
1352 /*!
1353  * @brief     Clear the interrupt flag
1354  *
1355  * @param     flag : Clear specifies interrupt flag.
1356  *                   @arg RCM_INT_LSIRDY : Clear LSI ready interrupt flag
1357  *                   @arg RCM_INT_LSERDY : Clear LSE ready interrupt flag
1358  *                   @arg RCM_INT_HSIRDY : Clear HSI ready interrupt flag
1359  *                   @arg RCM_INT_HSERDY : Clear HSE ready interrupt flag
1360  *                   @arg RCM_INT_PLLRDY : Clear PLL ready interrupt flag
1361  *                   @arg RCM_INT_PLL2RDY: Clear PLL2 ready interrupt flag
1362  *                   @arg RCM_INT_PLL3RDY: Clear PLL3 ready interrupt flag
1363  *                   @arg RCM_INT_CSS    : Clear Clock Security System interrupt flag
1364  *
1365  * @retval    None
1366  */
RCM_ClearIntFlag(uint32_t flag)1367 void RCM_ClearIntFlag(uint32_t flag)
1368 {
1369     uint32_t temp;
1370 
1371     temp = flag << 16;
1372     RCM->INT |= temp;
1373 }
1374 
1375 /**@} end of group RCM_Functions */
1376 /**@} end of group RCM_Driver */
1377 /**@} end of group APM32F10x_StdPeriphDriver */
1378