Skip to content

Commit

Permalink
kinetis: Unify cpu.c, update clocking initialization
Browse files Browse the repository at this point in the history
Unify cpu_init for all Kinetis CPUs to reduce code duplication.
Updated the MCG driver implementation to make the configuration easier.
Most clock settings are initialized by kinetis_mcg_init() called from
cpu_init. Board specific external clock source initialization
(FRDM-K64F, PhyNode) needs to be performed in board_init instead of
in cpu_init.
  • Loading branch information
Joakim Nohlgård committed Aug 1, 2017
1 parent aa67bdb commit 98bb2ce
Show file tree
Hide file tree
Showing 18 changed files with 626 additions and 692 deletions.
28 changes: 0 additions & 28 deletions boards/frdm-k22f/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,8 @@
#include "mcg.h"
#include "periph/gpio.h"

#define SIM_CLKDIV1_48MHZ (SIM_CLKDIV1_OUTDIV1(0) | \
SIM_CLKDIV1_OUTDIV2(1) | \
SIM_CLKDIV1_OUTDIV3(1) | \
SIM_CLKDIV1_OUTDIV4(1))

static void cpu_clock_init(void);

void board_init(void)
{
/* initialize the clock system */
cpu_clock_init();
/* initialize the CPU core */
cpu_init();

Expand All @@ -47,22 +38,3 @@ void board_init(void)
gpio_set(LED1_PIN);
gpio_set(LED2_PIN);
}

/**
* @brief Configure the controllers clock system
*
* | Clock name | Run mode frequency (max) | VLPR mode frequency (max) |
*
* | Core | 120 MHz | 4 MHz |
* | System | 120 MHz | 4 MHz |
* | Bus | 60 MHz | 4 MHz |
* | FlexBus | 30 MHz | 800 kHz |
* | Flash | 26.67 MHz | 4 MHz |
*/
static void cpu_clock_init(void)
{
/* setup system prescalers */
SIM->CLKDIV1 = (uint32_t)SIM_CLKDIV1_48MHZ;

kinetis_mcg_set_mode(KINETIS_MCG_PEE);
}
63 changes: 38 additions & 25 deletions boards/frdm-k22f/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,33 @@ extern "C"
* @name Clock system configuration
* @{
*/
#define KINETIS_CPU_USE_MCG 1
#define KINETIS_MCG_USE_ERC 1
#define KINETIS_MCG_USE_PLL 1
/* The crystal connected to OSC0 is 8 MHz */
#define KINETIS_MCG_DCO_RANGE (48000000u)
#define KINETIS_MCG_ERC_OSCILLATOR 1
#define KINETIS_MCG_ERC_FRDIV 3 /* ERC divider = 256 */
#define KINETIS_MCG_ERC_RANGE 1
#define KINETIS_MCG_ERC_FREQ (40000000u)
#define KINETIS_MCG_PLL_PRDIV 3 /* divide factor = 4 */
#define KINETIS_MCG_PLL_VDIV0 0 /* multiply factor = 24 */
#define KINETIS_MCG_PLL_FREQ (48000000u)

#define CLOCK_CORECLOCK KINETIS_MCG_PLL_FREQ
static const clock_config_t clock_config = {
/*
* This configuration results in the system running from the FLL output with
* the following clock frequencies:
* Core: 60 MHz
* Bus: 30 MHz
* Flex: 20 MHz
* Flash: 20 MHz
*/
.clkdiv1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) |
SIM_CLKDIV1_OUTDIV3(2) | SIM_CLKDIV1_OUTDIV4(2),
.default_mode = KINETIS_MCG_MODE_FEE,
/* The crystal connected to OSC0 is 8 MHz */
.erc_range = KINETIS_MCG_ERC_RANGE_HIGH,
.fcrdiv = 0, /* Fast IRC divide by 1 => 4 MHz */
.oscsel = 0, /* Use OSC0 for external clock */
.clc = 0, /* External load caps on the FRDM-K22F board */
.fll_frdiv = 0b011, /* Divide by 256 */
.fll_factor_fei = KINETIS_MCG_FLL_FACTOR_1464, /* FLL freq = 48 MHz */
.fll_factor_fee = KINETIS_MCG_FLL_FACTOR_1920, /* FLL freq = 60 MHz */
.pll_prdiv = 0b00011, /* Divide by 4 */
.pll_vdiv = 0b00110, /* Multiply by 30 => PLL freq = 60 MHz */
.enable_oscillator = true,
.select_fast_irc = true,
.enable_mcgirclk = false,
};
#define CLOCK_CORECLOCK (60000000ul)
#define CLOCK_BUSCLOCK (CLOCK_CORECLOCK / 2)
/** @} */

