void clk_out_init(void)
{
   /* Enable the FB_CLKOUT function on PTC3 (alt5 function) */
   PORTA_PCR15 = ( PORT_PCR_MUX(0x3));

   /* Select the CLKOUT in the SMI_SOPT2 mux to be bus clk*/
   SIM_SOPT2 |= SIM_SOPT2_CLKOUTSEL(2);

}
Ejemplo n.º 2
0
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
   
}
Ejemplo n.º 3
0
void UARTinit()
{
 SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;                                                   
	
 /* PORTA_PCR1: ISF=0,MUX=2 */
 PORTA_PCR1 |= (PORT_PCR_MUX(2));
 
 /* PORTA_PCR2: ISF=0,MUX=2 */
 PORTA_PCR2 |= (PORT_PCR_MUX(2));

 /* Disable TX & RX while we configure settings */
 UART0_C2 &= ~(UART0_C2_TE_MASK); //disable transmitter
 UART0_C2 &= ~(UART0_C2_RE_MASK); //disable receiver
 
 /* UART0_C1: LOOPS=0,DOZEEN=0,RSRC=0,M=0,WAKE=0,ILT=0,PE=0,PT=0 */
 UART0_C1 = 0x00U; /* Set the C1 register */
 /* UART0_C3: R8T9=0,R9T8=0,TXDIR=0,TXINV=0,ORIE=0,NEIE=0,FEIE=0,PEIE=0 */
 UART0_C3 = 0x00U; /* Set the C3 register */
 /* UART0_S2: LBKDIF=0,RXEDGIF=0,MSBF=0,RXINV=0,RWUID=0,BRK13=0,LBKDE=0,RAF=0 */
 UART0_S2 = 0x00U; /* Set the S2 register */
 
 SIM_SOPT2 |= SIM_SOPT2_UART0SRC(1); //set clock source to be from PLL/FLL
 SIM_SOPT2 |= SIM_SOPT2_CLKOUTSEL(0b100);
 unsigned SBR = 546;//137; //Set the baud rate register, SBR = 137
 UART0_BDH |= (~UART0_BDH_SBR_MASK) | SBR >> 8;
 UART0_BDL |= (~UART0_BDL_SBR_MASK) | SBR;
 
 char OSR = 3; //set the oversampling ratio to option #3 = 4x
 UART0_C4 &= (~UART0_C4_OSR_MASK) | OSR;
 
 /*
 * Target Baud rate = 38400 9600
 *
 * Baud rate = baud clock / ((OSR+1) * SBR)
 * baud clock = FLL/PLL = 20.97152MHz  32kHZ
 * OSR = 3
 * SBR = 137 //546
 * Resulting Baud rate = 20.97152MHz / ((3 + 1) * 546) = 9600
 */
 
 UART0_C5 |= UART0_C5_BOTHEDGE_MASK; //enable sampling on both edges of the clock
 UART0_C2 |= UART0_C2_TE_MASK; //enable transmitter
 UART0_C2 |= UART0_C2_RE_MASK; //enable receiver
 
	
}
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) ;
}
Ejemplo n.º 5
0
void __startup(void) {
  // The CPU has a watchdog feature which is on by default,
  // so we have to configure it to not have nasty reset-surprises
  // later on.
  startup_watchdog_hook();

  // If the system was in VLLS mode, some peripherials and 
  // the I/O pins are in latched mode. We need to restore
  // config and can then acknowledge the isolation to get back
  // to normal. For now, we'll just ack TODO: properly do this
  if (PMC_REGSC & PMC_REGSC_ACKISO_MASK) PMC_REGSC |= PMC_REGSC_ACKISO_MASK;

  // There is a write-once-after-reset register that allows to
  // set which power states are available. Let's set it here.
  SMC_PMPROT = ENABLED_POWER_MODES;

  // For the sake of simplicity, enable all GPIO port clocks
  SIM_SCGC5 |= (  SIM_SCGC5_PORTA_MASK
                | SIM_SCGC5_PORTB_MASK
                | SIM_SCGC5_PORTC_MASK
	        | SIM_SCGC5_PORTD_MASK
	        | SIM_SCGC5_PORTE_MASK);

  // ----------------------------------------------------------------------------------
  // Setup clocks
  // ----------------------------------------------------------------------------------
  // See section 5 in the Freescale K20 manual for how clock distribution works
  // The limits are outlined in section 5.5:
  //   Core and System clocks: max 72 MHz
  //   Bus/peripherial clock:  max 50 MHz (integer divide of core)
  //   Flash clock:            max 25 MHz
  //
  // The teensy 3.x has a 16 MHz external oscillator
  // So we'll enable the external clock for the OSC module. Since
  // we're in high-frequency mode, also enable capacitors
  OSC_CR = OSC_CR_SC8P_MASK | OSC_CR_SC2P_MASK; // TODO This does not actually seem enable the ext crystal

  // Set MCG to very high frequency crystal and request oscillator. We have
  // to do this first so that the divisor will be correct (512 and not 16)
  MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS0_MASK;

  // Select the external reference clock for MCGOUTCLK
  // The divider for the FLL has to be chosen that we get something in 31.25 to 39.0625 kHz
  // 16MHz / 512 = 31.25 kHz -> set FRDIV to 4
  MCG_C1 =  MCG_C1_CLKS(2) | MCG_C1_FRDIV(4);

  // Wait for OSC to become ready
  while ((MCG_S & MCG_S_OSCINIT0_MASK) == 0) ;

  // Wait for the FLL to synchronize to external reference
  while ((MCG_S & MCG_S_IREFST_MASK) != 0) ;

  // Wait for the clock mode to synchronize to external
  while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ;

  // The clock is now in FBE mode

#if F_CPU <= 16000000
  // For 16 MHz and below, the crystal is fast enough
  // -> enable BLPE mode which will disable both FLL and PLL
  MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS_MASK | MCG_C2_LP_MASK;
#else
  // We need PLL to go above 16 MHz
  #if   F_CPU == 96000000
    MCG_C5 = MCG_C5_PRDIV0(3); // 16MHz / 4 = 4MHz (this needs to be 2-4MHz)
    MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0); // Enable PLL*24 = 96 MHz
  #elif F_CPU == 72000000
    MCG_C5 = MCG_C5_PRDIV0(5); // 16 MHz / 6 = 2.66 MHz (this needs to be 2-4MHz)
    MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV0(3); // Enable PLL*27 = 71.82 MHz
  #elif F_CPU == 48000000
    MCG_C5 = MCG_C5_PRDIV0(7); // 16 MHz / 8 = 2 MHz (this needs to be 2-4MHz)
    MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0); // Enable PLL*24 = 48 MHz
  #elif F_CPU == 24000000
    // For 24 MHz, we'll use a 48 MHz PLL and divide in the SIM
    MCG_C5 = MCG_C5_PRDIV0(7); // 16 MHz / 8 = 2 MHz (this needs to be 2-4MHz)
    MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0); // Enable PLL*24 = 48 MHz
  #else
    #error "Unknown F_CPU value"
  #endif

  // Now that we setup and enabled the PLL, wait for it to become active
  while (!(MCG_S & MCG_S_PLLST_MASK)) ;
  // and locked
  while (!(MCG_S & MCG_S_LOCK0_MASK)) ;
