/** * \brief Enable USB clock. * * \note The SAM3S UDP hardware interprets div as div+1. For readability the hardware div+1 * is hidden in this implementation. Use div as div effective value. * * \param pll_id Source of the USB clock. * \param div Actual clock divisor. Must be superior to 0. */ void sysclk_enable_usb(void) { Assert(CONFIG_USBCLK_DIV > 0); #ifdef CONFIG_PLL0_SOURCE if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL0) { 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_udpck_to_pllack(CONFIG_USBCLK_DIV - 1); pmc_enable_udpck(); return; } #endif #ifdef CONFIG_PLL1_SOURCE if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL1) { 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_udpck_to_pllbck(CONFIG_USBCLK_DIV - 1); pmc_enable_udpck(); return; } #endif }
/** * \brief Enable USB clock. * * \note The SAM3S UDP hardware interprets div as div+1. For readability the hardware div+1 * is hidden in this implementation. Use div as div effective value. * * \param pll_id Source of the USB clock. * \param div Actual clock diviser. Must be superior to 0. */ void sysclk_enable_usb(void) { Assert(CONFIG_USBCLK_DIV > 0); switch (CONFIG_USBCLK_SOURCE) { #ifdef CONFIG_PLL0_SOURCE case USBCLK_SRC_PLL0: { 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_udpck_to_pllack(CONFIG_USBCLK_DIV - 1); pmc_enable_udpck(); break; } #endif #ifdef CONFIG_PLL1_SOURCE case USBCLK_SRC_PLL1: { 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_udpck_to_pllbck(CONFIG_USBCLK_DIV - 1); pmc_enable_udpck(); break; } #endif } }
/** * \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 */ }
static void sysclk_init_pll(void) { struct pll_config pllcfg; switch (CONFIG_PLL0_SOURCE) { case PLL_SRC_RC2MHZ: break; case PLL_SRC_RC32MHZ: osc_enable(OSC_ID_RC32MHZ); osc_wait_ready(OSC_ID_RC32MHZ); break; case PLL_SRC_XOSC: osc_enable(OSC_ID_XOSC); osc_wait_ready(OSC_ID_XOSC); break; default: //unhandled_case(CONFIG_PLL0_SOURCE); break; } pll_config_defaults(&pllcfg, 0); pll_enable(&pllcfg, 0); pll_wait_for_lock(0); }
/** * \brief Enable USB clock. * * \note The SAM3U UDP hardware interprets div as div+1. For readability the * hardware div+1 is hidden in this implementation. Use div as div * effective value. * * \param pll_id Source of the USB clock. * \param div Actual clock divisor. Must be superior to 0. */ void sysclk_enable_usb(void) { struct pll_config pllcfg; pll_enable_source(CONFIG_PLL1_SOURCE); pll_config_defaults(&pllcfg, 1); pll_enable(&pllcfg, 1); pll_wait_for_lock(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 }
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!"); }