1 /**
2 ******************************************************************************
3 * @file ft32f0xx_rcc.c
4 * @author FMD AE
5 * @brief This file provides firmware functions to manage the following
6 * functionalities of the Reset and clock control (RCC) peripheral:
7 * + Internal/external clocks, PLL, CSS and MCO configuration
8 * + System, AHB and APB busses clocks configuration
9 * + Peripheral clocks configuration
10 * + Interrupts and flags management
11 * @version V1.0.0
12 * @data 2021-07-01
13 ******************************************************************************
14 */
15
16
17 /* Includes ------------------------------------------------------------------*/
18 #include "ft32f0xx_rcc.h"
19
20
21 /* ---------------------- RCC registers mask -------------------------------- */
22 /* RCC Flag Mask */
23 #define FLAG_MASK ((uint8_t)0x1F)
24
25 /* CR register byte 2 (Bits[23:16]) base address */
26 #define CR_BYTE2_ADDRESS ((uint32_t)0x40021002)
27
28 /* CFGR register byte 3 (Bits[31:23]) base address */
29 #define CFGR_BYTE3_ADDRESS ((uint32_t)0x40021007)
30
31 /* CIR register byte 1 (Bits[15:8]) base address */
32 #define CIR_BYTE1_ADDRESS ((uint32_t)0x40021009)
33
34 /* CIR register byte 2 (Bits[23:16]) base address */
35 #define CIR_BYTE2_ADDRESS ((uint32_t)0x4002100A)
36
37 static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
38
39 /**
40 * @brief Resets the RCC clock configuration to the default reset state.
41 * @note The default reset state of the clock configuration is given below:
42 * @note HSI ON and used as system clock source
43 * @note HSI14, HSE and PLL OFF
44 * @note AHB, APB prescaler set to 1.
45 * @note CSS and MCO OFF
46 * @note All interrupts disabled
47 * @note However, this function doesn't modify the configuration of the
48 * @note Peripheral clocks
49 * @note LSI, LSE and RTC clocks
50 * @param None
51 * @retval None
52 */
RCC_DeInit(void)53 void RCC_DeInit(void)
54 {
55 /* Set HSION bit */
56 RCC->CR |= (uint32_t)0x00000001;
57
58 /* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE, MCOSEL[2:0], MCOPRE[2:0] and PLLNODIV bits */
59 RCC->CFGR &= (uint32_t)0x08FFB80C;
60
61 /* Reset HSEON, CSSON and PLLON bits */
62 RCC->CR &= (uint32_t)0xFEF6FFFF;
63
64 /* Reset HSEBYP bit */
65 RCC->CR &= (uint32_t)0xFFFBFFFF;
66
67 /* Reset PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */
68 RCC->CFGR &= (uint32_t)0xFFC0FFFF;
69
70 /* Reset PREDIV1[3:0] bits */
71 RCC->CFGR2 &= (uint32_t)0xFFFFFFF0;
72
73 /* Reset USARTSW[1:0], I2CSW, CECSW and ADCSW bits */
74 RCC->CFGR3 &= (uint32_t)0xFFF0FEAC;
75
76 /* Reset HSI14 bit */
77 RCC->CR2 &= (uint32_t)0xFFFFFFFE;
78
79 /* Disable all interrupts */
80 RCC->CIR = 0x00000000;
81 }
82
83 /**
84 * @brief Configures the External High Speed oscillator (HSE).
85 * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application
86 * software should wait on HSERDY flag to be set indicating that HSE clock
87 * is stable and can be used to clock the PLL and/or system clock.
88 * @note HSE state can not be changed if it is used directly or through the
89 * PLL as system clock. In this case, you have to select another source
90 * of the system clock then change the HSE state (ex. disable it).
91 * @note The HSE is stopped by hardware when entering STOP and STANDBY modes.
92 * @note This function resets the CSSON bit, so if the Clock security system(CSS)
93 * was previously enabled you have to enable it again after calling this
94 * function.
95 * @param RCC_HSE: specifies the new state of the HSE.
96 * This parameter can be one of the following values:
97 * @arg RCC_HSE_OFF: turn OFF the HSE oscillator, HSERDY flag goes low after
98 * 6 HSE oscillator clock cycles.
99 * @arg RCC_HSE_ON: turn ON the HSE oscillator
100 * @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock
101 * @retval None
102 */
RCC_HSEConfig(uint8_t RCC_HSE)103 void RCC_HSEConfig(uint8_t RCC_HSE)
104 {
105 /* Check the parameters */
106 assert_param(IS_RCC_HSE(RCC_HSE));
107
108 /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/
109 *(__IO uint8_t *) CR_BYTE2_ADDRESS = RCC_HSE_OFF;
110
111 /* Set the new HSE configuration -------------------------------------------*/
112 *(__IO uint8_t *) CR_BYTE2_ADDRESS = RCC_HSE;
113
114 }
115
116 /**
117 * @brief Waits for HSE start-up.
118 * @note This function waits on HSERDY flag to be set and return SUCCESS if
119 * this flag is set, otherwise returns ERROR if the timeout is reached
120 * and this flag is not set. The timeout value is defined by the constant
121 * HSE_STARTUP_TIMEOUT in ft32f0xx.h file. You can tailor it depending
122 * on the HSE crystal used in your application.
123 * @note The HSE is stopped by hardware when entering STOP and STANDBY modes.
124 * @param None
125 * @retval An ErrorStatus enumeration value:
126 * - SUCCESS: HSE oscillator is stable and ready to use
127 * - ERROR: HSE oscillator not yet ready
128 */
RCC_WaitForHSEStartUp(void)129 ErrorStatus RCC_WaitForHSEStartUp(void)
130 {
131 __IO uint32_t StartUpCounter = 0;
132 ErrorStatus status = ERROR;
133 FlagStatus HSEStatus = RESET;
134
135 /* Wait till HSE is ready and if timeout is reached exit */
136 do
137 {
138 HSEStatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY);
139 StartUpCounter++;
140 } while((StartUpCounter != HSE_STARTUP_TIMEOUT) && (HSEStatus == RESET));
141
142 if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET)
143 {
144 status = SUCCESS;
145 }
146 else
147 {
148 status = ERROR;
149 }
150 return (status);
151 }
152
153 /**
154 * @brief Adjusts the Internal High Speed oscillator (HSI) calibration value.
155 * @note The calibration is used to compensate for the variations in voltage
156 * and temperature that influence the frequency of the internal HSI RC.
157 * Refer to the Application Note AN4067 for more details on how to
158 * calibrate the HSI.
159 * @param HSICalibrationValue: specifies the HSI calibration trimming value.
160 * This parameter must be a number between 0 and 0x1F.
161 * @retval None
162 */
RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)163 void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)
164 {
165 uint32_t tmpreg = 0;
166
167 /* Check the parameters */
168 assert_param(IS_RCC_HSI_CALIBRATION_VALUE(HSICalibrationValue));
169
170 tmpreg = RCC->CR;
171
172 /* Clear HSITRIM[4:0] bits */
173 tmpreg &= ~RCC_CR_HSITRIM;
174
175 /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */
176 tmpreg |= (uint32_t)HSICalibrationValue << 3;
177
178 /* Store the new value */
179 RCC->CR = tmpreg;
180 }
181
182 /**
183 * @brief Enables or disables the Internal High Speed oscillator (HSI).
184 * @note After enabling the HSI, the application software should wait on
185 * HSIRDY flag to be set indicating that HSI clock is stable and can
186 * be used to clock the PLL and/or system clock.
187 * @note HSI can not be stopped if it is used directly or through the PLL
188 * as system clock. In this case, you have to select another source
189 * of the system clock then stop the HSI.
190 * @note The HSI is stopped by hardware when entering STOP and STANDBY modes.
191 * @param NewState: new state of the HSI.
192 * This parameter can be: ENABLE or DISABLE.
193 * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator
194 * clock cycles.
195 * @retval None
196 */
RCC_HSICmd(FunctionalState NewState)197 void RCC_HSICmd(FunctionalState NewState)
198 {
199 /* Check the parameters */
200 assert_param(IS_FUNCTIONAL_STATE(NewState));
201
202 if (NewState != DISABLE)
203 {
204 RCC->CR |= RCC_CR_HSION;
205 }
206 else
207 {
208 RCC->CR &= ~RCC_CR_HSION;
209 }
210 }
211
212 /**
213 * @brief Adjusts the Internal High Speed oscillator for ADC (HSI14)
214 * calibration value.
215 * @note The calibration is used to compensate for the variations in voltage
216 * and temperature that influence the frequency of the internal HSI RC.
217 * Refer to the Application Note AN4067 for more details on how to
218 * calibrate the HSI14.
219 * @param HSI14CalibrationValue: specifies the HSI14 calibration trimming value.
220 * This parameter must be a number between 0 and 0x1F.
221 * @retval None
222 */
RCC_AdjustHSI14CalibrationValue(uint8_t HSI14CalibrationValue)223 void RCC_AdjustHSI14CalibrationValue(uint8_t HSI14CalibrationValue)
224 {
225 uint32_t tmpreg = 0;
226
227 /* Check the parameters */
228 assert_param(IS_RCC_HSI14_CALIBRATION_VALUE(HSI14CalibrationValue));
229
230 tmpreg = RCC->CR2;
231
232 /* Clear HSI14TRIM[4:0] bits */
233 tmpreg &= ~RCC_CR2_HSI14TRIM;
234
235 /* Set the HSITRIM14[4:0] bits according to HSI14CalibrationValue value */
236 tmpreg |= (uint32_t)HSI14CalibrationValue << 3;
237
238 /* Store the new value */
239 RCC->CR2 = tmpreg;
240 }
241
242 /**
243 * @brief Enables or disables the Internal High Speed oscillator for ADC (HSI14).
244 * @note After enabling the HSI14, the application software should wait on
245 * HSIRDY flag to be set indicating that HSI clock is stable and can
246 * be used to clock the ADC.
247 * @note The HSI14 is stopped by hardware when entering STOP and STANDBY modes.
248 * @param NewState: new state of the HSI14.
249 * This parameter can be: ENABLE or DISABLE.
250 * @note When the HSI14 is stopped, HSI14RDY flag goes low after 6 HSI14 oscillator
251 * clock cycles.
252 * @retval None
253 */
RCC_HSI14Cmd(FunctionalState NewState)254 void RCC_HSI14Cmd(FunctionalState NewState)
255 {
256 /* Check the parameters */
257 assert_param(IS_FUNCTIONAL_STATE(NewState));
258
259 if (NewState != DISABLE)
260 {
261 RCC->CR2 |= RCC_CR2_HSI14ON;
262 }
263 else
264 {
265 RCC->CR2 &= ~RCC_CR2_HSI14ON;
266 }
267 }
268
269 /**
270 * @brief Enables or disables the Internal High Speed oscillator request from ADC.
271 * @param NewState: new state of the HSI14 ADC request.
272 * This parameter can be: ENABLE or DISABLE.
273 * @retval None
274 */
RCC_HSI14ADCRequestCmd(FunctionalState NewState)275 void RCC_HSI14ADCRequestCmd(FunctionalState NewState)
276 {
277 /* Check the parameters */
278 assert_param(IS_FUNCTIONAL_STATE(NewState));
279
280 if (NewState != DISABLE)
281 {
282 RCC->CR2 &= ~RCC_CR2_HSI14DIS;
283 }
284 else
285 {
286 RCC->CR2 |= RCC_CR2_HSI14DIS;
287 }
288 }
289
290 /**
291 * @brief Configures the External Low Speed oscillator (LSE).
292 * @note As the LSE is in the Backup domain and write access is denied to this
293 * domain after reset, you have to enable write access using
294 * PWR_BackupAccessCmd(ENABLE) function before to configure the LSE
295 * (to be done once after reset).
296 * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_Bypass), the application
297 * software should wait on LSERDY flag to be set indicating that LSE clock
298 * is stable and can be used to clock the RTC.
299 * @param RCC_LSE: specifies the new state of the LSE.
300 * This parameter can be one of the following values:
301 * @arg RCC_LSE_OFF: turn OFF the LSE oscillator, LSERDY flag goes low after
302 * 6 LSE oscillator clock cycles.
303 * @arg RCC_LSE_ON: turn ON the LSE oscillator
304 * @arg RCC_LSE_Bypass: LSE oscillator bypassed with external clock
305 * @retval None
306 */
RCC_LSEConfig(uint32_t RCC_LSE)307 void RCC_LSEConfig(uint32_t RCC_LSE)
308 {
309 /* Check the parameters */
310 assert_param(IS_RCC_LSE(RCC_LSE));
311
312 /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/
313 /* Reset LSEON bit */
314 RCC->BDCR &= ~(RCC_BDCR_LSEON);
315
316 /* Reset LSEBYP bit */
317 RCC->BDCR &= ~(RCC_BDCR_LSEBYP);
318
319 /* Configure LSE */
320 RCC->BDCR |= RCC_LSE;
321 }
322
323 /**
324 * @brief Configures the External Low Speed oscillator (LSE) drive capability.
325 * @param RCC_LSEDrive: specifies the new state of the LSE drive capability.
326 * This parameter can be one of the following values:
327 * @arg RCC_LSEDrive_Low: LSE oscillator low drive capability.
328 * @arg RCC_LSEDrive_MediumLow: LSE oscillator medium low drive capability.
329 * @arg RCC_LSEDrive_MediumHigh: LSE oscillator medium high drive capability.
330 * @arg RCC_LSEDrive_High: LSE oscillator high drive capability.
331 * @retval None
332 */
RCC_LSEDriveConfig(uint32_t RCC_LSEDrive)333 void RCC_LSEDriveConfig(uint32_t RCC_LSEDrive)
334 {
335 /* Check the parameters */
336 assert_param(IS_RCC_LSE_DRIVE(RCC_LSEDrive));
337
338 /* Clear LSEDRV[1:0] bits */
339 RCC->BDCR &= ~(RCC_BDCR_LSEDRV);
340
341 /* Set the LSE Drive */
342 RCC->BDCR |= RCC_LSEDrive;
343 }
344
345 /**
346 * @brief Enables or disables the Internal Low Speed oscillator (LSI).
347 * @note After enabling the LSI, the application software should wait on
348 * LSIRDY flag to be set indicating that LSI clock is stable and can
349 * be used to clock the IWDG and/or the RTC.
350 * @note LSI can not be disabled if the IWDG is running.
351 * @param NewState: new state of the LSI.
352 * This parameter can be: ENABLE or DISABLE.
353 * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator
354 * clock cycles.
355 * @retval None
356 */
RCC_LSICmd(FunctionalState NewState)357 void RCC_LSICmd(FunctionalState NewState)
358 {
359 /* Check the parameters */
360 assert_param(IS_FUNCTIONAL_STATE(NewState));
361
362 if (NewState != DISABLE)
363 {
364 RCC->CSR |= RCC_CSR_LSION;
365 }
366 else
367 {
368 RCC->CSR &= ~RCC_CSR_LSION;
369 }
370 }
371
372 /**
373 * @brief Configures the PLL clock source and multiplication factor.
374 * @note This function must be used only when the PLL is disabled.
375 *
376 * @param RCC_PLLSource: specifies the PLL entry clock source.
377 * This parameter can be one of the following values:
378 * @arg RCC_PLLSource_HSI_Div2: HSI oscillator clock selected as PLL clock source
379 * @arg RCC_PLLSource_PREDIV1: PREDIV1 clock selected as PLL clock entry
380 * @arg RCC_PLLSource_HSI48 HSI48 oscillator clock selected as PLL clock source,
381 * @arg RCC_PLLSource_HSI: HSI clock selected as PLL clock entry
382 * @note The minimum input clock frequency for PLL is 2 MHz (when using HSE as
383 * PLL source).
384 *
385 * @param RCC_PLLMul: specifies the PLL multiplication factor, which drive the PLLVCO clock
386 * This parameter can be RCC_PLLMul_x where x:[2,16]
387 *
388 * @retval None
389 */
RCC_PLLConfig(uint32_t RCC_PLLSource,uint32_t RCC_PLLMul)390 void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul)
391 {
392 /* Check the parameters */
393 assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource));
394 assert_param(IS_RCC_PLL_MUL(RCC_PLLMul));
395
396 /* Clear PLL Source [16] and Multiplier [21:18] bits */
397 RCC->CFGR &= ~(RCC_CFGR_PLLMULL | RCC_CFGR_PLLSRC);
398
399 /* Set the PLL Source and Multiplier */
400 RCC->CFGR |= (uint32_t)(RCC_PLLSource | RCC_PLLMul);
401 }
402
403 /**
404 * @brief Enables or disables the PLL.
405 * @note After enabling the PLL, the application software should wait on
406 * PLLRDY flag to be set indicating that PLL clock is stable and can
407 * be used as system clock source.
408 * @note The PLL can not be disabled if it is used as system clock source
409 * @note The PLL is disabled by hardware when entering STOP and STANDBY modes.
410 * @param NewState: new state of the PLL.
411 * This parameter can be: ENABLE or DISABLE.
412 * @retval None
413 */
RCC_PLLCmd(FunctionalState NewState)414 void RCC_PLLCmd(FunctionalState NewState)
415 {
416 /* Check the parameters */
417 assert_param(IS_FUNCTIONAL_STATE(NewState));
418
419 if (NewState != DISABLE)
420 {
421 RCC->CR |= RCC_CR_PLLON;
422 }
423 else
424 {
425 RCC->CR &= ~RCC_CR_PLLON;
426 }
427 }
428
429 /**
430 * @brief Enables or disables the Internal High Speed oscillator for USB (HSI48).
431 * @note After enabling the HSI48, the application software should wait on
432 * HSI48RDY flag to be set indicating that HSI48 clock is stable and can
433 * be used to clock the USB.
434 * @note The HSI48 is stopped by hardware when entering STOP and STANDBY modes.
435 * @param NewState: new state of the HSI48.
436 * This parameter can be: ENABLE or DISABLE.
437 * @retval None
438 */
RCC_HSI48Cmd(FunctionalState NewState)439 void RCC_HSI48Cmd(FunctionalState NewState)
440 {
441 /* Check the parameters */
442 assert_param(IS_FUNCTIONAL_STATE(NewState));
443
444 if (NewState != DISABLE)
445 {
446 RCC->CR2 |= RCC_CR2_HSI48ON;
447 }
448 else
449 {
450 RCC->CR2 &= ~RCC_CR2_HSI48ON;
451 }
452 }
453
454 /**
455 * @brief Configures the PREDIV1 division factor.
456 * @note This function must be used only when the PLL is disabled.
457 * @param RCC_PREDIV1_Div: specifies the PREDIV1 clock division factor.
458 * This parameter can be RCC_PREDIV1_Divx where x:[1,16]
459 * @retval None
460 */
RCC_PREDIV1Config(uint32_t RCC_PREDIV1_Div)461 void RCC_PREDIV1Config(uint32_t RCC_PREDIV1_Div)
462 {
463 uint32_t tmpreg = 0;
464
465 /* Check the parameters */
466 assert_param(IS_RCC_PREDIV1(RCC_PREDIV1_Div));
467
468 tmpreg = RCC->CFGR2;
469 /* Clear PREDIV1[3:0] bits */
470 tmpreg &= ~(RCC_CFGR2_PREDIV1);
471 /* Set the PREDIV1 division factor */
472 tmpreg |= RCC_PREDIV1_Div;
473 /* Store the new value */
474 RCC->CFGR2 = tmpreg;
475 }
476
477 /**
478 * @brief Enables or disables the Clock Security System.
479 * @note If a failure is detected on the HSE oscillator clock, this oscillator
480 * is automatically disabled and an interrupt is generated to inform the
481 * software about the failure (Clock Security System Interrupt, CSSI),
482 * allowing the MCU to perform rescue operations. The CSSI is linked to
483 * the Cortex-M0 NMI (Non-Maskable Interrupt) exception vector.
484 * @param NewState: new state of the Clock Security System.
485 * This parameter can be: ENABLE or DISABLE.
486 * @retval None
487 */
RCC_ClockSecuritySystemCmd(FunctionalState NewState)488 void RCC_ClockSecuritySystemCmd(FunctionalState NewState)
489 {
490 /* Check the parameters */
491 assert_param(IS_FUNCTIONAL_STATE(NewState));
492
493 if (NewState != DISABLE)
494 {
495 RCC->CR |= RCC_CR_CSSON;
496 }
497 else
498 {
499 RCC->CR &= ~RCC_CR_CSSON;
500 }
501 }
502 /**
503 * @brief Selects the clock source to output on MCO pin (PA8) and the corresponding
504 * prescsaler.
505 * @note PA8 should be configured in alternate function mode.
506 * @param RCC_MCOSource: specifies the clock source to output.
507 * This parameter can be one of the following values:
508 * @arg RCC_MCOSource_NoClock: No clock selected.
509 * @arg RCC_MCOSource_HSI14: HSI14 oscillator clock selected.
510 * @arg RCC_MCOSource_LSI: LSI oscillator clock selected.
511 * @arg RCC_MCOSource_LSE: LSE oscillator clock selected.
512 * @arg RCC_MCOSource_SYSCLK: System clock selected.
513 * @arg RCC_MCOSource_HSI: HSI oscillator clock selected.
514 * @arg RCC_MCOSource_HSE: HSE oscillator clock selected.
515 * @arg RCC_MCOSource_PLLCLK_Div2: PLL clock divided by 2 selected.
516 * @arg RCC_MCOSource_PLLCLK: PLL clock selected.
517 * @arg RCC_MCOSource_HSI48: HSI48 clock selected.
518 * @param RCC_MCOPrescaler: specifies the prescaler on MCO pin.
519 * This parameter can be one of the following values:
520 * @arg RCC_MCOPrescaler_1: MCO clock is divided by 1.
521 * @arg RCC_MCOPrescaler_2: MCO clock is divided by 2.
522 * @arg RCC_MCOPrescaler_4: MCO clock is divided by 4.
523 * @arg RCC_MCOPrescaler_8: MCO clock is divided by 8.
524 * @arg RCC_MCOPrescaler_16: MCO clock is divided by 16.
525 * @arg RCC_MCOPrescaler_32: MCO clock is divided by 32.
526 * @arg RCC_MCOPrescaler_64: MCO clock is divided by 64.
527 * @arg RCC_MCOPrescaler_128: MCO clock is divided by 128.
528 * @retval None
529 */
RCC_MCOConfig(uint8_t RCC_MCOSource,uint32_t RCC_MCOPrescaler)530 void RCC_MCOConfig(uint8_t RCC_MCOSource, uint32_t RCC_MCOPrescaler)
531 {
532 uint32_t tmpreg = 0;
533
534 /* Check the parameters */
535 assert_param(IS_RCC_MCO_SOURCE(RCC_MCOSource));
536 assert_param(IS_RCC_MCO_PRESCALER(RCC_MCOPrescaler));
537
538 /* Get CFGR value */
539 tmpreg = RCC->CFGR;
540 /* Clear MCOPRE[2:0] bits */
541 tmpreg &= ~(RCC_CFGR_MCO_PRE | RCC_CFGR_MCO | RCC_CFGR_PLLNODIV);
542 /* Set the RCC_MCOSource and RCC_MCOPrescaler */
543 tmpreg |= (RCC_MCOPrescaler | ((uint32_t)RCC_MCOSource<<24));
544 /* Store the new value */
545 RCC->CFGR = tmpreg;
546 }
547
548 /**
549 * @}
550 */
551 /**
552 * @brief Configures the system clock (SYSCLK).
553 * @note The HSI is used (enabled by hardware) as system clock source after
554 * startup from Reset, wake-up from STOP and STANDBY mode, or in case
555 * of failure of the HSE used directly or indirectly as system clock
556 * (if the Clock Security System CSS is enabled).
557 * @note A switch from one clock source to another occurs only if the target
558 * clock source is ready (clock stable after startup delay or PLL locked).
559 * If a clock source which is not yet ready is selected, the switch will
560 * occur when the clock source will be ready.
561 * You can use RCC_GetSYSCLKSource() function to know which clock is
562 * currently used as system clock source.
563 * @param RCC_SYSCLKSource: specifies the clock source used as system clock source
564 * This parameter can be one of the following values:
565 * @arg RCC_SYSCLKSource_HSI: HSI selected as system clock source
566 * @arg RCC_SYSCLKSource_HSE: HSE selected as system clock source
567 * @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock source
568 * @arg RCC_SYSCLKSource_HSI48: HSI48 selected as system clock source
569 * @retval None
570 */
RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)571 void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
572 {
573 uint32_t tmpreg = 0;
574
575 /* Check the parameters */
576 assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource));
577
578 tmpreg = RCC->CFGR;
579
580 /* Clear SW[1:0] bits */
581 tmpreg &= ~RCC_CFGR_SW;
582
583 /* Set SW[1:0] bits according to RCC_SYSCLKSource value */
584 tmpreg |= RCC_SYSCLKSource;
585
586 /* Store the new value */
587 RCC->CFGR = tmpreg;
588 }
589
590 /**
591 * @brief Returns the clock source used as system clock.
592 * @param None
593 * @retval The clock source used as system clock. The returned value can be one
594 * of the following values:
595 * - 0x00: HSI used as system clock
596 * - 0x04: HSE used as system clock
597 * - 0x08: PLL used as system clock
598 * - 0x0C: HSI48 used as system clock
599 */
RCC_GetSYSCLKSource(void)600 uint8_t RCC_GetSYSCLKSource(void)
601 {
602 return ((uint8_t)(RCC->CFGR & RCC_CFGR_SWS));
603 }
604
605 /**
606 * @brief Configures the AHB clock (HCLK).
607 * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from
608 * the system clock (SYSCLK).
609 * This parameter can be one of the following values:
610 * @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK
611 * @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2
612 * @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4
613 * @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8
614 * @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16
615 * @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64
616 * @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128
617 * @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256
618 * @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512
619 * @retval None
620 */
RCC_HCLKConfig(uint32_t RCC_SYSCLK)621 void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
622 {
623 uint32_t tmpreg = 0;
624
625 /* Check the parameters */
626 assert_param(IS_RCC_HCLK(RCC_SYSCLK));
627
628 tmpreg = RCC->CFGR;
629
630 /* Clear HPRE[3:0] bits */
631 tmpreg &= ~RCC_CFGR_HPRE;
632
633 /* Set HPRE[3:0] bits according to RCC_SYSCLK value */
634 tmpreg |= RCC_SYSCLK;
635
636 /* Store the new value */
637 RCC->CFGR = tmpreg;
638 }
639
640 /**
641 * @brief Configures the APB clock (PCLK).
642 * @param RCC_HCLK: defines the APB clock divider. This clock is derived from
643 * the AHB clock (HCLK).
644 * This parameter can be one of the following values:
645 * @arg RCC_HCLK_Div1: APB clock = HCLK
646 * @arg RCC_HCLK_Div2: APB clock = HCLK/2
647 * @arg RCC_HCLK_Div4: APB clock = HCLK/4
648 * @arg RCC_HCLK_Div8: APB clock = HCLK/8
649 * @arg RCC_HCLK_Div16: APB clock = HCLK/16
650 * @retval None
651 */
RCC_PCLKConfig(uint32_t RCC_HCLK)652 void RCC_PCLKConfig(uint32_t RCC_HCLK)
653 {
654 uint32_t tmpreg = 0;
655
656 /* Check the parameters */
657 assert_param(IS_RCC_PCLK(RCC_HCLK));
658
659 tmpreg = RCC->CFGR;
660
661 /* Clear PPRE[2:0] bits */
662 tmpreg &= ~RCC_CFGR_PPRE;
663
664 /* Set PPRE[2:0] bits according to RCC_HCLK value */
665 tmpreg |= RCC_HCLK;
666
667 /* Store the new value */
668 RCC->CFGR = tmpreg;
669 }
670
671 /**
672 * @brief Configures the ADC clock (ADCCLK).
673 * @note This function is obsolete.
674 * For proper ADC clock selection, refer to ADC_ClockModeConfig() in the ADC driver
675 * @param RCC_ADCCLK: defines the ADC clock source. This clock is derived
676 * from the HSI14 or APB clock (PCLK).
677 * This parameter can be one of the following values:
678 * @arg RCC_ADCCLK_HSI14: ADC clock = HSI14 (14MHz)
679 * @arg RCC_ADCCLK_PCLK_Div2: ADC clock = PCLK/2
680 * @arg RCC_ADCCLK_PCLK_Div4: ADC clock = PCLK/4
681 * @retval None
682 */
RCC_ADCCLKConfig(uint32_t RCC_ADCCLK)683 void RCC_ADCCLKConfig(uint32_t RCC_ADCCLK)
684 {
685 /* Check the parameters */
686 assert_param(IS_RCC_ADCCLK(RCC_ADCCLK));
687
688 /* Clear ADCPRE bit */
689 RCC->CFGR &= ~RCC_CFGR_ADCPRE;
690 /* Set ADCPRE bits according to RCC_PCLK value */
691 RCC->CFGR |= RCC_ADCCLK & 0xFFFF;
692
693 /* Clear ADCSW bit */
694 RCC->CFGR3 &= ~RCC_CFGR3_ADCSW;
695 /* Set ADCSW bits according to RCC_ADCCLK value */
696 RCC->CFGR3 |= RCC_ADCCLK >> 16;
697 }
698
699 /**
700 * @brief Configures the CEC clock (CECCLK).
701 * @param RCC_CECCLK: defines the CEC clock source. This clock is derived
702 * from the HSI or LSE clock.
703 * This parameter can be one of the following values:
704 * @arg RCC_CECCLK_HSI_Div244: CEC clock = HSI/244 (32768Hz)
705 * @arg RCC_CECCLK_LSE: CEC clock = LSE
706 * @retval None
707 */
708
709
710 /**
711 * @brief Configures the I2C1 clock (I2C1CLK).
712 * @param RCC_I2CCLK: defines the I2C1 clock source. This clock is derived
713 * from the HSI or System clock.
714 * This parameter can be one of the following values:
715 * @arg RCC_I2C1CLK_HSI: I2C1 clock = HSI
716 * @arg RCC_I2C1CLK_SYSCLK: I2C1 clock = System Clock
717 * @retval None
718 */
RCC_I2CCLKConfig(uint32_t RCC_I2CCLK)719 void RCC_I2CCLKConfig(uint32_t RCC_I2CCLK)
720 {
721 /* Check the parameters */
722 assert_param(IS_RCC_I2CCLK(RCC_I2CCLK));
723
724 /* Clear I2CSW bit */
725 RCC->CFGR3 &= ~RCC_CFGR3_I2C1SW;
726 /* Set I2CSW bits according to RCC_I2CCLK value */
727 RCC->CFGR3 |= RCC_I2CCLK;
728 }
729
730 /**
731 * @brief Configures the USART1 clock (USART1CLK).
732 * @param RCC_USARTCLK: defines the USART clock source. This clock is derived
733 * from the HSI or System clock.
734 * This parameter can be one of the following values:
735 * @arg RCC_USART1CLK_PCLK: USART1 clock = APB Clock (PCLK)
736 * @arg RCC_USART1CLK_SYSCLK: USART1 clock = System Clock
737 * @arg RCC_USART1CLK_LSE: USART1 clock = LSE Clock
738 * @arg RCC_USART1CLK_HSI: USART1 clock = HSI Clock
739 * @arg RCC_USART2CLK_PCLK: USART2 clock = APB Clock (PCLK)
740 * @arg RCC_USART2CLK_SYSCLK: USART2 clock = System Clock
741 * @arg RCC_USART2CLK_LSE: USART2 clock = LSE Clock
742 * @arg RCC_USART2CLK_HSI: USART2 clock = HSI Clock
743 * @arg RCC_USART3CLK_PCLK: USART3 clock = APB Clock (PCLK)
744 * @arg RCC_USART3CLK_SYSCLK: USART3 clock = System Clock
745 * @arg RCC_USART3CLK_LSE: USART3 clock = LSE Clock
746 * @arg RCC_USART3CLK_HSI: USART3 clock = HSI Clock
747 * @retval None
748 */
RCC_USARTCLKConfig(uint32_t RCC_USARTCLK)749 void RCC_USARTCLKConfig(uint32_t RCC_USARTCLK)
750 {
751 uint32_t tmp = 0;
752
753 /* Check the parameters */
754 assert_param(IS_RCC_USARTCLK(RCC_USARTCLK));
755
756 /* Get USART index */
757 tmp = (RCC_USARTCLK >> 28);
758
759 /* Clear USARTSW[1:0] bit */
760 if (tmp == (uint32_t)0x00000001)
761 {
762 /* Clear USART1SW[1:0] bit */
763 RCC->CFGR3 &= ~RCC_CFGR3_USART1SW;
764 }
765 // else if (tmp == (uint32_t)0x00000002)
766 // {
767 // /* Clear USART2SW[1:0] bit */
768 // RCC->CFGR3 &= ~RCC_CFGR3_USART2SW;
769 // }
770 // else
771 // {
772 // /* Clear USART3SW[1:0] bit */
773 // RCC->CFGR3 &= ~RCC_CFGR3_USART3SW;
774 // }
775
776 /* Set USARTxSW bits according to RCC_USARTCLK value */
777 RCC->CFGR3 |= RCC_USARTCLK;
778 }
779
780 /**
781 * @brief Configures the USB clock (USBCLK).
782 * @param RCC_USBCLK: defines the USB clock source. This clock is derived
783 * from the HSI48 or system clock.
784 * This parameter can be one of the following values:
785 * @arg RCC_USBCLK_HSI48: USB clock = HSI48
786 * @arg RCC_USBCLK_PLLCLK: USB clock = PLL clock
787 * @retval None
788 */
RCC_USBCLKConfig(uint32_t RCC_USBCLK)789 void RCC_USBCLKConfig(uint32_t RCC_USBCLK)
790 {
791 /* Check the parameters */
792 assert_param(IS_RCC_USBCLK(RCC_USBCLK));
793
794 /* Clear USBSW bit */
795 RCC->CFGR3 &= ~RCC_CFGR3_USBSW;
796 /* Set USBSW bits according to RCC_USBCLK value */
797 RCC->CFGR3 |= RCC_USBCLK;
798 }
799
800 /**
801 * @brief Returns the frequencies of the System, AHB and APB busses clocks.
802 * @note The frequency returned by this function is not the real frequency
803 * in the chip. It is calculated based on the predefined constant and
804 * the source selected by RCC_SYSCLKConfig():
805 *
806 * @note If SYSCLK source is HSI, function returns constant HSI_VALUE(*)
807 *
808 * @note If SYSCLK source is HSE, function returns constant HSE_VALUE(**)
809 *
810 * @note If SYSCLK source is PLL, function returns constant HSE_VALUE(**)
811 * or HSI_VALUE(*) multiplied by the PLL factors.
812 *
813 * @note If SYSCLK source is HSI48, function returns constant HSI48_VALUE(***)
814 *
815 * @note (*) HSI_VALUE is a constant defined in ft32f0xx.h file (default value
816 * 8 MHz) but the real value may vary depending on the variations
817 * in voltage and temperature, refer to RCC_AdjustHSICalibrationValue().
818 *
819 * @note (**) HSE_VALUE is a constant defined in ft32f0xx.h file (default value
820 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
821 * frequency of the crystal used. Otherwise, this function may
822 * return wrong result.
823 *
824 * @note (***) HSI48_VALUE is a constant defined in ft32f0xx.h file (default value
825 * 48 MHz) but the real value may vary depending on the variations
826 * in voltage and temperature.
827 *
828 * @note The result of this function could be not correct when using fractional
829 * value for HSE crystal.
830 *
831 * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold
832 * the clocks frequencies.
833 *
834 * @note This function can be used by the user application to compute the
835 * baudrate for the communication peripherals or configure other parameters.
836 * @note Each time SYSCLK, HCLK and/or PCLK clock changes, this function
837 * must be called to update the structure's field. Otherwise, any
838 * configuration based on this function will be incorrect.
839 *
840 * @retval None
841 */
RCC_GetClocksFreq(RCC_ClocksTypeDef * RCC_Clocks)842 void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
843 {
844 uint32_t tmp = 0, pllmull = 0, pllsource = 0, prediv1factor = 0, presc = 0, pllclk = 0;
845
846 /* Get SYSCLK source -------------------------------------------------------*/
847 tmp = RCC->CFGR & RCC_CFGR_SWS;
848
849 switch (tmp)
850 {
851 case 0x00: /* HSI used as system clock */
852 RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
853 break;
854 case 0x04: /* HSE used as system clock */
855 RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
856 break;
857 case 0x08: /* PLL used as system clock */
858 /* Get PLL clock source and multiplication factor ----------------------*/
859 pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
860 pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
861 pllmull = ( pllmull >> 18) + 2;
862
863 if (pllsource == 0x00)
864 {
865 /* HSI oscillator clock divided by 2 selected as PLL clock entry */
866 pllclk = (HSI_VALUE >> 1) * pllmull;
867 }
868 else
869 {
870 prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
871 /* HSE oscillator clock selected as PREDIV1 clock entry */
872 pllclk = (HSE_VALUE / prediv1factor) * pllmull;
873 }
874 RCC_Clocks->SYSCLK_Frequency = pllclk;
875 break;
876 case 0x0C: /* HSI48 used as system clock */
877 RCC_Clocks->SYSCLK_Frequency = HSI48_VALUE;
878 break;
879 default: /* HSI used as system clock */
880 RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
881 break;
882 }
883 /* Compute HCLK, PCLK clocks frequencies -----------------------------------*/
884 /* Get HCLK prescaler */
885 tmp = RCC->CFGR & RCC_CFGR_HPRE;
886 tmp = tmp >> 4;
887 presc = APBAHBPrescTable[tmp];
888 /* HCLK clock frequency */
889 RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
890
891 /* Get PCLK prescaler */
892 tmp = RCC->CFGR & RCC_CFGR_PPRE;
893 tmp = tmp >> 8;
894 presc = APBAHBPrescTable[tmp];
895 /* PCLK clock frequency */
896 RCC_Clocks->PCLK_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
897
898 /* ADCCLK clock frequency */
899 if((RCC->CFGR3 & RCC_CFGR3_ADCSW) != RCC_CFGR3_ADCSW)
900 {
901 /* ADC Clock is HSI14 Osc. */
902 RCC_Clocks->ADCCLK_Frequency = HSI14_VALUE;
903 }
904 else
905 {
906 if((RCC->CFGR & RCC_CFGR_ADCPRE) != RCC_CFGR_ADCPRE)
907 {
908 /* ADC Clock is derived from PCLK/2 */
909 RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK_Frequency >> 1;
910 }
911 else
912 {
913 /* ADC Clock is derived from PCLK/4 */
914 RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK_Frequency >> 2;
915 }
916
917 }
918
919 /* CECCLK clock frequency */
920
921
922 /* I2C1CLK clock frequency */
923 if((RCC->CFGR3 & RCC_CFGR3_I2C1SW) != RCC_CFGR3_I2C1SW)
924 {
925 /* I2C1 Clock is HSI Osc. */
926 RCC_Clocks->I2C1CLK_Frequency = HSI_VALUE;
927 }
928 else
929 {
930 /* I2C1 Clock is System Clock */
931 RCC_Clocks->I2C1CLK_Frequency = RCC_Clocks->SYSCLK_Frequency;
932 }
933
934 /* USART1CLK clock frequency */
935 if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == 0x0)
936 {
937 /* USART1 Clock is PCLK */
938 RCC_Clocks->USART1CLK_Frequency = RCC_Clocks->PCLK_Frequency;
939 }
940 else if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == RCC_CFGR3_USART1SW_0)
941 {
942 /* USART1 Clock is System Clock */
943 RCC_Clocks->USART1CLK_Frequency = RCC_Clocks->SYSCLK_Frequency;
944 }
945 else if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == RCC_CFGR3_USART1SW_1)
946 {
947 /* USART1 Clock is LSE Osc. */
948 RCC_Clocks->USART1CLK_Frequency = LSE_VALUE;
949 }
950 else if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == RCC_CFGR3_USART1SW)
951 {
952 /* USART1 Clock is HSI Osc. */
953 RCC_Clocks->USART1CLK_Frequency = HSI_VALUE;
954 }
955
956 /* USART2CLK clock frequency */
957 RCC_Clocks->USART2CLK_Frequency=RCC_Clocks->PCLK_Frequency;
958 /* USART2CLK clock frequency */
959 // if((RCC->CFGR3 & RCC_CFGR3_USART2SW) == 0x0)
960 // {
961 // /* USART Clock is PCLK */
962 // RCC_Clocks->USART2CLK_Frequency = RCC_Clocks->PCLK_Frequency;
963 // }
964 // else if((RCC->CFGR3 & RCC_CFGR3_USART2SW) == RCC_CFGR3_USART2SW_0)
965 // {
966 // /* USART Clock is System Clock */
967 // RCC_Clocks->USART2CLK_Frequency = RCC_Clocks->SYSCLK_Frequency;
968 // }
969 // else if((RCC->CFGR3 & RCC_CFGR3_USART2SW) == RCC_CFGR3_USART2SW_1)
970 // {
971 // /* USART Clock is LSE Osc. */
972 // RCC_Clocks->USART2CLK_Frequency = LSE_VALUE;
973 // }
974 // else if((RCC->CFGR3 & RCC_CFGR3_USART2SW) == RCC_CFGR3_USART2SW)
975 // {
976 // /* USART Clock is HSI Osc. */
977 // RCC_Clocks->USART2CLK_Frequency = HSI_VALUE;
978 // }
979
980
981 /* USART3CLK clock frequency */
982
983 /* USBCLK clock frequency */
984 if((RCC->CFGR3 & RCC_CFGR3_USBSW) != RCC_CFGR3_USBSW)
985 {
986 /* USB Clock is HSI48 */
987 RCC_Clocks->USBCLK_Frequency = HSI48_VALUE;
988 }
989 else
990 {
991 /* USB Clock is PLL clock */
992 RCC_Clocks->USBCLK_Frequency = pllclk;
993 }
994 }
995
996 /**
997 * @}
998 */
999
1000 /**
1001 * @brief Configures the RTC clock (RTCCLK).
1002 * @note As the RTC clock configuration bits are in the Backup domain and write
1003 * access is denied to this domain after reset, you have to enable write
1004 * access using PWR_BackupAccessCmd(ENABLE) function before to configure
1005 * the RTC clock source (to be done once after reset).
1006 * @note Once the RTC clock is configured it can't be changed unless the RTC
1007 * is reset using RCC_BackupResetCmd function, or by a Power On Reset (POR)
1008 *
1009 * @param RCC_RTCCLKSource: specifies the RTC clock source.
1010 * This parameter can be one of the following values:
1011 * @arg RCC_RTCCLKSource_LSE: LSE selected as RTC clock
1012 * @arg RCC_RTCCLKSource_LSI: LSI selected as RTC clock
1013 * @arg RCC_RTCCLKSource_HSE_Div32: HSE divided by 32 selected as RTC clock
1014 *
1015 * @note If the LSE or LSI is used as RTC clock source, the RTC continues to
1016 * work in STOP and STANDBY modes, and can be used as wakeup source.
1017 * However, when the HSE clock is used as RTC clock source, the RTC
1018 * cannot be used in STOP and STANDBY modes.
1019 *
1020 * @note The maximum input clock frequency for RTC is 2MHz (when using HSE as
1021 * RTC clock source).
1022 *
1023 * @retval None
1024 */
RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource)1025 void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource)
1026 {
1027 /* Check the parameters */
1028 assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource));
1029
1030 /* Select the RTC clock source */
1031 RCC->BDCR |= RCC_RTCCLKSource;
1032 }
1033
1034 /**
1035 * @brief Enables or disables the RTC clock.
1036 * @note This function must be used only after the RTC clock source was selected
1037 * using the RCC_RTCCLKConfig function.
1038 * @param NewState: new state of the RTC clock.
1039 * This parameter can be: ENABLE or DISABLE.
1040 * @retval None
1041 */
RCC_RTCCLKCmd(FunctionalState NewState)1042 void RCC_RTCCLKCmd(FunctionalState NewState)
1043 {
1044 /* Check the parameters */
1045 assert_param(IS_FUNCTIONAL_STATE(NewState));
1046
1047 if (NewState != DISABLE)
1048 {
1049 RCC->BDCR |= RCC_BDCR_RTCEN;
1050 }
1051 else
1052 {
1053 RCC->BDCR &= ~RCC_BDCR_RTCEN;
1054 }
1055 }
1056
1057 /**
1058 * @brief Forces or releases the Backup domain reset.
1059 * @note This function resets the RTC peripheral (including the backup registers)
1060 * and the RTC clock source selection in RCC_BDCR register.
1061 * @param NewState: new state of the Backup domain reset.
1062 * This parameter can be: ENABLE or DISABLE.
1063 * @retval None
1064 */
RCC_BackupResetCmd(FunctionalState NewState)1065 void RCC_BackupResetCmd(FunctionalState NewState)
1066 {
1067 /* Check the parameters */
1068 assert_param(IS_FUNCTIONAL_STATE(NewState));
1069
1070 if (NewState != DISABLE)
1071 {
1072 RCC->BDCR |= RCC_BDCR_BDRST;
1073 }
1074 else
1075 {
1076 RCC->BDCR &= ~RCC_BDCR_BDRST;
1077 }
1078 }
1079
1080 /**
1081 * @brief Enables or disables the AHB peripheral clock.
1082 * @note After reset, the peripheral clock (used for registers read/write access)
1083 * is disabled and the application software has to enable this clock before
1084 * using it.
1085 * @param RCC_AHBPeriph: specifies the AHB peripheral to gates its clock.
1086 * This parameter can be any combination of the following values:
1087 * @arg RCC_AHBPeriph_GPIOA: GPIOA clock
1088 * @arg RCC_AHBPeriph_GPIOB: GPIOB clock
1089 * @arg RCC_AHBPeriph_GPIOC: GPIOC clock
1090 * @arg RCC_AHBPeriph_GPIOD: GPIOD clock
1091 * @arg RCC_AHBPeriph_GPIOE: GPIOE clock
1092 * @arg RCC_AHBPeriph_GPIOF: GPIOF clock
1093 * @arg RCC_AHBPeriph_TS: TS clock
1094 * @arg RCC_AHBPeriph_CRC: CRC clock
1095 * @arg RCC_AHBPeriph_FLITF: (has effect only when the Flash memory is in power down mode)
1096 * @arg RCC_AHBPeriph_SRAM: SRAM clock
1097 * @arg RCC_AHBPeriph_DMA1: DMA1 clock
1098 * @arg RCC_AHBPeriph_DMA2: DMA2 clock
1099 * @param NewState: new state of the specified peripheral clock.
1100 * This parameter can be: ENABLE or DISABLE.
1101 * @retval None
1102 */
RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph,FunctionalState NewState)1103 void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
1104 {
1105 /* Check the parameters */
1106 assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph));
1107 assert_param(IS_FUNCTIONAL_STATE(NewState));
1108
1109 if (NewState != DISABLE)
1110 {
1111 RCC->AHBENR |= RCC_AHBPeriph;
1112 }
1113 else
1114 {
1115 RCC->AHBENR &= ~RCC_AHBPeriph;
1116 }
1117 }
1118
1119 /**
1120 * @brief Enables or disables the High Speed APB (APB2) peripheral clock.
1121 * @note After reset, the peripheral clock (used for registers read/write access)
1122 * is disabled and the application software has to enable this clock before
1123 * using it.
1124 * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.
1125 * This parameter can be any combination of the following values:
1126 * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock
1127 * @arg RCC_APB2Periph_USART6: USART6 clock
1128 * @arg RCC_APB2Periph_USART7: USART7 clock
1129 * @arg RCC_APB2Periph_USART8: USART8 clock
1130 * @arg RCC_APB2Periph_ADC1: ADC1 clock
1131 * @arg RCC_APB2Periph_TIM1: TIM1 clock
1132 * @arg RCC_APB2Periph_SPI1: SPI1 clock
1133 * @arg RCC_APB2Periph_USART1: USART1 clock
1134 * @arg RCC_APB2Periph_TIM15: TIM15 clock
1135 * @arg RCC_APB2Periph_TIM16: TIM16 clock
1136 * @arg RCC_APB2Periph_TIM17: TIM17 clock
1137 * @arg RCC_APB2Periph_DBGMCU: DBGMCU clock
1138 * @param NewState: new state of the specified peripheral clock.
1139 * This parameter can be: ENABLE or DISABLE.
1140 * @retval None
1141 */
RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph,FunctionalState NewState)1142 void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
1143 {
1144 /* Check the parameters */
1145 assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
1146 assert_param(IS_FUNCTIONAL_STATE(NewState));
1147
1148 if (NewState != DISABLE)
1149 {
1150 RCC->APB2ENR |= RCC_APB2Periph;
1151 }
1152 else
1153 {
1154 RCC->APB2ENR &= ~RCC_APB2Periph;
1155 }
1156 }
1157
1158 /**
1159 * @brief Enables or disables the Low Speed APB (APB1) peripheral clock.
1160 * @note After reset, the peripheral clock (used for registers read/write access)
1161 * is disabled and the application software has to enable this clock before
1162 * using it.
1163 * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock.
1164 * This parameter can be any combination of the following values:
1165 * @arg RCC_APB1Periph_TIM2: TIM2 clock
1166 * @arg RCC_APB1Periph_TIM3: TIM3 clock
1167 * @arg RCC_APB1Periph_TIM6: TIM6 clock
1168 * @arg RCC_APB1Periph_TIM7: TIM7 clock
1169 * @arg RCC_APB1Periph_TIM14: TIM14 clock
1170 * @arg RCC_APB1Periph_WWDG: WWDG clock
1171 * @arg RCC_APB1Periph_SPI2: SPI2 clock
1172 * @arg RCC_APB1Periph_USART2: USART2 clock
1173 * @arg RCC_APB1Periph_USART3: USART3 clock
1174 * @arg RCC_APB1Periph_USART4: USART4 clock
1175 * @arg RCC_APB1Periph_USART5: USART5 clock
1176 * @arg RCC_APB1Periph_I2C1: I2C1 clock
1177 * @arg RCC_APB1Periph_I2C2: I2C2 clock
1178 * @arg RCC_APB1Periph_USB: USB clock
1179 * @arg RCC_APB1Periph_CAN: CAN clock
1180 * @arg RCC_APB1Periph_CRS: CRS clock
1181 * @arg RCC_APB1Periph_PWR: PWR clock
1182 * @arg RCC_APB1Periph_DAC: DAC clock
1183 * @arg RCC_APB1Periph_CEC: CEC clock
1184 * @param NewState: new state of the specified peripheral clock.
1185 * This parameter can be: ENABLE or DISABLE.
1186 * @retval None
1187 */
RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph,FunctionalState NewState)1188 void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
1189 {
1190 /* Check the parameters */
1191 assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
1192 assert_param(IS_FUNCTIONAL_STATE(NewState));
1193
1194 if (NewState != DISABLE)
1195 {
1196 RCC->APB1ENR |= RCC_APB1Periph;
1197 }
1198 else
1199 {
1200 RCC->APB1ENR &= ~RCC_APB1Periph;
1201 }
1202 }
1203
1204 /**
1205 * @brief Forces or releases AHB peripheral reset.
1206 * @param RCC_AHBPeriph: specifies the AHB peripheral to reset.
1207 * This parameter can be any combination of the following values:
1208 * @arg RCC_AHBPeriph_GPIOA: GPIOA clock
1209 * @arg RCC_AHBPeriph_GPIOB: GPIOB clock
1210 * @arg RCC_AHBPeriph_GPIOC: GPIOC clock
1211 * @arg RCC_AHBPeriph_GPIOD: GPIOD clock
1212 * @arg RCC_AHBPeriph_GPIOE: GPIOE clock
1213 * @arg RCC_AHBPeriph_GPIOF: GPIOF clock
1214 * @arg RCC_AHBPeriph_TS: TS clock
1215 * @param NewState: new state of the specified peripheral reset.
1216 * This parameter can be: ENABLE or DISABLE.
1217 * @retval None
1218 */
RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph,FunctionalState NewState)1219 void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
1220 {
1221 /* Check the parameters */
1222 assert_param(IS_RCC_AHB_RST_PERIPH(RCC_AHBPeriph));
1223 assert_param(IS_FUNCTIONAL_STATE(NewState));
1224
1225 if (NewState != DISABLE)
1226 {
1227 RCC->AHBRSTR |= RCC_AHBPeriph;
1228 }
1229 else
1230 {
1231 RCC->AHBRSTR &= ~RCC_AHBPeriph;
1232 }
1233 }
1234
1235 /**
1236 * @brief Forces or releases High Speed APB (APB2) peripheral reset.
1237 * @param RCC_APB2Periph: specifies the APB2 peripheral to reset.
1238 * This parameter can be any combination of the following values:
1239 * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock
1240 * @arg RCC_APB2Periph_USART6: USART6 clock
1241 * @arg RCC_APB2Periph_USART7: USART7 clock
1242 * @arg RCC_APB2Periph_USART8: USART8 clock
1243 * @arg RCC_APB2Periph_ADC1: ADC1 clock
1244 * @arg RCC_APB2Periph_TIM1: TIM1 clock
1245 * @arg RCC_APB2Periph_SPI1: SPI1 clock
1246 * @arg RCC_APB2Periph_USART1: USART1 clock
1247 * @arg RCC_APB2Periph_TIM15: TIM15 clock
1248 * @arg RCC_APB2Periph_TIM16: TIM16 clock
1249 * @arg RCC_APB2Periph_TIM17: TIM17 clock
1250 * @arg RCC_APB2Periph_DBGMCU: DBGMCU clock
1251 * @param NewState: new state of the specified peripheral reset.
1252 * This parameter can be: ENABLE or DISABLE.
1253 * @retval None
1254 */
RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph,FunctionalState NewState)1255 void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
1256 {
1257 /* Check the parameters */
1258 assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
1259 assert_param(IS_FUNCTIONAL_STATE(NewState));
1260
1261 if (NewState != DISABLE)
1262 {
1263 RCC->APB2RSTR |= RCC_APB2Periph;
1264 }
1265 else
1266 {
1267 RCC->APB2RSTR &= ~RCC_APB2Periph;
1268 }
1269 }
1270
1271 /**
1272 * @brief Forces or releases Low Speed APB (APB1) peripheral reset.
1273 * @param RCC_APB1Periph: specifies the APB1 peripheral to reset.
1274 * This parameter can be any combination of the following values:
1275 * @arg RCC_APB1Periph_TIM2: TIM2 clock
1276 * @arg RCC_APB1Periph_TIM3: TIM3 clock
1277 * @arg RCC_APB1Periph_TIM6: TIM6 clock
1278 * @arg RCC_APB1Periph_TIM7: TIM7 clock
1279 * @arg RCC_APB1Periph_TIM14: TIM14 clock
1280 * @arg RCC_APB1Periph_WWDG: WWDG clock
1281 * @arg RCC_APB1Periph_SPI2: SPI2 clock
1282 * @arg RCC_APB1Periph_USART2: USART2 clock
1283 * @arg RCC_APB1Periph_USART3: USART3 clock
1284 * @arg RCC_APB1Periph_USART4: USART4 clock
1285 * @arg RCC_APB1Periph_USART5: USART5 clock
1286 * @arg RCC_APB1Periph_I2C1: I2C1 clock
1287 * @arg RCC_APB1Periph_I2C2: I2C2 clock
1288 * @arg RCC_APB1Periph_USB: USB clock
1289 * @arg RCC_APB1Periph_CAN: CAN clock
1290 * @arg RCC_APB1Periph_CRS: CRS clock
1291 * @arg RCC_APB1Periph_PWR: PWR clock
1292 * @arg RCC_APB1Periph_DAC: DAC clock
1293 * @arg RCC_APB1Periph_CEC: CEC clock
1294 * @param NewState: new state of the specified peripheral clock.
1295 * This parameter can be: ENABLE or DISABLE.
1296 * @retval None
1297 */
RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph,FunctionalState NewState)1298 void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
1299 {
1300 /* Check the parameters */
1301 assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
1302 assert_param(IS_FUNCTIONAL_STATE(NewState));
1303
1304 if (NewState != DISABLE)
1305 {
1306 RCC->APB1RSTR |= RCC_APB1Periph;
1307 }
1308 else
1309 {
1310 RCC->APB1RSTR &= ~RCC_APB1Periph;
1311 }
1312 }
1313
1314 /**
1315 * @}
1316 */
1317 /**
1318 * @brief Enables or disables the specified RCC interrupts.
1319 * @note The CSS interrupt doesn't have an enable bit; once the CSS is enabled
1320 * and if the HSE clock fails, the CSS interrupt occurs and an NMI is
1321 * automatically generated. The NMI will be executed indefinitely, and
1322 * since NMI has higher priority than any other IRQ (and main program)
1323 * the application will be stacked in the NMI ISR unless the CSS interrupt
1324 * pending bit is cleared.
1325 * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled.
1326 * This parameter can be any combination of the following values:
1327 * @arg RCC_IT_LSIRDY: LSI ready interrupt
1328 * @arg RCC_IT_LSERDY: LSE ready interrupt
1329 * @arg RCC_IT_HSIRDY: HSI ready interrupt
1330 * @arg RCC_IT_HSERDY: HSE ready interrupt
1331 * @arg RCC_IT_PLLRDY: PLL ready interrupt
1332 * @arg RCC_IT_HSI14RDY: HSI14 ready interrupt
1333 * @arg RCC_IT_HSI48RDY: HSI48 ready interrupt
1334 * @param NewState: new state of the specified RCC interrupts.
1335 * This parameter can be: ENABLE or DISABLE.
1336 * @retval None
1337 */
RCC_ITConfig(uint8_t RCC_IT,FunctionalState NewState)1338 void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState)
1339 {
1340 /* Check the parameters */
1341 assert_param(IS_RCC_IT(RCC_IT));
1342 assert_param(IS_FUNCTIONAL_STATE(NewState));
1343
1344 if (NewState != DISABLE)
1345 {
1346 /* Perform Byte access to RCC_CIR[13:8] bits to enable the selected interrupts */
1347 *(__IO uint8_t *) CIR_BYTE1_ADDRESS |= RCC_IT;
1348 }
1349 else
1350 {
1351 /* Perform Byte access to RCC_CIR[13:8] bits to disable the selected interrupts */
1352 *(__IO uint8_t *) CIR_BYTE1_ADDRESS &= (uint8_t)~RCC_IT;
1353 }
1354 }
1355
1356 /**
1357 * @brief Checks whether the specified RCC flag is set or not.
1358 * @param RCC_FLAG: specifies the flag to check.
1359 * This parameter can be one of the following values:
1360 * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready
1361 * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready
1362 * @arg RCC_FLAG_PLLRDY: PLL clock ready
1363 * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready
1364 * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready
1365 * @arg RCC_FLAG_OBLRST: Option Byte Loader (OBL) reset
1366 * @arg RCC_FLAG_PINRST: Pin reset
1367 * @arg RCC_FLAG_V18PWRRSTF: V1.8 power domain reset
1368 * @arg RCC_FLAG_PORRST: POR/PDR reset
1369 * @arg RCC_FLAG_SFTRST: Software reset
1370 * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset
1371 * @arg RCC_FLAG_WWDGRST: Window Watchdog reset
1372 * @arg RCC_FLAG_LPWRRST: Low Power reset
1373 * @arg RCC_FLAG_HSI14RDY: HSI14 oscillator clock ready
1374 * @arg RCC_FLAG_HSI48RDY: HSI48 oscillator clock ready
1375 * @retval The new state of RCC_FLAG (SET or RESET).
1376 */
RCC_GetFlagStatus(uint8_t RCC_FLAG)1377 FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
1378 {
1379 uint32_t tmp = 0;
1380 uint32_t statusreg = 0;
1381 FlagStatus bitstatus = RESET;
1382
1383 /* Check the parameters */
1384 assert_param(IS_RCC_FLAG(RCC_FLAG));
1385
1386 /* Get the RCC register index */
1387 tmp = RCC_FLAG >> 5;
1388
1389 if (tmp == 0) /* The flag to check is in CR register */
1390 {
1391 statusreg = RCC->CR;
1392 }
1393 else if (tmp == 1) /* The flag to check is in BDCR register */
1394 {
1395 statusreg = RCC->BDCR;
1396 }
1397 else if (tmp == 2) /* The flag to check is in CSR register */
1398 {
1399 statusreg = RCC->CSR;
1400 }
1401 else /* The flag to check is in CR2 register */
1402 {
1403 statusreg = RCC->CR2;
1404 }
1405
1406 /* Get the flag position */
1407 tmp = RCC_FLAG & FLAG_MASK;
1408
1409 if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET)
1410 {
1411 bitstatus = SET;
1412 }
1413 else
1414 {
1415 bitstatus = RESET;
1416 }
1417 /* Return the flag status */
1418 return bitstatus;
1419 }
1420
1421 /**
1422 * @brief Clears the RCC reset flags.
1423 * The reset flags are: RCC_FLAG_OBLRST, RCC_FLAG_PINRST, RCC_FLAG_V18PWRRSTF,
1424 * RCC_FLAG_PORRST, RCC_FLAG_SFTRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST,
1425 * RCC_FLAG_LPWRRST.
1426 * @param None
1427 * @retval None
1428 */
RCC_ClearFlag(void)1429 void RCC_ClearFlag(void)
1430 {
1431 /* Set RMVF bit to clear the reset flags */
1432 RCC->CSR |= RCC_CSR_RMVF;
1433 }
1434
1435 /**
1436 * @brief Checks whether the specified RCC interrupt has occurred or not.
1437 * @param RCC_IT: specifies the RCC interrupt source to check.
1438 * This parameter can be one of the following values:
1439 * @arg RCC_IT_LSIRDY: LSI ready interrupt
1440 * @arg RCC_IT_LSERDY: LSE ready interrupt
1441 * @arg RCC_IT_HSIRDY: HSI ready interrupt
1442 * @arg RCC_IT_HSERDY: HSE ready interrupt
1443 * @arg RCC_IT_PLLRDY: PLL ready interrupt
1444 * @arg RCC_IT_HSI14RDY: HSI14 ready interrupt
1445 * @arg RCC_IT_HSI48RDY: HSI48 ready interrupt
1446 * @arg RCC_IT_CSS: Clock Security System interrupt
1447 * @retval The new state of RCC_IT (SET or RESET).
1448 */
RCC_GetITStatus(uint8_t RCC_IT)1449 ITStatus RCC_GetITStatus(uint8_t RCC_IT)
1450 {
1451 ITStatus bitstatus = RESET;
1452
1453 /* Check the parameters */
1454 assert_param(IS_RCC_GET_IT(RCC_IT));
1455
1456 /* Check the status of the specified RCC interrupt */
1457 if ((RCC->CIR & RCC_IT) != (uint32_t)RESET)
1458 {
1459 bitstatus = SET;
1460 }
1461 else
1462 {
1463 bitstatus = RESET;
1464 }
1465 /* Return the RCC_IT status */
1466 return bitstatus;
1467 }
1468
1469 /**
1470 * @brief Clears the RCC's interrupt pending bits.
1471 * @param RCC_IT: specifies the interrupt pending bit to clear.
1472 * This parameter can be any combination of the following values:
1473 * @arg RCC_IT_LSIRDY: LSI ready interrupt
1474 * @arg RCC_IT_LSERDY: LSE ready interrupt
1475 * @arg RCC_IT_HSIRDY: HSI ready interrupt
1476 * @arg RCC_IT_HSERDY: HSE ready interrupt
1477 * @arg RCC_IT_PLLRDY: PLL ready interrupt
1478 * @arg RCC_IT_HSI48RDY: HSI48 ready interrupt
1479 * @arg RCC_IT_HSI14RDY: HSI14 ready interrupt
1480 * @arg RCC_IT_CSS: Clock Security System interrupt
1481 * @retval None
1482 */
RCC_ClearITPendingBit(uint8_t RCC_IT)1483 void RCC_ClearITPendingBit(uint8_t RCC_IT)
1484 {
1485 /* Check the parameters */
1486 assert_param(IS_RCC_CLEAR_IT(RCC_IT));
1487
1488 /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt
1489 pending bits */
1490 *(__IO uint8_t *) CIR_BYTE2_ADDRESS = RCC_IT;
1491 }
1492
1493 /**
1494 * @}
1495 */
1496
1497 /**
1498 * @}
1499 */
1500
1501 /**
1502 * @}
1503 */
1504
1505 /**
1506 * @}
1507 */
1508
1509 /************************ (C) COPYRIGHT FMD *****END OF FILE****/
1510