Beispiel #1
0
void clock_init(void){
	
	// use 8M oscillator as main clock, /1 prescaler
	// core switches to 8MHz operation after PRESC write
	SYSCTRL->OSC8M.bit.PRESC = 0;
	SYSCTRL->OSC8M.bit.ONDEMAND = 1;
	SYSCTRL->OSC8M.bit.RUNSTDBY = 0;
	
	// enable watchdog timer with a 1/2 second (16384 clock) timeout
	//WDT->CONFIG = WDT_CONFIG_WINDOW_8 | WDT_CONFIG_PER_16K;
	//WDT->CTRL = WDT_CTRL_ENABLE;

	// set up generic clock generators
	// GCLK0 = leave alone (8M core)
	// GCLK2 = leave alone (ULP 32K oscillator for WDT)
	// GCLK3 = OSC32K for display
	
	
	// GCLK1 = 10MHz calibration input (on PB23) - function H
	PORT->Group[1].PMUX[23/2].bit.PMUXO = PORT_PMUX_PMUXO_H_Val;
	PORT->Group[1].PINCFG[23].bit.PMUXEN = 1;
	
	GCLK->GENDIV.reg = GCLK_GENDIV_DIV(0) | GCLK_GENDIV_ID_GCLK1;
	GCLK->GENCTRL.reg =		(1 << GCLK_GENCTRL_RUNSTDBY_Pos) |
							(0 << GCLK_GENCTRL_DIVSEL_Pos) |
							(0 << GCLK_GENCTRL_OE_Pos) |
							(1 << GCLK_GENCTRL_GENEN_Pos) |
							GCLK_GENCTRL_SRC_GCLKIN |
							GCLK_GENCTRL_ID_GCLK1;
	

	// enable OSC32K
	SYSCTRL->OSC32K.reg =	((*(uint32_t *)SYSCTRL_FUSES_OSC32K_CAL_ADDR >> SYSCTRL_FUSES_OSC32K_CAL_Pos) << SYSCTRL_OSC32K_CALIB_Pos) |
							(2 << SYSCTRL_OSC32K_STARTUP_Pos) |
							(1 << SYSCTRL_OSC32K_RUNSTDBY_Pos) |
							(1 << SYSCTRL_OSC32K_EN32K_Pos) |
							(1 << SYSCTRL_OSC32K_ENABLE_Pos);
	// wait for it to start
	while ((SYSCTRL->PCLKSR.bit.OSC32KRDY) == 0);

	// configure GCLK3, pointed at OSC32K
	GCLK->GENDIV.reg = GCLK_GENDIV_DIV(0) | GCLK_GENDIV_ID_GCLK3;
	GCLK->GENCTRL.reg =		(1<<GCLK_GENCTRL_RUNSTDBY_Pos) |
							(0 << GCLK_GENCTRL_DIVSEL_Pos) |
							(0 << GCLK_GENCTRL_OE_Pos) |
							(1 << GCLK_GENCTRL_GENEN_Pos) |
							GCLK_GENCTRL_SRC_OSC32K |
							GCLK_GENCTRL_ID_GCLK3;

}
Beispiel #2
0
void RtcInit() {
//     SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_ENABLE | SYSCTRL_XOSC32K_EN32K;
//     //wait for crystal to warm up
//     while((SYSCTRL->PCLKSR.reg & (SYSCTRL_PCLKSR_XOSC32KRDY)) == 0);

    GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) |
                       GCLK_GENDIV_DIV(8);

    GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) |
                        GCLK_GENCTRL_SRC(GCLK_SOURCE_OSC8M) |
                        GCLK_GENCTRL_IDC |
                        GCLK_GENCTRL_RUNSTDBY |
                        GCLK_GENCTRL_GENEN;
    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
    // Configure RTC
    GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(RTC_GCLK_ID) |
                        GCLK_CLKCTRL_CLKEN |
                        GCLK_CLKCTRL_GEN(2);

    RTC->MODE1.CTRL.reg = RTC_MODE1_CTRL_MODE_COUNT16;
    while (RTC->MODE1.STATUS.bit.SYNCBUSY);
    // Prescaler needs to be enabled separately from the mode for some reason
    RTC->MODE1.CTRL.reg |= RTC_MODE1_CTRL_PRESCALER_DIV1;
    while (RTC->MODE1.STATUS.bit.SYNCBUSY);
    RTC->MODE1.PER.reg = 998;
    while (RTC->MODE1.STATUS.bit.SYNCBUSY);
    RTC->MODE1.READREQ.reg |= RTC_READREQ_RCONT | RTC_READREQ_ADDR(0x10);
    RTC->MODE1.INTENSET.reg = RTC_MODE1_INTENSET_OVF;
    RTC->MODE1.CTRL.bit.ENABLE = 1;
    while (RTC->MODE1.STATUS.bit.SYNCBUSY);

    NVIC_EnableIRQ(RTC_IRQn);

}
    void SDI12Timer::configSDI12TimerPrescale(void)
    {
        // Select generic clock generator 4 (Arduino core uses 0-3)
        // Most examples use this clock generator.. consider yourself warned!
        // I would use a higher clock number, but some of the cores don't include them for some reason
        REG_GCLK_GENDIV = GCLK_GENDIV_ID(4) |           // Select Generic Clock Generator 4
                          GCLK_GENDIV_DIV(3) ;          // Divide the 48MHz clock source by divisor 3: 48MHz/3=16MHz
        while (GCLK->STATUS.bit.SYNCBUSY);              // Wait for synchronization

        // Write the generic clock generator 5 configuration
        REG_GCLK_GENCTRL = GCLK_GENCTRL_ID(4) |         // Select GCLK4
                           GCLK_GENCTRL_SRC_DFLL48M |   // Set the 48MHz clock source
                           GCLK_GENCTRL_IDC |           // Set the duty cycle to 50/50 HIGH/LOW
                           GCLK_GENCTRL_GENEN;          // Enable the generic clock clontrol
        while (GCLK->STATUS.bit.SYNCBUSY);              // Wait for synchronization

        // Feed GCLK4 to TC4 (also feeds to TC5, the two must have the same source)
        REG_GCLK_CLKCTRL = GCLK_CLKCTRL_GEN_GCLK4 |     // Select Generic Clock Generator 4
                           GCLK_CLKCTRL_CLKEN |         // Enable the generic clock generator
                           GCLK_CLKCTRL_ID_TC4_TC5;     // Feed the Generic Clock Generator 4 to TC4 and TC5
        while (GCLK->STATUS.bit.SYNCBUSY);              // Wait for synchronization

        REG_TC4_CTRLA |= TC_CTRLA_PRESCALER_DIV1024 |   // Set prescaler to 1024, 16MHz/1024 = 15.625kHz
                         TC_CTRLA_WAVEGEN_NFRQ |        // Put the timer TC4 into normal frequency (NFRQ) mode
                         TC_CTRLA_MODE_COUNT8 |         // Put the timer TC4 into 8-bit mode
                         TC_CTRLA_ENABLE;               // Enable TC4
        while (TC4->COUNT16.STATUS.bit.SYNCBUSY);       // Wait for synchronization
    }
