Пример #1
0
/*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. !!! ***/

}
Пример #2
0
void pwmout_init(pwmout_t* obj, PinName pin) {
    // determine the channel
    PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
    MBED_ASSERT(pwm != (PWMName)NC);

    uint32_t clkdiv = 0;
    float clkval;

#if defined(TARGET_KL43Z)
    if (mcgirc_frequency()) {
        SIM->SOPT2 |= SIM_SOPT2_TPMSRC(3); // Clock source: MCGIRCLK
        clkval = mcgirc_frequency() / 1000000.0f;
    } else {
        SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: IRC48M
        clkval = CPU_INT_IRC_CLK_HZ / 1000000.0f;
    }
#else
    if (mcgpllfll_frequency()) {
        SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK
        clkval = mcgpllfll_frequency() / 1000000.0f;
    } else {
        SIM->SOPT2 |= SIM_SOPT2_TPMSRC(2); // Clock source: ExtOsc
        clkval = extosc_frequency() / 1000000.0f;
    }
#endif
    while (clkval > 1) {
        clkdiv++;
        clkval /= 2.0;
        if (clkdiv == 7)
            break;
    }

    pwm_clock = clkval;
    unsigned int port  = (unsigned int)pin >> PORT_SHIFT;
    unsigned int tpm_n = (pwm >> TPM_SHIFT);
    unsigned int ch_n  = (pwm & 0xFF);

    SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
    SIM->SCGC6 |= 1 << (SIM_SCGC6_TPM0_SHIFT + tpm_n);

    TPM_Type *tpm = (TPM_Type *)(TPM0_BASE + 0x1000 * tpm_n);
    tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(clkdiv); // (clock)MHz / clkdiv ~= (0.75)MHz
    tpm->CONTROLS[ch_n].CnSC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK); /* No Interrupts; High True pulses on Edge Aligned PWM */

    obj->CnV = &tpm->CONTROLS[ch_n].CnV;
    obj->MOD = &tpm->MOD;
    obj->CNT = &tpm->CNT;

    // default to 20ms: standard for servos, and fine for e.g. brightness control
    pwmout_period_ms(obj, 20);
    pwmout_write    (obj, 0);

    // Wire pinout
    pinmap_pinout(pin, PinMap_PWM);
}
Пример #3
0
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 ***/

}
Пример #4
0
void tpmInit()
{
#if defined(TPM_CLOCK_IRCLK)
    MCG_SC &= ~MCG_SC_FCRDIV_MASK;										    // zero fast IR clock divider
    MCG_C1 |= MCG_C1_IRCLKEN_MASK | MCG_C1_IREFSTEN_MASK;					// enable MCGIRCLK, also in stop mode
    MCG_C2 |= MCG_C2_IRCS_MASK;											    // select fast MCGIRCLK
    SIM_SOPT2 = (SIM_SOPT2 & ~SIM_SOPT2_TPMSRC_MASK) | SIM_SOPT2_TPMSRC(3);	// select MCGIRCLK for TPM source
#else
    SIM_SOPT2 = (SIM_SOPT2 & ~SIM_SOPT2_TPMSRC_MASK) | SIM_SOPT2_TPMSRC(1);	// PLL / 2 clock
#endif

    interruptRegisterTPMIRQHandler(timerTPMIRQHandler, 0);
    interruptRegisterTPMIRQHandler(timerTPMIRQHandler, 1);
    interruptRegisterTPMIRQHandler(timerTPMIRQHandler, 2);
}
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 Init_TPM(uint32_t period_ms)
{
	//turn on clock to TPM 
	SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK;
	
	//set clock source for tpm to be TPM Source 3 which is MCGIR (32 kHz)
	SIM->SOPT2 |= SIM_SOPT2_TPMSRC(3);

	// disable TPM
	TPM0->SC = 0;

	//set TPM to count up and divide by 32 with prescaler and use clock mode
	// will count at 1 kHz
	TPM0->SC = (TPM_SC_PS(5));
	
	//load the counter and mod. Note: 16-bit counter, not 32-bit
	TPM0->MOD = TPM_MOD_MOD(period_ms);

	
	TPM0->SC |= TPM_SC_TOIE_MASK;

	// Configure NVIC 
	NVIC_SetPriority(TPM0_IRQn, 128); // 0, 64, 128 or 192
	NVIC_ClearPendingIRQ(TPM0_IRQn); 
	NVIC_EnableIRQ(TPM0_IRQn);	
}
Пример #7
0
void initializeClock(){

	/**
	 * @brief Setup the microcontroller system.
	 *
	 * Typically this function configures the oscillator (PLL) that is part of the
	 * microcontroller device. For systems with variable clock speed it also updates
	 * the variable SystemCoreClock. SystemInit is called from startup_device file.
	 */
	SystemInit();	// Initialize the system


	/**
	 * @brief Updates the SystemCoreClock variable.
	 *
	 * It must be called whenever the core clock is changed during program
	 * execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
	 * the current core clock.
	 */
	void SystemCoreClockUpdate (void);

	/*
	 * Enable the internal 4 MHz clock clock and select it as the MCGIRCLK clock
	 */
    MCG_BASE_PTR->C1 = MCG_C1_IREFS_MASK | MCG_C1_IRCLKEN_MASK;
    MCG_BASE_PTR->C2 = MCG_C2_IRCS_MASK; 									//Select fast internal clock

    // Send the clock signal to TPM0, TPM1, and TPM2
    SIM_BASE_PTR->SCGC6 |= SIM_SCGC6_TPM0_MASK | SIM_SCGC6_TPM1_MASK | SIM_SCGC6_TPM2_MASK;
    SIM_BASE_PTR->SOPT2 |= SIM_SOPT2_TPMSRC(3);								// TPM Clock source select: 3 = MCGIRCLK
}
Пример #8
0
int TPM_init_IC(TPM_MemMapPtr TPMx, int  clock_source, int modulo, int clock_mode, int ps)
{
	int val = 1;
	int i;
	if(TPMx == TPM0_BASE_PTR)
		SIM_SCGC6	|= SIM_SCGC6_TPM0_MASK;
	else if(TPMx == TPM1_BASE_PTR)
		SIM_SCGC6	|= SIM_SCGC6_TPM1_MASK;
	else
		SIM_SCGC6	|= SIM_SCGC6_TPM2_MASK;
	
	SIM_SOPT2	|= SIM_SOPT2_TPMSRC(clock_source);
	
	TPM_MOD_REG(TPMx)  	=  modulo;
	
	TPM_SC_REG(TPMx)	= TPM_SC_TOIE_MASK | TPM_SC_CMOD(clock_mode) | TPM_SC_PS(ps);
	
	i= ps;
	
	while(i--)
	{
		val += val;
	}
	
	val=(mcg_clk_hz/2)/val;
	
	return val;
}
	void Init_RGB_LEDs(void) {
		SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTD_MASK;
		SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK | SIM_SCGC6_TPM2_MASK;
		SIM->SOPT2 |= SIM_SOPT2_TPMSRC(2);

		PORTB->PCR[18] &= ~PORT_PCR_MUX_MASK;  		
		PORTB->PCR[18] |= PORT_PCR_MUX(3);  			// TPM2_CH0 enable on PTB18
		PORTB->PCR[19] &= ~PORT_PCR_MUX_MASK;  
		PORTB->PCR[19] |= PORT_PCR_MUX(3);  			// TPM2_CH1 enable on PTB19
		PORTD->PCR[1] &= ~PORT_PCR_MUX_MASK;  
		PORTD->PCR[1] |= PORT_PCR_MUX(4);  				// TPM0_CH1 enable on PTD1

		TPM0->MOD  = TPM_MODULE;   								// 0x0063 / 25MHz = 4uS PWM period
		TPM0->CONTROLS[1].CnSC = TPM_Cn_MODE;  		// No Interrupts; High True pulses on Edge Aligned PWM
		TPM0->CONTROLS[1].CnV  = TPM_INIT_VAL; 		// set to initial duty cycle

		TPM2->MOD  = TPM_MODULE;   								// 0x0063 / 25MHz = 4uS PWM period */
		TPM2->CONTROLS[0].CnSC = TPM_Cn_MODE;  		// No Interrupts; High True pulses on Edge Aligned PWM
		TPM2->CONTROLS[0].CnV  = TPM_INIT_VAL; 		// set to initial duty cycle
		TPM2->CONTROLS[1].CnSC = TPM_Cn_MODE;  		// No Interrupts; High True pulses on Edge Aligned PWM
		TPM2->CONTROLS[1].CnV  = TPM_INIT_VAL; 		// set to initial duty cycle

		TPM2->SC = TPM_SC_CMOD(1) | TPM_SC_PS(0);  // Edge Aligned PWM running from BUSCLK
		TPM0->SC = TPM_SC_CMOD(1) | TPM_SC_PS(0);  // Edge Aligned PWM running from BUSCLK
	}
