Skip to content

[NUCLEO_L152RE/F103RB] Add automatic HSE/HSI clock configuration. #235

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 27, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

ER_IROM1 0x08000000 0x80000 { ; load address = execution address
*.o (RESET, +First)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

ER_IROM1 0x08000000 0x80000 { ; load address = execution address
*.o (RESET, +First)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,38 +38,25 @@
* in "stm32l1xx.h" file. When HSE is used as system clock source, directly or
* through PLL, and you are using different crystal you have to adapt the HSE
* value to your own configuration.
*
* 5. This file configures the system clock as follows:
*=============================================================================
* System Clock Configuration
*=============================================================================
* System Clock source | PLL(HSI)
*-----------------------------------------------------------------------------
* SYSCLK | 32000000 Hz
*-----------------------------------------------------------------------------
* HCLK | 32000000 Hz
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 1
*-----------------------------------------------------------------------------
* APB2 Prescaler | 1
*-----------------------------------------------------------------------------
* HSE Frequency | Not used
*-----------------------------------------------------------------------------
* PLL DIV | 2
*-----------------------------------------------------------------------------
* PLL MUL | 4
*-----------------------------------------------------------------------------
* VDD | 3.3 V
*-----------------------------------------------------------------------------
* Vcore | 1.8 V (Range 1)
*-----------------------------------------------------------------------------
* Flash Latency | 1 WS
*-----------------------------------------------------------------------------
* Require 48MHz for USB clock | Disabled
*-----------------------------------------------------------------------------
*=============================================================================
*
* 5. This file configures the system clock as follows:
*-----------------------------------------------------------------------------
* System clock source | 1- PLL_HSE_EXTC | 3- PLL_HSI
* | (external 8 MHz clock) | (internal 16 MHz)
* | 2- PLL_HSE_XTAL |
* | (external 8 MHz xtal) |
*-----------------------------------------------------------------------------
* SYSCLK(MHz) | 24 | 32
*-----------------------------------------------------------------------------
* AHBCLK (MHz) | 24 | 32
*-----------------------------------------------------------------------------
* APB1CLK (MHz) | 24 | 32
*-----------------------------------------------------------------------------
* APB2CLK (MHz) | 24 | 32
*-----------------------------------------------------------------------------
* USB capable (48 MHz precise clock) | YES | NO
*-----------------------------------------------------------------------------
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
Expand Down Expand Up @@ -142,14 +129,20 @@
* @{
*/

/* Select the clock sources (other than HSI) to start with (0=OFF, 1=ON) */
#define USE_PLL_HSE_EXTC (1) /* Use external clock */
#define USE_PLL_HSE_XTAL (1) /* Use external xtal */

/**
* @}
*/

/** @addtogroup STM32L1xx_System_Private_Variables
* @{
*/
uint32_t SystemCoreClock = 32000000;

uint32_t SystemCoreClock = 32000000; /* Default with HSI. Will be updated if HSE is used */

__I uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48};
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};

Expand All @@ -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}

void SetSysClock(void);

#if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0)
uint8_t SetSysClock_PLL_HSE(uint8_t bypass);
#endif

uint8_t SetSysClock_PLL_HSI(void);

/**
* @}
*/
Expand Down Expand Up @@ -198,35 +197,20 @@ void SystemInit (void)
/*!< Disable all interrupts */
RCC->CIR = 0x00000000;

/* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
/* Configure the System clock source, PLL Multiplier and Divider factors,
AHB/APBx prescalers and Flash settings */
SetSysClock();

/* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif

/* ADDED FOR MBED DEBUG PURPOSE */
/*
// Enable the GPIOA peripheral
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
// Output the system clock on MCO pin (PA.08)
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Select the clock to output on MCO pin (PA.08)
RCC_MCOConfig(RCC_MCOSource_SYSCLK, RCC_MCODiv_1);
//RCC_MCOConfig(RCC_MCOSource_HSI, RCC_MCODiv_1);
*/
}

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

/**
* @brief Configures the System clock frequency, AHB/APBx prescalers and Flash
* settings.
* @brief Configures the System clock source, PLL Multiplier and Divider factors,
* AHB/APBx prescalers and Flash settings
* @note This function should be called only once the RCC clock configuration
* is reset to the default reset state (done in SystemInit() function).
* @param None
* @retval None
*/
void SetSysClock(void)
{
__IO uint32_t StartUpCounter = 0, HSIStatus = 0;

/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
/* Enable HSI */
RCC->CR |= ((uint32_t)RCC_CR_HSION);

/* Wait till HSI is ready and if Time out is reached exit */
do
/* 1- Try to start with HSE and external clock */
#if USE_PLL_HSE_EXTC != 0
if (SetSysClock_PLL_HSE(1) == 0)
#endif
{
HSIStatus = RCC->CR & RCC_CR_HSIRDY;
} while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));
/* 2- If fail try to start with HSE and external xtal */
#if USE_PLL_HSE_XTAL != 0
if (SetSysClock_PLL_HSE(0) == 0)
#endif
{
/* 3- If fail start with HSI clock */
if (SetSysClock_PLL_HSI() == 0)
{
while(1)
{
// [TODO] Put something here to tell the user that a problem occured...
}
}
}
}

