/*
Name: Clocks_05.ino
*/
//*****************************************************************************
#include <kinetis.h>
//*****************************************************************************
volatile bool LED_on = true;
volatile uint32_t loopCounter = 0;
//*****************************************************************************
void setup() {
Serial.begin(115200);
Serial.printf("\n1. Serial print ready.\n");
Serial.printf("2. Serial print ready.\n");
// LED pin
pinMode(13, OUTPUT);
//*********************************
// If the internal load capacitors are being used, they should be selected
// before enabling the oscillator. Application specific. 16 pF and 8 pF selected
// in this example. pdf. 667
//OSC_CR = OSC_CR_SC16P_MASK | OSC_CR_SC8P_MASK;
OSC0_CR |= OSC_SC16P | OSC_SC8P;
// Enabling the oscillator for 8 MHz crystal. pdf. 631 and pdf. 663 for range (16 MHz crystal)
// RANGE=1, should be set to match the high frequency of the crystal being used
// HGO=1, high gain is selected, provides better noise immunity but does draw
// higher current
// EREFS=1, enable the external oscillator
// LP=0, low power mode not selected (not actually part of osc setup)
// IRCS=0, slow internal ref clock selected (not actually part of osc setup)
//MCG_C2 = MCG_C2_RANGE(1) | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK;
MCG_C2 |= MCG_C2_RANGE0(1) | MCG_C2_HGO0 | MCG_C2_EREFS;
// Select ext oscillator, reference divider and clear IREFS to start ext osc, pdf. 630
// CLKS=2, select the external clock source
// FRDIV=3, set the FLL ref divider to keep the ref clock in range
// (even if FLL is not being used) 16 MHz / 256 = 62.5 kHz
// IREFS=0, select the external clock
// IRCLKEN=0, disable IRCLK (can enable it if desired)
// IREFSTEN=0, disable IRC in stop mode (can keep it enabled in stop if desired)
//MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3);
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3);
// wait for oscillator to initialize, pdf. 637
// while (!(MCG_S & MCG_S_OSCINIT_MASK)) {}
while (!(MCG_S & MCG_S_OSCINIT0)) {}
// wait for Reference clock to switch to external reference, pdf. 638
//while (MCG_S & MCG_S_IREFST_MASK) {}
while (MCG_S & MCG_S_IREFST) {}
// Wait for MCGOUT to switch over to the external reference clock, pdf. 638
//while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2) {}
while (((MCG_S & MCG_S_CLKST_MASK) >> 2) != 0x2) {}
// Now configure the PLL and move to PBE mode, pdf. 634
// set the PRDIV field to generate a 4 MHz reference clock (16 MHz / 4)
// PRDIV=3 selects a divide by 4
//MCG_C5 = MCG_C5_PRDIV(1);
MCG_C5 = MCG_C5_PRDIV0(3);
// LOLIE can be optionally set to enable the loss of lock interrupt, pdf. 635
// the PLLS bit is set to enable the PLL
// the clock monitor is enabled, CME=1 to cause a reset if crystal fails
// set the VDIV field to 8, which is x24, giving 4 x 24 = 96 MHz
//MCG_C6 = MCG_C6_CME_MASK | MCG_C6_PLLS_MASK;
MCG_C6 = MCG_C6_PLLS | MCG_C6_CME0 | MCG_C6_VDIV0(8);
// wait until the source of the PLLS clock has switched to the PLL, pdf. 637
//while (!(MCG_S & MCG_S_PLLST_MASK)) {}
while (!(MCG_S & MCG_S_PLLST)) {}
// wait until the PLL has achieved lock, pdf. 637
//while (!(MCG_S & MCG_S_LOCK_MASK)) {}
while (!(MCG_S & MCG_S_LOCK0)) {}
// set up the SIM clock dividers BEFORE switching to the PLL to ensure the
// system clock speeds are in spec, pdf. 267
// core = PLL (96 MHz), bus = PLL/2 (48 MHz), flexbus = PLL/2 (48 MHz),
// flash = PLL/4 (24 MHz)
//SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1)
// | SIM_CLKDIV1_OUTDIV3(1) | SIM_CLKDIV1_OUTDIV4(3);
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1)
| SIM_CLKDIV1_OUTDIV3(15) | SIM_CLKDIV1_OUTDIV4(3);
// Transition into PEE (PLL Engaged External, pdf. 643) by setting CLKS to 0, pdf. 630
// previous MCG_C1 settings remain the same, just need to set CLKS to 0
//MCG_C1 &= ~MCG_C1_CLKS_MASK;
MCG_C1 &= ~MCG_C1_CLKS(2);
// Wait for MCGOUT to switch over to the PLL, pdf. 637
//while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3) {}
while (((MCG_S & MCG_S_CLKST_MASK) >> 2) != 0x3) {}
// The USB clock divider in the System Clock Divider Register 2 (SIM_CLKDIV2)
// should be configured to generate the 48 MHz USB clock before configuring
// the USB module, pdf. 269
SIM_CLKDIV2 |= SIM_CLKDIV2_USBDIV(1); // sets USB divider to /2 assuming reset
// state of the SIM_CLKDIV2 register
//*********************************
// Connect FlexBus clock to CLKOUT pin.
// Set PTC3 to mode ALT5, pdf. 221.
PORTC_PCR3 |= (0b101 << 8);
// Clock gate control enabled for Port C, pdf. 261.
//SIM_SCGC5 |= (0b1 << 11);
SIM_SCGC5 |= SIM_SCGC5_PORTC;
// Connects FlexBus CLKOUT to the CLKOUT pin,
// Teensy pin 9 when PTC3 ALT5 configuration is set, pdf. 240, 188.
SIM_SOPT2 |= (0b000 < 5);
//*********************************
Serial.printf("End of setup().\n");
}
//*****************************************************************************
void loop() {
if (++loopCounter > 1'000'000) {
loopCounter = 0;
digitalWrite(13, LED_on);
LED_on = !LED_on;
}
}