Пример #10
0
Файл: main.c Проект: Imajie/ARM
void init_PWM(void)
{
	// setup timer for PWM
	
	// set module clock to FLL
	SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1);
	
	// turn on TPM clock
	SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK;

	// turn off module clock
	TPM0_SC &= ~(TPM_SC_CMOD_MASK);

	// wait for counter to turn off
	while( TPM0_SC & TPM_SC_CMOD_MASK );
	
	// set MSB, set ELSB
	TPM0_C0SC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK);

	// Set the PWM period
	TPM0_MOD = 1000;

	// Set the initial value
	TPM0_C0V = 500;

	// Clear the counter
	TPM0_CNT = 0;

	// counter increments on TPM clock, PreScale = /1
	TPM0_SC = (TPM_SC_CMOD(1) | TPM_SC_PS(0));

	SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK;
	
	PORTC_PCR1 = PORT_PCR_MUX(4);		// Set PTC1 to TPM0_CH0
}
Пример #11
0
/* Initialize the turning servo with the TPM module.
 * Sets up the timer clock and aligns servo to center
 */
void InitServo() {
	SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK;
	SIM_SOPT2 &= ~(SIM_SOPT2_TPMSRC_MASK);
	SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1);

	SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK;

	TPM1_SC = 0;
	TPM1_CONF = 0;

	TPM1_SC = TPM_SC_PS(SERVO_CLK_PRESCALE);
	TPM1_SC |= TPM_SC_TOIE_MASK;

	TPM1_MOD = SERVO_CLK / (1 << (SERVO_CLK_PRESCALE + 1)) / SERVO_FREQ;

	TPM1_C0SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;
	TPM1_C1SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;

	SetServo(0.0);

	TPM1_SC |= TPM_SC_CMOD(1);

	enable_irq(INT_TPM1 - 16);

	PORTB_PCR0 = PORT_PCR_MUX(3);
}
Пример #12
0
void pwmout_init(pwmout_t* obj, PinName pin) {
    // determine the channel
    PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
    if (pwm == (uint32_t)NC) {
        error("PwmOut pin mapping failed");
    }

    unsigned int port = (unsigned int)pin >> PORT_SHIFT;
    unsigned int tpm_n = (pwm >> TPM_SHIFT);
    unsigned int ch_n = (pwm & 0xFF);

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

    TPM_Type *tpm = (TPM_Type *)(TPM0_BASE + 0x1000 * tpm_n);
    tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(6); // (48)MHz / 64 = (0.75)MHz
    tpm->CONTROLS[ch_n].CnSC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK); // No Interrupts; High True pulses on Edge Aligned PWM

    obj->CnV = &tpm->CONTROLS[ch_n].CnV;
    obj->MOD = &tpm->MOD;
    obj->CNT = &tpm->CNT;

    // default to 20ms: standard for servos, and fine for e.g. brightness control
    pwmout_period_ms(obj, 20);
    pwmout_write(obj, 0);

    // Wire pinout
    pinmap_pinout(pin, PinMap_PWM);
}
Пример #13
0
void TFC_InitServos()
{
               
               //Clock Setup for the TPM requires a couple steps.
               
    
				
               //1st,  set the clock mux
               //See Page 124 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012
               SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK;// We Want MCGPLLCLK/2 (See Page 196 of the KL25 Sub-Family Reference Manual, Rev. 3, September 2012)
               SIM_SOPT2 &= ~(SIM_SOPT2_TPMSRC_MASK);
               SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1); //We want the MCGPLLCLK/2 (See Page 196 of the KL25 Sub-Family Reference Manual, Rev. 3, September 2012)
  

				//Enable the Clock to the FTM1 Module
				//See Page 207 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012
				SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK; 
               
               //The TPM Module has Clock.  Now set up the peripheral
               
               //Blow away the control registers to ensure that the counter is not running
               TPM1_SC = 0;
               TPM1_CONF = 0;
               
               //While the counter is disabled we can setup the prescaler
               
               TPM1_SC = TPM_SC_PS(FTM1_CLK_PRESCALE);
               TPM1_SC |= TPM_SC_TOIE_MASK; //Enable Interrupts for the Timer Overflow
               
               //Setup the mod register to get the correct PWM Period
               
               TPM1_MOD = FTM1_CLOCK/(1<<(FTM1_CLK_PRESCALE+1))/FTM1_OVERFLOW_FREQUENCY;
               
               //Setup Channels 0 and 1
               
               TPM1_C0SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;
               TPM1_C1SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;
               
               //Enable the Counter
               
               //Set the Default duty cycle to servo neutral
               TFC_SetServo(0, 0.0);
               TFC_SetServo(1, 0.0);
               
               //Enable the TPM COunter
               TPM1_SC |= TPM_SC_CMOD(1);
               
               //Enable TPM1 IRQ on the NVIC
               enable_irq (INT_TPM1-16);
              
               //Enable the FTM functions on the the port
               
               PORTB_PCR0 = PORT_PCR_MUX(3);
               PORTB_PCR1 = PORT_PCR_MUX(3);
                              
}
Пример #14
0
void TFC_InitMotorPWM()
{
	//Clock Setup for the TPM requires a couple steps.

	
    //1st,  set the clock mux
    //See Page 124 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012
    SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK;// We Want MCGPLLCLK/2 (See Page 196 of the KL25 Sub-Family Reference Manual, Rev. 3, September 2012)
    SIM_SOPT2 &= ~(SIM_SOPT2_TPMSRC_MASK);
    SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1); //We want the MCGPLLCLK/2 (See Page 196 of the KL25 Sub-Family Reference Manual, Rev. 3, September 2012)


	//Enable the Clock to the FTM0 Module
	//See Page 207 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012
	SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK;
    
    //The TPM Module has Clock.  Now set up the peripheral
    
    //Blow away the control registers to ensure that the counter is not running
    TPM0_SC = 0;
    TPM0_CONF = 0;
    
    //Set TPM module to continue in debug mode
    TPM0_CONF |= 0x00000060;
    
    //While the counter is disabled we can setup the prescaler
    
    TPM0_SC = TPM_SC_PS(FTM0_CLK_PRESCALE);
    
    //Setup the mod register to get the correct PWM Period
    
    TPM0_MOD = FTM0_CLOCK/(1<<FTM0_CLK_PRESCALE)/FTM0_OVERFLOW_FREQUENCY;
    
    //Setup Channels 0,1,2,3
    TPM0_C0SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;
    TPM0_C1SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;
    TPM0_C2SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;
    TPM0_C3SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK;
    
    
    //Enable the Counter
    
    //Set the Default duty cycle to 50% duty cycle
    TFC_SetMotorPWM(0.0,0.0);
    
    //Enable the TPM Counter
    TPM0_SC |= TPM_SC_CMOD(1);
    
    
    //Enable the FTM functions on the the port
    PORTC_PCR1 = PORT_PCR_MUX(4);
    PORTC_PCR2 = PORT_PCR_MUX(4);     
    PORTC_PCR3 = PORT_PCR_MUX(4);  
    PORTC_PCR4 = PORT_PCR_MUX(4);
}
Пример #15
0
/**
 **===========================================================================
 **  Reset handler
 **===========================================================================
 */
