1 /********************************** (C) COPYRIGHT *******************************
2  * File Name          : ch32v10x_rcc.c
3  * Author             : WCH
4  * Version            : V1.0.0
5  * Date               : 2020/04/30
6  * Description        : This file provides all the RCC firmware functions.
7  * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
8  * SPDX-License-Identifier: Apache-2.0
9  *******************************************************************************/
10 #include "ch32v10x_rcc.h"
11 
12 /* RCC registers bit address in the alias region */
13 #define RCC_OFFSET                 (RCC_BASE - PERIPH_BASE)
14 
15 /* BDCTLR Register */
16 #define BDCTLR_OFFSET              (RCC_OFFSET + 0x20)
17 
18 /* RCC registers bit mask */
19 
20 /* CTLR register bit mask */
21 #define CTLR_HSEBYP_Reset          ((uint32_t)0xFFFBFFFF)
22 #define CTLR_HSEBYP_Set            ((uint32_t)0x00040000)
23 #define CTLR_HSEON_Reset           ((uint32_t)0xFFFEFFFF)
24 #define CTLR_HSEON_Set             ((uint32_t)0x00010000)
25 #define CTLR_HSITRIM_Mask          ((uint32_t)0xFFFFFF07)
26 
27 #define CFGR0_PLL_Mask             ((uint32_t)0xFFC0FFFF)
28 #define CFGR0_PLLMull_Mask         ((uint32_t)0x003C0000)
29 #define CFGR0_PLLSRC_Mask          ((uint32_t)0x00010000)
30 #define CFGR0_PLLXTPRE_Mask        ((uint32_t)0x00020000)
31 #define CFGR0_SWS_Mask             ((uint32_t)0x0000000C)
32 #define CFGR0_SW_Mask              ((uint32_t)0xFFFFFFFC)
33 #define CFGR0_HPRE_Reset_Mask      ((uint32_t)0xFFFFFF0F)
34 #define CFGR0_HPRE_Set_Mask        ((uint32_t)0x000000F0)
35 #define CFGR0_PPRE1_Reset_Mask     ((uint32_t)0xFFFFF8FF)
36 #define CFGR0_PPRE1_Set_Mask       ((uint32_t)0x00000700)
37 #define CFGR0_PPRE2_Reset_Mask     ((uint32_t)0xFFFFC7FF)
38 #define CFGR0_PPRE2_Set_Mask       ((uint32_t)0x00003800)
39 #define CFGR0_ADCPRE_Reset_Mask    ((uint32_t)0xFFFF3FFF)
40 #define CFGR0_ADCPRE_Set_Mask      ((uint32_t)0x0000C000)
41 
42 /* RSTSCKR register bit mask */
43 #define RSTSCKR_RMVF_Set           ((uint32_t)0x01000000)
44 
45 /* RCC Flag Mask */
46 #define FLAG_Mask                  ((uint8_t)0x1F)
47 
48 /* INTR register byte 2 (Bits[15:8]) base address */
49 #define INTR_BYTE2_ADDRESS         ((uint32_t)0x40021009)
50 
51 /* INTR register byte 3 (Bits[23:16]) base address */
52 #define INTR_BYTE3_ADDRESS         ((uint32_t)0x4002100A)
53 
54 /* CFGR0 register byte 4 (Bits[31:24]) base address */
55 #define CFGR0_BYTE4_ADDRESS        ((uint32_t)0x40021007)
56 
57 /* BDCTLR register base address */
58 #define BDCTLR_ADDRESS             (PERIPH_BASE + BDCTLR_OFFSET)
59 
60 static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
61 static __I uint8_t ADCPrescTable[4] = {2, 4, 6, 8};
62 
63 /*********************************************************************
64  * @fn      RCC_DeInit
65  *
66  * @brief   Resets the RCC clock configuration to the default reset state.
67  *
68  * @return  none
69  */
RCC_DeInit(void)70 void RCC_DeInit(void)
71 {
72     RCC->CTLR |= (uint32_t)0x00000001;
73     RCC->CFGR0 &= (uint32_t)0xF8FF0000;
74     RCC->CTLR &= (uint32_t)0xFEF6FFFF;
75     RCC->CTLR &= (uint32_t)0xFFFBFFFF;
76     RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
77     RCC->INTR = 0x009F0000;
78 }
79 
80 /*********************************************************************
81  * @fn      RCC_HSEConfig
82  *
83  * @brief   Configures the External High Speed oscillator (HSE).
84  *
85  * @param   RCC_HSE -
86  *            RCC_HSE_OFF - HSE oscillator OFF.
87  *            RCC_HSE_ON - HSE oscillator ON.
88  *            RCC_HSE_Bypass - HSE oscillator bypassed with external clock.
89  *
90  * @return  none
91  */
RCC_HSEConfig(uint32_t RCC_HSE)92 void RCC_HSEConfig(uint32_t RCC_HSE)
93 {
94     RCC->CTLR &= CTLR_HSEON_Reset;
95     RCC->CTLR &= CTLR_HSEBYP_Reset;
96 
97     switch(RCC_HSE)
98     {
99         case RCC_HSE_ON:
100             RCC->CTLR |= CTLR_HSEON_Set;
101             break;
102 
103         case RCC_HSE_Bypass:
104             RCC->CTLR |= CTLR_HSEBYP_Set | CTLR_HSEON_Set;
105             break;
106 
107         default:
108             break;
109     }
110 }
111 
112 /*********************************************************************
113  * @fn      RCC_WaitForHSEStartUp
114  *
115  * @brief   Waits for HSE start-up.
116  *
117  * @return  SUCCESS - HSE oscillator is stable and ready to use.
118  *                  ERROR - HSE oscillator not yet ready.
119  */
RCC_WaitForHSEStartUp(void)120 ErrorStatus RCC_WaitForHSEStartUp(void)
121 {
122     __IO uint32_t StartUpCounter = 0;
123 
124     ErrorStatus status = ERROR;
125     FlagStatus  HSEStatus = RESET;
126 
127     do
128     {
129         HSEStatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY);
130         StartUpCounter++;
131     } while((StartUpCounter != HSE_STARTUP_TIMEOUT) && (HSEStatus == RESET));
132 
133     if(RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET)
134     {
135         status = SUCCESS;
136     }
137     else
138     {
139         status = ERROR;
140     }
141 
142     return (status);
143 }
144 
145 /*********************************************************************
146  * @fn      RCC_AdjustHSICalibrationValue
147  *
148  * @brief   Adjusts the Internal High Speed oscillator (HSI) calibration value.
149  *
150  * @param   HSICalibrationValue - specifies the calibration trimming value.
151  *                    This parameter must be a number between 0 and 0x1F.
152  *
153  * @return  none
154  */
RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)155 void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)
156 {
157     uint32_t tmpreg = 0;
158 
159     tmpreg = RCC->CTLR;
160     tmpreg &= CTLR_HSITRIM_Mask;
161     tmpreg |= (uint32_t)HSICalibrationValue << 3;
162     RCC->CTLR = tmpreg;
163 }
164 
165 /*********************************************************************
166  * @fn      RCC_HSICmd
167  *
168  * @brief   Enables or disables the Internal High Speed oscillator (HSI).
169  *
170  * @param   NewState - ENABLE or DISABLE.
171  *
172  * @return  none
173  */
RCC_HSICmd(FunctionalState NewState)174 void RCC_HSICmd(FunctionalState NewState)
175 {
176     if(NewState)
177     {
178         RCC->CTLR |= (1 << 0);
179     }
180     else
181     {
182         RCC->CTLR &= ~(1 << 0);
183     }
184 }
185 
186 /*********************************************************************
187  * @fn      RCC_PLLConfig
188  *
189  * @brief   Configures the PLL clock source and multiplication factor.
190  *
191  * @param   RCC_PLLSource - specifies the PLL entry clock source.
192  *          RCC_PLLSource_HSI_Div2 - HSI oscillator clock divided by 2
193  *        selected as PLL clock entry.
194  *          RCC_PLLSource_HSE_Div1 - HSE oscillator clock selected as PLL
195  *        clock entry.
196  *          RCC_PLLSource_HSE_Div2 - HSE oscillator clock divided by 2
197  *        selected as PLL clock entry.
198  *          RCC_PLLMul - specifies the PLL multiplication factor.
199  *          This parameter can be RCC_PLLMul_x where x:[2,16].
200  *
201  * @return  none
202  */
RCC_PLLConfig(uint32_t RCC_PLLSource,uint32_t RCC_PLLMul)203 void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul)
204 {
205     uint32_t tmpreg = 0;
206 
207     tmpreg = RCC->CFGR0;
208     tmpreg &= CFGR0_PLL_Mask;
209     tmpreg |= RCC_PLLSource | RCC_PLLMul;
210     RCC->CFGR0 = tmpreg;
211 }
212 
213 /*********************************************************************
214  * @fn      RCC_PLLCmd
215  *
216  * @brief   Enables or disables the PLL.
217  *
218  * @param   NewState - ENABLE or DISABLE.
219  *
220  * @return  none
221  */
RCC_PLLCmd(FunctionalState NewState)222 void RCC_PLLCmd(FunctionalState NewState)
223 {
224     if(NewState)
225     {
226         RCC->CTLR |= (1 << 24);
227     }
228     else
229     {
230         RCC->CTLR &= ~(1 << 24);
231     }
232 }
233 
234 /*********************************************************************
235  * @fn      RCC_SYSCLKConfig
236  *
237  * @brief   Configures the system clock (SYSCLK).
238  *
239  * @param   RCC_SYSCLKSource - specifies the clock source used as system clock.
240  *            RCC_SYSCLKSource_HSI - HSI selected as system clock.
241  *            RCC_SYSCLKSource_HSE - HSE selected as system clock.
242  *            RCC_SYSCLKSource_PLLCLK - PLL selected as system clock.
243  *
244  * @return  none
245  */
RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)246 void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
247 {
248     uint32_t tmpreg = 0;
249 
250     tmpreg = RCC->CFGR0;
251     tmpreg &= CFGR0_SW_Mask;
252     tmpreg |= RCC_SYSCLKSource;
253     RCC->CFGR0 = tmpreg;
254 }
255 
256 /*********************************************************************
257  * @fn      RCC_GetSYSCLKSource
258  *
259  * @brief   Returns the clock source used as system clock.
260  *
261  * @return  0x00 - HSI used as system clock.
262  *          0x04 - HSE used as system clock.
263  *          0x08 - PLL used as system clock.
264  */
RCC_GetSYSCLKSource(void)265 uint8_t RCC_GetSYSCLKSource(void)
266 {
267     return ((uint8_t)(RCC->CFGR0 & CFGR0_SWS_Mask));
268 }
269 
270 /*********************************************************************
271  * @fn      RCC_HCLKConfig
272  *
273  * @brief   Configures the AHB clock (HCLK).
274  *
275  * @param   RCC_SYSCLK - defines the AHB clock divider. This clock is derived from
276  *        the system clock (SYSCLK).
277  *            RCC_SYSCLK_Div1 - AHB clock = SYSCLK.
278  *            RCC_SYSCLK_Div2 - AHB clock = SYSCLK/2.
279  *            RCC_SYSCLK_Div4 - AHB clock = SYSCLK/4.
280  *            RCC_SYSCLK_Div8 - AHB clock = SYSCLK/8.
281  *            RCC_SYSCLK_Div16 - AHB clock = SYSCLK/16.
282  *            RCC_SYSCLK_Div64 - AHB clock = SYSCLK/64.
283  *            RCC_SYSCLK_Div128 - AHB clock = SYSCLK/128.
284  *            RCC_SYSCLK_Div256 - AHB clock = SYSCLK/256.
285  *            RCC_SYSCLK_Div512 - AHB clock = SYSCLK/512.
286  *
287  * @return  none
288  */
RCC_HCLKConfig(uint32_t RCC_SYSCLK)289 void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
290 {
291     uint32_t tmpreg = 0;
292 
293     tmpreg = RCC->CFGR0;
294     tmpreg &= CFGR0_HPRE_Reset_Mask;
295     tmpreg |= RCC_SYSCLK;
296     RCC->CFGR0 = tmpreg;
297 }
298 
299 /*********************************************************************
300  * @fn      RCC_PCLK1Config
301  *
302  * @brief   Configures the Low Speed APB clock (PCLK1).
303  *
304  * @param   RCC_HCLK - defines the APB1 clock divider. This clock is derived from
305  *        the AHB clock (HCLK).
306  *            RCC_HCLK_Div1 - APB1 clock = HCLK.
307  *            RCC_HCLK_Div2 - APB1 clock = HCLK/2.
308  *            RCC_HCLK_Div4 - APB1 clock = HCLK/4.
309  *            RCC_HCLK_Div8 - APB1 clock = HCLK/8.
310  *            RCC_HCLK_Div16 - APB1 clock = HCLK/16.
311  *
312  * @return  none
313  */
RCC_PCLK1Config(uint32_t RCC_HCLK)314 void RCC_PCLK1Config(uint32_t RCC_HCLK)
315 {
316     uint32_t tmpreg = 0;
317 
318     tmpreg = RCC->CFGR0;
319     tmpreg &= CFGR0_PPRE1_Reset_Mask;
320     tmpreg |= RCC_HCLK;
321     RCC->CFGR0 = tmpreg;
322 }
323 
324 /*********************************************************************
325  * @fn      RCC_PCLK2Config
326  *
327  * @brief   Configures the High Speed APB clock (PCLK2).
328  *
329  * @param   RCC_HCLK - defines the APB2 clock divider. This clock is derived from
330  *        the AHB clock (HCLK).
331  *            RCC_HCLK_Div1 - APB1 clock = HCLK.
332  *            RCC_HCLK_Div2 - APB1 clock = HCLK/2.
333  *            RCC_HCLK_Div4 - APB1 clock = HCLK/4.
334  *            RCC_HCLK_Div8 - APB1 clock = HCLK/8.
335  *            RCC_HCLK_Div16 - APB1 clock = HCLK/16.
336  *
337  * @return  none
338  */
RCC_PCLK2Config(uint32_t RCC_HCLK)339 void RCC_PCLK2Config(uint32_t RCC_HCLK)
340 {
341     uint32_t tmpreg = 0;
342 
343     tmpreg = RCC->CFGR0;
344     tmpreg &= CFGR0_PPRE2_Reset_Mask;
345     tmpreg |= RCC_HCLK << 3;
346     RCC->CFGR0 = tmpreg;
347 }
348 
349 /*********************************************************************
350  * @fn      RCC_ITConfig
351  *
352  * @brief   Enables or disables the specified RCC interrupts.
353  *
354  * @param   RCC_IT - specifies the RCC interrupt sources to be enabled or disabled.
355  *            RCC_IT_LSIRDY - LSI ready interrupt.
356  *            RCC_IT_LSERDY - LSE ready interrupt.
357  *            RCC_IT_HSIRDY - HSI ready interrupt.
358  *            RCC_IT_HSERDY - HSE ready interrupt.
359  *            RCC_IT_PLLRDY - PLL ready interrupt.
360  *          NewState - ENABLE or DISABLE.
361  *
362  * @return  none
363  */
RCC_ITConfig(uint8_t RCC_IT,FunctionalState NewState)364 void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState)
365 {
366     if(NewState != DISABLE)
367     {
368         *(__IO uint8_t *)INTR_BYTE2_ADDRESS |= RCC_IT;
369     }
370     else
371     {
372         *(__IO uint8_t *)INTR_BYTE2_ADDRESS &= (uint8_t)~RCC_IT;
373     }
374 }
375 
376 /*********************************************************************
377  * @fn      RCC_USBCLKConfig
378  *
379  * @brief   Configures the USB clock (USBCLK).
380  *
381  * @param   RCC_USBCLKSource: specifies the USB clock source. This clock is
382  *        derived from the PLL output.
383  *          RCC_USBCLKSource_PLLCLK_1Div5: PLL clock divided by 1,5 selected as USB
384  *        clock source.
385  *          RCC_USBCLKSource_PLLCLK_Div1: PLL clock selected as USB clock source.
386  *
387  * @return  none
388  */
RCC_USBCLKConfig(uint32_t RCC_USBCLKSource)389 void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource)
390 {
391     if(RCC_USBCLKSource)
392     {
393         RCC->CFGR0 |= (1 << 22);
394     }
395     else
396     {
397         RCC->CFGR0 &= ~(1 << 22);
398     }
399 }
400 
401 /*********************************************************************
402  * @fn      RCC_ADCCLKConfig
403  *
404  * @brief   Configures the ADC clock (ADCCLK).
405  *
406  * @param   RCC_PCLK2 - defines the ADC clock divider. This clock is derived from
407  *        the APB2 clock (PCLK2).
408  *          RCC_PCLK2_Div2 - ADC clock = PCLK2/2.
409  *          RCC_PCLK2_Div4 - ADC clock = PCLK2/4.
410  *          RCC_PCLK2_Div6 - ADC clock = PCLK2/6.
411  *          RCC_PCLK2_Div8 - ADC clock = PCLK2/8.
412  *
413  * @return  none
414  */
RCC_ADCCLKConfig(uint32_t RCC_PCLK2)415 void RCC_ADCCLKConfig(uint32_t RCC_PCLK2)
416 {
417     uint32_t tmpreg = 0;
418 
419     tmpreg = RCC->CFGR0;
420     tmpreg &= CFGR0_ADCPRE_Reset_Mask;
421     tmpreg |= RCC_PCLK2;
422     RCC->CFGR0 = tmpreg;
423 }
424 
425 /*********************************************************************
426  * @fn      RCC_LSEConfig
427  *
428  * @brief   Configures the External Low Speed oscillator (LSE).
429  *
430  * @param   RCC_LSE - specifies the new state of the LSE.
431  *            RCC_LSE_OFF - LSE oscillator OFF.
432  *            RCC_LSE_ON - LSE oscillator ON.
433  *            RCC_LSE_Bypass - LSE oscillator bypassed with external clock.
434  *
435  * @return  none
436  */
RCC_LSEConfig(uint8_t RCC_LSE)437 void RCC_LSEConfig(uint8_t RCC_LSE)
438 {
439     *(__IO uint8_t *)BDCTLR_ADDRESS = RCC_LSE_OFF;
440     *(__IO uint8_t *)BDCTLR_ADDRESS = RCC_LSE_OFF;
441 
442     switch(RCC_LSE)
443     {
444         case RCC_LSE_ON:
445             *(__IO uint8_t *)BDCTLR_ADDRESS = RCC_LSE_ON;
446             break;
447 
448         case RCC_LSE_Bypass:
449             *(__IO uint8_t *)BDCTLR_ADDRESS = RCC_LSE_Bypass | RCC_LSE_ON;
450             break;
451 
452         default:
453             break;
454     }
455 }
456 
457 /*********************************************************************
458  * @fn      RCC_LSICmd
459  *
460  * @brief   Enables or disables the Internal Low Speed oscillator (LSI).
461  *
462  * @param   NewState - ENABLE or DISABLE.
463  *
464  * @return  none
465  */
RCC_LSICmd(FunctionalState NewState)466 void RCC_LSICmd(FunctionalState NewState)
467 {
468     if(NewState)
469     {
470         RCC->RSTSCKR |= (1 << 0);
471     }
472     else
473     {
474         RCC->RSTSCKR &= ~(1 << 0);
475     }
476 }
477 
478 /*********************************************************************
479  * @fn      RCC_RTCCLKConfig
480  *
481  * @brief   Once the RTC clock is selected it can't be changed unless the Backup domain is reset.
482  *
483  * @param   RCC_RTCCLKSource - specifies the RTC clock source.
484  *            RCC_RTCCLKSource_LSE - LSE selected as RTC clock.
485  *            RCC_RTCCLKSource_LSI - LSI selected as RTC clock.
486  *            RCC_RTCCLKSource_HSE_Div128 - HSE clock divided by 128 selected as RTC clock.
487  *
488  * @return  none
489  */
RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource)490 void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource)
491 {
492     RCC->BDCTLR |= RCC_RTCCLKSource;
493 }
494 
495 /*********************************************************************
496  * @fn      RCC_RTCCLKCmd
497  *
498  * @brief   This function must be used only after the RTC clock was selected
499  *        using the RCC_RTCCLKConfig function.
500  *
501  * @param   NewState - ENABLE or DISABLE.
502  *
503  * @return  none
504  */
RCC_RTCCLKCmd(FunctionalState NewState)505 void RCC_RTCCLKCmd(FunctionalState NewState)
506 {
507     if(NewState)
508     {
509         RCC->BDCTLR |= (1 << 15);
510     }
511     else
512     {
513         RCC->BDCTLR &= ~(1 << 15);
514     }
515 }
516 
517 /*********************************************************************
518  * @fn      RCC_GetClocksFreq
519  *
520  * @brief   The result of this function could be not correct when using
521  *        fractional value for HSE crystal.
522  *
523  * @param   RCC_Clocks - pointer to a RCC_ClocksTypeDef structure which will hold
524  *        the clocks frequencies.
525  *
526  * @return  none
527  */
RCC_GetClocksFreq(RCC_ClocksTypeDef * RCC_Clocks)528 void RCC_GetClocksFreq(RCC_ClocksTypeDef *RCC_Clocks)
529 {
530     uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0;
531 
532     tmp = RCC->CFGR0 & CFGR0_SWS_Mask;
533 
534     switch(tmp)
535     {
536         case 0x00:
537             RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
538             break;
539 
540         case 0x04:
541             RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
542             break;
543 
544         case 0x08:
545             pllmull = RCC->CFGR0 & CFGR0_PLLMull_Mask;
546             pllsource = RCC->CFGR0 & CFGR0_PLLSRC_Mask;
547             pllmull = (pllmull >> 18) + 2;
548 
549             if(pllsource == 0x00)
550             {
551                 if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE)
552                 {
553                     RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE)*pllmull;
554                 }
555                 else
556                 {
557                     RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;
558                 }
559             }
560             else
561             {
562                 if((RCC->CFGR0 & CFGR0_PLLXTPRE_Mask) != (uint32_t)RESET)
563                 {
564                     RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE >> 1) * pllmull;
565                 }
566                 else
567                 {
568                     RCC_Clocks->SYSCLK_Frequency = HSE_VALUE * pllmull;
569                 }
570             }
571             break;
572 
573         default:
574             RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
575             break;
576     }
577 
578     tmp = RCC->CFGR0 & CFGR0_HPRE_Set_Mask;
579     tmp = tmp >> 4;
580     presc = APBAHBPrescTable[tmp];
581     RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
582     tmp = RCC->CFGR0 & CFGR0_PPRE1_Set_Mask;
583     tmp = tmp >> 8;
584     presc = APBAHBPrescTable[tmp];
585     RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
586     tmp = RCC->CFGR0 & CFGR0_PPRE2_Set_Mask;
587     tmp = tmp >> 11;
588     presc = APBAHBPrescTable[tmp];
589     RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
590     tmp = RCC->CFGR0 & CFGR0_ADCPRE_Set_Mask;
591     tmp = tmp >> 14;
592     presc = ADCPrescTable[tmp];
593     RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc;
594 }
595 
596 /*********************************************************************
597  * @fn      RCC_AHBPeriphClockCmd
598  *
599  * @brief   Enables or disables the AHB peripheral clock.
600  *
601  * @param   RCC_AHBPeriph - specifies the AHB peripheral to gates its clock.
602  *            RCC_AHBPeriph_DMA1.
603  *            RCC_AHBPeriph_DMA2.
604  *            RCC_AHBPeriph_SRAM.
605  *          NewState: ENABLE or DISABLE.
606  *
607  * @return  none
608  */
RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph,FunctionalState NewState)609 void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
610 {
611     if(NewState != DISABLE)
612     {
613         RCC->AHBPCENR |= RCC_AHBPeriph;
614     }
615     else
616     {
617         RCC->AHBPCENR &= ~RCC_AHBPeriph;
618     }
619 }
620 
621 /*********************************************************************
622  * @fn      RCC_APB2PeriphClockCmd
623  *
624  * @brief   Enables or disables the High Speed APB (APB2) peripheral clock.
625  *
626  * @param   RCC_APB2Periph - specifies the APB2 peripheral to gates its clock.
627  *            RCC_APB2Periph_AFIO.
628  *            RCC_APB2Periph_GPIOA.
629  *            RCC_APB2Periph_GPIOB.
630  *            RCC_APB2Periph_GPIOC.
631  *            RCC_APB2Periph_GPIOD.
632  *            RCC_APB2Periph_GPIOE
633  *            RCC_APB2Periph_ADC1.
634  *            RCC_APB2Periph_ADC2
635  *            RCC_APB2Periph_TIM1.
636  *            RCC_APB2Periph_SPI1.
637  *            RCC_APB2Periph_TIM8
638  *            RCC_APB2Periph_USART1.
639  *          NewState - ENABLE or DISABLE
640  *
641  * @return  none
642  */
RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph,FunctionalState NewState)643 void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
644 {
645     if(NewState != DISABLE)
646     {
647         RCC->APB2PCENR |= RCC_APB2Periph;
648     }
649     else
650     {
651         RCC->APB2PCENR &= ~RCC_APB2Periph;
652     }
653 }
654 
655 /*********************************************************************
656  * @fn      RCC_APB1PeriphClockCmd
657  *
658  * @brief   Enables or disables the Low Speed APB (APB1) peripheral clock.
659  *
660  * @param   RCC_APB1Periph - specifies the APB1 peripheral to gates its clock.
661  *            RCC_APB1Periph_TIM2.
662  *            RCC_APB1Periph_TIM3.
663  *            RCC_APB1Periph_TIM4.
664  *            RCC_APB1Periph_WWDG.
665  *            RCC_APB1Periph_SPI2.
666  *            RCC_APB1Periph_USART2.
667  *            RCC_APB1Periph_I2C1.
668  *            RCC_APB1Periph_I2C2.
669  *            RCC_APB1Periph_USB.
670  *            RCC_APB1Periph_CAN1.
671  *            RCC_APB1Periph_BKP.
672  *            RCC_APB1Periph_PWR.
673  *            RCC_APB1Periph_DAC.
674  *          NewState - ENABLE or DISABLE.
675  *
676  * @return  none
677  */
RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph,FunctionalState NewState)678 void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
679 {
680     if(NewState != DISABLE)
681     {
682         RCC->APB1PCENR |= RCC_APB1Periph;
683     }
684     else
685     {
686         RCC->APB1PCENR &= ~RCC_APB1Periph;
687     }
688 }
689 
690 /*********************************************************************
691  * @fn      RCC_APB2PeriphResetCmd
692  *
693  * @brief   Forces or releases High Speed APB (APB2) peripheral reset.
694  *
695  * @param   RCC_APB2Periph - specifies the APB2 peripheral to reset.
696  *            RCC_APB2Periph_AFIO.
697  *            RCC_APB2Periph_GPIOA.
698  *            RCC_APB2Periph_GPIOB.
699  *            RCC_APB2Periph_GPIOC.
700  *            RCC_APB2Periph_GPIOD.
701  *            RCC_APB2Periph_GPIOE
702  *            RCC_APB2Periph_ADC1.
703  *            RCC_APB2Periph_TIM1.
704  *            RCC_APB2Periph_SPI1.
705  *            RCC_APB2Periph_USART1.
706  *          NewState - ENABLE or DISABLE
707  *
708  * @return  none
709  */
RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph,FunctionalState NewState)710 void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
711 {
712     if(NewState != DISABLE)
713     {
714         RCC->APB2PRSTR |= RCC_APB2Periph;
715     }
716     else
717     {
718         RCC->APB2PRSTR &= ~RCC_APB2Periph;
719     }
720 }
721 
722 /*********************************************************************
723  * @fn      RCC_APB1PeriphResetCmd
724  *
725  * @brief   Forces or releases Low Speed APB (APB1) peripheral reset.
726  *
727  * @param   RCC_APB1Periph - specifies the APB1 peripheral to reset.
728  *            RCC_APB1Periph_TIM2.
729  *            RCC_APB1Periph_TIM3.
730  *            RCC_APB1Periph_TIM4.
731  *            RCC_APB1Periph_WWDG.
732  *            RCC_APB1Periph_SPI2.
733  *            RCC_APB1Periph_USART2.
734  *            RCC_APB1Periph_USART3.
735  *            RCC_APB1Periph_I2C1.
736  *            RCC_APB1Periph_I2C2.
737  *            RCC_APB1Periph_USB.
738  *            RCC_APB1Periph_CAN1.
739  *            RCC_APB1Periph_BKP.
740  *            RCC_APB1Periph_PWR.
741  *            RCC_APB1Periph_DAC.
742  *          NewState - ENABLE or DISABLE.
743  *
744  * @return  none
745  */
RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph,FunctionalState NewState)746 void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
747 {
748     if(NewState != DISABLE)
749     {
750         RCC->APB1PRSTR |= RCC_APB1Periph;
751     }
752     else
753     {
754         RCC->APB1PRSTR &= ~RCC_APB1Periph;
755     }
756 }
757 
758 /*********************************************************************
759  * @fn      RCC_BackupResetCmd
760  *
761  * @brief   Forces or releases the Backup domain reset.
762  *
763  * @param   NewState - ENABLE or DISABLE.
764  *
765  * @return  none
766  */
RCC_BackupResetCmd(FunctionalState NewState)767 void RCC_BackupResetCmd(FunctionalState NewState)
768 {
769     if(NewState)
770     {
771         RCC->BDCTLR |= (1 << 16);
772     }
773     else
774     {
775         RCC->BDCTLR &= ~(1 << 16);
776     }
777 }
778 
779 /*********************************************************************
780  * @fn      RCC_ClockSecuritySystemCmd
781  *
782  * @brief   Enables or disables the Clock Security System.
783  *
784  * @param   NewState - ENABLE or DISABLE.
785  *
786  * @return  none
787  */
RCC_ClockSecuritySystemCmd(FunctionalState NewState)788 void RCC_ClockSecuritySystemCmd(FunctionalState NewState)
789 {
790     if(NewState)
791     {
792         RCC->CTLR |= (1 << 19);
793     }
794     else
795     {
796         RCC->CTLR &= ~(1 << 19);
797     }
798 }
799 
800 /*********************************************************************
801  * @fn      RCC_MCOConfig
802  *
803  * @brief   Selects the clock source to output on MCO pin.
804  *
805  * @param   RCC_MCO - specifies the clock source to output.
806  *            RCC_MCO_NoClock - No clock selected.
807  *            RCC_MCO_SYSCLK - System clock selected.
808  *            RCC_MCO_HSI - HSI oscillator clock selected.
809  *            RCC_MCO_HSE - HSE oscillator clock selected.
810  *            RCC_MCO_PLLCLK_Div2 - PLL clock divided by 2 selected.
811  *
812  * @return  none
813  */
RCC_MCOConfig(uint8_t RCC_MCO)814 void RCC_MCOConfig(uint8_t RCC_MCO)
815 {
816     *(__IO uint8_t *)CFGR0_BYTE4_ADDRESS = RCC_MCO;
817 }
818 
819 /*********************************************************************
820  * @fn      RCC_GetFlagStatus
821  *
822  * @brief   Checks whether the specified RCC flag is set or not.
823  *
824  * @param   RCC_FLAG - specifies the flag to check.
825  *            RCC_FLAG_HSIRDY - HSI oscillator clock ready.
826  *            RCC_FLAG_HSERDY - HSE oscillator clock ready.
827  *            RCC_FLAG_PLLRDY - PLL clock ready.
828  *            RCC_FLAG_LSERDY - LSE oscillator clock ready.
829  *            RCC_FLAG_LSIRDY - LSI oscillator clock ready.
830  *            RCC_FLAG_PINRST - Pin reset.
831  *            RCC_FLAG_PORRST - POR/PDR reset.
832  *            RCC_FLAG_SFTRST - Software reset.
833  *            RCC_FLAG_IWDGRST - Independent Watchdog reset.
834  *            RCC_FLAG_WWDGRST - Window Watchdog reset.
835  *            RCC_FLAG_LPWRRST - Low Power reset.
836  *
837  * @return  FlagStatus - SET or RESET.
838  */
RCC_GetFlagStatus(uint8_t RCC_FLAG)839 FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
840 {
841     uint32_t tmp = 0;
842     uint32_t statusreg = 0;
843 
844     FlagStatus bitstatus = RESET;
845     tmp = RCC_FLAG >> 5;
846 
847     if(tmp == 1)
848     {
849         statusreg = RCC->CTLR;
850     }
851     else if(tmp == 2)
852     {
853         statusreg = RCC->BDCTLR;
854     }
855     else
856     {
857         statusreg = RCC->RSTSCKR;
858     }
859 
860     tmp = RCC_FLAG & FLAG_Mask;
861 
862     if((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET)
863     {
864         bitstatus = SET;
865     }
866     else
867     {
868         bitstatus = RESET;
869     }
870 
871     return bitstatus;
872 }
873 
874 /*********************************************************************
875  * @fn      RCC_ClearFlag
876  *
877  * @brief   Clears the RCC reset flags.
878  *
879  * @return  none
880  */
RCC_ClearFlag(void)881 void RCC_ClearFlag(void)
882 {
883     RCC->RSTSCKR |= RSTSCKR_RMVF_Set;
884 }
885 
886 /*********************************************************************
887  * @fn      RCC_GetITStatus
888  *
889  * @brief   Checks whether the specified RCC interrupt has occurred or not.
890  *
891  * @param   RCC_IT - specifies the RCC interrupt source to check.
892  *            RCC_IT_LSIRDY - LSI ready interrupt.
893  *            RCC_IT_LSERDY - LSE ready interrupt.
894  *            RCC_IT_HSIRDY - HSI ready interrupt.
895  *            RCC_IT_HSERDY - HSE ready interrupt.
896  *            RCC_IT_PLLRDY - PLL ready interrupt.
897  *            RCC_IT_CSS - Clock Security System interrupt.
898  *
899  * @return  ITStatus - SET or RESET.
900  */
RCC_GetITStatus(uint8_t RCC_IT)901 ITStatus RCC_GetITStatus(uint8_t RCC_IT)
902 {
903     ITStatus bitstatus = RESET;
904 
905     if((RCC->INTR & RCC_IT) != (uint32_t)RESET)
906     {
907         bitstatus = SET;
908     }
909     else
910     {
911         bitstatus = RESET;
912     }
913 
914     return bitstatus;
915 }
916 
917 /*********************************************************************
918  * @fn      RCC_ClearITPendingBit
919  *
920  * @brief   Clears the RCC's interrupt pending bits.
921  *
922  * @param   RCC_IT - specifies the interrupt pending bit to clear.
923  *            RCC_IT_LSIRDY - LSI ready interrupt.
924  *            RCC_IT_LSERDY - LSE ready interrupt.
925  *            RCC_IT_HSIRDY - HSI ready interrupt.
926  *            RCC_IT_HSERDY - HSE ready interrupt.
927  *            RCC_IT_PLLRDY - PLL ready interrupt.
928  *            RCC_IT_CSS - Clock Security System interrupt.
929  *
930  * @return  none
931  */
RCC_ClearITPendingBit(uint8_t RCC_IT)932 void RCC_ClearITPendingBit(uint8_t RCC_IT)
933 {
934     *(__IO uint8_t *)INTR_BYTE3_ADDRESS = RCC_IT;
935 }
936 
937 
938 
939