Beispiel #4
0
Datei: rtt.c Projekt: adjih/RIOT
/**
 * @brief Initialize RTT module
 *
 * The RTT is running at 32768 Hz by default, i.e. @ XOSC32K frequency without
 * divider. There are 2 cascaded dividers in the clock path:
 *
 *  - GCLK_GENDIV_DIV(n): between 1 and 31
 *  - RTC_MODE0_CTRL_PRESCALER_DIVn: between 1 and 1024, see defines in `component_rtc.h`
 *
 * However the division scheme of GCLK_GENDIV_DIV can be changed by setting
 * GCLK_GENCTRL_DIVSEL:
 *
 *  - GCLK_GENCTRL_DIVSEL = 0: Clock divided by GENDIV.DIV (default)
 *  - GCLK_GENCTRL_DIVSEL = 1: Clock divided by 2^( GENDIV.DIV + 1 )
 */
void rtt_init(void)
{
    RtcMode0 *rtcMode0 = &(RTT_DEV);

    /* Turn on power manager for RTC */
    PM->APBAMASK.reg |= PM_APBAMASK_RTC;

    /* RTC uses External 32,768KHz Oscillator because OSC32K isn't accurate
     * enough (p1075/1138). Also keep running in standby. */
    SYSCTRL->XOSC32K.reg =  SYSCTRL_XOSC32K_ONDEMAND |
                            SYSCTRL_XOSC32K_EN32K |
                            SYSCTRL_XOSC32K_XTALEN |
                            SYSCTRL_XOSC32K_STARTUP(6) |
#if RTT_RUNSTDBY
                            SYSCTRL_XOSC32K_RUNSTDBY |
#endif
                            SYSCTRL_XOSC32K_ENABLE;

    /* Setup clock GCLK2 with divider 1 */
    GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(1);
    while (GCLK->STATUS.bit.SYNCBUSY) {}

    /* Enable GCLK2 with XOSC32K as source. Use divider without modification
     * and keep running in standby. */
    GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) |
                        GCLK_GENCTRL_GENEN |
#if RTT_RUNSTDBY
                        GCLK_GENCTRL_RUNSTDBY |