/* Output SYSCLK on MCO pin(PA8) for debugging purpose */
/*
// Enable GPIOA clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
// Configure MCO pin (PA8)
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Select the clock to output
RCC_MCOConfig(RCC_MCOSource_SYSCLK, RCC_MCODiv_1);
*/
}

if ((RCC->CR & RCC_CR_HSIRDY) != RESET)
#if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0)
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
{
__IO uint32_t StartUpCounter = 0;
__IO uint32_t HSEStatus = 0;

/* Bypass HSE: can be done only if HSE is OFF */
RCC->CR &= ((uint32_t)~RCC_CR_HSEON); /* To be sure HSE is OFF */
if (bypass != 0)
{
HSIStatus = (uint32_t)0x01;
RCC->CR |= ((uint32_t)RCC_CR_HSEBYP);
}
else
{
HSIStatus = (uint32_t)0x00;
RCC->CR &= ((uint32_t)~RCC_CR_HSEBYP);
}

if (HSIStatus == (uint32_t)0x01)

/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);

/* Wait till HSE is ready */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

/* Check if HSE has started correctly */
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
/* Enable 64-bit access */
FLASH->ACR |= FLASH_ACR_ACC64;

/* Enable Prefetch Buffer */
FLASH->ACR |= FLASH_ACR_PRFTEN;

/* Flash 1 wait state (latency) */
FLASH->ACR |= FLASH_ACR_LATENCY;

/* Power enable */
RCC->APB1ENR |= RCC_APB1ENR_PWREN;

/* Select the Voltage Range 1 (1.8 V) */
PWR->CR = PWR_CR_VOS_0;

Expand All @@ -368,18 +400,88 @@ void SetSysClock(void)
}

/* PLL configuration */
/* SYSCLK = (HSI 16 MHz * 4) / 2 = 32 MHz */
/* SYSCLK = 24 MHz ((8 MHz * 6) / 2) */
/* USBCLK = 48 MHz (8 MHz * 6) --> USB OK */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL | RCC_CFGR_PLLDIV));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI | RCC_CFGR_PLLMUL4 | RCC_CFGR_PLLDIV2);
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL6 | RCC_CFGR_PLLDIV2
| RCC_CFGR_HPRE_DIV1 /* HCLK = 24 MHz */
| RCC_CFGR_PPRE2_DIV1 /* PCLK2 = 24 MHz */
| RCC_CFGR_PPRE1_DIV1); /* PCLK1 = 24 MHz */

/* HCLK = 32 MHz */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

/* PCLK2 = 32 MHz */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;

/* Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}

/* PCLK1 = 32 MHz */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;

/* Wait till PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
{
}

return 1; // OK
}
else
{
return 0; // FAIL
}
}
#endif

/******************************************************************************/
/* PLL (clocked by HSI) used as System clock source */
/******************************************************************************/
uint8_t SetSysClock_PLL_HSI(void)
{
__IO uint32_t StartUpCounter = 0;
__IO uint32_t HSIStatus = 0;

/* Enable HSI */
RCC->CR |= ((uint32_t)RCC_CR_HSION);

/* Wait till HSI is ready */
do
{
HSIStatus = RCC->CR & RCC_CR_HSIRDY;
StartUpCounter++;
} while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));

if ((RCC->CR & RCC_CR_HSIRDY) != RESET)
{
/* Enable 64-bit access */
FLASH->ACR |= FLASH_ACR_ACC64;

/* Enable Prefetch Buffer */
FLASH->ACR |= FLASH_ACR_PRFTEN;

/* Flash 1 wait state (latency) */
FLASH->ACR |= FLASH_ACR_LATENCY;

/* Power enable */
RCC->APB1ENR |= RCC_APB1ENR_PWREN;

/* Select the Voltage Range 1 (1.8 V) */
PWR->CR = PWR_CR_VOS_0;

/* Wait Until the Voltage Regulator is ready */
while((PWR->CSR & PWR_CSR_VOSF) != RESET)
{
}

/* PLL configuration */
/* SYSCLK = 32 MHz ((16 MHz * 4) / 2) */
/* USBCLK = 64 MHz (16 MHz * 4) --> USB not possible */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL | RCC_CFGR_PLLDIV));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI | RCC_CFGR_PLLMUL4 | RCC_CFGR_PLLDIV2
| RCC_CFGR_HPRE_DIV1 /* HCLK = 32 MHz */
| RCC_CFGR_PPRE2_DIV1 /* PCLK2 = 32 MHz */
| RCC_CFGR_PPRE1_DIV1); /* PCLK1 = 32 MHz */

/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;
Expand All @@ -388,7 +490,7 @@ void SetSysClock(void)
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}

/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
Expand All @@ -397,11 +499,12 @@ void SetSysClock(void)
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
{
}

return 1; // OK
}
else
{
/* If HSI fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
return 0; // FAIL
}
}

Expand Down
Loading