[PATCH] bsp/stm32f4XXXX: System clock configuration

Tomasz Gregorek tomasz.gregorek at gmail.com
Tue Sep 30 14:18:05 UTC 2014


2014-09-21 20:07 GMT+02:00 <tomasz.gregorek at gmail.com>:

> From: Tomasz Gregorek <tomasz.gregorek at 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.gregorek at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20140930/cf1548e8/attachment-0002.html>


More information about the devel mailing list