void sysclk_init(void) { /* Set up system clock dividers if different from defaults */ if ((CONFIG_SYSCLK_CPU_DIV > 0) || (CONFIG_SYSCLK_PBA_DIV > 0) || (CONFIG_SYSCLK_PBB_DIV > 0)) { sysclk_set_prescalers(CONFIG_SYSCLK_CPU_DIV, CONFIG_SYSCLK_PBA_DIV, CONFIG_SYSCLK_PBB_DIV); } /* Switch to system clock selected by user */ switch (CONFIG_SYSCLK_SOURCE) { case SYSCLK_SRC_RCSYS: /* Already running from RCOSC */ break; #ifdef BOARD_OSC0_HZ case SYSCLK_SRC_OSC0: osc_enable(OSC_ID_OSC0); osc_wait_ready(OSC_ID_OSC0); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(BOARD_OSC0_HZ); sysclk_set_source(SYSCLK_SRC_OSC0); break; #endif #ifdef CONFIG_PLL0_SOURCE case SYSCLK_SRC_PLL0: { pll_enable_config_defaults(0); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz()); sysclk_set_source(SYSCLK_SRC_PLL0); break; } #endif default: Assert(false); break; } /* If the user has specified clock masks, enable only requested clocks */ #if defined(CONFIG_SYSCLK_INIT_CPUMASK) AVR32_PM.cpumask = SYSCLK_INIT_MINIMAL_CPUMASK | CONFIG_SYSCLK_INIT_CPUMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBAMASK) AVR32_PM.pbamask = SYSCLK_INIT_MINIMAL_PBAMASK | CONFIG_SYSCLK_INIT_PBAMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBBMASK) AVR32_PM.pbbmask = SYSCLK_INIT_MINIMAL_PBBMASK | CONFIG_SYSCLK_INIT_PBBMASK; #endif #if defined(CONFIG_SYSCLK_INIT_HSBMASK) AVR32_PM.hsbmask = SYSCLK_INIT_MINIMAL_HSBMASK | CONFIG_SYSCLK_INIT_HSBMASK; #endif #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) /* Signal that the internal frequencies are setup */ sysclk_initialized = true; #endif }
/** * \brief Enable clock for the USB module * * \pre CONFIG_USBCLK_SOURCE must be defined. * * \param frequency The required USB clock frequency in MHz: * \arg \c 6 for 6 MHz * \arg \c 48 for 48 MHz */ void sysclk_enable_usb(uint8_t frequency) { uint8_t prescaler; Assert((frequency == 6) || (frequency == 48)); /* * Enable or disable prescaler depending on if the USB frequency is 6 * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. */ if (frequency == 6) { prescaler = CLK_USBPSDIV_8_gc; } else { prescaler = 0; } /* * Switch to the system clock selected by the user. */ switch (CONFIG_USBCLK_SOURCE) { case USBCLK_SRC_RCOSC: if (!osc_is_ready(OSC_ID_RC32MHZ)) { osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); #ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC != OSC_ID_USBSOF) { osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); } osc_enable_autocalibration(OSC_ID_RC32MHZ, CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); #endif } ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) | CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm); break; #ifdef CONFIG_PLL0_SOURCE case USBCLK_SRC_PLL: pll_enable_config_defaults(0); ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) | CLK_USBSRC_PLL_gc | CLK_USBSEN_bm); break; #endif default: Assert(false); break; } sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); }
void sysclk_init(void) { uint8_t *reg = (uint8_t *)&PR.PRGEN; uint8_t i; #ifdef CONFIG_OSC_RC32_CAL uint16_t cal; #endif bool need_rc2mhz = false; /* Turn off all peripheral clocks that can be turned off. */ for (i = 0; i <= SYSCLK_PORT_F; i++) { *(reg++) = 0xff; } /* Set up system clock prescalers if different from defaults */ if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, CONFIG_SYSCLK_PSBCDIV); } #if (CONFIG_OSC_RC32_CAL==48000000UL) MSB(cal) = nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSC)); LSB(cal) = nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSCA)); /* * If a device has an uncalibrated value in the * production signature row (early sample part), load a * sane default calibration value. */ if (cal == 0xFFFF) { cal = 0x2340; } osc_user_calibration(OSC_ID_RC32MHZ,cal); #endif /* * Switch to the selected initial system clock source, unless * the default internal 2 MHz oscillator is selected. */ if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { need_rc2mhz = true; } else { switch (CONFIG_SYSCLK_SOURCE) { case SYSCLK_SRC_RC32MHZ: osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); #ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC != OSC_ID_USBSOF) { osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); } osc_enable_autocalibration(OSC_ID_RC32MHZ, CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); #endif break; case SYSCLK_SRC_RC32KHZ: osc_enable(OSC_ID_RC32KHZ); osc_wait_ready(OSC_ID_RC32KHZ); break; case SYSCLK_SRC_XOSC: osc_enable(OSC_ID_XOSC); osc_wait_ready(OSC_ID_XOSC); break; #ifdef CONFIG_PLL0_SOURCE case SYSCLK_SRC_PLL: if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { need_rc2mhz = true; } pll_enable_config_defaults(0); break; #endif default: //unhandled_case(CONFIG_SYSCLK_SOURCE); return; } ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); } if (need_rc2mhz) { #ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); osc_enable_autocalibration(OSC_ID_RC2MHZ, CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); #endif } else { osc_disable(OSC_ID_RC2MHZ); } #ifdef CONFIG_RTC_SOURCE sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); #endif }
void sysclk_init(void) { uint32_t ps_value = 0; bool is_fwu_enabled = false; #if CONFIG_HCACHE_ENABLE == 1 /* Enable HCACHE */ sysclk_enable_peripheral_clock(HCACHE); HCACHE->HCACHE_CTRL = HCACHE_CTRL_CEN_YES; while (!(HCACHE->HCACHE_SR & HCACHE_SR_CSTS_EN)); #endif /* Set up system clock dividers if different from defaults */ if ((CONFIG_SYSCLK_CPU_DIV > 0) || (CONFIG_SYSCLK_PBA_DIV > 0) || (CONFIG_SYSCLK_PBB_DIV > 0) || (CONFIG_SYSCLK_PBC_DIV > 0) || (CONFIG_SYSCLK_PBD_DIV > 0)) { sysclk_set_prescalers(CONFIG_SYSCLK_CPU_DIV, CONFIG_SYSCLK_PBA_DIV, CONFIG_SYSCLK_PBB_DIV, CONFIG_SYSCLK_PBC_DIV, CONFIG_SYSCLK_PBD_DIV ); } /* Automatically select best power scaling mode */ #ifdef CONFIG_FLASH_READ_MODE_HIGH_SPEED_ENABLE ps_value = BPM_PS_2; is_fwu_enabled = false; #elif (defined(CONFIG_PLL0_MUL) || defined(CONFIG_DFLL0_MUL) || defined(CONFIG_USBCLK_DIV)) /* USB/DFLL/PLL are not available in PS1 (BPM.PMCON.PS=1) mode */ ps_value = BPM_PS_0; is_fwu_enabled = false; #else if (sysclk_get_cpu_hz() <= FLASH_FREQ_PS1_FWS_1_MAX_FREQ) { ps_value = BPM_PS_1; if (sysclk_get_cpu_hz() > FLASH_FREQ_PS1_FWS_0_MAX_FREQ) { bpm_enable_fast_wakeup(BPM); is_fwu_enabled = true; } } else { ps_value = BPM_PS_0; } #endif /* Switch to system clock selected by user */ if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RCSYS) { /* Already running from RCSYS */ } #ifdef BOARD_OSC0_HZ else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_OSC0) { osc_enable(OSC_ID_OSC0); osc_wait_ready(OSC_ID_OSC0); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_OSC0); } #endif #ifdef CONFIG_DFLL0_SOURCE else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_DFLL) { dfll_enable_config_defaults(0); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_DFLL); } #endif #ifdef CONFIG_PLL0_SOURCE else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLL0) { pll_enable_config_defaults(0); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_PLL0); } #endif else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC80M) { osc_enable(OSC_ID_RC80M); osc_wait_ready(OSC_ID_RC80M); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_RC80M); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RCFAST) { osc_enable(OSC_ID_RCFAST); osc_wait_ready(OSC_ID_RCFAST); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_RCFAST); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC1M) { osc_enable(OSC_ID_RC1M); osc_wait_ready(OSC_ID_RC1M); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_RC1M); } else { Assert(false); } /* Automatically switch to low power mode */ bpm_configure_power_scaling(BPM, ps_value, BPM_PSCM_CPU_NOT_HALT); while ((bpm_get_status(BPM) & BPM_SR_PSOK) == 0); /* If the user has specified clock masks, enable only requested clocks */ irqflags_t const flags = cpu_irq_save(); #if defined(CONFIG_SYSCLK_INIT_CPUMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_CPUMASK - (uint32_t)PM); PM->PM_CPUMASK = SYSCLK_INIT_MINIMAL_CPUMASK | CONFIG_SYSCLK_INIT_CPUMASK; #endif #if defined(CONFIG_SYSCLK_INIT_HSBMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_HSBMASK - (uint32_t)PM); PM->PM_HSBMASK = SYSCLK_INIT_MINIMAL_HSBMASK | CONFIG_SYSCLK_INIT_HSBMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBAMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBAMASK - (uint32_t)PM); PM->PM_PBAMASK = SYSCLK_INIT_MINIMAL_PBAMASK | CONFIG_SYSCLK_INIT_PBAMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBBMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBBMASK - (uint32_t)PM); PM->PM_PBBMASK = SYSCLK_INIT_MINIMAL_PBBMASK | CONFIG_SYSCLK_INIT_PBBMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBCMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBCMASK - (uint32_t)PM); PM->PM_PBCMASK = SYSCLK_INIT_MINIMAL_PBCMASK | CONFIG_SYSCLK_INIT_PBCMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBDMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBDMASK - (uint32_t)PM); PM->PM_PBDMASK = SYSCLK_INIT_MINIMAL_PBDMASK | CONFIG_SYSCLK_INIT_PBDMASK; #endif cpu_irq_restore(flags); #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) /* Signal that the internal frequencies are setup */ sysclk_initialized = true; #endif }
void sysclk_init(void) { uint8_t *reg = (uint8_t *)&PR.PRGEN; uint8_t i; #ifdef CONFIG_OSC_RC32_CAL uint16_t cal; #endif /* Turn off all peripheral clocks that can be turned off. */ for (i = 0; i <= SYSCLK_PORT_F; i++) { *(reg++) = 0xff; } /* Set up system clock prescalers if different from defaults */ if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, CONFIG_SYSCLK_PSBCDIV); } #if (CONFIG_OSC_RC32_CAL==48000000UL) MSB(cal) = nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSC)); LSB(cal) = nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSCA)); /* * If a device has an uncalibrated value in the * production signature row (early sample part), load a * sane default calibration value. * * MODIFIED 16-7-2012 by C.DOGGEN: * - commented the if statement, otherwise the USART won't work * - don't know exactly the problem, but this seems to be a workaround. */ if (cal == 0xFFFF) { cal = 0x2340; } osc_user_calibration(OSC_ID_RC32MHZ,cal); #endif /* * Switch to the selected initial system clock source, unless * the default internal 2 MHz oscillator is selected. */ if (CONFIG_SYSCLK_SOURCE != SYSCLK_SRC_RC2MHZ) { bool need_rc2mhz = false; switch (CONFIG_SYSCLK_SOURCE) { case SYSCLK_SRC_RC32MHZ: osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); break; case SYSCLK_SRC_RC32KHZ: osc_enable(OSC_ID_RC32KHZ); osc_wait_ready(OSC_ID_RC32KHZ); break; case SYSCLK_SRC_XOSC: osc_enable(OSC_ID_XOSC); osc_wait_ready(OSC_ID_XOSC); break; #ifdef CONFIG_PLL0_SOURCE case SYSCLK_SRC_PLL: if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { need_rc2mhz = true; } pll_enable_config_defaults(0); break; #endif default: //unhandled_case(CONFIG_SYSCLK_SOURCE); return; } ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); #ifdef CONFIG_OSC_AUTOCAL osc_enable_autocalibration(CONFIG_OSC_AUTOCAL,CONFIG_OSC_AUTOCAL_REF_OSC); if (CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ || CONFIG_OSC_AUTOCAL_REF_OSC == OSC_ID_RC2MHZ) { need_rc2mhz = true; } #endif if (!need_rc2mhz) { osc_disable(OSC_ID_RC2MHZ); } } }