Hi All, we are currently developing a program using the ASF example for USB HID. This example uses the internal 32MHz oscillator and adjusts the calibration to be 48MHz needed for USB. The code is below.
Is is possible to use an external crystal to do the same job?
void sysclk_init(void) { //uint8_t *reg = (uint8_t *)&PR.PRGEN; uint8_t i; #ifdef CONFIG_OSC_RC32_CAL uint16_t cal; /* avoid Cppcheck Warning */ UNUSED(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 #if XMEGA_E case SYSCLK_SRC_RC8MHZ: osc_enable(OSC_ID_RC8MHZ); osc_wait_ready(OSC_ID_RC8MHZ); 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 }