/***************************************************************************** * @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
/*! * @brief 时钟分频设置函数 * @param outdiv1 内核分频系数, core clk = MCG / (outdiv1 +1) * @param outdiv2 bus分频系数, bus clk = MCG / (outdiv2 +1) * @param outdiv3 flexbus分频系数, flexbus clk = MCG / (outdiv3 +1) * @param outdiv4 flash分频系数, flash clk = MCG / (outdiv4 +1) * @since v1.0 * @author 飞思卡尔公司 * Sample usage: set_sys_dividers(0,1, 9,3); // core clk = MCG ; bus clk = MCG / 2 ; flexbus clk = MCG /10 ; flash clk = MCG / 4; */ __RAMFUNC void set_sys_dividers(uint32 outdiv1, uint32 outdiv2, uint32 outdiv3, uint32 outdiv4) { /* * This routine must be placed in RAM. It is a workaround for errata e2448. * Flash prefetch must be disabled when the flash clock divider is changed. * This cannot be performed while executing out of flash. * There must be a short delay after the clock dividers are changed before prefetch * can be re-enabled. */ uint32 temp_reg; uint8 i; temp_reg = FMC_PFAPR; // store present value of FMC_PFAPR // set M0PFD through M7PFD to 1 to disable prefetch FMC_PFAPR |= FMC_PFAPR_M7PFD_MASK | FMC_PFAPR_M6PFD_MASK | FMC_PFAPR_M5PFD_MASK | FMC_PFAPR_M4PFD_MASK | FMC_PFAPR_M3PFD_MASK | FMC_PFAPR_M2PFD_MASK | FMC_PFAPR_M1PFD_MASK | FMC_PFAPR_M0PFD_MASK; // set clock dividers to desired value SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV2(outdiv2) | SIM_CLKDIV1_OUTDIV3(outdiv3) | SIM_CLKDIV1_OUTDIV4(outdiv4); // wait for dividers to change for (i = 0 ; i < outdiv4 ; i++) {} FMC_PFAPR = temp_reg; // re-store original value of FMC_PFAPR return; } // set_sys_dividers
void __ramfunc__ kinesis_setdividers(uint32_t div1, uint32_t div2, uint32_t div3, uint32_t div4) { uint32_t regval; int i; /* Save the current value of the Flash Access Protection Register */ regval = getreg32(KINETIS_FMC_PFAPR); /* Set M0PFD through M7PFD to 1 to disable prefetch */ putreg32(FMC_PFAPR_M7PFD | FMC_PFAPR_M6PFD | FMC_PFAPR_M5PFD | FMC_PFAPR_M4PFD | FMC_PFAPR_M3PFD | FMC_PFAPR_M2PFD | FMC_PFAPR_M1PFD | FMC_PFAPR_M0PFD, KINETIS_FMC_PFAPR); /* Set clock dividers to desired value */ putreg32(SIM_CLKDIV1_OUTDIV1(div1) | SIM_CLKDIV1_OUTDIV2(div2) | SIM_CLKDIV1_OUTDIV3(div3) | SIM_CLKDIV1_OUTDIV4(div4), KINETIS_SIM_CLKDIV1); /* Wait for dividers to change */ for (i = 0 ; i < div4 ; i++); /* Re-store the saved value of FMC_PFAPR */ putreg32(regval, KINETIS_FMC_PFAPR); }
void InitClock() { // If the internal load capacitors are being used, they should be selected // before enabling the oscillator. Application specific. 16pF and 8pF selected // in this example OSC_CR = OSC_CR_SC16P_MASK | OSC_CR_SC8P_MASK; // Enabling the oscillator for 8 MHz crystal // RANGE=1, should be set to match the 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; // Select ext oscillator, reference divider and clear IREFS to start ext osc // 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) 8 MHz / 256 = 31.25 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); // wait for oscillator to initialize while (!(MCG_S & MCG_S_OSCINIT_MASK)){} // wait for Reference clock to switch to external reference while (MCG_S & MCG_S_IREFST_MASK){} // Wait for MCGOUT to switch over to the external reference clock while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){} // Now configure the PLL and move to PBE mode // set the PRDIV field to generate a 4MHz reference clock (8MHz /2) MCG_C5 = MCG_C5_PRDIV(1); // PRDIV=1 selects a divide by 2 // set the VDIV field to 0, which is x24, giving 4 x 24 = 96 MHz // the PLLS bit is set to enable the PLL // the clock monitor is enabled, CME=1 to cause a reset if crystal fails // LOLIE can be optionally set to enable the loss of lock interrupt MCG_C6 = MCG_C6_CME_MASK | MCG_C6_PLLS_MASK; // wait until the source of the PLLS clock has switched to the PLL while (!(MCG_S & MCG_S_PLLST_MASK)){} // wait until the PLL has achieved lock while (!(MCG_S & MCG_S_LOCK_MASK)){} // set up the SIM clock dividers BEFORE switching to the PLL to ensure the // system clock speeds are in spec. // core = PLL (96MHz), bus = PLL/2 (48MHz), flexbus = PLL/2 (48MHz), flash = PLL/4 (24MHz) SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV3(1) | SIM_CLKDIV1_OUTDIV4(3); // Transition into PEE by setting CLKS to 0 // previous MCG_C1 settings remain the same, just need to set CLKS to 0 MCG_C1 &= ~MCG_C1_CLKS_MASK; // Wait for MCGOUT to switch over to the PLL while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 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. SIM_CLKDIV2 |= SIM_CLKDIV2_USBDIV(1); // sets USB divider to /2 assuming reset // state of the SIM_CLKDIV2 register }
// Private functions static void hw_mcg_init(void) { /* Adjust clock dividers (core/system=div/1, bus=div/2, flex bus=div/2, flash=div/4) */ SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(SYS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV2(BUS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV3(BUS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV4(FLASH_CLK_DIV-1); /* Configure FEI internal clock speed */ MCG->C4 = (SYS_CLK_DMX | SYS_CLK_DRS); while((MCG->C4 & (MCG_C4_DRST_DRS_MASK | MCG_C4_DMX32_MASK)) != (SYS_CLK_DMX | SYS_CLK_DRS)); }
//----------------------------------------------------------------------------- // FUNCTION: boot_init_clock // SCOPE: Bootloader application system function // DESCRIPTION: Init the sytem clock. Here it uses PEE with external 8M crystal, Core clock = 48MHz, Bus clock = 24MHz //----------------------------------------------------------------------------- void Boot_Init_Clock() { SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV2(0x01) | SIM_CLKDIV1_OUTDIV3(0x04) | SIM_CLKDIV1_OUTDIV4(0x04); /* Set the system prescalers to safe value */ SIM_SCGC5 |= (uint32_t)SIM_SCGC5_PORTA_MASK; /* Enable EXTAL/XTAL pins clock gate */ PORTA_PCR18 &= (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07) ); /* Is external crystal/resonator used in targeted clock configuration? */ /* If yes, initialize also XTAL pin routing */ /* PORTA_PCR19: ISF=0,MUX=0 */ PORTA_PCR19 &= (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07) ); MCG_C2 = 0xa4; OSC_CR = 0x00; /* Set OSC_CR (OSCERCLK enable, oscillator capacitor load) */ MCG_C7 = 0x00; /* Select MCG OSC clock source */ MCG_C1 = 0x98; /* Set C1 (clock source selection, FLL ext. reference divider, int. reference enable etc.) */ 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. */ } MCG_C4 = 0x17; /* Set C4 (FLL output; trim values not changed) */ MCG_C5 = 0x00; /* Set C5 (PLL settings, PLL reference divider etc.) */ MCG_C6 = 0x00; /* Set C6 (PLL select, VCO divider etc.) */ while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } OSC_CR = 0x80; /* Set OSC_CR (OSCERCLK enable, oscillator capacitor load) */ MCG_C7 = 0x00; /* Select MCG OSC clock source */ MCG_C1 = 0x9a; /* Set C1 (clock source selection, FLL ext. reference divider, int. reference enable etc.) */ MCG_C2 = 0x24; /* Set C2 (freq. range, ext. and int. reference selection etc.; trim values not changed) */ MCG_C5 = 0x23; /* Set C5 (PLL settings, PLL reference divider etc.) */ MCG_C6 = 0x40; /* Set C6 (PLL select, VCO divider etc.) */ while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until PLL is locked*/ } while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } OSC_CR = 0x80; /* Set OSC_CR (OSCERCLK enable, oscillator capacitor load) */ MCG_C7 = 0x00; /* Select MCG OSC clock source */ MCG_C1 = 0x1a; MCG_C5 = 0x23; MCG_C6 = 0x40; while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until PLL is locked*/ } while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ } //while (NextMode != (TargetMode & CPU_MCG_MODE_INDEX_MASK)); /* Loop until the target MCG mode is set */ // SIM_CLKDIV1 = 0x11100000; // SIM_SOPT1 = 0x800C9010; // SIM_SOPT2 = 0x00011000; }
static void hw_mcg_init(void) { #ifdef FREESCALE_KSDK_BM BOARD_BootClockHSRUN(); #else /* Adjust clock dividers (core/system=div/1, bus=div/2, flex bus=div/2, flash=div/4) */ SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(SYS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV2(BUS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV3(BUS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV4(FLASH_CLK_DIV-1); /* Configure FEI internal clock speed */ MCG->C4 = (SYS_CLK_DMX | SYS_CLK_DRS); while((MCG->C4 & (MCG_C4_DRST_DRS_MASK | MCG_C4_DMX32_MASK)) != (SYS_CLK_DMX | SYS_CLK_DRS)); #endif }
/*FUNCTION********************************************************************** * * Function Name : CLOCK_HAL_SetOutDiv * Description : Set all clock out dividers setting at the same time * This function will set the setting for all clock out dividers. * *END**************************************************************************/ void CLOCK_HAL_SetOutDiv(SIM_Type * base, uint8_t outdiv1, uint8_t outdiv2, uint8_t outdiv3, uint8_t outdiv4) { uint32_t clkdiv1 = 0; clkdiv1 |= SIM_CLKDIV1_OUTDIV1(outdiv1); clkdiv1 |= SIM_CLKDIV1_OUTDIV2(outdiv2); clkdiv1 |= SIM_CLKDIV1_OUTDIV4(outdiv4); SIM_WR_CLKDIV1(base, clkdiv1); }
/** * initialize PDB 0 hardware * * count is the number of 1/16384 second time periods * continuous is a boolean value which determines if the counter will work in one-shot or * continuous mode */ void PDB0Init(uint16_t count, int continuous) { /* Enable the clock for PDB0 (PDBTimer 0) using the SIM_SCGC6 register * (System Clock Gating Control Register 6) (See 12.2.14 on page 344 of * the K70 Sub-Family Reference Manual, Rev. 2, Dec 2011) */ SIM_SCGC6 |= SIM_SCGC6_PDB_MASK; /* Disable PDBTimer 0 and clear any pending PDB Interrupt Flag using * the PDB0_SC register (Status and Control register for PDBTimer 0) * (See 43.3.1 on page 1199 of the K70 Sub-Family Reference Manual, * Rev. 2, Dec 2011) */ PDB0_SC = 0; /* With the MCGOUTCLK = FLL_Factor*IRC (which is 32768*640), and with the * peripheral clock divider set to 10, we end up with a peripheral clock of * 2,097,152 Hz. Setting the prescaler to divide by 128 yields a counter * frequency of 16384 Hz */ /* Set the Clock 2 (peripheral clock) output divider value to 10 using * the SIM_CLKDIV1 register (System Clock Divider Register 1) * (See 12.2.16 on page 347 of the K70 Sub-Family Reference Manual, * Rev. 2, Dec 2011) */ SIM_CLKDIV1 = (SIM_CLKDIV1 & ~SIM_CLKDIV1_OUTDIV2_MASK) | SIM_CLKDIV1_OUTDIV2(SIM_CLKDIV1_OUTDIV_DIVIDE_BY_10); /* Load timer count (16-bit value) into the modulo register */ PDB0_MOD = count; /* Load timer count (16-bit value) into the interrupt delay register */ PDB0_IDLY = count; /* Prescaler to divide by 128, Software trigger is selected, * PDB interrupt enabled, Multiplication factor is 1, * Continuous mode, Load OK, Enable the PDB */ PDB0_SC = PDB_SC_PRESCALER(PDB_SC_PRESCALER_DIVIDE_BY_128) | PDB_SC_TRGSEL(PDB_SC_TRGSEL_SOFTWARE_TRIGGER) | PDB_SC_PDBIE_MASK | PDB_SC_MULT(PDB_SC_MULT_BY_1) | (continuous ? PDB_SC_CONT_MASK : 0) | PDB_SC_LDOK_MASK | PDB_SC_PDBEN_MASK; /* Set the counter value (16-bit value) in the counter register */ PDB0_CNT = 0; /* Enable interrupts from PDB0 and set its interrupt priority */ NVICEnableIRQ(PDB0_IRQ_NUMBER, PDB0_INTERRUPT_PRIORITY); }
/** PLL initialization. */ static void pll_init(void) { // First move to FBE mode // Enable external oscillator, RANGE=0, HGO=, EREFS=, LP=, IRCS= MCG_C2 = 0; // Select external oscilator 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); while (MCG_S & MCG_S_IREFST_MASK); // wait for Reference clock Status bit to clear while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2); // Wait for clock status bits to show clock source is ext ref clk // ... FBE mode // Configure PLL Ref Divider, PLLCLKEN=0, PLLSTEN=0, PRDIV=0x18 // The crystal frequency is used to select the PRDIV value. Only even frequency crystals are supported // that will produce a 2MHz reference clock to the PLL. MCG_C5 = MCG_C5_PRDIV(REF_CLOCK_DIV - 1); // Ensure MCG_C6 is at the reset default of 0. LOLIE disabled, PLL disabled, clk monitor disabled, PLL VCO divider is clear MCG_C6 = 0; // Set system options dividers SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(CORE_DIV - 1) | // core/system clock SIM_CLKDIV1_OUTDIV2(BUS_DIV - 1) | // peripheral clock SIM_CLKDIV1_OUTDIV3(FLEXBUS_DIV - 1) | // FlexBus clock driven to the external pin (FB_CLK). SIM_CLKDIV1_OUTDIV4(FLASH_DIV - 1); // flash clock // Set the VCO divider and enable the PLL, LOLIE = 0, PLLS = 1, CME = 0, VDIV = MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(PLL_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_LOCK_MASK)); // Wait for LOCK bit to set // ...running PBE mode // 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); // ...running PEE mode }
static inline void set_safe_clock_dividers(void) { /* * We want to achieve the following clocks: * Core/system: <100MHz * Bus: <50MHz * FlexBus: <50MHz * Flash: <25MHz * * using dividers 1-2-2-4 will obey the above limits when using a 96MHz FLL source. */ SIM->CLKDIV1 = ( SIM_CLKDIV1_OUTDIV1(CONFIG_CLOCK_K60_SYS_DIV) | /* Core/System clock divider */ SIM_CLKDIV1_OUTDIV2(CONFIG_CLOCK_K60_BUS_DIV) | /* Bus clock divider */ SIM_CLKDIV1_OUTDIV3(CONFIG_CLOCK_K60_FB_DIV) | /* FlexBus divider, not used in Mulle */ SIM_CLKDIV1_OUTDIV4(CONFIG_CLOCK_K60_FLASH_DIV)); /* Flash clock divider */ }
// ============================================================================= // 功能:系统时钟初始化,从系统上电使用FEI到切换到使用外部的50M时钟合为时钟源,并经过 // PLL分频和倍频,使内核时钟为120M,bus时钟为2分频,FlexBus3分频,Flash6分频, // 各个模块(如portA~E)的时钟各自使用时配置,此处只配置系统时钟 // 参数:无 // 返回:无 // ============================================================================= void SysClockInit(void) { //初始化端口时钟,在系统初始化时全部打开 SIM->SCGC5 |= (SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK | SIM_SCGC5_PORTF_MASK ); //初始化PLL前,先初始化系统时钟分步器,分别用于配置 //core/system时钟、bus时钟、FlexBus时钟、Flash时钟 SIM->CLKDIV1 = ( 0 | SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV3(2) | SIM_CLKDIV1_OUTDIV4(5) ); //系统的PLL时钟分频配置,用于生成MCGOUTCLK = 120M //对于50M的crystal,分频为5,PLL倍频为24,则主时钟计算公式为: //MCGOUTCLK = ((50M/5) * 24)/2 = 120M PLL_Init(CLK0_FREQ_HZ,PLL0_PRDIV,PLL0_VDIV); }
/* * LPLD_Set_SYS_DIV * 设置系统始终分频 * * 说明: * 这段代码必须放置在RAM中,目的是防止程序跑飞,详见官方文档errata e2448. * 当Flash时钟分频改变的时候,Flash预读取必须禁用. * 禁止从Flash中运行以下代码. * 在预读取被重新使能之前必须在时钟分频改变后有一段小的延时. * * 参数: * outdiv1~outdiv4--分别为core, bus, FlexBus, Flash时钟分频系数 */ __ramfunc void LPLD_Set_SYS_DIV(uint32 outdiv1, uint32 outdiv2, uint32 outdiv3, uint32 outdiv4) { uint32 temp_reg; uint8 i; temp_reg = FMC->PFAPR; // 备份 FMC_PFAPR 寄存器 // 设置 M0PFD 到 M7PFD 为 1 禁用预先读取 FMC->PFAPR |= FMC_PFAPR_M7PFD_MASK | FMC_PFAPR_M6PFD_MASK | FMC_PFAPR_M5PFD_MASK | FMC_PFAPR_M4PFD_MASK | FMC_PFAPR_M3PFD_MASK | FMC_PFAPR_M2PFD_MASK | FMC_PFAPR_M1PFD_MASK | FMC_PFAPR_M0PFD_MASK; // 设置时钟分频为期望值 SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV2(outdiv2) | SIM_CLKDIV1_OUTDIV3(outdiv3) | SIM_CLKDIV1_OUTDIV4(outdiv4); // 延时一小段时间等待改变 for (i = 0 ; i < outdiv4 ; i++) {} FMC->PFAPR = temp_reg; // 回复原先的 FMC_PFAPR 寄存器值 return; } // set_sys_dividers
/* ** =================================================================== ** Method : Cpu_SetClockConfiguration (component MK22FN512VDC12) ** ** Description : ** Calling of this method will cause the clock configuration ** change and reconfiguration of all components according to ** the requested clock configuration setting. ** Parameters : ** NAME - DESCRIPTION ** ModeID - Clock configuration identifier ** Returns : ** --- - ERR_OK - OK. ** ERR_RANGE - Mode parameter out of range ** =================================================================== */ LDD_TError Cpu_SetClockConfiguration(LDD_TClockConfiguration ModeID) { if (ModeID > 0x03U) { return ERR_RANGE; /* Undefined clock configuration requested requested */ } if (0x03U == ClockConfigurationID) { if ((CPU_CLOCK_CONFIG_1 == ModeID) || ( CPU_CLOCK_CONFIG_2 == ModeID)) return ERR_FAILED; Cpu_SetMCGClockInModePEE(ModeID); } if (0x03U == ModeID) { if ((CPU_CLOCK_CONFIG_1 == ClockConfigurationID) || ( CPU_CLOCK_CONFIG_2 == ClockConfigurationID)) return ERR_FAILED; Cpu_SetMCGClockInModePEE(ModeID); } switch (ModeID) { case CPU_CLOCK_CONFIG_0: if (ClockConfigurationID == 2U) { /* Clock configuration 0 and clock configuration 2 use different clock configuration */ /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=4,OUTDIV4=4,??=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); /* Set the system prescalers to safe value */ Cpu_SetMCG(0U); /* Update clock source setting */ } /* 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(0x03) | SIM_CLKDIV1_OUTDIV4(0x02); /* Update system prescalers */ #if (BSPCFG_USB_CLK_FROM_IRC48M) SIM_CLKDIV2 = 0; SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(0x03); SIM_SCGC4 |= (SIM_SCGC4_USBOTG_MASK); /* Enable IRC 48MHz for USB module */ USB_CLK_RECOVER_IRC_EN = 0x03; #else /* SIM_CLKDIV2: USBDIV=4,USBFRAC=1 */ SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(0x4) | SIM_CLKDIV2_USBFRAC_MASK; /* Update USB clock prescalers */ /* SIM_SOPT2: PLLFLLSEL=0x01 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(0x01); /* Select PLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=0 */ #endif SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL(0x03)); /* System oscillator drives 32 kHz clock for various peripherals */ break; case CPU_CLOCK_CONFIG_1: if (ClockConfigurationID == 2U) { /* Clock configuration 1 and clock configuration 2 use different clock configuration */ /* 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); /* Set the system prescalers to safe value */ Cpu_SetMCG(0U); /* Update clock source setting */ } /* SIM_CLKDIV1: OUTDIV1=9,OUTDIV2=9,OUTDIV3=9,OUTDIV4=9,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x09) | SIM_CLKDIV1_OUTDIV2(0x09) | SIM_CLKDIV1_OUTDIV3(0x09) | SIM_CLKDIV1_OUTDIV4(0x09); /* Update system prescalers */ /* SIM_CLKDIV2: USBDIV=4,USBFRAC=1 */ SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(0x4) | SIM_CLKDIV2_USBFRAC_MASK; /* SIM_SOPT2: PLLFLLSEL=0x01 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(0x01); /* SIM_SOPT1: OSC32KSEL=0 */ SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL(0x03)); /* System oscillator drives 32 kHz clock for various peripherals */ break; case CPU_CLOCK_CONFIG_2: /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=4,OUTDIV4=4,??=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); /* Set the system prescalers to safe value */ if ((MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U) { /* MCG_SC: FCRDIV=1 */ MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)( MCG_SC_FCRDIV(0x06) )) | (uint8_t)( MCG_SC_FCRDIV(0x01) )); } else { /* MCG_C2: IRCS=0 */ MCG_C2 &= (uint8_t)~(uint8_t)(MCG_C2_IRCS_MASK); while((MCG_S & MCG_S_IRCST_MASK) != 0x00U) { /* Check that the source internal reference clock is slow clock. */ } /* MCG_SC: FCRDIV=1 */ MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)( MCG_SC_FCRDIV(0x06) )) | (uint8_t)( MCG_SC_FCRDIV(0x01) )); /* MCG_C2: IRCS=1 */ MCG_C2 |= MCG_C2_IRCS_MASK; while((MCG_S & MCG_S_IRCST_MASK) == 0x00U) { /* Check that the source internal reference clock is fast clock. */ } } Cpu_SetMCG(1U); /* Update clock source setting */ /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=0,OUTDIV3=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_OUTDIV2(0x00) | SIM_CLKDIV1_OUTDIV3(0x00) | SIM_CLKDIV1_OUTDIV4(0x03); /* Update system prescalers */ /* SIM_CLKDIV2: USBDIV=4,USBFRAC=1 */ SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(0x4) | SIM_CLKDIV2_USBFRAC_MASK; /* SIM_SOPT2: PLLFLLSEL=1 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(0x01); /* 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 */ break; case CPU_CLOCK_CONFIG_3: /* 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 */ #if (BSPCFG_USB_CLK_FROM_IRC48M) SIM_CLKDIV2 = 0; SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(0x03); SIM_SCGC4 |= (SIM_SCGC4_USBOTG_MASK); /* Enable IRC 48MHz for USB module */ USB_CLK_RECOVER_IRC_EN = 0x03; #else /* SIM_CLKDIV2: USBDIV=4,USBFRAC=1 */ SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(0x4) | SIM_CLKDIV2_USBFRAC_MASK; /* SIM_SOPT2: PLLFLLSEL=1 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(0x01); /* Select PLL as a clock source for various peripherals */ #endif /* SIM_SOPT1: OSC32KSEL=0 */ SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL(0x03)); /* System oscillator drives 32 kHz clock for various peripherals */ break; default: break; } LDD_SetClockConfiguration(ModeID); /* Call all LDD components to update the clock configuration */ ClockConfigurationID = ModeID; /* Store clock configuration identifier */ return ERR_OK; }
//锁相环频率为60M测试函数 void pllinit60M(void) { uint32_t temp_reg; //使能IO端口时钟 SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK ); //这里处在默认的FEI模式 //首先移动到FBE模式 MCG_C2 = 0; //MCG_C2 = MCG_C2_RANGE(2) | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK; //初始化晶振后释放锁定状态的振荡器和GPIO SIM_SCGC4 |= SIM_SCGC4_LLWU_MASK; LLWU_CS |= LLWU_CS_ACKISO_MASK; //选择外部晶振,参考分频器,清IREFS来启动外部晶振 //011 If RANGE = 0, Divide Factor is 8; for all other RANGE values, Divide Factor is 256. MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3); //等待晶振稳定 //while (!(MCG_S & MCG_S_OSCINIT_MASK)){} //等待锁相环初始化结束 while (MCG_S & MCG_S_IREFST_MASK){} //等待时钟切换到外部参考时钟 while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){} //进入FBE模式, //0x18==25分频=2M, //0x11==18分频=2.7778M //0x12==19分频=2.63M, //0x13==20分频=2.5M MCG_C5 = MCG_C5_PRDIV(0x18); //确保MCG_C6处于复位状态,禁止LOLIE、PLL、和时钟控制器,清PLL VCO分频器 MCG_C6 = 0x0; //保存FMC_PFAPR当前的值 temp_reg = FMC_PFAPR; //通过M&PFD置位M0PFD来禁止预取功能 FMC_PFAPR |= FMC_PFAPR_M7PFD_MASK | FMC_PFAPR_M6PFD_MASK | FMC_PFAPR_M5PFD_MASK | FMC_PFAPR_M4PFD_MASK | FMC_PFAPR_M3PFD_MASK | FMC_PFAPR_M2PFD_MASK | FMC_PFAPR_M1PFD_MASK | FMC_PFAPR_M0PFD_MASK; ///设置系统分频器 //MCG=PLL, core = MCG, bus = MCG/2, FlexBus = MCG/2, Flash clock= MCG/4 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV3(1) | SIM_CLKDIV1_OUTDIV4(3); //从新存FMC_PFAPR的原始值 FMC_PFAPR = temp_reg; //设置VCO分频器,使能PLL为100MHz, LOLIE=0, PLLS=1, CME=0, VDIV=26 MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(6); //VDIV = 31 (x55) //VDIV = 26 (x50) //VDIV = 6 (x30) while (!(MCG_S & MCG_S_PLLST_MASK)){}; // wait for PLL status bit to set while (!(MCG_S & MCG_S_LOCK_MASK)){}; // Wait for LOCK bit to set //进入PBE模式 //通过清零CLKS位来进入PEE模式 // CLKS=0, FRDIV=3, IREFS=0, IRCLKEN=0, IREFSTEN=0 MCG_C1 &= ~MCG_C1_CLKS_MASK; //等待时钟状态位更新 while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3){}; //SIM_CLKDIV2 |= SIM_CLKDIV2_USBDIV(1); //设置跟踪时钟为内核时钟 SIM_SOPT2 |= SIM_SOPT2_TRACECLKSEL_MASK; //在PTA6引脚上使能TRACE_CLKOU功能 PORTA_PCR6 = ( PORT_PCR_MUX(0x7)); //使能FlexBus模块时钟 SIM_SCGC7 |= SIM_SCGC7_FLEXBUS_MASK; //在PTA6引脚上使能FB_CLKOUT功能 PORTC_PCR3 = ( PORT_PCR_MUX(0x5)); }
/*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. !!! ***/ }
/*! Sets up the clock out of RESET *! */ void clock_initialise(void) { #if (CLOCK_MODE == CLOCK_MODE_RESET) // No clock setup #else // XTAL/EXTAL Pins SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; PORTA_PCR3 = PORT_PCR_MUX(0); PORTA_PCR4 = PORT_PCR_MUX(0); // Configure the Crystal Oscillator OSC0_CR = OSC_CR_ERCLKEN_M|OSC_CR_EREFSTEN_M|OSC_CR_SCP_M; // Fast Internal Clock divider MCG_SC = MCG_SC_FCRDIV_M; // Out of reset MCG is in FEI mode // ============================================================= SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(7) | SIM_CLKDIV1_OUTDIV3(3) | SIM_CLKDIV1_OUTDIV4(7); // Switch from FEI -> FEI/FBI/FEE/FBE // ============================================================= // Set up crystal or external clock source MCG_C2 = MCG_C2_LOCRE0_M | // LOCRE0 = 0,1 -> Loss of clock reset MCG_C2_RANGE0_M | // RANGE0 = 0,1,2 -> Oscillator low/high/very high clock range MCG_C2_HGO0_M | // HGO0 = 0,1 -> Oscillator low power/high gain MCG_C2_EREFS0_M | // EREFS0 = 0,1 -> Select external clock/crystal oscillator MCG_C2_IRCS_M; // IRCS = 0,1 -> Select slow/fast internal clock for internal reference #if ((CLOCK_MODE == CLOCK_MODE_FEI) || (CLOCK_MODE == CLOCK_MODE_FBI) || (CLOCK_MODE == CLOCK_MODE_BLPI) ) // Transition via FBI //===================================== #define BYPASS (1) // CLKS value used while FLL locks MCG_C1 = MCG_C1_CLKS(BYPASS) | // CLKS = 2 -> External reference source while PLL locks MCG_C1_FRDIV_M | // FRDIV = N -> XTAL/2^n ~ 31.25 kHz MCG_C1_IREFS_M | // IREFS = 0,1 -> External/Slow IRC for FLL source MCG_C1_IRCLKEN_M | // IRCLKEN = 0,1 -> IRCLK disable/enable MCG_C1_IREFSTEN_M; // IREFSTEN = 0,1 -> Internal reference enabled in STOP mode // Wait for S_IREFST to indicate FLL Reference has switched do { __asm__("nop"); } while ((MCG_S & MCG_S_IREFST_MASK) != (MCG_C1_IREFS_V<<MCG_S_IREFST_SHIFT)); // Wait for S_CLKST to indicating that OUTCLK has switched to bypass PLL/FLL do { __asm__("nop"); } while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(BYPASS)); // Set FLL Parameters MCG_C4 = (MCG_C4&~(MCG_C4_DMX32_MASK|MCG_C4_DRST_DRS_MASK))|MCG_C4_DMX32_M|MCG_C4_DRST_DRS_M; #endif #if ((CLOCK_MODE == CLOCK_MODE_FBE) || (CLOCK_MODE == CLOCK_MODE_FEE) || (CLOCK_MODE == CLOCK_MODE_PLBE) || (CLOCK_MODE == CLOCK_MODE_PBE) || (CLOCK_MODE == CLOCK_MODE_PEE)) // Transition via FBE //===================================== #define BYPASS (2) // CLKS value used while PLL locks MCG_C1 = MCG_C1_CLKS(BYPASS) | // CLKS = 2 -> External reference source while PLL locks MCG_C1_FRDIV_M | // FRDIV = N -> XTAL/2^n ~ 31.25 kHz MCG_C1_IREFS_M | // IREFS = 0,1 -> External/Slow IRC for FLL source MCG_C1_IRCLKEN_M | // IRCLKEN = 0,1 -> IRCLK disable/enable MCG_C1_IREFSTEN_M; // IREFSTEN = 0,1 -> Internal reference enabled in STOP mode #if (MCG_C2_EREFS_V != 0) // Wait for oscillator stable (if used) do { __asm__("nop"); } while ((MCG_S & MCG_S_OSCINIT0_MASK) == 0); #endif // Wait for S_IREFST to indicate FLL Reference has switched do { __asm__("nop"); } while ((MCG_S & MCG_S_IREFST_MASK) != (MCG_C1_IREFS_V<<MCG_S_IREFST_SHIFT)); // Wait for S_CLKST to indicating that OUTCLK has switched to bypass PLL/FLL do { __asm__("nop"); } while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(BYPASS)); // Set FLL Parameters MCG_C4 = (MCG_C4&~(MCG_C4_DMX32_MASK|MCG_C4_DRST_DRS_MASK))|MCG_C4_DMX32_M|MCG_C4_DRST_DRS_M; #endif // Select FEI/FBI/FEE/FBE clock mode MCG_C1 = MCG_C1_CLKS_M | // CLKS = 0,1,2 -> Select FLL/IRCSCLK/ERCLK MCG_C1_FRDIV_M | // FRDIV = N -> XTAL/2^n ~ 31.25 kHz MCG_C1_IREFS_M | // IREFS = 0,1 -> External/Slow IRC for FLL source MCG_C1_IRCLKEN_M | // IRCLKEN = 0,1 -> IRCLK disable/enable MCG_C1_IREFSTEN_M; // IREFSTEN = 0,1 -> Internal reference enabled in STOP mode // Wait for mode change do { __asm__("nop"); } while ((MCG_S & MCG_S_IREFST_MASK) != (MCG_C1_IREFS_V<<MCG_S_IREFST_SHIFT)); #if defined (MCG_C6_PLLS_V) && (MCG_C1_CLKS_V == 0) // FLL or PLL #define MCG_S_CLKST_M MCG_S_CLKST(MCG_C6_PLLS_V?3:0) #else #define MCG_S_CLKST_M MCG_S_CLKST(MCG_C1_CLKS_V) #endif // Wait for S_CLKST to indicating that OUTCLK has switched do { __asm__("nop"); } while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_M); // Set the SIM _CLKDIV dividers SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1_M | SIM_CLKDIV1_OUTDIV2_M | SIM_CLKDIV1_OUTDIV3_M | SIM_CLKDIV1_OUTDIV4_M; #if (CLOCK_MODE == CLOCK_MODE_BLPE) || (CLOCK_MODE == CLOCK_MODE_BLPI) // Select BLPE/BLPI clock mode MCG_C2 = MCG_C2_LOCRE0_M | // LOCRE0 = 0,1 -> Loss of clock reset MCG_C2_RANGE0_M | // RANGE0 = 0,1,2 -> Oscillator low/high/very high clock range MCG_C2_HGO0_M | // HGO0 = 0,1 -> Oscillator low power/high gain MCG_C2_EREFS0_M | // EREFS0 = 0,1 -> Select external clock/crystal oscillator MCG_C2_LP_M | // LP = 0,1 -> Select FLL enabled/disabled in bypass mode MCG_C2_IRCS_M; // IRCS = 0,1 -> Select slow/fast internal clock for internal reference #endif // (CLOCK_MODE == CLOCK_MODE_BLPE) || (CLOCK_MODE == CLOCK_MODE_BLPI) #endif // (CLOCK_MODE == CLOCK_MODE_RESET) // Basic clock multiplexing #if defined(MCU_MK20D5) || defined(MCU_MK20D7) || defined(MCU_MK40D10) || defined(MCU_MK40DZ10) // Peripheral clock choice (incl. USB), USBCLK = MCGCLK SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_M | // PLL rather than FLL for peripheral clock SIM_SOPT2_USBSRC_MASK; // MCGPLLCLK/2 Source as USB clock (48MHz req.) SIM_SOPT1 = (SIM_SOPT1&~SIM_SOPT1_OSC32KSEL_MASK)|SIM_SOPT1_OSC32KSEL_M; // ERCLK32K source #elif defined(MCU_MK60D10) || defined(MCU_MK60DZ10) // 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/2 Source as USB clock (48MHz req.) #elif defined(MCU_MKL24Z4) || defined(MCU_MKL25Z4) || defined(MCU_MKL26Z4) || defined(MCU_MKL46Z4) SIM_SOPT2 = SIM_SOPT2_UART0SRC_M | // UART0 clock - 0,1,2,3 -> Disabled, (MCGFLLCLK, MCGPLLCLK/2), OSCERCLK, MCGIRCLK SIM_SOPT2_TPMSRC_M | // TPM clock - 0,1,2,3 -> Disabled, (MCGFLLCLK, MCGPLLCLK/2), OSCERCLK, MCGIRCLK SIM_SOPT2_PLLFLLSEL_M | // Peripheral clock - 0,1 -> MCGFLLCLK,MCGPLLCLK/2 SIM_SOPT2_USBSRC_MASK; // MCGPLLCLK/2 Source as USB clock (48MHz req.) SIM_SOPT1 = (SIM_SOPT1&~SIM_SOPT1_OSC32KSEL_MASK)|SIM_SOPT1_OSC32KSEL_M; // ERCLK32K clock - 0,1,2,3 -> OSC32KCLK, - , RTC_CLKIN, LPO (1kHz) #elif defined(MCU_MKL14Z4) || defined(MCU_MKL15Z4) || defined(MCU_MKL16Z4) || defined(MCU_MKL34Z4) || defined(MCU_MKL36Z4) SIM_SOPT2 = SIM_SOPT2_UART0SRC_M | // UART0 clock - 0,1,2,3 -> Disabled, (MCGFLLCLK, MCGPLLCLK/2), OSCERCLK, MCGIRCLK SIM_SOPT2_TPMSRC_M | // TPM clock - 0,1,2,3 -> Disabled, (MCGFLLCLK, MCGPLLCLK/2), OSCERCLK, MCGIRCLK SIM_SOPT2_PLLFLLSEL_M; // Peripheral clock - 0,1 -> MCGFLLCLK,MCGPLLCLK/2 SIM_SOPT1 = (SIM_SOPT1&~SIM_SOPT1_OSC32KSEL_MASK)|SIM_SOPT1_OSC32KSEL_M; // ERCLK32K clock - 0,1,2,3 -> OSC32KCLK, - , RTC_CLKIN, LPO (1kHz) #elif defined(MCU_MKL02Z4) || defined(MCU_MKL04Z4) || defined(MCU_MKL05Z4) SIM_SOPT2 = SIM_SOPT2_UART0SRC_M | // UART0 clock - 0,1,2,3 -> Disabled, (MCGFLLCLK, MCGPLLCLK/2), OSCERCLK, MCGIRCLK SIM_SOPT2_TPMSRC_M ; // TPM2 source #else #error "CPU not set" #endif SystemCoreClockUpdate(); }
/*! @brief Sets up the clock out of RESET * */ void clock_initialise(void) { #if (CLOCK_MODE == CLOCK_MODE_NONE) // No clock setup #else // XTAL/EXTAL Pins SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; PORTA->PCR[3] = PORT_PCR_MUX(0); PORTA->PCR[4] = PORT_PCR_MUX(0); // Configure the Crystal Oscillator RTC->CR = RTC_CR_WPE_M|RTC_CR_SUP_M|RTC_CR_UM_M|RTC_CR_OSCE_M|RTC_CR_CLKO_M|RTC_CR_SCP_M; // Fast Internal Clock divider MCG->SC = MCG_SC_FCRDIV_M; // Out of reset MCG is in FEI mode // ============================================================= SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(7) | SIM_CLKDIV1_OUTDIV3(3) | SIM_CLKDIV1_OUTDIV4(7); // Switch from FEI -> FEI/FBI/FEE/FBE // ============================================================= // Set up crystal or external clock source MCG->C2 = MCG_C2_LOCRE0_M | // LOCRE0 = 0,1 -> Loss of clock reset enable MCG_C2_RANGE0_M | // RANGE0 = 0,1,2 -> Oscillator low/high/very high clock range MCG_C2_HGO0_M | // HGO0 = 0,1 -> Oscillator low power/high gain MCG_C2_EREFS0_M | // EREFS0 = 0,1 -> Select external clock/crystal oscillator MCG_C2_IRCS_M; // IRCS = 0,1 -> Select slow/fast internal clock for internal reference #if ((CLOCK_MODE == CLOCK_MODE_FEI) || (CLOCK_MODE == CLOCK_MODE_FBI) || (CLOCK_MODE == CLOCK_MODE_BLPI) ) // Transition via FBI //===================================== #define BYPASS (1) // CLKS value used while FLL locks MCG->C1 = MCG_C1_CLKS(BYPASS) | // CLKS = X -> External reference source while PLL locks MCG_C1_FRDIV_M | // FRDIV = N -> XTAL/2^n ~ 31.25 kHz MCG_C1_IREFS_M | // IREFS = 0,1 -> External/Slow IRC for FLL source MCG_C1_IRCLKEN_M | // IRCLKEN = 0,1 -> IRCLK disable/enable MCG_C1_IREFSTEN_M; // IREFSTEN = 0,1 -> Internal reference enabled in STOP mode // Wait for S_IREFST to indicate FLL Reference has switched do { __asm__("nop"); } while ((MCG->S & MCG_S_IREFST_MASK) != (MCG_C1_IREFS_V<<MCG_S_IREFST_SHIFT)); // Wait for S_CLKST to indicating that OUTCLK has switched to bypass PLL/FLL do { __asm__("nop"); } while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(BYPASS)); // Set FLL Parameters MCG->C4 = (MCG->C4&~(MCG_C4_DMX32_MASK|MCG_C4_DRST_DRS_MASK))|MCG_C4_DMX32_M|MCG_C4_DRST_DRS_M; #endif #if ((CLOCK_MODE == CLOCK_MODE_FBE) || (CLOCK_MODE == CLOCK_MODE_FEE) || (CLOCK_MODE == CLOCK_MODE_PLBE) || (CLOCK_MODE == CLOCK_MODE_PBE) || (CLOCK_MODE == CLOCK_MODE_PEE)) // Transition via FBE //===================================== #define BYPASS (2) // CLKS value used while PLL locks MCG->C1 = MCG_C1_CLKS(BYPASS) | // CLKS = 2 -> External reference source while PLL locks MCG_C1_FRDIV_M | // FRDIV = N -> XTAL/2^n ~ 31.25 kHz MCG_C1_IREFS_M | // IREFS = 0,1 -> External/Slow IRC for FLL source MCG_C1_IRCLKEN_M | // IRCLKEN = 0,1 -> IRCLK disable/enable MCG_C1_IREFSTEN_M; // IREFSTEN = 0,1 -> Internal reference enabled in STOP mode #if (MCG_C2_EREFS_V != 0) // Wait for oscillator stable (if used) do { __asm__("nop"); } while ((MCG->S & MCG_S_OSCINIT0_MASK) == 0); #endif // Wait for S_IREFST to indicate FLL Reference has switched do { __asm__("nop"); } while ((MCG->S & MCG_S_IREFST_MASK) != (MCG_C1_IREFS_V<<MCG_S_IREFST_SHIFT)); // Wait for S_CLKST to indicating that OUTCLK has switched to bypass PLL/FLL do { __asm__("nop"); } while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(BYPASS)); // Set FLL Parameters MCG->C4 = (MCG->C4&~(MCG_C4_DMX32_MASK|MCG_C4_DRST_DRS_MASK))|MCG_C4_DMX32_M|MCG_C4_DRST_DRS_M; #endif // Select FEI/FBI/FEE/FBE clock mode MCG->C1 = MCG_C1_CLKS_M | // CLKS = 0,1,2 -> Select FLL/IRCSCLK/ERCLK MCG_C1_FRDIV_M | // FRDIV = N -> XTAL/2^n ~ 31.25 kHz MCG_C1_IREFS_M | // IREFS = 0,1 -> External/Slow IRC for FLL source MCG_C1_IRCLKEN_M | // IRCLKEN = 0,1 -> IRCLK disable/enable MCG_C1_IREFSTEN_M; // IREFSTEN = 0,1 -> Internal reference enabled in STOP mode // Wait for mode change do { __asm__("nop"); } while ((MCG->S & MCG_S_IREFST_MASK) != (MCG_C1_IREFS_V<<MCG_S_IREFST_SHIFT)); #if defined (MCG_C6_PLLS_V) && (MCG_C1_CLKS_V == 0) // FLL or PLL #define MCG_S_CLKST_M MCG_S_CLKST(MCG_C6_PLLS_V?3:0) #else #define MCG_S_CLKST_M MCG_S_CLKST(MCG_C1_CLKS_V) #endif // Wait for S_CLKST to indicating that OUTCLK has switched do { __asm__("nop"); } while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_M); // Set the SIM _CLKDIV dividers SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1_M | SIM_CLKDIV1_OUTDIV2_M | SIM_CLKDIV1_OUTDIV3_M | SIM_CLKDIV1_OUTDIV4_M; #if (CLOCK_MODE == CLOCK_MODE_BLPE) || (CLOCK_MODE == CLOCK_MODE_BLPI) // Select BLPE/BLPI clock mode MCG->C2 = MCG_C2_LOCRE0_M | // LOCRE0 = 0,1 -> Loss of clock reset MCG_C2_RANGE0_M | // RANGE0 = 0,1,2 -> Oscillator low/high/very high clock range MCG_C2_HGO0_M | // HGO0 = 0,1 -> Oscillator low power/high gain MCG_C2_EREFS0_M | // EREFS0 = 0,1 -> Select external clock/crystal oscillator MCG_C2_LP_M | // LP = 0,1 -> Select FLL enabled/disabled in bypass mode MCG_C2_IRCS_M; // IRCS = 0,1 -> Select slow/fast internal clock for internal reference #endif // (CLOCK_MODE == CLOCK_MODE_BLPE) || (CLOCK_MODE == CLOCK_MODE_BLPI) #endif // (CLOCK_MODE == CLOCK_MODE_NONE) /*! * SOPT1 Clock multiplexing */ #if defined(SIM_SOPT1_OSC32KSEL_MASK) && defined(SIM_SOPT1_OSC32KSEL_M) // ERCLK32K source SIM->SOPT1 = (SIM->SOPT1&~SIM_SOPT1_OSC32KSEL_MASK)|SIM_SOPT1_OSC32KSEL_M; #endif /*! * SOPT2 Clock multiplexing */ #if defined(SIM_SOPT2_SDHCSRC_MASK) && defined(SIM_SOPT2_SDHCSRC_M) // SDHC clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_SDHCSRC_MASK)|SIM_SOPT2_SDHCSRC_M; #endif #if defined(SIM_SOPT2_TIMESRC_MASK) && defined(SIM_SOPT2_TIMESRC_M) // Ethernet time-stamp clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_TIMESRC_MASK)|SIM_SOPT2_TIMESRC_M; #endif #if defined(SIM_SOPT2_RMIISRC_MASK) && defined(SIM_SOPT2_RMIISRC_M) // RMII clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_RMIISRC_MASK)|SIM_SOPT2_RMIISRC_M; #endif #ifdef SIM_SCGC4_USBOTG_MASK // !! WARNING !! The USB interface must be disabled for clock changes to have effect !! WARNING !! SIM->SCGC4 &= ~SIM_SCGC4_USBOTG_MASK; #endif #if defined(SIM_SOPT2_USBSRC_MASK) && defined(SIM_SOPT2_USBSRC_M) // USB clock (48MHz req.) SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_USBSRC_MASK)|SIM_SOPT2_USBSRC_M; #endif #if defined(SIM_SOPT2_USBFSRC_MASK) && defined(SIM_SOPT2_USBFSRC_M) // USB clock (48MHz req.) SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_USBFSRC_MASK)|SIM_SOPT2_USBFSRC_M; #endif #if defined(SIM_SOPT2_PLLFLLSEL_MASK) && defined(SIM_SOPT2_PLLFLLSEL_M) // Peripheral clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_PLLFLLSEL_MASK)|SIM_SOPT2_PLLFLLSEL_M; #endif #if defined(SIM_SOPT2_UART0SRC_MASK) && defined(SIM_SOPT2_UART0SRC_M) // UART0 clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_UART0SRC_MASK)|SIM_SOPT2_UART0SRC_M; #endif #if defined(SIM_SOPT2_TPMSRC_MASK) && defined(SIM_SOPT2_TPMSRC_M) // TPM clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_TPMSRC_MASK)|SIM_SOPT2_TPMSRC_M; #endif #if defined(SIM_SOPT2_CLKOUTSEL_MASK) && defined(SIM_SOPT2_CLKOUTSEL_M) SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_CLKOUTSEL_MASK)|SIM_SOPT2_CLKOUTSEL_M; #endif #if defined(SIM_SOPT2_RTCCLKOUTSEL_MASK) && defined(SIM_SOPT2_RTCCLKOUTSEL_M) SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_RTCCLKOUTSEL_MASK)|SIM_SOPT2_RTCCLKOUTSEL_M; #endif #if defined(SIM_CLKDIV2_USBDIV_MASK) && defined(SIM_CLKDIV2_USBFRAC_MASK) && defined(SIM_CLKDIV2_USB_M) SIM->CLKDIV2 = (SIM->CLKDIV2&~(SIM_CLKDIV2_USBDIV_MASK|SIM_CLKDIV2_USBFRAC_MASK)) | SIM_CLKDIV2_USB_M; #endif SystemCoreClockUpdate(); }
.erclkDiv = 0U, #endif }, }; static const mcg_pll_config_t pll0Config = { .enableMode = 0U, .prdiv = CONFIG_MCG_PRDIV0, .vdiv = CONFIG_MCG_VDIV0, }; static const sim_clock_config_t simConfig = { .pllFllSel = PLLFLLSEL_MCGPLLCLK, /* PLLFLLSEL select PLL. */ .er32kSrc = ER32KSEL_RTC, /* ERCLK32K selection, use RTC. */ .clkdiv1 = SIM_CLKDIV1_OUTDIV1(CONFIG_K64_CORE_CLOCK_DIVIDER - 1) | SIM_CLKDIV1_OUTDIV2(CONFIG_K64_BUS_CLOCK_DIVIDER - 1) | SIM_CLKDIV1_OUTDIV3(CONFIG_K64_FLEXBUS_CLOCK_DIVIDER - 1) | SIM_CLKDIV1_OUTDIV4(CONFIG_K64_FLASH_CLOCK_DIVIDER - 1), }; /** * * @brief Initialize the system clock * * This routine will configure the multipurpose clock generator (MCG) to * set up the system clock. * The MCG has nine possible modes, including Stop mode. This routine assumes * that the current MCG mode is FLL Engaged Internal (FEI), as from reset. * It transitions through the FLL Bypassed External (FBE) and * PLL Bypassed External (PBE) modes to get to the desired * PLL Engaged External (PEE) mode and generate the maximum 120 MHz system
/************************************************************************************************ * SetPLL_Kinetis * 系统的锁相环设定,其完成的主要工作为: 设定CoreClock、BusClock、FlexClock、FlashClock * (设置的具体频率在KinetisConfig.h中配置) ************************************************************************************************/ static void SetPLL_Kinetis(void) { K_int32u_t temp_reg; K_int8u_t i; // First move to FBE mode // Enable external oscillator, RANGE=2, HGO=1, EREFS=1, LP=0, IRCS=0 MCG_C2 = MCG_C2_RANGE(1) | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK; // after initialization of oscillator release latched state of oscillator and GPIO SIM_SCGC4 |= SIM_SCGC4_LLWU_MASK; LLWU_CS |= LLWU_CS_ACKISO_MASK; // Select external oscilator 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); /* if we aren't using an osc input we don't need to wait for the osc to init */ while (MCG_S & MCG_S_IREFST_MASK){}; // wait for Reference clock Status bit to clear while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){}; // Wait for clock status bits to show clock source is ext ref clk // Now in FBE /* 设定PLL时钟 */ #if CORE_CLK_Kinetis <= 110 MCG_C5 = MCG_C5_PRDIV(REF_CLK_Kinetis/2 - 1); /* PLLCLK == 2MHz */ #else #if REF_CLK_Kinetis % 3 == 0 MCG_C5 = MCG_C5_PRDIV(REF_CLK_Kinetis/3 - 1); /* PLLCLK == 3MHz */ #elif REF_CLK_Kinetis % 4 == 0 MCG_C5 = MCG_C5_PRDIV(REF_CLK_Kinetis/4 - 1); /* PLLCLK == 4MHz */ #elif REF_CLK_Kinetis % 5 == 0 MCG_C5 = MCG_C5_PRDIV(REF_CLK_Kinetis*2/5 - 1); /* PLLCLK == 2.5MHz */ #endif #endif /* * Ensure MCG_C6 is at the reset default of 0. LOLIE disabled, * PLL disabled, clk monitor disabled, PLL VCO divider is clear */ MCG_C6 = 0x0; /* 设定各时钟的分频数 */ temp_reg = FMC_PFAPR; // store present value of FMC_PFAPR // set M0PFD through M7PFD to 1 to disable prefetch FMC_PFAPR |= FMC_PFAPR_M7PFD_MASK | FMC_PFAPR_M6PFD_MASK | FMC_PFAPR_M5PFD_MASK | FMC_PFAPR_M4PFD_MASK | FMC_PFAPR_M3PFD_MASK | FMC_PFAPR_M2PFD_MASK | FMC_PFAPR_M1PFD_MASK | FMC_PFAPR_M0PFD_MASK; // set clock dividers to desired value SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(DIV_BusClk_Kinetis - 1) | SIM_CLKDIV1_OUTDIV3(DIV_FlexClk_Kinetis - 1) | SIM_CLKDIV1_OUTDIV4(DIV_FlashClk_Kinetis - 1); // wait for dividers to change for (i = 0 ; i < DIV_FlashClk_Kinetis ; i++) {} FMC_PFAPR = temp_reg; // re-store original value of FMC_PFAPR /* 设置倍频数,倍频数为VDIV+24 */ #if CORE_CLK_Kinetis <= 110 MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(CORE_CLK_Kinetis/2 - 24); #else #if REF_CLK_Kinetis % 3 == 0 MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(CORE_CLK_Kinetis/3 - 24); #elif REF_CLK_Kinetis % 4 == 0 MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(CORE_CLK_Kinetis/4 - 24); #elif REF_CLK_Kinetis % 5 == 0 MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(CORE_CLK_Kinetis*2/5 - 24); #endif #endif while (!(MCG_S & MCG_S_PLLST_MASK)){}; // wait for PLL status bit to set while (!(MCG_S & MCG_S_LOCK_MASK)){}; // Wait for LOCK bit to set // Now running PBE Mode // 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){}; }
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 Sets up the clock out of RESET * */ void clock_initialise(void) { #if (CLOCK_MODE == CLOCK_MODE_NONE) // No clock setup #else // XTAL0/EXTAL0 Pins // Shouldn't be needed as default // SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; // PORTA->PCR[18] = PORT_PCR_MUX(0); // PORTA->PCR[19] = PORT_PCR_MUX(0); // Configure the Crystal Oscillators OSC0->CR = OSC0_CR_ERCLKEN_M|OSC0_CR_EREFSTEN_M|OSC0_CR_SCP_M; // XTAL/EXTAL Pins // Shouldn't be needed as default // SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK; // PORTE_PCR24 = PORT_PCR_MUX(0); // PORTE_PCR25 = PORT_PCR_MUX(0); SIM->SCGC1 |= SIM_SCGC1_OSC1_MASK; OSC1->CR = OSC1_CR_ERCLKEN_M|OSC1_CR_EREFSTEN_M|OSC1_CR_SCP_M; #if (MCG_C7_OSCSEL_V != 0) SIM->SCGC6 |= SIM_SCGC6_RTC_MASK; // Configure the RTC Crystal Oscillator RTC->CR = RTC_CR_SCP_M|RTC_CR_CLKO_M|RTC_CR_OSCE_M|RTC_CR_UM_M|RTC_CR_SUP_M|RTC_CR_WPE_M; #endif // Select OSCCLK Source MCG->C7 = MCG_C7_OSCSEL_M; // OSCSEL = 0,1 -> XTAL/XTAL32 // Fast Internal Clock divider MCG->SC = MCG_SC_FCRDIV_M; // Out of reset MCG is in FEI mode // ============================================================= // Set conservative SIM clock dividers BEFORE switching to ensure the clock speed remain within specification SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(7) | SIM_CLKDIV1_OUTDIV3(3) | SIM_CLKDIV1_OUTDIV4(7); // Switch from FEI -> FEI/FBI/FEE/FBE // ============================================================= // Set up crystal or external clock source for OSC0 MCG->C2 = MCG_C2_LOCRE0_M | // LOCRE0 = 0,1 -> Loss of clock reset enable MCG_C2_RANGE0_M | // RANGE0 = 0,1,2 -> Oscillator low/high/very high clock range MCG_C2_HGO0_M | // HGO0 = 0,1 -> Oscillator low power/high gain MCG_C2_EREFS0_M | // EREFS0 = 0,1 -> Select external clock/crystal oscillator MCG_C2_IRCS_M; // IRCS = 0,1 -> Select slow/fast internal clock for internal reference // Set up crystal or external clock source for OSC1 MCG->C10 = MCG_C10_LOCRE2_M | // LOCRE1 = 0,1 -> Loss of clock reset enable MCG_C10_RANGE1_M | // RANGE1 = 0,1,2 -> Oscillator low/high/very high clock range MCG_C10_HGO1_M | // HGO1 = 0,1 -> Oscillator low power/high gain MCG_C10_EREFS1_M; // EREFS1 = 0,1 -> Select external clock/crystal oscillator // Set up RTC clock monitor MCG->C8 = MCG_C8_LOCRE1_M | // LOCRE1 = 0,1 -> Loss of Lock Reset enable MCG_C8_CME1_M; // CME1 = 0,1 -> Clock monitor enable #if ((CLOCK_MODE == CLOCK_MODE_FEI) || (CLOCK_MODE == CLOCK_MODE_FBI) || (CLOCK_MODE == CLOCK_MODE_BLPI) ) // Transition via FBI //===================================== #define BYPASS (1) // CLKS value used while FLL locks MCG->C1 = MCG_C1_CLKS(BYPASS) | // CLKS = X -> External reference source while PLL locks MCG_C1_FRDIV_M | // FRDIV = N -> XTAL/2^n ~ 31.25 kHz MCG_C1_IREFS_M | // IREFS = 0,1 -> External/Slow IRC for FLL source MCG_C1_IRCLKEN_M | // IRCLKEN = 0,1 -> IRCLK disable/enable MCG_C1_IREFSTEN_M; // IREFSTEN = 0,1 -> Internal reference enabled in STOP mode // Wait for S_IREFST to indicate FLL Reference has switched do { __asm__("nop"); } while ((MCG->S & MCG_S_IREFST_MASK) != (MCG_C1_IREFS_V<<MCG_S_IREFST_SHIFT)); // Wait for S_CLKST to indicating that OUTCLK has switched to bypass PLL/FLL do { __asm__("nop"); } while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(BYPASS)); // Set FLL Parameters MCG->C4 = (MCG->C4&~(MCG_C4_DMX32_MASK|MCG_C4_DRST_DRS_MASK))|MCG_C4_DMX32_M|MCG_C4_DRST_DRS_M; #endif #if ((CLOCK_MODE == CLOCK_MODE_FBE) || (CLOCK_MODE == CLOCK_MODE_FEE) || (CLOCK_MODE == CLOCK_MODE_PLBE) || (CLOCK_MODE == CLOCK_MODE_PBE) || (CLOCK_MODE == CLOCK_MODE_PEE)) // Transition via FBE //===================================== #define BYPASS (2) // CLKS value used while PLL locks MCG->C1 = MCG_C1_CLKS(BYPASS) | // CLKS = 2 -> External reference source while PLL locks MCG_C1_FRDIV_M | // FRDIV = N -> XTAL/2^n ~ 31.25 kHz MCG_C1_IREFS_M | // IREFS = 0,1 -> External/Slow IRC for FLL source MCG_C1_IRCLKEN_M | // IRCLKEN = 0,1 -> IRCLK disable/enable MCG_C1_IREFSTEN_M; // IREFSTEN = 0,1 -> Internal reference enabled in STOP mode #if (MCG_C2_EREFS0_V != 0) // Wait for oscillator 0 stable (if used) do { __asm__("nop"); } while ((MCG->S & MCG_S_OSCINIT0_MASK) == 0); #endif #if (MCG_C10_EREFS1_V != 0) // Wait for oscillator 1 stable (if used) do { __asm__("nop"); } while ((MCG->S2 & MCG_S2_OSCINIT1_MASK) == 0); #endif // Wait for S_IREFST to indicate FLL Reference has switched do { __asm__("nop"); } while ((MCG->S & MCG_S_IREFST_MASK) != (MCG_C1_IREFS_V<<MCG_S_IREFST_SHIFT)); // Wait for S_CLKST to indicating that OUTCLK has switched to bypass PLL/FLL do { __asm__("nop"); } while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(BYPASS)); // Set FLL Parameters MCG->C4 = (MCG->C4&~(MCG_C4_DMX32_MASK|MCG_C4_DRST_DRS_MASK))|MCG_C4_DMX32_M|MCG_C4_DRST_DRS_M; #endif // Configure PLL0 Reference Frequency // ============================================================= MCG->C5 = MCG_C5_PLLREFSEL0_M | // PLLREFSEL0 = 0,1 -> OSC0/OSC1 select MCG_C5_PLLCLKEN0_M | // PLLCLKEN0 = 0,1 -> PLL -/enabled (irrespective of PLLS) MCG_C5_PLLSTEN0_M | // PLLSTEN0 = 0,1 -> disabled/enabled in normal stop mode MCG_C5_PRDIV0_M; // PRDIV0 = N -> PLL divider so PLL Ref. Freq. = 8-16 MHz // Configure PLL1 Reference Frequency // ============================================================= MCG->C11 = MCG_C11_PLLREFSEL1_M | // PLLREFSEL1 = 0,1 -> OSC0/OSC1 select MCG_C11_PLLCLKEN1_M | // PLLCLKEN = 0,1 -> PLL -/enabled (irrespective of PLLS) MCG_C11_PLLSTEN1_M | // PLLSTEN0 = 0,1 -> disabled/enabled in normal stop mode MCG_C11_PLLCS_M | // PLLCS = 0,1 -> PLL0/PLL1 used as MCG source MCG_C11_PRDIV1_M; // PRDIV0 = N -> PLL divider so PLL Ref. Freq. = 8-16 MHz // Set up PLL0 // ============================================================= MCG->C6 = MCG_C6_LOLIE0_M | // LOLIE0 = 0,1 -> Loss of Lock interrupt MCG_C6_PLLS_M | // PLLS = 0,1 -> Enable PLL MCG_C6_CME0_M | // CME0 = 0,1 -> Disable/enable clock monitor MCG_C6_VDIV0_M; // VDIV0 = N -> PLL Multiplication factor // Set up PLL1 // ============================================================= MCG->C12 = MCG_C12_LOLIE1_M | // LOLIE1 = 0,1 -> Loss of Lock interrupt MCG_C12_CME2_M | // CME2 = 0,1 -> Disable/enable clock monitor MCG_C12_VDIV1_M; // VDIV1 = N -> PLL Multiplication factor #if ((CLOCK_MODE == CLOCK_MODE_PBE) || (CLOCK_MODE == CLOCK_MODE_PEE)) // Transition via PBE // ============================================================= #if (MCG_C11_PLLCS_M == 0) // Wait for PLL0 to lock do { __asm__("nop"); } while((MCG->S & MCG_S_LOCK0_MASK) == 0); #else // Wait for PLL1 to lock do { __asm__("nop"); } while((MCG->S2 & MCG_S2_LOCK1_MASK) == 0); #endif // Wait until PLLS clock source changes to the PLL clock out do { __asm__("nop"); } while((MCG->S & MCG_S_PLLST_MASK) == 0); #endif #if ((CLOCK_MODE == CLOCK_MODE_FEI) || (CLOCK_MODE == CLOCK_MODE_FEE)) // Wait for FLL to lock do { __asm__("nop"); } while ((MCG->C4&MCG_C4_DRST_DRS_MASK) != MCG_C4_DRST_DRS_M); #endif // Select FEI/FBI/FEE/FBE/PBE/PEE clock mode MCG->C1 = MCG_C1_CLKS_M | // CLKS = 0,1,2 -> Select FLL/IRCSCLK/ERCLK MCG_C1_FRDIV_M | // FRDIV = N -> XTAL/2^n ~ 31.25 kHz MCG_C1_IREFS_M | // IREFS = 0,1 -> External/Slow IRC for FLL source MCG_C1_IRCLKEN_M | // IRCLKEN = 0,1 -> IRCLK disable/enable MCG_C1_IREFSTEN_M; // IREFSTEN = 0,1 -> Internal reference enabled in STOP mode // Wait for mode change do { __asm__("nop"); } while ((MCG->S & MCG_S_IREFST_MASK) != (MCG_C1_IREFS_V<<MCG_S_IREFST_SHIFT)); #if defined (MCG_C6_PLLS_V) && (MCG_C1_CLKS_V == 0) // FLL or PLL #define MCG_S_CLKST_M MCG_S_CLKST(MCG_C6_PLLS_V?3:0) #else #define MCG_S_CLKST_M MCG_S_CLKST(MCG_C1_CLKS_V) #endif // Wait for S_CLKST to indicating that OUTCLK has switched do { __asm__("nop"); } while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_M); // Set the SIM _CLKDIV dividers SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1_M | SIM_CLKDIV1_OUTDIV2_M | SIM_CLKDIV1_OUTDIV3_M | SIM_CLKDIV1_OUTDIV4_M; #if (CLOCK_MODE == CLOCK_MODE_BLPE) || (CLOCK_MODE == CLOCK_MODE_BLPI) // Select BLPE/BLPI clock mode MCG->C2 = MCG_C2_LOCRE0_M | // LOCRE0 = 0,1 -> Loss of clock reset MCG_C2_RANGE0_M | // RANGE0 = 0,1,2 -> Oscillator low/high/very high clock range MCG_C2_HGO0_M | // HGO0 = 0,1 -> Oscillator low power/high gain MCG_C2_EREFS0_M | // EREFS0 = 0,1 -> Select external clock/crystal oscillator MCG_C2_LP_M | // LP = 0,1 -> Select FLL enabled/disabled in bypass mode MCG_C2_IRCS_M; // IRCS = 0,1 -> Select slow/fast internal clock for internal reference #endif // (CLOCK_MODE == CLOCK_MODE_BLPE) || (CLOCK_MODE == CLOCK_MODE_BLPI) #endif // (CLOCK_MODE == CLOCK_MODE_NONE) /*! * SOPT1 Clock multiplexing */ #if defined(SIM_SOPT1_OSC32KSEL_MASK) && defined(SIM_SOPT1_OSC32KSEL_M) // ERCLK32K source SIM->SOPT1 = (SIM->SOPT1&~SIM_SOPT1_OSC32KSEL_MASK)|SIM_SOPT1_OSC32KSEL_M; #endif /*! * SOPT2 Clock multiplexing */ #if defined(SIM_SOPT2_SDHCSRC_MASK) && defined(SIM_SOPT2_SDHCSRC_M) // SDHC clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_SDHCSRC_MASK)|SIM_SOPT2_SDHCSRC_M; #endif #if defined(SIM_SOPT2_TIMESRC_MASK) && defined(SIM_SOPT2_TIMESRC_M) // Ethernet time-stamp clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_TIMESRC_MASK)|SIM_SOPT2_TIMESRC_M; #endif #if defined(SIM_SOPT2_RMIISRC_MASK) && defined(SIM_SOPT2_RMIISRC_M) // RMII clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_RMIISRC_MASK)|SIM_SOPT2_RMIISRC_M; #endif #ifdef SIM_SCGC4_USBOTG_MASK // !! WARNING !! The USB interface must be disabled for clock changes to have effect !! WARNING !! SIM->SCGC4 &= ~SIM_SCGC4_USBOTG_MASK; #endif #if defined(SIM_SOPT2_USBSRC_MASK) && defined(SIM_SOPT2_USBSRC_M) // USB clock (48MHz req.) SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_USBSRC_MASK)|SIM_SOPT2_USBSRC_M; #endif #if defined(SIM_SOPT2_USBFSRC_MASK) && defined(SIM_SOPT2_USBFSRC_M) // USB clock (48MHz req.) SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_USBFSRC_MASK)|SIM_SOPT2_USBFSRC_M; #endif #if defined(SIM_SOPT2_PLLFLLSEL_MASK) && defined(SIM_SOPT2_PLLFLLSEL_M) // Peripheral clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_PLLFLLSEL_MASK)|SIM_SOPT2_PLLFLLSEL_M; #endif #if defined(SIM_SOPT2_UART0SRC_MASK) && defined(SIM_SOPT2_UART0SRC_M) // UART0 clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_UART0SRC_MASK)|SIM_SOPT2_UART0SRC_M; #endif #if defined(SIM_SOPT2_TPMSRC_MASK) && defined(SIM_SOPT2_TPMSRC_M) // TPM clock SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_TPMSRC_MASK)|SIM_SOPT2_TPMSRC_M; #endif #if defined(SIM_SOPT2_CLKOUTSEL_MASK) && defined(SIM_SOPT2_CLKOUTSEL_M) SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_CLKOUTSEL_MASK)|SIM_SOPT2_CLKOUTSEL_M; #endif #if defined(SIM_SOPT2_RTCCLKOUTSEL_MASK) && defined(SIM_SOPT2_RTCCLKOUTSEL_M) SIM->SOPT2 = (SIM->SOPT2&~SIM_SOPT2_RTCCLKOUTSEL_MASK)|SIM_SOPT2_RTCCLKOUTSEL_M; #endif #if defined(SIM_CLKDIV2_USBDIV_MASK) && defined(SIM_CLKDIV2_USBFRAC_MASK) && defined(SIM_CLKDIV2_USB_M) SIM->CLKDIV2 = (SIM->CLKDIV2&~(SIM_CLKDIV2_USBDIV_MASK|SIM_CLKDIV2_USBFRAC_MASK)) | SIM_CLKDIV2_USB_M; #endif SystemCoreClockUpdate(); }
/** * @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 */ }
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. !!! ***/ }
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(); }
/** * Initialize the system * * @param none * @return none * * @brief Setup the microcontroller system. * Initialize the System. */ void SystemInit (void) { // system dividers SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV3(2) | SIM_CLKDIV1_OUTDIV4(5); // after reset, we are in FEI mode // enable external clock source - OSC0 #if __SYS_OSC_CLK <= 8000000 MCG_C2 = MCG_C2_LOCRE0_MASK | MCG_C2_RANGE(RANGE0_VAL) | (/*hgo_val*/0 << MCG_C2_HGO_SHIFT) | (/*erefs_val*/0 << MCG_C2_EREFS_SHIFT); #else // On rev. 1.0 of silicon there is an issue where the the input bufferd are enabled when JTAG is connected. // This has the affect of sometimes preventing the oscillator from running. To keep the oscillator amplitude // low, RANGE = 2 should not be used. This should be removed when fixed silicon is available. MCG_C2 = MCG_C2_LOCRE_MASK | MCG_C2_RANGE(2) | (/*hgo_val*/0 << MCG_C2_HGO_SHIFT) | (/*erefs_val*/0 << MCG_C2_EREFS_SHIFT); // MCG_C2 = MCG_C2_LOCRE_MASK | MCG_C2_RANGE(1) | (/*hgo_val*/0 << MCG_C2_HGO_SHIFT) | (/*erefs_val*/0 << MCG_C2_EREFS_SHIFT); #endif // select clock mode, we want FBE mode // CLKS = 2, FRDIV = frdiv_val, IREFS = 0, IRCLKEN = 0, IREFSTEN = 0 MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(FRDIV_VAL); /* wait until the MCG has moved into the proper mode */ // if the external oscillator is used need to wait for OSCINIT to set // for (i = 0 ; i < 10000 ; i++) // { // if (MCG_S & MCG_S_OSCINIT_MASK) break; // jump out early if OSCINIT sets before loop finishes // } // if (!(MCG_S & MCG_S_OSCINIT_MASK)) return 0x23; // check bit is really set and return with error if not set // wait for reference clock status bit is cleared and clock source is ext ref clk while ((MCG_S & MCG_S_IREFST_MASK) || MCG_S_CLKST(2) != (MCG_S & MCG_S_CLKST_MASK)); // ... FBE mode // enable clock monitor for osc0 MCG_C6 = MCG_C6_CME_MASK; // PLL0 MCG_C5 = MCG_C5_PRDIV(PRDIV_VAL - 1); // set PLL0 ref divider, osc0 is reference MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(VDIV_VAL - 16); // set VDIV and enable PLL // wait to lock... while (!(MCG_S & MCG_S_PLLST_MASK)); while (!(MCG_S & MCG_S_LOCK_MASK)); // // Use actual PLL settings to calculate PLL frequency // prdiv = ((MCG_C5 & MCG_C5_PRDIV_MASK) + 1); // vdiv = ((MCG_C6 & MCG_C6_VDIV_MASK) + 16); // ... PBE mode MCG_C1 &= ~MCG_C1_CLKS_MASK; // CLKS = 0, select PLL as MCG_OUT while (MCG_S_CLKST(3) != (MCG_S & MCG_S_CLKST_MASK)); // ... PEE mode /* ToDo: add code to initialize the system do not use global variables because this function is called before reaching pre-main. RW section maybe overwritten afterwards. */ SystemCoreClock = __SYSTEM_CLOCK; }
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); }
/*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. !!! ***/ /*** ### MK60DN512ZVLQ10 "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,STNDBYEN=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_STNDBYEN_MASK | WDOG_STCTRLH_WAITEN_MASK | WDOG_STCTRLH_STOPEN_MASK | WDOG_STCTRLH_ALLOWUPDATE_MASK | WDOG_STCTRLH_CLKSRC_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: PORTC=1,PORTA=1 */ SIM_SCGC5 |= (SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTA_MASK); /* Enable clock gate for ports to enable pin routing */ /* 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_CLKDIV2: USBDIV=0,USBFRAC=1 */ SIM_CLKDIV2 = (uint32_t)((SIM_CLKDIV2 & (uint32_t)~(uint32_t)( SIM_CLKDIV2_USBDIV(0x07) )) | (uint32_t)( SIM_CLKDIV2_USBFRAC_MASK )); /* Update USB clock 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_MASK); /* System oscillator drives 32 kHz clock for various peripherals */ /* 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: ??=0,??=0,RANGE=0,HGO=0,EREFS=0,LP=0,IRCS=0 */ MCG_C2 = MCG_C2_RANGE(0x00); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* 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 &= (uint32_t)~(uint32_t)(SIM_SOPT2_MCGCLKSEL_MASK); /* MCG_C5: ??=0,PLLCLKEN=0,PLLSTEN=0,PRDIV=0 */ MCG_C5 = MCG_C5_PRDIV(0x00); /* MCG_C6: LOLIE=0,PLLS=0,CME=0,VDIV=0 */ MCG_C6 = MCG_C6_VDIV(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. !!! ***/ }
/*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. !!! ***/ }
/* ===================================================================*/ LDD_TError Cpu_SetClockConfiguration(LDD_TClockConfiguration ModeID) { if (ModeID > 0x02U) { return ERR_RANGE; /* Undefined clock configuration requested requested */ } switch (ModeID) { case CPU_CLOCK_CONFIG_0: if (ClockConfigurationID == 2U) { /* Clock configuration 0 and clock configuration 2 use different clock configuration */ /* 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); /* Set the system prescalers to safe value */ Cpu_SetMCG(0U); /* Update clock source setting */ } /* 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 */ break; case CPU_CLOCK_CONFIG_1: if (ClockConfigurationID == 2U) { /* Clock configuration 1 and clock configuration 2 use different clock configuration */ /* 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); /* Set the system prescalers to safe value */ Cpu_SetMCG(0U); /* Update clock source setting */ } /* SIM_CLKDIV1: OUTDIV1=9,OUTDIV2=9,OUTDIV3=9,OUTDIV4=9,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x09) | SIM_CLKDIV1_OUTDIV2(0x09) | SIM_CLKDIV1_OUTDIV3(0x09) | SIM_CLKDIV1_OUTDIV4(0x09); /* 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 */ break; case CPU_CLOCK_CONFIG_2: /* 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); /* Set the system prescalers to safe value */ if ((MCG_C2 & MCG_C2_IRCS_MASK) == 0x00U) { /* MCG_SC: FCRDIV=1 */ MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)( MCG_SC_FCRDIV(0x06) )) | (uint8_t)( MCG_SC_FCRDIV(0x01) )); } else { /* MCG_C2: IRCS=0 */ MCG_C2 &= (uint8_t)~(uint8_t)(MCG_C2_IRCS_MASK); while((MCG_S & MCG_S_IRCST_MASK) != 0x00U) { /* Check that the source internal reference clock is slow clock. */ } /* MCG_SC: FCRDIV=1 */ MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)( MCG_SC_FCRDIV(0x06) )) | (uint8_t)( MCG_SC_FCRDIV(0x01) )); /* MCG_C2: IRCS=1 */ MCG_C2 |= MCG_C2_IRCS_MASK; while((MCG_S & MCG_S_IRCST_MASK) == 0x00U) { /* Check that the source internal reference clock is fast clock. */ } } Cpu_SetMCG(1U); /* Update clock source setting */ /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=0,OUTDIV3=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_OUTDIV2(0x00) | SIM_CLKDIV1_OUTDIV3(0x00) | SIM_CLKDIV1_OUTDIV4(0x03); /* 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 */ break; default: break; } LDD_SetClockConfiguration(ModeID); /* Call all LDD components to update the clock configuration */ ClockConfigurationID = ModeID; /* Store clock configuration identifier */ return ERR_OK; }