void __init_hardware(void) {
	/* This is a cleaned up output of Processor Expert generated code */

	/* Set the interrupt vector table position */
	SCB_VTOR = (uint32_t)__vector_table;
#if 0
	/* Disable the WDOG module */
	SIM_COPC = SIM_COPC_COPT(0x00);                                   
#endif
	/* System clock initialization */
	/* Enable clock gate for ports to enable pin routing */
	SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;
	/* Update system prescalers */
	SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x01);
	/* Select FLL as a clock source for various peripherals */
	SIM_SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK;
	/* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */
	SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03);
	/* Set the TPM clock */
	SIM_SOPT2 &= ~SIM_SOPT2_TPMSRC(0x01);
	SIM_SOPT2 |= SIM_SOPT2_TPMSRC(0x02);
	/* Enable XTAL IO pins */
	PORTA_PCR18 = PORT_PCR_MUX(0);
	PORTA_PCR19 = PORT_PCR_MUX(0);

	/* Switch to FBE Mode */
	MCG_C2 = MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK;
	OSC0_CR = OSC_CR_ERCLKEN_MASK;
	MCG_C1 = MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK;
	MCG_C4 &= ~MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03);
	MCG_C5 = MCG_C5_PRDIV0(0x03);
	MCG_C6 = MCG_C6_VDIV0(0x00);
	
	/* Check that the source of the FLL reference clock is the external reference clock. */
	while((MCG_S & MCG_S_IREFST_MASK) != 0x00U);
	/* Wait until external reference clock is selected as MCG output */
	while((MCG_S & 0x0CU) != 0x08U);

	/* Switch to PBE Mode */
	MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x00));
	/* Wait until external reference clock is selected as MCG output */
	while((MCG_S & 0x0CU) != 0x08U);
	/* Wait until locked */
	while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U);

	/* Switch to PEE Mode */
	MCG_C1 = MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK;
	/* Wait until output of the PLL is selected */
	while((MCG_S & 0x0CU) != 0x0CU);
}
void Timer_TPM::__init_timer() {    
    //Set TPM clocks
    SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); //Set TPM global clock source: MCGFLLCLK
    SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK; //Enable TPM block (clock gating)

    TPM0->SC = 0; //Reset TPM
    
    //Configure TPM prescaler
    TPM0->SC = TPM_SC_PS(0); //Prescaler set to 1
    
    TPM0->CNT = 0; //Set the count register
    
    //Set interrupt handler
    NVIC_SetVector(TPM0_IRQn, (uint32_t) __tpm_isr_wrapper);
    NVIC_EnableIRQ(TPM0_IRQn);
}
Пример #17
0
void TPM_init_PWM(TPM_MemMapPtr TPMx, int  clock_source, int module, int clock_mode, int ps, int counting_mode)
{
	if(TPMx == TPM0_BASE_PTR)
		SIM_SCGC6	|= SIM_SCGC6_TPM0_MASK;
	else if(TPMx == TPM1_BASE_PTR)
		SIM_SCGC6	|= SIM_SCGC6_TPM1_MASK;
	else
		SIM_SCGC6	|= SIM_SCGC6_TPM2_MASK;
	
	SIM_SOPT2	|= SIM_SOPT2_TPMSRC(clock_source);
	
	TPM_MOD_REG(TPMx)  	=  module;
	
	TPM_SC_REG(TPMx)	|= TPM_SC_CMOD(clock_mode) | TPM_SC_PS(ps);
	
	if(counting_mode)
		TPM_SC_REG(TPMx) |= TPM_SC_CPWMS_MASK;
}
Пример #18
0
void cfgPWM(void)
{
	//Select the CLK for the TPM Module - page 196
	SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1);
	
	/* Explanation about symbols
	x |= 0x01
	x = x | 0x01
	
	x &= ~0x01
	x = x & ~0x01
	x = x & 0xFE
	*/

	// Selects the MCGFLLCLK clock 
	SIM_SOPT2 &= ~(SIM_SOPT2_PLLFLLSEL_MASK); 
	
	//Clear counter register - page 553
	TPM2_CNT = 0;	
	//Set signal period to 1 ms
	TPM2_MOD = 1000;	
	//See page 552 for TPMx_SC configuration
	//(freq = ?)
	TPM2_SC = 0x0B;	
	//See page 556 for TPMx_CnSC configuration
	TPM2_C0SC = 0x28;		//0010 1000
	//See page 556 for TPMx_CnSC configuration
	TPM2_C1SC = 0x28;		//0010 1000
	
	
	//Clear counter register - page 553
	TPM0_CNT = 0;	
	//Set signal period to 1 ms
	TPM0_MOD = 1000;	
	//See page 552 for TPMx_SC configuration
	//(freq = ?)
	TPM0_SC = 0x0B;	
	//See page 556 for TPMx_CnSC configuration
	TPM0_C1SC = 0x28;		//0010 1000	
	
	TPM2_C0V = 1000;			//red
	TPM2_C1V = 1000;			//gren
	TPM0_C1V = 0;			//blue
}
Пример #19
0
/*configures TPM0_CH3   green LED to be PWM controlled*/
void tpm_init(void)
{
   SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK;   //enable TPM clock gate
   SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1) | SIM_SOPT2_PLLFLLSEL_MASK;  //select PLL as clock source of 
   
   TPM0_MOD = 1000;  
   
