38
38
* in "stm32l1xx.h" file. When HSE is used as system clock source, directly or
39
39
* through PLL, and you are using different crystal you have to adapt the HSE
40
40
* value to your own configuration.
41
- *
42
- * 5. This file configures the system clock as follows:
43
- *=============================================================================
44
- * System Clock Configuration
45
- *=============================================================================
46
- * System Clock source | PLL(HSI)
47
- *-----------------------------------------------------------------------------
48
- * SYSCLK | 32000000 Hz
49
- *-----------------------------------------------------------------------------
50
- * HCLK | 32000000 Hz
51
- *-----------------------------------------------------------------------------
52
- * AHB Prescaler | 1
53
- *-----------------------------------------------------------------------------
54
- * APB1 Prescaler | 1
55
- *-----------------------------------------------------------------------------
56
- * APB2 Prescaler | 1
57
- *-----------------------------------------------------------------------------
58
- * HSE Frequency | Not used
59
- *-----------------------------------------------------------------------------
60
- * PLL DIV | 2
61
- *-----------------------------------------------------------------------------
62
- * PLL MUL | 4
63
- *-----------------------------------------------------------------------------
64
- * VDD | 3.3 V
65
- *-----------------------------------------------------------------------------
66
- * Vcore | 1.8 V (Range 1)
67
- *-----------------------------------------------------------------------------
68
- * Flash Latency | 1 WS
69
- *-----------------------------------------------------------------------------
70
- * Require 48MHz for USB clock | Disabled
71
- *-----------------------------------------------------------------------------
72
- *=============================================================================
41
+ *
42
+ * 5. This file configures the system clock as follows:
43
+ *-----------------------------------------------------------------------------
44
+ * System clock source | 1- PLL_HSE_EXTC | 3- PLL_HSI
45
+ * | (external 8 MHz clock) | (internal 16 MHz)
46
+ * | 2- PLL_HSE_XTAL |
47
+ * | (external 8 MHz xtal) |
48
+ *-----------------------------------------------------------------------------
49
+ * SYSCLK(MHz) | 24 | 32
50
+ *-----------------------------------------------------------------------------
51
+ * AHBCLK (MHz) | 24 | 32
52
+ *-----------------------------------------------------------------------------
53
+ * APB1CLK (MHz) | 24 | 32
54
+ *-----------------------------------------------------------------------------
55
+ * APB2CLK (MHz) | 24 | 32
56
+ *-----------------------------------------------------------------------------
57
+ * USB capable (48 MHz precise clock) | YES | NO
58
+ *-----------------------------------------------------------------------------
59
+ ******************************************************************************
73
60
* @attention
74
61
*
75
62
* <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
142
129
* @{
143
130
*/
144
131
132
+ /* Select the clock sources (other than HSI) to start with (0=OFF, 1=ON) */
133
+ #define USE_PLL_HSE_EXTC (1) /* Use external clock */
134
+ #define USE_PLL_HSE_XTAL (1) /* Use external xtal */
135
+
145
136
/**
146
137
* @}
147
138
*/
148
139
149
140
/** @addtogroup STM32L1xx_System_Private_Variables
150
141
* @{
151
142
*/
152
- uint32_t SystemCoreClock = 32000000 ;
143
+
144
+ uint32_t SystemCoreClock = 32000000 ; /* Default with HSI. Will be updated if HSE is used */
145
+
153
146
__I uint8_t PLLMulTable [9 ] = {3 , 4 , 6 , 8 , 12 , 16 , 24 , 32 , 48 };
154
147
__I uint8_t AHBPrescTable [16 ] = {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 };
155
148
@@ -163,6 +156,12 @@ __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}
163
156
164
157
void SetSysClock (void );
165
158
159
+ #if (USE_PLL_HSE_XTAL != 0 ) || (USE_PLL_HSE_EXTC != 0 )
160
+ uint8_t SetSysClock_PLL_HSE (uint8_t bypass );
161
+ #endif
162
+
163
+ uint8_t SetSysClock_PLL_HSI (void );
164
+
166
165
/**
167
166
* @}
168
167
*/
@@ -198,35 +197,20 @@ void SystemInit (void)
198
197
/*!< Disable all interrupts */
199
198
RCC -> CIR = 0x00000000 ;
200
199
201
- /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
200
+ /* Configure the System clock source, PLL Multiplier and Divider factors,
201
+ AHB/APBx prescalers and Flash settings */
202
202
SetSysClock ();
203
203
204
+ /* Configure the Vector Table location add offset address ------------------*/
204
205
#ifdef VECT_TAB_SRAM
205
- SCB -> VTOR = SRAM_BASE | VECT_TAB_OFFSET ; /* Vector Table Relocation in Internal SRAM. */
206
+ SCB -> VTOR = SRAM_BASE | VECT_TAB_OFFSET ; /* Vector Table Relocation in Internal SRAM */
206
207
#else
207
- SCB -> VTOR = FLASH_BASE | VECT_TAB_OFFSET ; /* Vector Table Relocation in Internal FLASH. */
208
+ SCB -> VTOR = FLASH_BASE | VECT_TAB_OFFSET ; /* Vector Table Relocation in Internal FLASH */
208
209
#endif
209
-
210
- /* ADDED FOR MBED DEBUG PURPOSE */
211
- /*
212
- // Enable the GPIOA peripheral
213
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
214
- // Output the system clock on MCO pin (PA.08)
215
- GPIO_InitTypeDef GPIO_InitStructure;
216
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
217
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
218
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
219
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
220
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
221
- GPIO_Init(GPIOA, &GPIO_InitStructure);
222
- // Select the clock to output on MCO pin (PA.08)
223
- RCC_MCOConfig(RCC_MCOSource_SYSCLK, RCC_MCODiv_1);
224
- //RCC_MCOConfig(RCC_MCOSource_HSI, RCC_MCODiv_1);
225
- */
226
210
}
227
211
228
212
/**
229
- * @brief Update SystemCoreClock according to Clock Register Values
213
+ * @brief Update SystemCoreClock variable according to Clock Register Values.
230
214
* The SystemCoreClock variable contains the core clock (HCLK), it can
231
215
* be used by the user application to setup the SysTick timer or configure
232
216
* other parameters.
@@ -315,50 +299,98 @@ void SystemCoreClockUpdate (void)
315
299
}
316
300
317
301
/**
318
- * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash
319
- * settings.
302
+ * @brief Configures the System clock source, PLL Multiplier and Divider factors,
303
+ * AHB/APBx prescalers and Flash settings
320
304
* @note This function should be called only once the RCC clock configuration
321
305
* is reset to the default reset state (done in SystemInit() function).
322
306
* @param None
323
307
* @retval None
324
308
*/
325
309
void SetSysClock (void )
326
310
{
327
- __IO uint32_t StartUpCounter = 0 , HSIStatus = 0 ;
328
-
329
- /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
330
- /* Enable HSI */
331
- RCC -> CR |= ((uint32_t )RCC_CR_HSION );
332
-
333
- /* Wait till HSI is ready and if Time out is reached exit */
334
- do
311
+ /* 1- Try to start with HSE and external clock */
312
+ #if USE_PLL_HSE_EXTC != 0
313
+ if (SetSysClock_PLL_HSE (1 ) == 0 )
314
+ #endif
335
315
{
336
- HSIStatus = RCC -> CR & RCC_CR_HSIRDY ;
337
- } while ((HSIStatus == 0 ) && (StartUpCounter != HSI_STARTUP_TIMEOUT ));
316
+ /* 2- If fail try to start with HSE and external xtal */
317
+ #if USE_PLL_HSE_XTAL != 0
318
+ if (SetSysClock_PLL_HSE (0 ) == 0 )
319
+ #endif
320
+ {
321
+ /* 3- If fail start with HSI clock */
322
+ if (SetSysClock_PLL_HSI () == 0 )
323
+ {
324
+ while (1 )
325
+ {
326
+ // [TODO] Put something here to tell the user that a problem occured...
327
+ }
328
+ }
329
+ }
330
+ }
331
+
332
+ /* Output SYSCLK on MCO pin(PA8) for debugging purpose */
333
+ /*
334
+ // Enable GPIOA clock
335
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
336
+ // Configure MCO pin (PA8)
337
+ GPIO_InitTypeDef GPIO_InitStructure;
338
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
339
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
340
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
341
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
342
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
343
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
344
+ // Select the clock to output
345
+ RCC_MCOConfig(RCC_MCOSource_SYSCLK, RCC_MCODiv_1);
346
+ */
347
+ }
338
348
339
- if ((RCC -> CR & RCC_CR_HSIRDY ) != RESET )
349
+ #if (USE_PLL_HSE_XTAL != 0 ) || (USE_PLL_HSE_EXTC != 0 )
350
+ /******************************************************************************/
351
+ /* PLL (clocked by HSE) used as System clock source */
352
+ /******************************************************************************/
353
+ uint8_t SetSysClock_PLL_HSE (uint8_t bypass )
354
+ {
355
+ __IO uint32_t StartUpCounter = 0 ;
356
+ __IO uint32_t HSEStatus = 0 ;
357
+
358
+ /* Bypass HSE: can be done only if HSE is OFF */
359
+ RCC -> CR &= ((uint32_t )~RCC_CR_HSEON ); /* To be sure HSE is OFF */
360
+ if (bypass != 0 )
340
361
{
341
- HSIStatus = (uint32_t )0x01 ;
362
+ RCC -> CR | = (( uint32_t )RCC_CR_HSEBYP ) ;
342
363
}
343
364
else
344
365
{
345
- HSIStatus = (uint32_t )0x00 ;
366
+ RCC -> CR & = (( uint32_t )~ RCC_CR_HSEBYP ) ;
346
367
}
347
-
348
- if (HSIStatus == (uint32_t )0x01 )
368
+
369
+ /* Enable HSE */
370
+ RCC -> CR |= ((uint32_t )RCC_CR_HSEON );
371
+
372
+ /* Wait till HSE is ready */
373
+ do
374
+ {
375
+ HSEStatus = RCC -> CR & RCC_CR_HSERDY ;
376
+ StartUpCounter ++ ;
377
+ } while ((HSEStatus == 0 ) && (StartUpCounter != HSE_STARTUP_TIMEOUT ));
378
+
379
+ /* Check if HSE has started correctly */
380
+ if ((RCC -> CR & RCC_CR_HSERDY ) != RESET )
349
381
{
350
382
/* Enable 64-bit access */
351
383
FLASH -> ACR |= FLASH_ACR_ACC64 ;
352
-
384
+
353
385
/* Enable Prefetch Buffer */
354
386
FLASH -> ACR |= FLASH_ACR_PRFTEN ;
355
387
356
388
/* Flash 1 wait state (latency) */
357
389
FLASH -> ACR |= FLASH_ACR_LATENCY ;
358
-
390
+
359
391
/* Power enable */
360
392
RCC -> APB1ENR |= RCC_APB1ENR_PWREN ;
361
-
393
+
362
394
/* Select the Voltage Range 1 (1.8 V) */
363
395
PWR -> CR = PWR_CR_VOS_0 ;
364
396
@@ -368,18 +400,88 @@ void SetSysClock(void)
368
400
}
369
401
370
402
/* PLL configuration */
371
- /* SYSCLK = (HSI 16 MHz * 4) / 2 = 32 MHz */
403
+ /* SYSCLK = 24 MHz ((8 MHz * 6) / 2) */
404
+ /* USBCLK = 48 MHz (8 MHz * 6) --> USB OK */
372
405
RCC -> CFGR &= (uint32_t )((uint32_t )~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL | RCC_CFGR_PLLDIV ));
373
- RCC -> CFGR |= (uint32_t )(RCC_CFGR_PLLSRC_HSI | RCC_CFGR_PLLMUL4 | RCC_CFGR_PLLDIV2 );
406
+ RCC -> CFGR |= (uint32_t )(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL6 | RCC_CFGR_PLLDIV2
407
+ | RCC_CFGR_HPRE_DIV1 /* HCLK = 24 MHz */
408
+ | RCC_CFGR_PPRE2_DIV1 /* PCLK2 = 24 MHz */
409
+ | RCC_CFGR_PPRE1_DIV1 ); /* PCLK1 = 24 MHz */
374
410
375
- /* HCLK = 32 MHz */
376
- RCC -> CFGR |= (uint32_t )RCC_CFGR_HPRE_DIV1 ;
377
-
378
- /* PCLK2 = 32 MHz */
379
- RCC -> CFGR |= (uint32_t )RCC_CFGR_PPRE2_DIV1 ;
411
+ /* Enable PLL */
412
+ RCC -> CR |= RCC_CR_PLLON ;
413
+
414
+ /* Wait till PLL is ready */
415
+ while ((RCC -> CR & RCC_CR_PLLRDY ) == 0 )
416
+ {
417
+ }
380
418
381
- /* PCLK1 = 32 MHz */
382
- RCC -> CFGR |= (uint32_t )RCC_CFGR_PPRE1_DIV1 ;
419
+ /* Select PLL as system clock source */
420
+ RCC -> CFGR &= (uint32_t )((uint32_t )~(RCC_CFGR_SW ));
421
+ RCC -> CFGR |= (uint32_t )RCC_CFGR_SW_PLL ;
422
+
423
+ /* Wait till PLL is used as system clock source */
424
+ while ((RCC -> CFGR & (uint32_t )RCC_CFGR_SWS ) != (uint32_t )RCC_CFGR_SWS_PLL )
425
+ {
426
+ }
427
+
428
+ return 1 ; // OK
429
+ }
430
+ else
431
+ {
432
+ return 0 ; // FAIL
433
+ }
434
+ }
435
+ #endif
436
+
437
+ /******************************************************************************/
438
+ /* PLL (clocked by HSI) used as System clock source */
439
+ /******************************************************************************/
440
+ uint8_t SetSysClock_PLL_HSI (void )
441
+ {
442
+ __IO uint32_t StartUpCounter = 0 ;
443
+ __IO uint32_t HSIStatus = 0 ;
444
+
445
+ /* Enable HSI */
446
+ RCC -> CR |= ((uint32_t )RCC_CR_HSION );
447
+
448
+ /* Wait till HSI is ready */
449
+ do
450
+ {
451
+ HSIStatus = RCC -> CR & RCC_CR_HSIRDY ;
452
+ StartUpCounter ++ ;
453
+ } while ((HSIStatus == 0 ) && (StartUpCounter != HSI_STARTUP_TIMEOUT ));
454
+
455
+ if ((RCC -> CR & RCC_CR_HSIRDY ) != RESET )
456
+ {
457
+ /* Enable 64-bit access */
458
+ FLASH -> ACR |= FLASH_ACR_ACC64 ;
459
+
460
+ /* Enable Prefetch Buffer */
461
+ FLASH -> ACR |= FLASH_ACR_PRFTEN ;
462
+
463
+ /* Flash 1 wait state (latency) */
464
+ FLASH -> ACR |= FLASH_ACR_LATENCY ;
465
+
466
+ /* Power enable */
467
+ RCC -> APB1ENR |= RCC_APB1ENR_PWREN ;
468
+
469
+ /* Select the Voltage Range 1 (1.8 V) */
470
+ PWR -> CR = PWR_CR_VOS_0 ;
471
+
472
+ /* Wait Until the Voltage Regulator is ready */
473
+ while ((PWR -> CSR & PWR_CSR_VOSF ) != RESET )
474
+ {
475
+ }
476
+
477
+ /* PLL configuration */
478
+ /* SYSCLK = 32 MHz ((16 MHz * 4) / 2) */
479
+ /* USBCLK = 64 MHz (16 MHz * 4) --> USB not possible */
480
+ RCC -> CFGR &= (uint32_t )((uint32_t )~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL | RCC_CFGR_PLLDIV ));
481
+ RCC -> CFGR |= (uint32_t )(RCC_CFGR_PLLSRC_HSI | RCC_CFGR_PLLMUL4 | RCC_CFGR_PLLDIV2
482
+ | RCC_CFGR_HPRE_DIV1 /* HCLK = 32 MHz */
483
+ | RCC_CFGR_PPRE2_DIV1 /* PCLK2 = 32 MHz */
484
+ | RCC_CFGR_PPRE1_DIV1 ); /* PCLK1 = 32 MHz */
383
485
384
486
/* Enable PLL */
385
487
RCC -> CR |= RCC_CR_PLLON ;
@@ -388,7 +490,7 @@ void SetSysClock(void)
388
490
while ((RCC -> CR & RCC_CR_PLLRDY ) == 0 )
389
491
{
390
492
}
391
-
493
+
392
494
/* Select PLL as system clock source */
393
495
RCC -> CFGR &= (uint32_t )((uint32_t )~(RCC_CFGR_SW ));
394
496
RCC -> CFGR |= (uint32_t )RCC_CFGR_SW_PLL ;
@@ -397,11 +499,12 @@ void SetSysClock(void)
397
499
while ((RCC -> CFGR & (uint32_t )RCC_CFGR_SWS ) != (uint32_t )RCC_CFGR_SWS_PLL )
398
500
{
399
501
}
502
+
503
+ return 1 ; // OK
400
504
}
401
505
else
402
506
{
403
- /* If HSI fails to start-up, the application will have wrong clock
404
- configuration. User can add here some code to deal with this error */
507
+ return 0 ; // FAIL
405
508
}
406
509
}
407
510
0 commit comments