1 /**
2 ******************************************************************************
3 * @file  HAL_rcc.c
4 * @author  AE Team
5 * @version  V2.0.0
6 * @date  22/08/2017
7 * @brief  This file provides all the RCC firmware functions.
8 ******************************************************************************
9 * @copy
10 *
11 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13 * TIME. AS A RESULT, MindMotion SHALL NOT BE HELD LIABLE FOR ANY
14 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17 *
18 * <h2><center>&copy; COPYRIGHT 2017 MindMotion</center></h2>
19 */
20 //SJH&TM change
21 /* Includes ------------------------------------------------------------------*/
22 #include "HAL_rcc.h"
23 
24 /** @addtogroup StdPeriph_Driver
25 * @{
26 */
27 
28 /** @defgroup RCC
29 * @brief RCC driver modules
30 * @{
31 */
32 
33 /** @defgroup RCC_Private_TypesDefinitions
34 * @{
35 */
36 
37 /**
38 * @}
39 */
40 
41 /** @defgroup RCC_Private_Defines
42 * @{
43 */
44 
45 /* ------------ RCC registers bit address in the alias region ----------- */
46 #define RCC_OFFSET                (RCC_BASE - PERIPH_BASE)
47 
48 /* --- CR Register ---*/
49 
50 /* Alias word address of HSION bit */
51 #define CR_OFFSET                 (RCC_OFFSET + 0x00)
52 #define HSION_BitNumber           0x00
53 #define CR_HSION_BB               (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4))
54 
55 /* Alias word address of PLLON bit */
56 #define PLLON_BitNumber           0x18
57 #define CR_PLLON_BB               (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4))
58 
59 /* Alias word address of CSSON bit */
60 #define CSSON_BitNumber           0x13
61 #define CR_CSSON_BB               (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4))
62 
63 /* --- CFGR Register ---*/
64 
65 /* Alias word address of USBPRE bit */
66 #define CFGR_OFFSET               (RCC_OFFSET + 0x04)
67 #define USBPRE_BitNumber          0x16
68 #define CFGR_USBPRE_BB            (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (USBPRE_BitNumber * 4))
69 
70 /* --- BDCR Register ---*/
71 
72 /* Alias word address of RTCEN bit */
73 #define BDCR_OFFSET               (RCC_OFFSET + 0x20)
74 #define RTCEN_BitNumber           0x0F
75 #define BDCR_RTCEN_BB             (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (RTCEN_BitNumber * 4))
76 
77 /* Alias word address of BDRST bit */
78 #define BDRST_BitNumber           0x10
79 #define BDCR_BDRST_BB             (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (BDRST_BitNumber * 4))
80 
81 /* --- CSR Register ---*/
82 
83 /* Alias word address of LSION bit */
84 #define CSR_OFFSET                (RCC_OFFSET + 0x24)
85 #define LSION_BitNumber           0x00
86 #define CSR_LSION_BB              (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4))
87 
88 /* ---------------------- RCC registers bit mask ------------------------ */
89 
90 /* CR register bit mask */
91 #define CR_HSION_Reset            ((uint32_t)0xFFFFFFFE)
92 #define CR_HSION_Set              ((uint32_t)0x00000001)
93 #define CR_HSEBYP_Reset           ((uint32_t)0xFFFBFFFF)
94 #define CR_HSEBYP_Set             ((uint32_t)0x00040000)
95 #define CR_HSEON_Reset            ((uint32_t)0xFFFEFFFF)
96 #define CR_HSEON_Set              ((uint32_t)0x00010000)
97 #define CR_HSITRIM_Mask           ((uint32_t)0xFFFFC0FF)
98 #define CR_PLLON_Reset            ((uint32_t)0xFEFFFFFF)
99 #define CR_PLLON_Set              ((uint32_t)0x01000000)
100 
101 /* CFGR register bit mask */
102 #define CFGR_PLL_Mask             ((uint32_t)0xFFC0FFFF)
103 #define CFGR_PLLMull_Mask         ((uint32_t)0x003C0000)
104 #define CFGR_PLLSRC_Mask          ((uint32_t)0x00010000)
105 #define CFGR_PLLXTPRE_Mask        ((uint32_t)0x00020000)
106 #define CFGR_SWS_Mask             ((uint32_t)0x0000000C)
107 #define CFGR_SW_Mask              ((uint32_t)0xFFFFFFFC)
108 #define CFGR_HPRE_Reset_Mask      ((uint32_t)0xFFFFFF0F)
109 #define CFGR_HPRE_Set_Mask        ((uint32_t)0x000000F0)
110 #define CFGR_PPRE1_Reset_Mask     ((uint32_t)0xFFFFF8FF)
111 #define CFGR_PPRE1_Set_Mask       ((uint32_t)0x00000700)
112 #define CFGR_PPRE2_Reset_Mask     ((uint32_t)0xFFFFC7FF)
113 #define CFGR_PPRE2_Set_Mask       ((uint32_t)0x00003800)
114 #define CFGR_ADCPRE_Reset_Mask    ((uint32_t)0xFFFF3FFF)
115 #define CFGR_ADCPRE_Set_Mask      ((uint32_t)0x0000C000)
116 
117 /* CSR register bit mask */
118 #define CSR_LSION_Set              ((uint32_t)0x00000001)
119 #define CSR_LSION_Reset            ((uint32_t)0xFFFFFFFE)
120 #define CSR_RMVF_Set               ((uint32_t)0x01000000)
121 
122 /* RCC Flag Mask */
123 #define FLAG_Mask                 ((uint8_t)0x1F)
124 
125 /* Typical Value of the HSI in Hz */
126 #define HSI_Value                 ((uint32_t)8000000)
127 
128 /* CIR register byte 2 (Bits[15:8]) base address */
129 #define CIR_BYTE2_ADDRESS         ((uint32_t)0x40021009)
130 
131 /* CIR register byte 3 (Bits[23:16]) base address */
132 #define CIR_BYTE3_ADDRESS         ((uint32_t)0x4002100A)
133 
134 /* CFGR register byte 4 (Bits[31:24]) base address */
135 #define CFGR_BYTE4_ADDRESS        ((uint32_t)0x40021007)
136 
137 /* BDCR register base address */
138 #define BDCR_ADDRESS              (PERIPH_BASE + BDCR_OFFSET)
139 
140 #ifndef HSEStartUp_TimeOut
141 /* Time out for HSE start up */
142 #define HSEStartUp_TimeOut        ((uint16_t)0x0500)
143 #endif
144 
145 /**
146 * @}
147 */
148 
149 /** @defgroup RCC_Private_Macros
150 * @{
151 */
152 
153 /**
154 * @}
155 */
156 
157 /** @defgroup RCC_Private_Variables
158 * @{
159 */
160 
161 static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
162 
163 /**
164 * @}
165 */
166 
167 /** @defgroup RCC_Private_FunctionPrototypes
168 * @{
169 */
170 
171 /**
172 * @}
173 */
174 
175 /** @defgroup RCC_Private_Functions
176 * @{
177 */
178 
179 /**
180 * @brief  Resets the RCC clock configuration to the default reset state.
181 * @param  None
182 * @retval : None
183 */
RCC_DeInit(void)184 void RCC_DeInit(void)
185 {
186     /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
187     /* Set HSION bit */
188     RCC->CR |= (uint32_t)0x1;
189 
190     /* Reset SW, HPRE, PPRE1, PPRE2 and MCO bits */
191 		RCC->CFGR &= (uint32_t)0xF8FFC00C;
192 
193     /* Reset HSEON, CSSON and PLLON bits */
194     RCC->CR &= (uint32_t)0xFEF6FFFF;
195 
196     /* Reset HSEBYP bit */
197     RCC->CR &= (uint32_t)0xFFFBFFFF;
198 
199     /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */
200     RCC->CFGR &= (uint32_t)0xFF3CFFFF;
201     RCC->CR &= (uint32_t)0x008FFFFF;
202 
203     /* Disable all interrupts  */
204     RCC->CIR &= 0xFF62E262;
205 }
206 
207 /**
208 * @brief  Configures the External High Speed oscillator (HSE).
209 *   HSE can not be stopped if it is used directly or through the
210 *   PLL as system clock.
211 * @param RCC_HSE: specifies the new state of the HSE.
212 *   This parameter can be one of the following values:
213 * @arg RCC_HSE_OFF: HSE oscillator OFF
214 * @arg RCC_HSE_ON: HSE oscillator ON
215 * @arg RCC_HSE_Bypass: HSE oscillator bypassed with external
216 *   clock
217 * @retval : None
218 */
RCC_HSEConfig(uint32_t RCC_HSE)219 void RCC_HSEConfig(uint32_t RCC_HSE)
220 {
221     /* Check the parameters */
222     assert_param(IS_RCC_HSE(RCC_HSE));
223     /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/
224     /* Reset HSEON bit */
225     RCC->CR &= CR_HSEON_Reset;
226     /* Reset HSEBYP bit */
227     RCC->CR &= CR_HSEBYP_Reset;
228     /* Configure HSE (RCC_HSE_OFF is already covered by the code section above) */
229     switch(RCC_HSE)
230     {
231     case RCC_HSE_OFF:
232         /* Reset HSEBYP and HSEON bits */
233         RCC->CR &= ~(CR_HSEBYP_Set | CR_HSEON_Set);
234         break;
235 
236 		case RCC_HSE_ON:
237         /* Set HSEON bit */
238         RCC->CR |= CR_HSEON_Set;
239         break;
240 
241     case RCC_HSE_Bypass:
242         /* Set HSEBYP and HSEON bits */
243         RCC->CR |= CR_HSEBYP_Set | CR_HSEON_Set;
244         break;
245 
246     default:
247         break;
248     }
249 }
250 
251 /**
252 * @brief  Waits for HSE start-up.
253 * @param  None
254 * @retval : An ErrorStatus enumuration value:
255 * - SUCCESS: HSE oscillator is stable and ready to use
256 * - ERROR: HSE oscillator not yet ready
257 */
RCC_WaitForHSEStartUp(void)258 ErrorStatus RCC_WaitForHSEStartUp(void)
259 {
260     __IO uint32_t StartUpCounter = 0;
261     ErrorStatus status = ERROR;
262     FlagStatus HSEStatus = RESET;
263 
264     /* Wait till HSE is ready and if Time out is reached exit */
265     do
266     {
267         HSEStatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY);
268         StartUpCounter++;
269     } while((HSEStatus == RESET) && (StartUpCounter != HSEStartUp_TimeOut));
270     if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET)
271     {
272         status = SUCCESS;
273     }
274     else
275     {
276         status = ERROR;
277     }
278     return (status);
279 }
280 
281 /**
282 * @brief  Adjusts the Internal High Speed oscillator (HSI) calibration
283 *   value.
284 * @param HSICalibrationValue: specifies the calibration trimming value.
285 *   This parameter must be a number between 0 and 0x1F.
286 * @retval : None
287 */
RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)288 void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)
289 {
290     uint32_t tmpreg = 0;
291     /* Check the parameters */
292     assert_param(IS_RCC_CALIBRATION_VALUE(HSICalibrationValue));
293     tmpreg = RCC->CR;
294     /* Clear HSICAL[5:0] bits */
295     tmpreg &= CR_HSITRIM_Mask;
296     /* Set the HSICAL[5:0] bits according to HSICalibrationValue value */
297     tmpreg |= (uint32_t)((HSICalibrationValue&0x3f)<< 8);
298     /* Store the new value */
299     RCC->CR = tmpreg;
300 }
301 
302 /**
303 * @brief  Enables or disables the Internal High Speed oscillator (HSI).
304 *   HSI can not be stopped if it is used directly or through the
305 *   PLL as system clock.
306 * @param NewState: new state of the HSI.
307 *   This parameter can be: ENABLE or DISABLE.
308 * @retval : None
309 */
RCC_HSICmd(FunctionalState NewState)310 void RCC_HSICmd(FunctionalState NewState)
311 {
312     /* Check the parameters */
313     assert_param(IS_FUNCTIONAL_STATE(NewState));
314 
315     if(NewState==ENABLE)
316     {
317         RCC->CR |= CR_HSION_Set;
318     }
319     else
320     {
321         RCC->CR &= CR_HSION_Set;
322     }
323 }
324 /**
325 * @brief  Configures the PLL clock source and DM DN factor.
326 *   This function must be used only when the PLL is disabled.
327 * @param RCC_PLLSource: specifies the PLL entry clock source.
328 *   This parameter can be one of the following values:
329 * @arg RCC_PLLSource_HSI_Div2: HSI oscillator clock divided
330 *   by 2 selected as PLL clock entry
331 * @arg RCC_PLLSource_HSE_Div1: HSE oscillator clock selected
332 *   as PLL clock entry
333 * @arg RCC_PLLSource_HSE_Div2: HSE oscillator clock divided
334 *   by 2 selected as PLL clock entry
335 * @param RCC_PLLDN: specifies the PLL multiplication factor.
336 *   This parameter can be RCC_PLLMul_x where x:[31:26]
337 * @param RCC_PLLDM: specifies the PLL Divsior factor.
338 *   This parameter can be RCC_Divsior_x where x:[22:20]
339 * @retval : None
340 */
RCC_PLLDMDNConfig(uint32_t RCC_PLLSource,uint32_t RCC_PLLDN,uint32_t RCC_PLLDM)341 void RCC_PLLDMDNConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLDN, uint32_t RCC_PLLDM)
342 {
343     uint32_t tmpreg0 = 0;
344 
345     /* Check the parameters */
346     assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource));
347     assert_param(IS_RCC_PLL_MUL(RCC_PLLMul));
348     tmpreg0 = RCC->CR;
349 
350     /* Clear PLLDN, PLLDM bits */
351     /* Clear PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */
352     tmpreg0 &= 0x038fffff;
353 
354     /* Set the PLL configuration bits */
355     tmpreg0 |= (RCC_PLLDN<<26)|(RCC_PLLDM<<20);
356 
357     RCC->CR = tmpreg0;
358 }
359 
360 
361 /**
362 * @brief  Configures the PLL clock source and multiplication factor.
363 *   This function must be used only when the PLL is disabled.
364 * @param RCC_PLLSource: specifies the PLL entry clock source.
365 *   This parameter can be one of the following values:
366 * @arg RCC_PLLSource_HSI_Div2: HSI oscillator clock divided
367 *   by 2 selected as PLL clock entry
368 * @arg RCC_PLLSource_HSE_Div1: HSE oscillator clock selected
369 *   as PLL clock entry
370 * @arg RCC_PLLSource_HSE_Div2: HSE oscillator clock divided
371 *   by 2 selected as PLL clock entry
372 * @param RCC_PLLMul: specifies the PLL multiplication factor.
373 *   This parameter can be RCC_PLLMul_x where x:[31:26][22:20]
374 * @retval : None
375 */
RCC_PLLConfig(uint32_t RCC_PLLSource,uint32_t RCC_PLLMul)376 void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul)
377 {
378     uint32_t tmpreg = 0;
379     /* Check the parameters */
380     assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource));
381     assert_param(IS_RCC_PLL_MUL(RCC_PLLMul));
382     tmpreg = RCC->CFGR;
383     /* Clear PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */
384     tmpreg &= CFGR_PLL_Mask;
385     /* Set the PLL configuration bits */
386     tmpreg |= RCC_PLLSource;
387     /* Store the new value */
388     RCC->CFGR = tmpreg;
389 
390     if(RCC_PLLMul==RCC_PLLMul_2)
391     {
392         RCC_PLLDMDNConfig(RCC_PLLSource, 0x00000007, 0x00000003); //Frclk*8/4
393     }
394     if(RCC_PLLMul==RCC_PLLMul_3)
395     {
396         RCC_PLLDMDNConfig(RCC_PLLSource, 0x00000005, 0x00000001);//Frclk*6/2
397     }
398     if(RCC_PLLMul==RCC_PLLMul_4)
399     {
400         RCC_PLLDMDNConfig(RCC_PLLSource, 0x00000007, 0x00000001);//Frclk*8/2
401     }
402     if(RCC_PLLMul==RCC_PLLMul_5)
403     {
404         RCC_PLLDMDNConfig(RCC_PLLSource, 0x00000009, 0x00000001);//Frclk*10/2
405     }
406     if(RCC_PLLMul==RCC_PLLMul_6)
407     {
408         RCC_PLLDMDNConfig(RCC_PLLSource, 0x0000000B, 0x00000001);//Frclk*12/2
409     }
410     if(RCC_PLLMul==RCC_PLLMul_7)
411     {
412         RCC_PLLDMDNConfig(RCC_PLLSource, 0x0000000D, 0x00000001);//Frclk*14/2
413     }
414     if(RCC_PLLMul==RCC_PLLMul_8)
415     {
416         RCC_PLLDMDNConfig(RCC_PLLSource, 0x0000000F, 0x00000001);//Frclk*16/2
417     }
418     if(RCC_PLLMul==RCC_PLLMul_9)
419     {
420         RCC_PLLDMDNConfig(RCC_PLLSource, 0x00000011, 0x00000001);//Frclk*18/2
421     }
422     if(RCC_PLLMul==RCC_PLLMul_10)
423     {
424         RCC_PLLDMDNConfig(RCC_PLLSource, 0x00000013, 0x00000001);//Frclk*20/2
425     }
426     if(RCC_PLLMul==RCC_PLLMul_11)
427     {
428         RCC_PLLDMDNConfig(RCC_PLLSource, 0x00000015, 0x00000001);//Frclk*22/2
429     }
430     if(RCC_PLLMul==RCC_PLLMul_12)
431     {
432         RCC_PLLDMDNConfig(RCC_PLLSource, 0x00000017, 0x00000001);//Frclk*24/2
433     }
434     if(RCC_PLLMul==RCC_PLLMul_13)
435     {
436         RCC_PLLDMDNConfig(RCC_PLLSource, 0x00000019, 0x00000001);//Frclk*26/2
437     }
438     if(RCC_PLLMul==RCC_PLLMul_14)
439     {
440         RCC_PLLDMDNConfig(RCC_PLLSource, 0x0000001B, 0x00000001);//Frclk*28/2
441     }
442     if(RCC_PLLMul==RCC_PLLMul_15)
443     {
444         RCC_PLLDMDNConfig(RCC_PLLSource, 0x0000001D, 0x00000001);//Frclk*30/2
445     }
446     if(RCC_PLLMul==RCC_PLLMul_16)
447     {
448         RCC_PLLDMDNConfig(RCC_PLLSource, 0x0000001F, 0x00000001);//Frclk*32/2
449     }
450 
451 }
452 
453 
454 /**
455 * @brief  Enables or disables the PLL.
456 *   The PLL can not be disabled if it is used as system clock.
457 * @param NewState: new state of the PLL.
458 *   This parameter can be: ENABLE or DISABLE.
459 * @retval : None
460 */
RCC_PLLCmd(FunctionalState NewState)461 void RCC_PLLCmd(FunctionalState NewState)
462 {
463     /* Check the parameters */
464     assert_param(IS_FUNCTIONAL_STATE(NewState));
465 
466     if (NewState != DISABLE)
467     {
468         RCC->CR |= CR_PLLON_Set;
469     }
470     else
471     {
472         RCC->CR &= CR_PLLON_Reset;
473     }
474 }
475 
476 /**
477 * @brief  Configures the system clock (SYSCLK).
478 * @param RCC_SYSCLKSource: specifies the clock source used as system
479 *   clock. This parameter can be one of the following values:
480 * @arg RCC_SYSCLKSource_HSI: HSI selected as system clock
481 * @arg RCC_SYSCLKSource_HSE: HSE selected as system clock
482 * @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock
483 * @arg RCC_SYSCLKSource_LSI: LSI selected as system clock
484 * @retval : None
485 */
RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)486 void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
487 {
488     uint32_t tmpreg = 0;
489     /* Check the parameters */
490     assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource));
491     tmpreg = RCC->CFGR;
492     /* Clear SW[1:0] bits */
493     tmpreg &= CFGR_SW_Mask;
494     /* Set SW[1:0] bits according to RCC_SYSCLKSource value */
495     tmpreg |= RCC_SYSCLKSource;
496     /* Store the new value */
497     RCC->CFGR = tmpreg;
498 }
499 
500 /**
501 * @brief  Returns the clock source used as system clock.
502 * @param  None
503 * @retval : The clock source used as system clock. The returned value can
504 *   be one of the following:
505 * - 0x00: HSI/6 used as system clock
506 * - 0x04: HSE used as system clock
507 * - 0x08: PLL used as system clock
508 * - 0x0C: LSI used as system clock
509 */
RCC_GetSYSCLKSource(void)510 uint8_t RCC_GetSYSCLKSource(void)
511 {
512     return ((uint8_t)(RCC->CFGR & CFGR_SWS_Mask));
513 }
514 
515 /**
516 * @brief  Configures the AHB clock (HCLK).
517 * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from
518 *                    the system clock (SYSCLK).
519 *   This parameter can be one of the following values:
520 * @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK
521 * @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2
522 * @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4
523 * @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8
524 * @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16
525 * @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64
526 * @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128
527 * @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256
528 * @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512
529 * @retval : None
530 */
RCC_HCLKConfig(uint32_t RCC_SYSCLK)531 void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
532 {
533     uint32_t tmpreg = 0;
534     /* Check the parameters */
535     assert_param(IS_RCC_HCLK(RCC_SYSCLK));
536     tmpreg = RCC->CFGR;
537     /* Clear HPRE[3:0] bits */
538     tmpreg &= CFGR_HPRE_Reset_Mask;
539     /* Set HPRE[3:0] bits according to RCC_SYSCLK value */
540     tmpreg |= RCC_SYSCLK;
541     /* Store the new value */
542     RCC->CFGR = tmpreg;
543 }
544 
545 /**
546 * @brief  Configures the Low Speed APB clock (PCLK1).
547 * @param RCC_HCLK: defines the APB1 clock divider. This clock is derived from
548 *                  the AHB clock (HCLK).
549 *   This parameter can be one of the following values:
550 * @arg RCC_HCLK_Div1: APB1 clock = HCLK
551 * @arg RCC_HCLK_Div2: APB1 clock = HCLK/2
552 * @arg RCC_HCLK_Div4: APB1 clock = HCLK/4
553 * @arg RCC_HCLK_Div8: APB1 clock = HCLK/8
554 * @arg RCC_HCLK_Div16: APB1 clock = HCLK/16
555 * @retval : None
556 */
RCC_PCLK1Config(uint32_t RCC_HCLK)557 void RCC_PCLK1Config(uint32_t RCC_HCLK)
558 {
559     uint32_t tmpreg = 0;
560     /* Check the parameters */
561     assert_param(IS_RCC_PCLK(RCC_HCLK));
562     tmpreg = RCC->CFGR;
563     /* Clear PPRE1[2:0] bits */
564     tmpreg &= CFGR_PPRE1_Reset_Mask;
565     /* Set PPRE1[2:0] bits according to RCC_HCLK value */
566     tmpreg |= RCC_HCLK;
567     /* Store the new value */
568     RCC->CFGR = tmpreg;
569 }
570 
571 /**
572 * @brief  Configures the High Speed APB clock (PCLK2).
573 * @param RCC_HCLK: defines the APB2 clock divider. This clock is derived from
574 *                  the AHB clock (HCLK).
575 *   This parameter can be one of the following values:
576 * @arg RCC_HCLK_Div1: APB2 clock = HCLK
577 * @arg RCC_HCLK_Div2: APB2 clock = HCLK/2
578 * @arg RCC_HCLK_Div4: APB2 clock = HCLK/4
579 * @arg RCC_HCLK_Div8: APB2 clock = HCLK/8
580 * @arg RCC_HCLK_Div16: APB2 clock = HCLK/16
581 * @retval : None
582 */
RCC_PCLK2Config(uint32_t RCC_HCLK)583 void RCC_PCLK2Config(uint32_t RCC_HCLK)
584 {
585     uint32_t tmpreg = 0;
586     /* Check the parameters */
587     assert_param(IS_RCC_PCLK(RCC_HCLK));
588     tmpreg = RCC->CFGR;
589     /* Clear PPRE2[2:0] bits */
590     tmpreg &= CFGR_PPRE2_Reset_Mask;
591     /* Set PPRE2[2:0] bits according to RCC_HCLK value */
592     tmpreg |= RCC_HCLK << 3;
593     /* Store the new value */
594     RCC->CFGR = tmpreg;
595 }
596 
597 /**
598 * @brief  Enables or disables the specified RCC interrupts.
599 * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled.
600 *   This parameter can be any combination of the following values:
601 * @arg RCC_IT_LSIRDY: LSI ready interrupt
602 * @arg RCC_IT_LSERDY: LSE ready interrupt
603 * @arg RCC_IT_HSIRDY: HSI ready interrupt
604 * @arg RCC_IT_HSERDY: HSE ready interrupt
605 * @arg RCC_IT_PLLRDY: PLL ready interrupt
606 * @param NewState: new state of the specified RCC interrupts.
607 *   This parameter can be: ENABLE or DISABLE.
608 * @retval : None
609 */
RCC_ITConfig(uint8_t RCC_IT,FunctionalState NewState)610 void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState)
611 {
612     /* Check the parameters */
613     assert_param(IS_RCC_IT(RCC_IT));
614     assert_param(IS_FUNCTIONAL_STATE(NewState));
615     if (NewState != DISABLE)
616     {
617         /* Perform Byte access to RCC_CIR[12:8] bits to enable the selected interrupts */
618 
619         RCC->CIR |= ((uint32_t)RCC_IT)<<8;
620     }
621     else
622     {
623         /* Perform Byte access to RCC_CIR[12:8] bits to disable the selected interrupts */
624 
625         RCC->CIR &= ~((uint32_t)RCC_IT<<8);
626     }
627 }
628 
629 /**
630 * @brief  Configures the USB clock (USBCLK).
631 * @param RCC_USBCLKSource: specifies the USB clock source. This clock is
632 *                          derived from the PLL output.
633 *   This parameter can be one of the following values:
634 
635 * @arg RCC_USBCLKSource_PLLCLK_Div1: PLL clock selected as USB clock source
636 * @arg RCC_USBCLKSource_PLLCLK_Div2: PLL clock Div2 selected as USB clock source
637 * @arg RCC_USBCLKSource_PLLCLK_Div3: PLL clock Div3 selected as USB clock source
638 * @arg RCC_USBCLKSource_PLLCLK_Div4: PLL clock Div4 selected as USB clock source
639 * @retval : None
640 */
RCC_USBCLKConfig(uint32_t RCC_USBCLKSource)641 void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource)
642 {
643     /* Check the parameters */
644     assert_param(IS_RCC_USBCLK_SOURCE(RCC_USBCLKSource));
645     RCC->CFGR &= 0xff3fffff;
646     RCC->CFGR |= RCC_USBCLKSource;
647 }
648 
649 /**
650 * @brief  Enables or disables the Internal Low Speed oscillator (LSI).
651 *   LSI can not be disabled if the IWDG is running.
652 * @param NewState: new state of the LSI.
653 *   This parameter can be: ENABLE or DISABLE.
654 * @retval : None
655 */
RCC_LSICmd(FunctionalState NewState)656 void RCC_LSICmd(FunctionalState NewState)
657 {
658     /* Check the parameters */
659     assert_param(IS_FUNCTIONAL_STATE(NewState));
660 
661     if (NewState != DISABLE)
662     {
663         RCC->CSR |= CSR_LSION_Set;
664     }
665     else
666     {
667         RCC->CSR &= CSR_LSION_Reset;
668     }
669 }
670 
671 
672 /**
673 * @brief  Returns the frequencies of different on chip clocks.
674 * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which
675 *   will hold the clocks frequencies.
676 * @retval : None
677 */
RCC_GetClocksFreq(RCC_ClocksTypeDef * RCC_Clocks)678 void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
679 {
680     uint32_t tmp = 0, pllmull1 = 0,pllmull2 = 0, pllsource = 0, presc = 0;
681     /* Get SYSCLK source -------------------------------------------------------*/
682     tmp = RCC->CFGR & CFGR_SWS_Mask;
683     switch (tmp)
684     {
685     case 0x00:  /* HSI used as system clock */
686         RCC_Clocks->SYSCLK_Frequency = HSI_Value_Pll_OFF;
687         break;
688     case 0x04:  /* HSE used as system clock */
689         RCC_Clocks->SYSCLK_Frequency = HSE_Value;
690         break;
691     case 0x08:  /* PLL used as system clock */
692         /* Get PLL clock source and multiplication factor ----------------------*/
693         pllmull1 = ((RCC->CR&0xfc000000)>>26)+1;
694         pllmull2 = ((RCC->CR&0x00700000)>>20)+1;
695         pllsource = RCC->CFGR & CFGR_PLLSRC_Mask;
696         if (pllsource == 0x00)
697         {/* HSI oscillator clock divided by 2 selected as PLL clock entry */
698             RCC_Clocks->SYSCLK_Frequency = 2*(HSI_Value_Pll_ON >> 1) * pllmull1/pllmull2;
699         }
700         else
701         {/* HSE selected as PLL clock entry */
702             if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET)
703             {/* HSE oscillator clock divided by 2 */
704                 RCC_Clocks->SYSCLK_Frequency = (HSE_Value >> 1) * pllmull1/pllmull2;
705             }
706             else
707             {
708                 RCC_Clocks->SYSCLK_Frequency = HSE_Value * pllmull1/pllmull2;
709             }
710         }
711         break;
712     default:
713         RCC_Clocks->SYSCLK_Frequency = HSI_Value_Pll_OFF;
714         break;
715     }
716     /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/
717     /* Get HCLK prescaler */
718     tmp = RCC->CFGR & CFGR_HPRE_Set_Mask;
719     tmp = tmp >> 4;
720     presc = APBAHBPrescTable[tmp];
721     /* HCLK clock frequency */
722     RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
723     /* Get PCLK1 prescaler */
724     tmp = RCC->CFGR & CFGR_PPRE1_Set_Mask;
725     tmp = tmp >> 8;
726     presc = APBAHBPrescTable[tmp];
727     /* PCLK1 clock frequency */
728     RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
729     /* Get PCLK2 prescaler */
730     tmp = RCC->CFGR & CFGR_PPRE2_Set_Mask;
731     tmp = tmp >> 11;
732     presc = APBAHBPrescTable[tmp];
733     /* PCLK2 clock frequency */
734     RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
735 }
736 
737 /**
738 * @brief  Enables or disables the AHB peripheral clock.
739 * @param RCC_AHBPeriph: specifies the AHB peripheral to gates its clock.
740 *   This parameter can be any combination of the following values:
741 * @arg RCC_AHBPeriph_DMA1
742 * @arg RCC_AHBPeriph_SRAM
743 * @arg RCC_AHBPeriph_FLITF
744 * @arg RCC_AHBPeriph_AES
745 * @arg RCC_AHBPeriph_GPIOA
746 * @arg RCC_AHBPeriph_GPIOB
747 * @arg RCC_AHBPeriph_GPIOC
748 * @arg RCC_AHBPeriph_GPIOD
749 *   SRAM and FLITF clock can be disabled only during sleep mode.
750 * @param NewState: new state of the specified peripheral clock.
751 *   This parameter can be: ENABLE or DISABLE.
752 * @retval : None
753 */
RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph,FunctionalState NewState)754 void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
755 {
756     /* Check the parameters */
757     assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph));
758     assert_param(IS_FUNCTIONAL_STATE(NewState));
759     if (NewState != DISABLE)
760     {
761         RCC->AHBENR |= RCC_AHBPeriph;
762     }
763     else
764     {
765         RCC->AHBENR &= ~RCC_AHBPeriph;
766     }
767 }
768 
769 /**
770 * @brief  Enables or disables the High Speed APB (APB2) peripheral clock.
771 * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its
772 *   clock.
773 *   This parameter can be any combination of the following values:
774 * @arg RCC_APB2Periph_SYSCFG,  RCC_APB2Periph_ADC1,
775 *   RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,
776 *   RCC_APB2Periph_UART1, RCC_APB2Periph_COMP,
777 *   RCC_APB2Periph_TIM14, RCC_APB2Periph_TIM16,
778 *   RCC_APB2Periph_TIM17, RCC_APB2Periph_DBGMCU
779 *   RCC_APB2Periph_ALL
780 * @param NewState: new state of the specified peripheral clock.
781 *   This parameter can be: ENABLE or DISABLE.
782 * @retval : None
783 */
RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph,FunctionalState NewState)784 void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
785 {
786     /* Check the parameters */
787     assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
788     assert_param(IS_FUNCTIONAL_STATE(NewState));
789     if (NewState != DISABLE)
790     {
791         RCC->APB2ENR |= RCC_APB2Periph;
792     }
793     else
794     {
795         RCC->APB2ENR &= ~RCC_APB2Periph;
796     }
797 }
798 
799 /**
800 * @brief  Enables or disables the Low Speed APB (APB1) peripheral clock.
801 * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its
802 *   clock.
803 *   This parameter can be any combination of the following values:
804 * @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3,
805 *   RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2,
806 *   RCC_APB1Periph_UART2, RCC_APB1Periph_I2C1,
807 *   RCC_APB1Periph_USB, RCC_APB1Periph_CAN1,
808 *   RCC_APB1Periph_PWR, RCC_APB1Periph_CRS,
809 *   RCC_APB1Periph_ALL
810 * @param NewState: new state of the specified peripheral clock.
811 *   This parameter can be: ENABLE or DISABLE.
812 * @retval : None
813 */
RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph,FunctionalState NewState)814 void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
815 {
816     /* Check the parameters */
817     assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
818     assert_param(IS_FUNCTIONAL_STATE(NewState));
819     if (NewState != DISABLE)
820     {
821         RCC->APB1ENR |= RCC_APB1Periph;
822     }
823     else
824     {
825         RCC->APB1ENR &= ~RCC_APB1Periph;
826     }
827 }
828 
829 /**
830 * @brief  Forces or releases High Speed APB (APB2) peripheral reset.
831 * @param RCC_APB2Periph: specifies the APB2 peripheral to reset.
832 *   This parameter can be any combination of the following values:
833 * @arg RCC_APB2Periph_SYSCFG,  RCC_APB2Periph_ADC1,
834 *   RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,
835 *   RCC_APB2Periph_UART1, RCC_APB2Periph_COMP,
836 *   RCC_APB2Periph_TIM14, RCC_APB2Periph_TIM16,
837 *   RCC_APB2Periph_TIM17, RCC_APB2Periph_DBGMCU
838 *   RCC_APB2Periph_ALL
839 * @param NewState: new state of the specified peripheral reset.
840 *   This parameter can be: ENABLE or DISABLE.
841 * @retval : None
842 */
RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph,FunctionalState NewState)843 void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
844 {
845     /* Check the parameters */
846     assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
847     assert_param(IS_FUNCTIONAL_STATE(NewState));
848     if (NewState != DISABLE)
849     {
850         RCC->APB2RSTR |= RCC_APB2Periph;
851     }
852     else
853     {
854         RCC->APB2RSTR &= ~RCC_APB2Periph;
855     }
856 }
857 
858 /**
859 * @brief  Forces or releases Low Speed APB (APB1) peripheral reset.
860 * @param RCC_APB1Periph: specifies the APB1 peripheral to reset.
861 *   This parameter can be any combination of the following values:
862 * @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3,
863 *   RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2,
864 *   RCC_APB1Periph_UART2, RCC_APB1Periph_I2C1,
865 *   RCC_APB1Periph_USB, RCC_APB1Periph_CAN1,
866 *   RCC_APB1Periph_PWR, RCC_APB1Periph_CRS,
867 *   RCC_APB1Periph_ALL
868 * @param NewState: new state of the specified peripheral clock.
869 *   This parameter can be: ENABLE or DISABLE.
870 * @retval : None
871 */
RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph,FunctionalState NewState)872 void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
873 {
874     /* Check the parameters */
875     assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
876     assert_param(IS_FUNCTIONAL_STATE(NewState));
877     if (NewState != DISABLE)
878     {
879         RCC->APB1RSTR |= RCC_APB1Periph;
880     }
881     else
882     {
883         RCC->APB1RSTR &= ~RCC_APB1Periph;
884     }
885 }
886 
887 
888 /**
889 * @brief  Enables or disables the Clock Security System.
890 * @param NewState: new state of the Clock Security System..
891 *   This parameter can be: ENABLE or DISABLE.
892 * @retval : None
893 */
RCC_ClockSecuritySystemCmd(FunctionalState NewState)894 void RCC_ClockSecuritySystemCmd(FunctionalState NewState)
895 {
896     /* Check the parameters */
897     assert_param(IS_FUNCTIONAL_STATE(NewState));
898 
899     if(NewState==ENABLE)
900     {
901         RCC->CR |= (uint32_t)0x00080000;
902     }
903     else
904     {
905         RCC->CR &= (uint32_t)0xfff7ffff;
906     }
907 }
908 
909 /**
910 * @brief  Selects the clock source to output on MCO pin.
911 * @param RCC_MCO: specifies the clock source to output.
912 *   This parameter can be one of the following values:
913 * @arg RCC_MCO_NoClock: No clock selected
914 * @arg RCC_MCO_SYSCLK: System clock selected
915 * @arg RCC_MCO_HSI: HSI oscillator clock selected
916 * @arg RCC_MCO_HSE: HSE oscillator clock selected
917 * @arg RCC_MCO_PLLCLK_Div2: PLL clock divided by 2 selected
918 * @arg RCC_MCO_LSI: LSI clock selected
919 * @retval : None
920 */
RCC_MCOConfig(uint8_t RCC_MCO)921 void RCC_MCOConfig(uint8_t RCC_MCO)
922 {
923     /* Check the parameters */
924     assert_param(IS_RCC_MCO(RCC_MCO));
925     /* Perform Byte access to MCO[2:0] bits to select the MCO source */
926     RCC->CFGR &= 0xF8FFFFFF;
927     RCC->CFGR |= (RCC_MCO<<24);
928 }
929 
930 /**
931 * @brief  Checks whether the specified RCC flag is set or not.
932 * @param RCC_FLAG: specifies the flag to check.
933 *   This parameter can be one of the following values:
934 * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready
935 * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready
936 * @arg RCC_FLAG_PLLRDY: PLL clock ready
937 * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready
938 * @arg RCC_FLAG_PINRST: Pin reset
939 * @arg RCC_FLAG_PORRST: POR/PDR reset
940 * @arg RCC_FLAG_SFTRST: Software reset
941 * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset
942 * @arg RCC_FLAG_WWDGRST: Window Watchdog reset
943 * @retval : The new state of RCC_FLAG (SET or RESET).
944 */
RCC_GetFlagStatus(uint8_t RCC_FLAG)945 FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
946 {
947     uint32_t tmp = 0;
948     uint32_t statusreg = 0;
949     FlagStatus bitstatus = RESET;
950     /* Check the parameters */
951     assert_param(IS_RCC_FLAG(RCC_FLAG));
952     /* Get the RCC register index */
953     tmp = RCC_FLAG >> 5;
954     if (tmp == 1)               /* The flag to check is in CR register */
955     {
956         statusreg = RCC->CR;
957     }
958     else                       /* The flag to check is in CSR register */
959     {
960         statusreg = RCC->CSR;
961     }
962     /* Get the flag position */
963     tmp = RCC_FLAG & FLAG_Mask;
964     if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET)
965     {
966         bitstatus = SET;
967     }
968     else
969     {
970         bitstatus = RESET;
971     }
972     /* Return the flag status */
973     return bitstatus;
974 }
975 
976 /**
977 * @brief  Clears the RCC reset flags.
978 *   The reset flags are: RCC_FLAG_PINRST, RCC_FLAG_PORRST,
979 *   RCC_FLAG_SFTRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST
980 * @param  None
981 * @retval : None
982 */
RCC_ClearFlag(void)983 void RCC_ClearFlag(void)
984 {
985     /* Set RMVF bit to clear the reset flags */
986     RCC->CSR |= CSR_RMVF_Set;
987 }
988 
989 /**
990 * @brief  Checks whether the specified RCC interrupt has occurred or not.
991 * @param RCC_IT: specifies the RCC interrupt source to check.
992 *   This parameter can be one of the following values:
993 * @arg RCC_IT_LSIRDY: LSI ready interrupt
994 * @arg RCC_IT_HSIRDY: HSI ready interrupt
995 * @arg RCC_IT_HSERDY: HSE ready interrupt
996 * @arg RCC_IT_PLLRDY: PLL ready interrupt
997 * @arg RCC_IT_CSS: Clock Security System interrupt
998 * @retval : The new state of RCC_IT (SET or RESET).
999 */
RCC_GetITStatus(uint8_t RCC_IT)1000 ITStatus RCC_GetITStatus(uint8_t RCC_IT)
1001 {
1002     ITStatus bitstatus = RESET;
1003     /* Check the parameters */
1004     assert_param(IS_RCC_GET_IT(RCC_IT));
1005     /* Check the status of the specified RCC interrupt */
1006     if ((RCC->CIR & RCC_IT) != (uint32_t)RESET)
1007     {
1008         bitstatus = SET;
1009     }
1010     else
1011     {
1012         bitstatus = RESET;
1013     }
1014     /* Return the RCC_IT status */
1015     return  bitstatus;
1016 }
1017 
1018 /**
1019 * @brief  Clears the RCC interrupt pending bits.
1020 * @param RCC_IT: specifies the interrupt pending bit to clear.
1021 *   This parameter can be any combination of the following values:
1022 * @arg RCC_IT_LSIRDY: LSI ready interrupt
1023 * @arg RCC_IT_HSIRDY: HSI ready interrupt
1024 * @arg RCC_IT_HSERDY: HSE ready interrupt
1025 * @arg RCC_IT_PLLRDY: PLL ready interrupt
1026 * @arg RCC_IT_CSS: Clock Security System interrupt
1027 * @retval : None
1028 */
RCC_ClearITPendingBit(uint8_t RCC_IT)1029 void RCC_ClearITPendingBit(uint8_t RCC_IT)
1030 {
1031     /* Check the parameters */
1032     assert_param(IS_RCC_CLEAR_IT(RCC_IT));
1033     /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt
1034     pending bits */
1035 
1036     RCC->CIR |= (uint32_t)RCC_IT<<16;
1037 }
1038 
1039 /**
1040 * @}
1041 */
1042 
1043 /**
1044 * @}
1045 */
1046 
1047 /**
1048 * @}
1049 */
1050 
1051 /*-------------------------(C) COPYRIGHT 2017 MindMotion ----------------------*/
1052