Пример #1
0
    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
    }
Пример #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);

}
Пример #3
0
void
SystemInit(void)
{
    // Setup flash to work with 48Mhz clock
    NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_RWS_HALF;

    // Enable external 32Khz crystal
    uint32_t val = (SYSCTRL_XOSC32K_STARTUP(6)
                    | SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K);
    SYSCTRL->XOSC32K.reg = val;
    SYSCTRL->XOSC32K.reg = val | SYSCTRL_XOSC32K_ENABLE;
    while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSC32KRDY))
        ;

    // Reset GCLK
    GCLK->CTRL.reg = GCLK_CTRL_SWRST;
    while (GCLK->CTRL.reg & GCLK_CTRL_SWRST)
        ;

    // Route 32Khz clock to DFLL48M
    GCLK->GENDIV.reg = GCLK_GENDIV_ID(CLK_32K);
    GCLK->GENCTRL.reg = (GCLK_GENCTRL_ID(CLK_32K)
                         | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_GENEN);
    GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_ID(MCLK_DFLL48M)
                         | GCLK_CLKCTRL_GEN(CLK_32K) | GCLK_CLKCTRL_CLKEN);

    // Configure DFLL48M clock
    SYSCTRL->DFLLCTRL.reg = 0;
    uint32_t mul = DIV_ROUND_CLOSEST(CONFIG_CLOCK_FREQ, CLK_32K_FREQ);
    SYSCTRL->DFLLMUL.reg = (SYSCTRL_DFLLMUL_CSTEP(31)
                            | SYSCTRL_DFLLMUL_FSTEP(511)
                            | SYSCTRL_DFLLMUL_MUL(mul));
    SYSCTRL->DFLLCTRL.reg = (SYSCTRL_DFLLCTRL_MODE | SYSCTRL_DFLLCTRL_WAITLOCK
                             | SYSCTRL_DFLLCTRL_QLDIS
                             | SYSCTRL_DFLLCTRL_ENABLE);
    uint32_t ready = (SYSCTRL_PCLKSR_DFLLRDY | SYSCTRL_PCLKSR_DFLLLCKC
                      | SYSCTRL_PCLKSR_DFLLLCKF);
    while ((SYSCTRL->PCLKSR.reg & ready) != ready)
        ;

    // Switch main clock to DFLL48M clock
    GCLK->GENDIV.reg = GCLK_GENDIV_ID(CLK_MAIN);
    GCLK->GENCTRL.reg = (GCLK_GENCTRL_ID(CLK_MAIN)
                         | GCLK_GENCTRL_SRC_DFLL48M
                         | GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN);
}
Пример #4
0
Файл: rtt.c Проект: 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();
}
Пример #5
0
/*******************************************************************************************
*Description: Function responsible of RTC initialization
*Input Parameters: bool timeRep this parameter can be TIME_H24 (24 hour mode) or TIME_H12 (12 hour mode)
*Return Parameter: None
*******************************************************************************************/
void RTCInt::begin(bool timeRep, int oscillatorType) 
{
  
  
  PM->APBAMASK.reg |= PM_APBAMASK_RTC; // turn on digital interface clock for RTC
  
  GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK4 | (RTC_GCLK_ID << GCLK_CLKCTRL_ID_Pos)));
  while (GCLK->STATUS.bit.SYNCBUSY);
  
  //Set the oscillator to use - M0 only
  if(oscillatorType==HIGH_PRECISION)
  //External oscillator
  GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(4) | GCLK_GENCTRL_DIVSEL );
  
  else
  //Internal low power oscillator (default configuration)
  GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN |  GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(4) | GCLK_GENCTRL_DIVSEL );
  
  while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
  
  GCLK->GENDIV.reg = GCLK_GENDIV_ID(4); 
  GCLK->GENDIV.bit.DIV=4;
  while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
  
  

  RTCdisable();

  RTCreset();

  RTC->MODE2.CTRL.reg |= RTC_MODE2_CTRL_MODE_CLOCK; // set RTC operating mode
  RTC->MODE2.CTRL.reg |= RTC_MODE2_CTRL_PRESCALER_DIV1024; // set prescaler to 1024 for MODE2
  RTC->MODE2.CTRL.bit.MATCHCLR = 0; // disable clear on match
  
  
  if (timeRep)
  {
    RTC->MODE2.CTRL.bit.CLKREP = 0; // 24h time representation
	time_Mode = true;
  }		
  else
  {  
    RTC->MODE2.CTRL.bit.CLKREP = 1; // 12h time representation
	time_Mode = false;
  }	

  RTC->MODE2.READREQ.reg &= ~RTC_READREQ_RCONT; // disable continuously mode

  
  while (RTCSync());
	RTCresetRemove();
  RTCenable();
  
}
Пример #6
0
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;
}
Пример #7
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;
}
Пример #8
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();
}
Пример #9
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();
}
void SystemInit( void )
{
  /* Set 1 Flash Wait State for 48MHz, cf tables 20.9 and 35.27 in SAMD21 Datasheet */
  NVMCTRL->CTRLB.bit.RWS = NVMCTRL_CTRLB_RWS_HALF_Val ;

  /* Turn on the digital interface clock */
  PM->APBAMASK.reg |= PM_APBAMASK_GCLK ;

  /* ----------------------------------------------------------------------------------------------
   * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
   */
  SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP( 0x6u ) | /* cf table 15.10 of product datasheet in chapter 15.8.6 */
                         SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K ;
  SYSCTRL->XOSC32K.bit.ENABLE = 1 ; /* separate call, as described in chapter 15.6.3 */

  while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSC32KRDY) == 0 )
  {
    /* Wait for oscillator stabilization */
  }

  /* Software reset the module to ensure it is re-initialized correctly */
  /* Note: Due to synchronization, there is a delay from writing CTRL.SWRST until the reset is complete.
   * CTRL.SWRST and STATUS.SYNCBUSY will both be cleared when the reset is complete, as described in chapter 13.8.1
   */
  GCLK->CTRL.reg = GCLK_CTRL_SWRST ;

  while ( (GCLK->CTRL.reg & GCLK_CTRL_SWRST) && (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) )
  {
    /* Wait for reset to complete */
  }

  /* ----------------------------------------------------------------------------------------------
   * 2) Put XOSC32K as source of Generic Clock Generator 1
   */
  GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ) ; // Generic Clock Generator 1

  while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
  {
    /* Wait for synchronization */
  }

  /* Write Generic Clock Generator 1 configuration */
  GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ) | // Generic Clock Generator 1
                      GCLK_GENCTRL_SRC_XOSC32K | // Selected source is External 32KHz Oscillator