#endif
                        GCLK_GENCTRL_SRC_XOSC32K;
    while (GCLK->STATUS.bit.SYNCBUSY) {}

    /* Connect GCLK2 to RTC */
    GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN_GCLK2 |
                        GCLK_CLKCTRL_CLKEN |
                        GCLK_CLKCTRL_ID(RTC_GCLK_ID);
    while (GCLK->STATUS.bit.SYNCBUSY) {}

    /* Disable RTC */
    rtt_poweroff();

    /* Reset RTC */
    rtcMode0->CTRL.bit.SWRST = 1;
    while (rtcMode0->STATUS.bit.SYNCBUSY || rtcMode0->CTRL.bit.SWRST) {}

    /* Configure as 32bit counter with no prescaler and no clear on match compare */
    rtcMode0->CTRL.reg = RTC_MODE0_CTRL_MODE_COUNT32 |
                         RTT_PRESCALER;
    while (rtcMode0->STATUS.bit.SYNCBUSY) {}

    /* Setup interrupt */
    NVIC_EnableIRQ(RTT_IRQ);

    /* Enable RTC */
    rtt_poweron();
}
void WatchdogSAMD::_initialize_wdt() {
    // One-time initialization of watchdog timer.
    // Insights from rickrlh and rbrucemtl in Arduino forum!

#if defined(__SAMD51__)
    // SAMD51 WDT uses OSCULP32k as input clock now
    // section: 20.5.3
    OSC32KCTRL->OSCULP32K.bit.EN1K  = 1; // Enable out 1K (for WDT)
    OSC32KCTRL->OSCULP32K.bit.EN32K = 0; // Disable out 32K

    // Enable WDT early-warning interrupt
    NVIC_DisableIRQ(WDT_IRQn);
    NVIC_ClearPendingIRQ(WDT_IRQn);
    NVIC_SetPriority(WDT_IRQn, 0); // Top priority
    NVIC_EnableIRQ(WDT_IRQn);

    while(WDT->SYNCBUSY.reg);
    
    USB->DEVICE.CTRLA.bit.ENABLE = 0;         // Disable the USB peripheral
    while(USB->DEVICE.SYNCBUSY.bit.ENABLE);   // Wait for synchronization
    USB->DEVICE.CTRLA.bit.RUNSTDBY = 0;       // Deactivate run on standby
    USB->DEVICE.CTRLA.bit.ENABLE = 1;         // Enable the USB peripheral
    while(USB->DEVICE.SYNCBUSY.bit.ENABLE);   // Wait for synchronization
#else
    // Generic clock generator 2, divisor = 32 (2^(DIV+1))
    GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(4);
    // Enable clock generator 2 using low-power 32KHz oscillator.
    // With /32 divisor above, this yields 1024Hz(ish) clock.
    GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) |
                        GCLK_GENCTRL_GENEN |
                        GCLK_GENCTRL_SRC_OSCULP32K |
                        GCLK_GENCTRL_DIVSEL;
    while(GCLK->STATUS.bit.SYNCBUSY);
    // WDT clock = clock gen 2
    GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_WDT |
                        GCLK_CLKCTRL_CLKEN |
                        GCLK_CLKCTRL_GEN_GCLK2;

    // Enable WDT early-warning interrupt
    NVIC_DisableIRQ(WDT_IRQn);
    NVIC_ClearPendingIRQ(WDT_IRQn);
    NVIC_SetPriority(WDT_IRQn, 0); // Top priority
    NVIC_EnableIRQ(WDT_IRQn);
