Пример #1
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

#ifdef CONFIG_PLL1_SOURCE
        case SYSCLK_SRC_PLLBCK:
            pll_enable_source(CONFIG_PLL1_SOURCE);
            pll_config_defaults(&pllcfg, 1);
            pll_enable(&pllcfg, 1);
            pll_wait_for_lock(1);
            pmc_switch_mck_to_pllbck(CONFIG_SYSCLK_PRES);
            break;
#endif
    }

    /* Update the SystemFrequency variable */
    SystemCoreClockUpdate();

#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
    /* Signal that the internal frequencies are setup */
    sysclk_initialized = 1;
#endif
}
Пример #2
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

#ifdef CONFIG_PLL1_SOURCE
    else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLBCK) {
        struct pll_config pllcfg;

        pll_enable_source(CONFIG_PLL1_SOURCE);
        pll_config_defaults(&pllcfg, 1);
        pll_enable(&pllcfg, 1);
        pll_wait_for_lock(1);
        pmc_switch_mck_to_pllbck(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

#ifdef CONFIG_CPCLK_ENABLE
    /* Enable coprocessor clock */
    sysclk_configure_cpclk();
#endif
}
/**
 * \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) {
	}
}