//                      GCLK_GENCTRL_OE | // Output clock to a pin for tests
                      GCLK_GENCTRL_GENEN ;

  while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
  {
    /* Wait for synchronization */
  }

  /* ----------------------------------------------------------------------------------------------
   * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference)
   */
  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GENERIC_CLOCK_MULTIPLEXER_DFLL48M ) | // Generic Clock Multiplexer 0
                      GCLK_CLKCTRL_GEN_GCLK1 | // Generic Clock Generator 1 is source
                      GCLK_CLKCTRL_CLKEN ;

  while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
  {
    /* Wait for synchronization */
  }

  /* ----------------------------------------------------------------------------------------------
   * 4) Enable DFLL48M clock
   */

  /* DFLL Configuration in Closed Loop mode, cf product datasheet chapter 15.6.7.1 - Closed-Loop Operation */

  /* Remove the OnDemand mode, Bug http://avr32.icgroup.norway.atmel.com/bugzilla/show_bug.cgi?id=9905 */
  SYSCTRL->DFLLCTRL.bit.ONDEMAND = 0 ;

  while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
  {
    /* Wait for synchronization */
  }

  SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 31 ) | // Coarse step is 31, half of the max value
                         SYSCTRL_DFLLMUL_FSTEP( 511 ) | // Fine step is 511, half of the max value
                         SYSCTRL_DFLLMUL_MUL( (__CLOCK_48MHz/__CLOCK_32KHz) ) ; // External 32KHz is the reference

  while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
  {
    /* Wait for synchronization */
  }

  /* Write full configuration to DFLL control register */
  SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */
                           SYSCTRL_DFLLCTRL_WAITLOCK |
                           SYSCTRL_DFLLCTRL_QLDIS ; /* Disable Quick lock */

  while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
  {
    /* Wait for synchronization */
  }

  /* Enable the DFLL */
  SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_ENABLE ;

  while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKC) == 0 ||
          (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKF) == 0 )
  {
    /* Wait for locks flags */
  }

  while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 )
  {
    /* Wait for synchronization */
  }

  /* ----------------------------------------------------------------------------------------------
   * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz.
   */
  GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_MAIN ) ; // Generic Clock Generator 0

  while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
  {
    /* Wait for synchronization */
  }

  /* Write Generic Clock Generator 0 configuration */
  GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_MAIN ) | // Generic Clock Generator 0
                      GCLK_GENCTRL_SRC_DFLL48M | // Selected source is DFLL 48MHz
