Skip to content

Commit 8ef99f8

Browse files
committed
Merge pull request #145 from Sissors/master
Added MCGPLLFLL clock function, squished some 'bugs'
2 parents cee9a71 + 153a9dd commit 8ef99f8

File tree

4 files changed

+52
-9
lines changed

4 files changed

+52
-9
lines changed

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/clk_freqs.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ static uint32_t extosc_frequency(void) {
7272
}
7373
} else { //PLL is selected
7474
divider = (1u + (MCG->C5 & MCG_C5_PRDIV0_MASK));
75-
multiplier = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 24u);
76-
return MCGClock * divider / multiplier;
75+
multiplier = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 24u);
76+
return MCGClock * divider / multiplier;
7777
}
7878
}
7979

@@ -83,6 +83,23 @@ static uint32_t extosc_frequency(void) {
8383
return 0;
8484
}
8585

86+
//Get MCG PLL/2 or FLL frequency, depending on which one is active, sets PLLFLLSEL bit
87+
static uint32_t mcgpllfll_frequency(void) {
88+
if ((MCG->C1 & MCG_C1_CLKS_MASK) != MCG_C1_CLKS(0)) //PLL/FLL is not selected
89+
return 0;
90+
91+
uint32_t MCGClock = SystemCoreClock * (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT));
92+
if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u) { //FLL is selected
93+
SIM->SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK; //MCG peripheral clock is FLL output
94+
return MCGClock;
95+
} else { //PLL is selected
96+
SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; //MCG peripheral clock is PLL output
97+
return (MCGClock >> 1);
98+
}
99+
100+
//It is possible the SystemCoreClock isn't running on the PLL, and the PLL is still active
101+
//for the peripherals, this is however an unlikely setup
102+
}
86103

87104
#ifdef __cplusplus
88105
}

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/pwmout_api.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "cmsis.h"
1919
#include "pinmap.h"
2020
#include "error.h"
21+
#include "clk_freqs.h"
2122

2223
static const PinMap PinMap_PWM[] = {
2324
// LEDs
@@ -73,7 +74,14 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
7374
error("PwmOut pin mapping failed");
7475

7576
uint32_t clkdiv = 0;
76-
float clkval = SystemCoreClock / 1000000.0f;
77+
float clkval;
78+
if (mcgpllfll_frequency()) {
79+
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK
80+
clkval = mcgpllfll_frequency() / 1000000.0f;
81+
} else {
82+
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(2); // Clock source: ExtOsc
83+
clkval = extosc_frequency() / 1000000.0f;
84+
}
7785

7886
while (clkval > 1) {
7987
clkdiv++;
@@ -89,7 +97,6 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
8997

9098
SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
9199
SIM->SCGC6 |= 1 << (SIM_SCGC6_TPM0_SHIFT + tpm_n);
92-
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK
93100

94101
TPM_Type *tpm = (TPM_Type *)(TPM0_BASE + 0x1000 * tpm_n);
95102
tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(clkdiv); // (clock)MHz / clkdiv ~= (0.75)MHz

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/serial_api.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
7171
obj->uart = (UARTLP_Type *)uart;
7272
// enable clk
7373
switch (uart) {
74-
case UART_0: if ((MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0)) //PLL/FLL is selected
75-
SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK | (1<<SIM_SOPT2_UART0SRC_SHIFT);
74+
case UART_0: if (mcgpllfll_frequency() != 0) //PLL/FLL is selected
75+
SIM->SOPT2 |= (1<<SIM_SOPT2_UART0SRC_SHIFT);
7676
else
7777
SIM->SOPT2 |= (2<<SIM_SOPT2_UART0SRC_SHIFT);
7878
SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; break;
@@ -123,7 +123,14 @@ void serial_baud(serial_t *obj, int baudrate) {
123123
// Disable UART before changing registers
124124
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
125125

126-
uint32_t PCLK = (obj->uart == UART0) ? SystemCoreClock : bus_frequency();
126+
uint32_t PCLK;
127+
if (obj->uart == UART0) {
128+
if (mcgpllfll_frequency() != 0)
129+
PCLK = mcgpllfll_frequency();
130+
else
131+
PCLK = extosc_frequency();
132+
} else
133+
PCLK = bus_frequency();
127134

128135
// First we check to see if the basic divide with no DivAddVal/MulVal
129136
// ratio gives us an integer result. If it does, we set DivAddVal = 0,

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/us_ticker.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,22 @@ static void lptmr_init(void) {
102102
}
103103
}
104104
}
105-
//No suitable external oscillator clock -> Use fast internal oscillator (4MHz)
105+
//No suitable external oscillator clock -> Use fast internal oscillator (4MHz / divider)
106106
MCG->C1 |= MCG_C1_IRCLKEN_MASK;
107107
MCG->C2 |= MCG_C2_IRCS_MASK;
108-
LPTMR0->PSR = LPTMR_PSR_PCS(0) | LPTMR_PSR_PRESCALE(1);
108+
LPTMR0->PSR = LPTMR_PSR_PCS(0);
109+
switch (MCG->SC & MCG_SC_FCRDIV_MASK) {
110+
case MCG_SC_FCRDIV(0): //4MHz
111+
LPTMR0->PSR |= LPTMR_PSR_PRESCALE(1);
112+
break;
113+
case MCG_SC_FCRDIV(1): //2MHz
114+
LPTMR0->PSR |= LPTMR_PSR_PRESCALE(0);
115+
break;
116+
default: //1MHz or anything else, in which case we put it on 1MHz
117+
MCG->SC &= ~MCG_SC_FCRDIV_MASK;
118+
MCG->SC |= MCG_SC_FCRDIV(2);
119+
LPTMR0->PSR |= LPTMR_PSR_PBYP_MASK;
120+
}
109121

110122
}
111123

0 commit comments

Comments
 (0)