diff options
-rw-r--r-- | c/src/lib/libbsp/arm/stm32f4/Makefile.am | 1 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/stm32f4/include/stm32f4.h | 10 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_flash.h | 54 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_rcc.h | 150 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/stm32f4/preinstall.am | 4 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c | 280 |
6 files changed, 475 insertions, 24 deletions
diff --git a/c/src/lib/libbsp/arm/stm32f4/Makefile.am b/c/src/lib/libbsp/arm/stm32f4/Makefile.am index 027fcad382..055a0b1d1d 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 59d13ef0f6..d26f914887 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 0000000000..55d9dc6f3b --- /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.gregorek@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 8126340e89..311e484235 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 fd1604deca..fe9a3b073a 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 d337d3aa2c..0d08458c2e 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(); } |