Example #1
0
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;
	}
}
Example #2
0
/**
 * \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");
}
Example #3
0
/**
 * 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;
}
Example #4
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);
}
Example #5
0
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
}
Example #6
0
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
}
Example #7
0
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
}
Example #8
0
/**
 * \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");
	}
}
Example #9
0
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) {
	}
}