/** * \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 } }