/* ** =================================================================== ** Method : Cpu_SetMCGModeFBE (component MK21FN1M0MC12) ** ** Description : ** This method sets the MCG to FBE mode. ** This method is internal. It is used by Processor Expert only. ** =================================================================== */ static void Cpu_SetMCGModeFBE(uint8_t CLKMode) { switch (CLKMode) { case 0U: /* Switch to FBE Mode */ /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK); /* OSC_CR: ERCLKEN=1,??=0,EREFSTEN=1,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK); /* MCG_C7: OSCSEL=0 */ MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK); /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03)); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=1 */ MCG_C5 = MCG_C5_PRDIV0(0x01); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=6 */ MCG_C6 = MCG_C6_VDIV0(0x06); while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */ } while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ } while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } break; case 1U: /* Switch to FBE Mode */ /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */ MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK); /* OSC_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C7: OSCSEL=0 */ MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK); /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */ MCG_C5 = MCG_C5_PRDIV0(0x00); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ MCG_C6 = MCG_C6_VDIV0(0x00); while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */ } while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ } while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } break; default: break; } }
void PEE(void) { MCG->C6 &= ~MCG_C6_CME0_MASK; MCG->C2 &= ~MCG_C2_LP_MASK; MCG->C2 |= MCG_C2_RANGE0(3) |// Very high frequency range selected for the crystal oscillator MCG_C2_EREFS0_MASK ; MCG->C5 &= ~MCG_C5_PRDIV0_MASK; MCG->C5 |= MCG_C5_PRDIV0(2 - 1); // External clock div 4 MCG->C6 &= ~MCG_C6_VDIV0_MASK; MCG->C6 |= MCG_C6_VDIV0(24 - 24) | // Mul 24. 8 / 4 * 24 = 48MHz MCG_C6_CME0_MASK | MCG_C6_PLLS_MASK; MCG->C1 &= ~MCG_C1_CLKS_MASK; MCG->C1 |= ~MCG_C1_CLKS_MASK | // Output of PLL is selected for MCGOUTCLK MCG_C1_FRDIV(3) | MCG_C1_IRCLKEN_MASK; while((MCG->S & MCG_S_OSCINIT0_MASK) == 0); // wait for osc init. while((MCG->S & MCG_S_PLLST_MASK) != MCG_S_PLLST_MASK); // wait for PLL while((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)); // wait for PLL is selected SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(2 - 1) | // core/system clock = MCGOUTCLK / 2 = 96 / 2 = 48MHz SIM_CLKDIV1_OUTDIV4(2 - 1); // flash/bus clock = core/system / 2 = 24MHz }
/*lint -esym(765,Cpu_Interrupt) Disable MISRA rule (8.10) checking for symbols (Cpu_Interrupt). */ void __init_hardware(void) { /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/ /*** ### MKL25Z128VLK4 "Cpu" init code ... ***/ /*** PE initialization code after reset ***/ SCB_VTOR = (uint32_t)(&__vect_table); /* Set the interrupt vector table position */ /* Disable the WDOG module */ /* SIM_COPC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COPT=0,COPCLKS=0,COPW=0 */ SIM_COPC = SIM_COPC_COPT(0x00); /* System clock initialization */ /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x03)); /* Set the system prescalers to safe value */ /* SIM_SCGC5: PORTD=1,PORTB=1,PORTA=1 */ SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTA_MASK; /* Enable clock gate for ports to enable pin routing */ if ((PMC_REGSC & PMC_REGSC_ACKISO_MASK) != 0x0U) { /* PMC_REGSC: ACKISO=1 */ PMC_REGSC |= PMC_REGSC_ACKISO_MASK; /* Release IO pads after wakeup from VLLS mode. */ } /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x00)); /* Update system prescalers */ /* SIM_SOPT2: PLLFLLSEL=0 */ SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_PLLFLLSEL_MASK); /* Select FLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=3 */ SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */ /* SIM_SOPT2: TPMSRC=1 */ SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)( SIM_SOPT2_TPMSRC(0x02) )) | (uint32_t)( SIM_SOPT2_TPMSRC(0x01) )); /* Set the TPM clock */ /* Switch to FEI Mode */ /* MCG_C1: CLKS=0,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x00) | MCG_C1_IREFS_MASK | MCG_C1_IRCLKEN_MASK; /* MCG_C2: LOCRE0=0,??=0,RANGE0=0,HGO0=0,EREFS0=0,LP=0,IRCS=0 */ MCG_C2 = MCG_C2_RANGE0(0x00); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC0_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */ MCG_C5 = MCG_C5_PRDIV0(0x00); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ MCG_C6 = MCG_C6_VDIV0(0x00); while((MCG_S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */ } while((MCG_S & 0x0CU) != 0x00U) { /* Wait until output of the FLL is selected */ } /*** End of PE initialization code after reset ***/ /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/ }
/** * @brief Initialize the PLL Bypassed External Mode. * * MCGOUTCLK is derived from external reference clock (oscillator). * PLL output is not used. * Clock source is the external reference clock (oscillator). * The PLL loop will locks to VDIV times the frequency * corresponding by PRDIV. * Previous allowed mode are FBE or BLPE. */ static void kinetis_mcg_set_pbe(void) { /* select external reference clock and divide factor */ MCG->C1 = (uint8_t)(MCG_C1_CLKS(2) | MCG_C1_FRDIV(KINETIS_MCG_ERC_FRDIV)); /* Wait until ERC is selected */ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)); /* PLL is not disabled in bypass mode */ MCG->C2 &= ~(uint8_t)(MCG_C2_LP_MASK); /* set external reference devider */ MCG->C5 = (uint8_t)(MCG_C5_PRDIV0(KINETIS_MCG_PLL_PRDIV)); /* set external reference devider */ MCG->C6 = (uint8_t)(MCG_C6_VDIV0(KINETIS_MCG_PLL_VDIV0)); /* select PLL */ MCG->C6 |= (uint8_t)(MCG_C6_PLLS_MASK); /* Wait until the source of the PLLS clock is PLL */ while ((MCG->S & MCG_S_PLLST_MASK) == 0); /* Wait until PLL locked */ while ((MCG->S & MCG_S_LOCK0_MASK) == 0); current_mode = KINETIS_MCG_PBE; }
/* ** =================================================================== ** Method : Cpu_SetMCGModePBE (component MK22FN512VDC12) ** ** Description : ** This method sets the MCG to PBE mode. ** This method is internal. It is used by Processor Expert only. ** =================================================================== */ static void Cpu_SetMCGModePBE(uint8_t CLKMode) { switch (CLKMode) { case 0U: /* Switch to PBE Mode */ /* OSC_CR: ERCLKEN=1,??=0,EREFSTEN=1,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK); /* MCG_C7: OSCSEL=0 */ MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK); /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03)); /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ MCG_C2 = (MCG_C2_RANGE(0x02) | MCG_C2_EREFS_MASK); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=b (devider is 12) */ MCG_C5 = MCG_C5_PRDIV0(0x0b); /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0x10 (multiply is 40)*/ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x10)); while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */ } break; case 1U: /* Switch to PBE Mode */ /* OSC_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C7: OSCSEL=0 */ MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK); /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */ MCG_C2 = (MCG_C2_RANGE(0x02) | MCG_C2_EREFS_MASK | MCG_C2_IRCS_MASK); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=b(devider is 12) */ MCG_C5 = MCG_C5_PRDIV0(0x0b); /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0x10 (multiply is 40)*/ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x10)); /* FCTRIM = 13*/ while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */ } break; default: break; } }
/***************************************************************************** * @name pll_init * * @brief: Initialization of the MCU. * * @param : None * * @return : None ***************************************************************************** * It will configure the MCU to disable STOP and COP Modules. * It also set the MCG configuration and bus clock frequency. ****************************************************************************/ static unsigned char pll_init() { /* First move to FBE mode */ /* Enable external oscillator, RANGE=1, HGO=1, EREFS=1, LP=0, IRCS=0 */ MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_HGO0_MASK | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK; /* Select external oscillator and Reference Divider and clear IREFS to start ext osc CLKS=2, FRDIV=3, IREFS=0, IRCLKEN=0, IREFSTEN=0 */ MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3); /* Wait for oscillator to initialize */ while (!(MCG_S & MCG_S_OSCINIT0_MASK)){}; /* Wait for Reference clock Status bit to clear */ while (MCG_S & MCG_S_IREFST_MASK){}; /* Wait for clock status bits to show clock source is ext ref clk */ while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){}; MCG_C5 = MCG_C5_PRDIV0(BSP_REF_CLOCK_DIV - 1) | MCG_C5_PLLCLKEN0_MASK; /* Ensure MCG_C6 is at the reset default of 0. LOLIE disabled, PLL enabled, clk monitor disabled, PLL VCO divider is clear */ MCG_C6 = 0; /* Set system options dividers */ #if (defined MCU_MK20D5) || (defined MCU_MK40D7) SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(BSP_CORE_DIV - 1) | /* core/system clock */ SIM_CLKDIV1_OUTDIV2(BSP_BUS_DIV - 1) | /* peripheral clock; */ SIM_CLKDIV1_OUTDIV4(BSP_FLASH_DIV - 1); /* flash clock */ #else SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(BSP_CORE_DIV - 1) | /* Core/system clock */ SIM_CLKDIV1_OUTDIV2(BSP_BUS_DIV - 1) | /* Peripheral clock; */ SIM_CLKDIV1_OUTDIV3(BSP_FLEXBUS_DIV - 1)| /* FlexBus clock driven to the external pin (FB_CLK)*/ SIM_CLKDIV1_OUTDIV4(BSP_FLASH_DIV - 1); /* Flash clock */ #endif /* Set the VCO divider and enable the PLL, LOLIE = 0, PLLS = 1, CME = 0, VDIV = */ MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV0(BSP_CLOCK_MUL - 24); /* 2MHz * BSP_CLOCK_MUL */ while (!(MCG_S & MCG_S_PLLST_MASK)){}; /* Wait for PLL status bit to set */ while (!(MCG_S & MCG_S_LOCK0_MASK)){}; /* Wait for LOCK bit to set */ /* Transition into PEE by setting CLKS to 0 CLKS=0, FRDIV=3, IREFS=0, IRCLKEN=0, IREFSTEN=0 */ MCG_C1 &= ~MCG_C1_CLKS_MASK; /* Wait for clock status bits to update */ while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3){}; /* Enable the ER clock of oscillators */ OSC_CR = OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK; /* Now running in PEE Mode */ SIM_SOPT1 |= SIM_SOPT1_USBREGEN_MASK; return 0; } //pll_init
/* ** =================================================================== ** Method : Cpu_SetMCGClockInModePEE (component MK22FN512VDC12) ** ** Description : ** Calling of this method will cause the clock frequency ** change in mode PEE, typically from 120M to 80M, vice versa. ** Parameters : ** NAME - DESCRIPTION ** ModeID - Clock configuration identifier ** Returns : ** --- - ERR_OK - OK. ** ERR_RANGE - Mode parameter out of range ** =================================================================== */ static LDD_TError Cpu_SetMCGClockInModePEE(LDD_TClockConfiguration ModeID) { if (ModeID > 0x03U) return ERR_RANGE; switch (ModeID) { case CPU_CLOCK_CONFIG_3: /* OSC_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC_CR = OSC_CR_ERCLKEN_MASK; /* SIM_SOPT2: MCGCLKSEL=0 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(0x01); /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); /* MCG_C2: ??=0,??=0,RANGE=2,HGO=0,EREFS=1,LP=0,IRCS=0 */ MCG_C2 = (MCG_C2_RANGE(0x02) | MCG_C2_EREFS_MASK); /* MCG_C5: ??=0,PLLCLKEN=0,PLLSTEN=0,PRDIV=5 (devider is 6) */ MCG_C5 = MCG_C5_PRDIV0(0x05); /* MCG_C6: LOLIE=0,PLLS=1,CME=0,VDIV=6 */ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x06)); while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ } break; case CPU_CLOCK_CONFIG_0: /* OSC_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC_CR = (uint8_t)0x80U; /* SIM_SOPT2: MCGCLKSEL=0 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(0x01); /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); /* MCG_C2: ??=0,??=0,RANGE=2,HGO=0,EREFS=1,LP=0,IRCS=0 */ MCG_C2 = (MCG_C2_RANGE(0x02) | MCG_C2_EREFS_MASK); /* MCG_C5: ??=0,PLLCLKEN=0,PLLSTEN=0,PRDIV=0xb (devider is 12) */ MCG_C5 = MCG_C5_PRDIV0(0x0b); /* MCG_C6: LOLIE=0,PLLS=1,CME=0,VDIV=16 (multiply is 40)*/ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x10)); while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ } break; default: break; } return ERR_OK; }
void BoardConfig_vfnInit(void) { /* SIM_SOPT2: PLLFLLSEL=1 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; /* Select PLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=3 */ SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */ /* Switch to FBE Mode */ /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK); /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC0_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=3 */ MCG_C5 = MCG_C5_PRDIV0(0x03); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ MCG_C6 = MCG_C6_VDIV0(0x00); while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ } while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } /* Switch to PBE Mode */ /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0 */ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x00)); while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */ } SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK; GPIO_vfnPinMux(GPIO_PORT_C,10,GPIO_MUX_ALT_1); GPIO_vfnPinMux(GPIO_PORT_C,11,GPIO_MUX_ALT_1); GPIO_vfnPinMux(GPIO_PORT_C,12,GPIO_MUX_ALT_1); GPIO_vfnPinMux(GPIO_PORT_C,13,GPIO_MUX_ALT_1); GPIO_vfnPinMux(GPIO_PORT_D,7,GPIO_MUX_ALT_1); GPIO_vfnPinMux(GPIO_PORT_D,6,GPIO_MUX_ALT_1); GPIO_vfnPinMux(GPIO_PORT_B,19,GPIO_MUX_ALT_1); GPIOC_PDDR |= (1<<10) | (1<<11) | (1<<12) | (1<<13); GPIOD_PDDR |= (1<<7) | (1<<6); GPIOB_PDDR |= (1<<19); }
void FBE_to_PBE (void ) { MCG->C5 |=MCG_C5_PRDIV0(0x3); // Divider Factor = 4 , 8MHz/4=2MHz in range 2MHz->4MHz MCG->C6 |=MCG_C6_PLLS_MASK ; // PLL is selected MCG->C6 |=MCG_C6_VDIV0(0x18); // PLL out = 2MHz * 48 = 96MHz while((MCG->S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } while((MCG->S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */ } }
void Clock_init(void) { // Init system clock /* System clock initialization */ /* SIM_SCGC5: PORTA=1 */ SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; /* Enable clock gate for ports to enable pin routing */ /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x01)); /* Update system prescalers */ /* SIM_SOPT2: PLLFLLSEL=0 */ SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_PLLFLLSEL_MASK); /* Select FLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=0 */ SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL(0x03)); /* System oscillator drives 32 kHz clock for various peripherals */ /* SIM_SOPT2: TPMSRC=1 */ SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)( SIM_SOPT2_TPMSRC(0x02) )) | (uint32_t)( SIM_SOPT2_TPMSRC(0x01) )); /* Set the TPM clock */ /* PORTA_PCR18: ISF=0,MUX=0 */ PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* PORTA_PCR19: ISF=0,MUX=0 */ PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* MCG_SC: FCRDIV=1 */ MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)( MCG_SC_FCRDIV(0x06) )) | (uint8_t)( MCG_SC_FCRDIV(0x01) )); /* Switch to FEE Mode */ /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */ MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK); /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC0_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); /* MCG_C4: DMX32=0,DRST_DRS=1 */ MCG_C4 = (uint8_t)((MCG_C4 & (uint8_t)~(uint8_t)( MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x02) )) | (uint8_t)( MCG_C4_DRST_DRS(0x01) )); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */ MCG_C5 = MCG_C5_PRDIV0(0x00); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ MCG_C6 = MCG_C6_VDIV0(0x00); while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ } while((MCG_S & 0x0CU) != 0x00U) { /* Wait until output of the FLL is selected */ } /*** End of PE initialization code after reset ***/ }
/** **=========================================================================== ** Reset handler **=========================================================================== */ void __init_hardware(void) { /* This is a cleaned up output of Processor Expert generated code */ /* Set the interrupt vector table position */ SCB_VTOR = (uint32_t)__vector_table; #if 0 /* Disable the WDOG module */ SIM_COPC = SIM_COPC_COPT(0x00); #endif /* System clock initialization */ /* Enable clock gate for ports to enable pin routing */ SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; /* Update system prescalers */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x01); /* Select FLL as a clock source for various peripherals */ SIM_SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK; /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */ SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* Set the TPM clock */ SIM_SOPT2 &= ~SIM_SOPT2_TPMSRC(0x01); SIM_SOPT2 |= SIM_SOPT2_TPMSRC(0x02); /* Enable XTAL IO pins */ PORTA_PCR18 = PORT_PCR_MUX(0); PORTA_PCR19 = PORT_PCR_MUX(0); /* Switch to FBE Mode */ MCG_C2 = MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK; OSC0_CR = OSC_CR_ERCLKEN_MASK; MCG_C1 = MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK; MCG_C4 &= ~MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03); MCG_C5 = MCG_C5_PRDIV0(0x03); MCG_C6 = MCG_C6_VDIV0(0x00); /* Check that the source of the FLL reference clock is the external reference clock. */ while((MCG_S & MCG_S_IREFST_MASK) != 0x00U); /* Wait until external reference clock is selected as MCG output */ while((MCG_S & 0x0CU) != 0x08U); /* Switch to PBE Mode */ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x00)); /* Wait until external reference clock is selected as MCG output */ while((MCG_S & 0x0CU) != 0x08U); /* Wait until locked */ while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U); /* Switch to PEE Mode */ MCG_C1 = MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK; /* Wait until output of the PLL is selected */ while((MCG_S & 0x0CU) != 0x0CU); }
void CLOCK_EnablePll0(mcg_pll_config_t const *config) { assert(config); uint8_t mcg_c5 = 0U; mcg_c5 |= MCG_C5_PRDIV0(config->prdiv); MCG->C5 = mcg_c5; /* Disable the PLL first. */ MCG->C6 = (MCG->C6 & ~MCG_C6_VDIV0_MASK) | MCG_C6_VDIV0(config->vdiv); /* Set enable mode. */ MCG->C5 |= ((uint32_t)kMCG_PllEnableIndependent | (uint32_t)config->enableMode); /* Wait for PLL lock. */ while (!(MCG->S & MCG_S_LOCK0_MASK)) { } }
/* Switch to PBE Mode */ void PBE(void) { MCG->C6 &= ~MCG_C6_CME0_MASK; MCG->C2 &= ~MCG_C2_LP_MASK; MCG->C2 |= MCG_C2_RANGE0(3) |// Very high frequency range selected for the crystal oscillator MCG_C2_EREFS0_MASK; MCG->C5 &= ~MCG_C5_PRDIV0_MASK; MCG->C5 |= MCG_C5_PRDIV0(2 - 1); // External clock div 2 MCG->C6 &= ~MCG_C6_VDIV0_MASK; MCG->C6 |= MCG_C6_VDIV0(24 - 24) | // Mul 24. 8 / 2 * 24 = 96MHz MCG_C6_CME0_MASK | MCG_C6_PLLS_MASK; MCG->C1 &= ~MCG_C1_CLKS_MASK; MCG->C1 |= MCG_C1_CLKS(2); // Output of ExTAL is selected for MCGOUTCLK while((MCG->S & MCG_S_OSCINIT0_MASK) == 0); // wait for osc init. while((MCG->S & MCG_S_PLLST_MASK) != MCG_S_PLLST_MASK); // wait for PLL while((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)); // wait for EXTAL is selected }
/* ** =================================================================== ** Method : Cpu_SetMCGModePEE (component MK21FN1M0MC12) ** ** Description : ** This method sets the MCG to PEE mode. ** This method is internal. It is used by Processor Expert only. ** =================================================================== */ static void Cpu_SetMCGModePEE(uint8_t CLKMode) { switch (CLKMode) { case 0U: /* Switch to PEE Mode */ /* OSC_CR: ERCLKEN=1,??=0,EREFSTEN=1,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK); /* MCG_C7: OSCSEL=0 */ MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK); /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03)); /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=1 */ MCG_C5 = MCG_C5_PRDIV0(0x01); /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=6 */ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x06)); while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ } break; default: break; } }
/*lint -esym(765,Cpu_Interrupt) Disable MISRA rule (8.10) checking for symbols (Cpu_Interrupt). */ void __init_hardware(void) { /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/ /*** ### MK70FN1M0VMJ12 "Cpu" init code ... ***/ /*** PE initialization code after reset ***/ SCB_VTOR = (uint32_t)(&__vect_table); /* Set the interrupt vector table position */ /* Disable the WDOG module */ /* WDOG_UNLOCK: WDOGUNLOCK=0xC520 */ WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */ /* WDOG_UNLOCK: WDOGUNLOCK=0xD928 */ WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */ /* WDOG_STCTRLH: ??=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,??=0,??=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */ WDOG_STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) | WDOG_STCTRLH_WAITEN_MASK | WDOG_STCTRLH_STOPEN_MASK | WDOG_STCTRLH_ALLOWUPDATE_MASK | WDOG_STCTRLH_CLKSRC_MASK | 0x0100U; /* System clock initialization */ /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=3,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV2(0x01) | SIM_CLKDIV1_OUTDIV3(0x03) | SIM_CLKDIV1_OUTDIV4(0x03); /* Set the system prescalers to safe value */ /* SIM_SCGC5: PORTE=1,PORTA=1 */ SIM_SCGC5 |= (SIM_SCGC5_PORTE_MASK | SIM_SCGC5_PORTA_MASK); /* Enable clock gate for ports to enable pin routing */ if ((PMC_REGSC & PMC_REGSC_ACKISO_MASK) != 0x0U) { /* PMC_REGSC: ACKISO=1 */ PMC_REGSC |= PMC_REGSC_ACKISO_MASK; /* Release IO pads after wakeup from VLLS mode. */ } /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=0,OUTDIV3=1,OUTDIV4=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV2(0x00) | SIM_CLKDIV1_OUTDIV3(0x01) | SIM_CLKDIV1_OUTDIV4(0x01); /* Update system prescalers */ /* SIM_SOPT2: PLLFLLSEL=0 */ SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_PLLFLLSEL(0x03)); /* Select FLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=0 */ SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL_MASK); /* System oscillator drives 32 kHz clock for various peripherals */ /* SIM_SCGC1: OSC1=1 */ SIM_SCGC1 |= SIM_SCGC1_OSC1_MASK; /* Switch to FEI Mode */ /* MCG_C1: CLKS=0,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x00) | MCG_C1_IREFS_MASK | MCG_C1_IRCLKEN_MASK; /* MCG_C2: LOCRE0=0,??=0,RANGE0=0,HGO0=0,EREFS0=0,LP=0,IRCS=0 */ MCG_C2 = MCG_C2_RANGE0(0x00); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC0_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C10: LOCRE2=0,??=0,RANGE1=0,HGO1=0,EREFS1=0,??=0,??=0 */ MCG_C10 = MCG_C10_RANGE1(0x00); /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC1_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C7: OSCSEL=0 */ MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK); /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=0 */ MCG_C5 = MCG_C5_PRDIV0(0x00); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ MCG_C6 = MCG_C6_VDIV0(0x00); /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */ MCG_C11 = MCG_C11_PRDIV1(0x00); /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */ MCG_C12 = MCG_C12_VDIV1(0x00); /* 3 */ while((MCG_S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */ } while((MCG_S & 0x0CU) != 0x00U) { /* Wait until output of the FLL is selected */ } /*** End of PE initialization code after reset ***/ /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/ }
/*lint -esym(765,Cpu_Interrupt) Disable MISRA rule (8.10) checking for symbols (Cpu_Interrupt). */ void __init_hardware(void) { /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/ /*** ### MKL46Z256VMC4 "Cpu" init code ... ***/ /*** PE initialization code after reset ***/ SCB_VTOR = (uint32_t)(&__vect_table); /* Set the interrupt vector table position */ /* Disable the WDOG module */ /* SIM_COPC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COPT=0,COPCLKS=0,COPW=0 */ SIM_COPC = SIM_COPC_COPT(0x00); /* System clock initialization */ /* SIM_SCGC5: PORTE=1,PORTC=1,PORTB=1,PORTA=1 */ SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTA_MASK; /* Enable clock gate for ports to enable pin routing */ /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x01)); /* Update system prescalers */ /* SIM_SOPT2: PLLFLLSEL=1 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; /* Select PLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=2 */ SIM_SOPT1 = (uint32_t)((SIM_SOPT1 & (uint32_t)~(uint32_t)( SIM_SOPT1_OSC32KSEL(0x01) )) | (uint32_t)( SIM_SOPT1_OSC32KSEL(0x02) )); /* System oscillator drives 32 kHz clock for various peripherals */ /* SIM_SOPT2: TPMSRC=1 */ SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)( SIM_SOPT2_TPMSRC(0x02) )) | (uint32_t)( SIM_SOPT2_TPMSRC(0x01) )); /* Set the TPM clock */ /* PORTA_PCR18: ISF=0,MUX=0 */ PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* PORTA_PCR19: ISF=0,MUX=0 */ PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* Switch to FBE Mode */ /* MCG_C2: LOCRE0=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ MCG_C2 = (uint8_t)((MCG_C2 & (uint8_t)~(uint8_t)( MCG_C2_LOCRE0_MASK | MCG_C2_RANGE0(0x01) | MCG_C2_HGO0_MASK | MCG_C2_LP_MASK | MCG_C2_IRCS_MASK )) | (uint8_t)( MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK )); /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC0_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=3 */ MCG_C5 = MCG_C5_PRDIV0(0x03); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ MCG_C6 = MCG_C6_VDIV0(0x00); while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ } while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } /* Switch to PBE Mode */ /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0 */ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x00)); while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */ } /* Switch to PEE Mode */ /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ } /* Initialization of the RTC_CLKIN pin */ /* PORTC_PCR1: ISF=0,MUX=1 */ PORTC_PCR1 = (uint32_t)((PORTC_PCR1 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x06) )) | (uint32_t)( PORT_PCR_MUX(0x01) )); /*** End of PE initialization code after reset ***/ /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/ }
void ResetHandler(void) { uint32_t *src = &_etext; uint32_t *dest = &_sdata; WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE; startup_early_hook(); // enable clocks to always-used peripherals SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL; // if the RTC oscillator isn't enabled, get it started early if (!(RTC_CR & RTC_CR_OSCE)) { RTC_SR = 0; RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE; } // TODO: do this while the PLL is waiting to lock.... while (dest < &_edata) *dest++ = *src++; dest = &_sbss; while (dest < &_ebss) *dest++ = 0; SCB_VTOR = 0; // use vector table in flash // start in FEI mode // enable capacitors for crystal OSC0_CR = OSC_SC8P | OSC_SC2P; // enable osc, 8-32 MHz range, low power mode MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS; // switch to crystal as clock source, FLL input = 16 MHz / 512 MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(4); // wait for crystal oscillator to begin while ((MCG_S & MCG_S_OSCINIT0) == 0) ; // wait for FLL to use oscillator while ((MCG_S & MCG_S_IREFST) != 0) ; // wait for MCGOUT to use oscillator while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ; // now we're in FBE mode // config PLL input for 16 MHz Crystal / 4 = 4 MHz MCG_C5 = MCG_C5_PRDIV0(3); // config PLL for 96 MHz output MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); // wait for PLL to start using xtal as its input while (!(MCG_S & MCG_S_PLLST)) ; // wait for PLL to lock while (!(MCG_S & MCG_S_LOCK0)) ; // now we're in PBE mode #if F_CPU == 96000000 // config divisors: 96 MHz core, 48 MHz bus, 24 MHz flash SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); #elif F_CPU == 48000000 // config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); #elif F_CPU == 24000000 // config divisors: 24 MHz core, 24 MHz bus, 24 MHz flash SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(3) | SIM_CLKDIV1_OUTDIV4(3); #else #error "Error, F_CPU must be 96000000, 48000000, or 24000000" #endif // switch to PLL as clock source, FLL input = 16 MHz / 512 MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4); // wait for PLL clock to be used while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ; // now we're in PEE mode // configure USB for 48 MHz clock SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); // USB = 96 MHz PLL / 2 // USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0 SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6); // initialize the SysTick counter SYST_RVR = (F_CPU / 1000) - 1; SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_TICKINT | SYST_CSR_ENABLE; //init_pins(); __enable_irq(); _init_Teensyduino_internal_(); if (RTC_SR & RTC_SR_TIF) rtc_set(TIME_T); __libc_init_array(); /* for (ptr = &__init_array_start; ptr < &__init_array_end; ptr++) { (*ptr)(); } */ startup_late_hook(); main(); while (1) ; }
/*! * @brief PLL超频 * @param PLL_e 频率设置参数 * @return 超频频率(MHz) * @since v5.0 * @warning 此函数只能在 复位后没进行任何频率设置情况下调用,即MCG在FEI模式下才可调用 * Sample usage: uint8 clk = pll_init(PLL100); //超频 */ uint8 pll_init(PLL_e pll) { mcg_div_count( pll); SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; //PTA18 和 PTA19 用于 晶振 // set clock dividers to desired value SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(mcg_div.core_div) | SIM_CLKDIV1_OUTDIV4(mcg_div.bus_div); //上电复位后,单片机会自动进入 FEI 模式,使用 内部参考时钟 //FEI -> FBE OSC0_CR = ( 0 | OSC_CR_ERCLKEN_MASK //使能 外部参考时钟 //| OSC_CR_SC2P_MASK //配置电容 //| OSC_CR_SC4P_MASK //配置电容 //| OSC_CR_SC8P_MASK //配置电容 | OSC_CR_SC16P_MASK //配置电容 ); MCG_C2 = ( 0 | MCG_C2_RANGE0(2) | MCG_C2_EREFS0_MASK ); MCG_C1 = (0 | MCG_C1_CLKS(2) | MCG_C1_FRDIV(7) | MCG_C1_IRCLKEN_MASK ); while (MCG_S & MCG_S_IREFST_MASK) {}; //等待FLL参考时钟 为 外部参考时钟(S[IREFST]=0,表示使用外部参考时钟,) while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(0x2)) {}; //等待选择外部参考时钟 //现在已经进入了 FBE模式 //FBE -> PBE MCG_C5 = MCG_C5_PRDIV0(mcg_cfg[pll].prdiv); //分频, EXTAL_IN_MHz/( PRDIV+1) MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV0(mcg_cfg[pll].vdiv) ; //倍频, EXTAL_IN_MHz/( PRDIV+1) * (VDIV+24) while (!(MCG_S & MCG_S_PLLST_MASK)) {}; //等待时钟源选择PLL while (!(MCG_S & MCG_S_LOCK0_MASK)) {}; //等待 PLL锁了(锁相环) // 现在已经进入了 PBE 模式 // PBE -> PEE //MCG_C1 &= ~MCG_C1_CLKS_MASK; MCG_C1 = MCG_C1_IRCLKEN_MASK; while (((MCG_S & MCG_S_CLKST_MASK) ) != MCG_S_CLKST(0x3)) {};//等待选择输出PLL // 现在已经进入了 PEE 模式 SIM_SOPT2 |= (0 //选择 PLL时钟 | SIM_SOPT2_PLLFLLSEL_MASK ); return mcg_cfg[pll].clk; } //pll_init
void Boot_Init_Clock(void){ /* System clock initialization */ /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x03)); /* Set the system prescalers to safe value */ /* SIM_SCGC5: PORTA=1 */ SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; /* Enable clock gate for ports to enable pin routing */ if ((PMC_REGSC & PMC_REGSC_ACKISO_MASK) != 0x0U) { /* PMC_REGSC: ACKISO=1 */ PMC_REGSC |= PMC_REGSC_ACKISO_MASK; /* Release IO pads after wakeup from VLLS mode. */ } /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x01)); /* Update system prescalers */ /* SIM_SOPT2: PLLFLLSEL=1 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; /* Select PLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=3 */ SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */ /* SIM_SOPT2: TPMSRC=1 */ SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)( SIM_SOPT2_TPMSRC(0x02) )) | (uint32_t)( SIM_SOPT2_TPMSRC(0x01) )); /* Set the TPM clock */ /* PORTA_PCR18: ISF=0,MUX=0 */ PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* PORTA_PCR19: ISF=0,MUX=0 */ PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* Switch to FBE Mode */ /* MCG_C2: LOCRE0=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ MCG_C2 = (uint8_t)((MCG_C2 & (uint8_t)~(uint8_t)( MCG_C2_LOCRE0_MASK | MCG_C2_RANGE0(0x01) | MCG_C2_HGO0_MASK | MCG_C2_LP_MASK | MCG_C2_IRCS_MASK )) | (uint8_t)( MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK )); /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC0_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=3 */ MCG_C5 = MCG_C5_PRDIV0(0x03); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ MCG_C6 = MCG_C6_VDIV0(0x00); while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ } while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } /* Switch to PBE Mode */ /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0 */ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x00)); while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */ } /* Switch to PEE Mode */ /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ } /* MCG_C6: CME0=1 */ MCG_C6 |= MCG_C6_CME0_MASK; /* Enable the clock monitor */ /*** End of PE initialization code after reset ***/ }
void ResetHandler(void) { /* * Enable watchdog timer. Allow settings to be changed later, in case the * application firmware wants to adjust its settings or disable it. * * Originally I tried using the 1 kHz low-power oscillator here, but that seemed to * run into an issue where refreshes weren't taking effect. It seems similar to * this problem on the Freescale forums, which didn't really have a satisfactory * solution: * * https://community.freescale.com/thread/309519 * * As a workaround, I'm using the "alternate" system clock. */ { const uint32_t watchdog_timeout = F_BUS / 100; // 10ms WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; asm volatile ("nop"); asm volatile ("nop"); WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN | WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN | WDOG_STCTRLH_CLKSRC; WDOG_PRESC = 0; WDOG_TOVALH = watchdog_timeout >> 16; WDOG_TOVALL = watchdog_timeout; } // enable clocks to always-used peripherals SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL; // release I/O pins hold, if we woke up from VLLS mode if (PMC_REGSC & PMC_REGSC_ACKISO) PMC_REGSC |= PMC_REGSC_ACKISO; // start in FEI mode // enable capacitors for crystal OSC0_CR = OSC_SC8P | OSC_SC2P; // enable osc, 8-32 MHz range, low power mode MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS; // switch to crystal as clock source, FLL input = 16 MHz / 512 MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(4); // wait for crystal oscillator to begin while ((MCG_S & MCG_S_OSCINIT0) == 0) ; // wait for FLL to use oscillator while ((MCG_S & MCG_S_IREFST) != 0) ; // wait for MCGOUT to use oscillator while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ; // now we're in FBE mode // config PLL input for 16 MHz Crystal / 4 = 4 MHz MCG_C5 = MCG_C5_PRDIV0(3); // config PLL for 96 MHz output MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); // Copy things while we're waiting on the PLL { // Relocate data and text to RAM uint32_t *src = &_eflash; uint32_t *dest = &_sdtext; while (dest < &_edtext) *dest++ = *src++; // Clear BSS dest = &_sbss; while (dest < &_ebss) *dest++ = 0; // Copy IVT to RAM src = (uint32_t*) &gVectors[0]; dest = &ramVectors[0]; while (dest <= &ramVectors[63]) *dest++ = *src++; // Switch to ram IVT SCB_VTOR = (uint32_t) &ramVectors[0]; } // wait for PLL to start using xtal as its input while (!(MCG_S & MCG_S_PLLST)) ; // wait for PLL to lock while (!(MCG_S & MCG_S_LOCK0)) ; // now we're in PBE mode // config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); // switch to PLL as clock source, FLL input = 16 MHz / 512 MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4); // wait for PLL clock to be used while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ; // now we're in PEE mode // configure USB for 48 MHz clock SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); // USB = 96 MHz PLL / 2 // USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0 SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6); __enable_irq(); main(); }
void __startup(void) { // The CPU has a watchdog feature which is on by default, // so we have to configure it to not have nasty reset-surprises // later on. startup_watchdog_hook(); // If the system was in VLLS mode, some peripherials and // the I/O pins are in latched mode. We need to restore // config and can then acknowledge the isolation to get back // to normal. For now, we'll just ack TODO: properly do this if (PMC_REGSC & PMC_REGSC_ACKISO_MASK) PMC_REGSC |= PMC_REGSC_ACKISO_MASK; // There is a write-once-after-reset register that allows to // set which power states are available. Let's set it here. SMC_PMPROT = ENABLED_POWER_MODES; // For the sake of simplicity, enable all GPIO port clocks SIM_SCGC5 |= ( SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK); // ---------------------------------------------------------------------------------- // Setup clocks // ---------------------------------------------------------------------------------- // See section 5 in the Freescale K20 manual for how clock distribution works // The limits are outlined in section 5.5: // Core and System clocks: max 72 MHz // Bus/peripherial clock: max 50 MHz (integer divide of core) // Flash clock: max 25 MHz // // The teensy 3.x has a 16 MHz external oscillator // So we'll enable the external clock for the OSC module. Since // we're in high-frequency mode, also enable capacitors OSC_CR = OSC_CR_SC8P_MASK | OSC_CR_SC2P_MASK; // TODO This does not actually seem enable the ext crystal // Set MCG to very high frequency crystal and request oscillator. We have // to do this first so that the divisor will be correct (512 and not 16) MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS0_MASK; // Select the external reference clock for MCGOUTCLK // The divider for the FLL has to be chosen that we get something in 31.25 to 39.0625 kHz // 16MHz / 512 = 31.25 kHz -> set FRDIV to 4 MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(4); // Wait for OSC to become ready while ((MCG_S & MCG_S_OSCINIT0_MASK) == 0) ; // Wait for the FLL to synchronize to external reference while ((MCG_S & MCG_S_IREFST_MASK) != 0) ; // Wait for the clock mode to synchronize to external while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ; // The clock is now in FBE mode #if F_CPU <= 16000000 // For 16 MHz and below, the crystal is fast enough // -> enable BLPE mode which will disable both FLL and PLL MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS_MASK | MCG_C2_LP_MASK; #else // We need PLL to go above 16 MHz #if F_CPU == 96000000 MCG_C5 = MCG_C5_PRDIV0(3); // 16MHz / 4 = 4MHz (this needs to be 2-4MHz) MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0); // Enable PLL*24 = 96 MHz #elif F_CPU == 72000000 MCG_C5 = MCG_C5_PRDIV0(5); // 16 MHz / 6 = 2.66 MHz (this needs to be 2-4MHz) MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV0(3); // Enable PLL*27 = 71.82 MHz #elif F_CPU == 48000000 MCG_C5 = MCG_C5_PRDIV0(7); // 16 MHz / 8 = 2 MHz (this needs to be 2-4MHz) MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0); // Enable PLL*24 = 48 MHz #elif F_CPU == 24000000 // For 24 MHz, we'll use a 48 MHz PLL and divide in the SIM MCG_C5 = MCG_C5_PRDIV0(7); // 16 MHz / 8 = 2 MHz (this needs to be 2-4MHz) MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0); // Enable PLL*24 = 48 MHz #else #error "Unknown F_CPU value" #endif // Now that we setup and enabled the PLL, wait for it to become active while (!(MCG_S & MCG_S_PLLST_MASK)) ; // and locked while (!(MCG_S & MCG_S_LOCK0_MASK)) ; #endif // Next up: Setup clock dividers for MCU, peripherials, flash and USB // This is done by the SIM (System Integration Module) // There are two registers: // SIM_CLKDIV1: // OUTDIV1: Core/system clock divider // OUTDIV2: Peripherial/Bus clock // OUTDIV4: Flash clock // SIM_CLKDIV2: // USBDIV: Divisor // USBFRAC: Fraction // Output is input_clock*(USBFRAC+1)/(USBDIV+1) // // USB needs a 48MHz clock, so the divider should be setup accordingly. Also, // for the USB FS OTG controller to work, the system clock needs to be >= 20 MHz #if F_CPU == 96000000 // 96 MHz core, 48 MHz bus, 24 MHz flash (OVERCLOCKED!) SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); // 96 * 1/2 = 48 #elif F_CPU == 72000000 // 72 MHz core, 36 MHz bus, 24 MHz flash SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(2); SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC_MASK; // 72 * 2/3 = 48 #elif F_CPU == 48000000 // 48 MHz core, 48 MHz bus, 24 MHz flash, USB = 96 / 2 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(1); SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(0); // 48 * 1/1 = 48 #elif F_CPU == 24000000 // PLL is 48 MHz // 24 MHz core, 24 MHz bus, 24 MHz flash SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(1); SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(0); // 48 * 1/1 = 48 // -- For the modes <= 16 MHz, we have the MCG clock on 16 MHz, without FLL/PLL // Also, USB is not possible #elif F_CPU == 16000000 // 16 MHz core, 16 MHz bus, 16 MHz flash SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(0); #elif F_CPU == 8000000 // 8 MHz core, 8 MHz bus, 8 MHz flash SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(1); #else #error "Unsupported F_CPU value" #endif // The dividers are set, so we can transition over to PLL for > 16 MHz #if F_CPU > 16000000 // Switch clock source to PLL, keep FLL divider at 512 MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4); // Wait for the clock to sync while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ; // Use PLL for USB and Bus/peripherals, core for trace and put OSCERCLK0 on CLKOUT pin SIM_SOPT2 = SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK | SIM_SOPT2_TRACECLKSEL_MASK | SIM_SOPT2_CLKOUTSEL(6); #endif // ---------------------------------------------------------------------------------- // Relocate data from flash to RAM as necessary // ---------------------------------------------------------------------------------- // // At the minimum, the .data and .bss sections have to be setup in RAM. Also, since // they are aligned to 4 bytes, we can use uint32s for copying (which is faster than // byte by byte) uint32_t * src = &_etext; uint32_t * dest = &_sdata; while (dest < &_edata) *dest++ = *src++; // Also zero out .bss dest = &_sbss; while (dest < &_ebss) *dest++ = 0; // TODO: Relocate interrupt vector to RAM for speed? // Init systick? #if ENABLE_SYSTICK_HANDLER systick_init(); #endif // Enable interrupts before entering main? #if ENABLE_INTERRUPTS_ON_STARTUP interrupt_enable(); #endif // After everthing is done, call main main(); // This should be unreachable code as long as main() does not return. // To avoid running the instruction pointer into places it shouldn't go, // loop forever // TODO: Going into sleep would maybe be a better solution while (1); }
/** * @brief K20x clock initialization. * @note All the involved constants come from the file @p board.h. * @note This function is meant to be invoked early during the system * initialization, it is usually invoked from the file * @p board.c. * @todo This function needs to be more generic. * * @special */ void k20x_clock_init(void) { #if !KINETIS_NO_INIT /* Disable the watchdog */ WDOG->UNLOCK = 0xC520; WDOG->UNLOCK = 0xD928; WDOG->STCTRLH &= ~WDOG_STCTRLH_WDOGEN; SIM->SCGC5 |= SIM_SCGC5_PORTA | SIM_SCGC5_PORTB | SIM_SCGC5_PORTC | SIM_SCGC5_PORTD | SIM_SCGC5_PORTE; #if KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEI /* This is the default mode at reset. */ /* Configure FEI mode */ MCG->C4 = MCG_C4_DRST_DRS(KINETIS_MCG_FLL_DRS) | (KINETIS_MCG_FLL_DMX32 ? MCG_C4_DMX32 : 0); /* Set clock dividers */ SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1-1) | SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2-1) | SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4-1); SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0); /* not strictly necessary since usb_lld will set this */ #elif KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE uint32_t ratio, frdiv; uint32_t ratios[] = { 32, 64, 128, 256, 512, 1024, 1280, 1536 }; uint8_t ratio_quantity = sizeof(ratios) / sizeof(ratios[0]); uint8_t i; /* EXTAL0 and XTAL0 */ PORTA->PCR[18] = 0; PORTA->PCR[19] = 0; /* * Start in FEI mode */ /* Internal capacitors for crystal */ #if defined(KINETIS_BOARD_OSCILLATOR_SETTING) OSC0->CR = KINETIS_BOARD_OSCILLATOR_SETTING; #else /* KINETIS_BOARD_OSCILLATOR_SETTING */ /* Disable the internal capacitors */ OSC0->CR = 0; #endif /* KINETIS_BOARD_OSCILLATOR_SETTING */ /* TODO: need to add more flexible calculation, specially regarding * divisors which may not be available depending on the XTAL * frequency, which would required other registers to be modified. */ /* Enable OSC, low power mode */ MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0; if (KINETIS_XTAL_FREQUENCY > 8000000UL) MCG->C2 |= MCG_C2_RANGE0(2); else MCG->C2 |= MCG_C2_RANGE0(1); frdiv = 7; ratio = KINETIS_XTAL_FREQUENCY / 31250UL; for (i = 0; i < ratio_quantity; ++i) { if (ratio == ratios[i]) { frdiv = i; break; } } /* Switch to crystal as clock source, FLL input of 31.25 KHz */ MCG->C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(frdiv); /* Wait for crystal oscillator to begin */ while (!(MCG->S & MCG_S_OSCINIT0)); /* Wait for the FLL to use the oscillator */ while (MCG->S & MCG_S_IREFST); /* Wait for the MCGOUTCLK to use the oscillator */ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)); /* * Now in FBE mode */ #define KINETIS_PLLIN_FREQUENCY 2000000UL /* * Config PLL input for 2 MHz * TODO: Make sure KINETIS_XTAL_FREQUENCY >= 2Mhz && <= 50Mhz */ MCG->C5 = MCG_C5_PRDIV0((KINETIS_XTAL_FREQUENCY/KINETIS_PLLIN_FREQUENCY) - 1); /* * Config PLL output to match KINETIS_SYSCLK_FREQUENCY * TODO: make sure KINETIS_SYSCLK_FREQUENCY is a match */ for(i = 24; i < 56; i++) { if(i == (KINETIS_PLLCLK_FREQUENCY/KINETIS_PLLIN_FREQUENCY)) { /* Config PLL to match KINETIS_PLLCLK_FREQUENCY */ MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(i-24); break; } } if(i>=56) /* Config PLL for 96 MHz output as default setting */ MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); /* Wait for PLL to start using crystal as its input, and to lock */ while ((MCG->S & (MCG_S_PLLST|MCG_S_LOCK0))!=(MCG_S_PLLST|MCG_S_LOCK0)); /* * Now in PBE mode */ /* Set the PLL dividers for the different clocks */ SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1-1) | SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2-1) | SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4-1); SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0); SIM->SOPT2 = SIM_SOPT2_PLLFLLSEL; /* Switch to PLL as clock source */ MCG->C1 = MCG_C1_CLKS(0); /* Wait for PLL clock to be used */ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL); /* * Now in PEE mode */ #else /* KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE */ #error Unimplemented KINETIS_MCG_MODE #endif /* KINETIS_MCG_MODE == ... */ #endif /* !KINETIS_NO_INIT */ }
/** * @brief MK20D5 clock initialization. * @note All the involved constants come from the file @p board.h. * @note This function is meant to be invoked early during the system * initialization, it is usually invoked from the file * @p board.c. * @todo This function needs to be more generic. * * @special */ void mk20d50_clock_init(void) { /* Disable the watchdog */ WDOG->UNLOCK = 0xC520; WDOG->UNLOCK = 0xD928; WDOG->STCTRLH &= ~WDOG_STCTRLH_WDOGEN; SIM->SCGC5 |= SIM_SCGC5_PORTA | SIM_SCGC5_PORTB | SIM_SCGC5_PORTC | SIM_SCGC5_PORTD | SIM_SCGC5_PORTE; /* EXTAL0 and XTAL0 */ PORTA->PCR[18] = 0; PORTA->PCR[19] = 0; /* * Start in FEI mode */ /* Disable capacitors for crystal */ OSC->CR = 0; /* Enable OSC, 8-32 MHz range, low power mode */ MCG->C2 = MCG_C2_RANGE0(1) | MCG_C2_LOCRE0 | MCG_C2_EREFS0; /* Switch to crystal as clock source, FLL input of 8 MHz / 256 = 31.25 KHz */ MCG->C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3); /* Wait for crystal oscillator to begin */ while (!(MCG->S & MCG_S_OSCINIT0)); /* Wait for the FLL to use the oscillator */ while (MCG->S & MCG_S_IREFST); /* Wait for the MCGOUTCLK to use the oscillator */ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)); /* * Now in FBE mode */ /* Config PLL input for 2 MHz (8 MHz crystal / 4) */ MCG->C5 = MCG_C5_PRDIV0(3); /* Config PLL for 96 MHz output */ MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); /* Wait for PLL to start using crystal as its input */ while (!(MCG->S & MCG_S_PLLST)); /* Wait for PLL to lock */ while (!(MCG->S & MCG_S_LOCK0)); /* * Now in PBE mode */ /* Switch to PLL as clock source */ MCG->C1 = MCG_C1_CLKS(0); /* Wait for PLL clock to be used */ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL); /* * Now in PEE mode */ }
/** * @brief KL2x clocks and PLL initialization. * @note All the involved constants come from the file @p board.h. * @note This function should be invoked just after the system reset. * * @special */ void kl2x_clock_init(void) { #if !KINETIS_NO_INIT /* Disable COP watchdog */ SIM->COPC = 0; /* Enable PORTA */ SIM->SCGC5 |= SIM_SCGC5_PORTA; /* --- MCG mode: FEI (default out of reset) --- f_MCGOUTCLK = f_int * F F is the FLL factor selected by C4[DRST_DRS] and C4[DMX32] bits. Typical f_MCGOUTCLK = 21 MHz immediately after reset. C4[DMX32]=0 and C4[DRST_DRS]=00 => FLL factor=640. C3[SCTRIM] and C4[SCFTRIM] factory trim values apply to f_int. */ /* System oscillator drives 32 kHz clock (OSC32KSEL=0) */ SIM->SOPT1 &= ~SIM_SOPT1_OSC32KSEL_MASK; #if KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEI /* This is the default mode at reset. */ /* The MCGOUTCLK is divided by OUTDIV1 and OUTDIV4: * OUTDIV1 (divider for core/system and bus/flash clock) * OUTDIV4 (additional divider for bus/flash clock) */ SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | /* OUTDIV1 = divide-by-2 => 24 MHz */ SIM_CLKDIV1_OUTDIV4(0); /* OUTDIV4 = divide-by-1 => 24 MHz */ #elif KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEE /* * FLL Enabled External (FEE) MCG Mode * 24 MHz core, 12 MHz bus - using 32.768 kHz crystal with FLL. * f_MCGOUTCLK = (f_ext / FLL_R) * F * = (32.768 kHz ) * * FLL_R is the reference divider selected by C1[FRDIV] * F is the FLL factor selected by C4[DRST_DRS] and C4[DMX32]. * * Then the core/system and bus/flash clocks are divided: * f_SYS = f_MCGOUTCLK / OUTDIV1 = 48 MHz / 1 = 48 MHz * f_BUS = f_MCGOUTCLK / OUTDIV1 / OUTDIV4 = MHz / 4 = 24 MHz */ SIM->SOPT2 = SIM_SOPT2_TPMSRC(1); /* MCGFLLCLK clock or MCGPLLCLK/2 */ /* PLLFLLSEL=0 -> MCGFLLCLK */ /* The MCGOUTCLK is divided by OUTDIV1 and OUTDIV4: * OUTDIV1 (divider for core/system and bus/flash clock) * OUTDIV4 (additional divider for bus/flash clock) */ SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_MCG_FLL_OUTDIV1 - 1) | SIM_CLKDIV1_OUTDIV4(KINETIS_MCG_FLL_OUTDIV4 - 1); /* EXTAL0 and XTAL0 */ PORTA->PCR[18] &= ~0x01000700; /* Set PA18 to analog (default) */ PORTA->PCR[19] &= ~0x01000700; /* Set PA19 to analog (default) */ OSC0->CR = 0; /* From KL25P80M48SF0RM section 24.5.1.1 "Initializing the MCG". */ /* To change from FEI mode to FEE mode: */ /* (1) Select the external clock source in C2 register. Use low-power OSC mode (HGO0=0) which enables internal feedback resistor, for 32.768 kHz crystal configuration. */ MCG->C2 = MCG_C2_RANGE0(0) | /* low frequency range (<= 40 kHz) */ MCG_C2_EREFS0; /* external reference (using a crystal) */ /* (2) Write to C1 to select the clock mode. */ MCG->C1 = /* Clear the IREFS bit to switch to the external reference. */ MCG_C1_CLKS_FLLPLL | /* Use FLL for system clock, MCGCLKOUT. */ MCG_C1_FRDIV(0); /* Don't divide 32kHz ERCLK FLL reference. */ MCG->C6 = 0; /* PLLS=0: Select FLL as MCG source, not PLL */ /* Loop until S[OSCINIT0] is 1, indicating the crystal selected by C2[EREFS0] has been initialized. */ while ((MCG->S & MCG_S_OSCINIT0) == 0) ; /* Loop until S[IREFST] is 0, indicating the external reference is the current reference clock source. */ while ((MCG->S & MCG_S_IREFST) != 0) ; /* Wait until external reference clock is FLL reference. */ /* (1)(e) Loop until S[CLKST] indicates FLL feeds MCGOUTCLK. */ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_FLL) ; /* Wait until FLL has been selected. */ /* --- MCG mode: FEE --- */ /* Set frequency range for DCO output (MCGFLLCLK). */ MCG->C4 = (KINETIS_MCG_FLL_DMX32 ? MCG_C4_DMX32 : 0) | MCG_C4_DRST_DRS(KINETIS_MCG_FLL_DRS); /* Wait for the FLL lock time; t[fll_acquire][max] = 1 ms */ /* TODO - not implemented - is it required? Freescale example code seems to omit it. */ #elif KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE /* * PLL Enabled External (PEE) MCG Mode * 48 MHz core, 24 MHz bus - using 8 MHz crystal with PLL. * f_MCGOUTCLK = (OSCCLK / PLL_R) * M * = 8 MHz / 2 * 24 = 96 MHz * PLL_R is the reference divider selected by C5[PRDIV0] * M is the multiplier selected by C6[VDIV0] * * Then the core/system and bus/flash clocks are divided: * f_SYS = f_MCGOUTCLK / OUTDIV1 = 96 MHz / 2 = 48 MHz * f_BUS = f_MCGOUTCLK / OUTDIV1 / OUTDIV4 = 96 MHz / 4 = 24 MHz */ /* The MCGOUTCLK is divided by OUTDIV1 and OUTDIV4: * OUTDIV1 (divider for core/system and bus/flash clock) * OUTDIV4 (additional divider for bus/flash clock) */ SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | /* OUTDIV1 = divide-by-2 => 48 MHz */ SIM_CLKDIV1_OUTDIV4(1); /* OUTDIV4 = divide-by-2 => 24 MHz */ SIM->SOPT2 = SIM_SOPT2_TPMSRC(1) | /* MCGFLLCLK clock or MCGPLLCLK/2 */ SIM_SOPT2_PLLFLLSEL; /* PLLFLLSEL=MCGPLLCLK/2 */ /* EXTAL0 and XTAL0 */ PORTA->PCR[18] &= ~0x01000700; /* Set PA18 to analog (default) */ PORTA->PCR[19] &= ~0x01000700; /* Set PA19 to analog (default) */ OSC0->CR = 0; /* From KL25P80M48SF0RM section 24.5.1.1 "Initializing the MCG". */ /* To change from FEI mode to FBE mode: */ /* (1) Select the external clock source in C2 register. Use low-power OSC mode (HGO0=0) which enables internal feedback resistor since FRDM-KL25Z has feedback resistor R25 unpopulated. Use high-gain mode by setting C2[HGO0] instead if external feedback resistor Rf is installed. */ MCG->C2 = MCG_C2_RANGE0(2) | /* very high frequency range */ MCG_C2_EREFS0; /* external reference (using a crystal) */ /* (2) Write to C1 to select the clock mode. */ MCG->C1 = /* Clear the IREFS bit to switch to the external reference. */ MCG_C1_CLKS_ERCLK | /* Use ERCLK for system clock, MCGCLKOUT. */ MCG_C1_FRDIV(3); /* Divide ERCLK / 256 for FLL reference. */ /* Note: FLL reference frequency must be 31.25 kHz to 39.0625 kHz. 8 MHz / 256 = 31.25 kHz. */ MCG->C4 &= ~(MCG_C4_DMX32 | MCG_C4_DRST_DRS_MASK); MCG->C6 = 0; /* PLLS=0: Select FLL as MCG source, not PLL */ /* (3) Once configuration is set, wait for MCG mode change. */ /* From KL25P80M48SF0RM section 24.5.31: */ /* (1)(c) Loop until S[OSCINIT0] is 1, indicating the crystal selected by C2[EREFS0] has been initialized. */ while ((MCG->S & MCG_S_OSCINIT0) == 0) ; /* (1)(d) Loop until S[IREFST] is 0, indicating the external reference is the current reference clock source. */ while ((MCG->S & MCG_S_IREFST) != 0) ; /* Wait until external reference clock is FLL reference. */ /* (1)(e) Loop until S[CLKST] is 2'b10, indicating the external reference clock is selected to feed MCGOUTCLK. */ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_ERCLK) ; /* Wait until external reference clock has been selected. */ /* --- MCG mode: FBE (FLL bypassed, external crystal) --- Now the MCG is in FBE mode. Although the FLL is bypassed, it is still on. */ /* (2) Then configure C5[PRDIV0] to generate the correct PLL reference frequency. */ MCG->C5 = MCG_C5_PRDIV0(1); /* PLL External Reference Divide by 2 */ /* (3) Then from FBE transition to PBE mode. */ /* (3)(b) C6[PLLS]=1 to select PLL. */ /* (3)(b) C6[VDIV0]=5'b0000 (x24) 2 MHz * 24 = 48 MHz. */ MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); /* (3)(d) Loop until S[PLLST], indicating PLL is the PLLS clock source. */ while ((MCG->S & MCG_S_PLLST) == 0) ; /* wait until PLL is the PLLS clock source. */ /* (3)(e) Loop until S[LOCK0] is set, indicating the PLL has acquired lock. */ /* PLL selected as MCG source. VDIV0=00000 (Multiply=24). */ while ((MCG->S & MCG_S_LOCK0) == 0) ; /* wait until PLL locked */ /* --- MCG mode: PBE (PLL bypassed, external crystal) --- */ /* (4) Transition from PBE mode to PEE mode. */ /* (4)(a) C1[CLKS] = 2'b00 to select PLL output as system clock source. */ // Switch to PEE mode // Select PLL output (CLKS=0) // FLL external reference divider (FRDIV=3) // External reference clock for FLL (IREFS=0) MCG->C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(3); /* (4)(b) Loop until S[CLKST] are 2'b11, indicating the PLL output is selected for MCGOUTCLK. */ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL) ; /* wait until clock switched to PLL output */ /* --- MCG mode: PEE (PLL enabled, external crystal) --- */ #else /* KINETIS_MCG_MODE != KINETIS_MCG_MODE_PEE */ #error Unimplemented KINETIS_MCG_MODE #endif /* KINETIS_MCG_MODE != KINETIS_MCG_MODE_PEE */ #endif /* !KINETIS_NO_INIT */ }
/** * @brief MK20D5 clock initialization. * @note All the involved constants come from the file @p board.h. * @note This function is meant to be invoked early during the system * initialization, it is usually invoked from the file * @p board.c. * @todo This function needs to be more generic. * * @special */ void mk20d50_clock_init(void) { uint32_t ratio, frdiv; uint32_t ratios[] = { 32, 64, 128, 256, 512, 1024, 1280, 1536 }; int ratio_quantity = sizeof(ratios) / sizeof(ratios[0]); int i; /* Disable the watchdog */ WDOG->UNLOCK = 0xC520; WDOG->UNLOCK = 0xD928; WDOG->STCTRLH &= ~WDOG_STCTRLH_WDOGEN; SIM->SCGC5 |= SIM_SCGC5_PORTA | SIM_SCGC5_PORTB | SIM_SCGC5_PORTC | SIM_SCGC5_PORTD | SIM_SCGC5_PORTE; /* EXTAL0 and XTAL0 */ PORTA->PCR[18] = 0; PORTA->PCR[19] = 0; /* * Start in FEI mode */ /* Disable capacitors for crystal */ OSC->CR = 0; /* TODO: need to add more flexible calculation, specially regarding * divisors which may not be available depending on the XTAL * frequency, which would required other registers to be modified. */ /* Enable OSC, low power mode */ MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0; if (KINETIS_XTAL_FREQUENCY > 8000000) MCG->C2 |= MCG_C2_RANGE0(2); else MCG->C2 |= MCG_C2_RANGE0(1); frdiv = 7; ratio = KINETIS_XTAL_FREQUENCY / 31250; for (i = 0; i < ratio_quantity; ++i) { if (ratio == ratios[i]) { frdiv = i; break; } } /* Switch to crystal as clock source, FLL input of 31.25 KHz */ MCG->C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(frdiv); /* Wait for crystal oscillator to begin */ while (!(MCG->S & MCG_S_OSCINIT0)); /* Wait for the FLL to use the oscillator */ while (MCG->S & MCG_S_IREFST); /* Wait for the MCGOUTCLK to use the oscillator */ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)); /* * Now in FBE mode */ /* Config PLL input for 2 MHz */ MCG->C5 = MCG_C5_PRDIV0((KINETIS_XTAL_FREQUENCY / 2000000) - 1); /* Config PLL for 96 MHz output */ MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); /* Wait for PLL to start using crystal as its input */ while (!(MCG->S & MCG_S_PLLST)); /* Wait for PLL to lock */ while (!(MCG->S & MCG_S_LOCK0)); /* * Now in PBE mode */ /* Switch to PLL as clock source */ MCG->C1 = MCG_C1_CLKS(0); /* Wait for PLL clock to be used */ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL); /* * Now in PEE mode */ }
// ============================================================================= // 功能:PLL初始化部分,主要对PLL和晶振初始化,是时间从内部时钟切换到外部时钟的主要部 // 分,此处使用PLL0和OSC0作为内部时钟源,经分频和倍频,使内核时钟达到150M // 参数:crystal_fre_hz,外部晶振频率 // prdiv,PLL分频参数 // vdiv,PLL倍频参数 // 返回:实际配置的MCG输出频率 // ============================================================================= u32 PLL_Init(u32 crystal_fre_hz, u8 prdiv, u8 vdiv) { //reset后,系统处于FEI模式,时钟配置过程为: //FEI--->FBE--->PBE--->PEE(手册640页table25-22) //默认使用振荡器0,设置振荡器0 // 配置控制寄存器MCG_C2 // 先清bit位,配置高速晶振,high-gain operation,外部晶振 MCG->C2 &= ~(MCG_C2_RANGE0_MASK | MCG_C2_HGO0_MASK | MCG_C2_EREFS0_MASK); MCG->C2 |= (MCG_C2_RANGE0(1) | (0 << MCG_C2_HGO0_SHIFT) | (0 << MCG_C2_EREFS0_SHIFT)); // 配置控制寄存器MCG_C1 //先清bit位,CLK为外部时钟,FRDIV为5时,配置分频为1024,即配置FLL处于 //31.25-39.0625 kHz 之间 MCG->C1 &= ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK); MCG->C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(5); while((MCG->S & MCG_S_IREFST_MASK)); //等待FLL时钟转为外部源 while(((MCG->S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2); // Now in FBE MCG->C6 |= MCG_C6_CME0_MASK; // start Configure PLL0 MCG->C5 &= ~MCG_C5_PLLREFSEL0_MASK; // ensure OSC0 MCG->C11 &= ~MCG_C11_PLLCS_MASK; // select PLL0 // Configure MCG_C5 MCG->C5 &= ~MCG_C5_PRDIV0_MASK; // clear settings MCG->C5 |= MCG_C5_PRDIV0(prdiv - 1); //set PLL ref divider // Configure MCG_C6 MCG->C6 &= ~MCG_C6_VDIV0_MASK; // clear settings MCG->C6 |= MCG_C6_PLLS_MASK | MCG_C6_VDIV0(vdiv - 16); // write new VDIV while(!(MCG->S & MCG_S_PLLST_MASK)); // wait for PLLST status bit to set while(!(MCG->S & MCG_S_LOCK0_MASK)); // Wait for LOCK bit to set // Use actual PLL settings to calculate PLL frequency prdiv = ((MCG->C5 & MCG_C5_PRDIV0_MASK) + 1); vdiv = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 16); // now in PBE MCG->C1 &= ~MCG_C1_CLKS_MASK; // 清CLKS,选择MCG_OUT源为PLL while(((MCG->S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3); // start Configure PLL1 if needed, for DDR,so, CLK = 100MHz #if (CN_CFG_DDR_USED == 1) // Configure MCG_C12 MCG->C11 &= ~MCG_C11_PLLREFSEL1_MASK; // Clear select bit to choose OSC0 MCG->C11 &= ~MCG_C11_PRDIV1_MASK; MCG->C11 |= MCG_C11_PRDIV1(5 - 1); MCG->C12 &= ~MCG_C12_VDIV1_MASK; // clear VDIV settings MCG->C12 |= MCG_C12_VDIV1(24 - 16); // write new VDIV and enable PLL // Now enable the PLL MCG->C11 |= MCG_C11_PLLCLKEN1_MASK; // Set PLLCLKEN2 to enable PLL1 while(!(MCG->S2 & MCG_S2_LOCK1_MASK)); // Wait for PLL1 locked #endif //MCGOUT equals PLL output frequency/2 return (((crystal_fre_hz / prdiv) * vdiv) / 2); }
void __pe_initialize_hardware(void) { /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/ /*** ### MK21FN1M0VMC12 "Cpu" init code ... ***/ /*** PE initialization code after reset ***/ /* Disable the WDOG module */ /* WDOG_UNLOCK: WDOGUNLOCK=0xC520 */ WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */ /* WDOG_UNLOCK: WDOGUNLOCK=0xD928 */ WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */ /* WDOG_STCTRLH: ??=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,??=0,??=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */ WDOG_STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) | WDOG_STCTRLH_WAITEN_MASK | WDOG_STCTRLH_STOPEN_MASK | WDOG_STCTRLH_ALLOWUPDATE_MASK | WDOG_STCTRLH_CLKSRC_MASK | 0x0100U; #if MQX_ENABLE_LOW_POWER /* Reset from LLWU wake up source */ if (_lpm_get_reset_source() == MQX_RESET_SOURCE_LLWU) { PMC_REGSC |= PMC_REGSC_ACKISO_MASK; } #endif /* SIM_SCGC6: RTC=1 */ SIM_SCGC6 |= SIM_SCGC6_RTC_MASK; if ((RTC_CR & RTC_CR_OSCE_MASK) == 0u) { /* Only if the OSCILLATOR is not already enabled */ /* RTC_CR: SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ RTC_CR &= (uint32_t)~(uint32_t)( RTC_CR_SC2P_MASK | RTC_CR_SC4P_MASK | RTC_CR_SC8P_MASK | RTC_CR_SC16P_MASK ); /* RTC_CR: OSCE=1 */ RTC_CR |= RTC_CR_OSCE_MASK; /* RTC_CR: CLKO=0 */ RTC_CR &= (uint32_t)~(uint32_t)(RTC_CR_CLKO_MASK); } /* System clock initialization */ /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=3,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV2(0x01) | SIM_CLKDIV1_OUTDIV3(0x03) | SIM_CLKDIV1_OUTDIV4(0x03); /* Set the system prescalers to safe value */ /* SIM_SCGC5: PORTD=1,PORTC=1,PORTA=1 */ SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTA_MASK; /* Enable clock gate for ports to enable pin routing */ /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=2,OUTDIV4=4,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV2(0x01) | SIM_CLKDIV1_OUTDIV3(0x02) | SIM_CLKDIV1_OUTDIV4(0x04); /* Update system prescalers */ /* SIM_CLKDIV2: USBDIV=0,USBFRAC=0 */ SIM_CLKDIV2 = (uint32_t)0x09UL; /* Update USB clock prescalers */ /* SIM_SOPT2: PLLFLLSEL=1 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; /* Select PLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=0 */ SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL(0x03)); /* System oscillator drives 32 kHz clock for various peripherals */ /* PORTA_PCR18: ISF=0,MUX=0 */ PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* PORTA_PCR19: ISF=0,MUX=0 */ PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* Switch to FBE Mode */ /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK); /* OSC_CR: ERCLKEN=1,??=0,EREFSTEN=1,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC_CR = (OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK); /* MCG_C7: OSCSEL=0 */ MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK); /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03)); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=1 */ MCG_C5 = MCG_C5_PRDIV0(0x01); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=6 */ MCG_C6 = MCG_C6_VDIV0(0x06); while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */ } while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ } while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } /* Switch to PBE Mode */ /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=6 */ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x06)); while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */ } /* Switch to PEE Mode */ /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03)); while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ } /*** End of PE initialization code after reset ***/ /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/ }
/*lint -esym(765,Cpu_Interrupt) Disable MISRA rule (8.10) checking for symbols (Cpu_Interrupt). */ void __init_hardware(void) { /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/ /*** ### MK22FX512VLQ12 "Cpu" init code ... ***/ /*** PE initialization code after reset ***/ SCB_VTOR = (uint32_t)(&__vect_table); /* Set the interrupt vector table position */ /* Disable the WDOG module */ /* WDOG_UNLOCK: WDOGUNLOCK=0xC520 */ WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */ /* WDOG_UNLOCK: WDOGUNLOCK=0xD928 */ WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */ /* WDOG_STCTRLH: ??=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,??=0,??=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */ WDOG_STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) | WDOG_STCTRLH_WAITEN_MASK | WDOG_STCTRLH_STOPEN_MASK | WDOG_STCTRLH_ALLOWUPDATE_MASK | WDOG_STCTRLH_CLKSRC_MASK | 0x0100U; /* System clock initialization */ /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=3,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV2(0x01) | SIM_CLKDIV1_OUTDIV3(0x03) | SIM_CLKDIV1_OUTDIV4(0x03); /* Set the system prescalers to safe value */ /* SIM_SCGC5: PORTE=1,PORTD=1,PORTB=1,PORTA=1 */ SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTA_MASK; /* Enable clock gate for ports to enable pin routing */ /* SIM_SCGC5: LPTMR=1 */ SIM_SCGC5 |= SIM_SCGC5_LPTMR_MASK; if ((PMC_REGSC & PMC_REGSC_ACKISO_MASK) != 0x0U) { /* PMC_REGSC: ACKISO=1 */ PMC_REGSC |= PMC_REGSC_ACKISO_MASK; /* Release IO pads after wakeup from VLLS mode. */ } /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=4,OUTDIV4=4,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV2(0x01) | SIM_CLKDIV1_OUTDIV3(0x04) | SIM_CLKDIV1_OUTDIV4(0x04); /* Update system prescalers */ /* SIM_SOPT2: PLLFLLSEL=1 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; /* Select PLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=3 */ SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */ /* PORTA_PCR18: ISF=0,MUX=0 */ PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* PORTA_PCR19: ISF=0,MUX=0 */ PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* Switch to FBE Mode */ /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK); /* OSC_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C7: OSCSEL=0 */ MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK); /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=1 */ MCG_C5 = MCG_C5_PRDIV0(0x01); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=6 */ MCG_C6 = MCG_C6_VDIV0(0x06); while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */ } while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ } while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } /* Switch to PBE Mode */ /* MCG_C1: CLKS=2,FRDIV=4,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x04) | MCG_C1_IRCLKEN_MASK); /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=6 */ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x06)); while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */ } /* Switch to PEE Mode */ /* MCG_C1: CLKS=0,FRDIV=4,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x04) | MCG_C1_IRCLKEN_MASK); while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ } /*** End of PE initialization code after reset ***/ /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/ }
/*! Sets up the clock for USB operation (out of RESET) *! *! MCGOUTCLK = 48MHz *! core/platform/system clock = PLL (48MHz), *! bus clock = PLL (48MHz), *! flash clock = PLL/2 (24MHz) *! *! Assumes 8 MHz external crystal *! *! Modes: FEI [FLL engaged internal] -> *! FBE [FLL bypassed external] -> *! PBE [PLL bypassed external] -> *! PEE [PLL engaged external] *! *! Refer 24.5.3.1 of K20 Family reference */ void initClock(void) { MCG_C7 = 0; // OSCSEL = 0 => Crystal Osc // Out of reset MCG is in FEI mode // Configure the Crystal Oscillator OSC0_CR = OSC_CR_SC16P_MASK; // 1. Switch from FEI (FLL engaged internal) to FBE (FLL bypassed external) // 1 a) Set up crystal MCG_C2 = // oscillator in low power mode (w/o Rf) MCG_C2_EREFS0_MASK | // because crystal is being used MCG_C2_RANGE0(1) | // 4 or 8 MHz is in high frequency range MCG_C2_IRCS_MASK; // 1 b) Select clock mode MCG_C1 = MCG_C1_CLKS(2) | // CLKS = 10 -> External reference clock MCG_C1_FRDIV(FRDIV_VALUE) | // FRDIV = 2,3 -> 8MHz,4MHz/256 = 31.25 kHz MCG_C1_IRCLKEN_MASK; // IRCLKEN = 1 -> MCGIRCLK active // Make sure - reset default MCG_C4 &= ~(MCG_C4_DMX32_MASK|MCG_C4_DRST_DRS_MASK); // 1 c) Wait for crystal to start up while ((MCG_S & MCG_S_OSCINIT0_MASK) == 0) { } // 1 d) Wait for mode change while ((MCG_S & MCG_S_IREFST_MASK) != 0) { } // 1 e) Wait for MCGOUT indicating that the external reference to be fed to MCGOUT while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) { } // 2. Configure PLL Ref. Freq. // 2 a) Set PRDIV for correct range MCG_C5 = MCG_C5_PLLCLKEN0_MASK | MCG_C5_PRDIV0(PRDIV_VALUE); // PRDIV=3,1, PLL Ref Freq. = 8MHz,4MHz/4 => 2 MHz MCG_C6 = 0; // 3. FBE => BLPE => PBE // 3 a) BLPE MCG_C2 = // oscillator in low power mode (w/o external Rf) MCG_C2_EREFS0_MASK | // because crystal is being used MCG_C2_RANGE0(1) | // 4 or 8 MHz is in high frequency range MCG_C2_IRCS_MASK ; // 3 b) BLPE/PBE MCG_C6 = MCG_C6_PLLS_MASK|MCG_C6_VDIV0(0); // 2MHz x 24 = 96MHz // 3 c) BPE MCG_C2 = // oscillator in low power mode (w/o Rf) MCG_C2_EREFS0_MASK | // because crystal is being used MCG_C2_RANGE0(1) | // 4 or 8 MHz is in high frequency range MCG_C2_IRCS_MASK; // 3 d) Wait until PLLS clock source changes to the PLL while((MCG_S & MCG_S_PLLST_MASK) == 0) { } // 3 e) Wait for PLL to acquired lock while((MCG_S & MCG_S_LOCK0_MASK) == 0) { } // Set up the SIM clock dividers BEFORE switching to the PLL to ensure the // system clock speeds are in spec. #if 1 || (CPU == MK20D5) { // Disable Flash pre-fetch while changing flash divider uint32_t temp = FMC_PFAPR; FMC_PFAPR |= FMC_PFAPR_M3AP_MASK|FMC_PFAPR_M2AP_MASK|FMC_PFAPR_M1AP_MASK|FMC_PFAPR_M0AP_MASK; // core/platform/system clock = PLL (48MHz), bus clock = PLL (48MHz), flash clock = PLL/2 (24MHz) SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(1); FMC_PFAPR = temp; } #elif CPU == MKL25Z4 { // Disable Flash pre-fetch while changing flash divider uint32_t temp = FMC_PFAPR; FMC_PFAPR |= FMC_PFAPR_M3AP_MASK|FMC_PFAPR_M2AP_MASK|FMC_PFAPR_M1AP_MASK|FMC_PFAPR_M0AP_MASK; // core/platform/system clock = PLL/2 (48MHz), bus clock/flash clock = PLL/2/2 (24MHz) SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV4(1); FMC_PFAPR = temp; } #endif // 4. PBE mode transitions into PEE mode: // 4 a) Select clock mode MCG_C1 = MCG_C1_CLKS(0) | // CLKS = 0 -> FLL or PLL is selected MCG_C1_FRDIV(FRDIV_VALUE) | // FRDIV = 2,3 -> 8MHz,4MHz/256 = 31.25 kHz MCG_C1_IRCLKEN_MASK; // 4 b) Wait for clock stable while ((MCG_S & MCG_S_CLKST_MASK) != (3<<MCG_S_CLKST_SHIFT)) { } // Now MCGOUTCLK=MCGPLLCLK=[(2 MHz / 1) * 24] = 48 MHz // Basic clock selection #if 1 || (CPU == MK20D5) // Peripheral clock choice (incl. USB), USBCLK = MCGCLK SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK | // PLL rather than FLL for peripheral clock SIM_SOPT2_USBSRC_MASK; // MCGPLLCLK Source as USB clock (48MHz req.) // USB Clock = Divider input clock x [(USBFRAC+1)/(USBDIV+1)] // USBDIV 0-7, USBFRAC 0-1 // SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(0); #elif CPU == MKL25Z4 SIM_SOPT2 = SIM_SOPT2_UART0SRC(1) | // MCGPLLCLK/2 as UART0 clock SIM_SOPT2_TPMSRC(1) | // MCGPLLCLK/2 as TPM clock SIM_SOPT2_PLLFLLSEL_MASK | // PLL rather than FLL for peripheral clock SIM_SOPT2_USBSRC_MASK; // MCGPLLCLK/2 Source as USB clock (48MHz req.) #else #error "CPU not set" #endif }