#ifdef FRDM_REVA   
   TPM0_C3SC = TPM_CnSC_MSB_MASK |TPM_CnSC_ELSB_MASK;  //PWM edge aligned
   TPM0_C3V = 500;
#else
   TPM0_C5SC = TPM_CnSC_MSB_MASK |TPM_CnSC_ELSB_MASK;  //PWM edge aligned
   TPM0_C5V = 500;
  
#endif
   
    TPM0_SC |= TPM_SC_PS(0) | TPM_SC_CMOD(1);
  
}
Пример #20
0
void TPM_vfnInit(uint8_t bTPMToEnable, uint8_t bTPMClockSource, uint16_t wTPMModulo)
{
	uint32_t * pdwTPM_ModRegister;
	
	/* Confirm the TPM to be enable is within the available on the SoC */
	if(bTPMToEnable < MAX_TPM)
	{
		
		SIM_SCGC6 |= TPM_gadwClockGateMask[bTPMToEnable];
		
		/* Select the TPM clock source and load the period*/
		SIM_SOPT2 |= SIM_SOPT2_TPMSRC(bTPMClockSource);
		
		pdwTPM_ModRegister = (uint32_t*)TPM_gapdwRegisters[bTPMToEnable][TPM_MOD];
		
		
		*pdwTPM_ModRegister = wTPMModulo;
	}
		
}
Пример #21
0
void tpm_init(void){
	
		PORTD->PCR[5] = PORT_PCR_MUX(4);  //TPM0_CH5
		PORTE->PCR[29] = PORT_PCR_MUX(3); //TPM0_CH2 
	
		SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK; //dolaczenie sygnalu taktujacego do modulu TMP

		SIM->SCGC5 |=  (SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK); //dolaczenie sygnalu taktujacego do portu D i E, zrobione tez w leds initializze
	
	
		SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // MCGFLLCLK clock or MCGPLLCLK/2
		SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; //MCGPLLCLK clock with fixed divide by two
	
		TPM0->MOD = TPM_MOD_MOD(4095); 
		TPM0->CNT |=  TPM_CNT_COUNT_SHIFT; //reset counter

		//edge aligned pwm
		
		TPM0->CONTROLS[2].CnSC |= TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; //high true pulses
		TPM0->CONTROLS[5].CnSC |= TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK | TPM_CnSC_ELSA_MASK; //low true pulses
		
		//edge aligned pwm end
		
		//center aligned PWM
		/*
		TPM0->CONTROLS[2].CnSC |= TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; //high-true pulses
		TPM0->CONTROLS[5].CnSC |= TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK; //low true pulses
		*/
		//center aligned PWM end
	
		TPM0->CONTROLS[2].CnV = TPM_CnV_VAL(0); //poczatkowa wartosc wspolczyynika wypelninia	
		TPM0->CONTROLS[5].CnV = TPM_CnV_VAL(0); //poczatkowa wartosc wspolczyynika wypelninia


		TPM0->SC = TPM_SC_PS(0x07) | TPM_SC_CPWMS_MASK | TPM_SC_CMOD(0x01); 
		//divide by 128 !!
		//upcounting
	  //increment every counter clock
}
Пример #22
0
Файл: tpm.c Проект: zwzmzd/kl02z
static void _TPM_InitBasic(uint32_t instance, uint32_t modulo, TPM_ClockDiv_Type ps)
{
    /* enable clock gate */
    *(uint32_t*)SIM_TPMClockGateTable[instance].addr |= SIM_TPMClockGateTable[instance].mask;
    
    /* disable FTM, we must set CLKS(0) before config FTM! */
    TPM_InstanceTable[instance]->SC = 0;
     
    /* set CNT and CNTIN */
    TPM_InstanceTable[instance]->CNT = 0;
    
    /* set modulo */
    TPM_InstanceTable[instance]->MOD = modulo;
    
    /* set FTM clock to system clock */
    SIM->SOPT2 &= ~SIM_SOPT2_TPMSRC_MASK;
    SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1);
    
    /* set ps, this must be done after set modulo */
    TPM_InstanceTable[instance]->SC &= ~TPM_SC_PS_MASK;
    TPM_InstanceTable[instance]->SC |= TPM_SC_PS(ps); 
    
}
Пример #23
0
void Echo_init(void){

	// PORTE 20 CONFIG (TPM1 Channel 0)
	
	SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK;
	
	PORTE->PCR[ECHO_PIN] |= PORT_PCR_MUX(0x03);											 
											 		
											 

	

	
//***************************************************************
	
// TPM1 CONFIG

	SIM->SOPT2 |= SIM_SOPT2_TPMSRC(3);	   // MCGIRC 
       
	MCG->C1 |= MCG_C1_IRCLKEN_MASK; 		   // MCGIRCLK active.
	MCG->C2 |= MCG_C2_IRCS_MASK;										// External FAST (4MHz) reference clock is selected.
	
	SIM->SCGC6 |= SIM_SCGC6_TPM1_MASK;

	TPM1->SC |= TPM_SC_PS(1)            // Divide by 2  (1MHz)
		   | TPM_SC_CMOD(0x01);	  	// Enabling TPM1 

	NVIC_ClearPendingIRQ(TPM1_IRQn);					
	NVIC_EnableIRQ(TPM1_IRQn);
	NVIC_SetPriority(TPM1_IRQn, 1);
	
	TPM1->CONTROLS[0].CnSC |= TPM_CnSC_ELSA_MASK		// Input capture -> every edge
				     | TPM_CnSC_ELSB_MASK
				     | TPM_CnSC_CHIE_MASK;			// Channel int. enabled
										 
}
Пример #24
0
/*! Sets up the clock for USB operation (out of RESET)
 *!
 *! MCGOUTCLK = 48MHz
 *! core/platform/system clock = PLL (48MHz), 
 *! bus clock = PLL (48MHz),
 *! flash clock = PLL/2 (24MHz)
 *!
 *! Assumes 8 MHz external crystal
 *!
 *! Modes: FEI [FLL engaged internal] -> 
 *!        FBE [FLL bypassed external] ->
 *!        PBE [PLL bypassed external] ->
 *!        PEE [PLL engaged external]
 *!
 *! Refer 24.5.3.1 of K20 Family reference
 */
