/** * \brief Configure clock for coprocessor. */ static void sysclk_configure_cpclk(void) { #if ((CONFIG_CPCLK_PRES < CPCLK_PRES_MIN) || (CONFIG_CPCLK_PRES > CPCLK_PRES_MAX)) #error Invalid CONFIG_CPCLK_PRES setting. #endif /* Assert coprocessor reset and reset its peripheral */ RSTC->RSTC_CPMR = RSTC_CPMR_CPKEY(0x5Au); #ifdef CONFIG_PLL0_SOURCE if ((CONFIG_CPCLK_SOURCE == CPCLK_SRC_PLLACK) && (pll_is_locked(0) == 0)) { struct pll_config pllcfg; pll_enable_source(CONFIG_PLL0_SOURCE); pll_config_defaults(&pllcfg, 0); pll_enable(&pllcfg, 0); pll_wait_for_lock(0); } #endif #ifdef CONFIG_PLL1_SOURCE if ((CONFIG_CPCLK_SOURCE == CPCLK_SRC_PLLBCK) && (pll_is_locked(1) == 0)) { struct pll_config pllcfg; pll_enable_source(CONFIG_PLL1_SOURCE); pll_config_defaults(&pllcfg, 1); pll_enable(&pllcfg, 1); pll_wait_for_lock(1); } #endif uint32_t read_reg; /* Enables Coprocessor Bus Master Clock */ PMC->PMC_SCER = PMC_SCER_CPBMCK | PMC_SCER_CPKEY_PASSWD; /* Enables the Coprocessor Clocks */ PMC->PMC_SCER = PMC_SCER_CPCK | PMC_SCER_CPKEY_PASSWD; /* Set coprocessor clock prescaler and source */ read_reg = REG_PMC_MCKR; read_reg &= ~PMC_MCKR_CPPRES_Msk; read_reg |= PMC_MCKR_CPPRES(CONFIG_CPCLK_PRES - 1); REG_PMC_MCKR = read_reg; /* Choose coprocessor main clock source */ read_reg = REG_PMC_MCKR; read_reg &= ~PMC_MCKR_CPCSS_Msk; read_reg |= (CONFIG_CPCLK_SOURCE << PMC_MCKR_CPCSS_Pos); REG_PMC_MCKR = read_reg; /* Release coprocessor peripheral reset */ RSTC->RSTC_CPMR |= (RSTC_CPMR_CPKEY(0x5Au) | RSTC_CPMR_CPEREN); /* Enable Core 1 SRAM1 and SRAM2 memories */ pmc_enable_periph_clk(42); /* ID_SRAM1_2 */ }
/** * \brief Test Pll and DFLL (if have) * * This test enables pll/dfll source clock, sets its mul and div * factor, and then enables it. Check if it's locked after max * startup time. * * \param test Current test case. */ static void run_pll_dfll_test(const struct test_case *test) { uint32_t wait; bool status; /* avoid Cppcheck Warning */ UNUSED(wait); UNUSED(status); #if (defined CONFIG_PLL0_SOURCE) || (defined CONFIG_PLL1_SOURCE) struct pll_config pllcfg; #endif #ifdef CONFIG_PLL0_SOURCE pll_enable_source(CONFIG_PLL0_SOURCE); pll_config_defaults(&pllcfg, 0); pll_enable(&pllcfg, PLL0); for (wait = 0; wait < PLL_MAX_STARTUP_CYCLES; wait++) { //waiting PLL0 lock __asm__("nop"); }; status = pll_is_locked(PLL0); test_assert_true(test, status, "PLL0 can't be locked"); #endif #ifdef CONFIG_PLL1_SOURCE pll_enable_source(CONFIG_PLL1_SOURCE); pll_config_defaults(&pllcfg, 1); pll_enable(&pllcfg, PLL1); for (wait = 0; wait < PLL_MAX_STARTUP_CYCLES; wait++) { //waiting PLL1 lock __asm__("nop"); }; status = pll_is_locked(PLL1); test_assert_true(test, status, "PLL1 can't be locked"); #endif #ifdef CONFIG_DFLL0_SOURCE struct dfll_config dfllcfg; osc_enable(OSC_ID_RCSYS); osc_wait_ready(OSC_ID_RCSYS); dfll_config_defaults(&dfllcfg, 0); dfll_enable_closed_loop(&dfllcfg, 0); for (wait = 0; wait < DFLL_MAX_LOCK_CYCLES; wait++) { //waiting DFLL lock __asm__("nop"); }; status = dfll_is_fine_locked(0); test_assert_true(test, status, "DFLL can't be locked"); #endif }
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); } }