Ejemplo n.º 1
0
//-----------------------------------------------------------------------------
static void sys_init(void)
{
  OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_XTALEN |
      OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_RUNSTDBY | OSC32KCTRL_XOSC32K_STARTUP(7);
  while (0 == OSC32KCTRL->STATUS.bit.XOSC32KRDY);

  #define LDR (((unsigned long)F_CPU * 32) / 32768)

  GCLK->GENCTRL[1].reg = GCLK_GENCTRL_SRC(GCLK_SOURCE_XOSC32K) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN;

  GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = GCLK_PCHCTRL_GEN(1) | GCLK_PCHCTRL_CHEN;
  while (0 == (GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg & GCLK_PCHCTRL_CHEN));

  GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL032K].reg = GCLK_PCHCTRL_GEN(1) | GCLK_PCHCTRL_CHEN;
  while (0 == (GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL032K].reg & GCLK_PCHCTRL_CHEN));

  OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(LDR % 32) |
      OSCCTRL_DPLLRATIO_LDR((LDR / 32) - 1);
  OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_XOSC32 |
      OSCCTRL_DPLLCTRLB_DIV(1) | OSCCTRL_DPLLCTRLB_WUF | OSCCTRL_DPLLCTRLB_LBYPASS;
  OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE | OSCCTRL_DPLLCTRLA_RUNSTDBY;

  while (0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY || 0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK);

  GCLK->GENCTRL[0].reg = GCLK_GENCTRL_SRC(GCLK_SOURCE_DPLL0) |
      GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN;
}
Ejemplo n.º 2
0
//-----------------------------------------------------------------------------
static void uart_init(uint32_t baud)
{
  HAL_GPIO_UART_TX_out();
  HAL_GPIO_UART_TX_pmuxen(HAL_GPIO_PMUX_D);
  HAL_GPIO_UART_RX_in();
  HAL_GPIO_UART_RX_pmuxen(HAL_GPIO_PMUX_D);

  MCLK->APBBMASK.reg |= MCLK_APBBMASK_SERCOM2;

  GCLK->PCHCTRL[SERCOM2_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN;
  while (0 == (GCLK->PCHCTRL[SERCOM2_GCLK_ID_CORE].reg & GCLK_PCHCTRL_CHEN));

  SERCOM2->USART.CTRLA.reg =
      SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE(1/*INT_CLK*/) |
      SERCOM_USART_CTRLA_RXPO(1/*PAD1*/) | SERCOM_USART_CTRLA_TXPO(0/*PAD0*/) |
      SERCOM_USART_CTRLA_SAMPR(1);

  SERCOM2->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN |
      SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/);

  #define BAUD_VAL (F_CPU / (16 * baud))
  #define FP_VAL   ((F_CPU / baud - 16 * BAUD_VAL) / 2)

  SERCOM2->USART.BAUD.reg = 
      SERCOM_USART_BAUD_FRACFP_BAUD(BAUD_VAL) |
      SERCOM_USART_BAUD_FRACFP_FP(FP_VAL);

  SERCOM2->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
}
Ejemplo n.º 3
0
void sam_gclk_chan_enable(uint8_t channel, uint8_t srcgen)
{
  irqstate_t flags;
  uint32_t regaddr;
  uint32_t regval;

  /* Get the address of the peripheral channel control register */

  regaddr = SAM_GCLK_PCHCTRL(channel);

  /* Disable generic clock channel */

  flags = enter_critical_section();
  sam_gclk_chan_disable(channel);

  /* Configure the peripheral channel */

  regval =  GCLK_PCHCTRL_GEN(srcgen);
  putreg32(regval, regaddr);

  /* Enable the peripheral channel */

  regval |= GCLK_PCHCTRL_CHEN;
  putreg32(regval, regaddr);

  /* Wait for clock synchronization */

  while ((getreg32(regaddr) &GCLK_PCHCTRL_CHEN) == 0);
  leave_critical_section(flags);
}
Ejemplo n.º 4
0
static void ADC_Init(void)
{
	// - Enable TCC0 Bus clock (ADC control clock)
	MCLK->APBDMASK.reg |= MCLK_APBDMASK_ADC;
	// - Enable ADC_GCLK and link it to GCLK0 (see "PCHCTRLm Mapping" from product datasheet)
	GCLK->PCHCTRL[30].reg = (GCLK_PCHCTRL_CHEN|GCLK_PCHCTRL_GEN(0));
	/* Disable ADC (required for configuration) */
	ADC->CTRLA.bit.ENABLE = 0x00;
	/* Reset ADC configuration */
	ADC->CTRLA.bit.SWRST = 0x01;
	/* configure GCLK_ADC prescaler */
	ADC->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV2_Val;
	/* Set Reference voltage source as internal */
	ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val;
	/* Set ADC resolution to 12-bit */
	ADC->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_12BIT_Val;
	/* Set conversion type to single ended */
	ADC->CTRLC.bit.DIFFMODE = 0x00;
	/* Enable Start conversion on event reception*/
	ADC->EVCTRL.bit.STARTEI = 0x01;
	/* Enable ADC result ready interrupt */
	ADC->INTENSET.bit.RESRDY = 0x01;
	/* Enable general ADC interrupt (ID 22)*/
	NVIC_EnableIRQ(ADC_IRQn);
	/* Enable ADC */
	ADC->CTRLA.bit.ENABLE = 0x01;
}
Ejemplo n.º 5
0
//-----------------------------------------------------------------------------
static void uart_init(uint32_t baud)
{
  uint64_t br = (uint64_t)65536 * (F_CPU - 16 * baud) / F_CPU;

  HAL_GPIO_UART_TX_out();
  HAL_GPIO_UART_TX_pmuxen(HAL_GPIO_PMUX_D);
  HAL_GPIO_UART_RX_in();
  HAL_GPIO_UART_RX_pmuxen(HAL_GPIO_PMUX_D);

  MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM4;

  GCLK->PCHCTRL[SERCOM4_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN;
  while (0 == (GCLK->PCHCTRL[SERCOM4_GCLK_ID_CORE].reg & GCLK_PCHCTRL_CHEN));

  SERCOM4->USART.CTRLA.reg =
      SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE(1/*USART_INT_CLK*/) |
      SERCOM_USART_CTRLA_RXPO(3/*PAD3*/) | SERCOM_USART_CTRLA_TXPO(1/*PAD2*/);

  SERCOM4->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN |
      SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/);

  SERCOM4->USART.BAUD.reg = (uint16_t)br;

  SERCOM4->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
}
Ejemplo n.º 6
0
/** Configures and starts the DFLL in closed loop mode with the given reference
 *  generator.
 *
 *  \param[in]  source_generator  Reference generator to use for the DFLL
 */
