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); }
void main_clock_init (void) { /* enable the xosc32k and set the start up time */ SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP(6) | SYSCTRL_XOSC32K_EN32K | SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_ENABLE; while (!SYSCTRL->PCLKSR.bit.XOSC32KRDY){} /* enable the generic clock GEN1 and configure the XOSC32K as clock source for it */ GCLK->GENCTRL.reg = GCLK_GENCTRL_ID_GCLK1 | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_IDC; while (GCLK->STATUS.bit.SYNCBUSY){} /* Enable the DFLL and set the operation mode as closed loop */ SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE | SYSCTRL_DFLLCTRL_MODE; while(!SYSCTRL->PCLKSR.bit.DFLLRDY){} /* Load the Multiply factor, Coarse Step and fine Step for DFLL */ SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(0x1F/4) | SYSCTRL_DFLLMUL_FSTEP(0xFF/4) | SYSCTRL_DFLLMUL_MUL(1465); /* Enable the Generic Clock GEN 1 as DFLL48 as Reference */ GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID(0); /* wait for fine lock */ while(!SYSCTRL->PCLKSR.bit.DFLLLCKF){} /* Set the NVM Read Wait States to 1, Since the operating frequency 48 MHz */ NVMCTRL->CTRLB.bit.RWS = 1; /* Enable the Generic Clock 0 and Configure the DFLL as Clock Source for it*/ GCLK->GENCTRL.reg = GCLK_GENCTRL_ID_GCLK0 | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_IDC; while(GCLK->STATUS.bit.SYNCBUSY){} }
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; }
// **************************************************************************** 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(); }
void _sysctrl_init_referenced_generators(void) { void *hw = (void *)SYSCTRL; #if CONF_DFLL_CONFIG == 1 # if CONF_DFLL_USBCRM != 1 && CONF_DFLL_MODE != CONF_DFLL_OPEN_LOOP_MODE hri_gclk_write_CLKCTRL_reg(GCLK, GCLK_CLKCTRL_ID(0) | GCLK_CLKCTRL_GEN(CONF_DFLL_GCLK) | ( 1 << GCLK_CLKCTRL_CLKEN_Pos )); # endif hri_sysctrl_write_DFLLCTRL_reg(hw, SYSCTRL_DFLLCTRL_ENABLE); while(!hri_sysctrl_get_PCLKSR_DFLLRDY_bit(hw)) {; } hri_sysctrl_write_DFLLMUL_reg(hw, SYSCTRL_DFLLMUL_CSTEP( CONF_DFLL_CSTEP) | SYSCTRL_DFLLMUL_FSTEP(CONF_DFLL_FSTEP) | SYSCTRL_DFLLMUL_MUL(CONF_DFLL_MUL)); hri_sysctrl_write_DFLLVAL_reg(hw, CONF_DFLLVAL); hri_sysctrl_dfllctrl_reg_t tmp = ( CONF_DFLL_WAITLOCK << SYSCTRL_DFLLCTRL_WAITLOCK_Pos ) | ( CONF_DFLL_BPLCKC << SYSCTRL_DFLLCTRL_BPLCKC_Pos ) | ( CONF_DFLL_QLDIS << SYSCTRL_DFLLCTRL_QLDIS_Pos ) | ( CONF_DFLL_CCDIS << SYSCTRL_DFLLCTRL_CCDIS_Pos ) | ( CONF_DFLL_RUNSTDBY << SYSCTRL_DFLLCTRL_RUNSTDBY_Pos ) | ( CONF_DFLL_USBCRM << SYSCTRL_DFLLCTRL_USBCRM_Pos ) | ( CONF_DFLL_LLAW << SYSCTRL_DFLLCTRL_LLAW_Pos ) | ( CONF_DFLL_STABLE << SYSCTRL_DFLLCTRL_STABLE_Pos ) | ( CONF_DFLL_MODE << SYSCTRL_DFLLCTRL_MODE_Pos ) | ( CONF_DFLL_ENABLE << SYSCTRL_DFLLCTRL_ENABLE_Pos ); hri_sysctrl_write_DFLLCTRL_reg(hw, tmp); #endif #if CONF_DPLL_CONFIG == 1 # if CONF_DPLL_REFCLK == SYSCTRL_DPLLCTRLB_REFCLK_GCLK_Val hri_gclk_write_CLKCTRL_reg(GCLK, GCLK_CLKCTRL_ID(1) | GCLK_CLKCTRL_GEN(CONF_DPLL_GCLK) | ( 1 << GCLK_CLKCTRL_CLKEN_Pos )); # endif hri_sysctrl_write_DPLLCTRLA_reg(hw, ( CONF_DPLL_RUNSTDBY << SYSCTRL_DPLLCTRLA_RUNSTDBY_Pos ) | ( CONF_DPLL_ENABLE << SYSCTRL_DPLLCTRLA_ENABLE_Pos )); hri_sysctrl_write_DPLLRATIO_reg(hw, SYSCTRL_DPLLRATIO_LDRFRAC(CONF_DPLL_LDRFRAC) | SYSCTRL_DPLLRATIO_LDR(CONF_DPLL_LDR)); hri_sysctrl_write_DPLLCTRLB_reg(hw, SYSCTRL_DPLLCTRLB_DIV( CONF_DPLL_DIV) | ( CONF_DPLL_LBYPASS << SYSCTRL_DPLLCTRLB_LBYPASS_Pos ) | SYSCTRL_DPLLCTRLB_LTIME(CONF_DPLL_LTIME) | SYSCTRL_DPLLCTRLB_REFCLK(CONF_DPLL_REFCLK) | ( CONF_DPLL_WUF << SYSCTRL_DPLLCTRLB_WUF_Pos ) | ( CONF_DPLL_LPEN << SYSCTRL_DPLLCTRLB_LPEN_Pos ) | SYSCTRL_DPLLCTRLB_FILTER(CONF_DPLL_FILTER)); #endif #if CONF_DFLL_CONFIG == 1 # if CONF_DFLL_ENABLE == 1 if (hri_sysctrl_get_DFLLCTRL_MODE_bit(hw)) { # if CONF_DFLL_USBCRM == 0 hri_sysctrl_pclksr_reg_t status_mask = SYSCTRL_PCLKSR_DFLLRDY | SYSCTRL_PCLKSR_DFLLLCKF | SYSCTRL_PCLKSR_DFLLLCKC; # else hri_sysctrl_pclksr_reg_t status_mask = SYSCTRL_PCLKSR_DFLLRDY; # endif while(hri_sysctrl_get_PCLKSR_reg(hw, status_mask) != status_mask) {; } } else { while(!hri_sysctrl_get_PCLKSR_DFLLRDY_bit(hw)) {; } } # endif # if CONF_DFLL_ONDEMAND == 1 hri_sysctrl_set_DFLLCTRL_ONDEMAND_bit(hw); # endif #endif #if CONF_DPLL_CONFIG == 1 # if CONF_DPLL_ENABLE == 1 while (!( hri_sysctrl_get_DPLLSTATUS_ENABLE_bit(hw) || hri_sysctrl_get_DPLLSTATUS_LOCK_bit(hw) || hri_sysctrl_get_DPLLSTATUS_CLKRDY_bit(hw))) {; } # endif # if CONF_DPLL_ONDEMAND == 1 hri_sysctrl_set_DPLLCTRLA_ONDEMAND_bit(hw); # endif #endif #if CONF_DFLL_CONFIG == 1 while(hri_gclk_get_STATUS_SYNCBUSY_bit(GCLK)) {; } #endif #if CONF_OSC32K_CONFIG == 0 || CONF_OSC32K_ENABLE == 0 /* Disable after all possible configurations needs sync written. */ hri_sysctrl_clear_OSC32K_ENABLE_bit(hw); #endif (void)hw; }