void initClock(void) {
   MCG_C7 = 0; // OSCSEL = 0 => Crystal Osc
   
   // Out of reset MCG is in FEI mode
   // Configure the Crystal Oscillator
   OSC0_CR = OSC_CR_SC16P_MASK;
   
   // 1. Switch from FEI (FLL engaged internal) to FBE (FLL bypassed external)
   
   // 1 a) Set up crystal 
   MCG_C2 =                         // oscillator in low power mode (w/o Rf)
            MCG_C2_EREFS0_MASK |    // because crystal is being used
            MCG_C2_RANGE0(1)   |    // 4 or 8 MHz is in high frequency range
            MCG_C2_IRCS_MASK;
 
   // 1 b) Select clock mode
   MCG_C1 =  MCG_C1_CLKS(2)            |  // CLKS = 10   -> External reference clock
             MCG_C1_FRDIV(FRDIV_VALUE) |  // FRDIV = 2,3   -> 8MHz,4MHz/256 = 31.25 kHz
             MCG_C1_IRCLKEN_MASK;         // IRCLKEN = 1 -> MCGIRCLK active
   
   // Make sure - reset default
   MCG_C4 &= ~(MCG_C4_DMX32_MASK|MCG_C4_DRST_DRS_MASK);
   
   // 1 c) Wait for crystal to start up        
   while ((MCG_S & MCG_S_OSCINIT0_MASK) == 0) {
   }
   // 1 d) Wait for mode change
   while ((MCG_S & MCG_S_IREFST_MASK) != 0) {
   }
   // 1 e) Wait for MCGOUT indicating that the external reference to be fed to MCGOUT
   while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) {
   }
   
   // 2. Configure PLL Ref. Freq.
   
   // 2 a) Set PRDIV for correct range
   MCG_C5 =  MCG_C5_PLLCLKEN0_MASK |
             MCG_C5_PRDIV0(PRDIV_VALUE);    // PRDIV=3,1, PLL Ref Freq. = 8MHz,4MHz/4 => 2 MHz

   MCG_C6 = 0;
   
   // 3. FBE => BLPE => PBE
   // 3 a) BLPE
   MCG_C2 =                         // oscillator in low power mode (w/o external Rf)
            MCG_C2_EREFS0_MASK |    // because crystal is being used
            MCG_C2_RANGE0(1)   |    // 4 or 8 MHz is in high frequency range
            MCG_C2_IRCS_MASK ;
   // 3 b) BLPE/PBE
   MCG_C6 = MCG_C6_PLLS_MASK|MCG_C6_VDIV0(0); // 2MHz x 24 = 96MHz
   // 3 c) BPE
   MCG_C2 =                         // oscillator in low power mode (w/o Rf)
            MCG_C2_EREFS0_MASK |    // because crystal is being used
            MCG_C2_RANGE0(1)   |    // 4 or 8 MHz is in high frequency range
            MCG_C2_IRCS_MASK;
   // 3 d) Wait until PLLS clock source changes to the PLL
   while((MCG_S & MCG_S_PLLST_MASK) == 0) {
   }
   // 3 e)  Wait for PLL to acquired lock
   while((MCG_S & MCG_S_LOCK0_MASK) == 0) {
   }
   // Set up the SIM clock dividers BEFORE switching to the PLL to ensure the
   // system clock speeds are in spec.
#if 1 || (CPU == MK20D5)
   {
   // Disable Flash pre-fetch while changing flash divider
   uint32_t temp = FMC_PFAPR;
   FMC_PFAPR |= FMC_PFAPR_M3AP_MASK|FMC_PFAPR_M2AP_MASK|FMC_PFAPR_M1AP_MASK|FMC_PFAPR_M0AP_MASK;
   // core/platform/system clock = PLL (48MHz), bus clock = PLL (48MHz), flash clock = PLL/2 (24MHz)
   SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(1);
   FMC_PFAPR = temp;
   }
#elif CPU == MKL25Z4
   {
   // Disable Flash pre-fetch while changing flash divider
   uint32_t temp = FMC_PFAPR;
   FMC_PFAPR |= FMC_PFAPR_M3AP_MASK|FMC_PFAPR_M2AP_MASK|FMC_PFAPR_M1AP_MASK|FMC_PFAPR_M0AP_MASK;
   // core/platform/system clock = PLL/2 (48MHz), bus clock/flash clock = PLL/2/2 (24MHz)
   SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV4(1);
   FMC_PFAPR = temp;
   }
#endif
   
   // 4. PBE mode transitions into PEE mode:
   // 4 a) Select clock mode
   MCG_C1 = MCG_C1_CLKS(0)  |    // CLKS  = 0 -> FLL or PLL is selected
            MCG_C1_FRDIV(FRDIV_VALUE) |  // FRDIV = 2,3   -> 8MHz,4MHz/256 = 31.25 kHz
            MCG_C1_IRCLKEN_MASK;
   
   // 4 b)  Wait for clock stable
   while ((MCG_S & MCG_S_CLKST_MASK) != (3<<MCG_S_CLKST_SHIFT)) {
   }
   // Now MCGOUTCLK=MCGPLLCLK=[(2 MHz / 1) * 24] = 48 MHz
   
   // Basic clock selection