static void init_dfll(
		const enum system_clock_source source_generator)
{
	struct system_gclk_gen_config cpu_clock_conf;
	system_gclk_gen_get_config_defaults(&cpu_clock_conf);
	cpu_clock_conf.output_enable = ENABLE_CPU_CLOCK_OUT;

	/* Switch to OSC8M/OSC16M while the DFLL is being reconfigured */
#if SAML21
	cpu_clock_conf.source_clock = SYSTEM_CLOCK_SOURCE_OSC16M;
#else
	cpu_clock_conf.source_clock = SYSTEM_CLOCK_SOURCE_OSC8M;
#endif
	system_gclk_gen_set_config(GCLK_GENERATOR_0, &cpu_clock_conf);

	/* Turn off DFLL before adjusting its configuration */
	system_clock_source_disable(SYSTEM_CLOCK_SOURCE_DFLL);

	/* Configure DFLL reference clock, use raw register write to
	 * force-configure the channel even if the currently selected generator
	 * clock has failed */
#if SAML21
        GCLK->PCHCTRL[SYSCTRL_GCLK_ID_DFLL48].reg = GCLK_PCHCTRL_GEN(source_generator);      
#else
	GCLK->CLKCTRL.reg =
			GCLK_CLKCTRL_ID(SYSCTRL_GCLK_ID_DFLL48) |
			GCLK_CLKCTRL_GEN(source_generator);
#endif
	system_gclk_chan_enable(SYSCTRL_GCLK_ID_DFLL48);

	/* Configure DFLL */
	struct system_clock_source_dfll_config config_dfll;
	system_clock_source_dfll_get_config_defaults(&config_dfll);
	config_dfll.on_demand = false;
	config_dfll.loop_mode = SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED;
	config_dfll.multiply_factor =
			(48000000UL / system_gclk_chan_get_hz(SYSCTRL_GCLK_ID_DFLL48));
	system_clock_source_dfll_set_config(&config_dfll);

	/* Restart DFLL */
	system_clock_source_enable(SYSTEM_CLOCK_SOURCE_DFLL);
	while (system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_DFLL) == false) {
		/* Wait for DFLL to be stable before switch back */
	}

	/* Switch back to the DFLL as the CPU clock source */
	cpu_clock_conf.source_clock = SYSTEM_CLOCK_SOURCE_DFLL;
	system_gclk_gen_set_config(GCLK_GENERATOR_0, &cpu_clock_conf);
};
Ejemplo n.º 7
0
Archivo: gclk.c Proyecto: Gussy/sam0
/**
 * \brief Writes a Generic Clock configuration to the hardware module.
 *
 * Writes out a given configuration of a Generic Clock configuration to the
 * hardware module. If the clock is currently running, it will be stopped.
 *
 * \note Once called the clock will not be running; to start the clock,
 *       call \ref system_gclk_chan_enable() after configuring a clock channel.
 *
 * \param[in] channel   Generic Clock channel to configure
 * \param[in] config    Configuration settings for the clock
 *
 */
