/*lint -esym(765,Cpu_Interrupt) Disable MISRA rule (8.10) checking for symbols (Cpu_Interrupt). */ void __init_hardware(void) { /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/ /*** ### MKL25Z128VLK4 "Cpu" init code ... ***/ /*** PE initialization code after reset ***/ SCB_VTOR = (uint32_t)(&__vect_table); /* Set the interrupt vector table position */ /* Disable the WDOG module */ /* SIM_COPC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COPT=0,COPCLKS=0,COPW=0 */ SIM_COPC = SIM_COPC_COPT(0x00); /* System clock initialization */ /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x03)); /* Set the system prescalers to safe value */ /* SIM_SCGC5: PORTD=1,PORTB=1,PORTA=1 */ SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTA_MASK; /* Enable clock gate for ports to enable pin routing */ if ((PMC_REGSC & PMC_REGSC_ACKISO_MASK) != 0x0U) { /* PMC_REGSC: ACKISO=1 */ PMC_REGSC |= PMC_REGSC_ACKISO_MASK; /* Release IO pads after wakeup from VLLS mode. */ } /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x00)); /* Update system prescalers */ /* SIM_SOPT2: PLLFLLSEL=0 */ SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_PLLFLLSEL_MASK); /* Select FLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=3 */ SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */ /* SIM_SOPT2: TPMSRC=1 */ SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)( SIM_SOPT2_TPMSRC(0x02) )) | (uint32_t)( SIM_SOPT2_TPMSRC(0x01) )); /* Set the TPM clock */ /* Switch to FEI Mode */ /* MCG_C1: CLKS=0,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x00) | MCG_C1_IREFS_MASK | MCG_C1_IRCLKEN_MASK; /* MCG_C2: LOCRE0=0,??=0,RANGE0=0,HGO0=0,EREFS0=0,LP=0,IRCS=0 */ MCG_C2 = MCG_C2_RANGE0(0x00); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC0_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */ MCG_C5 = MCG_C5_PRDIV0(0x00); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ MCG_C6 = MCG_C6_VDIV0(0x00); while((MCG_S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */ } while((MCG_S & 0x0CU) != 0x00U) { /* Wait until output of the FLL is selected */ } /*** End of PE initialization code after reset ***/ /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/ }
/***************************************************************************** * @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
/*-------------------------------------------------------------------------------*/ void FBE(void) { MCG->C6 &= ~MCG_C6_CME0_MASK; //External clock monitor is disabled for OSC0. MCG->C2 |= MCG_C2_RANGE0(3) | // Very high frequency range selected for the crystal oscillator MCG_C2_EREFS0_MASK ; //Oscillator requested MCG->C4 &= ~MCG_C4_DRST_DRS_MASK; // Reset DCO Range MCG->C4 &= ~MCG_C4_DMX32_MASK; // DCO Maximum Frequency MCG->C4 |= MCG_C4_DRST_DRS(1); // 31.25 * 1280 = 40000kHz MCG->C6 &= ~MCG_C6_PLLS_MASK; // Select FLL MCG->C1 &= ~MCG_C1_CLKS_MASK; // Reset Clock Source Select MCG->C1 |= MCG_C1_CLKS(2) | //External reference clock is selected MCG_C1_FRDIV(3)| // Divide Factor is 256 MCG_C1_IRCLKEN_MASK; //MCGIRCLK active // Output of FLL is selected for MCGOUTCLK while((MCG->S & MCG_S_OSCINIT0_MASK) == 0); // wait for osc init while((MCG->S & MCG_S_PLLST_MASK) != 0); // wait for FLL while((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)); // wait for EXTAL is selected SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1 - 1) | // core/system clock = MCGOUTCLK / 1 = 8 / 1 = 8MHz SIM_CLKDIV1_OUTDIV4(1 - 1); // flash/bus clock = core/system / 1 = 8MHz }
/*! * @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
static void SetSIMRegisters() { // TODO SIM->COPC = SIM_COPC_COPT(0);//disable watchdog immediately //do the rest in order listed in data sheet SIM->SOPT2 = SIM_SOPT2_UART0SRC(0)|SIM_SOPT2_TPMSRC(0);//no clocks enabled for // uart0 or TPM counterClock SIM->SOPT4 = ((0 << SIM_SOPT4_TPM1CLKSEL_SHIFT)&SIM_SOPT4_TPM1CLKSEL_MASK)|((0 << SIM_SOPT4_TPM0CLKSEL_SHIFT)&SIM_SOPT4_TPM0CLKSEL_MASK)|((0<<SIM_SOPT4_TPM1CH0SRC_SHIFT)&SIM_SOPT4_TPM1CH0SRC_MASK);//don't care settings SIM->SOPT5 = ((0<<SIM_SOPT5_UART0ODE_SHIFT)&SIM_SOPT5_UART0ODE_MASK)|((0<<SIM_SOPT5_UART0RXSRC_SHIFT)&SIM_SOPT5_UART0RXSRC_MASK)|((0<<SIM_SOPT5_UART0TXSRC_SHIFT)&SIM_SOPT5_UART0TXSRC_MASK);//don't cares SIM->SOPT7 = ((0<<SIM_SOPT7_ADC0ALTTRGEN_SHIFT)&SIM_SOPT7_ADC0ALTTRGEN_MASK)|((0<<SIM_SOPT7_ADC0PRETRGSEL_SHIFT)&SIM_SOPT7_ADC0PRETRGSEL_MASK)|((0<<SIM_SOPT7_ADC0TRGSEL_SHIFT)&SIM_SOPT7_ADC0TRGSEL_MASK);//don't cares SIM->SCGC4 = ((1<<SIM_SCGC4_SPI0_SHIFT)&SIM_SCGC4_SPI0_MASK)|((0<<SIM_SCGC4_CMP_SHIFT)&SIM_SCGC4_CMP_MASK)|((0<<SIM_SCGC4_UART0_SHIFT)&SIM_SCGC4_UART0_MASK)|((1<<SIM_SCGC4_I2C1_SHIFT)&SIM_SCGC4_I2C1_MASK)|((1<<SIM_SCGC4_I2C0_SHIFT)&SIM_SCGC4_I2C0_MASK);//enable the I2C module SIM->SCGC5 = ((1<<SIM_SCGC5_PORTB_SHIFT)&SIM_SCGC5_PORTB_MASK)|((1<<SIM_SCGC5_PORTA_SHIFT)&SIM_SCGC5_PORTA_MASK)|((0<<SIM_SCGC5_LPTMR_SHIFT)&SIM_SCGC5_LPTMR_MASK);//enable both ports SIM->SCGC6 = ((0<<SIM_SCGC6_ADC0_SHIFT)&SIM_SCGC6_ADC0_MASK)|((0<<SIM_SCGC6_TPM1_SHIFT)&SIM_SCGC6_TPM1_MASK)|((0<<SIM_SCGC6_TPM0_SHIFT)&SIM_SCGC6_TPM0_MASK)|((0<<SIM_SCGC6_FTF_SHIFT)&SIM_SCGC6_FTF_MASK);//don't cares SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0)|SIM_CLKDIV1_OUTDIV4(4);//clk configured for 4MHz core, .8 MHz Bus Clk (fastest allowable in BLPI mode) //this is unchanged from default, do not alter. If we need to save power we can turn off flash, but this has caused hard faults. we need to move the interrupt vectors out of flash to do this SIM_FCFG1 = ((0<<SIM_FCFG1_FLASHDOZE_SHIFT)&SIM_FCFG1_FLASHDOZE_MASK)|((0<<SIM_FCFG1_FLASHDIS_SHIFT)&SIM_FCFG1_FLASHDIS_MASK);//flash disabled to conserve power, other settings are don't cares, TODO:verify flash size setting is unimportant //SIM_FCFG2 = SIM_FCFG2 only has maxaddr0, which is read only. //SIM_SRVCOP, we do not need to reset timer, it is disabled already. return; }
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 PEE(void) { MCG->C6 &= ~MCG_C6_CME0_MASK; MCG->C2 &= ~MCG_C2_LP_MASK; MCG->C2 |= MCG_C2_RANGE0(3) |// Very high frequency range selected for the crystal oscillator MCG_C2_EREFS0_MASK ; MCG->C5 &= ~MCG_C5_PRDIV0_MASK; MCG->C5 |= MCG_C5_PRDIV0(2 - 1); // External clock div 4 MCG->C6 &= ~MCG_C6_VDIV0_MASK; MCG->C6 |= MCG_C6_VDIV0(24 - 24) | // Mul 24. 8 / 4 * 24 = 48MHz MCG_C6_CME0_MASK | MCG_C6_PLLS_MASK; MCG->C1 &= ~MCG_C1_CLKS_MASK; MCG->C1 |= ~MCG_C1_CLKS_MASK | // Output of PLL is selected for MCGOUTCLK MCG_C1_FRDIV(3) | MCG_C1_IRCLKEN_MASK; while((MCG->S & MCG_S_OSCINIT0_MASK) == 0); // wait for osc init. while((MCG->S & MCG_S_PLLST_MASK) != MCG_S_PLLST_MASK); // wait for PLL while((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)); // wait for PLL is selected SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(2 - 1) | // core/system clock = MCGOUTCLK / 2 = 96 / 2 = 48MHz SIM_CLKDIV1_OUTDIV4(2 - 1); // flash/bus clock = core/system / 2 = 24MHz }
/** * @brief Configure the controllers clock system */ static void cpu_clock_init(void) { /* setup system prescalers */ SIM->CLKDIV1 = (uint32_t)SIM_CLKDIV1_OUTDIV4(1); modem_clock_init(); kinetis_mcg_set_mode(KINETIS_MCG_PEE); }
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 }
/*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) { SIM_WR_CLKDIV1(base, (SIM_RD_CLKDIV1(base) & ~(SIM_CLKDIV1_OUTDIV1_MASK | SIM_CLKDIV1_OUTDIV4_MASK)) \ | (SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV4(outdiv4))); }
// 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; }
void vfnMcuConfig (void) { #if defined(CLKOUT) SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK; //Enable clock on PTC3 PORTC_PCR3 = PORT_PCR_MUX(0x05); //PTC3 as CLKOUT SIM_SOPT2 &= ~SIM_SOPT2_CLKOUTSEL_MASK; //Clear CLKOUTSEL register SIM_SOPT2 |= SIM_SOPT2_CLKOUTSEL(0x02); //Select BUSCLK as CLKOUT output #endif /* Actual PLL frequency is 48MHz --> 96MHz needed for USB to work due freq divider by 2 */ /* Set dividers for new PLL frequency */ SIM_CLKDIV1 = ( 0 | SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV4(1) ); /* Return MCG to PBE */ MCG_C6 |= MCG_C6_PLLS_MASK; MCG_C2 &= ~MCG_C2_LP_MASK; MCG_C1 &= ~MCG_C1_IREFS_MASK; MCG_C1 |= MCG_C1_CLKS(2); /* Move MCG to FBE */ MCG_C6 &= ~MCG_C6_PLLS_MASK; MCG_C5 &= ~MCG_C5_PLLCLKEN0_MASK; /* Configure PLL to run @96MHz */ MCG_C6 &= ~MCG_C6_VDIV0_MASK; MCG_C5 &= ~MCG_C5_PRDIV0_MASK; MCG_C6 |= (USB_PLL_VDIV - 24); MCG_C5 |= (USB_PLL_PRDIV - 1); MCG_C5 |= MCG_C5_PLLCLKEN0_MASK; //Enable PLL while(!(MCG_S & MCG_S_LOCK0_MASK)); //Wait for PLL to lock /* Go to PBE */ MCG_C6 |= MCG_C6_PLLS_MASK; /* Go to PEE */ MCG_C1 &= ~MCG_C1_CLKS_MASK; /* MCG is now configured */ /* Reconfigure UART0 with new frequency */ #if TERM_PORT_NUM==0 uart0_init (UART0_BASE_PTR, 48000, TERMINAL_BAUD); #elif TERM_PORT_NUM==1 uart_init (UART1_BASE_PTR, 24000, TERMINAL_BAUD); #else uart_init (UART2_BASE_PTR, 24000, TERMINAL_BAUD); #endif }
void Clock_init(void) { // Init system clock /* System clock initialization */ /* SIM_SCGC5: PORTA=1 */ SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; /* Enable clock gate for ports to enable pin routing */ /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x01)); /* Update system prescalers */ /* SIM_SOPT2: PLLFLLSEL=0 */ SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_PLLFLLSEL_MASK); /* Select FLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=0 */ SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL(0x03)); /* System oscillator drives 32 kHz clock for various peripherals */ /* SIM_SOPT2: TPMSRC=1 */ SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)( SIM_SOPT2_TPMSRC(0x02) )) | (uint32_t)( SIM_SOPT2_TPMSRC(0x01) )); /* Set the TPM clock */ /* PORTA_PCR18: ISF=0,MUX=0 */ PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* PORTA_PCR19: ISF=0,MUX=0 */ PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* MCG_SC: FCRDIV=1 */ MCG_SC = (uint8_t)((MCG_SC & (uint8_t)~(uint8_t)( MCG_SC_FCRDIV(0x06) )) | (uint8_t)( MCG_SC_FCRDIV(0x01) )); /* Switch to FEE Mode */ /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */ MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK); /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC0_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); /* MCG_C4: DMX32=0,DRST_DRS=1 */ MCG_C4 = (uint8_t)((MCG_C4 & (uint8_t)~(uint8_t)( MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x02) )) | (uint8_t)( MCG_C4_DRST_DRS(0x01) )); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */ MCG_C5 = MCG_C5_PRDIV0(0x00); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ MCG_C6 = MCG_C6_VDIV0(0x00); while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ } while((MCG_S & 0x0CU) != 0x00U) { /* Wait until output of the FLL is selected */ } /*** End of PE initialization code after reset ***/ }
void PBE_to_PEE(void) { MCG->C5 |= MCG_C5_PLLCLKEN0_MASK ; // MCGPLLCLK is active SIM->SOPT2 |=SIM_SOPT2_PLLFLLSEL_MASK; // Selects the MCGPLLCLK clock for various peripheral clocking options MCG->C1 &=~MCG_C1_CLKS_MASK; // PLL or FLL reference clock is selected. SIM->CLKDIV1 |=SIM_CLKDIV1_OUTDIV1(0x1); //Factor Divider1 == 2 => core clock = 96MHz/2 =48MHz SIM->CLKDIV1 |=SIM_CLKDIV1_OUTDIV4(0x1); //Factor Divider4 == 2 => bus clock = 48MHz/2 =24MHz while((MCG->S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ } }
/*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_OUTDIV4(outdiv4); SIM_WR_CLKDIV1(base, clkdiv1); }
/** **=========================================================================== ** Reset handler **=========================================================================== */ void __init_hardware(void) { /* This is a cleaned up output of Processor Expert generated code */ /* Set the interrupt vector table position */ SCB_VTOR = (uint32_t)__vector_table; #if 0 /* Disable the WDOG module */ SIM_COPC = SIM_COPC_COPT(0x00); #endif /* System clock initialization */ /* Enable clock gate for ports to enable pin routing */ SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; /* Update system prescalers */ SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x01); /* Select FLL as a clock source for various peripherals */ SIM_SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK; /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */ SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* Set the TPM clock */ SIM_SOPT2 &= ~SIM_SOPT2_TPMSRC(0x01); SIM_SOPT2 |= SIM_SOPT2_TPMSRC(0x02); /* Enable XTAL IO pins */ PORTA_PCR18 = PORT_PCR_MUX(0); PORTA_PCR19 = PORT_PCR_MUX(0); /* Switch to FBE Mode */ MCG_C2 = MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK; OSC0_CR = OSC_CR_ERCLKEN_MASK; MCG_C1 = MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK; MCG_C4 &= ~MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03); MCG_C5 = MCG_C5_PRDIV0(0x03); MCG_C6 = MCG_C6_VDIV0(0x00); /* Check that the source of the FLL reference clock is the external reference clock. */ while((MCG_S & MCG_S_IREFST_MASK) != 0x00U); /* Wait until external reference clock is selected as MCG output */ while((MCG_S & 0x0CU) != 0x08U); /* Switch to PBE Mode */ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x00)); /* Wait until external reference clock is selected as MCG output */ while((MCG_S & 0x0CU) != 0x08U); /* Wait until locked */ while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U); /* Switch to PEE Mode */ MCG_C1 = MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK; /* Wait until output of the PLL is selected */ while((MCG_S & 0x0CU) != 0x0CU); }
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 }
/** 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 */ }
/** * @brief Configure the controllers clock system */ static void cpu_clock_init(void) { /* setup system prescalers */ SIM->CLKDIV1 = (uint32_t)SIM_CLKDIV1_OUTDIV4(1); modem_clock_init(); kinetis_mcg_set_mode(KINETIS_MCG_PEE); /* * Setup USBFSOTG clock * USB clock should be 48 MHz, use MCGPLLCLK as clock source * usb_clk = (pll_clk * 1 / 1) = 48MHz * 1 / 1 = 48MHz */ #if MODULE_USBDEV SIM->SOPT2 &= ~(SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK); SIM->SOPT2 |= SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK; SIM->CLKDIV2 = 0; #endif }
void FEI(void) { MCG->C1 |= MCG_C1_IREFS_MASK; // Internal clock (32.768kHz) for FLL MCG->C4 &= ~MCG_C4_DRST_DRS_MASK; MCG->C4 |= MCG_C4_DRST_DRS(1); // 32.768 * 732 = 24MHz MCG->C2 |= MCG_C2_RANGE0(0) ; // Reset MCG_C2 MCG->C1 &= ~MCG_C1_CLKS_MASK; // Output of FLL is selected for MCGOUTCLK MCG->C1 |= MCG_C1_CLKS(0) | MCG_C1_FRDIV(0)| // Divide Factor is 32 MCG_C1_IRCLKEN_MASK; // MCGIRCLK active while((MCG->S & MCG_S_IREFST_MASK) == 0); // wait for Internal clock is selected while((MCG->S & MCG_S_CLKST_MASK) != 0); // wait for FLL is selected SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1 - 1) | // core/system clock = MCGOUTCLK / 1 = 8 / 1 = 24MHz SIM_CLKDIV1_OUTDIV4(1 - 1); // flash/bus clock = core/system / 1 = 24MHz SIM->SCGC5 |= (1UL << 11); /* Enable Clock to Port C */ }
// ============================================================================= // 功能:系统时钟初始化,从系统上电使用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
/*lint -esym(765,Cpu_Interrupt) Disable MISRA rule (8.10) checking for symbols (Cpu_Interrupt). */ void __init_hardware(void) { /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/ /*** ### MKL46Z256VMC4 "Cpu" init code ... ***/ /*** PE initialization code after reset ***/ SCB_VTOR = (uint32_t)(&__vect_table); /* Set the interrupt vector table position */ /* Disable the WDOG module */ /* SIM_COPC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COPT=0,COPCLKS=0,COPW=0 */ SIM_COPC = SIM_COPC_COPT(0x00); /* System clock initialization */ /* SIM_SCGC5: PORTE=1,PORTC=1,PORTB=1,PORTA=1 */ SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTA_MASK; /* Enable clock gate for ports to enable pin routing */ /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x01)); /* Update system prescalers */ /* SIM_SOPT2: PLLFLLSEL=1 */ SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; /* Select PLL as a clock source for various peripherals */ /* SIM_SOPT1: OSC32KSEL=2 */ SIM_SOPT1 = (uint32_t)((SIM_SOPT1 & (uint32_t)~(uint32_t)( SIM_SOPT1_OSC32KSEL(0x01) )) | (uint32_t)( SIM_SOPT1_OSC32KSEL(0x02) )); /* System oscillator drives 32 kHz clock for various peripherals */ /* SIM_SOPT2: TPMSRC=1 */ SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)( SIM_SOPT2_TPMSRC(0x02) )) | (uint32_t)( SIM_SOPT2_TPMSRC(0x01) )); /* Set the TPM clock */ /* PORTA_PCR18: ISF=0,MUX=0 */ PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* PORTA_PCR19: ISF=0,MUX=0 */ PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* Switch to FBE Mode */ /* MCG_C2: LOCRE0=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ MCG_C2 = (uint8_t)((MCG_C2 & (uint8_t)~(uint8_t)( MCG_C2_LOCRE0_MASK | MCG_C2_RANGE0(0x01) | MCG_C2_HGO0_MASK | MCG_C2_LP_MASK | MCG_C2_IRCS_MASK )) | (uint8_t)( MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK )); /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ OSC0_CR = OSC_CR_ERCLKEN_MASK; /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); /* MCG_C4: DMX32=0,DRST_DRS=0 */ MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=3 */ MCG_C5 = MCG_C5_PRDIV0(0x03); /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ MCG_C6 = MCG_C6_VDIV0(0x00); while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ } while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } /* Switch to PBE Mode */ /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0 */ MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x00)); while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ } while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */ } /* Switch to PEE Mode */ /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ } /* Initialization of the RTC_CLKIN pin */ /* PORTC_PCR1: ISF=0,MUX=1 */ PORTC_PCR1 = (uint32_t)((PORTC_PCR1 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x06) )) | (uint32_t)( PORT_PCR_MUX(0x01) )); /*** End of PE initialization code after reset ***/ /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/ }
/*! 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(); }
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) ; }
/*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. !!! ***/ }
/************************************************************************************************ * 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){}; }