#if 1 || (CPU == MK20D5)
   // Peripheral clock choice (incl. USB), USBCLK = MCGCLK
   SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK | // PLL rather than FLL for peripheral clock
                SIM_SOPT2_USBSRC_MASK;     // MCGPLLCLK Source as USB clock (48MHz req.)
   
   // USB Clock = Divider input clock x [(USBFRAC+1)/(USBDIV+1)] 
   // USBDIV 0-7, USBFRAC 0-1
//   SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1);
   SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(0);

#elif CPU == MKL25Z4 
   SIM_SOPT2 = SIM_SOPT2_UART0SRC(1)     | // MCGPLLCLK/2 as UART0 clock
		         SIM_SOPT2_TPMSRC(1)       | // MCGPLLCLK/2 as TPM clock
			      SIM_SOPT2_PLLFLLSEL_MASK  | // PLL rather than FLL for peripheral clock 
               SIM_SOPT2_USBSRC_MASK;      // MCGPLLCLK/2 Source as USB clock (48MHz req.)
#else
   #error "CPU not set"
#endif
}
Пример #25
0
/*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. !!! ***/

}
Пример #26
0
/** init the timer TPM1 for measuring temperature using input capture
 *
 */
void smt160_init()
{
    int prio = 2;	// priorita interruptu; 0 az 3, 0 = max

    /* Initialize our global variables */
    gsmt_start = 0;
    gsmt_pulse = 0;
    gsmt_period = 0;
    gsmt_tmp_pulse = 0;
    gsmt_pulses = 0;
    gsmt_period_sum = 0;
    gsmt_sumcnt = 0;

    /* Enable Port A clock (pins used for input capture) */
    SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;

    /* enable input pins for TPM1 channels 0 and 1
      The timer channel is Alt 3 function of the pins */
    PORTA_PCR12 = PORT_PCR_MUX(3);		/* PTA12 = channel 0 for TPM1 */
    PORTA_PCR13 = PORT_PCR_MUX(1);		/* using PTA13 as GPIO for deciding falling/rising */
    GPIOA_PDDR &= ~(1 << SMT160_INPUT_PIN_NO);			/* set PTA13 to input mode */

    /* Enable clock for timer TMP1 */
    SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK;
    /* and clock source */
    SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1); // select the PLLFLLCLK as TPM clock source

    /*  Set timer to input capture mode etc. */
    TPM1_SC = TPM_SC_CMOD(1) | TPM_SC_PS(0);	//0x08;	// CMOD = 01, prescaler = 1

    /* test TOF interrupt
    TPM1_SC |= TPM_SC_TOIE_MASK;
    TPM1_MOD = 10000;
    */

#if 0
    // Input capture config
    // Version with 2 input pins used: channel 0 detects pulses, channel 1
    // detects period.
    TPM1_C0SC = 0;	/* clear any pending interrupt and set all values to default */
    TPM1_C0SC |= TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK;	/* input capture on falling and rising edges */
    TPM1_C0SC |= TPM_CnSC_CHIE_MASK;	/* enable channel interrupt */


    TPM1_C1SC = 0;	/* clear any pending interrupt and set all values to default */
    TPM1_C1SC |= TPM_CnSC_ELSA_MASK;	/* input capture on rising edges only */
    TPM1_C1SC |= TPM_CnSC_CHIE_MASK;	/* enable channel interrupt */
#endif

    // Input capture config
    // Version with 1 pin used; wait for rising edge
    TPM1_C0SC = 0;	/* clear any pending interrupt and set all values to default */
    /* input capture on rising and falling edge + enable channel interrupt */
    TPM1_C0SC |= TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK | TPM_CnSC_CHIE_MASK;


    // Enable the interrupt
    // Note: sample code package provides function for this in arm_cm0.c; (enable_irq(interrupt);)
    // CMSIS compatible environment should implement NVIC_EnableIRQ((IRQn_Type)interrupt);
    // In NVIC there are 32-bit registers where each bit corresponds to 1 interrupt
    // The number of the interrupt used in NVIC is "non-core" int number, which is the
    // absolute number - 16. (there are 16 core interrupts which are not controlled by NVIC)
    // ICPR register = clear pending flag (writing 1 clears pending interrupt)
    // ISER register = enable interrupt by writing 1 to its bit
    NVIC_ICPR |= (1 << (INT_TPM1 - 16) );	// clear possibly pending interrupt
    NVIC_ISER |= (1 << (INT_TPM1 - 16) );	// enable the interrupt

    // Set priority for the interrupt
    // Bit field starting location = 8 * (IRQ mod 4) + 6 =
    // Zde IRQ = 18 (cislo TPM1 int v MKL25Z4.h - 16)
    // start = 8 * 18 mod 4 + 6 = 8 * 2 + 6 = 22
    NVIC_IPR4 = ((prio & 0x03) << 22);

    EnableInterrupts;

}
Пример #27
0
void Boot_Init_Clock(void){
	
	  /* System clock initialization */
	  /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
	  SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x03)); /* Set the system prescalers to safe value */
	  /* SIM_SCGC5: PORTA=1 */
	  SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;   /* Enable clock gate for ports to enable pin routing */
	  if ((PMC_REGSC & PMC_REGSC_ACKISO_MASK) != 0x0U) {
	    /* PMC_REGSC: ACKISO=1 */
	    PMC_REGSC |= PMC_REGSC_ACKISO_MASK; /* Release IO pads after wakeup from VLLS mode. */
	  }
	  /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
	  SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x01)); /* Update system prescalers */
	  /* SIM_SOPT2: PLLFLLSEL=1 */
	  SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; /* Select PLL as a clock source for various peripherals */
	  /* SIM_SOPT1: OSC32KSEL=3 */
	  SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */
	  /* SIM_SOPT2: TPMSRC=1 */
	  SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(
	               SIM_SOPT2_TPMSRC(0x02)
	              )) | (uint32_t)(
	               SIM_SOPT2_TPMSRC(0x01)
	              ));                      /* Set the TPM clock */
	  /* PORTA_PCR18: ISF=0,MUX=0 */
	  PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));
	  /* PORTA_PCR19: ISF=0,MUX=0 */
	  PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));
	  /* Switch to FBE Mode */
	  /* MCG_C2: LOCRE0=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */
	  MCG_C2 = (uint8_t)((MCG_C2 & (uint8_t)~(uint8_t)(
	            MCG_C2_LOCRE0_MASK |
	            MCG_C2_RANGE0(0x01) |
	            MCG_C2_HGO0_MASK |
	            MCG_C2_LP_MASK |
	            MCG_C2_IRCS_MASK
	           )) | (uint8_t)(
	            MCG_C2_RANGE0(0x02) |
	            MCG_C2_EREFS0_MASK
	           ));
	  /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
	  OSC0_CR = OSC_CR_ERCLKEN_MASK;
	  /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
	  MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
	  /* MCG_C4: DMX32=0,DRST_DRS=0 */
	  MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
	  /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=3 */
	  MCG_C5 = MCG_C5_PRDIV0(0x03);
	  /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
	  MCG_C6 = MCG_C6_VDIV0(0x00);
	  while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */
	  }
	  while((MCG_S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */
	  }
	  /* Switch to PBE Mode */
	  /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0 */
	  MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x00));
	  while((MCG_S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */
	  }
	  while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */
	  }
	  /* Switch to PEE Mode */
	  /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
	  MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
	  while((MCG_S & 0x0CU) != 0x0CU) {    /* Wait until output of the PLL is selected */
	  }
	  /* MCG_C6: CME0=1 */
	  MCG_C6 |= MCG_C6_CME0_MASK;          /* Enable the clock monitor */
	  /*** End of PE initialization code after reset ***/
}
Пример #28
0
/**
 * @brief   KL2x clocks and PLL initialization.
 * @note    All the involved constants come from the file @p board.h.
 * @note    This function should be invoked just after the system reset.
 *
 * @special
 */
