Skip to content

Added MCGPLLFLL clock function, squished some 'bugs' #145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 14, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ static uint32_t extosc_frequency(void) {
}
} else { //PLL is selected
divider = (1u + (MCG->C5 & MCG_C5_PRDIV0_MASK));
multiplier = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 24u);
return MCGClock * divider / multiplier;
multiplier = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 24u);
return MCGClock * divider / multiplier;
}
}

Expand All @@ -83,6 +83,23 @@ static uint32_t extosc_frequency(void) {
return 0;
}

//Get MCG PLL/2 or FLL frequency, depending on which one is active, sets PLLFLLSEL bit
static uint32_t mcgpllfll_frequency(void) {
if ((MCG->C1 & MCG_C1_CLKS_MASK) != MCG_C1_CLKS(0)) //PLL/FLL is not selected
return 0;

uint32_t MCGClock = SystemCoreClock * (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT));
if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u) { //FLL is selected
SIM->SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK; //MCG peripheral clock is FLL output
return MCGClock;
} else { //PLL is selected
SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; //MCG peripheral clock is PLL output
return (MCGClock >> 1);
}

//It is possible the SystemCoreClock isn't running on the PLL, and the PLL is still active
//for the peripherals, this is however an unlikely setup
}

#ifdef __cplusplus
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
#include "clk_freqs.h"

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

uint32_t clkdiv = 0;
float clkval = SystemCoreClock / 1000000.0f;
float clkval;
if (mcgpllfll_frequency()) {
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK
clkval = mcgpllfll_frequency() / 1000000.0f;
} else {
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(2); // Clock source: ExtOsc
clkval = extosc_frequency() / 1000000.0f;
}

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

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

TPM_Type *tpm = (TPM_Type *)(TPM0_BASE + 0x1000 * tpm_n);
tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(clkdiv); // (clock)MHz / clkdiv ~= (0.75)MHz
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
obj->uart = (UARTLP_Type *)uart;
// enable clk
switch (uart) {
case UART_0: if ((MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0)) //PLL/FLL is selected
SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK | (1<<SIM_SOPT2_UART0SRC_SHIFT);
case UART_0: if (mcgpllfll_frequency() != 0) //PLL/FLL is selected
SIM->SOPT2 |= (1<<SIM_SOPT2_UART0SRC_SHIFT);
else
SIM->SOPT2 |= (2<<SIM_SOPT2_UART0SRC_SHIFT);
SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; break;
Expand Down Expand Up @@ -123,7 +123,14 @@ void serial_baud(serial_t *obj, int baudrate) {
// Disable UART before changing registers
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);

uint32_t PCLK = (obj->uart == UART0) ? SystemCoreClock : bus_frequency();
uint32_t PCLK;
if (obj->uart == UART0) {
if (mcgpllfll_frequency() != 0)
PCLK = mcgpllfll_frequency();
else
PCLK = extosc_frequency();
} else
PCLK = bus_frequency();

// First we check to see if the basic divide with no DivAddVal/MulVal
// ratio gives us an integer result. If it does, we set DivAddVal = 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,22 @@ static void lptmr_init(void) {
}
}
}
//No suitable external oscillator clock -> Use fast internal oscillator (4MHz)
//No suitable external oscillator clock -> Use fast internal oscillator (4MHz / divider)
MCG->C1 |= MCG_C1_IRCLKEN_MASK;
MCG->C2 |= MCG_C2_IRCS_MASK;
LPTMR0->PSR = LPTMR_PSR_PCS(0) | LPTMR_PSR_PRESCALE(1);
LPTMR0->PSR = LPTMR_PSR_PCS(0);
switch (MCG->SC & MCG_SC_FCRDIV_MASK) {
case MCG_SC_FCRDIV(0): //4MHz
LPTMR0->PSR |= LPTMR_PSR_PRESCALE(1);
break;
case MCG_SC_FCRDIV(1): //2MHz
LPTMR0->PSR |= LPTMR_PSR_PRESCALE(0);
break;
default: //1MHz or anything else, in which case we put it on 1MHz
MCG->SC &= ~MCG_SC_FCRDIV_MASK;
MCG->SC |= MCG_SC_FCRDIV(2);
LPTMR0->PSR |= LPTMR_PSR_PBYP_MASK;
}

}

Expand Down