#endif

    _initialized = true;
}
Beispiel #6
0
void SaLBuzzerInit() {

    pinOut(BUZZER);
    pinCfg(BUZZER);
//
    PM->APBCMASK.reg |= PM_APBCMASK_TC5;
//
    GCLK->GENDIV.reg =  GCLK_GENDIV_ID(5) |
                        GCLK_GENDIV_DIV(1);
    GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(5) |
                        GCLK_GENCTRL_SRC_OSC8M |
                        GCLK_GENCTRL_GENEN;

    GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN(0) |
                        GCLK_CLKCTRL_CLKEN |
                        GCLK_CLKCTRL_ID(TC5_GCLK_ID);


    TC5->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16|
                             TC_CTRLA_RUNSTDBY |
                             //	 TC_CTRLA_PRESCSYNC_GCLK |
                             TC_CTRLA_PRESCALER_DIV4;

    // TC5->COUNT16.EVCTRL.bit.EVACT = 0x1;

    TC5->COUNT16.CC[0].bit.CC = 700;

    //TC5->COUNT16.PER.reg = 0x02;

    TC5->COUNT16.INTENSET.reg = TC_INTENSET_MC0;

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

    TC5->COUNT16.EVCTRL.bit.EVACT = 0x1;


    NVIC_EnableIRQ(TC5_IRQn);
    NVIC_SetPriority(TC5_IRQn,0xFFF);

    TC5->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_STOP;
}
Beispiel #7
0
void rtc_init(void)
{
    RtcMode2 *rtcMode2 = &(RTC_DEV);

    /* Turn on power manager for RTC */
    PM->APBAMASK.reg |= PM_APBAMASK_RTC;

    SYSCTRL->OSC32K.bit.ENABLE = 0;
    SYSCTRL->OSC32K.bit.ONDEMAND = 1;
    SYSCTRL->OSC32K.bit.RUNSTDBY = 0;
    SYSCTRL->OSC32K.bit.EN1K = 1;
    SYSCTRL->OSC32K.bit.EN32K = 1;
    SYSCTRL->OSC32K.bit.ENABLE = 1;

    /* Setup clock GCLK2 with OSC32K divided by 32 */
    GCLK->GENDIV.reg = GCLK_GENDIV_ID(2)|GCLK_GENDIV_DIV(4);
    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
    GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC32K | GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_DIVSEL );
    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
    GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | (RTC_GCLK_ID << GCLK_CLKCTRL_ID_Pos)));
    while (GCLK->STATUS.bit.SYNCBUSY);

    /* DISABLE RTC MASTER */
    while (rtcMode2->STATUS.reg & RTC_STATUS_SYNCBUSY);
    rtc_poweroff();

    /* Reset RTC */
    while (rtcMode2->STATUS.bit.SYNCBUSY);
    rtcMode2->CTRL.reg= RTC_MODE2_CTRL_SWRST;
    while (rtcMode2->STATUS.bit.SYNCBUSY);

    /* RTC config with RTC_MODE2_CTRL_CLKREP = 0 (24h) */
    rtcMode2->CTRL.reg = RTC_MODE2_CTRL_PRESCALER_DIV1024|RTC_MODE2_CTRL_MODE_CLOCK;
    while (rtcMode2->STATUS.bit.SYNCBUSY);
    rtcMode2->INTENSET.reg = RTC_MODE2_INTENSET_OVF;
    while (rtcMode2->STATUS.bit.SYNCBUSY);
    rtc_poweron();
}
Beispiel #8
0
void rtc_init(void)
{
    RtcMode2 *rtcMode2 = &(RTC_DEV);

    /* Turn on power manager for RTC */
    PM->APBAMASK.reg |= PM_APBAMASK_RTC;

    /* RTC uses External 32,768KHz Oscillator (OSC32K isn't accurate enough p1075/1138)*/
    SYSCTRL->XOSC32K.reg =  SYSCTRL_XOSC32K_ONDEMAND |
                            SYSCTRL_XOSC32K_EN32K |
                            SYSCTRL_XOSC32K_XTALEN |
                            SYSCTRL_XOSC32K_STARTUP(6) |
                            SYSCTRL_XOSC32K_ENABLE;

    /* Setup clock GCLK2 with OSC32K divided by 32 */
    GCLK->GENDIV.reg = GCLK_GENDIV_ID(2)|GCLK_GENDIV_DIV(4);
    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
    GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_DIVSEL );
    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
    GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | (RTC_GCLK_ID << GCLK_CLKCTRL_ID_Pos)));
    while (GCLK->STATUS.bit.SYNCBUSY);

    /* DISABLE RTC MASTER */
    while (rtcMode2->STATUS.reg & RTC_STATUS_SYNCBUSY);
    rtc_poweroff();

    /* Reset RTC */
    while (rtcMode2->STATUS.bit.SYNCBUSY);
    rtcMode2->CTRL.reg= RTC_MODE2_CTRL_SWRST;
    while (rtcMode2->STATUS.bit.SYNCBUSY);

    /* RTC config with RTC_MODE2_CTRL_CLKREP = 0 (24h) */
    rtcMode2->CTRL.reg = RTC_MODE2_CTRL_PRESCALER_DIV1024|RTC_MODE2_CTRL_MODE_CLOCK;
    while (rtcMode2->STATUS.bit.SYNCBUSY);
    rtcMode2->INTENSET.reg = RTC_MODE2_INTENSET_OVF;
    while (rtcMode2->STATUS.bit.SYNCBUSY);
    rtc_poweron();
}
Beispiel #9
0
void sam_gclk_config(FAR const struct sam_gclkconfig_s *config)
{
  uint32_t genctrl;
  uint32_t gendiv;

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

  genctrl = ((uint32_t)config->gclk << GCLK_GENCTRL_ID_SHIFT) |
            ((uint32_t)config->clksrc << GCLK_GENCTRL_SRC_SHIFT);
  gendiv  = ((uint32_t)config->gclk << GCLK_GENDIV_ID_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 */

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

          gendiv  |= GCLK_GENDIV_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();

  /* Select the generator */

  putreg32(((uint32_t)config->gclk << GCLK_GENDIV_ID_SHIFT),
           SAM_GCLK_GENDIV);

  /* Wait for synchronization */

  sam_gclck_waitsyncbusy();

  /* Write the new generator configuration */

  putreg32(gendiv, SAM_GCLK_GENDIV);

  /* Wait for synchronization */

  sam_gclck_waitsyncbusy();

  /* Enable the clock generator */

  genctrl |= GCLK_GENCTRL_GENEN;
  putreg32(genctrl, SAM_GCLK_GENCTRL);

  /* Wait for synchronization */

  sam_gclck_waitsyncbusy();
}
Beispiel #10
0
/**
 * \brief Initializes generators

 */
void _gclk_init_generators(void)
{
	void *hw = (void *)GCLK;

# if CONF_GCLK_GEN_0_GENEN == 1
	hri_gclk_write_GENDIV_reg(hw, GCLK_GENDIV_DIV(CONF_GCLK_GEN_0_DIV) |
			GCLK_GENDIV_ID(0));
	hri_gclk_write_GENCTRL_reg(hw,
			(CONF_GCLK_GEN_0_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos) |
			(CONF_GCLK_GEN_0_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) |
			(CONF_GCLK_GEN_0_OE << GCLK_GENCTRL_OE_Pos) |
			(CONF_GCLK_GEN_0_OOV << GCLK_GENCTRL_OOV_Pos) |
			(CONF_GCLK_GEN_0_IDC << GCLK_GENCTRL_IDC_Pos) |
			(CONF_GCLK_GEN_0_GENEN << GCLK_GENCTRL_GENEN_Pos) |
			CONF_GCLK_GEN_0_SRC |
			GCLK_GENCTRL_ID(0));
# endif

# if CONF_GCLK_GEN_1_GENEN == 1
	hri_gclk_write_GENDIV_reg(hw, GCLK_GENDIV_DIV(CONF_GCLK_GEN_1_DIV) |
			GCLK_GENDIV_ID(1));
	hri_gclk_write_GENCTRL_reg(hw,
			(CONF_GCLK_GEN_1_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos) |
			(CONF_GCLK_GEN_1_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) |
			(CONF_GCLK_GEN_1_OE << GCLK_GENCTRL_OE_Pos) |
			(CONF_GCLK_GEN_1_OOV << GCLK_GENCTRL_OOV_Pos) |
			(CONF_GCLK_GEN_1_IDC << GCLK_GENCTRL_IDC_Pos) |
			(CONF_GCLK_GEN_1_GENEN << GCLK_GENCTRL_GENEN_Pos) |
			CONF_GCLK_GEN_1_SRC |
			GCLK_GENCTRL_ID(1));
# endif

# if CONF_GCLK_GEN_2_GENEN == 1
	hri_gclk_write_GENDIV_reg(hw, GCLK_GENDIV_DIV(CONF_GCLK_GEN_2_DIV) |
			GCLK_GENDIV_ID(2));
	hri_gclk_write_GENCTRL_reg(hw,
			(CONF_GCLK_GEN_2_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos) |
			(CONF_GCLK_GEN_2_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) |
			(CONF_GCLK_GEN_2_OE << GCLK_GENCTRL_OE_Pos) |
			(CONF_GCLK_GEN_2_OOV << GCLK_GENCTRL_OOV_Pos) |
			(CONF_GCLK_GEN_2_IDC << GCLK_GENCTRL_IDC_Pos) |
			(CONF_GCLK_GEN_2_GENEN << GCLK_GENCTRL_GENEN_Pos) |
			CONF_GCLK_GEN_2_SRC |
			GCLK_GENCTRL_ID(2));
# endif

# if CONF_GCLK_GEN_3_GENEN == 1
	hri_gclk_write_GENDIV_reg(hw, GCLK_GENDIV_DIV(CONF_GCLK_GEN_3_DIV) |
			GCLK_GENDIV_ID(3));
	hri_gclk_write_GENCTRL_reg(hw,
			(CONF_GCLK_GEN_3_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos) |
			(CONF_GCLK_GEN_3_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) |
			(CONF_GCLK_GEN_3_OE << GCLK_GENCTRL_OE_Pos) |
			(CONF_GCLK_GEN_3_OOV << GCLK_GENCTRL_OOV_Pos) |
			(CONF_GCLK_GEN_3_IDC << GCLK_GENCTRL_IDC_Pos) |
			(CONF_GCLK_GEN_3_GENEN << GCLK_GENCTRL_GENEN_Pos) |
			CONF_GCLK_GEN_3_SRC |
			GCLK_GENCTRL_ID(3));
# endif

# if CONF_GCLK_GEN_4_GENEN == 1
	hri_gclk_write_GENDIV_reg(hw, GCLK_GENDIV_DIV(CONF_GCLK_GEN_4_DIV) |
			GCLK_GENDIV_ID(4));
	hri_gclk_write_GENCTRL_reg(hw,
			(CONF_GCLK_GEN_4_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos) |
			(CONF_GCLK_GEN_4_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) |
			(CONF_GCLK_GEN_4_OE << GCLK_GENCTRL_OE_Pos) |
			(CONF_GCLK_GEN_4_OOV << GCLK_GENCTRL_OOV_Pos) |
			(CONF_GCLK_GEN_4_IDC << GCLK_GENCTRL_IDC_Pos) |
			(CONF_GCLK_GEN_4_GENEN << GCLK_GENCTRL_GENEN_Pos) |
			CONF_GCLK_GEN_4_SRC |
			GCLK_GENCTRL_ID(4));
# endif

# if CONF_GCLK_GEN_5_GENEN == 1
	hri_gclk_write_GENDIV_reg(hw, GCLK_GENDIV_DIV(CONF_GCLK_GEN_5_DIV) |
			GCLK_GENDIV_ID(5));
	hri_gclk_write_GENCTRL_reg(hw,
			(CONF_GCLK_GEN_5_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos) |
			(CONF_GCLK_GEN_5_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) |
			(CONF_GCLK_GEN_5_OE << GCLK_GENCTRL_OE_Pos) |
			(CONF_GCLK_GEN_5_OOV << GCLK_GENCTRL_OOV_Pos) |
			(CONF_GCLK_GEN_5_IDC << GCLK_GENCTRL_IDC_Pos) |
			(CONF_GCLK_GEN_5_GENEN << GCLK_GENCTRL_GENEN_Pos) |
			CONF_GCLK_GEN_5_SRC |
			GCLK_GENCTRL_ID(5));
# endif

# if CONF_GCLK_GEN_6_GENEN == 1
	hri_gclk_write_GENDIV_reg(hw, GCLK_GENDIV_DIV(CONF_GCLK_GEN_6_DIV) |
			GCLK_GENDIV_ID(6));
	hri_gclk_write_GENCTRL_reg(hw,
			(CONF_GCLK_GEN_6_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos) |
			(CONF_GCLK_GEN_6_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) |
			(CONF_GCLK_GEN_6_OE << GCLK_GENCTRL_OE_Pos) |
			(CONF_GCLK_GEN_6_OOV << GCLK_GENCTRL_OOV_Pos) |
			(CONF_GCLK_GEN_6_IDC << GCLK_GENCTRL_IDC_Pos) |
			(CONF_GCLK_GEN_6_GENEN << GCLK_GENCTRL_GENEN_Pos) |
			CONF_GCLK_GEN_6_SRC |
			GCLK_GENCTRL_ID(6));
# endif

# if CONF_GCLK_GEN_7_GENEN == 1
	hri_gclk_write_GENDIV_reg(hw, GCLK_GENDIV_DIV(CONF_GCLK_GEN_7_DIV) |
			GCLK_GENDIV_ID(7));
	hri_gclk_write_GENCTRL_reg(hw,
			(CONF_GCLK_GEN_7_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos) |
			(CONF_GCLK_GEN_7_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos) |
			(CONF_GCLK_GEN_7_OE << GCLK_GENCTRL_OE_Pos) |
			(CONF_GCLK_GEN_7_OOV << GCLK_GENCTRL_OOV_Pos) |
			(CONF_GCLK_GEN_7_IDC << GCLK_GENCTRL_IDC_Pos) |
			(CONF_GCLK_GEN_7_GENEN << GCLK_GENCTRL_GENEN_Pos) |
			CONF_GCLK_GEN_7_SRC |
			GCLK_GENCTRL_ID(7));
# endif
}
Beispiel #11
0
/**
 * @brief   Configure clock sources and the cpu frequency
 */
static void clk_init(void)
{
    /* enable clocks for the power, sysctrl and gclk modules */
    PM->APBAMASK.reg = (PM_APBAMASK_PM | PM_APBAMASK_SYSCTRL |
                        PM_APBAMASK_GCLK);

    /* adjust NVM wait states, see table 42.30 (p. 1070) in the datasheet */
#if (CLOCK_CORECLOCK > 24000000)
    PM->APBAMASK.reg |= PM_AHBMASK_NVMCTRL;
    NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_RWS(1);
    PM->APBAMASK.reg &= ~PM_AHBMASK_NVMCTRL;
#endif

    /* configure internal 8MHz oscillator to run without prescaler */
    SYSCTRL->OSC8M.bit.PRESC = 0;
    SYSCTRL->OSC8M.bit.ONDEMAND = 1;
    SYSCTRL->OSC8M.bit.RUNSTDBY = 0;
    SYSCTRL->OSC8M.bit.ENABLE = 1;
    while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC8MRDY)) {}

