Style comments from me. I will let those who know who the HW comment on that.
On September 20, 2014 1:23:26 PM CDT, "tomasz.grego...@gmail.com" <tomasz.grego...@gmail.com> wrote: >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 slow down Flash memory for the high speeds. >--- > c/src/lib/libbsp/arm/stm32f4/include/stm32f4.h | 10 + > .../libbsp/arm/stm32f4/include/stm32f4xxxx_flash.h | 41 ++++ > .../libbsp/arm/stm32f4/include/stm32f4xxxx_rcc.h | 94 +++++++++ >c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c | 211 >+++++++++++++++++++++ > 4 files changed, 356 insertions(+) >create mode 100644 >c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_flash.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..31b3992 >--- /dev/null >+++ b/c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_flash.h >@@ -0,0 +1,41 @@ >+/** >+ * @file >+ * @ingroup stm32f4_flash >+ * @brief STM32F4XXXX FLASH support. >+ */ >+ >+/* >+ * Copyright (c) 2014 Tomasz Gregorek. All rights reserved. >+ * >+ * <tomasz.grego...@gmial.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; >+ >+/** @} */ >+ >+#endif /* LIBBSP_ARM_STM32F4_STM32F4XXXX_FLASH_H */ >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..ce85b8e 100644 >--- a/c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_rcc.h >+++ b/c/src/lib/libbsp/arm/stm32f4/include/stm32f4xxxx_rcc.h >@@ -56,4 +56,98 @@ typedef struct { > > /** @} */ > >+#define RCC_CR_HSION BSP_BIT32(0) >+#define RCC_CR_HSIRDY BSP_BIT32(1) >+#define RCC_CR_HSITRIM 3 >+#define RCC_CR_HSICAL 8 >+#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 0 >+#define RCC_PLLCFGR_PLLN 6 >+#define RCC_PLLCFGR_PLLP 16 >+ >+#define RCC_PLLCFGR_PLLSRC_HSE BSP_BIT32(22) >+#define RCC_PLLCFGR_PLLSRC_HSI 0 >+ >+#define RCC_PLLCFGR_PLLQ 24 >+ >+ >+#define RCC_CFGR_SW 0 >+#define RCC_CFGR_SW_MASK 3 >+#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_MASK (3 << RCC_CFGR_SWS) >+ >+#define RCC_CFGR_SWS_HSI 0 >+#define RCC_CFGR_SWS_HSE (1 << RCC_CFGR_SWS) >+#define RCC_CFGR_SWS_PLL (2 << RCC_CFGR_SWS) >+ >+#define RCC_CFGR_HPRE 4 >+#define RCC_CFGR_HPRE_BY_1 0 >+#define RCC_CFGR_HPRE_BY_2 ( 8 << RCC_CFGR_HPRE) >+#define RCC_CFGR_HPRE_BY_4 ( 9 << RCC_CFGR_HPRE) >+#define RCC_CFGR_HPRE_BY_8 (10 << RCC_CFGR_HPRE) >+#define RCC_CFGR_HPRE_BY_16 (11 << RCC_CFGR_HPRE) >+#define RCC_CFGR_HPRE_BY_64 (12 << RCC_CFGR_HPRE) >+#define RCC_CFGR_HPRE_BY_128 (13 << RCC_CFGR_HPRE) >+#define RCC_CFGR_HPRE_BY_256 (14 << RCC_CFGR_HPRE) >+#define RCC_CFGR_HPRE_BY_512 (15 << RCC_CFGR_HPRE) >+ >+#define RCC_CFGR_PPRE1 10 >+#define RCC_CFGR_PPRE1_BY_1 0 >+#define RCC_CFGR_PPRE1_BY_2 (4 << RCC_CFGR_PPRE1) >+#define RCC_CFGR_PPRE1_BY_4 (5 << RCC_CFGR_PPRE1) >+#define RCC_CFGR_PPRE1_BY_8 (6 << RCC_CFGR_PPRE1) >+#define RCC_CFGR_PPRE1_BY_16 (7 << RCC_CFGR_PPRE1) >+ >+#define RCC_CFGR_PPRE2 13 >+#define RCC_CFGR_PPRE2_BY_1 0 >+#define RCC_CFGR_PPRE2_BY_2 (4 << RCC_CFGR_PPRE2) >+#define RCC_CFGR_PPRE2_BY_4 (5 << RCC_CFGR_PPRE2) >+#define RCC_CFGR_PPRE2_BY_8 (6 << RCC_CFGR_PPRE2) >+#define RCC_CFGR_PPRE2_BY_16 (7 << RCC_CFGR_PPRE2) >+ >+#define RCC_CFGR_RTCPRE 16 >+#define RCC_CFGR_RTCPRE_SET(a) (a << RCC_CFGR_RTCPRE) >+ >+#define RCC_CFGR_MCO1 21 >+#define RCC_CFGR_MCO1_HSI 0 >+#define RCC_CFGR_MCO1_LSE (1 << RCC_CFGR_MCO1) >+#define RCC_CFGR_MCO1_HSE (2 << RCC_CFGR_MCO1) >+#define RCC_CFGR_MCO1_PLL (3 << RCC_CFGR_MCO1) >+ >+#define RCC_CFGR_I2SSRC BSP_BIT32(23) >+ >+#define RCC_CFGR_MCO1PRE 24 >+#define RCC_CFGR_MCO1PRE_BY_1 0 >+#define RCC_CFGR_MCO1PRE_BY_2 (4 << RCC_CFGR_MCO1PRE) >+#define RCC_CFGR_MCO1PRE_BY_3 (5 << RCC_CFGR_MCO1PRE) >+#define RCC_CFGR_MCO1PRE_BY_4 (6 << RCC_CFGR_MCO1PRE) >+#define RCC_CFGR_MCO1PRE_BY_5 (7 << RCC_CFGR_MCO1PRE) >+ >+#define RCC_CFGR_MCO2PRE 27 >+#define RCC_CFGR_MCO2PRE_BY_1 0 >+#define RCC_CFGR_MCO2PRE_BY_2 (4 << RCC_CFGR_MCO2PRE) >+#define RCC_CFGR_MCO2PRE_BY_3 (5 << RCC_CFGR_MCO2PRE) >+#define RCC_CFGR_MCO2PRE_BY_4 (6 << RCC_CFGR_MCO2PRE) >+#define RCC_CFGR_MCO2PRE_BY_5 (7 << RCC_CFGR_MCO2PRE) >+ >+#define RCC_CFGR_MCO2 30 >+#define RCC_CFGR_MCO2_SYSCLK 0 >+#define RCC_CFGR_MCO2_PLLI2S (1 << RCC_CFGR_MCO2) >+#define RCC_CFGR_MCO2_HSE (2 << RCC_CFGR_MCO2) >+#define RCC_CFGR_MCO2_PLL (3 << RCC_CFGR_MCO2) >+ >+ > #endif /* LIBBSP_ARM_STM32F4_STM32F4XXXX_RCC_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..31823d1 100644 >--- a/c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c >+++ b/c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c >@@ -17,9 +17,220 @@ > #include <bsp/irq.h> > #include <bsp/bootcard.h> > #include <bsp/irq-generic.h> >+#include <bsp/stm32f4.h> >+#include <bsp/stm32f4xxxx_rcc.h> >+#include <bsp/stm32f4xxxx_flash.h> >+ >+static rtems_status_code set_system_clk(uint32_t sysclk, uint32_t >hseclk, uint32_t hseflag); >+ >+static void init_main_osc(void) >+{ >+ volatile stm32f4_rcc *rcc = STM32F4_RCC; >+ >+ /* 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 >*/ >+ >+ set_system_clk(STM32F4_SYSCLK / 1000000L, STM32F4_HSE_OSCILLATOR / >1000000L, 1); >+} >+ >+ >+/* >+ * Sets up clocks configuration to achieve desired system clock >+ * as close as possible with simple math >+ */ >+static rtems_status_code set_system_clk(uint32_t sysclk, uint32_t >hseclk, uint32_t hseflag) >+{ >+ volatile stm32f4_rcc *rcc = STM32F4_RCC; >+ volatile stm32f4_flash *flash = STM32F4_FLASH; >+ rtems_interrupt_level level; >+ long timeout = 0; >+ const long timeoutset = 10000000L; >+ >+ int srcclk = 0; >+ >+ int pll_m = 0; >+ int pll_n = 0; >+ int pll_p = 0; >+ int pll_q = 0; >+ //int cr; No C++ style comments and no commented out code without good reason. >+ int ahbpre = 0; >+ int apbpre1 = 0; >+ int apbpre2 = 0; >+ >+ if (sysclk == 16) { >+ /* Revert to reset values */ >+ rcc->cr |= 0x00000001; /* turn on HSI */ >+ while (! (rcc->cr & (1 << 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 >*/ >+ >+ flash->acr = 0; /* slow clock so no cache, no prefetch, no latency >*/ >+ >+ return RTEMS_SUCCESSFUL; >+ } >+ >+ if (hseclk == 0 || hseflag == 0) { >+ srcclk = 16; >+ hseflag = 0; >+ } >+ else { >+ srcclk = hseclk; >+ } >+ >+ if (sysclk > 180) { >+ return RTEMS_INVALID_NUMBER; >+ } >+ else if (sysclk > 96) { >+ pll_n = sysclk; /* multpily by the desired speed in MHz */ >+ pll_p = 0; /* divide by 2 */ >+ } >+ else if (sysclk > 48) { >+ pll_n = sysclk >> 1; /* multpily by 2x the desired speed in MHz */ >+ pll_p = 1; /* divide by 4 */ >+ } >+ else if (sysclk > 24) { >+ pll_n = sysclk >> 2; /* multpily by 4x the desired speed in MHz */ >+ pll_p = 3; /* divide by 8 */ >+ } >+ else { >+ return RTEMS_INVALID_NUMBER; >+ } >+ >+ /* >+ * 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. >+ */ >+ pll_m = srcclk; /* divide by the oscilator speed in MHz */ >+ pll_n <<= 1; /* multiply by requested clock x2 */ >+ >+ /* pll_q is a prescaler from VCO for the USB OTG FS, SDIO and RNG, >+ * should result in the 48MHz for the USB >+ */ >+ pll_q = ((long)(srcclk * pll_n + srcclk * pll_n / 2)) / pll_m / 48; >+ >+ if (pll_q < 2) >+ { >+ pll_q = 2; >+ } >+ Pull the { up. >+ /* APB1 prescaler, APB1 clock must be < 42MHz */ >+ apbpre1 = (sysclk * 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 = (sysclk * 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; >+ } >+ I thought RTEMS style had } else and } else if. Is that right? If so adjust style. >+ rtems_interrupt_disable(level); >+ >+ rcc->cr |= RCC_CR_HSION; /* turn on HSI */ >+ timeout = timeoutset; >+ while ((! (rcc->cr & RCC_CR_HSIRDY) ) && timeout--); >+ >+ if (timeout == 0) while(1); >+ >+ /* all prescalers to 0, clock source to HSI */ >+ rcc->cfgr &= 0x00000300; >+ rcc->cfgr |= RCC_CFGR_SW_HSI; >+ >+ timeout = timeoutset; >+ while ( ( (rcc->cfgr & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_HSI ) && >--timeout ); >+ >+ if (timeout == 0) while(1); >+ >+ /* turn off PLL */ >+ rcc->cr &= ~ (RCC_CR_PLLON | RCC_CR_PLLRDY); >+ >+ if (hseflag) { >+ rcc->cr |= RCC_CR_HSEON; >+ timeout = timeoutset; >+ while ((! (rcc->cr & RCC_CR_HSERDY) ) && timeout--); >+ } >+ >+ rcc->pllcfgr &= 0xF0BC8000; /* clear PLL prescalers */ >+ >+ /* set pll parameters */ >+ rcc->pllcfgr |=(pll_m << RCC_PLLCFGR_PLLM) // input divider >+ | (pll_n << RCC_PLLCFGR_PLLN) // multiplier >+ | (pll_p << RCC_PLLCFGR_PLLP) // output divider from >table >+ // HSE v HSI >+ | (hseflag ? RCC_PLLCFGR_PLLSRC_HSE : >RCC_PLLCFGR_PLLSRC_HSI) >+ | (pll_q << RCC_PLLCFGR_PLLQ); // PLLQ >+ >+ /* set prescalers for the internal busses */ >+ rcc->cfgr |= apbpre1 >+ | apbpre2 >+ | ahbpre; >+ >+ /* set flash parameters, hard coded for now for fast system clocks >*/ >+ flash->acr |= 5 // latency >+ | (1 << 9) // instruction cache >+ | (1 << 10);// data cache >+ >+ /* turn on PLL */ >+ rcc->cr |= RCC_CR_PLLON; >+ timeout = timeoutset; >+ while ( (! (rcc->cr & RCC_CR_PLLRDY) ) && --timeout ); >+ >+ if (timeout == 0) while(1); >+ >+ /* clock source to PLL */ >+ rcc->cfgr = (rcc->cfgr & ~RCC_CFGR_SW_MASK) | RCC_CFGR_SW_PLL; >+ timeout = timeoutset; >+ while ( ((rcc->cfgr & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL) && >--timeout ); >+ //if (timeout == 0) while(1); >+ >+ rtems_interrupt_enable(level); >+ >+ return RTEMS_SUCCESSFUL; >+} >+ > > void bsp_start(void) > { >+ init_main_osc(); >+ > stm32f4_gpio_set_config_array(&stm32f4_start_config_gpio [0]); > > bsp_interrupt_initialize(); >-- >2.1.0 > >_______________________________________________ >devel mailing list >devel@rtems.org >http://lists.rtems.org/mailman/listinfo/devel _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel