[PATCH] bsp:stm32f4XXXX system clock configuration

Tomasz Gregorek tomasz.gregorek at gmail.com
Sun Sep 21 16:13:30 UTC 2014


There are not only styles to be corrected. I will send a new version soon.

2014-09-20 20:41 GMT+02:00 Joel Sherrill <joel.sherrill at oarcorp.com>:

> 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.gregorek at gmail.com" <
> tomasz.gregorek at gmail.com> wrote:
> >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 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.gregorek at 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 at rtems.org
> >http://lists.rtems.org/mailman/listinfo/devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20140921/a31e4538/attachment-0002.html>


More information about the devel mailing list