#if CLOCK_USE_PLL
    /* reset the GCLK module so it is in a known state */
    GCLK->CTRL.reg = GCLK_CTRL_SWRST;
    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}

    /* setup generic clock 1 to feed DPLL with 1MHz */
    GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(8) |
                        GCLK_GENDIV_ID(1));
    GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN |
                         GCLK_GENCTRL_SRC_OSC8M |
                         GCLK_GENCTRL_ID(1));
    GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_GEN(1) |
                         GCLK_CLKCTRL_ID(1) |
                         GCLK_CLKCTRL_CLKEN);
    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}

    /* enable PLL */
    SYSCTRL->DPLLRATIO.reg = (SYSCTRL_DPLLRATIO_LDR(CLOCK_PLL_MUL));
    SYSCTRL->DPLLCTRLB.reg = (SYSCTRL_DPLLCTRLB_REFCLK_GCLK);
    SYSCTRL->DPLLCTRLA.reg = (SYSCTRL_DPLLCTRLA_ENABLE);
    while(!(SYSCTRL->DPLLSTATUS.reg &
           (SYSCTRL_DPLLSTATUS_CLKRDY | SYSCTRL_DPLLSTATUS_LOCK))) {}

    /* select the PLL as source for clock generator 0 (CPU core clock) */
    GCLK->GENDIV.reg =  (GCLK_GENDIV_DIV(CLOCK_PLL_DIV) |
                        GCLK_GENDIV_ID(0));
    GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN |
                         GCLK_GENCTRL_SRC_FDPLL |
                         GCLK_GENCTRL_ID(0));
