mbed library sources
Fork of mbed-src by
Diff: targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/system_stm32l1xx.c
- Revision:
- 354:e67efb2aab0e
- Parent:
- 139:e3413eddde57
--- a/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/system_stm32l1xx.c Thu Oct 16 14:45:07 2014 +0100 +++ b/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/system_stm32l1xx.c Thu Oct 16 15:00:10 2014 +0100 @@ -2,44 +2,25 @@ ****************************************************************************** * @file system_stm32l1xx.c * @author MCD Application Team - * @version V1.2.0 - * @date 14-March-2014 + * @version V2.0.0 + * @date 5-September-2014 * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. - * This file contains the system clock configuration for STM32L1xx Ultra - * Low power devices, and is generated by the clock configuration - * tool STM32L1xx_Clock_Configuration_V1.2.0.xls - * - * 1. This file provides two functions and one global variable to be called from - * user application: - * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier - * and Divider factors, AHB/APBx prescalers and Flash settings), - * depending on the configuration made in the clock xls tool. - * This function is called at startup just after reset and + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and * before branch to main program. This call is made inside - * the "startup_stm32l1xx_xx.s" file. - * + * the "startup_stm32l1xx.s" file. + * * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used * by the user application to setup the SysTick * timer or configure other parameters. * * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must * be called whenever the core clock is changed - * during program execution. - * - * 2. After each device reset the MSI (2.1 MHz Range) is used as system clock source. - * Then SystemInit() function is called, in "startup_stm32l1xx_xx.s" file, to - * configure the system clock before to branch to main program. - * - * 3. If the system clock source selected by user fails to startup, the SystemInit() - * function will do nothing and MSI still used as system clock source. User can - * add some code to deal with this issue inside the SetSysClock() function. - * - * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define - * 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. + * during program execution. * - * 5. This file configures the system clock as follows: + * 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) @@ -55,7 +36,7 @@ * APB2CLK (MHz) | 24 | 32 *----------------------------------------------------------------------------- * USB capable (48 MHz precise clock) | YES | NO - *----------------------------------------------------------------------------- + *----------------------------------------------------------------------------- ****************************************************************************** * @attention * @@ -99,6 +80,7 @@ */ #include "stm32l1xx.h" +#include "hal_tick.h" /** * @} @@ -115,7 +97,20 @@ /** @addtogroup STM32L1xx_System_Private_Defines * @{ */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSE_VALUE */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000) /*!< Default value of the Internal oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSI_VALUE */ + +/*!< Uncomment the following line if you need to use external SRAM mounted + on STM32L152D_EVAL board as data memory */ +/* #define DATA_IN_ExtSRAM */ + /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ /* #define VECT_TAB_SRAM */ @@ -140,11 +135,17 @@ /** @addtogroup STM32L1xx_System_Private_Variables * @{ */ - + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ 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}; +const uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48}; +const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; /** * @} @@ -154,7 +155,11 @@ * @{ */ -void SetSysClock(void); +#if defined (STM32L151xD) || defined (STM32L152xD) || defined (STM32L162xD) +#ifdef DATA_IN_ExtSRAM + static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM */ +#endif /* STM32L151xD || STM32L152xD || STM32L162xD */ #if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0) uint8_t SetSysClock_PLL_HSE(uint8_t bypass); @@ -197,20 +202,31 @@ /*!< Disable all interrupts */ RCC->CIR = 0x00000000; - /* Configure the System clock source, PLL Multiplier and Divider factors, +#ifdef DATA_IN_ExtSRAM + SystemInit_ExtMemCtl(); +#endif /* DATA_IN_ExtSRAM */ + +#ifdef VECT_TAB_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. */ +#endif + + /* Configure the Cube driver */ + SystemCoreClock = 16000000; // At this stage the HSI is used as system clock + HAL_Init(); + + /* 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 */ -#else - SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ -#endif + + /* Reset the timer to avoid issues after the RAM initialization */ + TIM_MST_RESET_ON; + TIM_MST_RESET_OFF; } /** - * @brief Update SystemCoreClock variable according to Clock Register Values. + * @brief Update SystemCoreClock 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. @@ -230,7 +246,7 @@ * * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) * - * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) * or HSI_VALUE(*) multiplied/divided by the PLL factors. * * (*) HSI_VALUE is a constant defined in stm32l1xx.h file (default value @@ -243,7 +259,7 @@ * have wrong result. * * - The result of this function could be not correct when using fractional - * value for HSE crystal. + * value for HSE crystal. * @param None * @retval None */ @@ -298,6 +314,133 @@ SystemCoreClock >>= tmp; } +#if defined (STM32L151xD) || defined (STM32L152xD) || defined (STM32L162xD) +#ifdef DATA_IN_ExtSRAM +/** + * @brief Setup the external memory controller. + * Called in SystemInit() function before jump to main. + * This function configures the external SRAM mounted on STM32L152D_EVAL board + * This SRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ +/*-- GPIOs Configuration -----------------------------------------------------*/ +/* + +-------------------+--------------------+------------------+------------------+ + + SRAM pins assignment + + +-------------------+--------------------+------------------+------------------+ + | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 | + | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 | + | PD4 <-> FSMC_NOE | PE7 <-> FSMC_D4 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 | + | PD5 <-> FSMC_NWE | PE8 <-> FSMC_D5 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 | + | PD8 <-> FSMC_D13 | PE9 <-> FSMC_D6 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 | + | PD9 <-> FSMC_D14 | PE10 <-> FSMC_D7 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 | + | PD10 <-> FSMC_D15 | PE11 <-> FSMC_D8 | PF12 <-> FSMC_A6 | PG10<-> FSMC_NE2 | + | PD11 <-> FSMC_A16 | PE12 <-> FSMC_D9 | PF13 <-> FSMC_A7 |------------------+ + | PD12 <-> FSMC_A17 | PE13 <-> FSMC_D10 | PF14 <-> FSMC_A8 | + | PD13 <-> FSMC_A18 | PE14 <-> FSMC_D11 | PF15 <-> FSMC_A9 | + | PD14 <-> FSMC_D0 | PE15 <-> FSMC_D12 |------------------+ + | PD15 <-> FSMC_D1 |--------------------+ + +-------------------+ +*/ + + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHBENR = 0x000080D8; + + /* Connect PDx pins to FSMC Alternate function */ + GPIOD->AFR[0] = 0x00CC00CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAA0A0A; + /* Configure PDx pins speed to 40 MHz */ + GPIOD->OSPEEDR = 0xFFFF0F0F; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FSMC Alternate function */ + GPIOE->AFR[0] = 0xC00000CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA800A; + /* Configure PEx pins speed to 40 MHz */ + GPIOE->OSPEEDR = 0xFFFFC00F; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FSMC Alternate function */ + GPIOF->AFR[0] = 0x00CCCCCC; + GPIOF->AFR[1] = 0xCCCC0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA000AAA; + /* Configure PFx pins speed to 40 MHz */ + GPIOF->OSPEEDR = 0xFF000FFF; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FSMC Alternate function */ + GPIOG->AFR[0] = 0x00CCCCCC; + GPIOG->AFR[1] = 0x00000C00; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0x00200AAA; + /* Configure PGx pins speed to 40 MHz */ + GPIOG->OSPEEDR = 0x00300FFF; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +/*-- FSMC Configuration ------------------------------------------------------*/ + /* Enable the FSMC interface clock */ + RCC->AHBENR = 0x400080D8; + + /* Configure and enable Bank1_SRAM3 */ + FSMC_Bank1->BTCR[4] = 0x00001011; + FSMC_Bank1->BTCR[5] = 0x00000300; + FSMC_Bank1E->BWTR[4] = 0x0FFFFFFF; +/* + Bank1_SRAM3 is configured as follow: + + p.FSMC_AddressSetupTime = 0; + p.FSMC_AddressHoldTime = 0; + p.FSMC_DataSetupTime = 3; + p.FSMC_BusTurnAroundDuration = 0; + p.FSMC_CLKDivision = 0; + p.FSMC_DataLatency = 0; + p.FSMC_AccessMode = FSMC_AccessMode_A; + + FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3; + FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; + FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; + FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; + FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; + FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; + FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; + FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; + FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; + FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; + + FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); + + FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE); +*/ + +} +#endif /* DATA_IN_ExtSRAM */ +#endif /* STM32L151xD || STM32L152xD || STM32L162xD */ + /** * @brief Configures the System clock source, PLL Multiplier and Divider factors, * AHB/APBx prescalers and Flash settings @@ -329,21 +472,8 @@ } } - /* 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); - */ + /* Output clock on MCO1 pin(PA8) for debugging purpose */ + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); } #if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0) @@ -352,85 +482,61 @@ /******************************************************************************/ uint8_t SetSysClock_PLL_HSE(uint8_t bypass) { - __IO uint32_t StartUpCounter = 0; - __IO uint32_t HSEStatus = 0; + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; - /* 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) + /* Used to gain time after DeepSleep in case HSI is used */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) { - RCC->CR |= ((uint32_t)RCC_CR_HSEBYP); + return 0; + } + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE and HSI48 oscillators and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI; + if (bypass == 0) + { + RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ } else { - RCC->CR &= ((uint32_t)~RCC_CR_HSEBYP); + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ } - - /* 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; - - /* Wait Until the Voltage Regulator is ready */ - while((PWR->CSR & PWR_CSR_VOSF) != RESET) - { - } - - /* PLL configuration */ - /* 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_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 */ - - /* Enable PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till PLL is ready */ - 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; - - /* 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 + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + // SYSCLK = 24 MHz ((8 MHz * 6) / 2) + // USBCLK = 48 MHz (8 MHz * 6) --> USB OK + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV2; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { return 0; // FAIL } + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 24 MHz + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 24 MHz + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 24 MHz + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 24 MHz + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) + { + return 0; // FAIL + } + + /* Output clock on MCO1 pin(PA8) for debugging purpose */ + //if (bypass == 0) + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_2); // 4 MHz + //else + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1); // 8 MHz + + return 1; // OK } #endif @@ -439,73 +545,48 @@ /******************************************************************************/ 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; + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; - /* 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; - - /* Wait till PLL is ready */ - 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; - - /* 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 + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSI oscillator and activate PLL with HSI as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_OFF; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + // SYSCLK = 32 MHz ((16 MHz * 4) / 2) + // USBCLK = 64 MHz (16 MHz * 4) --> USB not possible + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV2; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { return 0; // FAIL } + + /* Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0 */ + while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOS) != RESET) {}; + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 32 MHz + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 32 MHz + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 32 MHz + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 32 MHz + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) + { + return 0; // FAIL + } + + /* Output clock on MCO1 pin(PA8) for debugging purpose */ + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1); // 16 MHz + + return 1; // OK } /** @@ -520,4 +601,4 @@ * @} */ -/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/