Expand Down Expand Up @@ -211,20 +224,20 @@ static const spi_conf_t spi_config[] = {
* @{
*/
#define I2C_NUMOF (1U)
#define I2C_CLK CLOCK_CORECLOCK
#define I2C_CLK CLOCK_BUSCLOCK
#define I2C_0_EN 1
#define I2C_IRQ_PRIO 1
/* Low (10 kHz): MUL = 4, SCL divider = 1280, total: 5120 */
#define KINETIS_I2C_F_ICR_LOW (0x35)
#define KINETIS_I2C_F_MULT_LOW (2)
/* Normal (100 kHz): MUL = 2, SCL divider = 240, total: 480 */
#define KINETIS_I2C_F_ICR_NORMAL (0x1F)
/* Low (10 kHz): MUL = 2, SCL divider = 1536, total: 3072 */
#define KINETIS_I2C_F_ICR_LOW (0x36)
#define KINETIS_I2C_F_MULT_LOW (1)
/* Normal (100 kHz): MUL = 2, SCL divider = 160, total: 320 */
#define KINETIS_I2C_F_ICR_NORMAL (0x1D)
#define KINETIS_I2C_F_MULT_NORMAL (1)
/* Fast (400 kHz): MUL = 1, SCL divider = 128, total: 128 */
#define KINETIS_I2C_F_ICR_FAST (0x17)
/* Fast (400 kHz): MUL = 1, SCL divider = 80, total: 80 */
#define KINETIS_I2C_F_ICR_FAST (0x14)
#define KINETIS_I2C_F_MULT_FAST (0)
/* Fast plus (1000 kHz): MUL = 1, SCL divider = 48, total: 48 */
#define KINETIS_I2C_F_ICR_FAST_PLUS (0x10)
/* Fast plus (1000 kHz): MUL = 1, SCL divider = 30, total: 30 */
#define KINETIS_I2C_F_ICR_FAST_PLUS (0x05)
#define KINETIS_I2C_F_MULT_FAST_PLUS (0)

/* I2C 0 device configuration */
Expand All @@ -235,7 +248,7 @@ static const spi_conf_t spi_config[] = {
#define I2C_0_IRQ_HANDLER isr_i2c0
/* I2C 0 pin configuration */
#define I2C_0_PORT PORTB
#define I2C_0_PORT_CLKEN() (SIM->SCGC5 |= (SIM_SCGC5_PORTE_MASK))
#define I2C_0_PORT_CLKEN() (SIM->SCGC5 |= (SIM_SCGC5_PORTB_MASK))
#define I2C_0_PIN_AF 2
#define I2C_0_SDA_PIN 3
#define I2C_0_SCL_PIN 2
Expand Down
4 changes: 4 additions & 0 deletions boards/frdm-k64f/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@

void board_init(void)
{
/* RMII RXCLK pin configuration */
SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK;
PORTA->PCR[18] &= ~(PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07));

/* initialize the CPU core */
cpu_init();

Expand Down
61 changes: 37 additions & 24 deletions boards/frdm-k64f/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,34 @@ extern "C"
* @name Clock system configuration
* @{
*/
#define KINETIS_CPU_USE_MCG 1

#define KINETIS_MCG_USE_ERC 1
#define KINETIS_MCG_USE_PLL 1
#define KINETIS_MCG_DCO_RANGE (24000000U)
#define KINETIS_MCG_ERC_OSCILLATOR 0
#define KINETIS_MCG_ERC_FRDIV 6 /* ERC devider = 1280 */
#define KINETIS_MCG_ERC_RANGE 2
#define KINETIS_MCG_ERC_FREQ 50000000
#define KINETIS_MCG_PLL_PRDIV 19 /* divide factor = 20 */
#define KINETIS_MCG_PLL_VDIV0 0 /* multiply factor = 24 */
#define KINETIS_MCG_PLL_FREQ 60000000

#define CLOCK_CORECLOCK KINETIS_MCG_PLL_FREQ
#define CLOCK_BUSCLOCK (CLOCK_CORECLOCK / 2)
static const clock_config_t clock_config = {
/*
* This configuration results in the system running from the PLL output with
* the following clock frequencies:
* Core: 60 MHz
* Bus: 60 MHz
* Flex: 20 MHz
* Flash: 20 MHz
*/
.clkdiv1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) |
SIM_CLKDIV1_OUTDIV3(2) | SIM_CLKDIV1_OUTDIV4(2),
.default_mode = KINETIS_MCG_MODE_PEE,
/* The board has an external RMII (Ethernet) clock which drives the ERC at 50 MHz */
.erc_range = KINETIS_MCG_ERC_RANGE_VERY_HIGH,
.fcrdiv = 0, /* Fast IRC divide by 1 => 4 MHz */
.oscsel = 0, /* Use EXTAL for external clock */
.clc = 0, /* External load caps on board */
.fll_frdiv = 0b111, /* Divide by 1536 => FLL input 32252 Hz */
.fll_factor_fei = KINETIS_MCG_FLL_FACTOR_1464, /* FLL freq = 48 MHz */
.fll_factor_fee = KINETIS_MCG_FLL_FACTOR_1920, /* FLL freq = 62.5 MHz */
.pll_prdiv = 0b10011, /* Divide by 20 */
.pll_vdiv = 0b00000, /* Multiply by 24 => PLL freq = 60 MHz */
.enable_oscillator = false, /* Use EXTAL directly without OSC0 */
.select_fast_irc = true,
.enable_mcgirclk = false,
};
#define CLOCK_CORECLOCK (60000000ul)
#define CLOCK_BUSCLOCK (CLOCK_CORECLOCK / 1)
/** @} */

/**
Expand Down Expand Up @@ -206,20 +219,20 @@ static const spi_conf_t spi_config[] = {
* @{
*/
#define I2C_NUMOF (1U)
#define I2C_CLK CLOCK_CORECLOCK
#define I2C_CLK CLOCK_BUSCLOCK
#define I2C_0_EN 1
#define I2C_IRQ_PRIO 1
/* Low (10 kHz): MUL = 4, SCL divider = 2560, total: 10240 */
#define KINETIS_I2C_F_ICR_LOW (0x3D)
/* Low (10 kHz): MUL = 4, SCL divider = 1536, total: 6144 */
#define KINETIS_I2C_F_ICR_LOW (0x36)
#define KINETIS_I2C_F_MULT_LOW (2)
/* Normal (100 kHz): MUL = 2, SCL divider = 240, total: 480 */
#define KINETIS_I2C_F_ICR_NORMAL (0x1F)
/* Normal (100 kHz): MUL = 2, SCL divider = 320, total: 640 */
#define KINETIS_I2C_F_ICR_NORMAL (0x25)
#define KINETIS_I2C_F_MULT_NORMAL (1)
/* Fast (400 kHz): MUL = 1, SCL divider = 128, total: 128 */
#define KINETIS_I2C_F_ICR_FAST (0x17)
/* Fast (400 kHz): MUL = 1, SCL divider = 160, total: 160 */
#define KINETIS_I2C_F_ICR_FAST (0x1D)
#define KINETIS_I2C_F_MULT_FAST (0)
/* Fast plus (1000 kHz): MUL = 1, SCL divider = 48, total: 48 */
#define KINETIS_I2C_F_ICR_FAST_PLUS (0x10)
/* Fast plus (1000 kHz): MUL = 1, SCL divider = 64, total: 64 */
#define KINETIS_I2C_F_ICR_FAST_PLUS (0x12)
#define KINETIS_I2C_F_MULT_FAST_PLUS (0)

/* I2C 0 device configuration */
Expand Down
51 changes: 3 additions & 48 deletions boards/mulle/board.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2015 Eistec AB
* Copyright (C) 2014-2017 Eistec AB
*
* 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
Expand Down Expand Up @@ -74,17 +74,6 @@ static devfs_t mulle_nor_devfs = {
/** @brief Initialize the GPIO pins controlling the power switches. */
static inline void power_pins_init(void);

/**
* @brief Set clock prescalers to safe values
*
* This should be done before switching to FLL/PLL as clock source to ensure
* that all clocks remain within the specified limits.
*/
static inline void set_safe_clock_dividers(void);

/** @brief Set the FLL source clock to RTC32k */
static inline void set_fll_source(void);

static void increase_boot_count(void);
static int mulle_nvram_init(void);

Expand Down Expand Up @@ -123,12 +112,8 @@ void board_init(void)
* for debug prints as well */
rtt_init();

/* Set up clocks */
set_safe_clock_dividers();

set_fll_source();

kinetis_mcg_set_mode(KINETIS_MCG_FEE);
/* Set 32 kHz clock source */
SIM->SOPT1 = (SIM->SOPT1 & ~(SIM_SOPT1_OSC32KSEL_MASK)) | SIM_SOPT1_OSC32KSEL(2);

/* At this point we need to wait for 1 ms until the clock is stable.
* Since the clock is not yet stable we can only guess how long we must
Expand Down Expand Up @@ -167,36 +152,6 @@ static inline void power_pins_init(void)
gpio_clear(MULLE_POWER_VSEC);
}

static inline void set_safe_clock_dividers(void)
{
/*
* We want to achieve the following clocks:
* Core/system: <100MHz
* Bus: <50MHz
* FlexBus: <50MHz
* Flash: <25MHz
*
* using dividers 1-2-2-4 will obey the above limits when using a 96MHz FLL source.
*/
SIM->CLKDIV1 = (
SIM_CLKDIV1_OUTDIV1(CONFIG_CLOCK_K60_SYS_DIV) | /* Core/System clock divider */
SIM_CLKDIV1_OUTDIV2(CONFIG_CLOCK_K60_BUS_DIV) | /* Bus clock divider */
SIM_CLKDIV1_OUTDIV3(CONFIG_CLOCK_K60_FB_DIV) | /* FlexBus divider, not used in Mulle */
SIM_CLKDIV1_OUTDIV4(CONFIG_CLOCK_K60_FLASH_DIV)); /* Flash clock divider */

}

static inline void set_fll_source(void)
{
/* Select FLL as source (as opposed to PLL) */
SIM->SOPT2 &= ~(SIM_SOPT2_PLLFLLSEL_MASK);
/* Use external 32kHz RTC clock as source for OSC32K */
SIM->SOPT1 = (SIM->SOPT1 & ~(SIM_SOPT1_OSC32KSEL_MASK)) | SIM_SOPT1_OSC32KSEL(2);

/* Select RTC 32kHz clock as reference clock for the FLL */
MCG->C7 = (MCG_C7_OSCSEL_MASK);
}

static int mulle_nvram_init(void)
{
union {
Expand Down
27 changes: 0 additions & 27 deletions boards/mulle/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,32 +176,5 @@ extern mtd_dev_t *mtd0;
#define MULLE_VBAT_ADC_LINE ADC_LINE(6)
#define MULLE_VCHR_ADC_LINE ADC_LINE(7)
/** @} */

/**
* @name K60 clock dividers
*/
/** @{ */
/**
* System clock divider setting, the actual hardware register value, see reference manual for details.
*/
#define CONFIG_CLOCK_K60_SYS_DIV 0x00

/**
* Bus clock divider setting, the actual hardware register value, see reference manual for details
*/
#define CONFIG_CLOCK_K60_BUS_DIV 0x01

/**
* Flexbus clock divider setting, the actual hardware register value, see reference manual for details
*/
#define CONFIG_CLOCK_K60_FB_DIV 0x01

/**
* Flash clock divider setting, the actual hardware register value, see reference manual for details
*/
#define CONFIG_CLOCK_K60_FLASH_DIV 0x03

/** @} */

#endif /* BOARD_H */
/** @} */
Loading

0 comments on commit 98bb2ce

Please sign in to comment.