#endif

  // Next up: Setup clock dividers for MCU, peripherials, flash and USB
  // This is done by the SIM (System Integration Module)
  // There are two registers:
  //  SIM_CLKDIV1:
  //   OUTDIV1: Core/system clock divider
  //   OUTDIV2: Peripherial/Bus clock
  //   OUTDIV4: Flash clock
  //  SIM_CLKDIV2:
  //   USBDIV: Divisor
  //   USBFRAC: Fraction
  //   Output is input_clock*(USBFRAC+1)/(USBDIV+1)
  //
  // USB needs a 48MHz clock, so the divider should be setup accordingly. Also,
  // for the USB FS OTG controller to work, the system clock needs to be >= 20 MHz
#if F_CPU == 96000000
  // 96 MHz core, 48 MHz bus, 24 MHz flash (OVERCLOCKED!)
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3);
  SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); // 96 * 1/2 = 48
#elif F_CPU == 72000000
  // 72 MHz core, 36 MHz bus, 24 MHz flash
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(2);
  SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC_MASK; // 72 * 2/3 = 48
#elif F_CPU == 48000000
  // 48 MHz core, 48 MHz bus, 24 MHz flash, USB = 96 / 2
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(1);
  SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(0); // 48 * 1/1 = 48
#elif F_CPU == 24000000
  // PLL is 48 MHz
  // 24 MHz core, 24 MHz bus, 24 MHz flash
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(1);
  SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(0); // 48 * 1/1 = 48

  // -- For the modes <= 16 MHz, we have the MCG clock on 16 MHz, without FLL/PLL
  //    Also, USB is not possible
#elif F_CPU == 16000000
  // 16 MHz core, 16 MHz bus, 16 MHz flash
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(0);
#elif F_CPU == 8000000
  // 8 MHz core, 8 MHz bus, 8 MHz flash
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(1);
#else
  #error "Unsupported F_CPU value"
#endif

  // The dividers are set, so we can transition over to PLL for > 16 MHz
#if F_CPU > 16000000
  // Switch clock source to PLL, keep FLL divider at 512
  MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4);

  // Wait for the clock to sync
  while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ;

  // Use PLL for USB and Bus/peripherals, core for trace and put OSCERCLK0 on CLKOUT pin
  SIM_SOPT2 = SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK | SIM_SOPT2_TRACECLKSEL_MASK | SIM_SOPT2_CLKOUTSEL(6);
#endif


  // ----------------------------------------------------------------------------------
  // Relocate data from flash to RAM as necessary
  // ----------------------------------------------------------------------------------
  //
  // At the minimum, the .data and .bss sections have to be setup in RAM. Also, since
  // they are aligned to 4 bytes, we can use uint32s for copying (which is faster than
  // byte by byte)
  uint32_t * src = &_etext;
  uint32_t * dest = &_sdata;
  while (dest < &_edata) *dest++ = *src++;

  // Also zero out .bss
  dest = &_sbss;
  while (dest < &_ebss) *dest++ = 0;

  // TODO: Relocate interrupt vector to RAM for speed?


  // Init systick?
#if ENABLE_SYSTICK_HANDLER
  systick_init();
#endif

  // Enable interrupts before entering main?
#if ENABLE_INTERRUPTS_ON_STARTUP
  interrupt_enable();
#endif

  // After everthing is done, call main
  main(); 

  // This should be unreachable code as long as main() does not return.
  // To avoid running the instruction pointer into places it shouldn't go, 
  // loop forever
  // TODO: Going into sleep would maybe be a better solution
  while (1);
}
Ejemplo n.º 6
0
void ResetHandler(void)
{
    /*
     * Enable watchdog timer. Allow settings to be changed later, in case the
     * application firmware wants to adjust its settings or disable it.
     *
     * Originally I tried using the 1 kHz low-power oscillator here, but that seemed to
     * run into an issue where refreshes weren't taking effect. It seems similar to
     * this problem on the Freescale forums, which didn't really have a satisfactory
     * solution:
     *
     *  https://community.freescale.com/thread/309519
     *
     * As a workaround, I'm using the "alternate" system clock.
     */
    {
        const uint32_t watchdog_timeout = F_BUS / 100;  // 10ms

        WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
        WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
        asm volatile ("nop");
        asm volatile ("nop");
        WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN |
            WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN | WDOG_STCTRLH_CLKSRC;
        WDOG_PRESC = 0;
        WDOG_TOVALH = watchdog_timeout >> 16;
        WDOG_TOVALL = watchdog_timeout;
    }

    // enable clocks to always-used peripherals
    SIM_SCGC5 = 0x00043F82;     // clocks active to all GPIO
    SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL;

    // release I/O pins hold, if we woke up from VLLS mode
    if (PMC_REGSC & PMC_REGSC_ACKISO) PMC_REGSC |= PMC_REGSC_ACKISO;

    // start in FEI mode
    // enable capacitors for crystal
    OSC0_CR = OSC_SC8P | OSC_SC2P;
    // enable osc, 8-32 MHz range, low power mode
    MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS;
    // switch to crystal as clock source, FLL input = 16 MHz / 512
    MCG_C1 =  MCG_C1_CLKS(2) | MCG_C1_FRDIV(4);
    // wait for crystal oscillator to begin
    while ((MCG_S & MCG_S_OSCINIT0) == 0) ;
    // wait for FLL to use oscillator
    while ((MCG_S & MCG_S_IREFST) != 0) ;
    // wait for MCGOUT to use oscillator
    while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ;
    // now we're in FBE mode
    // config PLL input for 16 MHz Crystal / 4 = 4 MHz
    MCG_C5 = MCG_C5_PRDIV0(3);
    // config PLL for 96 MHz output
    MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0);

    // Copy things while we're waiting on the PLL
    {
        // Relocate data and text to RAM
        uint32_t *src = &_eflash;
        uint32_t *dest = &_sdtext;
        while (dest < &_edtext) *dest++ = *src++;

        // Clear BSS
        dest = &_sbss;
        while (dest < &_ebss) *dest++ = 0;

        // Copy IVT to RAM
        src = (uint32_t*) &gVectors[0];
        dest = &ramVectors[0];
        while (dest <= &ramVectors[63]) *dest++ = *src++;

        // Switch to ram IVT
        SCB_VTOR = (uint32_t) &ramVectors[0];
    }

    // wait for PLL to start using xtal as its input
    while (!(MCG_S & MCG_S_PLLST)) ;
    // wait for PLL to lock
    while (!(MCG_S & MCG_S_LOCK0)) ;
    // now we're in PBE mode

    // config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash
    SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) |  SIM_CLKDIV1_OUTDIV4(3);
    // switch to PLL as clock source, FLL input = 16 MHz / 512
    MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4);
    // wait for PLL clock to be used
    while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ;
    // now we're in PEE mode
    // configure USB for 48 MHz clock
    SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); // USB = 96 MHz PLL / 2
    // USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0
    SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6);

    __enable_irq();
    main();
}