void kl2x_clock_init(void) {
#if !KINETIS_NO_INIT
  /* Disable COP watchdog */
  SIM->COPC = 0;

  /* Enable PORTA */
  SIM->SCGC5 |= SIM_SCGC5_PORTA;

  /* --- MCG mode: FEI (default out of reset) ---
     f_MCGOUTCLK = f_int * F
     F is the FLL factor selected by C4[DRST_DRS] and C4[DMX32] bits.
     Typical f_MCGOUTCLK = 21 MHz immediately after reset.
     C4[DMX32]=0 and C4[DRST_DRS]=00  =>  FLL factor=640.
     C3[SCTRIM] and C4[SCFTRIM] factory trim values apply to f_int. */

  /* System oscillator drives 32 kHz clock (OSC32KSEL=0) */
  SIM->SOPT1 &= ~SIM_SOPT1_OSC32KSEL_MASK;

#if KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEI
  /* This is the default mode at reset. */
  /* The MCGOUTCLK is divided by OUTDIV1 and OUTDIV4:
   * OUTDIV1 (divider for core/system and bus/flash clock)
   * OUTDIV4 (additional divider for bus/flash clock) */
  SIM->CLKDIV1 =
          SIM_CLKDIV1_OUTDIV1(1) |  /* OUTDIV1 = divide-by-2 => 24 MHz */
          SIM_CLKDIV1_OUTDIV4(0);   /* OUTDIV4 = divide-by-1 => 24 MHz */

#elif KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEE
  /*
   * FLL Enabled External (FEE) MCG Mode
   * 24 MHz core, 12 MHz bus - using 32.768 kHz crystal with FLL.
   * f_MCGOUTCLK = (f_ext / FLL_R) * F
   *             = (32.768 kHz ) *
   *  FLL_R is the reference divider selected by C1[FRDIV]
   *  F is the FLL factor selected by C4[DRST_DRS] and C4[DMX32].
   *
   * Then the core/system and bus/flash clocks are divided:
   *   f_SYS = f_MCGOUTCLK / OUTDIV1 = 48 MHz / 1 = 48 MHz
   *   f_BUS = f_MCGOUTCLK / OUTDIV1 / OUTDIV4 =  MHz / 4 = 24 MHz
   */

  SIM->SOPT2 =
          SIM_SOPT2_TPMSRC(1);  /* MCGFLLCLK clock or MCGPLLCLK/2 */
          /* PLLFLLSEL=0 -> MCGFLLCLK */

  /* The MCGOUTCLK is divided by OUTDIV1 and OUTDIV4:
   * OUTDIV1 (divider for core/system and bus/flash clock)
   * OUTDIV4 (additional divider for bus/flash clock) */
  SIM->CLKDIV1 =
          SIM_CLKDIV1_OUTDIV1(KINETIS_MCG_FLL_OUTDIV1 - 1) |
          SIM_CLKDIV1_OUTDIV4(KINETIS_MCG_FLL_OUTDIV4 - 1);

  /* EXTAL0 and XTAL0 */
  PORTA->PCR[18] &= ~0x01000700; /* Set PA18 to analog (default) */
  PORTA->PCR[19] &= ~0x01000700; /* Set PA19 to analog (default) */

  OSC0->CR = 0;

  /* From KL25P80M48SF0RM section 24.5.1.1 "Initializing the MCG". */
  /* To change from FEI mode to FEE mode: */
  /* (1) Select the external clock source in C2 register.
         Use low-power OSC mode (HGO0=0) which enables internal feedback
         resistor, for 32.768 kHz crystal configuration.  */
  MCG->C2 =
          MCG_C2_RANGE0(0) |  /* low frequency range (<= 40 kHz) */
          MCG_C2_EREFS0;      /* external reference (using a crystal) */
  /* (2) Write to C1 to select the clock mode. */
  MCG->C1 = /* Clear the IREFS bit to switch to the external reference. */
          MCG_C1_CLKS_FLLPLL |  /* Use FLL for system clock, MCGCLKOUT. */
          MCG_C1_FRDIV(0);      /* Don't divide 32kHz ERCLK FLL reference. */
  MCG->C6 = 0;  /* PLLS=0: Select FLL as MCG source, not PLL */

  /* Loop until S[OSCINIT0] is 1, indicating the
     crystal selected by C2[EREFS0] has been initialized. */
  while ((MCG->S & MCG_S_OSCINIT0) == 0)
    ;
  /* Loop until S[IREFST] is 0, indicating the
     external reference is the current reference clock source. */
  while ((MCG->S & MCG_S_IREFST) != 0)
    ;  /* Wait until external reference clock is FLL reference. */
  /* (1)(e) Loop until S[CLKST] indicates FLL feeds MCGOUTCLK. */
  while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_FLL)
    ;  /* Wait until FLL has been selected. */

  /* --- MCG mode: FEE --- */
  /* Set frequency range for DCO output (MCGFLLCLK). */
  MCG->C4 = (KINETIS_MCG_FLL_DMX32 ? MCG_C4_DMX32 : 0) |
            MCG_C4_DRST_DRS(KINETIS_MCG_FLL_DRS);

  /* Wait for the FLL lock time; t[fll_acquire][max] = 1 ms */
  /* TODO - not implemented - is it required? Freescale example code
     seems to omit it. */

