int main(void) { // Configure pin 7 on EXT1 as output ioport_configure_pin(EXT1_PIN_7,IOPORT_DIR_OUTPUT); sysclk_init(); board_init(); // Start TC and configure pin to get PWM output to LED on IO1 Xplained Pro extension board tc_init(); while (1) { struct pll_config pcfg; /* * Initial state: Running from RC32M prescalers with 16x * prescaling of CLKsys, 2x prescaling for CLKper2 and 2x * prescaling for CLKper. */ wait_for_btn_press(); /* * Prescale CLKsys by 128x, prescale all peripheral clocks by 1. */ sysclk_set_prescalers(SYSCLK_PSADIV_128, SYSCLK_PSBCDIV_1_1); wait_for_btn_press(); /* * Switch to RC2M with 4x prescaling of CLKsys, 4x prescaling * for CLKper2 and 1x prescaling for CLKper. */ osc_enable(OSC_ID_RC2MHZ); do {} while (!osc_is_ready(OSC_ID_RC2MHZ)); sysclk_set_source(SYSCLK_SRC_RC2MHZ); sysclk_set_prescalers(SYSCLK_PSADIV_4, SYSCLK_PSBCDIV_4_1); osc_disable(OSC_ID_RC32MHZ); wait_for_btn_press(); /* * Switch to PLL with RC2M as reference and 4x multiplier. * Prescale CLKsys by 128x, and all peripheral clocks by 1x. */ pll_config_init(&pcfg, PLL_SRC_RC2MHZ, 1, 4); pll_enable(&pcfg, 0); do {} while (!pll_is_locked(0)); sysclk_set_prescalers(SYSCLK_PSADIV_128, SYSCLK_PSBCDIV_1_1); sysclk_set_source(SYSCLK_SRC_PLL); wait_for_btn_press(); /* * Go back to the initial state and start over. */ osc_enable(OSC_ID_RC32MHZ); do {} while(!osc_is_ready(OSC_ID_RC32MHZ)); sysclk_set_source(SYSCLK_SRC_RC32MHZ); sysclk_set_prescalers(SYSCLK_PSADIV_16, SYSCLK_PSBCDIV_2_2); pll_disable(0); osc_disable(OSC_ID_RC2MHZ); } }
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 main function. Do the Fibonacci calculation with and without * PicoCache and print the calculation time to the UART console. */ int main(void) { /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the console uart */ configure_console(); /* Output example information */ printf("-- FLASHCALW Example3 --\r\n"); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); /* Intialize time tick utilities */ time_tick_init(sysclk_get_cpu_hz()); /* Calculate the Fibonacci without PicoCache */ flash_picocache_example( "Fibonacci calculation without PicoCache at 48MHz", false); /* Calculate the Fibonacci with PicoCache */ flash_picocache_example( "Fibonacci calculation with PicoCache at 48MHz", true); puts("From now on, System is running at 12MHz\r"); puts("Please check the power consumption\r"); printf("Push %s to continue\r\n", BUTTON_0_NAME); wait_for_pushbutton(); sysclk_set_prescalers(2, 0, 0, 0, 0); reconfigure_com_port(); flashcalw_set_wait_state(0); /* Calculate the Fibonacci without PicoCache */ flash_picocache_example( "Fibonacci calculation without PicoCache at 12MHz", false); puts("Please check the power consumption\r"); printf("Push %s to continue\r\n", BUTTON_0_NAME); wait_for_pushbutton(); /* Calculate the Fibonacci with PicoCache */ flash_picocache_example( "Fibonacci calculation with PicoCache at 12MHz", true); puts("End"); while (true) { } }
/** * Function to initialize the clock and disable clock for not required modules. */ void sysclk_init(void) { #if !MEGA_XX_UN0 && !MEGA_XX_UN1 uint8_t *reg = (uint8_t *)&(POWER_REG_ADD); uint8_t i; /* Turn off all peripheral clocks that can be turned off. */ for (i = 0; i < NUMBER_OF_POWER_REG; i++) { *(reg++) = 0xFF; } #endif #if !MEGA_UNSPECIFIED && !MEGA_XX /* Set up system clock prescalers if different from defaults */ if ((CONFIG_SYSCLK_PSDIV != SYSCLK_PSDIV_8) || (SYSCLK_PSDIV_8 != CLKPR)) { sysclk_set_prescalers(CONFIG_SYSCLK_PSDIV); } #endif }
void sysclk_init(void) { sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV,CONFIG_SYSCLK_PSBCDIV); //* Replace osc_user_calibration(OSC_ID_RC32MHZ,cal); DFLLRC32M.CALA=0x40; DFLLRC32M.CALB=0x23; osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); //* Replace osc_enable_autocalibration(CONFIG_OSC_AUTOCAL,CONFIG_OSC_AUTOCAL_REF_OSC); OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); // Calibrate 32MRC at 48MHz using USB SOF // 48MHz/1kHz=0xBB80 DFLLRC32M.COMP1=0x80; DFLLRC32M.COMP2=0xBB; OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; DFLLRC32M.CTRL |= DFLL_ENABLE_bm; }
void sysclk_init_opt(void) { sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV,CONFIG_SYSCLK_PSBCDIV); /* Loads 48MHz internal RC calibration value */ DFLLRC32M.CALA=nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSCA)); DFLLRC32M.CALB=nvm_read_production_signature_row( nvm_get_production_signature_row_offset(USBRCOSC)); osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); // Calibrate 32MRC at 48MHz using USB SOF // 48MHz/1kHz=0xBB80 DFLLRC32M.COMP1=0x80; DFLLRC32M.COMP2=0xBB; OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; DFLLRC32M.CTRL |= DFLL_ENABLE_bm; }
/** * Function to initialize the clock and disable clock for not required modules. */ void sysclk_init(void) { #if !MEGA_XX_UN0 && !MEGA_XX_UN1 uint8_t *reg = (uint8_t *)&(POWER_REG_ADD); uint8_t i; /* Turn off all peripheral clocks that can be turned off. * The debugWIRE system of some devices that shares system clock with the SPI module. * Thus the PRSPI bit in the PRR register must not be set when debugging. */ for (i = 0; i < NUMBER_OF_POWER_REG; i++) { *(reg++) = 0xFF; } #endif #if !MEGA_UNSPECIFIED && !MEGA_XX /* Set up system clock prescalers if different from defaults */ if ((CONFIG_SYSCLK_PSDIV != SYSCLK_PSDIV_8) || (SYSCLK_PSDIV_8 != CLKPR)) { sysclk_set_prescalers(CONFIG_SYSCLK_PSDIV); } #endif }
/** * \brief Switch between various system clock sources and prescalers at * run time. * * \return Unused (ANSI-C compatibility). */ int main(void) { struct genclk_config gcfg; sysclk_init(); board_init(); /* Setup SysTick Timer for 1 msec interrupts */ if (SysTick_Config(SystemCoreClock / 1000)) { while (1); // Capture error } /* Enable PIO module related clock */ sysclk_enable_peripheral_clock(PIN_PUSHBUTTON_1_ID); /* Configure specific CLKOUT pin */ ioport_set_pin_mode(GCLK_PIN, GCLK_PIN_MUX); ioport_disable_pin(GCLK_PIN); /* Configure the output clock source and frequency */ genclk_config_defaults(&gcfg, GCLK_ID); genclk_config_set_source(&gcfg, GENCLK_PCK_SRC_PLLACK); genclk_config_set_divider(&gcfg, GENCLK_PCK_PRES_1); genclk_enable(&gcfg, GCLK_ID); while (1) { /* * Initial state. */ wait_for_switches(); /* * Divide MCK frequency by 2. */ sysclk_set_prescalers(SYSCLK_PRES_2); genclk_config_set_divider(&gcfg, GENCLK_PCK_PRES_2); genclk_enable(&gcfg, GCLK_ID); wait_for_switches(); #ifdef BOARD_NO_32K_XTAL /* * Switch to the slow clock with all prescalers disabled. */ sysclk_set_source(SYSCLK_SRC_SLCK_RC); sysclk_set_prescalers(SYSCLK_PRES_1); genclk_config_set_source(&gcfg, GENCLK_PCK_SRC_SLCK_RC); genclk_config_set_divider(&gcfg, GENCLK_PCK_PRES_1); genclk_enable(&gcfg, GCLK_ID); osc_disable(OSC_MAINCK_XTAL); wait_for_switches(); #endif /* * Switch to internal 8 MHz RC. */ /* Switch to slow clock before switch main clock */ sysclk_set_source(SYSCLK_SRC_SLCK_RC); osc_enable(OSC_MAINCK_8M_RC); osc_wait_ready(OSC_MAINCK_8M_RC); sysclk_set_source(SYSCLK_SRC_MAINCK_8M_RC); genclk_config_set_source(&gcfg, GENCLK_PCK_SRC_MAINCK_8M_RC); genclk_enable(&gcfg, GCLK_ID); wait_for_switches(); #if BOARD_FREQ_MAINCK_XTAL /* * Switch to external crystal (8MHz or 12MHz, depend on the board). */ osc_enable(OSC_MAINCK_XTAL); osc_wait_ready(OSC_MAINCK_XTAL); sysclk_set_source(SYSCLK_SRC_MAINCK_XTAL); genclk_config_set_source(&gcfg, GENCLK_PCK_SRC_MAINCK_XTAL); genclk_enable(&gcfg, GCLK_ID); osc_disable(OSC_MAINCK_8M_RC); wait_for_switches(); #endif /* * Go back to the initial state and start over. */ sysclk_init(); genclk_config_set_source(&gcfg, GENCLK_PCK_SRC_PLLACK); genclk_config_set_divider(&gcfg, GENCLK_PCK_PRES_1); genclk_enable(&gcfg, GCLK_ID); } }
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 }
/** * \brief Show menu for error insertion and handle user's selection. * * This function changes device configurations and does some hacks to make * the device behave incorrectly. * * The menu entries are * - Change clock frequency: Changes the peripheral clock divider, simulating * that the clock system has malfunctioned. This should be detected by the * Class B frequency consistency test. * * - Mess with test timer: Changes how often periodic tests are performed, * simulating an error with an interrupt timer. This should be detected by * the Class B interrupt monitor. * * - Change a Flash section: Changes the string for the menu title stored in * program memory to "Out of cheese", simulating Flash memory corruption. * This can be changed back by selecting the menu item again. This should be * detected by the Class B Flash CRC test. * * - Scramble SRAM section: Starts a continuous DMA transfer in the background * to a memory location, simulating transient SRAM corruption. This should * be detected by the periodic and power-on Class B SRAM test. * * - Enter infinite loop: Simulates a runaway program counter by looping * forever. This should be detected by the watchdog timer system which is * tested on device power-up. * * - Change ADC reference: Enables a callback function for the ADC, which will * change the voltage reference after the next completed conversion. This * will cause the analog IO test to fail when user turns up the power to the * plate. */ void oven_classb_error_insertion(void) { uint8_t menu_status; struct keyboard_event input; struct adc_channel_config adcch_conf; /* Initialize menu system */ gfx_mono_menu_init(&error_menu); /* Wait for user to select something in the menu system */ do { do { keyboard_get_key_state(&input); oven_wdt_periodic_reset(); /* Wait for key release */ } while (input.type != KEYBOARD_RELEASE); /* Send key to menu system */ menu_status = gfx_mono_menu_process_key(&error_menu, input.keycode); oven_wdt_periodic_reset(); } while (menu_status == GFX_MONO_MENU_EVENT_IDLE); /* Handle the user's selection */ switch (menu_status) { case 0: /* Change cpu frequency by modifying the prescalers */ sysclk_set_prescalers(CLK_PSADIV_4_gc, CLK_PSBCDIV_1_1_gc); break; case 1: /* Change timing of the periodic temperature tests */ OVEN_PERIODIC_TEMPTEST_TC.CTRLA = TC_CLKSEL_DIV256_gc; break; case 2: /* Change flash section. */ oven_classb_flash_corrupter(); break; case 3: /* Disrupt SRAM by setting up the DMA to write to a location on * the heap, triggered by the class B frequency monitor timer */ PR.PRGEN &= ~PR_DMA_bm; DMA.CTRL |= DMA_ENABLE_bm; DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_TCD1_CCA_gc; /* Address of Timer D1 CNT base is 0x0960. */ DMA.CH0.SRCADDR0 = 0x60; DMA.CH0.SRCADDR1 = 0x09; DMA.CH0.SRCADDR2 = 0x00; DMA.CH0.DESTADDR0 = ((uint16_t)&variable_for_sram_error) & 0xFF; DMA.CH0.DESTADDR1 = (((uint16_t)&variable_for_sram_error) >> 8) & 0xFF; DMA.CH0.DESTADDR2 = 0x00; DMA.CH0.CTRLA = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_REPEAT_bm | DMA_CH_ENABLE_bm; break; case 4: /* Enter infinite loop */ while (1) { } break; case 5: /* Set up ADC channel interrupt */ adc_set_callback(&ADCA, adc_foul_callback); adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf); adcch_enable_interrupt(&adcch_conf); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); adcch_read_configuration(&ADCA, ADC_CH2, &adcch_conf); adcch_enable_interrupt(&adcch_conf); adcch_write_configuration(&ADCA, ADC_CH2, &adcch_conf); break; case 6: /* Back */ break; case GFX_MONO_MENU_EVENT_EXIT: /* Fall through to default */ default: /* Nothing, go back. */ break; } }
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); } } }
int main(void) { sysclk_init(); board_init(); /* Enable one wait state for flash access */ flashcalw_set_wait_state(1); /* * Configure systick for 200ms (CPU frequency / 5) at startup time. * * Note: CPU frequency will be changed with below clock switching. */ if (SysTick_Config(sysclk_get_cpu_hz() / 5)) { while (1) { /* Capture error */ } } while (1) { struct dfll_config dcfg; struct pll_config pcfg; /* avoid Cppcheck Warning */ UNUSED(pcfg); /* * Initial state: Running from RC80M with all * prescalers set to 2 (Divide frequency by 4). */ wait_for_switches(); /* * Divide CPU frequency by 8. This will make the LED * blink half as fast. */ sysclk_set_prescalers(3, 3, 3, 3, 3); wait_for_switches(); /* * Switch to the DFLL running at ~48 MHz in Open Loop * mode, with the CPU running at ~48 MHz. */ dfll_config_init_open_loop_mode(&dcfg); dfll_config_tune_for_target_hz(&dcfg, 48000000); dfll_enable_open_loop(&dcfg, 0); sysclk_set_prescalers(1, 1, 1, 1, 1); sysclk_set_source(SYSCLK_SRC_DFLL); osc_disable(OSC_ID_RC80M); wait_for_switches(); /* * Switch to the slow clock with all prescalers * disabled. */ sysclk_set_source(SYSCLK_SRC_RCSYS); sysclk_set_prescalers(0, 0, 0, 0, 0); dfll_disable_open_loop(0); wait_for_switches(); /* * Switch to the RCFAST clock with all prescalers * disabled. */ osc_enable(OSC_ID_RCFAST); sysclk_set_prescalers(0, 0, 0, 0, 0); osc_wait_ready(OSC_ID_RCFAST); sysclk_set_source(SYSCLK_SRC_RCFAST); wait_for_switches(); /* * Switch to the RC1M clock with all prescalers * disabled. */ osc_enable(OSC_ID_RC1M); sysclk_set_prescalers(0, 0, 0, 0, 0); osc_wait_ready(OSC_ID_RC1M); sysclk_set_source(SYSCLK_SRC_RC1M); osc_disable(OSC_ID_RCFAST); wait_for_switches(); /* * Switch to external OSC0, if available. */ #ifdef BOARD_OSC0_HZ osc_enable(OSC_ID_OSC0); osc_wait_ready(OSC_ID_OSC0); sysclk_set_source(SYSCLK_SRC_OSC0); osc_disable(OSC_ID_RC1M); wait_for_switches(); /* * Switch to PLL0 running at 96 MHz. Use OSC0 as the * source */ pll_config_init(&pcfg, PLL_SRC_OSC0, 1, 96000000 / BOARD_OSC0_HZ); pll_enable(&pcfg, 0); sysclk_set_prescalers(2, 2, 2, 2, 2); pll_wait_for_lock(0); sysclk_set_source(SYSCLK_SRC_PLL0); wait_for_switches(); #endif /* * Switch to the DFLL, using the 32 kHz oscillator as a * reference if available, or failing that, the 115 kHz * RCSYS oscillator. */ #ifdef BOARD_OSC32_HZ osc_enable(OSC_ID_OSC32); dfll_config_init_closed_loop_mode(&dcfg, GENCLK_SRC_OSC32K, 1, CONFIG_DFLL0_FREQ / BOARD_OSC32_HZ); osc_wait_ready(OSC_ID_OSC32); #else dfll_config_init_closed_loop_mode(&dcfg, GENCLK_SRC_RCSYS, 1, CONFIG_DFLL0_FREQ / OSC_RCSYS_NOMINAL_HZ); #endif dfll_enable_closed_loop(&dcfg, 0); sysclk_set_prescalers(1, 1, 1, 1, 1); dfll_wait_for_fine_lock(0); sysclk_set_source(SYSCLK_SRC_DFLL); #ifdef BOARD_OSC0_HZ osc_disable(OSC_ID_OSC0); #endif wait_for_switches(); /* * Go back to the initial state and start over. */ osc_enable(OSC_ID_RC80M); sysclk_set_prescalers(2, 2, 2, 2, 2); osc_wait_ready(OSC_ID_RC80M); sysclk_set_source(SYSCLK_SRC_RC80M); dfll_disable_closed_loop(0); #ifdef BOARD_OSC32_HZ osc_disable(OSC_ID_OSC32); #endif } }
/** * \brief Test audio data transfer and receive. * * \param test Current test case. */ static void run_iis_test(const struct test_case *test) { uint32_t i; struct iis_config config; struct iis_dev_inst dev_inst; struct genclk_config gencfg; struct pll_config pcfg; /* Set the GCLK according to the sample rate */ genclk_config_defaults(&gencfg, IISC_GCLK_NUM); /* CPUCLK 48M */ pll_config_init(&pcfg, PLL_SRC_OSC0, 2, 96000000 / BOARD_OSC0_HZ); pll_enable(&pcfg, 0); sysclk_set_prescalers(0, 0, 0, 0, 0); pll_wait_for_lock(0); sysclk_set_source(SYSCLK_SRC_PLL0); /* GCLK according fs ratio */ genclk_enable_source(GENCLK_SRC_CLK_CPU); genclk_config_set_source(&gencfg, GENCLK_SRC_CLK_CPU); genclk_config_set_divider(&gencfg, 4); genclk_enable(&gencfg, IISC_GCLK_NUM); /* Set the configuration */ iis_get_config_defaults(&config); config.data_format = IIS_DATE_16BIT_COMPACT; config.slot_length = IIS_SLOT_LENGTH_16BIT; config.fs_ratio = IIS_FS_RATE_256; config.tx_channels = IIS_CHANNEL_STEREO; config.rx_channels = IIS_CHANNEL_STEREO; config.tx_dma = IIS_ONE_DMA_CHANNEL_FOR_BOTH_CHANNELS; config.rx_dma = IIS_ONE_DMA_CHANNEL_FOR_BOTH_CHANNELS; config.loopback = true; iis_init(&dev_inst, IISC, &config); /* Enable the IIS module. */ iis_enable(&dev_inst); /* Config PDCA module */ pdca_enable(PDCA); pdca_channel_set_config(PDCA_IISC_CHANNEL0, &pdca_iisc_config_tx); pdca_channel_set_config(PDCA_IISC_CHANNEL1, &pdca_iisc_config_rx); pdca_channel_write_load(PDCA_IISC_CHANNEL0, (void *)output_samples, SOUND_SAMPLES / 2); pdca_channel_write_load(PDCA_IISC_CHANNEL1, (void *)input_samples, SOUND_SAMPLES / 2); pdca_channel_enable(PDCA_IISC_CHANNEL0); pdca_channel_enable(PDCA_IISC_CHANNEL1); /* Enable the functions */ iis_enable_transmission(&dev_inst); iis_enable_clocks(&dev_inst); /** * Since the transfer and receive timing is not under control, we * need adjust here the enable sequence and add some delay * functions if it's needed. */ delay_us(20); iis_enable_reception(&dev_inst); while (!(pdca_get_channel_status(PDCA_IISC_CHANNEL1) == PDCA_CH_TRANSFER_COMPLETED)) { } /* Disable the PDCA module. */ pdca_channel_disable(PDCA_IISC_CHANNEL0); pdca_channel_disable(PDCA_IISC_CHANNEL1); pdca_disable(PDCA); /* Disable the IISC module. */ iis_disable(&dev_inst); for (i = 0; i < SOUND_SAMPLES; i++) { if (input_samples[i] != output_samples[i]) { flag = false; } } test_assert_true(test, flag == true, "Audio data did not match!"); }