diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/system_clock.c new file mode 100644 index 0000000000..b0c89fa5c4 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/system_clock.c @@ -0,0 +1,245 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2017 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * This file configures the system clock as follows: + *----------------------------------------------------------------- + * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) + * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) + * | 3- USE_PLL_HSI (internal 16 MHz) + *----------------------------------------------------------------- + * SYSCLK(MHz) | 32 + * AHBCLK (MHz) | 32 + * APB1CLK (MHz) | 32 + * USB capable | YES + *----------------------------------------------------------------- + */ + +#include "stm32l0xx.h" +#include "mbed_assert.h" + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. + This value must be a multiple of 0x100. */ + +#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) +#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) +#define USE_PLL_HSI 0x2 // Use HSI internal clock + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +uint8_t SetSysClock_PLL_HSE(uint8_t bypass); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +uint8_t SetSysClock_PLL_HSI(void); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ + + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ +void SystemInit (void) +{ + /*!< Set MSION bit */ + RCC->CR |= (uint32_t)0x00000100U; + + /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ + RCC->CFGR &= (uint32_t) 0x88FF400CU; + + /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFF6U; + + /*!< Reset HSI48ON bit */ + RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; + + /*!< Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFFU; + + /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ + RCC->CFGR &= (uint32_t)0xFF02FFFFU; + + /*!< Disable all interrupts */ + RCC->CIER = 0x00000000U; + + /* 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 + +} + +/** + * @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) +{ +#if ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) + /* 1- Try to start with HSE and external clock */ + if (SetSysClock_PLL_HSE(1) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) + /* 2- If fail try to start with HSE and external xtal */ + if (SetSysClock_PLL_HSE(0) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSI) + /* 3- If fail start with HSI clock */ + if (SetSysClock_PLL_HSI() == 0) +#endif + { + while(1) { + MBED_ASSERT(1); + } + } + } + } + + /* Output clock on MCO1 pin(PA8) for debugging purpose */ + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI48, RCC_MCODIV_1); +} + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSE(uint8_t bypass) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Used to gain time after DeepSleep in case HSI is used */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) { + 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_HSI48; + if (bypass == 0) { + RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ + } else { + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ + } + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ + // PLLCLK = (8 MHz * 8)/2 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + return 0; // FAIL + } + + /* Select HSI48 as USB clock source */ + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != 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; // 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 */ + //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 /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +/******************************************************************************/ +/* PLL (clocked by HSI) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSI(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; + + /* 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 and HSI48 oscillators and activate PLL with HSI as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSEState = RCC_HSE_OFF; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = 16; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ + // PLLCLK = (16 MHz * 4)/2 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; + 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; // 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 + } + + RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + RCC_PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != 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 +} +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/system_stm32l0xx.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/system_stm32l0xx.c deleted file mode 100644 index 2f0ea002e9..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/system_stm32l0xx.c +++ /dev/null @@ -1,468 +0,0 @@ -/** - ****************************************************************************** - * @file system_stm32l0xx.c - * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File. - * - * 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_stm32l0xx.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. - * - * 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) | 32 | 32 - *----------------------------------------------------------------------------- - * AHBCLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB1CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB2CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * USB capable (48 MHz precise clock) | YES | YES - *----------------------------------------------------------------------------- - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2015 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32l0xx_system - * @{ - */ - -/** @addtogroup STM32L0xx_System_Private_Includes - * @{ - */ - -#include "stm32l0xx.h" - -#if !defined (HSE_VALUE) - #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ - -#if !defined (MSI_VALUE) - #define MSI_VALUE ((uint32_t)2000000U) /*!< Value of the Internal oscillator in Hz*/ -#endif /* MSI_VALUE */ - -#if !defined (HSI_VALUE) - #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI_VALUE */ - - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Defines - * @{ - */ -/************************* Miscellaneous Configuration ************************/ - -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. - This value must be a multiple of 0x100. */ -/******************************************************************************/ -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Macros - * @{ - */ - -/* 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 STM32L0xx_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; - const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; - const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; - const uint8_t PLLMulTable[9] = {3U, 4U, 6U, 8U, 12U, 16U, 24U, 32U, 48U}; - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_FunctionPrototypes - * @{ - */ - -#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); - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Functions - * @{ - */ - -/** - * @brief Setup the microcontroller system. - * @param None - * @retval None - */ -void SystemInit (void) -{ -/*!< Set MSION bit */ - RCC->CR |= (uint32_t)0x00000100U; - - /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ - RCC->CFGR &= (uint32_t) 0x88FF400CU; - - /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFF6U; - - /*!< Reset HSI48ON bit */ - RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; - - /*!< Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFFU; - - /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ - RCC->CFGR &= (uint32_t)0xFF02FFFFU; - - /*!< Disable all interrupts */ - RCC->CIER = 0x00000000U; - - /* 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 - -} - -/** - * @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. - * - * @note Each time the core clock (HCLK) changes, this function must be called - * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @note - The system frequency computed by this function is not the real - * frequency in the chip. It is calculated based on the predefined - * constant and the selected clock source: - * - * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI - * value as defined by the MSI range. - * - * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) - * - * - If SYSCLK source is HSE, 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 stm32l0xx_hal.h file (default value - * 16 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * - * (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value - * 8 MHz), user has to ensure that HSE_VALUE is same as the real - * frequency of the crystal used. Otherwise, this function may - * have wrong result. - * - * - The result of this function could be not correct when using fractional - * value for HSE crystal. - * @param None - * @retval None - */ -void SystemCoreClockUpdate (void) -{ - uint32_t tmp = 0U, pllmul = 0U, plldiv = 0U, pllsource = 0U, msirange = 0U; - - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & RCC_CFGR_SWS; - - switch (tmp) - { - case 0x00U: /* MSI used as system clock */ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U; - SystemCoreClock = (32768U * (1U << (msirange + 1U))); - break; - case 0x04U: /* HSI used as system clock */ - SystemCoreClock = HSI_VALUE; - break; - case 0x08U: /* HSE used as system clock */ - SystemCoreClock = HSE_VALUE; - break; - case 0x0CU: /* PLL used as system clock */ - /* Get PLL clock source and multiplication factor ----------------------*/ - pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; - plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; - pllmul = PLLMulTable[(pllmul >> 18U)]; - plldiv = (plldiv >> 22U) + 1U; - - pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; - - if (pllsource == 0x00U) - { - /* HSI oscillator clock selected as PLL clock entry */ - SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv); - } - else - { - /* HSE selected as PLL clock entry */ - SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv); - } - break; - default: /* MSI used as system clock */ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U; - SystemCoreClock = (32768U * (1U << (msirange + 1U))); - break; - } - /* Compute HCLK clock frequency --------------------------------------------*/ - /* Get HCLK prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)]; - /* HCLK clock frequency */ - SystemCoreClock >>= tmp; -} - -/** - * @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) -{ - /* 1- Try to start with HSE and external clock */ -#if USE_PLL_HSE_EXTC != 0 - if (SetSysClock_PLL_HSE(1) == 0) -#endif - { - /* 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 clock on MCO1 pin(PA8) for debugging purpose */ - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI48, RCC_MCODIV_1); -} - -#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) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* Used to gain time after DeepSleep in case HSI is used */ - if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) - { - 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_HSI48; - if (bypass == 0) - { - RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ - } - else - { - RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ - } - RCC_OscInitStruct.HSIState = RCC_HSI_OFF; - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ - - // PLLCLK = (8 MHz * 8)/2 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) - { - return 0; // FAIL - } - - /* Select HSI48 as USB clock source */ - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; - PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; - HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); - - /* 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 */ - //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 - -/******************************************************************************/ -/* PLL (clocked by HSI) used as System clock source */ -/******************************************************************************/ -uint8_t SetSysClock_PLL_HSI(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* 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 and HSI48 oscillators and activate PLL with HSI as source */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; - RCC_OscInitStruct.HSEState = RCC_HSE_OFF; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) && \ - !defined (STM32L011xx) && !defined (STM32L021xx) - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ -#endif - // PLLCLK = (16 MHz * 4)/2 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - 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; // 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 -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/system_clock.c new file mode 100644 index 0000000000..afe7ff433a --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/system_clock.c @@ -0,0 +1,260 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2017 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * This file configures the system clock as follows: + *----------------------------------------------------------------- + * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) + * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) + * | 3- USE_PLL_HSI (internal 16 MHz) + *----------------------------------------------------------------- + * SYSCLK(MHz) | 32 + * AHBCLK (MHz) | 32 + * APB1CLK (MHz) | 32 + * USB capable | YES + *----------------------------------------------------------------- + */ + +#include "stm32l0xx.h" +#include "mbed_assert.h" + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. + This value must be a multiple of 0x100. */ + +#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) +#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) +#define USE_PLL_HSI 0x2 // Use HSI internal clock + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +uint8_t SetSysClock_PLL_HSE(uint8_t bypass); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +uint8_t SetSysClock_PLL_HSI(void); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ + + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ +void SystemInit (void) +{ + /*!< Set MSION bit */ + RCC->CR |= (uint32_t)0x00000100U; + + /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ + RCC->CFGR &= (uint32_t) 0x88FF400CU; + + /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFF6U; + + /*!< Reset HSI48ON bit */ + RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; + + /*!< Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFFU; + + /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ + RCC->CFGR &= (uint32_t)0xFF02FFFFU; + + /*!< Disable all interrupts */ + RCC->CIER = 0x00000000U; + + /* 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 + +} + +/** + * @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) +{ +#if ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) + /* 1- Try to start with HSE and external clock */ + if (SetSysClock_PLL_HSE(1) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) + /* 2- If fail try to start with HSE and external xtal */ + if (SetSysClock_PLL_HSE(0) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSI) + /* 3- If fail start with HSI clock */ + if (SetSysClock_PLL_HSI() == 0) +#endif + { + while(1) { + MBED_ASSERT(1); + } + } + } + } + + /* Output clock on MCO1 pin(PA8) for debugging purpose */ + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI48, RCC_MCODIV_1); +} + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSE(uint8_t bypass) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; + + /* Used to gain time after DeepSleep in case HSI is used */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) { + 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_HSI48; + if (bypass == 0) { + RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ + } else { + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ + } + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ + // PLLCLK = (8 MHz * 8)/2 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; + 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; // 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 + } + + RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + RCC_PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != 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 /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +/******************************************************************************/ +/* PLL (clocked by HSI) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSI(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + RCC_CRSInitTypeDef RCC_CRSInitStruct = {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. */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + __HAL_RCC_PWR_CLK_DISABLE(); + + /* Enable HSI and HSI48 oscillators and activate PLL with HSI as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSEState = RCC_HSE_OFF; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + // PLLCLK = (16 MHz * 6)/3 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + return 0; // FAIL + } + + /* Select HSI48 as USB clock source */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* 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 + } + + /* Configure the clock recovery system (CRS) ********************************/ + /* Enable CRS Clock */ + __HAL_RCC_CRS_CLK_ENABLE(); + /* Default Synchro Signal division factor (not divided) */ + RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; + /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ + RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; + /* HSI48 is synchronized with USB SOF at 1KHz rate */ + RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); + RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; + /* Set the TRIM[5:0] to the default value */ + RCC_CRSInitStruct.HSI48CalibrationValue = 0x20; + /* Start automatic synchronization */ + HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct); + + /* 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 +} +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/system_stm32l0xx.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/system_stm32l0xx.c deleted file mode 100644 index ff295e14cb..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/system_stm32l0xx.c +++ /dev/null @@ -1,485 +0,0 @@ -/** - ****************************************************************************** - * @file system_stm32l0xx.c - * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File. - * - * 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_stm32l0xx.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. - * - * 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) | 32 | 32 - *----------------------------------------------------------------------------- - * AHBCLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB1CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB2CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * USB capable (48 MHz precise clock) | YES | YES - *----------------------------------------------------------------------------- - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2015 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32l0xx_system - * @{ - */ - -/** @addtogroup STM32L0xx_System_Private_Includes - * @{ - */ - -#include "stm32l0xx.h" - -#if !defined (HSE_VALUE) - #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ - -#if !defined (MSI_VALUE) - #define MSI_VALUE ((uint32_t)2000000U) /*!< Value of the Internal oscillator in Hz*/ -#endif /* MSI_VALUE */ - -#if !defined (HSI_VALUE) - #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI_VALUE */ - - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Defines - * @{ - */ -/************************* Miscellaneous Configuration ************************/ - -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. - This value must be a multiple of 0x100. */ -/******************************************************************************/ -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Macros - * @{ - */ - -/* Select the clock sources (other than HSI) to start with (0=OFF, 1=ON) */ -#define USE_PLL_HSE_EXTC (0) /* Use external clock */ -#define USE_PLL_HSE_XTAL (0) /* Use external xtal */ - -/** - * @} - */ - -/** @addtogroup STM32L0xx_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; - const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; - const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; - const uint8_t PLLMulTable[9] = {3U, 4U, 6U, 8U, 12U, 16U, 24U, 32U, 48U}; - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_FunctionPrototypes - * @{ - */ - -#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); - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Functions - * @{ - */ - -/** - * @brief Setup the microcontroller system. - * @param None - * @retval None - */ -void SystemInit (void) -{ -/*!< Set MSION bit */ - RCC->CR |= (uint32_t)0x00000100U; - - /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ - RCC->CFGR &= (uint32_t) 0x88FF400CU; - - /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFF6U; - - /*!< Reset HSI48ON bit */ - RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; - - /*!< Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFFU; - - /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ - RCC->CFGR &= (uint32_t)0xFF02FFFFU; - - /*!< Disable all interrupts */ - RCC->CIER = 0x00000000U; - - /* 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 - -} - -/** - * @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. - * - * @note Each time the core clock (HCLK) changes, this function must be called - * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @note - The system frequency computed by this function is not the real - * frequency in the chip. It is calculated based on the predefined - * constant and the selected clock source: - * - * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI - * value as defined by the MSI range. - * - * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) - * - * - If SYSCLK source is HSE, 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 stm32l0xx_hal.h file (default value - * 16 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * - * (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value - * 8 MHz), user has to ensure that HSE_VALUE is same as the real - * frequency of the crystal used. Otherwise, this function may - * have wrong result. - * - * - The result of this function could be not correct when using fractional - * value for HSE crystal. - * @param None - * @retval None - */ -void SystemCoreClockUpdate (void) -{ - uint32_t tmp = 0U, pllmul = 0U, plldiv = 0U, pllsource = 0U, msirange = 0U; - - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & RCC_CFGR_SWS; - - switch (tmp) - { - case 0x00U: /* MSI used as system clock */ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U; - SystemCoreClock = (32768U * (1U << (msirange + 1U))); - break; - case 0x04U: /* HSI used as system clock */ - SystemCoreClock = HSI_VALUE; - break; - case 0x08U: /* HSE used as system clock */ - SystemCoreClock = HSE_VALUE; - break; - case 0x0CU: /* PLL used as system clock */ - /* Get PLL clock source and multiplication factor ----------------------*/ - pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; - plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; - pllmul = PLLMulTable[(pllmul >> 18U)]; - plldiv = (plldiv >> 22U) + 1U; - - pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; - - if (pllsource == 0x00U) - { - /* HSI oscillator clock selected as PLL clock entry */ - SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv); - } - else - { - /* HSE selected as PLL clock entry */ - SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv); - } - break; - default: /* MSI used as system clock */ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U; - SystemCoreClock = (32768U * (1U << (msirange + 1U))); - break; - } - /* Compute HCLK clock frequency --------------------------------------------*/ - /* Get HCLK prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)]; - /* HCLK clock frequency */ - SystemCoreClock >>= tmp; -} - -/** - * @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) -{ - /* 1- Try to start with HSE and external clock */ -#if USE_PLL_HSE_EXTC != 0 - if (SetSysClock_PLL_HSE(1) == 0) -#endif - { - /* 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 clock on MCO1 pin(PA8) for debugging purpose */ - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI48, RCC_MCODIV_1); -} - -#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) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* Used to gain time after DeepSleep in case HSI is used */ - if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) - { - 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_HSI48; - if (bypass == 0) - { - RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ - } - else - { - RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ - } - RCC_OscInitStruct.HSIState = RCC_HSI_OFF; -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) && \ - !defined (STM32L011xx) && !defined (STM32L021xx) - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ -#endif - // PLLCLK = (8 MHz * 8)/2 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - 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; // 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 */ - //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 - -/******************************************************************************/ -/* PLL (clocked by HSI) used as System clock source */ -/******************************************************************************/ -uint8_t SetSysClock_PLL_HSI(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; - RCC_CRSInitTypeDef RCC_CRSInitStruct = {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. */ - __HAL_RCC_PWR_CLK_ENABLE(); - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); - __HAL_RCC_PWR_CLK_DISABLE(); - - /* Enable HSI and HSI48 oscillators and activate PLL with HSI as source */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; - RCC_OscInitStruct.HSEState = RCC_HSE_OFF; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ - RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; - // PLLCLK = (16 MHz * 6)/3 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) - { - return 0; // FAIL - } - - /* Select HSI48 as USB clock source */ - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; - PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; - HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); - - /* 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 - } - - /* Configure the clock recovery system (CRS) ********************************/ - /* Enable CRS Clock */ - __HAL_RCC_CRS_CLK_ENABLE(); - /* Default Synchro Signal division factor (not divided) */ - RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; - /* Set the SYNCSRC[1:0] bits according to CRS_Source value */ - RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; - /* HSI48 is synchronized with USB SOF at 1KHz rate */ - RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); - RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; - /* Set the TRIM[5:0] to the default value */ - RCC_CRSInitStruct.HSI48CalibrationValue = 0x20; - /* Start automatic synchronization */ - HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct); - - /* 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 -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_clock.c new file mode 100644 index 0000000000..1ea86c05f7 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_clock.c @@ -0,0 +1,227 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2017 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * This file configures the system clock as follows: + *----------------------------------------------------------------- + * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) + * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) + * | 3- USE_PLL_HSI (internal 16 MHz) + *----------------------------------------------------------------- + * SYSCLK(MHz) | 32 + * AHBCLK (MHz) | 32 + * APB1CLK (MHz) | 32 + * USB capable | NO + *----------------------------------------------------------------- + */ + +#include "stm32l0xx.h" +#include "mbed_assert.h" + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. + This value must be a multiple of 0x100. */ + +#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) +#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) +#define USE_PLL_HSI 0x2 // Use HSI internal clock + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +uint8_t SetSysClock_PLL_HSE(uint8_t bypass); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +uint8_t SetSysClock_PLL_HSI(void); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ + + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ +void SystemInit (void) +{ + /*!< Set MSION bit */ + RCC->CR |= (uint32_t)0x00000100U; + + /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ + RCC->CFGR &= (uint32_t) 0x88FF400CU; + + /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFF6U; + + /*!< Reset HSI48ON bit */ + RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; + + /*!< Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFFU; + + /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ + RCC->CFGR &= (uint32_t)0xFF02FFFFU; + + /*!< Disable all interrupts */ + RCC->CIER = 0x00000000U; + + /* 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 + +} + +/** + * @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) +{ +#if ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) + /* 1- Try to start with HSE and external clock */ + if (SetSysClock_PLL_HSE(1) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) + /* 2- If fail try to start with HSE and external xtal */ + if (SetSysClock_PLL_HSE(0) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSI) + /* 3- If fail start with HSI clock */ + if (SetSysClock_PLL_HSI() == 0) +#endif + { + while(1) { + MBED_ASSERT(1); + } + } + } + } + + /* Output clock on MCO1 pin(PA8) for debugging purpose */ + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); +} + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSE(uint8_t bypass) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Used to gain time after DeepSleep in case HSI is used */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) { + 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 oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + if (bypass == 0) { + RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ + } else { + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ + } + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + // PLLCLK = (8 MHz * 8)/2 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; + 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; // 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 */ + //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 /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +/******************************************************************************/ +/* PLL (clocked by HSI) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSI(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* 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_OscInitStruct.HSEState = RCC_HSE_OFF; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + // PLLCLK = (16 MHz * 4)/2 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; + 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; // 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 +} +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_stm32l0xx.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_stm32l0xx.c deleted file mode 100644 index 6f3e66cf45..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_stm32l0xx.c +++ /dev/null @@ -1,465 +0,0 @@ -/** - ****************************************************************************** - * @file system_stm32l0xx.c - * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File. - * - * 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_stm32l0xx.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. - * - * 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) | 32 | 32 - *----------------------------------------------------------------------------- - * AHBCLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB1CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB2CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * USB capable (48 MHz precise clock) | YES | YES - *----------------------------------------------------------------------------- - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2015 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32l0xx_system - * @{ - */ - -/** @addtogroup STM32L0xx_System_Private_Includes - * @{ - */ - -#include "stm32l0xx.h" - -#if !defined (HSE_VALUE) - #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ - -#if !defined (MSI_VALUE) - #define MSI_VALUE ((uint32_t)2000000U) /*!< Value of the Internal oscillator in Hz*/ -#endif /* MSI_VALUE */ - -#if !defined (HSI_VALUE) - #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI_VALUE */ - - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Defines - * @{ - */ -/************************* Miscellaneous Configuration ************************/ - -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. - This value must be a multiple of 0x100. */ -/******************************************************************************/ -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Macros - * @{ - */ - -/* 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 STM32L0xx_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; - const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; - const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; - const uint8_t PLLMulTable[9] = {3U, 4U, 6U, 8U, 12U, 16U, 24U, 32U, 48U}; - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_FunctionPrototypes - * @{ - */ - -#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); - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Functions - * @{ - */ - -/** - * @brief Setup the microcontroller system. - * @param None - * @retval None - */ -void SystemInit (void) -{ -/*!< Set MSION bit */ - RCC->CR |= (uint32_t)0x00000100U; - - /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ - RCC->CFGR &= (uint32_t) 0x88FF400CU; - - /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFF6U; - - /*!< Reset HSI48ON bit */ - RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; - - /*!< Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFFU; - - /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ - RCC->CFGR &= (uint32_t)0xFF02FFFFU; - - /*!< Disable all interrupts */ - RCC->CIER = 0x00000000U; - - /* 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 - -} - -/** - * @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. - * - * @note Each time the core clock (HCLK) changes, this function must be called - * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @note - The system frequency computed by this function is not the real - * frequency in the chip. It is calculated based on the predefined - * constant and the selected clock source: - * - * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI - * value as defined by the MSI range. - * - * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) - * - * - If SYSCLK source is HSE, 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 stm32l0xx_hal.h file (default value - * 16 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * - * (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value - * 8 MHz), user has to ensure that HSE_VALUE is same as the real - * frequency of the crystal used. Otherwise, this function may - * have wrong result. - * - * - The result of this function could be not correct when using fractional - * value for HSE crystal. - * @param None - * @retval None - */ -void SystemCoreClockUpdate (void) -{ - uint32_t tmp = 0U, pllmul = 0U, plldiv = 0U, pllsource = 0U, msirange = 0U; - - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & RCC_CFGR_SWS; - - switch (tmp) - { - case 0x00U: /* MSI used as system clock */ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U; - SystemCoreClock = (32768U * (1U << (msirange + 1U))); - break; - case 0x04U: /* HSI used as system clock */ - SystemCoreClock = HSI_VALUE; - break; - case 0x08U: /* HSE used as system clock */ - SystemCoreClock = HSE_VALUE; - break; - case 0x0CU: /* PLL used as system clock */ - /* Get PLL clock source and multiplication factor ----------------------*/ - pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; - plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; - pllmul = PLLMulTable[(pllmul >> 18U)]; - plldiv = (plldiv >> 22U) + 1U; - - pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; - - if (pllsource == 0x00U) - { - /* HSI oscillator clock selected as PLL clock entry */ - SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv); - } - else - { - /* HSE selected as PLL clock entry */ - SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv); - } - break; - default: /* MSI used as system clock */ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U; - SystemCoreClock = (32768U * (1U << (msirange + 1U))); - break; - } - /* Compute HCLK clock frequency --------------------------------------------*/ - /* Get HCLK prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)]; - /* HCLK clock frequency */ - SystemCoreClock >>= tmp; -} - -/** - * @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) -{ - /* 1- Try to start with HSE and external clock */ -#if USE_PLL_HSE_EXTC != 0 - if (SetSysClock_PLL_HSE(1) == 0) -#endif - { - /* 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 clock on MCO1 pin(PA8) for debugging purpose */ - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI48, RCC_MCODIV_1); -} - -#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) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* Used to gain time after DeepSleep in case HSI is used */ - if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) - { - 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_HSI48; - if (bypass == 0) - { - RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ - } - else - { - RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ - } - RCC_OscInitStruct.HSIState = RCC_HSI_OFF; -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) && \ - !defined (STM32L011xx) && !defined (STM32L021xx) - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ -#endif - // PLLCLK = (8 MHz * 8)/2 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - 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; // 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 */ - //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 - -/******************************************************************************/ -/* PLL (clocked by HSI) used as System clock source */ -/******************************************************************************/ -uint8_t SetSysClock_PLL_HSI(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* 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 and HSI48 oscillators and activate PLL with HSI as source */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; - RCC_OscInitStruct.HSEState = RCC_HSE_OFF; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) && \ - !defined (STM32L011xx) && !defined (STM32L021xx) - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ -#endif - // PLLCLK = (16 MHz * 4)/2 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - 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; // 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 -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_clock.c new file mode 100644 index 0000000000..1ea86c05f7 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_clock.c @@ -0,0 +1,227 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2017 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * This file configures the system clock as follows: + *----------------------------------------------------------------- + * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) + * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) + * | 3- USE_PLL_HSI (internal 16 MHz) + *----------------------------------------------------------------- + * SYSCLK(MHz) | 32 + * AHBCLK (MHz) | 32 + * APB1CLK (MHz) | 32 + * USB capable | NO + *----------------------------------------------------------------- + */ + +#include "stm32l0xx.h" +#include "mbed_assert.h" + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. + This value must be a multiple of 0x100. */ + +#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) +#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) +#define USE_PLL_HSI 0x2 // Use HSI internal clock + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +uint8_t SetSysClock_PLL_HSE(uint8_t bypass); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +uint8_t SetSysClock_PLL_HSI(void); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ + + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ +void SystemInit (void) +{ + /*!< Set MSION bit */ + RCC->CR |= (uint32_t)0x00000100U; + + /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ + RCC->CFGR &= (uint32_t) 0x88FF400CU; + + /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFF6U; + + /*!< Reset HSI48ON bit */ + RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; + + /*!< Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFFU; + + /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ + RCC->CFGR &= (uint32_t)0xFF02FFFFU; + + /*!< Disable all interrupts */ + RCC->CIER = 0x00000000U; + + /* 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 + +} + +/** + * @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) +{ +#if ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) + /* 1- Try to start with HSE and external clock */ + if (SetSysClock_PLL_HSE(1) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) + /* 2- If fail try to start with HSE and external xtal */ + if (SetSysClock_PLL_HSE(0) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSI) + /* 3- If fail start with HSI clock */ + if (SetSysClock_PLL_HSI() == 0) +#endif + { + while(1) { + MBED_ASSERT(1); + } + } + } + } + + /* Output clock on MCO1 pin(PA8) for debugging purpose */ + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); +} + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSE(uint8_t bypass) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Used to gain time after DeepSleep in case HSI is used */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) { + 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 oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + if (bypass == 0) { + RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ + } else { + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ + } + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + // PLLCLK = (8 MHz * 8)/2 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; + 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; // 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 */ + //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 /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +/******************************************************************************/ +/* PLL (clocked by HSI) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSI(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* 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_OscInitStruct.HSEState = RCC_HSE_OFF; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + // PLLCLK = (16 MHz * 4)/2 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; + 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; // 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 +} +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_stm32l0xx.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_stm32l0xx.c deleted file mode 100644 index d8eb0577f7..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_stm32l0xx.c +++ /dev/null @@ -1,523 +0,0 @@ -/** - ****************************************************************************** - * @file system_stm32l0xx.c - * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File. - * - * 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_stm32l0xx.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. - * - * 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) | 32 | 32 - *----------------------------------------------------------------------------- - * AHBCLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB1CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB2CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * USB capable (48 MHz precise clock) | YES | YES - *----------------------------------------------------------------------------- - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2015 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32l0xx_system - * @{ - */ - -/** @addtogroup STM32L0xx_System_Private_Includes - * @{ - */ - -#include "stm32l0xx.h" - -#if !defined (HSE_VALUE) - #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ - -#if !defined (MSI_VALUE) - #define MSI_VALUE ((uint32_t)2000000U) /*!< Value of the Internal oscillator in Hz*/ -#endif /* MSI_VALUE */ - -#if !defined (HSI_VALUE) - #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI_VALUE */ - - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Defines - * @{ - */ -/************************* Miscellaneous Configuration ************************/ - -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. - This value must be a multiple of 0x100. */ -/******************************************************************************/ -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Macros - * @{ - */ - -/* Select the clock sources (other than HSI) to start with (0=OFF, 1=ON) */ -#define USE_PLL_HSE_EXTC (0) /* Use external clock */ -#define USE_PLL_HSE_XTAL (0) /* Use external xtal */ -#define USE_MSI_OSC (0) /* Use multi-speed internal RC oscillator */ - -/** - * @} - */ - -/** @addtogroup STM32L0xx_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; - const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; - const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; - const uint8_t PLLMulTable[9] = {3U, 4U, 6U, 8U, 12U, 16U, 24U, 32U, 48U}; - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_FunctionPrototypes - * @{ - */ - -#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); -uint8_t SetSysClock_MSI(void); - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Functions - * @{ - */ - -/** - * @brief Setup the microcontroller system. - * @param None - * @retval None - */ -void SystemInit (void) -{ -/*!< Set MSION bit */ - RCC->CR |= (uint32_t)0x00000100U; - - /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ - RCC->CFGR &= (uint32_t) 0x88FF400CU; - - /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFF6U; - - /*!< Reset HSI48ON bit */ - RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; - - /*!< Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFFU; - - /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ - RCC->CFGR &= (uint32_t)0xFF02FFFFU; - - /*!< Disable all interrupts */ - RCC->CIER = 0x00000000U; - - /* 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 - -} - -/** - * @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. - * - * @note Each time the core clock (HCLK) changes, this function must be called - * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @note - The system frequency computed by this function is not the real - * frequency in the chip. It is calculated based on the predefined - * constant and the selected clock source: - * - * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI - * value as defined by the MSI range. - * - * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) - * - * - If SYSCLK source is HSE, 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 stm32l0xx_hal.h file (default value - * 16 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * - * (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value - * 8 MHz), user has to ensure that HSE_VALUE is same as the real - * frequency of the crystal used. Otherwise, this function may - * have wrong result. - * - * - The result of this function could be not correct when using fractional - * value for HSE crystal. - * @param None - * @retval None - */ -void SystemCoreClockUpdate (void) -{ - uint32_t tmp = 0U, pllmul = 0U, plldiv = 0U, pllsource = 0U, msirange = 0U; - - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & RCC_CFGR_SWS; - - switch (tmp) - { - case 0x00U: /* MSI used as system clock */ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U; - SystemCoreClock = (32768U * (1U << (msirange + 1U))); - break; - case 0x04U: /* HSI used as system clock */ - SystemCoreClock = HSI_VALUE; - break; - case 0x08U: /* HSE used as system clock */ - SystemCoreClock = HSE_VALUE; - break; - case 0x0CU: /* PLL used as system clock */ - /* Get PLL clock source and multiplication factor ----------------------*/ - pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; - plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; - pllmul = PLLMulTable[(pllmul >> 18U)]; - plldiv = (plldiv >> 22U) + 1U; - - pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; - - if (pllsource == 0x00U) - { - /* HSI oscillator clock selected as PLL clock entry */ - SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv); - } - else - { - /* HSE selected as PLL clock entry */ - SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv); - } - break; - default: /* MSI used as system clock */ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U; - SystemCoreClock = (32768U * (1U << (msirange + 1U))); - break; - } - /* Compute HCLK clock frequency --------------------------------------------*/ - /* Get HCLK prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)]; - /* HCLK clock frequency */ - SystemCoreClock >>= tmp; -} - -/** - * @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) -{ - /* 1- Try to start with HSE and external clock */ -#if USE_PLL_HSE_EXTC != 0 - if (SetSysClock_PLL_HSE(1) == 0) -#endif - { - /* 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 try to start with MSI */ - #if USE_MSI_OSC != 0 - if (SetSysClock_MSI() == 0) - #endif - { - /* 4- 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 clock on MCO1 pin(PA8) for debugging purpose */ - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI48, RCC_MCODIV_1); -} - -#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) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* Used to gain time after DeepSleep in case HSI is used */ - if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) - { - 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_HSI48; - if (bypass == 0) - { - RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ - } - else - { - RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ - } - RCC_OscInitStruct.HSIState = RCC_HSI_OFF; -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) && \ - !defined (STM32L011xx) && !defined (STM32L021xx) - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ -#endif - // PLLCLK = (8 MHz * 8)/2 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - 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; // 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 */ - //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 - -/******************************************************************************/ -/* PLL (clocked by HSI) used as System clock source */ -/******************************************************************************/ -uint8_t SetSysClock_PLL_HSI(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* 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 and HSI48 oscillators and activate PLL with HSI as source */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; - RCC_OscInitStruct.HSEState = RCC_HSE_OFF; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) && \ - !defined (STM32L011xx) && !defined (STM32L021xx) - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ -#endif - // PLLCLK = (16 MHz * 4)/2 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - 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; // 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 -} - -/******************************************************************************/ -/* MSI (4Mhz) used as System clock source */ -/******************************************************************************/ -uint8_t SetSysClock_MSI(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* Enable MSI Oscillator */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; - RCC_OscInitStruct.MSIState = RCC_MSI_ON; - RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6; - RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK) - { - /* Initialization Error */ - return 0; - } - - /* Select MSI 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_MSI; // 4 MHz - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 4 MHz - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 4 MHz - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 4 MHz - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0)!= HAL_OK) - { - /* Initialization Error */ - return 0; - } - - /* Enable Power Control clock */ - __HAL_RCC_PWR_CLK_ENABLE(); - - /* 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. */ - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); - - /* Disable Power Control clock */ - __HAL_RCC_PWR_CLK_DISABLE(); - - /* 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 -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/system_clock.c new file mode 100644 index 0000000000..0aa0cc6987 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/system_clock.c @@ -0,0 +1,244 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2017 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * This file configures the system clock as follows: + *----------------------------------------------------------------- + * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) + * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) + * | 3- USE_PLL_HSI (internal 16 MHz) + *----------------------------------------------------------------- + * SYSCLK(MHz) | 32 + * AHBCLK (MHz) | 32 + * APB1CLK (MHz) | 32 + * USB capable | YES + *----------------------------------------------------------------- + */ + +#include "stm32l0xx.h" +#include "mbed_assert.h" + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. + This value must be a multiple of 0x100. */ + +#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) +#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) +#define USE_PLL_HSI 0x2 // Use HSI internal clock + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +uint8_t SetSysClock_PLL_HSE(uint8_t bypass); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +uint8_t SetSysClock_PLL_HSI(void); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ + + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ +void SystemInit (void) +{ + /*!< Set MSION bit */ + RCC->CR |= (uint32_t)0x00000100U; + + /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ + RCC->CFGR &= (uint32_t) 0x88FF400CU; + + /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFF6U; + + /*!< Reset HSI48ON bit */ + RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; + + /*!< Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFFU; + + /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ + RCC->CFGR &= (uint32_t)0xFF02FFFFU; + + /*!< Disable all interrupts */ + RCC->CIER = 0x00000000U; + + /* 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 + +} + +/** + * @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) +{ +#if ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) + /* 1- Try to start with HSE and external clock */ + if (SetSysClock_PLL_HSE(1) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) + /* 2- If fail try to start with HSE and external xtal */ + if (SetSysClock_PLL_HSE(0) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSI) + /* 3- If fail start with HSI clock */ + if (SetSysClock_PLL_HSI() == 0) +#endif + { + while(1) { + MBED_ASSERT(1); + } + } + } + } + + /* Output clock on MCO1 pin(PA8) for debugging purpose */ + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI48, RCC_MCODIV_1); +} + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSE(uint8_t bypass) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; + + /* Used to gain time after DeepSleep in case HSI is used */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) { + 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_HSI48; + if (bypass == 0) { + RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ + } else { + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ + } + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ + // PLLCLK = (8 MHz * 8)/2 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; + 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; // 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 + } + + RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + RCC_PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != 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 /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +/******************************************************************************/ +/* PLL (clocked by HSI) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSI(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; + + /* 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 and HSI48 oscillators and activate PLL with HSI as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSEState = RCC_HSE_OFF; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = 16; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ + // PLLCLK = (16 MHz * 4)/2 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; + 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; // 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 + } + + RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + RCC_PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != 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 +} +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/system_stm32l0xx.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/system_stm32l0xx.c deleted file mode 100644 index 83f4fe6c24..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/system_stm32l0xx.c +++ /dev/null @@ -1,464 +0,0 @@ -/** - ****************************************************************************** - * @file system_stm32l0xx.c - * @author MCD Application Team - * @version V1.7.0 - * @date 31-May-2016 - * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File. - * - * 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_stm32l0xx.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. - * - * 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) | 32 | 32 - *----------------------------------------------------------------------------- - * AHBCLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB1CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB2CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * USB capable (48 MHz precise clock) | YES | YES - *----------------------------------------------------------------------------- - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2015 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32l0xx_system - * @{ - */ - -/** @addtogroup STM32L0xx_System_Private_Includes - * @{ - */ - -#include "stm32l0xx.h" - -#if !defined (HSE_VALUE) - #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ - -#if !defined (MSI_VALUE) - #define MSI_VALUE ((uint32_t)2000000U) /*!< Value of the Internal oscillator in Hz*/ -#endif /* MSI_VALUE */ - -#if !defined (HSI_VALUE) - #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI_VALUE */ - - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Defines - * @{ - */ -/************************* Miscellaneous Configuration ************************/ - -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. - This value must be a multiple of 0x100. */ -/******************************************************************************/ -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Macros - * @{ - */ - -/* 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 STM32L0xx_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; - const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; - const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; - const uint8_t PLLMulTable[9] = {3U, 4U, 6U, 8U, 12U, 16U, 24U, 32U, 48U}; - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_FunctionPrototypes - * @{ - */ - -#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); - -/** - * @} - */ - -/** @addtogroup STM32L0xx_System_Private_Functions - * @{ - */ - -/** - * @brief Setup the microcontroller system. - * @param None - * @retval None - */ -void SystemInit (void) -{ -/*!< Set MSION bit */ - RCC->CR |= (uint32_t)0x00000100U; - - /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ - RCC->CFGR &= (uint32_t) 0x88FF400CU; - - /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFF6U; - - /*!< Reset HSI48ON bit */ - RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; - - /*!< Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFFU; - - /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ - RCC->CFGR &= (uint32_t)0xFF02FFFFU; - - /*!< Disable all interrupts */ - RCC->CIER = 0x00000000U; - - /* 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 - -} - -/** - * @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. - * - * @note Each time the core clock (HCLK) changes, this function must be called - * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @note - The system frequency computed by this function is not the real - * frequency in the chip. It is calculated based on the predefined - * constant and the selected clock source: - * - * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI - * value as defined by the MSI range. - * - * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) - * - * - If SYSCLK source is HSE, 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 stm32l0xx_hal.h file (default value - * 16 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * - * (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value - * 8 MHz), user has to ensure that HSE_VALUE is same as the real - * frequency of the crystal used. Otherwise, this function may - * have wrong result. - * - * - The result of this function could be not correct when using fractional - * value for HSE crystal. - * @param None - * @retval None - */ -void SystemCoreClockUpdate (void) -{ - uint32_t tmp = 0U, pllmul = 0U, plldiv = 0U, pllsource = 0U, msirange = 0U; - - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & RCC_CFGR_SWS; - - switch (tmp) - { - case 0x00U: /* MSI used as system clock */ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U; - SystemCoreClock = (32768U * (1U << (msirange + 1U))); - break; - case 0x04U: /* HSI used as system clock */ - SystemCoreClock = HSI_VALUE; - break; - case 0x08U: /* HSE used as system clock */ - SystemCoreClock = HSE_VALUE; - break; - case 0x0CU: /* PLL used as system clock */ - /* Get PLL clock source and multiplication factor ----------------------*/ - pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; - plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; - pllmul = PLLMulTable[(pllmul >> 18U)]; - plldiv = (plldiv >> 22U) + 1U; - - pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; - - if (pllsource == 0x00U) - { - /* HSI oscillator clock selected as PLL clock entry */ - SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv); - } - else - { - /* HSE selected as PLL clock entry */ - SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv); - } - break; - default: /* MSI used as system clock */ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U; - SystemCoreClock = (32768U * (1U << (msirange + 1U))); - break; - } - /* Compute HCLK clock frequency --------------------------------------------*/ - /* Get HCLK prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)]; - /* HCLK clock frequency */ - SystemCoreClock >>= tmp; -} - -/** - * @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) -{ - /* 1- Try to start with HSE and external clock */ -#if USE_PLL_HSE_EXTC != 0 - if (SetSysClock_PLL_HSE(1) == 0) -#endif - { - /* 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 clock on MCO1 pin(PA8) for debugging purpose */ - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI48, RCC_MCODIV_1); -} - -#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) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* Used to gain time after DeepSleep in case HSI is used */ - if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) - { - 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_HSI48; - if (bypass == 0) - { - RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ - } - else - { - RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ - } - RCC_OscInitStruct.HSIState = RCC_HSI_OFF; -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) && \ - !defined (STM32L011xx) && !defined (STM32L021xx) - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ -#endif - // PLLCLK = (8 MHz * 8)/2 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - 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; // 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 */ - //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 - -/******************************************************************************/ -/* PLL (clocked by HSI) used as System clock source */ -/******************************************************************************/ -uint8_t SetSysClock_PLL_HSI(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* 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 and HSI48 oscillators and activate PLL with HSI as source */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; - RCC_OscInitStruct.HSEState = RCC_HSE_OFF; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) && \ - !defined (STM32L011xx) && !defined (STM32L021xx) - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ -#endif - // PLLCLK = (16 MHz * 4)/2 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - 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; // 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 -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_clock.c new file mode 100644 index 0000000000..0aa0cc6987 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_clock.c @@ -0,0 +1,244 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2017 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * This file configures the system clock as follows: + *----------------------------------------------------------------- + * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) + * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) + * | 3- USE_PLL_HSI (internal 16 MHz) + *----------------------------------------------------------------- + * SYSCLK(MHz) | 32 + * AHBCLK (MHz) | 32 + * APB1CLK (MHz) | 32 + * USB capable | YES + *----------------------------------------------------------------- + */ + +#include "stm32l0xx.h" +#include "mbed_assert.h" + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. + This value must be a multiple of 0x100. */ + +#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) +#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) +#define USE_PLL_HSI 0x2 // Use HSI internal clock + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +uint8_t SetSysClock_PLL_HSE(uint8_t bypass); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +uint8_t SetSysClock_PLL_HSI(void); +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ + + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ +void SystemInit (void) +{ + /*!< Set MSION bit */ + RCC->CR |= (uint32_t)0x00000100U; + + /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ + RCC->CFGR &= (uint32_t) 0x88FF400CU; + + /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFF6U; + + /*!< Reset HSI48ON bit */ + RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; + + /*!< Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFFU; + + /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ + RCC->CFGR &= (uint32_t)0xFF02FFFFU; + + /*!< Disable all interrupts */ + RCC->CIER = 0x00000000U; + + /* 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 + +} + +/** + * @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) +{ +#if ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) + /* 1- Try to start with HSE and external clock */ + if (SetSysClock_PLL_HSE(1) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) + /* 2- If fail try to start with HSE and external xtal */ + if (SetSysClock_PLL_HSE(0) == 0) +#endif + { +#if ((CLOCK_SOURCE) & USE_PLL_HSI) + /* 3- If fail start with HSI clock */ + if (SetSysClock_PLL_HSI() == 0) +#endif + { + while(1) { + MBED_ASSERT(1); + } + } + } + } + + /* Output clock on MCO1 pin(PA8) for debugging purpose */ + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); + //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI48, RCC_MCODIV_1); +} + +#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSE(uint8_t bypass) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; + + /* Used to gain time after DeepSleep in case HSI is used */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) { + 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_HSI48; + if (bypass == 0) { + RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ + } else { + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ + } + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ + // PLLCLK = (8 MHz * 8)/2 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; + 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; // 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 + } + + RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + RCC_PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != 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 /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ + +#if ((CLOCK_SOURCE) & USE_PLL_HSI) +/******************************************************************************/ +/* PLL (clocked by HSI) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSI(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; + + /* 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 and HSI48 oscillators and activate PLL with HSI as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSEState = RCC_HSE_OFF; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = 16; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ + // PLLCLK = (16 MHz * 4)/2 = 32 MHz + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; + 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; // 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 + } + + RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + RCC_PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != 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 +} +#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_stm32l0xx.c b/targets/TARGET_STM/TARGET_STM32L0/device/system_stm32l0xx.c similarity index 53% rename from targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_stm32l0xx.c rename to targets/TARGET_STM/TARGET_STM32L0/device/system_stm32l0xx.c index 83f4fe6c24..16d835199c 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_stm32l0xx.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/system_stm32l0xx.c @@ -6,37 +6,21 @@ * @date 31-May-2016 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File. * - * This file provides two functions and one global variable to be called from + * 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 + * - SystemInit(): This function is called at startup just after reset and * before branch to main program. This call is made inside * the "startup_stm32l0xx.s" file. * * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used - * by the user application to setup the SysTick + * 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. * - * 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) | 32 | 32 - *----------------------------------------------------------------------------- - * AHBCLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB1CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * APB2CLK (MHz) | 32 | 32 - *----------------------------------------------------------------------------- - * USB capable (48 MHz precise clock) | YES | YES - *----------------------------------------------------------------------------- + * ****************************************************************************** * @attention * @@ -73,22 +57,22 @@ /** @addtogroup stm32l0xx_system * @{ - */ - + */ + /** @addtogroup STM32L0xx_System_Private_Includes * @{ */ #include "stm32l0xx.h" -#if !defined (HSE_VALUE) +#if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (MSI_VALUE) #define MSI_VALUE ((uint32_t)2000000U) /*!< Value of the Internal oscillator in Hz*/ #endif /* MSI_VALUE */ - + #if !defined (HSI_VALUE) #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ @@ -125,10 +109,6 @@ * @{ */ -/* 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 */ - /** * @} */ @@ -139,12 +119,12 @@ /* 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 + 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; + uint32_t SystemCoreClock = 2000000U; const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; const uint8_t PLLMulTable[9] = {3U, 4U, 6U, 8U, 12U, 16U, 24U, 32U, 48U}; @@ -157,12 +137,6 @@ uint32_t SystemCoreClock = 32000000; * @{ */ -#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); - /** * @} */ @@ -171,25 +145,29 @@ uint8_t SetSysClock_PLL_HSI(void); * @{ */ +/*+ MBED */ +#if 0 +/*- MBED */ + /** * @brief Setup the microcontroller system. * @param None * @retval None */ void SystemInit (void) -{ +{ /*!< Set MSION bit */ RCC->CR |= (uint32_t)0x00000100U; /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ RCC->CFGR &= (uint32_t) 0x88FF400CU; - + /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFF6U; - + /*!< Reset HSI48ON bit */ RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; - + /*!< Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFFU; @@ -198,49 +176,52 @@ void SystemInit (void) /*!< Disable all interrupts */ RCC->CIER = 0x00000000U; - + /* 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 - } +/*+ MBED */ +#endif +/*- MBED */ + /** * @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. - * + * * @note Each time the core clock (HCLK) changes, this function must be called * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @note - The system frequency computed by this function is not the real - * frequency in the chip. It is calculated based on the predefined + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined * constant and the selected clock source: - * - * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI + * + * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI * value as defined by the MSI range. - * + * * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) - * + * * - If SYSCLK source is HSE, 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 stm32l0xx_hal.h file (default value * 16 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * + * in voltage and temperature. + * * (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value * 8 MHz), user has to ensure that HSE_VALUE is same as the real * frequency of the crystal used. Otherwise, this function may * have wrong result. - * + * * - The result of this function could be not correct when using fractional * value for HSE crystal. * @param None @@ -252,7 +233,7 @@ void SystemCoreClockUpdate (void) /* Get SYSCLK source -------------------------------------------------------*/ tmp = RCC->CFGR & RCC_CFGR_SWS; - + switch (tmp) { case 0x00U: /* MSI used as system clock */ @@ -271,7 +252,7 @@ void SystemCoreClockUpdate (void) plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; pllmul = PLLMulTable[(pllmul >> 18U)]; plldiv = (plldiv >> 22U) + 1U; - + pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; if (pllsource == 0x00U) @@ -297,157 +278,7 @@ void SystemCoreClockUpdate (void) SystemCoreClock >>= tmp; } -/** - * @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) -{ - /* 1- Try to start with HSE and external clock */ -#if USE_PLL_HSE_EXTC != 0 - if (SetSysClock_PLL_HSE(1) == 0) -#endif - { - /* 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 clock on MCO1 pin(PA8) for debugging purpose */ - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); - //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI48, RCC_MCODIV_1); -} - -#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) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* Used to gain time after DeepSleep in case HSI is used */ - if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) - { - 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_HSI48; - if (bypass == 0) - { - RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */ - } - else - { - RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External 8 MHz clock on OSC_IN */ - } - RCC_OscInitStruct.HSIState = RCC_HSI_OFF; -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) && \ - !defined (STM32L011xx) && !defined (STM32L021xx) - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ -#endif - // PLLCLK = (8 MHz * 8)/2 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - 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; // 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 */ - //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 - -/******************************************************************************/ -/* PLL (clocked by HSI) used as System clock source */ -/******************************************************************************/ -uint8_t SetSysClock_PLL_HSI(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* 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 and HSI48 oscillators and activate PLL with HSI as source */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48; - RCC_OscInitStruct.HSEState = RCC_HSE_OFF; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; -#if !defined (STM32L031xx) && !defined (STM32L041xx) && !defined(STM32L051xx) && !defined(STM32L061xx) && !defined(STM32L071xx) && !defined(STM32L081xx) && \ - !defined (STM32L011xx) && !defined (STM32L021xx) - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; /* For USB and RNG clock */ -#endif - // PLLCLK = (16 MHz * 4)/2 = 32 MHz - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; - RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - 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; // 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 -} /** * @} diff --git a/targets/targets.json b/targets/targets.json index 142edbc094..772041c5de 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1215,6 +1215,13 @@ "supported_toolchains": ["uARM"], "default_toolchain": "uARM", "supported_form_factors": ["ARDUINO"], + "config": { + "clock_source": { + "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", + "value": "USE_PLL_HSE_EXTC|USE_PLL_HSE_XTAL|USE_PLL_HSI", + "macro_name": "CLOCK_SOURCE" + } + }, "detect_code": ["0780"], "device_has_add": ["LOWPOWERTIMER", "SERIAL_FC", "FLASH"], "default_lib": "small", @@ -1227,6 +1234,13 @@ "extra_labels_add": ["STM32L0", "STM32L031K6"], "default_toolchain": "uARM", "supported_form_factors": ["ARDUINO"], + "config": { + "clock_source": { + "help": "Mask value : USE_PLL_HSE_EXTC (need HW patch) | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", + "value": "USE_PLL_HSI", + "macro_name": "CLOCK_SOURCE" + } + }, "detect_code": ["0790"], "device_has_add": ["LOWPOWERTIMER", "SERIAL_FC", "FLASH"], "default_lib": "small", @@ -1238,6 +1252,13 @@ "supported_form_factors": ["ARDUINO", "MORPHO"], "core": "Cortex-M0+", "extra_labels_add": ["STM32L0", "STM32L053R8"], + "config": { + "clock_source": { + "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", + "value": "USE_PLL_HSE_EXTC|USE_PLL_HSE_XTAL|USE_PLL_HSI", + "macro_name": "CLOCK_SOURCE" + } + }, "detect_code": ["0715"], "device_has_add": ["ANALOGOUT", "LOWPOWERTIMER", "SERIAL_FC", "SERIAL_ASYNCH", "FLASH"], "default_lib": "small", @@ -1249,6 +1270,13 @@ "supported_form_factors": ["ARDUINO", "MORPHO"], "core": "Cortex-M0+", "extra_labels_add": ["STM32L0", "STM32L073RZ", "STM32L073xx"], + "config": { + "clock_source": { + "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", + "value": "USE_PLL_HSE_EXTC|USE_PLL_HSE_XTAL|USE_PLL_HSI", + "macro_name": "CLOCK_SOURCE" + } + }, "detect_code": ["0760"], "device_has_add": ["ANALOGOUT", "LOWPOWERTIMER", "SERIAL_FC", "SERIAL_ASYNCH", "TRNG", "FLASH"], "release_versions": ["2", "5"], @@ -1418,6 +1446,13 @@ "core": "Cortex-M0+", "extra_labels_add": ["STM32L0", "STM32L053C8"], "macros": ["RTC_LSI=1"], + "config": { + "clock_source": { + "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", + "value": "USE_PLL_HSE_EXTC|USE_PLL_HSE_XTAL|USE_PLL_HSI", + "macro_name": "CLOCK_SOURCE" + } + }, "device_has_add": ["ANALOGOUT", "LOWPOWERTIMER", "SERIAL_FC", "FLASH"], "default_lib": "small", "release_versions": ["2"], @@ -1429,6 +1464,13 @@ "extra_labels_add": ["STM32L0", "STM32L072CZ", "STM32L072xx"], "supported_form_factors": ["ARDUINO", "MORPHO"], "macros": ["RTC_LSI=1"], + "config": { + "clock_source": { + "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", + "value": "USE_PLL_HSI", + "macro_name": "CLOCK_SOURCE" + } + }, "detect_code": ["0833"], "device_has_add": ["ANALOGOUT", "LOWPOWERTIMER", "SERIAL_FC", "SERIAL_ASYNCH", "TRNG"], "release_versions": ["2", "5"],