#elif KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE
  /*
   * PLL Enabled External (PEE) MCG Mode
   * 48 MHz core, 24 MHz bus - using 8 MHz crystal with PLL.
   * f_MCGOUTCLK = (OSCCLK / PLL_R) * M
   *             =  8 MHz / 2 * 24 = 96 MHz
   *  PLL_R is the reference divider selected by C5[PRDIV0]
   *  M is the multiplier selected by C6[VDIV0]
   *
   * Then the core/system and bus/flash clocks are divided:
   *   f_SYS = f_MCGOUTCLK / OUTDIV1 = 96 MHz / 2 = 48 MHz
   *   f_BUS = f_MCGOUTCLK / OUTDIV1 / OUTDIV4 = 96 MHz / 4 = 24 MHz
   */

  /* The MCGOUTCLK is divided by OUTDIV1 and OUTDIV4:
   * OUTDIV1 (divider for core/system and bus/flash clock)
   * OUTDIV4 (additional divider for bus/flash clock) */
  SIM->CLKDIV1 =
          SIM_CLKDIV1_OUTDIV1(1) |  /* OUTDIV1 = divide-by-2 => 48 MHz */
          SIM_CLKDIV1_OUTDIV4(1);   /* OUTDIV4 = divide-by-2 => 24 MHz */

  SIM->SOPT2 =
          SIM_SOPT2_TPMSRC(1) | /* MCGFLLCLK clock or MCGPLLCLK/2 */
          SIM_SOPT2_PLLFLLSEL;  /* PLLFLLSEL=MCGPLLCLK/2 */

  /* EXTAL0 and XTAL0 */
  PORTA->PCR[18] &= ~0x01000700; /* Set PA18 to analog (default) */
  PORTA->PCR[19] &= ~0x01000700; /* Set PA19 to analog (default) */

  OSC0->CR = 0;

  /* From KL25P80M48SF0RM section 24.5.1.1 "Initializing the MCG". */
  /* To change from FEI mode to FBE mode: */
  /* (1) Select the external clock source in C2 register.
         Use low-power OSC mode (HGO0=0) which enables internal feedback
         resistor since FRDM-KL25Z has feedback resistor R25 unpopulated.
         Use high-gain mode by setting C2[HGO0] instead if external
         feedback resistor Rf is installed.  */
  MCG->C2 =
          MCG_C2_RANGE0(2) |  /* very high frequency range */
          MCG_C2_EREFS0;      /* external reference (using a crystal) */
  /* (2) Write to C1 to select the clock mode. */
  MCG->C1 = /* Clear the IREFS bit to switch to the external reference. */
          MCG_C1_CLKS_ERCLK |  /* Use ERCLK for system clock, MCGCLKOUT. */
          MCG_C1_FRDIV(3);     /* Divide ERCLK / 256 for FLL reference. */
  /* Note: FLL reference frequency must be 31.25 kHz to 39.0625 kHz.
     8 MHz / 256 = 31.25 kHz. */
  MCG->C4 &= ~(MCG_C4_DMX32 | MCG_C4_DRST_DRS_MASK);
  MCG->C6 = 0;  /* PLLS=0: Select FLL as MCG source, not PLL */

  /* (3) Once configuration is set, wait for MCG mode change. */

  /* From KL25P80M48SF0RM section 24.5.31: */
  /* (1)(c) Loop until S[OSCINIT0] is 1, indicating the
     crystal selected by C2[EREFS0] has been initialized. */
  while ((MCG->S & MCG_S_OSCINIT0) == 0)
    ;
  /* (1)(d) Loop until S[IREFST] is 0, indicating the
     external reference is the current reference clock source. */
  while ((MCG->S & MCG_S_IREFST) != 0)
    ;  /* Wait until external reference clock is FLL reference. */
  /* (1)(e) Loop until S[CLKST] is 2'b10, indicating
     the external reference clock is selected to feed MCGOUTCLK. */
  while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_ERCLK)
    ;  /* Wait until external reference clock has been selected. */

  /* --- MCG mode: FBE (FLL bypassed, external crystal) ---
     Now the MCG is in FBE mode.
     Although the FLL is bypassed, it is still on. */

  /* (2)    Then configure C5[PRDIV0] to generate the
     correct PLL reference frequency. */
  MCG->C5 = MCG_C5_PRDIV0(1);  /* PLL External Reference Divide by 2 */
  /* (3)    Then from FBE transition to PBE mode. */
  /* (3)(b) C6[PLLS]=1 to select PLL. */
  /* (3)(b) C6[VDIV0]=5'b0000 (x24) 2 MHz * 24 = 48 MHz. */
  MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0);
  /* (3)(d) Loop until S[PLLST], indicating PLL
     is the PLLS clock source. */
  while ((MCG->S & MCG_S_PLLST) == 0)
    ;  /* wait until PLL is the PLLS clock source. */
  /* (3)(e) Loop until S[LOCK0] is set, indicating the PLL has acquired lock. */
  /* PLL selected as MCG source. VDIV0=00000 (Multiply=24). */
  while ((MCG->S & MCG_S_LOCK0) == 0)
    ;  /* wait until PLL locked */

  /* --- MCG mode: PBE (PLL bypassed, external crystal) --- */

  /* (4)    Transition from PBE mode to PEE mode. */
  /* (4)(a) C1[CLKS] = 2'b00 to select PLL output as system clock source. */
  // Switch to PEE mode
  //    Select PLL output (CLKS=0)
  //    FLL external reference divider (FRDIV=3)
  //    External reference clock for FLL (IREFS=0)
  MCG->C1 = MCG_C1_CLKS(0) |
            MCG_C1_FRDIV(3);
  /* (4)(b) Loop until S[CLKST] are 2'b11, indicating the PLL output is selected for MCGOUTCLK. */
  while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL)
    ;  /* wait until clock switched to PLL output */

  /* --- MCG mode: PEE (PLL enabled, external crystal) --- */

#else /* KINETIS_MCG_MODE != KINETIS_MCG_MODE_PEE */
#error Unimplemented KINETIS_MCG_MODE
#endif /* KINETIS_MCG_MODE != KINETIS_MCG_MODE_PEE */

#endif /* !KINETIS_NO_INIT */
}