Skip to content

Commit c81f920

Browse files
committed
Merge pull request #235 from bcostm/master
[NUCLEO_L152RE/F103RB] Add automatic HSE/HSI clock configuration.
2 parents b6fadb4 + d1c498d commit c81f920

File tree

10 files changed

+530
-773
lines changed

10 files changed

+530
-773
lines changed

libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F103RB/system_stm32f10x.c

Lines changed: 132 additions & 630 deletions
Large diffs are not rendered by default.

libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_MICRO/stm32l1xx.sct

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2929

30-
LR_IROM1 0x08000000 0x80000 { ; load region size_region (512 KB)
30+
; STM32L152RE: 512KB FLASH + 80KB SRAM
31+
LR_IROM1 0x08000000 0x80000 { ; load region size_region
3132

3233
ER_IROM1 0x08000000 0x80000 { ; load address = execution address
3334
*.o (RESET, +First)

libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/TOOLCHAIN_ARM_STD/stm32l1xx.sct

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2929

30-
LR_IROM1 0x08000000 0x80000 { ; load region size_region (512 KB)
30+
; STM32L152RE: 512KB FLASH + 80KB SRAM
31+
LR_IROM1 0x08000000 0x80000 { ; load region size_region
3132

3233
ER_IROM1 0x08000000 0x80000 { ; load address = execution address
3334
*.o (RESET, +First)

libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/system_stm32l1xx.c

Lines changed: 189 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -38,38 +38,25 @@
3838
* in "stm32l1xx.h" file. When HSE is used as system clock source, directly or
3939
* through PLL, and you are using different crystal you have to adapt the HSE
4040
* 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+
******************************************************************************
7360
* @attention
7461
*
7562
* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
@@ -142,14 +129,20 @@
142129
* @{
143130
*/
144131

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+
145136
/**
146137
* @}
147138
*/
148139

149140
/** @addtogroup STM32L1xx_System_Private_Variables
150141
* @{
151142
*/
152-
uint32_t SystemCoreClock = 32000000;
143+
144+
uint32_t SystemCoreClock = 32000000; /* Default with HSI. Will be updated if HSE is used */
145+
153146
__I uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48};
154147
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
155148

@@ -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}
163156

164157
void SetSysClock(void);
165158

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+
166165
/**
167166
* @}
168167
*/
@@ -198,35 +197,20 @@ void SystemInit (void)
198197
/*!< Disable all interrupts */
199198
RCC->CIR = 0x00000000;
200199

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 */
202202
SetSysClock();
203203

204+
/* Configure the Vector Table location add offset address ------------------*/
204205
#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 */
206207
#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 */
208209
#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-
*/
226210
}
227211

228212
/**
229-
* @brief Update SystemCoreClock according to Clock Register Values
213+
* @brief Update SystemCoreClock variable according to Clock Register Values.
230214
* The SystemCoreClock variable contains the core clock (HCLK), it can
231215
* be used by the user application to setup the SysTick timer or configure
232216
* other parameters.
@@ -315,50 +299,98 @@ void SystemCoreClockUpdate (void)
315299
}
316300

317301
/**
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
320304
* @note This function should be called only once the RCC clock configuration
321305
* is reset to the default reset state (done in SystemInit() function).
322306
* @param None
323307
* @retval None
324308
*/
325309
void SetSysClock(void)
326310
{
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
335315
{
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+
}
338348

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)
340361
{
341-
HSIStatus = (uint32_t)0x01;
362+
RCC->CR |= ((uint32_t)RCC_CR_HSEBYP);
342363
}
343364
else
344365
{
345-
HSIStatus = (uint32_t)0x00;
366+
RCC->CR &= ((uint32_t)~RCC_CR_HSEBYP);
346367
}
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)
349381
{
350382
/* Enable 64-bit access */
351383
FLASH->ACR |= FLASH_ACR_ACC64;
352-
384+
353385
/* Enable Prefetch Buffer */
354386
FLASH->ACR |= FLASH_ACR_PRFTEN;
355387

356388
/* Flash 1 wait state (latency) */
357389
FLASH->ACR |= FLASH_ACR_LATENCY;
358-
390+
359391
/* Power enable */
360392
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
361-
393+
362394
/* Select the Voltage Range 1 (1.8 V) */
363395
PWR->CR = PWR_CR_VOS_0;
364396

@@ -368,18 +400,88 @@ void SetSysClock(void)
368400
}
369401

370402
/* 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 */
372405
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 */
374410

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+
}
380418

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 */
383485

384486
/* Enable PLL */
385487
RCC->CR |= RCC_CR_PLLON;
@@ -388,7 +490,7 @@ void SetSysClock(void)
388490
while((RCC->CR & RCC_CR_PLLRDY) == 0)
389491
{
390492
}
391-
493+
392494
/* Select PLL as system clock source */
393495
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
394496
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
@@ -397,11 +499,12 @@ void SetSysClock(void)
397499
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
398500
{
399501
}
502+
503+
return 1; // OK
400504
}
401505
else
402506
{
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
405508
}
406509
}
407510

0 commit comments

Comments
 (0)