2014-09-21 20:07 GMT+02:00 <tomasz.grego...@gmail.com>: > From: Tomasz Gregorek <tomasz.grego...@gmail.com> > > Added simple math to caclulate register values for the PLL > and for the prescalers. It will try to keep 48MHz for the USB OTG FS. > Also it will set latency on the Flash memory for the high speeds. > > Limitations: > It is assumed that 1MHz resolution is enough. > Best fits for the clocks are achieved with multiplies of 42MHz. > Even though APB1, APB2 and AHB are calculated user is still required > to provide correct values for the bsp configuration for the: > STM32F4_PCLK1 > STM32F4_PCLK2 > STM32F4_HCLK (= system clock) > as those are used for the peripheral clocking calculations. > --- > c/src/lib/libbsp/arm/stm32f4/Makefile.am | 1 + > c/src/lib/libbsp/arm/stm32f4/include/stm32f4.h | 10 + > .../libbsp/arm/stm32f4/include/stm32f4xxxx_flash.h | 54 ++++ > .../libbsp/arm/stm32f4/include/stm32f4xxxx_rcc.h | 150 +++++++++-- > c/src/lib/libbsp/arm/stm32f4/preinstall.am | 4 + > c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c | 280 > ++++++++++++++++++++- > 6 files changed, 475 insertions(+), 24 deletions(-) > create mode 100644 > c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_flash.h > > diff --git a/c/src/lib/libbsp/arm/stm32f4/Makefile.am > b/c/src/lib/libbsp/arm/stm32f4/Makefile.am > index 027fcad..055a0b1 100644 > --- a/c/src/lib/libbsp/arm/stm32f4/Makefile.am > +++ b/c/src/lib/libbsp/arm/stm32f4/Makefile.am > @@ -51,6 +51,7 @@ include_bsp_HEADERS += include/stm32f10xxx_rcc.h > include_bsp_HEADERS += include/stm32f10xxx_exti.h > include_bsp_HEADERS += include/stm32f4xxxx_gpio.h > include_bsp_HEADERS += include/stm32f4xxxx_rcc.h > +include_bsp_HEADERS += include/stm32f4xxxx_flash.h > include_bsp_HEADERS += include/stm32_i2c.h > include_bsp_HEADERS += include/i2c.h > include_bsp_HEADERS += include/stm32_usart.h > diff --git a/c/src/lib/libbsp/arm/stm32f4/include/stm32f4.h > b/c/src/lib/libbsp/arm/stm32f4/include/stm32f4.h > index 59d13ef..d26f914 100644 > --- a/c/src/lib/libbsp/arm/stm32f4/include/stm32f4.h > +++ b/c/src/lib/libbsp/arm/stm32f4/include/stm32f4.h > @@ -55,6 +55,16 @@ > > /** @} */ > > +/** > + * @name STM32F4XXXX FLASH > + * @{ > + */ > + > +#include <bsp/stm32f4xxxx_flash.h> > +#define STM32F4_FLASH ((volatile stm32f4_flash *) (STM32F4_BASE + > 0x40023C00)) > + > +/** @} */ > + > #include <bsp/stm32_i2c.h> > > /** > diff --git a/c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_flash.h > b/c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_flash.h > new file mode 100644 > index 0000000..55d9dc6 > --- /dev/null > +++ b/c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_flash.h > @@ -0,0 +1,54 @@ > +/** > + * @file > + * > + * @ingroup stm32f4_flash > + * > + * @brief STM32F4XXXX FLASH support. > + * > + * Contains structure desribing registers responsible for the flash memory > + * configuration. > + */ > + > +/* > + * Copyright (c) 2014 Tomasz Gregorek. All rights reserved. > + * > + * <tomasz.grego...@gmail.com> > + * > + * The license and distribution terms for this file may be > + * found in the file LICENSE in this distribution or at > + * http://www.rtems.org/license/LICENSE. > + */ > + > +#ifndef LIBBSP_ARM_STM32F4_STM32F4XXXX_FLASH_H > +#define LIBBSP_ARM_STM32F4_STM32F4XXXX_FLASH_H > + > +#include <bsp/utility.h> > + > +/** > + * @defgroup stm32f10xxx_flash STM32F4XXXX FLASH Support > + * @ingroup stm32f4_flash > + * @brief STM32F4FXXX FLASH Support > + * @{ > + */ > + > +typedef struct { > + uint32_t acr; > + uint32_t keyr; > + uint32_t optkeyr; > + uint32_t sr; > + uint32_t cr; > + uint32_t optcr; > + uint32_t optcr1; > +} stm32f4_flash; > + > +/** @} */ > + > +#define FLASH_ACR_LATENCY( val ) BSP_FLD32( val, 0, 3 ) > +#define FLASH_ACR_LATENCY_MSK BSP_MSK32( 0, 3 ) > +#define FLASH_ACR_PRFTEN BSP_BIT32( 8 ) > +#define FLASH_ACR_ICEN BSP_BIT32( 9 ) > +#define FLASH_ACR_DCEN BSP_BIT32( 10 ) > +#define FLASH_ACR_ICRST BSP_BIT32( 11 ) > +#define FLASH_ACR_DCRST BSP_BIT32( 12 ) > + > +#endif /* LIBBSP_ARM_STM32F4_STM32F4XXXX_FLASH_H */ > \ No newline at end of file > diff --git a/c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_rcc.h > b/c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_rcc.h > index 8126340..311e484 100644 > --- a/c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_rcc.h > +++ b/c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_rcc.h > @@ -31,29 +31,135 @@ > */ > > typedef struct { > - uint32_t cr; > - uint32_t pllcfgr; > - uint32_t cfgr; > - uint32_t cir; > - uint32_t ahbrstr [3]; > - uint32_t reserved_1c; > - uint32_t apbrstr [2]; > - uint32_t reserved_28 [2]; > - uint32_t ahbenr [3]; > - uint32_t reserved_3c; > - uint32_t apbenr [2]; > - uint32_t reserved_48 [2]; > - uint32_t ahblpenr [3]; > - uint32_t reserved_5c; > - uint32_t apblpenr [2]; > - uint32_t reserved_68 [2]; > - uint32_t bdcr; > - uint32_t csr; > - uint32_t reserved_78 [2]; > - uint32_t sscgr; > - uint32_t plli2scfgr; > + uint32_t cr; > + uint32_t pllcfgr; > + uint32_t cfgr; > + uint32_t cir; > + uint32_t ahbrstr[ 3 ]; > + uint32_t reserved_1c; > + uint32_t apbrstr[ 2 ]; > + uint32_t reserved_28[ 2 ]; > + uint32_t ahbenr[ 3 ]; > + uint32_t reserved_3c; > + uint32_t apbenr[ 2 ]; > + uint32_t reserved_48[ 2 ]; > + uint32_t ahblpenr[ 3 ]; > + uint32_t reserved_5c; > + uint32_t apblpenr[ 2 ]; > + uint32_t reserved_68[ 2 ]; > + uint32_t bdcr; > + uint32_t csr; > + uint32_t reserved_78[ 2 ]; > + uint32_t sscgr; > + uint32_t plli2scfgr; > } stm32f4_rcc; > > /** @} */ > > -#endif /* LIBBSP_ARM_STM32F4_STM32F4XXXX_RCC_H */ > +#define RCC_CR_HSION BSP_BIT32( 0 ) > +#define RCC_CR_HSIRDY BSP_BIT32( 1 ) > +#define RCC_CR_HSITRIM( val ) BSP_FLD32( val, 3, 7 ) > +#define RCC_CR_HSITRIM_MSK BSP_MSK32( 3, 7 ) > +#define RCC_CR_HSICAL( val ) BSP_FLD32( val, 8, 15 ) > +#define RCC_CR_HSICAL_MSK BSP_MSK32( 8, 15 ) > +#define RCC_CR_HSEON BSP_BIT32( 16 ) > +#define RCC_CR_HSERDY BSP_BIT32( 17 ) > +#define RCC_CR_HSEBYP BSP_BIT32( 18 ) > +#define RCC_CR_CSSON BSP_BIT32( 19 ) > +#define RCC_CR_PLLON BSP_BIT32( 24 ) > +#define RCC_CR_PLLRDY BSP_BIT32( 25 ) > +#define RCC_CR_PLLI2SON BSP_BIT32( 26 ) > +#define RCC_CR_PLLI2SRDY BSP_BIT32( 27 ) > + > +#define RCC_PLLCFGR_PLLM( val ) BSP_FLD32( val, 0, 5 ) > +#define RCC_PLLCFGR_PLLM_MSK BSP_MSK32( 0, 5 ) > +#define RCC_PLLCFGR_PLLN( val ) BSP_FLD32( val, 6, 14 ) > +#define RCC_PLLCFGR_PLLN_MSK BSP_MSK32( 6, 14 ) > + > +#define RCC_PLLCFGR_PLLP 16 > +#define RCC_PLLCFGR_PLLP_MSK BSP_MSK32( 16, 17 ) > +#define RCC_PLLCFGR_PLLP_BY_2 0 > +#define RCC_PLLCFGR_PLLP_BY_4 BSP_FLD32( 1, 16, 17 ) > +#define RCC_PLLCFGR_PLLP_BY_6 BSP_FLD32( 2, 16, 17 ) > +#define RCC_PLLCFGR_PLLP_BY_8 BSP_FLD32( 3, 16, 17 ) > + > +#define RCC_PLLCFGR_PLLSRC_HSE BSP_BIT32( 22 ) > +#define RCC_PLLCFGR_PLLSRC_HSI 0 > + > +#define RCC_PLLCFGR_PLLQ( val ) BSP_FLD32( val, 24, 27 ) > +#define RCC_PLLCFGR_PLLQ_MSK BSP_MSK32( 24, 27 ) > + > +#define RCC_CFGR_SW 0 > +#define RCC_CFGR_SW_MSK BSP_MSK32( 0, 1 ) > +#define RCC_CFGR_SW_HSI 0 > +#define RCC_CFGR_SW_HSE 1 > +#define RCC_CFGR_SW_PLL 2 > + > +#define RCC_CFGR_SWS 2 > +#define RCC_CFGR_SWS_MSK BSP_MSK32( 2, 3 ) > +#define RCC_CFGR_SWS_HSI 0 > +#define RCC_CFGR_SWS_HSE BSP_FLD32( 1, 2, 3 ) > +#define RCC_CFGR_SWS_PLL BSP_FLD32( 2, 2, 3 ) > + > +#define RCC_CFGR_HPRE 4 > +#define RCC_CFGR_HPRE_BY_1 0 > +#define RCC_CFGR_HPRE_BY_2 BSP_FLD32( 8, 4, 7 ) > +#define RCC_CFGR_HPRE_BY_4 BSP_FLD32( 9, 4, 7 ) > +#define RCC_CFGR_HPRE_BY_8 BSP_FLD32( 10, 4, 7 ) > +#define RCC_CFGR_HPRE_BY_16 BSP_FLD32( 11, 4, 7 ) > +#define RCC_CFGR_HPRE_BY_64 BSP_FLD32( 12, 4, 7 ) > +#define RCC_CFGR_HPRE_BY_128 BSP_FLD32( 13, 4, 7 ) > +#define RCC_CFGR_HPRE_BY_256 BSP_FLD32( 14, 4, 7 ) > +#define RCC_CFGR_HPRE_BY_512 BSP_FLD32( 15, 4, 7 ) > + > +#define RCC_CFGR_PPRE1 10 > +#define RCC_CFGR_PPRE1_BY_1 0 > +#define RCC_CFGR_PPRE1_BY_2 BSP_FLD32( 4, 10, 12 ) > +#define RCC_CFGR_PPRE1_BY_4 BSP_FLD32( 5, 10, 12 ) > +#define RCC_CFGR_PPRE1_BY_8 BSP_FLD32( 6, 10, 12 ) > +#define RCC_CFGR_PPRE1_BY_16 BSP_FLD32( 7, 10, 12 ) > + > +#define RCC_CFGR_PPRE2 13 > +#define RCC_CFGR_PPRE2 BSP_MSK32( 13, 15 ) > +#define RCC_CFGR_PPRE2_BY_1 0 > +#define RCC_CFGR_PPRE2_BY_2 BSP_FLD32( 4, 13, 15 ) > +#define RCC_CFGR_PPRE2_BY_4 BSP_FLD32( 5, 13, 15 ) > +#define RCC_CFGR_PPRE2_BY_8 BSP_FLD32( 6, 13, 15 ) > +#define RCC_CFGR_PPRE2_BY_16 BSP_FLD32( 7, 13, 15 ) > + > +#define RCC_CFGR_RTCPRE( val ) BSP_FLD32( val, 16, 20 ) > +#define RCC_CFGR_RTCPRE_MSK BSP_MSK32( 16, 20 ) > + > +#define RCC_CFGR_MCO1 21 > +#define RCC_CFGR_MCO1_MSK BSP_MSK32( 21, 22 ) > +#define RCC_CFGR_MCO1_HSI 0 > +#define RCC_CFGR_MCO1_LSE BSP_FLD32( 1, 21, 22 ) > +#define RCC_CFGR_MCO1_HSE BSP_FLD32( 2, 21, 22 ) > +#define RCC_CFGR_MCO1_PLL BSP_FLD32( 3, 21, 22 ) > + > +#define RCC_CFGR_I2SSRC BSP_BIT32( 23 ) > + > +#define RCC_CFGR_MCO1PRE 24 > +#define RCC_CFGR_MCO1PRE_MSK BSP_MSK32( 24, 26 ) > +#define RCC_CFGR_MCO1PRE_BY_1 0 > +#define RCC_CFGR_MCO1PRE_BY_2 BSP_FLD32( 4, 24, 26 ) > +#define RCC_CFGR_MCO1PRE_BY_3 BSP_FLD32( 5, 24, 26 ) > +#define RCC_CFGR_MCO1PRE_BY_4 BSP_FLD32( 6, 24, 26 ) > +#define RCC_CFGR_MCO1PRE_BY_5 BSP_FLD32( 7, 24, 26 ) > + > +#define RCC_CFGR_MCO2PRE 27 > +#define RCC_CFGR_MCO2PRE_MSK BSP_MSK32( 27, 29 ) > +#define RCC_CFGR_MCO2PRE_BY_1 0 > +#define RCC_CFGR_MCO2PRE_BY_2 BSP_FLD32( 4, 27, 29 ) > +#define RCC_CFGR_MCO2PRE_BY_3 BSP_FLD32( 5, 27, 29 ) > +#define RCC_CFGR_MCO2PRE_BY_4 BSP_FLD32( 6, 27, 29 ) > +#define RCC_CFGR_MCO2PRE_BY_5 BSP_FLD32( 7, 27, 29 ) > + > +#define RCC_CFGR_MCO2 30 > +#define RCC_CFGR_MCO2_MSK BSP_MSK32( 30, 31 ) > +#define RCC_CFGR_MCO2_SYSCLK 0 > +#define RCC_CFGR_MCO2_PLLI2S BSP_FLD32( 1, 30, 31 ) > +#define RCC_CFGR_MCO2_HSE BSP_FLD32( 2, 30, 31 ) > +#define RCC_CFGR_MCO2_PLL BSP_FLD32( 3, 30, 31 ) > + > +#endif /* LIBBSP_ARM_STM32F4_STM32F4XXXX_RCC_H */ > \ No newline at end of file > diff --git a/c/src/lib/libbsp/arm/stm32f4/preinstall.am > b/c/src/lib/libbsp/arm/stm32f4/preinstall.am > index fd1604d..fe9a3b0 100644 > --- a/c/src/lib/libbsp/arm/stm32f4/preinstall.am > +++ b/c/src/lib/libbsp/arm/stm32f4/preinstall.am > @@ -121,6 +121,10 @@ $(PROJECT_INCLUDE)/bsp/stm32f4xxxx_rcc.h: > include/stm32f4xxxx_rcc.h $(PROJECT_IN > $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/stm32f4xxxx_rcc.h > PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/stm32f4xxxx_rcc.h > > +$(PROJECT_INCLUDE)/bsp/stm32f4xxxx_flash.h: include/stm32f4xxxx_flash.h > $(PROJECT_INCLUDE)/bsp/$(dirstamp) > + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/stm32f4xxxx_flash.h > +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/stm32f4xxxx_flash.h > + > $(PROJECT_INCLUDE)/bsp/stm32_i2c.h: include/stm32_i2c.h > $(PROJECT_INCLUDE)/bsp/$(dirstamp) > $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/stm32_i2c.h > PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/stm32_i2c.h > diff --git a/c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c > b/c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c > index d337d3a..0d08458 100644 > --- a/c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c > +++ b/c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c > @@ -17,10 +17,286 @@ > #include <bsp/irq.h> > #include <bsp/bootcard.h> > #include <bsp/irq-generic.h> > +#include <assert.h> > +#include <bsp/stm32f4.h> > > -void bsp_start(void) > +#ifdef STM32F4_FAMILY_F4XXXX > + > +#include <bsp/stm32f4xxxx_rcc.h> > +#include <bsp/stm32f4xxxx_flash.h> > + > +static rtems_status_code set_system_clk( > + uint32_t sys_clk, > + uint32_t hse_clk, > + uint32_t hse_flag > +); > + > +static void init_main_osc( void ) > +{ > + volatile stm32f4_rcc *rcc = STM32F4_RCC; > + rtems_status_code status; > + > + /* Revert to reset values */ > + rcc->cr |= RCC_CR_HSION; /* turn on HSI */ > + > + while ( !( rcc->cr & RCC_CR_HSIRDY ) ) ; > + > + rcc->cfgr &= 0x00000300; /* all prescalers to 0, clock source to HSI */ > + > + rcc->cr &= 0xF0F0FFFD; /* turn off all clocks and PLL except HSI */ > + > + status = set_system_clk( STM32F4_SYSCLK / 1000000L, > + STM32F4_HSE_OSCILLATOR / 1000000L, > + 1 ); > + > + assert( rtems_is_status_successful( status ) ); > +} > + > +/** > + * @brief Sets up clocks configuration. > + * > + * Set up clocks configuration to achieve desired system clock > + * as close as possible with simple math. > + * > + * Limitations: > + * It is assumed that 1MHz resolution is enough. > + * Best fits for the clocks are achieved with multiplies of 42MHz. > + * Even though APB1, APB2 and AHB are calculated user is still required > + * to provide correct values for the bsp configuration for the: > + * STM32F4_PCLK1 > + * STM32F4_PCLK2 > + * STM32F4_HCLK > + * as those are used for the peripheral clocking calculations. > + * > + * @param sys_clk Desired system clock in MHz. > + * @param hse_clk External clock speed in MHz. > + * @param hse_flag Flag determining which clock source to use, 1 for HSE, > + * 0 for HSI. > + * > + * @retval RTEMS_SUCCESSFUL Configuration has been succesfully aplied for > the > + * requested clock speed. > + * @retval RTEMS_TIMEOUT HSE clock didn't start or PLL didn't lock. > + * @retval RTEMS_INVALID_NUMBER Requested clock speed is out of range. > + */ > +static rtems_status_code set_system_clk( > + uint32_t sys_clk, > + uint32_t hse_clk, > + uint32_t hse_flag > +) > +{ > + volatile stm32f4_rcc *rcc = STM32F4_RCC; > + volatile stm32f4_flash *flash = STM32F4_FLASH; > + long timeout = 0; > + > + int src_clk = 0; > + > + uint32_t pll_m = 0; > + uint32_t pll_n = 0; > + uint32_t pll_p = 0; > + uint32_t pll_q = 0; > + > + uint32_t ahbpre = 0; > + uint32_t apbpre1 = 0; > + uint32_t apbpre2 = 0; > + > + if ( sys_clk == 16 && hse_clk != 16 ) { > + /* Revert to reset values */ > + rcc->cr |= RCC_CR_HSION; /* turn on HSI */ > + > + while ( !( rcc->cr & RCC_CR_HSIRDY ) ) ; > + > + /* all prescalers to 0, clock source to HSI */ > + rcc->cfgr &= 0x00000300 | RCC_CFGR_SW_HSI; > + rcc->cr &= 0xF0F0FFFD; /* turn off all clocks and PLL except HSI */ > + flash->acr = 0; /* slow clock so no cache, no prefetch, no latency */ > + > + return RTEMS_SUCCESSFUL; > + } > + > + if ( sys_clk == hse_clk ) { > + /* Revert to reset values */ > + rcc->cr |= RCC_CR_HSEON; /* turn on HSE */ > + timeout = 400; > + > + while ( !( rcc->cr & RCC_CR_HSERDY ) && --timeout ) ; > + > + assert( timeout != 0 ); > + > + if ( timeout == 0 ) { > + return RTEMS_TIMEOUT; > + } > + > + /* all prescalers to 0, clock source to HSE */ > + rcc->cfgr &= 0x00000300; > + rcc->cfgr |= RCC_CFGR_SW_HSE; > + /* turn off all clocks and PLL except HSE */ > + rcc->cr &= 0xF0F0FFFC | RCC_CR_HSEON; > + flash->acr = 0; /* slow clock so no cache, no prefetch, no latency */ > + > + return RTEMS_SUCCESSFUL; > + } > + > + /* > + * Lets use 1MHz input for PLL so we get higher VCO output > + * this way we get better value for the PLL_Q divader for the USB > + * > + * Though you might want to use 2MHz as per CPU specification: > + * > + * Caution:The software has to set these bits correctly to ensure > + * that the VCO input frequency ranges from 1 to 2 MHz. > + * It is recommended to select a frequency of 2 MHz to limit PLL jitter. > + */ > + > + if ( sys_clk > 180 ) { > + return RTEMS_INVALID_NUMBER; > + } else if ( sys_clk >= 96 ) { > + pll_n = sys_clk << 1; > + pll_p = RCC_PLLCFGR_PLLP_BY_2; > + } else if ( sys_clk >= 48 ) { > + pll_n = sys_clk << 2; > + pll_p = RCC_PLLCFGR_PLLP_BY_4; > + } else if ( sys_clk >= 24 ) { > + pll_n = sys_clk << 3; > + pll_p = RCC_PLLCFGR_PLLP_BY_8; > + } else { > + return RTEMS_INVALID_NUMBER; > + } > + > + if ( hse_clk == 0 || hse_flag == 0 ) { > + src_clk = 16; > + hse_flag = 0; > + } else { > + src_clk = hse_clk; > + } > + > + pll_m = src_clk; /* divide by the oscilator speed in MHz */ > + > + /* pll_q is a prescaler from VCO for the USB OTG FS, SDIO and RNG, > + * best if results in the 48MHz for the USB > + */ > + pll_q = ( (long) ( src_clk * pll_n + src_clk * pll_n / 2 ) ) / pll_m / > 48; > + > + if ( pll_q < 2 ) { > + pll_q = 2; > + } > + > + /* APB1 prescaler, APB1 clock must be < 42MHz */ > + apbpre1 = ( sys_clk * 100 ) / 42; > + > + if ( apbpre1 <= 100 ) { > + apbpre1 = RCC_CFGR_PPRE1_BY_1; > + } else if ( apbpre1 <= 200 ) { > + apbpre1 = RCC_CFGR_PPRE1_BY_2; > + } else if ( apbpre1 <= 400 ) { > + apbpre1 = RCC_CFGR_PPRE1_BY_4; > + } else if ( apbpre1 <= 800 ) { > + apbpre1 = RCC_CFGR_PPRE1_BY_8; > + } else if ( apbpre1 ) { > + apbpre1 = RCC_CFGR_PPRE1_BY_16; > + } > + > + /* APB2 prescaler, APB2 clock must be < 84MHz */ > + apbpre2 = ( sys_clk * 100 ) / 84; > + > + if ( apbpre2 <= 100 ) { > + apbpre2 = RCC_CFGR_PPRE2_BY_1; > + } else if ( apbpre2 <= 200 ) { > + apbpre2 = RCC_CFGR_PPRE2_BY_2; > + } else if ( apbpre2 <= 400 ) { > + apbpre2 = RCC_CFGR_PPRE2_BY_4; > + } else if ( apbpre2 <= 800 ) { > + apbpre2 = RCC_CFGR_PPRE2_BY_8; > + } else { > + apbpre2 = RCC_CFGR_PPRE2_BY_16; > + } > + > + rcc->cr |= RCC_CR_HSION; /* turn on HSI */ > + > + while ( ( !( rcc->cr & RCC_CR_HSIRDY ) ) ) ; > + > + /* all prescalers to 0, clock source to HSI */ > + rcc->cfgr &= 0x00000300; > + rcc->cfgr |= RCC_CFGR_SW_HSI; > + > + while ( ( ( rcc->cfgr & RCC_CFGR_SWS_MSK ) != RCC_CFGR_SWS_HSI ) ) ; > + > + /* turn off PLL */ > + rcc->cr &= ~( RCC_CR_PLLON | RCC_CR_PLLRDY ); > + > + /* turn on HSE */ > + if ( hse_flag ) { > + rcc->cr |= RCC_CR_HSEON; > + timeout = 400; > + > + while ( ( !( rcc->cr & RCC_CR_HSERDY ) ) && timeout-- ) ; > + > + assert( timeout != 0 ); > + > + if ( timeout == 0 ) { > + return RTEMS_TIMEOUT; > + } > + } > + > + rcc->pllcfgr &= 0xF0BC8000; /* clear PLL prescalers */ > + > + /* set pll parameters */ > + rcc->pllcfgr |= RCC_PLLCFGR_PLLM( pll_m ) | /* input divider */ > + RCC_PLLCFGR_PLLN( pll_n ) | /* multiplier */ > + pll_p | /* output divider from > table */ > + /* HSE v HSI */ > + ( hse_flag ? RCC_PLLCFGR_PLLSRC_HSE : > RCC_PLLCFGR_PLLSRC_HSI ) > + | > + RCC_PLLCFGR_PLLQ( pll_q ); /* PLLQ divider */ > + > + /* set prescalers for the internal busses */ > + rcc->cfgr |= apbpre1 | > + apbpre2 | > + ahbpre; > + > + /* > + * Set flash parameters, hard coded for now for fast system clocks. > + * TODO implement some math to use flash on as low latancy as possible > + */ > + flash->acr = FLASH_ACR_LATENCY( 5 ) | /* latency */ > + FLASH_ACR_ICEN | /* instruction cache */ > + FLASH_ACR_DCEN; /* data cache */ > + > + /* turn on PLL */ > + rcc->cr |= RCC_CR_PLLON; > + timeout = 40000; > + > + while ( ( !( rcc->cr & RCC_CR_PLLRDY ) ) && --timeout ) ; > + > + assert( timeout != 0 ); > + > + if ( timeout == 0 ) { > + return RTEMS_TIMEOUT; > + } > + > + /* clock source to PLL */ > + rcc->cfgr = ( rcc->cfgr & ~RCC_CFGR_SW_MSK ) | RCC_CFGR_SW_PLL; > + > + while ( ( ( rcc->cfgr & RCC_CFGR_SWS_MSK ) != RCC_CFGR_SWS_PLL ) ) ; > + > + return RTEMS_SUCCESSFUL; > +} > + > +#endif /* STM32F4_FAMILY_F4XXXX */ > + > +#ifdef STM32F4_FAMILY_F10XXX > + > +static void init_main_osc( void ) > +{ > + > +} > + > +#endif /* STM32F4_FAMILY_F10XXX */ > + > +void bsp_start( void ) > { > - stm32f4_gpio_set_config_array(&stm32f4_start_config_gpio [0]); > + init_main_osc(); > + > + stm32f4_gpio_set_config_array( &stm32f4_start_config_gpio[ 0 ] ); > > bsp_interrupt_initialize(); > } > -- > 2.1.0 > > Hi
Any chance for someone to take a look at this patch? Cheers Tomasz
_______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel