/**
 * Initialize the system
 *
 * @brief  Setup the microcontroller system.
 *         Initialize the System and update the SystemCoreClock variable.
 */
void SystemInit(void)
{
	/*** Configure XOSC32KHz */
	// - Set XOSC32K as external crystal oscillator
	OSC32KCTRL->XOSC32K.bit.XTALEN = 1;
	// - Enable 32.768kHz output
	OSC32KCTRL->XOSC32K.bit.EN32K = 1;
	// - Enable 1kHz output
	OSC32KCTRL->XOSC32K.bit.EN1K = 1;
	// - Behavior in Low power (see "XOSC32K Sleep Behavior" table from product datasheet)
	OSC32KCTRL->XOSC32K.bit.RUNSTDBY = 0;
	OSC32KCTRL->XOSC32K.bit.ONDEMAND = 0;
	// - Set XOSC32K Startup time (see "Start-Up Time for 32KHz External Crystal Oscillator" table from product datasheet)
	OSC32KCTRL->XOSC32K.bit.STARTUP = 2;
	// - Enable XOSC32K
	OSC32KCTRL->XOSC32K.bit.ENABLE = 1;
	while(!(OSC32KCTRL->STATUS.bit.XOSC32KRDY));
	/*** Configure DPLL */
	// - Select DPLL Reference clock (0:XOSC32K , 1:XOSC , 2:GCLK)
	OSCCTRL->DPLLCTRLB.bit.REFCLK = 0;
	// - Set DPLL Prescaler
	OSCCTRL->DPLLPRESC.reg = 0;
	// - Set DPLL Ratio (48000000 / 32768 = 1464.84375)
	OSCCTRL->DPLLRATIO.bit.LDR = 1464;
	OSCCTRL->DPLLRATIO.bit.LDRFRAC = 14; //(0.84375 * 16)
	// - Enable DPLL
	OSCCTRL->DPLLCTRLA.bit.ENABLE = 1;
	while(OSCCTRL->DPLLSYNCBUSY.bit.ENABLE);
	//** Set Flash wait State according to 48MHz CPU clock */
	NVMCTRL->CTRLB.bit.RWS = 3;
	//** Set Performance level according to 48MHz CPU clock (0:PL0 2:PL2)*/
	PM->PLCFG.bit.PLSEL = 2	;
	while(!PM->INTFLAG.bit.PLRDY);
	/*** Set Generic clock 0 source as DPLL (MAIN clock for CPU and synchronous clock) */
	while((GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL_GCLK0));
	GCLK->GENCTRL[0].reg = (GCLK_GENCTRL_OE|GCLK_GENCTRL_SRC_DPLL96M|GCLK_GENCTRL_DIV(1)|GCLK_GENCTRL_GENEN);
	while((GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL_GCLK0));
	//*** Set PA27 as GCLK0_IO (PMUX : H = 0x07)
	PORT->Group[0].WRCONFIG.reg = (uint32_t)( PORT_WRCONFIG_HWSEL | PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_PINMASK(1 << 11) | PORT_WRCONFIG_PMUXEN | (0x7 << PORT_WRCONFIG_PMUX_Pos) );	
	/*** Update System Core clock variable */
	SystemCoreClock = 48000000;
	return;
}
示例#2
0
void sam_gclk_config(FAR const struct sam_gclkconfig_s *config)
{
  irqstate_t flags;
  uintptr_t regaddr;
  uint32_t regval;
  uint32_t genctrl;

  /* Select the requested source clock for the generator */

  genctrl = ((uint32_t)config->clksrc << GCLK_GENCTRL_SRC_SHIFT);

#if 0 /* Not yet supported */
  /* Configure the clock to be either high or low when disabled */

  if (config->level)
    {
      genctrl |= GCLK_GENCTRL_OOV;
    }
#endif

  /* Configure if the clock output to I/O pin should be enabled */

  if (config->output)
    {
      genctrl |= GCLK_GENCTRL_OE;
    }

  /* Set the prescaler division factor */

  if (config->prescaler > 1)
    {
      /* Check if division is a power of two */

      if (((config->prescaler & (config->prescaler - 1)) == 0))
        {
          /* Determine the index of the highest bit set to get the
           * division factor that must be loaded into the division
           * register.
           */

          uint32_t count = 0;
          uint32_t mask;

          for (mask = 2; mask < (uint32_t)config->prescaler; mask <<= 1)
            {
              count++;
            }

          /* Set binary divider power of 2 division factor */

          genctrl |= count << GCLK_GENCTRL_DIV_SHIFT;
          genctrl |= GCLK_GENCTRL_DIVSEL;
        }
      else
        {
          /* Set integer division factor */

          genctrl |= GCLK_GENCTRL_DIV((uint32_t)config->prescaler);

          /* Enable non-binary division with increased duty cycle accuracy */

          genctrl |= GCLK_GENCTRL_IDC;
        }
    }

  /* Enable or disable the clock in standby mode */

  if (config->runstandby)
    {
      genctrl |= GCLK_GENCTRL_RUNSTDBY;
    }

  /* Wait for synchronization */

  sam_gclck_waitsyncbusy(config->gclk);

  /* Preserve the GENEN bit */

  regaddr  = SAM_GCLK_GENCTRL(config->gclk);

  flags    = enter_critical_section();
  regval   = getreg32(regaddr);
  regval  &= GCLK_GENCTRL_GENEN;
  genctrl |= regval;

  /* Configure the generator */

  putreg32(genctrl, regaddr);

  /* Wait for synchronization */

  sam_gclck_waitsyncbusy(config->gclk);
  leave_critical_section(flags);
  sam_gclck_waitsyncbusy(config->gclk);

  /* Enable the clock generator */

  flags    = enter_critical_section();
  genctrl |= GCLK_GENCTRL_GENEN;
  putreg32(genctrl, regaddr);

  /* Wait for synchronization */

  sam_gclck_waitsyncbusy(config->gclk);
  leave_critical_section(flags);
}