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