void system_gclk_chan_set_config(
		const uint8_t channel,
		struct system_gclk_chan_config *const config)
{
	/* Sanity check arguments */
	Assert(config);

	/* Disable generic clock channel */
	system_gclk_chan_disable(channel);

	/* Configure the peripheral channel */
	GCLK->PCHCTRL[channel].reg = GCLK_PCHCTRL_GEN(config->source_generator);


}
Ejemplo n.º 8
0
static void TCC0_Init(void){
	// - Enable TCC0 Bus clock (Timer counter control clock)
	MCLK->APBCMASK.reg |= MCLK_APBCMASK_TCC0;
	//Enable GCLK for TCC0 and link it to GCLK0 see "PCHCTRLm Mapping" from product datasheet
	GCLK->PCHCTRL[25].reg = (GCLK_PCHCTRL_CHEN|GCLK_PCHCTRL_GEN(0));
	// - Disable TCC0
	TCC0->CTRLA.reg &=~(TCC_CTRLA_ENABLE);
	// - Set TCC0 in waveform mode Normal PWM
	TCC0->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;
	// - Set PER to maximum counter value (resolution : 0xFF)
	TCC0->PER.reg = 0xFF;
	// - Set WO[0] compare register to 0x7F (PWM duty cycle = 50%)
	TCC0->CC[0].reg = 0x7F;
	// - Enable Channel 0 Match Event Output
	TCC0->EVCTRL.bit.MCEO0 = 0x01;
	// - Set PB10 (LED) as TCC0 Waveform out (PMUX : F = 0x05)
	PORT->Group[1].WRCONFIG.reg = (uint32_t)(PORT_WRCONFIG_WRPINCFG|PORT_WRCONFIG_WRPMUX|1<<10|PORT_WRCONFIG_PMUXEN|(0x5<<PORT_WRCONFIG_PMUX_Pos));	 
	// - ENABLE TCC0
	TCC0->CTRLA.reg |= TCC_CTRLA_ENABLE;
 }