//                      GCLK_GENCTRL_OE | // Output clock to a pin for tests
                      GCLK_GENCTRL_IDC | // Set 50/50 duty cycle
                      GCLK_GENCTRL_GENEN ;

  while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
  {
    /* Wait for synchronization */
  }

  /* ----------------------------------------------------------------------------------------------
   * 6) Modify PRESCaler value of OSC8M to have 8MHz
   */
  SYSCTRL->OSC8M.bit.PRESC = SYSCTRL_OSC8M_PRESC_0_Val ;
  SYSCTRL->OSC8M.bit.ONDEMAND = 0 ;

  /* ----------------------------------------------------------------------------------------------
   * 7) Put OSC8M as source for Generic Clock Generator 3
   */
  GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) ; // Generic Clock Generator 3

  /* Write Generic Clock Generator 3 configuration */
  GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) | // Generic Clock Generator 3
                      GCLK_GENCTRL_SRC_OSC8M | // Selected source is RC OSC 8MHz (already enabled at reset)
//                      GCLK_GENCTRL_OE | // Output clock to a pin for tests
                      GCLK_GENCTRL_GENEN ;

  while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
  {
    /* Wait for synchronization */
  }

  /* ----------------------------------------------------------------------------------------------
   * 8) Put OSC8M as source for Generic Clock Generator 2, with freq/8
   */
  GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_OSC1M ) | 8 << 8; // Generic Clock Generator 4

  /* Write Generic Clock Generator 3 configuration */
  GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_OSC1M ) | // Generic Clock Generator 4
                      GCLK_GENCTRL_SRC_OSC8M | // Selected source is RC OSC 8MHz (already enabled at reset)
//                      GCLK_GENCTRL_OE | // Output clock to a pin for tests
                      GCLK_GENCTRL_GENEN ;

  while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
  {
    /* Wait for synchronization */
  }

  /*
   * Now that all system clocks are configured, we can set CPU and APBx BUS clocks.
   * There values are normally the one present after Reset.
   */
  PM->CPUSEL.reg  = PM_CPUSEL_CPUDIV_DIV1 ;
  PM->APBASEL.reg = PM_APBASEL_APBADIV_DIV1_Val ;
  PM->APBBSEL.reg = PM_APBBSEL_APBBDIV_DIV1_Val ;
  PM->APBCSEL.reg = PM_APBCSEL_APBCDIV_DIV1_Val ;

  SystemCoreClock=__CLOCK_48MHz ;

	return;
}
Пример #11
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
}
Пример #12
0
Файл: cpu.c Проект: ant9000/RIOT
/**
 * @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) {}
    }
}
Пример #13
0
// ****************************************************************************
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();
}
Пример #14
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);


}