static void ctrl_sam3ucfg_cb(void) { switch(udd_g_ctrlreq.req.wValue & 0xFF) { /* Turn on slow clock */ case 0x01: osc_enable(OSC_MAINCK_XTAL); osc_wait_ready(OSC_MAINCK_XTAL); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); break; /* Turn off slow clock */ case 0x02: pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); break; /* Jump to ROM-resident bootloader */ case 0x03: /* Turn off connected stuff */ board_power(0); /* Clear ROM-mapping bit. */ efc_perform_command(EFC0, EFC_FCMD_CGPB, 1); /* Disconnect USB (will kill connection) */ udc_detach(); /* With knowledge that I will rise again, I lay down my life. */ while (RSTC->RSTC_SR & RSTC_SR_SRCMP); RSTC->RSTC_CR |= RSTC_CR_KEY(0xA5) | RSTC_CR_PERRST | RSTC_CR_PROCRST; while(1); break; #ifdef PLATFORMCW1180 /* 0xA0 starts CW1180 Specific Commands */ case 0xA0: enable_lcd(); redraw_background(); break; #endif /* Oh well, sucks to be you */ default: break; } }
/** * \brief Test wait mode. */ static void test_wait_mode(void) { puts(STRING_WAIT); #if SAMG55 /* Wait for the transmission done before changing clock */ while (!usart_is_tx_empty(CONSOLE_UART)) { } #else /* Wait for the transmission done before changing clock */ while (!uart_is_tx_empty(CONSOLE_UART)) { } #endif /* Configure fast RC oscillator */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); #if (SAMG) pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); #else pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); #endif pmc_switch_mck_to_mainck(PMC_PCK_PRES_CLK_1); #if (SAMG) g_ul_current_mck = 8000000; /* 8MHz */ #else g_ul_current_mck = 4000000; /* 4MHz */ #endif /* Disable unused clock to save power */ pmc_osc_disable_xtal(0); example_disable_pll(); /* Set wakeup input for fast startup */ example_set_wakeup_from_wait_mode(); /* Enter into wait Mode */ pmc_enable_waitmode(); /* Set default clock and re-configure UART */ set_default_working_clock(); reconfigure_console(g_ul_current_mck, CONF_UART_BAUDRATE); puts("Exit from wait Mode.\r"); }
/** * Execute the application binary * * \param addr Application start address. * \return If success, no return; * 1 - address alignment error; * 2 - address not executable. */ static uint8_t _app_exec(void *addr) { uint32_t i; /* Check parameters */ if ((uint32_t)addr & 0x7F) { return 1; } if ((uint32_t)addr > CM_SRAM_END) { return 2; } __disable_irq(); /* Disable SysTick */ SysTick->CTRL = 0; /* Disable IRQs & clear pending IRQs */ for (i = 0; i < 8; i++) { NVIC->ICER[i] = 0xFFFFFFFF; NVIC->ICPR[i] = 0xFFFFFFFF; } /* Switch clock to slow RC */ osc_enable(OSC_SLCK_32K_RC); osc_wait_ready(OSC_SLCK_32K_RC); pmc_switch_mck_to_sclk(SYSCLK_PRES_1); /* Switch clock to fast RC */ osc_enable(OSC_MAINCK_12M_RC); osc_wait_ready(OSC_MAINCK_12M_RC); pmc_switch_mck_to_mainck(SYSCLK_PRES_1); /* Modify vector table location */ __DSB(); __ISB(); SCB->VTOR = ((uint32_t)addr & SCB_VTOR_TBLOFF_Msk); __DSB(); __ISB(); __enable_irq(); /* Jump to application */ jump_to_app(addr); /* Never be here */ return 0; }
/** * Save clock settings and shutdown PLLs */ __always_inline static void pmc_save_clock_settings( uint32_t *p_osc_setting, uint32_t *p_pll0_setting, uint32_t *p_pll1_setting, uint32_t *p_mck_setting) { if (p_osc_setting) { *p_osc_setting = PMC->CKGR_MOR; } if (p_pll0_setting) { *p_pll0_setting = PMC->CKGR_PLLAR; } if (p_pll1_setting) { #if (SAM3S || SAM4S) *p_pll1_setting = PMC->CKGR_PLLBR; #elif (SAM3U || SAM3XA) *p_pll1_setting = PMC->CKGR_UCKR; #else *p_pll1_setting = 0; #endif } if (p_mck_setting) { *p_mck_setting = PMC->PMC_MCKR; } /* Switch MCK to internal 4/8/12M RC for fast wakeup and disable unused clock for power saving. */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); pmc_osc_disable_xtal(0); pmc_disable_pllack(); #if (SAM3S || SAM4S) pmc_disable_pllbck(); #elif (SAM3U || SAM3XA) pmc_disable_upll_clock(); #endif pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_1); }
void sysclk_init(void) { struct pll_config pllcfg; /* Set a flash wait state depending on the new cpu frequency */ system_init_flash(sysclk_get_cpu_hz()); /* Config system clock setting */ if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_RC) { osc_enable(OSC_SLCK_32K_RC); osc_wait_ready(OSC_SLCK_32K_RC); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) { osc_enable(OSC_SLCK_32K_XTAL); osc_wait_ready(OSC_SLCK_32K_XTAL); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_BYPASS) { osc_enable(OSC_SLCK_32K_BYPASS); osc_wait_ready(OSC_SLCK_32K_BYPASS); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_4M_RC) { /* Already running from SYSCLK_SRC_MAINCK_4M_RC */ } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_8M_RC) { osc_enable(OSC_MAINCK_8M_RC); osc_wait_ready(OSC_MAINCK_8M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_12M_RC) { osc_enable(OSC_MAINCK_12M_RC); osc_wait_ready(OSC_MAINCK_12M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_XTAL) { osc_enable(OSC_MAINCK_XTAL); osc_wait_ready(OSC_MAINCK_XTAL); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_BYPASS) { osc_enable(OSC_MAINCK_BYPASS); osc_wait_ready(OSC_MAINCK_BYPASS); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } #ifdef CONFIG_PLL0_SOURCE else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) { pll_enable_source(CONFIG_PLL0_SOURCE); // Source is mainck, select source for mainck if (CONFIG_PLL0_SOURCE == PLL_SRC_MAINCK_4M_RC || CONFIG_PLL0_SOURCE == PLL_SRC_MAINCK_8M_RC || CONFIG_PLL0_SOURCE == PLL_SRC_MAINCK_12M_RC) { pmc_mainck_osc_select(0); while(!pmc_osc_is_ready_mainck()); # ifndef CONFIG_PLL1_SOURCE pmc_osc_disable_main_xtal(); # endif } else if (CONFIG_PLL0_SOURCE == PLL_SRC_MAINCK_XTAL || CONFIG_PLL0_SOURCE == PLL_SRC_MAINCK_BYPASS) { pmc_mainck_osc_select(CKGR_MOR_MOSCSEL); while(!pmc_osc_is_ready_mainck()); } pll_config_defaults(&pllcfg, 0); pll_enable(&pllcfg, 0); pll_wait_for_lock(0); pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); } #endif else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_UPLLCK) { pll_enable_source(CONFIG_PLL1_SOURCE); pll_config_defaults(&pllcfg, 1); pll_enable(&pllcfg, 1); pll_wait_for_lock(1); pmc_switch_mck_to_upllck(CONFIG_SYSCLK_PRES); } /* Update the SystemFrequency variable */ SystemCoreClockUpdate(); #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) /* Signal that the internal frequencies are setup */ sysclk_initialized = 1; #endif }
void sysclk_init(void) { /* Set flash wait state to max in case the below clock switching. */ system_init_flash(CHIP_FREQ_CPU_MAX); /* Config system clock setting */ if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_RC) { osc_enable(OSC_SLCK_32K_RC); osc_wait_ready(OSC_SLCK_32K_RC); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) { osc_enable(OSC_SLCK_32K_XTAL); osc_wait_ready(OSC_SLCK_32K_XTAL); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_BYPASS) { osc_enable(OSC_SLCK_32K_BYPASS); osc_wait_ready(OSC_SLCK_32K_BYPASS); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_4M_RC) { /* Already running from SYSCLK_SRC_MAINCK_4M_RC */ } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_8M_RC) { osc_enable(OSC_MAINCK_8M_RC); osc_wait_ready(OSC_MAINCK_8M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_12M_RC) { osc_enable(OSC_MAINCK_12M_RC); osc_wait_ready(OSC_MAINCK_12M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_XTAL) { osc_enable(OSC_MAINCK_XTAL); osc_wait_ready(OSC_MAINCK_XTAL); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_BYPASS) { osc_enable(OSC_MAINCK_BYPASS); osc_wait_ready(OSC_MAINCK_BYPASS); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); } #ifdef CONFIG_PLL0_SOURCE else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) { struct pll_config pllcfg; pll_enable_source(CONFIG_PLL0_SOURCE); pll_config_defaults(&pllcfg, 0); pll_enable(&pllcfg, 0); pll_wait_for_lock(0); pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); } #endif /* Update the SystemFrequency variable */ SystemCoreClockUpdate(); /* Set a flash wait state depending on the new cpu frequency */ system_init_flash(sysclk_get_cpu_hz()); #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) /* Signal that the internal frequencies are setup */ sysclk_initialized = 1; #endif }
void sysclk_init(void) { struct pll_config pllcfg; /* Set a flash wait state depending on the new cpu frequency */ system_init_flash(sysclk_get_cpu_hz()); /* Config system clock setting */ switch (CONFIG_SYSCLK_SOURCE) { case SYSCLK_SRC_SLCK_RC: osc_enable(OSC_SLCK_32K_RC); osc_wait_ready(OSC_SLCK_32K_RC); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_SLCK_XTAL: osc_enable(OSC_SLCK_32K_XTAL); osc_wait_ready(OSC_SLCK_32K_XTAL); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_SLCK_BYPASS: osc_enable(OSC_SLCK_32K_BYPASS); osc_wait_ready(OSC_SLCK_32K_BYPASS); pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_MAINCK_4M_RC: /* Already running from SYSCLK_SRC_MAINCK_4M_RC */ break; case SYSCLK_SRC_MAINCK_8M_RC: osc_enable(OSC_MAINCK_8M_RC); osc_wait_ready(OSC_MAINCK_8M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_MAINCK_12M_RC: osc_enable(OSC_MAINCK_12M_RC); osc_wait_ready(OSC_MAINCK_12M_RC); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_MAINCK_XTAL: osc_enable(OSC_MAINCK_XTAL); osc_wait_ready(OSC_MAINCK_XTAL); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); break; case SYSCLK_SRC_MAINCK_BYPASS: osc_enable(OSC_MAINCK_BYPASS); osc_wait_ready(OSC_MAINCK_BYPASS); pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); break; #ifdef CONFIG_PLL0_SOURCE case SYSCLK_SRC_PLLACK: pll_enable_source(CONFIG_PLL0_SOURCE); pll_config_defaults(&pllcfg, 0); pll_enable(&pllcfg, 0); pll_wait_for_lock(0); pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); break; #endif case SYSCLK_SRC_UPLLCK: pll_enable_source(CONFIG_PLL1_SOURCE); pll_config_defaults(&pllcfg, 1); pll_enable(&pllcfg, 1); pll_wait_for_lock(1); pmc_switch_mck_to_upllck(CONFIG_SYSCLK_PRES); break; } /* Update the SystemFrequency variable */ SystemCoreClockUpdate(); #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) /* Signal that the internal frequencies are setup */ sysclk_initialized = 1; #endif }
/** * \brief Change clock configuration. * * \param p_uc_str Hint string to be output on console before changing clock. */ static void user_change_clock(uint8_t *p_uc_str) { uint8_t uc_key; uint32_t ul_id; /* Print menu */ puts(CLOCK_LIST_MENU); while (uart_read(CONSOLE_UART, &uc_key)) { } printf("Select option is: %c\n\r\n\r", uc_key); if (p_uc_str) { puts((char const *)p_uc_str); } while (!uart_is_tx_empty(CONSOLE_UART)) { } if ((uc_key >= MIN_CLOCK_FAST_RC_ITEM) && (uc_key <= MAX_CLOCK_FAST_RC_ITEM)) { ul_id = uc_key - MIN_CLOCK_FAST_RC_ITEM; /* Save current clock */ g_ul_current_mck = g_fastrc_clock_list[ul_id][0]; /* Switch MCK to Slow clock */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); /* Switch mainck to fast RC */ pmc_osc_enable_fastrc(CKGR_MOR_MOSCRCF_8_MHz); pmc_switch_mainck_to_fastrc(g_fastrc_clock_list[ul_id][1]); /* Switch MCK to mainck */ pmc_switch_mck_to_mainck(g_fastrc_clock_list[ul_id][2]); /* Disable unused clock to save power */ pmc_osc_disable_xtal(0); example_disable_pll(); } else if ((uc_key >= MIN_CLOCK_PLL_ITEM) && (uc_key <= MAX_CLOCK_PLL_ITEM)) { ul_id = uc_key - MIN_CLOCK_PLL_ITEM; /* Save current clock */ g_ul_current_mck = g_pll_clock_list[ul_id][0]; #if (SAMG) /* Switch MCK to main clock */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_1); #else /* Switch MCK to slow clock */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); /* Switch mainck to external xtal */ pmc_switch_mainck_to_xtal(0, BOARD_OSC_STARTUP_US); #endif /* Configure PLL and switch clock */ example_switch_clock(g_pll_clock_list[ul_id][1], PLL_COUNT, g_pll_clock_list[ul_id][2], g_pll_clock_list[ul_id][3]); #if (!SAMG) /* Disable unused clock to save power */ pmc_osc_disable_fastrc(); #endif } else { puts("Clock is not changed.\r"); } }
static unsigned long wait_mode_power_down_hook( unsigned long delay_ms ) { bool jtag_enabled = ( ( CoreDebug ->DHCSR & CoreDebug_DEMCR_TRCENA_Msk ) != 0 ) ? true : false; bool jtag_delay_elapsed = ( mico_get_time() > JTAG_DEBUG_SLEEP_DELAY_MS ) ? true : false; uint32_t elapsed_cycles = 0; /* Criteria to enter WAIT mode * 1. Clock needed counter is 0 and no JTAG debugging * 2. Clock needed counter is 0, in JTAG debugging session, and MiCO system tick has progressed over 3 seconds. * This is to give OpenOCD enough time to poke the JTAG tap before the CPU enters WAIT mode. */ if ( ( samg5x_clock_needed_counter == 0 ) && ( ( jtag_enabled == false ) || ( ( jtag_enabled == true ) && ( jtag_delay_elapsed == true ) ) ) ) { uint32_t total_sleep_cycles; uint32_t total_delay_cycles; /* Start real-time timer */ rtt_init( RTT, RTT_CLOCK_PRESCALER ); /* Start atomic operation */ DISABLE_INTERRUPTS; /* Ensure deep sleep bit is enabled, otherwise system doesn't go into deep sleep */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Disable SysTick */ SysTick->CTRL &= ( ~( SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk ) ); /* End atomic operation */ ENABLE_INTERRUPTS; /* Expected total time CPU executing in this function (including WAIT mode time) */ total_sleep_cycles = MS_TO_CYCLES( delay_ms ); /* Total cycles in WAIT mode loop */ total_delay_cycles = ( total_sleep_cycles / RTT_MAX_CYCLES + 1 ) * RC_OSC_DELAY_CYCLES + WAIT_MODE_ENTER_DELAY_CYCLES + WAIT_MODE_EXIT_DELAY_CYCLES; if ( total_sleep_cycles > total_delay_cycles ) { /* Adjust total sleep cycle to exclude exit delay */ total_sleep_cycles -= WAIT_MODE_EXIT_DELAY_CYCLES; /* Prepare platform specific settings before entering powersave */ // platform_enter_powersave(); ///* Prepare WLAN bus before entering powersave */ //platform_bus_enter_powersave(); /* Disable brownout detector */ supc_disable_brownout_detector( SUPC ); /* Backup system I/0 functions and set all to GPIO to save power */ system_io_backup_value = matrix_get_system_io(); matrix_set_system_io( 0x0CF0 ); /* Switch Master Clock to Main Clock (internal fast RC oscillator) */ pmc_switch_mck_to_mainck( PMC_PCK_PRES_CLK_1 ); /* Switch on internal fast RC oscillator, switch Main Clock source to internal fast RC oscillator and disables external fast crystal */ pmc_switch_mainck_to_fastrc( CKGR_MOR_MOSCRCF_8_MHz ); /* Disable external fast crystal */ pmc_osc_disable_xtal( 0 ); /* Disable PLLA */ pmc_disable_pllack( ); /* This above process introduces certain delay. Add delay to the elapsed cycles */ elapsed_cycles += rtt_read_timer_value( RTT ); while ( wake_up_interrupt_triggered == false && elapsed_cycles < total_sleep_cycles ) { uint32_t current_sleep_cycles = total_sleep_cycles - elapsed_cycles; /* Start real-time timer and alarm */ rtt_init( RTT, RTT_CLOCK_PRESCALER ); rtt_write_alarm_time( RTT, ( current_sleep_cycles > RTT_MAX_CYCLES ) ? RTT_MAX_CYCLES - RC_OSC_DELAY_CYCLES : current_sleep_cycles - RC_OSC_DELAY_CYCLES ); __asm("wfi"); /* Enter WAIT mode */ //pmc_enable_waitmode(); /* Clear wake-up status */ rtt_get_status( RTT ); /* Add sleep time to the elapsed cycles */ elapsed_cycles += rtt_read_timer_value( RTT ); } /* Re-enable real-time timer to time clock reinitialisation delay */ rtt_init( RTT, RTT_CLOCK_PRESCALER ); /* Reinit fast clock. This takes ~19ms, but the timing has been compensated */ init_clocks(); /* Disable unused clock to save power */ pmc_osc_disable_fastrc(); /* Restore system I/O pins */ matrix_set_system_io( system_io_backup_value ); /* Restore WLAN bus */ //platform_bus_exit_powersave(); // /* Restore platform-specific settings */ // platform_exit_powersave(); /* Add clock reinitialisation delay to elapsed cycles */ elapsed_cycles += rtt_read_timer_value( RTT ); /* Disable RTT to save power */ RTT->RTT_MR = (uint32_t)( 1 << 20 ); } } /* Start atomic operation */ DISABLE_INTERRUPTS; /* Switch SysTick back on */ SysTick->CTRL |= ( SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk ); /* Clear flag indicating interrupt triggered by wake up pin */ wake_up_interrupt_triggered = false; /* End atomic operation */ ENABLE_INTERRUPTS; /* Return total time in milliseconds */ return CYCLES_TO_MS( elapsed_cycles ); }
/** * \brief Application entry point for pmc_clock switch example. * * \return Unused (ANSI-C compatibility). */ int main(void) { /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the console uart */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Configure PCK */ ioport_set_pin_mode(GCLK_PIN, GCLK_PIN_MUX); ioport_disable_pin(GCLK_PIN); /* Configure the push button */ configure_buttons(); puts("-I- Press Button "BUTTON_NAME" to continue.\r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } puts("\n\r-I- Switch 8Mhz fast RC oscillator to be the source of the main clock \n\r" "-I- The master clock is main clock divided by 2\n\r" "-I- From now on, the UART baud rate is 2400bps. So please change the terminal setting before the next clock switch\r\n" "-I- Press Button "BUTTON_NAME" to switch next clock configuration... \r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* First switch to slow clock */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); #if (SAM3S || SAM4S || SAM4C) /* Then cut the PLL B */ pmc_disable_pllbck(); #endif /* Switch the mainck clock to the Fast RC, parameter '1' stands for 8Mhz */ pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); /* And finalize by switching to Fast RC */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_2); /* The clock source for the UART is the PCK, so the uart needs re-configuration */ config_uart_and_pck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES_CLK_2, (CHIP_FREQ_MAINCK_RC_8MHZ / 2)); for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } puts("\n\r-I- Switch the XTAL 32K crystal oscillator to be the source of the slow clock\n\r" "-I- The master clock is slow clock\n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration after it has been measured.\r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* Enable the External 32K oscillator */ pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); /* If a new value for CSS field corresponds to Main Clock or Slow Clock, * program the CSS field first. */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); /* The clock source for the UART is the PCK, so the uart needs *re-configuration. */ config_uart_and_pck(PMC_PCK_CSS_SLOW_CLK, PMC_PCK_PRES_CLK_1, BOARD_FREQ_SLCK_XTAL); for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } /* Switch the mainck to the Fast RC, parameter '2' stands for 12Mhz */ pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); /* If a new value for CSS field corresponds to Main Clock or Slow Clock, * program the CSS field first. */ pmc_switch_mck_to_mainck(PMC_PCK_PRES_CLK_1); /* The clock source for the UART is the PCK, so the uart needs * re-configuration. */ config_uart_and_pck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES_CLK_1, CHIP_FREQ_MAINCK_RC_12MHZ); puts("\n\r-I- Switch 12Mhz fast RC oscillator to be the source of the main clock\n\r" "-I- The master clock is the main clock\n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration after it has been measured.\r\n"); for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } #if SAM4C puts("-I- Switch to 8.192Mhz PLLA clock as the source of the master clock \n\r" "-I- The master clock is PLLA clock divided by 2 \n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration... \r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* Enable the PLLA clock, the mainck equals 32.768K * 250 = 8.192Mhz */ pmc_enable_pllack((250 - 1), 0x3f, 1); #else puts("-I- Switch to 128Mhz PLLA clock as the source of the master clock \n\r" "-I- The master clock is PLLA clock divided by 2 \n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration... \r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* Enable the PLLA clock, the mainck equals 12Mhz * (32-1+1) / 3 = 128Mhz */ pmc_enable_pllack((32 - 1), 0x3f, 3); #endif /* If a new value for CSS field corresponds to PLL Clock, Program the PRES * field first. */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_2); /* Delay for a while */ /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* Then program the CSS field. */ pmc_switch_mck_to_pllack(PMC_MCKR_PRES_CLK_2); /* The clock source for the UART is the PCK, so the uart needs * re-configuration */ config_uart_and_pck(PMC_PCK_CSS_PLLA_CLK, PMC_PCK_PRES_CLK_2, PMC_CLOCK_SWITCHING_EXAMPLE_FIXED_PLLA/2); for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } puts("\n\r-I- Switch the XTAL 32K crystal oscillator to be the source of the slow clock\n\r" "-I- The master clock is slow clock\n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration...\r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* Switch slow clck to extern 32k xtal */ pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); /* Delay for a while to make sure the clock is stable */ /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; /* If a new value for CSS field corresponds to Main Clock or Slow Clock, * program the CSS field first. */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_2); /* Switch the mck to sclk but keep the PRES field same */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_2); /* Then program the PRES field. */ pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1); /* The clock source for the UART is the PCK, so the uart needs * re-configuration */ config_uart_and_pck(PMC_PCK_CSS_SLOW_CLK, PMC_PCK_PRES_CLK_1, BOARD_FREQ_SLCK_XTAL); for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } /* Switch mainck to external xtal */ pmc_switch_mainck_to_xtal(0, BOARD_OSC_STARTUP_US); /* If a new value for CSS field corresponds to Main Clock or Slow Clock, * program the CSS field first. */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_1); /* Then program the PRES field. */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_16); /* The clock source for the UART is the PCK, so the uart needs * re-configuration. */ config_uart_and_pck(PMC_PCK_CSS_MAIN_CLK, PMC_PCK_PRES_CLK_16, (BOARD_FREQ_MAINCK_XTAL / 16)); #if SAM4C puts("\n\r-I- Switch the external 8MHz crystal oscillator to be the source of the main clock\n\r" "-I- The master clock is main clock divided by 16\n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration...\r\n"); #else puts("\n\r-I- Switch the external 12MHz crystal oscillator to be the source of the main clock\n\r" "-I- The master clock is main clock divided by 16\n\r" "-I- Press Button "BUTTON_NAME" to switch next clock configuration...\r\n"); #endif #if (SAM3S || SAM4S || SAM4C) for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } puts("-I- Switch to 96Mhz PLLB clock as the source of the master clock\n\r" "-I- The master clock is PLLB clock divided by 2 \r"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; #if SAM4C /* Enable the PLLB clock, the mainck equals (8Mhz * (11+1) / 1) = 96Mhz * with the initialize counter be 0x3f */ pmc_enable_pllbck(11, 0x3f, 1); #else /* Enable the PLLB clock, the mainck equals (12Mhz * (7+1) / 1) = 96Mhz * with the initialize counter be 0x3f */ pmc_enable_pllbck(7, 0x3f, 1); #endif /* If a new value for CSS field corresponds to PLL Clock, Program the PRES * field first. */ pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_2); /* Then program the CSS field. */ pmc_switch_mck_to_pllbck(PMC_MCKR_PRES_CLK_2); /* The clock source for the UART is the PCK, so the uart needs * re-configuration. */ #if SAM4C config_uart_and_pck(PMC_PCK_CSS_PLLB_CLK, PMC_PCK_PRES_CLK_2, (BOARD_FREQ_MAINCK_XTAL * 12 / 2)); #else config_uart_and_pck(PMC_PCK_CSS_PLLB_CLK, PMC_PCK_PRES_CLK_2, (BOARD_FREQ_MAINCK_XTAL * 8 / 2)); #endif puts("-I- Press Button "BUTTON_NAME" to switch next clock configuration...\r\n"); #endif for (gs_uc_wait_button = 1; gs_uc_wait_button;) { } puts("\r\n\r\n-I- Done.\r\n"); /* Wait for UART transmit done */ while (!uart_is_tx_empty(CONF_UART)) { }; while (1) { } }