Ejemplo n.º 9
0
//-----------------------------------------------------------------------------
static void timer_init(void)
{
  MCLK->APBAMASK.reg |= MCLK_APBAMASK_TC0;

  GCLK->PCHCTRL[TC0_GCLK_ID].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN;
  while (0 == (GCLK->PCHCTRL[TC0_GCLK_ID].reg & GCLK_PCHCTRL_CHEN));

  TC0->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | TC_CTRLA_PRESCALER_DIV1024 |
      TC_CTRLA_PRESCSYNC_RESYNC;

  TC0->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ;

  TC0->COUNT16.COUNT.reg = 0;

  timer_set_period(PERIOD_SLOW);

  TC0->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;

  TC0->COUNT16.INTENSET.reg = TC_INTENSET_MC(1);

  NVIC_EnableIRQ(TC0_IRQn);
}
Ejemplo n.º 10
0
void _oscctrl_init_referenced_generators(void)
{
	void *                     hw = (void *)OSCCTRL;
	hri_oscctrl_dfllctrl_reg_t tmp;

#if CONF_DFLL_CONFIG == 1
#if CONF_DFLL_OVERWRITE_CALIBRATION == 0
#define NVM_DFLL_COARSE_POS 26
#define NVM_DFLL_COARSE_SIZE 6
	uint32_t coarse;
	coarse = *((uint32_t *)(NVMCTRL_OTP5)) >> NVM_DFLL_COARSE_POS;
#endif
#if CONF_DFLL_USBCRM != 1 && CONF_DFLL_MODE != 0
	hri_gclk_write_PCHCTRL_reg(GCLK, 0, (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(CONF_DFLL_GCLK));
#endif
	hri_oscctrl_write_DFLLCTRL_reg(hw, OSCCTRL_DFLLCTRL_ENABLE);
	while (!hri_oscctrl_get_STATUS_DFLLRDY_bit(hw))
		;
	hri_oscctrl_write_DFLLMUL_reg(hw,
	                              OSCCTRL_DFLLMUL_CSTEP(CONF_DFLL_CSTEP) | OSCCTRL_DFLLMUL_FSTEP(CONF_DFLL_FSTEP)
	                                  | OSCCTRL_DFLLMUL_MUL(CONF_DFLL_MUL));
	while (!hri_oscctrl_get_STATUS_DFLLRDY_bit(hw))
		;

#if CONF_DFLL_OVERWRITE_CALIBRATION == 0
	/* FINE is set to fixed value, which defined by DFLL48M Characteristics */
	hri_oscctrl_write_DFLLVAL_reg(hw, OSCCTRL_DFLLVAL_COARSE(coarse) | OSCCTRL_DFLLVAL_FINE(512));
#else
	hri_oscctrl_write_DFLLVAL_reg(hw, OSCCTRL_DFLLVAL_COARSE(CONF_DFLL_COARSE) | OSCCTRL_DFLLVAL_FINE(CONF_DFLL_FINE));
#endif

	tmp = (CONF_DFLL_WAITLOCK << OSCCTRL_DFLLCTRL_WAITLOCK_Pos) | (CONF_DFLL_BPLCKC << OSCCTRL_DFLLCTRL_BPLCKC_Pos)
	      | (CONF_DFLL_QLDIS << OSCCTRL_DFLLCTRL_QLDIS_Pos) | (CONF_DFLL_CCDIS << OSCCTRL_DFLLCTRL_CCDIS_Pos)
	      | (CONF_DFLL_RUNSTDBY << OSCCTRL_DFLLCTRL_RUNSTDBY_Pos) | (CONF_DFLL_USBCRM << OSCCTRL_DFLLCTRL_USBCRM_Pos)
	      | (CONF_DFLL_LLAW << OSCCTRL_DFLLCTRL_LLAW_Pos) | (CONF_DFLL_STABLE << OSCCTRL_DFLLCTRL_STABLE_Pos)
	      | (CONF_DFLL_MODE << OSCCTRL_DFLLCTRL_MODE_Pos) | (CONF_DFLL_ENABLE << OSCCTRL_DFLLCTRL_ENABLE_Pos);
	hri_oscctrl_write_DFLLCTRL_reg(hw, tmp);

#endif

#if CONF_DPLL_CONFIG == 1
#if CONF_DPLL_REFCLK == 2
	hri_gclk_write_PCHCTRL_reg(GCLK, 1, (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(CONF_DPLL_GCLK));
#endif
	hri_oscctrl_write_DPLLRATIO_reg(
	    hw, OSCCTRL_DPLLRATIO_LDRFRAC(CONF_DPLL_LDRFRAC) | OSCCTRL_DPLLRATIO_LDR(CONF_DPLL_LDR));
	hri_oscctrl_write_DPLLCTRLB_reg(hw,
	                                OSCCTRL_DPLLCTRLB_DIV(CONF_DPLL_DIV)
	                                    | (CONF_DPLL_LBYPASS << OSCCTRL_DPLLCTRLB_LBYPASS_Pos)
	                                    | OSCCTRL_DPLLCTRLB_LTIME(CONF_DPLL_LTIME)
	                                    | OSCCTRL_DPLLCTRLB_REFCLK(CONF_DPLL_REFCLK)
	                                    | (CONF_DPLL_WUF << OSCCTRL_DPLLCTRLB_WUF_Pos)
	                                    | (CONF_DPLL_LPEN << OSCCTRL_DPLLCTRLB_LPEN_Pos)
	                                    | OSCCTRL_DPLLCTRLB_FILTER(CONF_DPLL_FILTER));
	hri_oscctrl_write_DPLLPRESC_reg(hw, OSCCTRL_DPLLPRESC_PRESC(CONF_DPLL_PRESC));
	hri_oscctrl_write_DPLLCTRLA_reg(hw,
	                                (0 << OSCCTRL_DPLLCTRLA_ONDEMAND_Pos)
	                                    | (CONF_DPLL_RUNSTDBY << OSCCTRL_DPLLCTRLA_RUNSTDBY_Pos)
	                                    | (CONF_DPLL_ENABLE << OSCCTRL_DPLLCTRLA_ENABLE_Pos));
#endif

#if CONF_DFLL_CONFIG == 1
	if (hri_oscctrl_get_DFLLCTRL_MODE_bit(hw)) {
		hri_oscctrl_status_reg_t status_mask = OSCCTRL_STATUS_DFLLRDY | OSCCTRL_STATUS_DFLLLCKC;

		while (hri_oscctrl_get_STATUS_reg(hw, status_mask) != status_mask)
			;
	} else {
		while (!hri_oscctrl_get_STATUS_DFLLRDY_bit(hw))
			;
	}
#if CONF_DFLL_ONDEMAND == 1
	hri_oscctrl_set_DFLLCTRL_ONDEMAND_bit(hw);
#endif
#endif

#if CONF_DPLL_CONFIG == 1
#if CONF_DPLL_ENABLE == 1
	while (!(hri_oscctrl_get_DPLLSTATUS_LOCK_bit(hw) || hri_oscctrl_get_DPLLSTATUS_CLKRDY_bit(hw)))
		;
#endif
#if CONF_DPLL_ONDEMAND == 1
	hri_oscctrl_set_DPLLCTRLA_ONDEMAND_bit(hw);
#endif
#endif

#if CONF_DFLL_CONFIG == 1
	while (hri_gclk_read_SYNCBUSY_reg(GCLK))
		;
#endif
	(void)hw, (void)tmp;
}