Skip to content

Commit 689333f

Browse files
authored
Merge pull request RIOT-OS#8928 from gebart/pr/kinetis-clock-init
kinetis: Refactor clock initialization code
2 parents 07eb208 + c54f6b4 commit 689333f

File tree

11 files changed

+358
-159
lines changed

11 files changed

+358
-159
lines changed

boards/frdm-k22f/include/periph_conf.h

+13-9
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,24 @@ static const clock_config_t clock_config = {
4141
*/
4242
.clkdiv1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) |
4343
SIM_CLKDIV1_OUTDIV3(2) | SIM_CLKDIV1_OUTDIV4(2),
44+
.rtc_clc = 0, /* External load caps on the FRDM-K22F board */
45+
.osc32ksel = SIM_SOPT1_OSC32KSEL(2),
46+
.clock_flags =
47+
KINETIS_CLOCK_OSC0_EN |
48+
KINETIS_CLOCK_RTCOSC_EN |
49+
KINETIS_CLOCK_USE_FAST_IRC |
50+
0,
4451
.default_mode = KINETIS_MCG_MODE_FEE,
4552
/* The crystal connected to OSC0 is 8 MHz */
4653
.erc_range = KINETIS_MCG_ERC_RANGE_HIGH,
47-
.fcrdiv = 0, /* Fast IRC divide by 1 => 4 MHz */
48-
.oscsel = 0, /* Use OSC0 for external clock */
49-
.clc = 0, /* External load caps on the FRDM-K22F board */
50-
.fll_frdiv = 0b011, /* Divide by 256 */
54+
.osc_clc = 0, /* External load caps on the FRDM-K22F board */
55+
.oscsel = MCG_C7_OSCSEL(0), /* Use OSC0 for external clock */
56+
.fcrdiv = MCG_SC_FCRDIV(0), /* Fast IRC divide by 1 => 4 MHz */
57+
.fll_frdiv = MCG_C1_FRDIV(0b011), /* Divide by 256 */
5158
.fll_factor_fei = KINETIS_MCG_FLL_FACTOR_1464, /* FLL freq = 48 MHz */
5259
.fll_factor_fee = KINETIS_MCG_FLL_FACTOR_1920, /* FLL freq = 60 MHz */
53-
.pll_prdiv = 0b00011, /* Divide by 4 */
54-
.pll_vdiv = 0b00110, /* Multiply by 30 => PLL freq = 60 MHz */
55-
.enable_oscillator = true,
56-
.select_fast_irc = true,
57-
.enable_mcgirclk = false,
60+
.pll_prdiv = MCG_C5_PRDIV0(0b00011), /* Divide by 4 */
61+
.pll_vdiv = MCG_C6_VDIV0(0b00110), /* Multiply by 30 => PLL freq = 60 MHz */
5862
};
5963
#define CLOCK_CORECLOCK (60000000ul)
6064
#define CLOCK_BUSCLOCK (CLOCK_CORECLOCK / 2)

boards/frdm-k64f/include/periph_conf.h

+13-9
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,24 @@ static const clock_config_t clock_config = {
4242
*/
4343
.clkdiv1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) |
4444
SIM_CLKDIV1_OUTDIV3(2) | SIM_CLKDIV1_OUTDIV4(2),
45+
.rtc_clc = 0, /* External load caps on board */
46+
.osc32ksel = SIM_SOPT1_OSC32KSEL(2),
47+
.clock_flags =
48+
/* No OSC0_EN, use EXTAL directly without OSC0 */
49+
KINETIS_CLOCK_RTCOSC_EN |
50+
KINETIS_CLOCK_USE_FAST_IRC |
51+
0,
4552
.default_mode = KINETIS_MCG_MODE_PEE,
4653
/* The board has an external RMII (Ethernet) clock which drives the ERC at 50 MHz */
4754
.erc_range = KINETIS_MCG_ERC_RANGE_VERY_HIGH,
48-
.fcrdiv = 0, /* Fast IRC divide by 1 => 4 MHz */
49-
.oscsel = 0, /* Use EXTAL for external clock */
50-
.clc = 0, /* External load caps on board */
51-
.fll_frdiv = 0b111, /* Divide by 1536 => FLL input 32252 Hz */
55+
.osc_clc = 0, /* External load caps on board */
56+
.oscsel = MCG_C7_OSCSEL(0), /* Use EXTAL for external clock */
57+
.fcrdiv = MCG_SC_FCRDIV(0), /* Fast IRC divide by 1 => 4 MHz */
58+
.fll_frdiv = MCG_C1_FRDIV(0b111), /* Divide by 1536 => FLL input 32252 Hz */
5259
.fll_factor_fei = KINETIS_MCG_FLL_FACTOR_1464, /* FLL freq = 48 MHz */
5360
.fll_factor_fee = KINETIS_MCG_FLL_FACTOR_1920, /* FLL freq = 62.5 MHz */
54-
.pll_prdiv = 0b10011, /* Divide by 20 */
55-
.pll_vdiv = 0b00000, /* Multiply by 24 => PLL freq = 60 MHz */
56-
.enable_oscillator = false, /* Use EXTAL directly without OSC0 */
57-
.select_fast_irc = true,
58-
.enable_mcgirclk = false,
61+
.pll_prdiv = MCG_C5_PRDIV0(0b10011), /* Divide by 20 */
62+
.pll_vdiv = MCG_C6_VDIV0(0b00000), /* Multiply by 24 => PLL freq = 60 MHz */
5963
};
6064
#define CLOCK_CORECLOCK (60000000ul)
6165
#define CLOCK_BUSCLOCK (CLOCK_CORECLOCK / 1)