#else /* do not use PLL, use internal 8MHz oscillator directly */
    GCLK->GENDIV.reg =  (GCLK_GENDIV_DIV(CLOCK_DIV) |
                        GCLK_GENDIV_ID(0));
    GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN |
                         GCLK_GENCTRL_SRC_OSC8M |
                         GCLK_GENCTRL_ID(0));
#endif

    /* make sure we synchronize clock generator 0 before we go on */
    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}

    /* Setup Clock generator 2 with divider 1 (32.768kHz) */
    GCLK->GENDIV.reg  = (GCLK_GENDIV_ID(2)  | GCLK_GENDIV_DIV(0));
    GCLK->GENCTRL.reg = (GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_GENEN |
            GCLK_GENCTRL_RUNSTDBY |
            GCLK_GENCTRL_SRC_OSCULP32K);

    while (GCLK->STATUS.bit.SYNCBUSY) {}

    /* redirect all peripherals to a disabled clock generator (7) by default */
    for (int i = 0x3; i <= 0x22; i++) {
        GCLK->CLKCTRL.reg = ( GCLK_CLKCTRL_ID(i) | GCLK_CLKCTRL_GEN_GCLK7 );
        while (GCLK->STATUS.bit.SYNCBUSY) {}
    }
}
// ****************************************************************************
void HAL_hardware_init(bool is_servo_reader, bool servo_output_enabled, bool uart_output_enabled)
{
    uint32_t *coarse_p;
    uint32_t coarse;

    // FIXME: output diagnostics on UART only if uart_output_enabled is false
    (void) uart_output_enabled;


    // ------------------------------------------------
    // Perform GPIO initialization as early as possible
    HAL_gpio_set(HAL_GPIO_BLANK);
    HAL_gpio_out(HAL_GPIO_BLANK);

    HAL_gpio_clear(HAL_GPIO_SWITCHED_LIGHT_OUTPUT);
    HAL_gpio_out(HAL_GPIO_SWITCHED_LIGHT_OUTPUT);

    HAL_gpio_out(HAL_GPIO_XLAT);

    HAL_gpio_out(HAL_GPIO_SIN);
    HAL_gpio_pmuxen(HAL_GPIO_SIN);

    HAL_gpio_out(HAL_GPIO_SCK);
    HAL_gpio_pmuxen(HAL_GPIO_SCK);

    HAL_gpio_in(HAL_GPIO_CH3);
    HAL_gpio_pmuxen(HAL_GPIO_CH3);

    HAL_gpio_in(HAL_GPIO_PUSH_BUTTON);

    HAL_gpio_pmuxen(HAL_GPIO_USB_DM);
    HAL_gpio_pmuxen(HAL_GPIO_USB_DP);

    // Turn the status LED on to signify we are initializing
    HAL_gpio_out(HAL_GPIO_LED);
    HAL_gpio_out(HAL_GPIO_LED2);
    HAL_gpio_set(HAL_GPIO_LED);
    HAL_gpio_set(HAL_GPIO_LED2);

    // ------------------------------------------------
    // Configure GPIOs shared between servo inputs, servo output and UART

    // Output UART Tx on OUT in all cases when the servo output is disabled
    if (servo_output_enabled) {
        HAL_gpio_out(HAL_GPIO_OUT);
        HAL_gpio_pmuxen(HAL_GPIO_OUT);
    }
    else {
        HAL_gpio_out(HAL_GPIO_TX_ON_OUT);
        HAL_gpio_pmuxen(HAL_GPIO_TX_ON_OUT);
        tx_pad = HAL_GPIO_TX_ON_OUT.txpo;
    }

    if (is_servo_reader) {
        HAL_gpio_in(HAL_GPIO_ST);
        HAL_gpio_pmuxen(HAL_GPIO_ST);
        HAL_gpio_in(HAL_GPIO_TH);
        HAL_gpio_pmuxen(HAL_GPIO_TH);
    }
    else {
        HAL_gpio_in(HAL_GPIO_RX);
        HAL_gpio_pmuxen(HAL_GPIO_RX);

        // In case we have a UART and a servi output, TH is unused. We can
        // use TH as Tx signal, just like in the LPC812 Mk4 light controller
        if (servo_output_enabled) {
            HAL_gpio_out(HAL_GPIO_TX_ON_TH);
            HAL_gpio_pmuxen(HAL_GPIO_TX_ON_TH);
            tx_pad = HAL_GPIO_TX_ON_TH.txpo;
        }
        else {
            HAL_gpio_in(HAL_GPIO_TH);
            HAL_gpio_pmuxen(HAL_GPIO_TH);
        }
    }


    // ------------------------------------------------
    // Since we intend to run at 48 MHz system clock, we neeed to conigure
    // one wait state for the flash according to the datasheet.
    NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_RWS(1);

    // ------------------------------------------------
    // Set up the PLL to provide a 48 MHz system clock
    SYSCTRL->INTFLAG.reg =
            SYSCTRL_INTFLAG_BOD33RDY |
            SYSCTRL_INTFLAG_BOD33DET |
            SYSCTRL_INTFLAG_DFLLRDY;

    SYSCTRL->DFLLCTRL.reg = 0;
    while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY));

    SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_MUL(48000);

    // Load PLL calibration values from NVRAM
    coarse_p = (uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR;
    coarse = (*coarse_p & FUSES_DFLL48M_COARSE_CAL_Msk) >> FUSES_DFLL48M_COARSE_CAL_Pos;
    SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(512);

    SYSCTRL->DFLLCTRL.reg =
            SYSCTRL_DFLLCTRL_ENABLE |
            SYSCTRL_DFLLCTRL_USBCRM |
            SYSCTRL_DFLLCTRL_BPLCKC |
            SYSCTRL_DFLLCTRL_STABLE |
            SYSCTRL_DFLLCTRL_CCDIS;

    while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY));


    // ------------------------------------------------
    // Reset the generic clock control block
    GCLK->CTRL.reg = GCLK_CTRL_SWRST;
    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);

    // Setup GENCLK0 to run at 48 MHz. This clock is used for high speed
    // peripherals such as SPI, USB and UART
    GCLK->GENDIV.reg =
        GCLK_GENDIV_ID(0) |
        GCLK_GENDIV_DIV(1);

    GCLK->GENCTRL.reg =
            GCLK_GENCTRL_ID(0) |
            GCLK_GENCTRL_SRC_DFLL48M |
            GCLK_GENCTRL_RUNSTDBY |
            GCLK_GENCTRL_GENEN;

    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);

    // Setup GENCLK1 to run at 2 MHz. We use GENCLK1 for timers that need
    // microsecond resolution (e.g. servo output and servo reader).
    // We derive the clock from the 48 MHz PLL, so we use a clock divider of
    // 24
    GCLK->GENDIV.reg =
        GCLK_GENDIV_ID(1) |
        GCLK_GENDIV_DIV(24);

    GCLK->GENCTRL.reg =
            GCLK_GENCTRL_ID(1) |
            GCLK_GENCTRL_SRC_DFLL48M |
            GCLK_GENCTRL_RUNSTDBY |
            GCLK_GENCTRL_GENEN;

    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);


    // ------------------------------------------------
    // Turn on power to the peripherals we use
    PM->APBCMASK.reg =
        UART_SERCOM_APBCMASK |
        SPI_SERCOM_APBCMASK |
        PM_APBAMASK_EIC |
        PM_APBCMASK_EVSYS |
        PM_APBCMASK_TCC0 |
        PM_APBCMASK_TC4 |
        PM_APBBMASK_USB;


    // ------------------------------------------------
    // Initialize the Event System

    // Use GLKGEN0 (48 MHz) as clock source for the EVSYS0..2
    GCLK->CLKCTRL.reg =
        GCLK_CLKCTRL_ID_EVSYS_0 |
        GCLK_CLKCTRL_CLKEN |
        GCLK_CLKCTRL_GEN(0);

    GCLK->CLKCTRL.reg =
        GCLK_CLKCTRL_ID_EVSYS_1 |
        GCLK_CLKCTRL_CLKEN |
        GCLK_CLKCTRL_GEN(0);

    GCLK->CLKCTRL.reg =
        GCLK_CLKCTRL_ID_EVSYS_2 |
        GCLK_CLKCTRL_CLKEN |
        GCLK_CLKCTRL_GEN(0);

    // Always turn on the Generic Clock within EVSYS
    EVSYS->CTRL.reg = EVSYS_CTRL_GCLKREQ;


    // ------------------------------------------------
    // Configure the SYSTICK to create an interrupt every 1 millisecond
    SysTick_Config(48000);
    NVIC_SetPriority(SysTick_IRQn, 0);


    // ------------------------
    // The UART Tx can be used for diagnostics output if it is not in use.
    // The pin is in use when HAL gets passed "uart_output_enabled==true"
    // (UART used for pre-processor, winch or slave output), or when we
    // have a servo reader and the servo output is enabled.
    //
    // Or in other words: the UART can output diagnostics on the OUT pin
    // when it is not in use, or the UART can output diagnostics on the TH/Tx
    // pin when we the UART reader is in use and no UART output function is
    // configured.
    diagnostics_on_uart = !uart_output_enabled;
    if (is_servo_reader) {
        if (servo_output_enabled) {
            diagnostics_on_uart = false;
        }
    }


    __enable_irq();
}
Beispiel #13
0
void uart_init(uint32_t baud) {

    uint32_t UART_CLKGEN_F = 8000000UL;
    uint64_t br = (uint64_t)65536 * (UART_CLKGEN_F - 16 * baud) / UART_CLKGEN_F;

    //enable GPS pins
    //  SaLPinMode(MTK3339_RX_PIN,INPUT);
    //  SaLPinMode(MTK3339_TX_PIN,OUTPUT);
    SYSCTRL->OSC8M.reg -= SYSCTRL_OSC8M_ENABLE;
    SYSCTRL->OSC8M.reg -= SYSCTRL_OSC8M_PRESC_3;
    SYSCTRL->OSC8M.reg |= SYSCTRL_OSC8M_ENABLE;



    //portB22->PINCFG->reg = 0x44;
    // portB23->PINCFG->reg = 0x44;

    // GPS pin configs
    ((Port *)PORT)->Group[1].PINCFG[22].reg = 0x41;
    ((Port *)PORT)->Group[1].PINCFG[23].reg = 0x41;
    ((Port *)PORT)->Group[1].PMUX[11].reg = 0x32;


    // usb port configs
  //  ((Port *)PORT)->Group[0].PINCFG[24].reg = 0x41;
   // ((Port *)PORT)->Group[0].PINCFG[25].reg = 0x41;
   // ((Port *)PORT)->Group[0].PMUX[12].reg = 0x24;


    //enable power to sercom 5 module
    PM->APBCMASK.reg |= PM_APBCMASK_SERCOM5;
    //enable and configure the sercom clock
    GCLK->GENDIV.reg =  GCLK_GENDIV_ID(3) |
                        GCLK_GENDIV_DIV(1);
    GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(3) |
                        GCLK_GENCTRL_SRC_OSC8M |
                        GCLK_GENCTRL_IDC |
                        GCLK_GENCTRL_RUNSTDBY |
                        GCLK_GENCTRL_GENEN;
    GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_SERCOM5_CORE |
                        GCLK_CLKCTRL_GEN_GCLK3 |
                        GCLK_CLKCTRL_CLKEN;
    //     GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_SERCOMX_SLOW |
    //                         GCLK_CLKCTRL_GEN_GCLK3 |
    //                         GCLK_CLKCTRL_CLKEN;
    GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_SERCOM3_CORE |
                        GCLK_CLKCTRL_GEN_GCLK3 |
                        GCLK_CLKCTRL_CLKEN;

    //configure the sercom module for the gps (sercom 5)
    SERCOM5->USART.CTRLA.reg = SERCOM_USART_CTRLA_DORD |
                               SERCOM_USART_CTRLA_MODE_USART_INT_CLK |
                               SERCOM_USART_CTRLA_RXPO(3) |
                               SERCOM_USART_CTRLA_TXPO(1);
    uart_sync(SERCOM5);
    SERCOM5->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN |
                               SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/);
    // SERCOM_USART_CTRLB_SFDE;
    uart_sync(SERCOM5);
    SERCOM5->USART.BAUD.reg = (uint16_t)br;
    uart_sync(SERCOM5);
    SERCOM5->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
    uart_sync(SERCOM5);

    SaLInitUsart(&USART_0,SERCOM5);


}