1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #7158 from OTAkeys/pr/stmclk_f4

cpu/stm32f4: implement stmclk interface for stm32f4
This commit is contained in:
Alexandre Abadie 2017-06-15 11:23:24 +02:00 committed by GitHub
commit 9dadb9cbaf
19 changed files with 71571 additions and 30761 deletions

View File

@ -31,23 +31,22 @@ extern "C" {
* @name Clock system configuration
* @{
*/
#define CLOCK_HSE (16000000U) /* external oscillator */
#define CLOCK_CORECLOCK (168000000U) /* desired core clock frequency */
/* the actual PLL values are automatically generated */
#define CLOCK_PLL_M (CLOCK_HSE / 1000000)
#define CLOCK_PLL_N ((CLOCK_CORECLOCK / 1000000) * 2)
#define CLOCK_PLL_P (2U)
#define CLOCK_PLL_Q (CLOCK_PLL_N / 48)
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV2
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV4
#define CLOCK_FLASH_LATENCY FLASH_ACR_LATENCY_5WS
/* bus clocks for simplified peripheral initialization, UPDATE MANUALLY! */
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (16000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (0)
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 168MHz */
#define CLOCK_CORECLOCK (168000000U)
/* peripheral clock setup */
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1 /* min 25MHz */
#define CLOCK_AHB (CLOCK_CORECLOCK / 1)
#define CLOCK_APB2 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV4 /* max 42MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 4)
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV2 /* max 84MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 2)
/** @} */
/**

View File

@ -29,23 +29,22 @@ extern "C" {
* @name Clock system configuration
* @{
*/
#define CLOCK_HSE (16000000U) /* external oscillator */
#define CLOCK_CORECLOCK (168000000U) /* desired core clock frequency */
/* the actual PLL values are automatically generated */
#define CLOCK_PLL_M (CLOCK_HSE / 1000000)
#define CLOCK_PLL_N ((CLOCK_CORECLOCK / 1000000) * 2)
#define CLOCK_PLL_P (2U)
#define CLOCK_PLL_Q (CLOCK_PLL_N / 48)
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV2
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV4
#define CLOCK_FLASH_LATENCY FLASH_ACR_LATENCY_5WS
/* bus clocks for simplified peripheral initialization, UPDATE MANUALLY! */
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (16000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (0)
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 168MHz */
#define CLOCK_CORECLOCK (168000000U)
/* peripheral clock setup */
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1 /* min 25MHz */
#define CLOCK_AHB (CLOCK_CORECLOCK / 1)
#define CLOCK_APB2 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV4 /* max 42MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 4)
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV2 /* max 84MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 2)
/** @} */
/**

View File

@ -26,25 +26,26 @@ extern "C" {
#endif
/**
* @name Clock system configuration
* @name Clock system configuration
* @{
*/
#define CLOCK_HSE (8000000U) /* external oscillator */
#define CLOCK_CORECLOCK (84000000U) /* desired core clock frequency */
/* the actual PLL values are automatically generated */
#define CLOCK_PLL_M (CLOCK_HSE / 1000000)
#define CLOCK_PLL_N ((CLOCK_CORECLOCK / 1000000) * 2)
#define CLOCK_PLL_P (2U)
#define CLOCK_PLL_Q (CLOCK_PLL_N / 48)
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV2
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1
#define CLOCK_FLASH_LATENCY FLASH_ACR_LATENCY_5WS
/* bus clocks for simplified peripheral initialization, UPDATE MANUALLY! */
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (8000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (1)
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 84MHz */
#define CLOCK_CORECLOCK (84000000U)
/* PLL Output divisor */
#define P (4U)
/* peripheral clock setup */
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1 /* min 25MHz */
#define CLOCK_AHB (CLOCK_CORECLOCK / 1)
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV2 /* max 42MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1 /* max 84MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 1)
/** @} */

View File

@ -26,25 +26,24 @@ extern "C" {
#endif
/**
* @name Clock system configuration
* @name Clock system configuration
* @{
*/
#define CLOCK_HSE (8000000U) /* external oscillator */
#define CLOCK_CORECLOCK (100000000U) /* desired core clock frequency */
/* the actual PLL values are automatically generated */
#define CLOCK_PLL_M (CLOCK_HSE / 1000000)
#define CLOCK_PLL_N ((CLOCK_CORECLOCK / 1000000) * 2)
#define CLOCK_PLL_P (2U)
#define CLOCK_PLL_Q (CLOCK_PLL_N / 48)
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV2
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1
#define CLOCK_FLASH_LATENCY FLASH_ACR_LATENCY_5WS
/* bus clocks for simplified peripheral initialization, UPDATE MANUALLY! */
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (8000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (1)
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 100MHz */
#define CLOCK_CORECLOCK (96000000U)
/* peripheral clock setup */
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1 /* min 25MHz */
#define CLOCK_AHB (CLOCK_CORECLOCK / 1)
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV2 /* max 50MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1 /* max 100MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 1)
/** @} */

View File

@ -29,22 +29,21 @@ extern "C" {
* @name Clock system configuration
* @{
*/
#define CLOCK_HSE (8000000U) /* external oscillator */
#define CLOCK_CORECLOCK (100000000U) /* desired core clock frequency */
/* the actual PLL values are automatically generated */
#define CLOCK_PLL_M (CLOCK_HSE / 1000000)
#define CLOCK_PLL_N ((CLOCK_CORECLOCK / 1000000) * 2)
#define CLOCK_PLL_P (2U)
#define CLOCK_PLL_Q (CLOCK_PLL_N / 48)
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV2
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1
#define CLOCK_FLASH_LATENCY FLASH_ACR_LATENCY_5WS
/* bus clocks for simplified peripheral initialization, UPDATE MANUALLY! */
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (8000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (1)
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 100MHz */
#define CLOCK_CORECLOCK (96000000U)
/* peripheral clock setup */
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1 /* min 25MHz */
#define CLOCK_AHB (CLOCK_CORECLOCK / 1)
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV2 /* max 50MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1 /* max 100MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 1)
/** @} */

View File

@ -26,26 +26,25 @@ extern "C" {
#endif
/**
* @name Clock system configuration
* @name Clock system configuration
* @{
*/
#define CLOCK_HSE (8000000U) /* external oscillator */
#define CLOCK_CORECLOCK (180000000U) /* desired core clock frequency */
/* the actual PLL values are automatically generated */
#define CLOCK_PLL_M (CLOCK_HSE / 1000000)
#define CLOCK_PLL_N ((CLOCK_CORECLOCK / 1000000) * 2)
#define CLOCK_PLL_P (2U)
#define CLOCK_PLL_Q (CLOCK_PLL_N / 48)
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV2
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1
#define CLOCK_FLASH_LATENCY FLASH_ACR_LATENCY_5WS
/* bus clocks for simplified peripheral initialization, UPDATE MANUALLY! */
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (8000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (1)
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 180MHz */
#define CLOCK_CORECLOCK (168000000U)
/* peripheral clock setup */
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1 /* min 25MHz */
#define CLOCK_AHB (CLOCK_CORECLOCK / 1)
#define CLOCK_APB1 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB2 (CLOCK_CORECLOCK / 1)
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV4 /* max 45MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 4)
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV2 /* max 90MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 2)
/** @} */
/**

View File

@ -31,22 +31,21 @@ extern "C" {
* @name Clock system configuration
* @{
*/
#define CLOCK_HSE (8000000U) /* external oscillator */
#define CLOCK_CORECLOCK (100000000U) /* desired core clock frequency */
/* the actual PLL values are automatically generated */
#define CLOCK_PLL_M (CLOCK_HSE / 1000000)
#define CLOCK_PLL_N ((CLOCK_CORECLOCK / 1000000) * 2)
#define CLOCK_PLL_P (2U)
#define CLOCK_PLL_Q (CLOCK_PLL_N / 48)
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV2
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1
#define CLOCK_FLASH_LATENCY FLASH_ACR_LATENCY_5WS
/* bus clocks for simplified peripheral initialization, UPDATE MANUALLY! */
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (8000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (1)
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 100MHz */
#define CLOCK_CORECLOCK (96000000U)
/* peripheral clock setup */
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1 /* min 25MHz */
#define CLOCK_AHB (CLOCK_CORECLOCK / 1)
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV2 /* max 50MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1 /* max 100MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 1)
/** @} */

View File

@ -29,22 +29,21 @@ extern "C" {
* @name Clock system configuration
* @{
*/
#define CLOCK_HSE (8000000U) /* external oscillator */
#define CLOCK_CORECLOCK (180000000U) /* desired core clock frequency */
/* the actual PLL values are automatically generated */
#define CLOCK_PLL_M (CLOCK_HSE / 1000000)
#define CLOCK_PLL_N ((CLOCK_CORECLOCK / 1000000) * 2)
#define CLOCK_PLL_P (2U)
#define CLOCK_PLL_Q (CLOCK_PLL_N / 48)
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV4
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV2
#define CLOCK_FLASH_LATENCY FLASH_ACR_LATENCY_5WS
/* bus clocks for simplified peripheral initialization, UPDATE MANUALLY! */
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (8000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (1)
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 180MHz */
#define CLOCK_CORECLOCK (168000000U)
/* peripheral clock setup */
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1 /* min 25MHz */
#define CLOCK_AHB (CLOCK_CORECLOCK / 1)
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV4 /* max 45MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 4)
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV2 /* max 90MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 2)
/** @} */

View File

@ -29,23 +29,22 @@ extern "C" {
* @name Clock system configuration
* @{
*/
#define CLOCK_HSE (8000000U) /* external oscillator */
#define CLOCK_CORECLOCK (180000000U) /* desired core clock frequency */
/* the actual PLL values are automatically generated */
#define CLOCK_PLL_M (CLOCK_HSE / 1000000)
#define CLOCK_PLL_N ((CLOCK_CORECLOCK / 1000000) * 2)
#define CLOCK_PLL_P (2U)
#define CLOCK_PLL_Q (CLOCK_PLL_N / 48)
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV2
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1
#define CLOCK_FLASH_LATENCY FLASH_ACR_LATENCY_5WS
/* bus clocks for simplified peripheral initialization, UPDATE MANUALLY! */
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (8000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (1)
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 100MHz */
#define CLOCK_CORECLOCK (168000000U)
/* peripheral clock setup */
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1 /* min 25MHz */
#define CLOCK_AHB (CLOCK_CORECLOCK / 1)
#define CLOCK_APB1 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB2 (CLOCK_CORECLOCK / 1)
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV4 /* max 45MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 4)
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV2 /* max 90MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 2)
/** @} */
/**

View File

@ -27,26 +27,25 @@ extern "C" {
#endif
/**
* @name Clock system configuration
* @name Clock system configuration
* @{
*/
#define CLOCK_HSE (8000000U) /* external oscillator */
#define CLOCK_CORECLOCK (168000000U) /* desired core clock frequency */
/* the actual PLL values are automatically generated */
#define CLOCK_PLL_M (CLOCK_HSE / 1000000)
#define CLOCK_PLL_N ((CLOCK_CORECLOCK / 1000000) * 2)
#define CLOCK_PLL_P (2U)
#define CLOCK_PLL_Q (CLOCK_PLL_N / 48)
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV2
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV4
#define CLOCK_FLASH_LATENCY FLASH_ACR_LATENCY_5WS
/* bus clocks for simplified peripheral initialization, UPDATE MANUALLY! */
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (8000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (1)
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 168MHz */
#define CLOCK_CORECLOCK (168000000U)
/* peripheral clock setup */
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1 /* min 25MHz */
#define CLOCK_AHB (CLOCK_CORECLOCK / 1)
#define CLOCK_APB2 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV4 /* max 42MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 4)
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV2 /* max 84MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 2)
/** @} */
/**

View File

@ -20,28 +20,9 @@
#include <stdint.h>
#include "cpu.h"
#include "periph_conf.h"
#include "stmclk.h"
#include "periph/init.h"
/* Check the source to be used for the PLL */
#if defined(CLOCK_HSI) && defined(CLOCK_HSE)
#error "Only provide one of two CLOCK_HSI/CLOCK_HSE"
#elif CLOCK_HSI
#define CLOCK_CR_SOURCE RCC_CR_HSION
#define CLOCK_CR_SOURCE_RDY RCC_CR_HSIRDY
#define CLOCK_PLL_SOURCE RCC_PLLCFGR_PLLSRC_HSI
#define CLOCK_DISABLE_HSI 0
#elif CLOCK_HSE
#define CLOCK_CR_SOURCE RCC_CR_HSEON
#define CLOCK_CR_SOURCE_RDY RCC_CR_HSERDY
#define CLOCK_PLL_SOURCE RCC_PLLCFGR_PLLSRC_HSE
#define CLOCK_DISABLE_HSI 1
#else
#error "Please provide CLOCK_HSI or CLOCK_HSE in boards/NAME/includes/perhip_cpu.h"
#endif
static void cpu_clock_init(void);
/**
* @brief Initialize the CPU, set IRQ priorities
*/
@ -50,110 +31,7 @@ void cpu_init(void)
/* initialize the Cortex-M core */
cortexm_init();
/* initialize the clock system */
cpu_clock_init();
stmclk_init_sysclk();
/* trigger static peripheral initialization */
periph_init();
}
/**
* @brief Configure the controllers clock system
*
* The clock initialization make the following assumptions:
* - the external HSE clock from an external oscillator is used as base clock
* - the internal PLL circuit is used for clock refinement
*
* Use the following formulas to calculate the needed values:
*
* SYSCLK = ((XTAL_SPEED / CLOCK_PLL_M) * CLOCK_PLL_N) / CLOCK_PLL_P
* USB, SDIO and RNG Clock = ((XTAL_SPEED / CLOCK_PLL_M) * CLOCK_PLL_N) / CLOCK_PLL_Q
*
* The actual used values are specified in the board's `periph_conf.h` file.
*
* NOTE: currently there is not timeout for initialization of PLL and other locks
* -> when wrong values are chosen, the initialization could stall
*/
static void cpu_clock_init(void)
{
/* reset clock configuration register */
RCC->CFGR = 0;
/* disable HSE, CSS and PLL */
RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_CSSON | RCC_CR_PLLON);
/* disable all clock interrupts */
RCC->CIR = 0;
/* enable the high speed clock */
RCC->CR |= CLOCK_CR_SOURCE;
/* wait for the high speed clock source to be ready */
while (!(RCC->CR & CLOCK_CR_SOURCE_RDY)) {}
/* setup power module */
/* enable the power module */
periph_clk_en(APB1, RCC_APB1ENR_PWREN);
/* set the voltage scaling to 1 to enable the maximum frequency */
PWR->CR |= PWR_CR_VOS_1;
/* setup the peripheral bus prescalers */
/* set the AHB clock divider */
RCC->CFGR &= ~RCC_CFGR_HPRE;
RCC->CFGR |= CLOCK_AHB_DIV;
/* set the APB2 (high speed) bus clock divider */
RCC->CFGR &= ~RCC_CFGR_PPRE2;
RCC->CFGR |= CLOCK_APB2_DIV;
/* set the APB1 (low speed) bus clock divider */
RCC->CFGR &= ~RCC_CFGR_PPRE1;
RCC->CFGR |= CLOCK_APB1_DIV;
/* configure the PLL */
/* reset PLL config register */
RCC->PLLCFGR = 0;
/* set high speed clock as source for the PLL */
RCC->PLLCFGR |= CLOCK_PLL_SOURCE;
/* set division factor for main PLL input clock */
RCC->PLLCFGR |= (CLOCK_PLL_M & 0x3F);
/* set main PLL multiplication factor for VCO */
RCC->PLLCFGR |= (CLOCK_PLL_N & 0x1FF) << 6;
/* set main PLL division factor for main system clock */
RCC->PLLCFGR |= (((CLOCK_PLL_P & 0x03) >> 1) - 1) << 16;
/* set main PLL division factor for USB OTG FS, SDIO and RNG clocks */
RCC->PLLCFGR |= (CLOCK_PLL_Q & 0x0F) << 24;
/* enable PLL again */
RCC->CR |= RCC_CR_PLLON;
/* wait until PLL is stable */
while(!(RCC->CR & RCC_CR_PLLRDY)) {}
/* configure flash latency */
/* reset flash access control register */
FLASH->ACR = 0;
/* enable instruction cache */
FLASH->ACR |= FLASH_ACR_ICEN;
/* enable data cache */
FLASH->ACR |= FLASH_ACR_DCEN;
/* enable pre-fetch buffer */
// FLASH->ACR |= FLASH_ACR_PRFTEN;
/* set flash latency */
FLASH->ACR &= ~FLASH_ACR_LATENCY;
FLASH->ACR |= CLOCK_FLASH_LATENCY;
/* configure the sysclock and the peripheral clocks */
/* set sysclock to be driven by the PLL clock */
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* wait for sysclock to be stable */
while (!(RCC->CFGR & RCC_CFGR_SWS_PLL)) {}
#if CLOCK_DISABLE_HSI
/* disable the HSI if we use the HSE */
RCC->CR &= ~(RCC_CR_HSION);
while (RCC->CR & RCC_CR_HSIRDY) {}
#endif
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

177
cpu/stm32f4/stmclk.c Normal file
View File

@ -0,0 +1,177 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
* 2017 OTA keys S.A.
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_stm32f4
* @{
*
* @file
* @brief Implementation of STM32 clock configuration
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Vincent Dupont <vincent@otakeys.com>
* @}
*/
#include "cpu.h"
#include "stmclk.h"
#include "periph_conf.h"
/* make sure we have all needed information about the clock configuration */
#ifndef CLOCK_HSE
#error "Please provide CLOCK_HSE in your board's perhip_conf.h"
#endif
#ifndef CLOCK_LSE
#error "Please provide CLOCK_LSE in your board's periph_conf.h"
#endif
/**
* @name PLL configuration
* @{
*/
/* figure out which input to use */
#if (CLOCK_HSE)
#define PLL_IN CLOCK_HSE
#define PLL_SRC RCC_PLLCFGR_PLLSRC_HSE
#else
#define PLL_IN (16000000U) /* HSI fixed @ 16MHz */
#define PLL_SRC RCC_PLLCFGR_PLLSRC_HSI
#endif
#ifndef P
/* we fix P to 2 (so the PLL output equals 2 * CLOCK_CORECLOCK) */
#define P (2U)
#if ((P != 2) && (P != 4) && (P != 6) && (P != 8))
#error "PLL configuration: PLL P value is invalid"
#endif
#endif /* P */
/* the recommended input clock for the PLL should be 2MHz */
#define M (PLL_IN / 2000000U)
#if ((M < 2) || (M > 63))
#error "PLL configuration: PLL M value is out of range"
#endif
/* next we multiply the input freq to 2 * CORECLOCK */
#define N (P * CLOCK_CORECLOCK / 2000000U)
#if ((N < 50) || (N > 432))
#error "PLL configuration: PLL N value is out of range"
#endif
/* finally we need to set Q, so that the USB clock is 48MHz */
#define Q ((P * CLOCK_CORECLOCK) / 48000000U)
#if ((Q * 48000000U) != (P * CLOCK_CORECLOCK))
#error "PLL configuration: USB frequency is not 48MHz"
#endif
/* now we get the actual bitfields */
#define PLL_P (((P / 2) - 1) << RCC_PLLCFGR_PLLP_Pos)
#define PLL_M (M << RCC_PLLCFGR_PLLM_Pos)
#define PLL_N (N << RCC_PLLCFGR_PLLN_Pos)
#define PLL_Q (Q << RCC_PLLCFGR_PLLQ_Pos)
/** @} */
/**
* @name Deduct the needed flash wait states from the core clock frequency
* @{
*/
#define FLASH_WAITSTATES (CLOCK_CORECLOCK / 30000000U)
/** @} */
void stmclk_init_sysclk(void)
{
/* disable any interrupts. Global interrupts could be enabled if this is
* called from some kind of bootloader... */
unsigned is = irq_disable();
RCC->CIR = 0;
/* enable HSI clock for the duration of initialization */
stmclk_enable_hsi();
/* use HSI as system clock while we do any further configuration and
* configure the AHB and APB clock dividers as configure by the board */
RCC->CFGR = (RCC_CFGR_SW_HSI | CLOCK_AHB_DIV |
CLOCK_APB1_DIV | CLOCK_APB2_DIV);
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_HSI) {}
/* we enable I+D cashes, pre-fetch, and we set the actual number of
* needed flash wait states */
FLASH->ACR = (FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN | FLASH_WAITSTATES);
/* disable all active clocks except HSI -> resets the clk configuration */
RCC->CR = (RCC_CR_HSION | RCC_CR_HSITRIM_4);
/* if configured, we need to enable the HSE clock now */
#if (CLOCK_HSE)
RCC->CR |= (RCC_CR_HSEON);
while (!(RCC->CR & RCC_CR_HSERDY)) {}
#endif
/* now we can safely configure and start the PLL */
RCC->PLLCFGR = (PLL_SRC | PLL_M | PLL_N | PLL_P | PLL_Q);
RCC->CR |= (RCC_CR_PLLON);
while (!(RCC->CR & RCC_CR_PLLRDY)) {}
/* now that the PLL is running, we use it as system clock */
RCC->CFGR |= (RCC_CFGR_SW_PLL);
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL) {}
stmclk_disable_hsi();
irq_restore(is);
}
void stmclk_enable_hsi(void)
{
RCC->CR |= (RCC_CR_HSION);
while (!(RCC->CR & RCC_CR_HSIRDY)) {}
}
void stmclk_disable_hsi(void)
{
if ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_HSI) {
RCC->CR &= ~(RCC_CR_HSION);
}
}
void stmclk_enable_lfclk(void)
{
/* configure the low speed clock domain (LSE vs LSI) */
#if CLOCK_LSE
/* allow write access to backup domain */
stmclk_bdp_unlock();
/* enable LSE */
RCC->BDCR |= RCC_BDCR_LSEON;
while (!(RCC->BDCR & RCC_BDCR_LSERDY)) {}
/* disable write access to back domain when done */
stmclk_bdp_lock();
#else
RCC->CSR |= RCC_CSR_LSION;
while (!(RCC->CSR & RCC_CSR_LSIRDY)) {}
#endif
}
void stmclk_disable_lfclk(void)
{
#if CLOCK_LSE
stmclk_bdp_unlock();
RCC->BDCR &= ~(RCC_BDCR_LSEON);
stmclk_bdp_lock();
#else
RCC->CSR &= ~(RCC_CSR_LSION);
#endif
}
void stmclk_bdp_unlock(void)
{
periph_clk_en(APB1, RCC_APB1ENR_PWREN);
PWR->CR |= PWR_CR_DBP;
}
void stmclk_bdp_lock(void)
{
PWR->CR &= ~(PWR_CR_DBP);
periph_clk_dis(APB1, RCC_APB1ENR_PWREN);
}