boards/frdm-kw41z/board.c

-6
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,12 @@
2020

2121
#include "board.h"
2222
#include "periph/gpio.h"
23-
#include "periph/rtt.h"
2423

2524
void board_init(void)
2625
{
2726
/* initialize the CPU core */
2827
cpu_init();
2928

30-
#if MODULE_XTIMER && !(KINETIS_XTIMER_SOURCE_PIT)
31-
/* Start the RTT, used as time base for xtimer when using LPTMR backend */
32-
rtt_init();
33-
#endif
34-
3529
/* initialize and turn off LEDs */
3630
gpio_init(LED0_PIN, GPIO_OUT);
3731
gpio_set(LED0_PIN);

boards/frdm-kw41z/include/periph_conf.h

+17-7
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,30 @@ static const clock_config_t clock_config = {
3939
* Flash: 24 MHz
4040
*/
4141
.clkdiv1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV4(1),
42+
/* unsure if this RTC load cap configuration is correct, but it matches the
43+
* settings used by the example code in the NXP provided SDK */
44+
.rtc_clc = 0,
45+
/* Use the 32 kHz oscillator as ERCLK32K. Note that the values here have a
46+
* different mapping for the KW41Z than the values used in the Kinetis K series */
47+
.osc32ksel = SIM_SOPT1_OSC32KSEL(0),
48+
.clock_flags =
49+
KINETIS_CLOCK_OSC0_EN | /* Enable RSIM oscillator */
50+
KINETIS_CLOCK_RTCOSC_EN |
51+
KINETIS_CLOCK_USE_FAST_IRC |
52+
KINETIS_CLOCK_MCGIRCLK_EN | /* Used for LPUART clocking */
53+
KINETIS_CLOCK_MCGIRCLK_STOP_EN |
54+
0,
4255
/* Using FEI mode by default, the external crystal settings below are only
4356
* used if mode is changed to an external mode (PEE, FBE, or FEE) */
4457
.default_mode = KINETIS_MCG_MODE_FEI,
4558
/* The crystal connected to RSIM OSC is 32 MHz */
4659
.erc_range = KINETIS_MCG_ERC_RANGE_VERY_HIGH,
47-
.fcrdiv = 0, /* Fast IRC divide by 1 => 4 MHz */
48-
.oscsel = 0, /* Use RSIM for external clock */
49-
.clc = 0, /* no load cap configuration */
50-
.fll_frdiv = 0b101, /* Divide by 1024 */
60+
.osc_clc = 0, /* no load cap configuration */
61+
.oscsel = MCG_C7_OSCSEL(0), /* Use RSIM for external clock */
62+
.fcrdiv = MCG_SC_FCRDIV(0), /* Fast IRC divide by 1 => 4 MHz */
63+
.fll_frdiv = MCG_C1_FRDIV(0b101), /* Divide by 1024 */
5164
.fll_factor_fei = KINETIS_MCG_FLL_FACTOR_1464, /* FEI FLL freq = 48 MHz */
5265
.fll_factor_fee = KINETIS_MCG_FLL_FACTOR_1280, /* FEE FLL freq = 40 MHz */
53-
.enable_oscillator = true, /* Use RF module oscillator */
54-
.select_fast_irc = true,
55-
.enable_mcgirclk = true, /* Used for LPUART clocking */
5666
};
5767
/* Radio xtal frequency, either 32 MHz or 26 MHz */
5868
#define CLOCK_RADIOXTAL (32000000ul)

boards/mulle/board.c

-22
Original file line numberDiff line numberDiff line change
@@ -103,28 +103,6 @@ void board_init(void)
103103
/* Turn on AVDD for reading voltages */
104104
gpio_set(MULLE_POWER_AVDD);
105105

106-
/* Initialize RTC oscillator as early as possible since we are using it as a
107-
* base clock for the FLL.
108-
* It takes a while to stabilize the oscillator, therefore we do this as
109-
* soon as possible during boot in order to let it stabilize while other
110-
* stuff is initializing. */
111-
/* If the clock is not stable then the UART will have the wrong baud rate
112-
* for debug prints as well */
113-
rtt_init();
114-
115-
/* Set 32 kHz clock source */
116-
SIM->SOPT1 = (SIM->SOPT1 & ~(SIM_SOPT1_OSC32KSEL_MASK)) | SIM_SOPT1_OSC32KSEL(2);
117-
118-
/* At this point we need to wait for 1 ms until the clock is stable.
119-
* Since the clock is not yet stable we can only guess how long we must
120-
* wait. I have tried to make this as short as possible but still being able
121-
* to read the initialization messages written on the UART.
122-
* (If the clock is not stable all UART output is garbled until it has
123-
* stabilized) */
124-
for (int i = 0; i < 100000; ++i) {
125-
__asm__ volatile("nop\n");
126-
}
127-
128106
/* initialize the CPU */
129107
cpu_init();
130108

boards/mulle/include/periph_conf.h

+25-24
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@ extern "C"
3333
* @name Clock system configuration
3434
* @{
3535
*/
36+
/* The crystal on the Mulle is designed for 12.5 pF load capacitance. According
37+
* to the data sheet, the K60 will have a 5 pF parasitic capacitance on the
38+
* XTAL32/EXTAL32 connection. The board traces might give some minor parasitic
39+
* capacitance as well. */
40+
/* Use the equation
41+
* CL = (C1 * C2) / (C1 + C2) + Cstray
42+
* with C1 == C2:
43+
* C1 = 2 * (CL - Cstray)
44+
*/
45+
/* enable 14pF load capacitor which will yield a crystal load capacitance of 12 pF */
46+
#define RTC_LOAD_CAP_BITS (RTC_CR_SC8P_MASK | RTC_CR_SC4P_MASK | RTC_CR_SC2P_MASK)
47+
3648
static const clock_config_t clock_config = {
3749
/*
3850
* This configuration results in the system running from the FLL output with
@@ -48,24 +60,28 @@ static const clock_config_t clock_config = {
4860
* consumption than using the 16 MHz crystal and the OSC0 module */
4961
.clkdiv1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) |
5062
SIM_CLKDIV1_OUTDIV3(1) | SIM_CLKDIV1_OUTDIV4(1),
63+
.rtc_clc = RTC_LOAD_CAP_BITS,
64+
.osc32ksel = SIM_SOPT1_OSC32KSEL(2),
65+
.clock_flags =
66+
/* no OSC0_EN, the RTC module provides the clock input signal for the FLL */
67+
KINETIS_CLOCK_RTCOSC_EN |
68+
KINETIS_CLOCK_USE_FAST_IRC |
69+
0,
5170
.default_mode = KINETIS_MCG_MODE_FEE,
5271
.erc_range = KINETIS_MCG_ERC_RANGE_LOW, /* Input clock is 32768 Hz */
53-
.fcrdiv = 0, /* Fast IRC divide by 1 => 4 MHz */
54-
.oscsel = 1, /* Use RTC for external clock */
5572
/* 16 pF capacitors yield ca 10 pF load capacitance as required by the
5673
* onboard xtal, not used when OSC0 is disabled */
57-
.clc = 0b0001,
58-
.fll_frdiv = 0b000, /* Divide by 1 => FLL input 32768 Hz */
74+
.osc_clc = OSC_CR_SC16P_MASK,
75+
.oscsel = MCG_C7_OSCSEL(1), /* Use RTC for external clock */
76+
.fcrdiv = MCG_SC_FCRDIV(0), /* Fast IRC divide by 1 => 4 MHz */
77+
.fll_frdiv = MCG_C1_FRDIV(0b000), /* Divide by 1 => FLL input 32768 Hz */
5978
.fll_factor_fei = KINETIS_MCG_FLL_FACTOR_1464, /* FLL freq = 48 MHz */
6079
.fll_factor_fee = KINETIS_MCG_FLL_FACTOR_1464, /* FLL freq = 48 MHz */
6180
/* PLL is unavailable when using a 32768 Hz source clock, so the
6281
* configuration below can only be used if the above config is modified to
6382
* use the 16 MHz crystal instead of the RTC. */
64-
.pll_prdiv = 0b00111, /* Divide by 8 */
65-
.pll_vdiv = 0b01100, /* Multiply by 36 => PLL freq = 72 MHz */
66-
.enable_oscillator = false, /* the RTC module provides the clock input signal */
67-
.select_fast_irc = true, /* Only used for FBI mode */
68-
.enable_mcgirclk = false,
83+
.pll_prdiv = MCG_C5_PRDIV0(0b00111), /* Divide by 8 */
84+
.pll_vdiv = MCG_C6_VDIV0(0b01100), /* Multiply by 36 => PLL freq = 72 MHz */
6985
};
7086
#define CLOCK_CORECLOCK (48000000ul)
7187
#define CLOCK_BUSCLOCK (CLOCK_CORECLOCK / 1)
@@ -382,21 +398,6 @@ static const spi_conf_t spi_config[] = {
382398
#define RTT_MAX_VALUE (0xffffffff)
383399
#define RTT_FREQUENCY (1) /* in Hz */
384400

385-
/**
386-
* RTC module crystal load capacitance configuration bits.
387-
*/
388-
/* The crystal on the Mulle is designed for 12.5 pF load capacitance. According
389-
* to the data sheet, the K60 will have a 5 pF parasitic capacitance on the
390-
* XTAL32/EXTAL32 connection. The board traces might give some minor parasitic
391-
* capacitance as well. */
392-
/* Use the equation
393-
* CL = (C1 * C2) / (C1 + C2) + Cstray
394-
* with C1 == C2:
395-
* C1 = 2 * (CL - Cstray)
396-
*/
397-
/* enable 14pF load capacitor which will yield a crystal load capacitance of 12 pF */
398-
#define RTC_LOAD_CAP_BITS (RTC_CR_SC8P_MASK | RTC_CR_SC4P_MASK | RTC_CR_SC2P_MASK)
399-
400401
/** @} */
401402

402403
#ifdef __cplusplus

boards/pba-d-01-kw2x/include/periph_conf.h

+13-9
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,24 @@ static const clock_config_t clock_config = {
4343
*/
4444
.clkdiv1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) |
4545
SIM_CLKDIV1_OUTDIV4(1),
46+
.rtc_clc = 0, /* External load caps on the FRDM-K22F board */
47+
.osc32ksel = SIM_SOPT1_OSC32KSEL(2),
48+
.clock_flags =
49+
/* No OSC0_EN, use modem clock from EXTAL0 */
50+
KINETIS_CLOCK_RTCOSC_EN |
51+
KINETIS_CLOCK_USE_FAST_IRC |
52+
0,
4653
.default_mode = KINETIS_MCG_MODE_PEE,
4754
/* The modem generates a 4 MHz clock signal */
4855
.erc_range = KINETIS_MCG_ERC_RANGE_HIGH,
49-
.fcrdiv = 0, /* Fast IRC divide by 1 => 4 MHz */
50-
.oscsel = 0, /* Use EXTAL0 for external clock */
51-
.clc = 0, /* OSC0 is unused*/
52-
.fll_frdiv = 0b010, /* Divide by 128 */
56+
.osc_clc = 0, /* OSC0 is unused*/
57+
.oscsel = MCG_C7_OSCSEL(0), /* Use EXTAL0 for external clock */
58+
.fcrdiv = MCG_SC_FCRDIV(0), /* Fast IRC divide by 1 => 4 MHz */
59+
.fll_frdiv = MCG_C1_FRDIV(0b010), /* Divide by 128 */
5360
.fll_factor_fei = KINETIS_MCG_FLL_FACTOR_1464, /* FLL freq = 48 MHz */
5461
.fll_factor_fee = KINETIS_MCG_FLL_FACTOR_1280, /* FLL freq = 40 MHz */
55-
.pll_prdiv = 0b00001, /* Divide by 2 */
56-
.pll_vdiv = 0b00000, /* Multiply by 24 => PLL freq = 48 MHz */
57-
.enable_oscillator = false, /* Use modem clock from EXTAL0 */
58-
.select_fast_irc = true,
59-
.enable_mcgirclk = false,
62+
.pll_prdiv = MCG_C5_PRDIV0(0b00001), /* Divide by 2 */
63+
.pll_vdiv = MCG_C6_VDIV0(0b00000), /* Multiply by 24 => PLL freq = 48 MHz */
6064
};
6165
#define CLOCK_CORECLOCK (48000000ul)
6266
#define CLOCK_BUSCLOCK (CLOCK_CORECLOCK / 1)

boards/teensy31/include/periph_conf.h

+13-9
Original file line numberDiff line numberDiff line change
@@ -45,24 +45,28 @@ static const clock_config_t clock_config = {
4545
* consumption than using the 16 MHz crystal and the OSC0 module */
4646
.clkdiv1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) |
4747
SIM_CLKDIV1_OUTDIV3(1) | SIM_CLKDIV1_OUTDIV4(1),
48+
/* RTC crystal has to be soldered by the user, we can't know the load cap requirements */
49+
.rtc_clc = 0,
50+
.osc32ksel = SIM_SOPT1_OSC32KSEL(2),
51+
.clock_flags =
52+
KINETIS_CLOCK_RTCOSC_EN |
53+
KINETIS_CLOCK_USE_FAST_IRC |
54+
0,
4855
.default_mode = KINETIS_MCG_MODE_FEE,
4956
.erc_range = KINETIS_MCG_ERC_RANGE_LOW, /* Input clock is 32768 Hz */
50-
.fcrdiv = 0, /* Fast IRC divide by 1 => 4 MHz */
51-
.oscsel = 1, /* Use RTC for external clock */
5257
/* 16 pF capacitors yield ca 10 pF load capacitance as required by the
5358
* onboard xtal, not used when OSC0 is disabled */
54-
.clc = 0b0001,
55-
.fll_frdiv = 0b000, /* Divide by 1 => FLL input 32768 Hz */
59+
.osc_clc = OSC_CR_SC16P_MASK,
60+
.oscsel = MCG_C7_OSCSEL(1), /* Use RTC oscillator as external clock */
61+
.fcrdiv = MCG_SC_FCRDIV(0), /* Fast IRC divide by 1 => 4 MHz */
62+
.fll_frdiv = MCG_C1_FRDIV(0b000), /* Divide by 1 => FLL input 32768 Hz */
5663
.fll_factor_fei = KINETIS_MCG_FLL_FACTOR_1464, /* FLL freq = 48 MHz */
5764
.fll_factor_fee = KINETIS_MCG_FLL_FACTOR_1464, /* FLL freq = 48 MHz */
5865
/* PLL is unavailable when using a 32768 Hz source clock, so the
5966
* configuration below can only be used if the above config is modified to
6067
* use the 16 MHz crystal instead of the RTC. */
61-
.pll_prdiv = 0b00111, /* Divide by 8 */
62-
.pll_vdiv = 0b01100, /* Multiply by 36 => PLL freq = 72 MHz */
63-
.enable_oscillator = false, /* the RTC module provides the clock input signal */
64-
.select_fast_irc = true, /* Only used for FBI mode */
65-
.enable_mcgirclk = false,
68+
.pll_prdiv = MCG_C5_PRDIV0(0b00111), /* Divide by 8 */
69+
.pll_vdiv = MCG_C6_VDIV0(0b01100), /* Multiply by 36 => PLL freq = 72 MHz */
6670
};
6771
#define CLOCK_CORECLOCK (48000000ul)
6872
#define CLOCK_BUSCLOCK (CLOCK_CORECLOCK / 1)

cpu/kinetis/include/cpu_conf_kinetis.h

+4
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ extern "C"
124124
/** Enable PIT clock gate */
125125
#define PIT_CLKEN() (bit_set32(&SIM->SCGC6, SIM_SCGC6_PIT_SHIFT))
126126
#endif
127+
#ifdef SIM_SCGC6_RTC_SHIFT
128+
/** Enable RTC clock gate */
129+
#define RTC_CLKEN() (bit_set32(&SIM->SCGC6, SIM_SCGC6_RTC_SHIFT))
130+
#endif
127131
/** @} */
128132

129133
/**

0 commit comments

Comments
 (0)