mbed library sources
Fork of mbed-src by
Diff: targets/cmsis/TARGET_STM/TARGET_DISCO_F051R8/system_stm32f0xx.c
- Revision:
- 240:9a7c54113eaf
- Parent:
- 130:1dec54e4aec3
diff -r 8cadf13dff33 -r 9a7c54113eaf targets/cmsis/TARGET_STM/TARGET_DISCO_F051R8/system_stm32f0xx.c --- a/targets/cmsis/TARGET_STM/TARGET_DISCO_F051R8/system_stm32f0xx.c Thu Jun 26 09:15:07 2014 +0100 +++ b/targets/cmsis/TARGET_STM/TARGET_DISCO_F051R8/system_stm32f0xx.c Thu Jun 26 09:45:08 2014 +0100 @@ -3,11 +3,11 @@ * @file system_stm32f0xx.c * @author MCD Application Team * @version V1.0.1 - * @date 29-May-2012 + * @date 12-January-2014 * @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File. * This file contains the system clock configuration for STM32F0xx devices, * and is generated by the clock configuration tool - * STM32f0xx_Clock_Configuration_V1.0.1.xls + * STM32F0xx_Clock_Configuration_V1.0.1.xls * * 1. This file provides two functions and one global variable to be called from * user application: @@ -40,52 +40,44 @@ * value to your own configuration. * * 5. This file configures the system clock as follows: - *============================================================================= - *============================================================================= - * System Clock source | PLL(HSI) *----------------------------------------------------------------------------- - * SYSCLK(Hz) | 48000000 - *----------------------------------------------------------------------------- - * HCLK(Hz) | 48000000 - *----------------------------------------------------------------------------- - * AHB Prescaler | 1 - *----------------------------------------------------------------------------- - * APB Prescaler | 1 + * System clock source | 1- PLL_HSE_EXTC | 3- PLL_HSI + * | (external 8 MHz clock) | (internal 8 MHz) + * | 2- PLL_HSE_XTAL | + * | (external 8 MHz xtal) | *----------------------------------------------------------------------------- - * HSE Frequency(Hz) | NA - *---------------------------------------------------------------------------- - * PLLMUL | 12 - *----------------------------------------------------------------------------- - * PREDIV | 2 + * SYSCLK(MHz) | 48 | 48 *----------------------------------------------------------------------------- - * I2S input clock(Hz) | 48000000 - * | - * To achieve the following I2S config: | - * - Master clock output (MCKO): OFF | - * - Frame wide : 16bit | - * - Audio sampling freq (KHz) : 44.1 | - * - Error % : 0.2674 | + * AHBCLK (MHz) | 48 | 48 *----------------------------------------------------------------------------- - * Flash Latency(WS) | 1 - *----------------------------------------------------------------------------- - * Prefetch Buffer | ON + * APBCLK (MHz) | 48 | 48 *----------------------------------------------------------------------------- ****************************************************************************** * @attention * - * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> * - * http://www.st.com/software_license_agreement_liberty_v2 + * 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. * - * 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 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. * ****************************************************************************** */ @@ -127,6 +119,10 @@ * @{ */ +/* 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 */ + /** * @} */ @@ -145,7 +141,11 @@ * @{ */ -static void SetSysClock(void); +#if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0) +uint8_t SetSysClock_PLL_HSE(uint8_t bypass); +#endif + +uint8_t SetSysClock_PLL_HSI(void); /** * @} @@ -191,7 +191,8 @@ /* Disable all interrupts */ RCC->CIR = 0x00000000; - /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */ + /* Configure the System clock source, PLL Multiplier and Divider factors, + AHB/APBx prescalers and Flash settings */ SetSysClock(); } @@ -275,35 +276,136 @@ } /** - * @brief Configures the System clock frequency, 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). + * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. * @param None * @retval None */ -static void SetSysClock(void) +void SetSysClock(void) { -/******************************************************************************/ -/* PLL (clocked by HSI) used as System clock source */ + /* 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 MCO pin (PA8) for debugging purpose + /* + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; + GPIO_Init(GPIOA, &GPIO_InitStructure); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_0); + // Output clock on MCO pin + // Warning: only RCC_MCOPrescaler_1 is available on STM32F030x8 devices + RCC_MCOConfig(RCC_MCOSource_SYSCLK, RCC_MCOPrescaler_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) +{ + __IO uint32_t StartUpCounter = 0; + __IO uint32_t HSEStatus = 0; - /* At this stage the HSI is already enabled and used as System clock source */ + /* Bypass HSE: can be done only if HSE is OFF */ + RCC->CR &= ((uint32_t)~RCC_CR_HSEON); /* To be sure HSE is OFF */ + if (bypass != 0) + { + RCC->CR |= ((uint32_t)RCC_CR_HSEBYP); + } + else + { + RCC->CR &= ((uint32_t)~RCC_CR_HSEBYP); + } - /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/ + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + /* Check if HSE has started correctly */ + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + /* Enable Prefetch Buffer */ + FLASH->ACR |= FLASH_ACR_PRFTBE; /* Enable Prefetch Buffer and set Flash Latency */ FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; - /* HCLK = SYSCLK / 1 */ - RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; + /* PLL configuration + PLLCLK = 48 MHz (xtal 8 MHz * 6) */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6 + | RCC_CFGR_HPRE_DIV1 /* HCLK = 48 MHz */ + | RCC_CFGR_PPRE_DIV1); /* PCLK = 48 MHz */ + + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } - /* PCLK = HCLK / 1 */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1; + /* Select PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) + { + } - /* PLL configuration */ + return 1; // OK + } + else + { + return 0; // FAIL + } +} +#endif + +/******************************************************************************/ +/* PLL (clocked by HSI) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSI(void) +{ + /* Enable Prefetch Buffer and set Flash Latency */ + FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; + + /* PLL configuration + PLLCLK = 48 MHz ((HSI 8 MHz / 2) * 12) */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL12); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL12 + | RCC_CFGR_HPRE_DIV1 /* HCLK = 48 MHz */ + | RCC_CFGR_PPRE_DIV1); /* PCLK = 48 MHz */ /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; @@ -321,6 +423,8 @@ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) { } + + return 1; // OK } /**