--- /dev/null
+/**\r
+ * \file\r
+ *\r
+ * \brief Power Management Controller (PMC) driver for SAM.\r
+ *\r
+ * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.\r
+ *\r
+ * \asf_license_start\r
+ *\r
+ * \page License\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ * this list of conditions and the following disclaimer in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ *\r
+ * 3. The name of Atmel may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ *\r
+ * 4. This software may only be redistributed and used in connection with an\r
+ * Atmel microcontroller product.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR\r
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * \asf_license_stop\r
+ *\r
+ */\r
+/*\r
+ * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>\r
+ */\r
+\r
+#include "pmc.h"\r
+\r
+#if (SAM3N)\r
+# define MAX_PERIPH_ID 31\r
+#elif (SAM3XA)\r
+# define MAX_PERIPH_ID 44\r
+#elif (SAM3U)\r
+# define MAX_PERIPH_ID 29\r
+#elif (SAM3S || SAM4S)\r
+# define MAX_PERIPH_ID 34\r
+#elif (SAM4E)\r
+# define MAX_PERIPH_ID 47\r
+#elif (SAMV71)\r
+# define MAX_PERIPH_ID 63\r
+#elif (SAMV70)\r
+# define MAX_PERIPH_ID 63\r
+#elif (SAME70)\r
+# define MAX_PERIPH_ID 63\r
+#elif (SAMS70)\r
+# define MAX_PERIPH_ID 63\r
+#elif (SAM4N)\r
+# define MAX_PERIPH_ID 31\r
+#elif (SAM4C || SAM4CM || SAM4CP)\r
+# define MAX_PERIPH_ID 43\r
+#elif (SAMG51)\r
+# define MAX_PERIPH_ID 47\r
+#elif (SAMG53)\r
+# define MAX_PERIPH_ID 47\r
+#elif (SAMG54)\r
+# define MAX_PERIPH_ID 47\r
+#elif (SAMG55)\r
+# define MAX_PERIPH_ID 50\r
+#endif\r
+\r
+/// @cond 0\r
+/**INDENT-OFF**/\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+/**INDENT-ON**/\r
+/// @endcond\r
+\r
+/**\r
+ * \defgroup sam_drivers_pmc_group Power Management Controller (PMC)\r
+ *\r
+ * \par Purpose\r
+ *\r
+ * The Power Management Controller (PMC) optimizes power consumption by\r
+ * controlling all system and user peripheral clocks. The PMC enables/disables\r
+ * the clock inputs to many of the peripherals and the Cortex-M Processor.\r
+ *\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * \brief Set the prescaler of the MCK.\r
+ *\r
+ * \param ul_pres Prescaler value.\r
+ */\r
+void pmc_mck_set_prescaler(uint32_t ul_pres)\r
+{\r
+ PMC->PMC_MCKR =\r
+ (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres;\r
+ while (!(PMC->PMC_SR & PMC_SR_MCKRDY));\r
+}\r
+\r
+#if SAMV71 || SAMV70 || SAME70 || SAMS70\r
+/**\r
+ * \brief Set the division of the MCK.\r
+ *\r
+ * \param ul_div Division value.\r
+ */\r
+void pmc_mck_set_division(uint32_t ul_div)\r
+{\r
+ switch (ul_div) {\r
+ case 1:\r
+ ul_div = PMC_MCKR_MDIV_EQ_PCK;\r
+ break;\r
+ case 2:\r
+ ul_div = PMC_MCKR_MDIV_PCK_DIV2;\r
+ break;\r
+ case 3:\r
+ ul_div = PMC_MCKR_MDIV_PCK_DIV3;\r
+ break;\r
+ case 4:\r
+ ul_div = PMC_MCKR_MDIV_PCK_DIV4;\r
+ break;\r
+ default:\r
+ ul_div = PMC_MCKR_MDIV_EQ_PCK;\r
+ break;\r
+ }\r
+ PMC->PMC_MCKR =\r
+ (PMC->PMC_MCKR & (~PMC_MCKR_MDIV_Msk)) | ul_div;\r
+ while (!(PMC->PMC_SR & PMC_SR_MCKRDY));\r
+}\r
+#endif\r
+\r
+/**\r
+ * \brief Set the source of the MCK.\r
+ *\r
+ * \param ul_source Source selection value.\r
+ */\r
+void pmc_mck_set_source(uint32_t ul_source)\r
+{\r
+ PMC->PMC_MCKR =\r
+ (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | ul_source;\r
+ while (!(PMC->PMC_SR & PMC_SR_MCKRDY));\r
+}\r
+\r
+/**\r
+ * \brief Switch master clock source selection to slow clock.\r
+ *\r
+ * \param ul_pres Processor clock prescaler.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+uint32_t pmc_switch_mck_to_sclk(uint32_t ul_pres)\r
+{\r
+ uint32_t ul_timeout;\r
+\r
+ PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) |\r
+ PMC_MCKR_CSS_SLOW_CLK;\r
+ for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY);\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres;\r
+ for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY);\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/**\r
+ * \brief Switch master clock source selection to main clock.\r
+ *\r
+ * \param ul_pres Processor clock prescaler.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+uint32_t pmc_switch_mck_to_mainck(uint32_t ul_pres)\r
+{\r
+ uint32_t ul_timeout;\r
+\r
+ PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) |\r
+ PMC_MCKR_CSS_MAIN_CLK;\r
+ for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY);\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres;\r
+ for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY);\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/**\r
+ * \brief Switch master clock source selection to PLLA clock.\r
+ *\r
+ * \param ul_pres Processor clock prescaler.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+uint32_t pmc_switch_mck_to_pllack(uint32_t ul_pres)\r
+{\r
+ uint32_t ul_timeout;\r
+\r
+ PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres;\r
+ for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY);\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) |\r
+ PMC_MCKR_CSS_PLLA_CLK;\r
+\r
+ for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY);\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55)\r
+/**\r
+ * \brief Switch master clock source selection to PLLB clock.\r
+ *\r
+ * \param ul_pres Processor clock prescaler.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+uint32_t pmc_switch_mck_to_pllbck(uint32_t ul_pres)\r
+{\r
+ uint32_t ul_timeout;\r
+\r
+ PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres;\r
+ for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY);\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) |\r
+ PMC_MCKR_CSS_PLLB_CLK;\r
+ for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY);\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+#endif\r
+\r
+#if (SAM3XA || SAM3U || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+/**\r
+ * \brief Switch master clock source selection to UPLL clock.\r
+ *\r
+ * \param ul_pres Processor clock prescaler.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+uint32_t pmc_switch_mck_to_upllck(uint32_t ul_pres)\r
+{\r
+ uint32_t ul_timeout;\r
+\r
+ PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres;\r
+ for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY);\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) |\r
+ PMC_MCKR_CSS_UPLL_CLK;\r
+ for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY);\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+#endif\r
+\r
+/**\r
+ * \brief Switch slow clock source selection to external 32k (Xtal or Bypass).\r
+ *\r
+ * \note Switching SCLK back to 32krc is only possible by shutting down the\r
+ * VDDIO power supply.\r
+ *\r
+ * \param ul_bypass 0 for Xtal, 1 for bypass.\r
+ */\r
+void pmc_switch_sclk_to_32kxtal(uint32_t ul_bypass)\r
+{\r
+ /* Set Bypass mode if required */\r
+ if (ul_bypass == 1) {\r
+ SUPC->SUPC_MR |= SUPC_MR_KEY_PASSWD |\r
+ SUPC_MR_OSCBYPASS;\r
+ }\r
+\r
+ SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL;\r
+}\r
+\r
+/**\r
+ * \brief Check if the external 32k Xtal is ready.\r
+ *\r
+ * \retval 1 External 32k Xtal is ready.\r
+ * \retval 0 External 32k Xtal is not ready.\r
+ */\r
+uint32_t pmc_osc_is_ready_32kxtal(void)\r
+{\r
+ return ((SUPC->SUPC_SR & SUPC_SR_OSCSEL)\r
+ && (PMC->PMC_SR & PMC_SR_OSCSELS));\r
+}\r
+\r
+/**\r
+ * \brief Switch main clock source selection to internal fast RC.\r
+ *\r
+ * \param ul_moscrcf Fast RC oscillator(4/8/12Mhz).\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ * \retval 2 Invalid frequency.\r
+ */\r
+void pmc_switch_mainck_to_fastrc(uint32_t ul_moscrcf)\r
+{\r
+ /* Enable Fast RC oscillator but DO NOT switch to RC now */\r
+ PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN);\r
+\r
+ /* Wait the Fast RC to stabilize */\r
+ while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));\r
+\r
+ /* Change Fast RC oscillator frequency */\r
+ PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) |\r
+ CKGR_MOR_KEY_PASSWD | ul_moscrcf;\r
+\r
+ /* Wait the Fast RC to stabilize */\r
+ while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));\r
+\r
+ /* Switch to Fast RC */\r
+ PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) |\r
+ CKGR_MOR_KEY_PASSWD;\r
+}\r
+\r
+/**\r
+ * \brief Enable fast RC oscillator.\r
+ *\r
+ * \param ul_rc Fast RC oscillator(4/8/12Mhz).\r
+ */\r
+void pmc_osc_enable_fastrc(uint32_t ul_rc)\r
+{\r
+ /* Enable Fast RC oscillator but DO NOT switch to RC */\r
+ PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN);\r
+ /* Wait the Fast RC to stabilize */\r
+ while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));\r
+\r
+ /* Change Fast RC oscillator frequency */\r
+ PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) |\r
+ CKGR_MOR_KEY_PASSWD | ul_rc;\r
+ /* Wait the Fast RC to stabilize */\r
+ while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));\r
+}\r
+\r
+/**\r
+ * \brief Disable the internal fast RC.\r
+ */\r
+void pmc_osc_disable_fastrc(void)\r
+{\r
+ /* Disable Fast RC oscillator */\r
+ PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCEN &\r
+ ~CKGR_MOR_MOSCRCF_Msk)\r
+ | CKGR_MOR_KEY_PASSWD;\r
+}\r
+\r
+/**\r
+ * \brief Check if the main fastrc is ready.\r
+ *\r
+ * \retval 0 Xtal is not ready, otherwise ready.\r
+ */\r
+uint32_t pmc_osc_is_ready_fastrc(void)\r
+{\r
+ return (PMC->PMC_SR & PMC_SR_MOSCRCS);\r
+}\r
+\r
+/**\r
+ * \brief Enable main XTAL oscillator.\r
+ *\r
+ * \param ul_xtal_startup_time Xtal start-up time, in number of slow clocks.\r
+ */\r
+void pmc_osc_enable_main_xtal(uint32_t ul_xtal_startup_time)\r
+{\r
+ uint32_t mor = PMC->CKGR_MOR;\r
+ mor &= ~(CKGR_MOR_MOSCXTBY|CKGR_MOR_MOSCXTEN);\r
+ mor |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN |\r
+ CKGR_MOR_MOSCXTST(ul_xtal_startup_time);\r
+ PMC->CKGR_MOR = mor;\r
+ /* Wait the main Xtal to stabilize */\r
+ while (!(PMC->PMC_SR & PMC_SR_MOSCXTS));\r
+}\r
+\r
+/**\r
+ * \brief Bypass main XTAL.\r
+ */\r
+void pmc_osc_bypass_main_xtal(void)\r
+{\r
+ uint32_t mor = PMC->CKGR_MOR;\r
+ mor &= ~(CKGR_MOR_MOSCXTBY|CKGR_MOR_MOSCXTEN);\r
+ mor |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTBY;\r
+ /* Enable Crystal oscillator but DO NOT switch now. Keep MOSCSEL to 0 */\r
+ PMC->CKGR_MOR = mor;\r
+ /* The MOSCXTS in PMC_SR is automatically set */\r
+}\r
+\r
+/**\r
+ * \brief Disable the main Xtal.\r
+ */\r
+void pmc_osc_disable_main_xtal(void)\r
+{\r
+ uint32_t mor = PMC->CKGR_MOR;\r
+ mor &= ~(CKGR_MOR_MOSCXTBY|CKGR_MOR_MOSCXTEN);\r
+ PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | mor;\r
+}\r
+\r
+/**\r
+ * \brief Check if the main crystal is bypassed.\r
+ *\r
+ * \retval 0 Xtal is bypassed, otherwise not.\r
+ */\r
+uint32_t pmc_osc_is_bypassed_main_xtal(void)\r
+{\r
+ return (PMC->CKGR_MOR & CKGR_MOR_MOSCXTBY);\r
+}\r
+\r
+/**\r
+ * \brief Check if the main crystal is ready.\r
+ *\r
+ * \note If main crystal is bypassed, it's always ready.\r
+ *\r
+ * \retval 0 main crystal is not ready, otherwise ready.\r
+ */\r
+uint32_t pmc_osc_is_ready_main_xtal(void)\r
+{\r
+ return (PMC->PMC_SR & PMC_SR_MOSCXTS);\r
+}\r
+\r
+/**\r
+ * \brief Switch main clock source selection to external Xtal/Bypass.\r
+ *\r
+ * \note The function may switch MCK to SCLK if MCK source is MAINCK to avoid\r
+ * any system crash.\r
+ *\r
+ * \note If used in Xtal mode, the Xtal is automatically enabled.\r
+ *\r
+ * \param ul_bypass 0 for Xtal, 1 for bypass.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+void pmc_switch_mainck_to_xtal(uint32_t ul_bypass,\r
+ uint32_t ul_xtal_startup_time)\r
+{\r
+ /* Enable Main Xtal oscillator */\r
+ if (ul_bypass) {\r
+ PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) |\r
+ CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTBY |\r
+ CKGR_MOR_MOSCSEL;\r
+ } else {\r
+ PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) |\r
+ CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN |\r
+ CKGR_MOR_MOSCXTST(ul_xtal_startup_time);\r
+ /* Wait the Xtal to stabilize */\r
+ while (!(PMC->PMC_SR & PMC_SR_MOSCXTS));\r
+\r
+ PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCSEL;\r
+ }\r
+}\r
+\r
+/**\r
+ * \brief Disable the external Xtal.\r
+ *\r
+ * \param ul_bypass 0 for Xtal, 1 for bypass.\r
+ */\r
+void pmc_osc_disable_xtal(uint32_t ul_bypass)\r
+{\r
+ /* Disable xtal oscillator */\r
+ if (ul_bypass) {\r
+ PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) |\r
+ CKGR_MOR_KEY_PASSWD;\r
+ } else {\r
+ PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) |\r
+ CKGR_MOR_KEY_PASSWD;\r
+ }\r
+}\r
+\r
+/**\r
+ * \brief Check if the MAINCK is ready. Depending on MOSCEL, MAINCK can be one\r
+ * of Xtal, bypass or internal RC.\r
+ *\r
+ * \retval 1 Xtal is ready.\r
+ * \retval 0 Xtal is not ready.\r
+ */\r
+uint32_t pmc_osc_is_ready_mainck(void)\r
+{\r
+ return PMC->PMC_SR & PMC_SR_MOSCSELS;\r
+}\r
+\r
+/**\r
+ * \brief Select Main Crystal or internal RC as main clock source.\r
+ *\r
+ * \note This function will not enable/disable RC or Main Crystal.\r
+ *\r
+ * \param ul_xtal_rc 0 internal RC is selected, otherwise Main Crystal.\r
+ */\r
+void pmc_mainck_osc_select(uint32_t ul_xtal_rc)\r
+{\r
+ uint32_t mor = PMC->CKGR_MOR;\r
+ if (ul_xtal_rc) {\r
+ mor |= CKGR_MOR_MOSCSEL;\r
+ } else {\r
+ mor &= ~CKGR_MOR_MOSCSEL;\r
+ }\r
+ PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | mor;\r
+}\r
+\r
+/**\r
+ * \brief Enable PLLA clock.\r
+ *\r
+ * \param mula PLLA multiplier.\r
+ * \param pllacount PLLA counter.\r
+ * \param diva Divider.\r
+ */\r
+void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva)\r
+{\r
+ /* first disable the PLL to unlock the lock */\r
+ pmc_disable_pllack();\r
+\r
+#if (SAM4C || SAM4CM || SAM4CP || SAMG)\r
+ PMC->CKGR_PLLAR = CKGR_PLLAR_PLLAEN(diva) |\r
+ CKGR_PLLAR_PLLACOUNT(pllacount) | CKGR_PLLAR_MULA(mula);\r
+#else\r
+ PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_DIVA(diva) |\r
+ CKGR_PLLAR_PLLACOUNT(pllacount) | CKGR_PLLAR_MULA(mula);\r
+#endif\r
+ while ((PMC->PMC_SR & PMC_SR_LOCKA) == 0);\r
+}\r
+\r
+/**\r
+ * \brief Disable PLLA clock.\r
+ */\r
+void pmc_disable_pllack(void)\r
+{\r
+#if (SAM4C || SAM4CM || SAM4CP || SAMG)\r
+ PMC->CKGR_PLLAR = CKGR_PLLAR_MULA(0);\r
+#else\r
+ PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0);\r
+#endif\r
+}\r
+\r
+/**\r
+ * \brief Is PLLA locked?\r
+ *\r
+ * \retval 0 Not locked.\r
+ * \retval 1 Locked.\r
+ */\r
+uint32_t pmc_is_locked_pllack(void)\r
+{\r
+ return (PMC->PMC_SR & PMC_SR_LOCKA);\r
+}\r
+\r
+#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55)\r
+/**\r
+ * \brief Enable PLLB clock.\r
+ *\r
+ * \param mulb PLLB multiplier.\r
+ * \param pllbcount PLLB counter.\r
+ * \param divb Divider.\r
+ */\r
+void pmc_enable_pllbck(uint32_t mulb, uint32_t pllbcount, uint32_t divb)\r
+{\r
+ /* first disable the PLL to unlock the lock */\r
+ pmc_disable_pllbck();\r
+\r
+#if SAMG55\r
+ PMC->CKGR_PLLAR = CKGR_PLLAR_PLLAEN(divb) |\r
+ CKGR_PLLAR_PLLACOUNT(pllbcount) | CKGR_PLLAR_MULA(mulb);\r
+#else\r
+ PMC->CKGR_PLLBR =\r
+ CKGR_PLLBR_DIVB(divb) | CKGR_PLLBR_PLLBCOUNT(pllbcount)\r
+ | CKGR_PLLBR_MULB(mulb);\r
+#endif\r
+ while ((PMC->PMC_SR & PMC_SR_LOCKB) == 0);\r
+}\r
+\r
+/**\r
+ * \brief Disable PLLB clock.\r
+ */\r
+void pmc_disable_pllbck(void)\r
+{\r
+ PMC->CKGR_PLLBR = CKGR_PLLBR_MULB(0);\r
+}\r
+\r
+/**\r
+ * \brief Is PLLB locked?\r
+ *\r
+ * \retval 0 Not locked.\r
+ * \retval 1 Locked.\r
+ */\r
+uint32_t pmc_is_locked_pllbck(void)\r
+{\r
+ return (PMC->PMC_SR & PMC_SR_LOCKB);\r
+}\r
+#endif\r
+\r
+#if (SAM3XA || SAM3U || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+/**\r
+ * \brief Enable UPLL clock.\r
+ */\r
+void pmc_enable_upll_clock(void)\r
+{\r
+ PMC->CKGR_UCKR = CKGR_UCKR_UPLLCOUNT(3) | CKGR_UCKR_UPLLEN;\r
+\r
+ /* Wait UTMI PLL Lock Status */\r
+ while (!(PMC->PMC_SR & PMC_SR_LOCKU));\r
+}\r
+\r
+/**\r
+ * \brief Disable UPLL clock.\r
+ */\r
+void pmc_disable_upll_clock(void)\r
+{\r
+ PMC->CKGR_UCKR &= ~CKGR_UCKR_UPLLEN;\r
+}\r
+\r
+/**\r
+ * \brief Is UPLL locked?\r
+ *\r
+ * \retval 0 Not locked.\r
+ * \retval 1 Locked.\r
+ */\r
+uint32_t pmc_is_locked_upll(void)\r
+{\r
+ return (PMC->PMC_SR & PMC_SR_LOCKU);\r
+}\r
+#endif\r
+\r
+/**\r
+ * \brief Enable the specified peripheral clock.\r
+ *\r
+ * \note The ID must NOT be shifted (i.e., 1 << ID_xxx).\r
+ *\r
+ * \param ul_id Peripheral ID (ID_xxx).\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Invalid parameter.\r
+ */\r
+uint32_t pmc_enable_periph_clk(uint32_t ul_id)\r
+{\r
+ if (ul_id > MAX_PERIPH_ID) {\r
+ return 1;\r
+ }\r
+\r
+ if (ul_id < 32) {\r
+ if ((PMC->PMC_PCSR0 & (1u << ul_id)) != (1u << ul_id)) {\r
+ PMC->PMC_PCER0 = 1 << ul_id;\r
+ }\r
+#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+ } else {\r
+ ul_id -= 32;\r
+ if ((PMC->PMC_PCSR1 & (1u << ul_id)) != (1u << ul_id)) {\r
+ PMC->PMC_PCER1 = 1 << ul_id;\r
+ }\r
+#endif\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/**\r
+ * \brief Disable the specified peripheral clock.\r
+ *\r
+ * \note The ID must NOT be shifted (i.e., 1 << ID_xxx).\r
+ *\r
+ * \param ul_id Peripheral ID (ID_xxx).\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Invalid parameter.\r
+ */\r
+uint32_t pmc_disable_periph_clk(uint32_t ul_id)\r
+{\r
+ if (ul_id > MAX_PERIPH_ID) {\r
+ return 1;\r
+ }\r
+\r
+ if (ul_id < 32) {\r
+ if ((PMC->PMC_PCSR0 & (1u << ul_id)) == (1u << ul_id)) {\r
+ PMC->PMC_PCDR0 = 1 << ul_id;\r
+ }\r
+#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 \\r
+ || SAMV70 || SAME70 || SAMS70)\r
+ } else {\r
+ ul_id -= 32;\r
+ if ((PMC->PMC_PCSR1 & (1u << ul_id)) == (1u << ul_id)) {\r
+ PMC->PMC_PCDR1 = 1 << ul_id;\r
+ }\r
+#endif\r
+ }\r
+ return 0;\r
+}\r
+\r
+/**\r
+ * \brief Enable all peripheral clocks.\r
+ */\r
+void pmc_enable_all_periph_clk(void)\r
+{\r
+ PMC->PMC_PCER0 = PMC_MASK_STATUS0;\r
+ while ((PMC->PMC_PCSR0 & PMC_MASK_STATUS0) != PMC_MASK_STATUS0);\r
+\r
+#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMV71 \\r
+ || SAMV70 || SAME70 || SAMS70)\r
+ PMC->PMC_PCER1 = PMC_MASK_STATUS1;\r
+ while ((PMC->PMC_PCSR1 & PMC_MASK_STATUS1) != PMC_MASK_STATUS1);\r
+#endif\r
+}\r
+\r
+/**\r
+ * \brief Disable all peripheral clocks.\r
+ */\r
+void pmc_disable_all_periph_clk(void)\r
+{\r
+ PMC->PMC_PCDR0 = PMC_MASK_STATUS0;\r
+ while ((PMC->PMC_PCSR0 & PMC_MASK_STATUS0) != 0);\r
+\r
+#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMV71 \\r
+ || SAMV70 || SAME70 || SAMS70)\r
+ PMC->PMC_PCDR1 = PMC_MASK_STATUS1;\r
+ while ((PMC->PMC_PCSR1 & PMC_MASK_STATUS1) != 0);\r
+#endif\r
+}\r
+\r
+/**\r
+ * \brief Check if the specified peripheral clock is enabled.\r
+ *\r
+ * \note The ID must NOT be shifted (i.e., 1 << ID_xxx).\r
+ *\r
+ * \param ul_id Peripheral ID (ID_xxx).\r
+ *\r
+ * \retval 0 Peripheral clock is disabled or unknown.\r
+ * \retval 1 Peripheral clock is enabled.\r
+ */\r
+uint32_t pmc_is_periph_clk_enabled(uint32_t ul_id)\r
+{\r
+ if (ul_id > MAX_PERIPH_ID) {\r
+ return 0;\r
+ }\r
+\r
+#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMV71 \\r
+ || SAMV70 || SAME70 || SAMS70)\r
+ if (ul_id < 32) {\r
+#endif\r
+ if ((PMC->PMC_PCSR0 & (1u << ul_id))) {\r
+ return 1;\r
+ } else {\r
+ return 0;\r
+ }\r
+#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMV71 \\r
+ || SAMV70 || SAME70 || SAMS70)\r
+ } else {\r
+ ul_id -= 32;\r
+ if ((PMC->PMC_PCSR1 & (1u << ul_id))) {\r
+ return 1;\r
+ } else {\r
+ return 0;\r
+ }\r
+ }\r
+#endif\r
+}\r
+\r
+/**\r
+ * \brief Set the prescaler for the specified programmable clock.\r
+ *\r
+ * \param ul_id Peripheral ID.\r
+ * \param ul_pres Prescaler value.\r
+ */\r
+void pmc_pck_set_prescaler(uint32_t ul_id, uint32_t ul_pres)\r
+{\r
+ PMC->PMC_PCK[ul_id] =\r
+ (PMC->PMC_PCK[ul_id] & ~PMC_PCK_PRES_Msk) | ul_pres;\r
+ while ((PMC->PMC_SCER & (PMC_SCER_PCK0 << ul_id))\r
+ && !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)));\r
+}\r
+\r
+/**\r
+ * \brief Set the source oscillator for the specified programmable clock.\r
+ *\r
+ * \param ul_id Peripheral ID.\r
+ * \param ul_source Source selection value.\r
+ */\r
+void pmc_pck_set_source(uint32_t ul_id, uint32_t ul_source)\r
+{\r
+ PMC->PMC_PCK[ul_id] =\r
+ (PMC->PMC_PCK[ul_id] & ~PMC_PCK_CSS_Msk) | ul_source;\r
+ while ((PMC->PMC_SCER & (PMC_SCER_PCK0 << ul_id))\r
+ && !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)));\r
+}\r
+\r
+/**\r
+ * \brief Switch programmable clock source selection to slow clock.\r
+ *\r
+ * \param ul_id Id of the programmable clock.\r
+ * \param ul_pres Programmable clock prescaler.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+uint32_t pmc_switch_pck_to_sclk(uint32_t ul_id, uint32_t ul_pres)\r
+{\r
+ uint32_t ul_timeout;\r
+\r
+ PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_SLOW_CLK | ul_pres;\r
+ for (ul_timeout = PMC_TIMEOUT;\r
+ !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/**\r
+ * \brief Switch programmable clock source selection to main clock.\r
+ *\r
+ * \param ul_id Id of the programmable clock.\r
+ * \param ul_pres Programmable clock prescaler.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+uint32_t pmc_switch_pck_to_mainck(uint32_t ul_id, uint32_t ul_pres)\r
+{\r
+ uint32_t ul_timeout;\r
+\r
+ PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_MAIN_CLK | ul_pres;\r
+ for (ul_timeout = PMC_TIMEOUT;\r
+ !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/**\r
+ * \brief Switch programmable clock source selection to PLLA clock.\r
+ *\r
+ * \param ul_id Id of the programmable clock.\r
+ * \param ul_pres Programmable clock prescaler.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+uint32_t pmc_switch_pck_to_pllack(uint32_t ul_id, uint32_t ul_pres)\r
+{\r
+ uint32_t ul_timeout;\r
+\r
+ PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_PLLA_CLK | ul_pres;\r
+ for (ul_timeout = PMC_TIMEOUT;\r
+ !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55)\r
+/**\r
+ * \brief Switch programmable clock source selection to PLLB clock.\r
+ *\r
+ * \param ul_id Id of the programmable clock.\r
+ * \param ul_pres Programmable clock prescaler.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+uint32_t pmc_switch_pck_to_pllbck(uint32_t ul_id, uint32_t ul_pres)\r
+{\r
+ uint32_t ul_timeout;\r
+\r
+ PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_PLLB_CLK | ul_pres;\r
+ for (ul_timeout = PMC_TIMEOUT;\r
+ !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id));\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+#endif\r
+\r
+#if (SAM3XA || SAM3U || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+/**\r
+ * \brief Switch programmable clock source selection to UPLL clock.\r
+ *\r
+ * \param ul_id Id of the programmable clock.\r
+ * \param ul_pres Programmable clock prescaler.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+uint32_t pmc_switch_pck_to_upllck(uint32_t ul_id, uint32_t ul_pres)\r
+{\r
+ uint32_t ul_timeout;\r
+\r
+ PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_UPLL_CLK | ul_pres;\r
+ for (ul_timeout = PMC_TIMEOUT;\r
+ !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id));\r
+ --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+#endif\r
+\r
+/**\r
+ * \brief Switch programmable clock source selection to mck.\r
+ *\r
+ * \param ul_id Id of the programmable clock.\r
+ * \param ul_pres Programmable clock prescaler.\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Timeout error.\r
+ */\r
+uint32_t pmc_switch_pck_to_mck(uint32_t ul_id, uint32_t ul_pres)\r
+{\r
+ uint32_t ul_timeout;\r
+\r
+ PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_MCK | ul_pres;\r
+ for (ul_timeout = PMC_TIMEOUT;\r
+ !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) {\r
+ if (ul_timeout == 0) {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/**\r
+ * \brief Enable the specified programmable clock.\r
+ *\r
+ * \param ul_id Id of the programmable clock.\r
+ */\r
+void pmc_enable_pck(uint32_t ul_id)\r
+{\r
+ PMC->PMC_SCER = PMC_SCER_PCK0 << ul_id;\r
+}\r
+\r
+/**\r
+ * \brief Disable the specified programmable clock.\r
+ *\r
+ * \param ul_id Id of the programmable clock.\r
+ */\r
+void pmc_disable_pck(uint32_t ul_id)\r
+{\r
+ PMC->PMC_SCDR = PMC_SCER_PCK0 << ul_id;\r
+}\r
+\r
+/**\r
+ * \brief Enable all programmable clocks.\r
+ */\r
+void pmc_enable_all_pck(void)\r
+{\r
+ PMC->PMC_SCER = PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2;\r
+}\r
+\r
+/**\r
+ * \brief Disable all programmable clocks.\r
+ */\r
+void pmc_disable_all_pck(void)\r
+{\r
+ PMC->PMC_SCDR = PMC_SCDR_PCK0 | PMC_SCDR_PCK1 | PMC_SCDR_PCK2;\r
+}\r
+\r
+/**\r
+ * \brief Check if the specified programmable clock is enabled.\r
+ *\r
+ * \param ul_id Id of the programmable clock.\r
+ *\r
+ * \retval 0 Programmable clock is disabled or unknown.\r
+ * \retval 1 Programmable clock is enabled.\r
+ */\r
+uint32_t pmc_is_pck_enabled(uint32_t ul_id)\r
+{\r
+ if (ul_id > 2) {\r
+ return 0;\r
+ }\r
+\r
+ return (PMC->PMC_SCSR & (PMC_SCSR_PCK0 << ul_id));\r
+}\r
+\r
+#if (SAM4C || SAM4CM || SAM4CP)\r
+/**\r
+ * \brief Enable Coprocessor Clocks.\r
+ */\r
+void pmc_enable_cpck(void)\r
+{\r
+ PMC->PMC_SCER = PMC_SCER_CPCK | PMC_SCER_CPKEY_PASSWD;\r
+}\r
+\r
+/**\r
+ * \brief Disable Coprocessor Clocks.\r
+ */\r
+void pmc_disable_cpck(void)\r
+{\r
+ PMC->PMC_SCDR = PMC_SCDR_CPCK | PMC_SCDR_CPKEY_PASSWD;\r
+}\r
+\r
+/**\r
+ * \brief Check if the Coprocessor Clocks is enabled.\r
+ *\r
+ * \retval 0 Coprocessor Clocks is disabled.\r
+ * \retval 1 Coprocessor Clocks is enabled.\r
+ */\r
+bool pmc_is_cpck_enabled(void)\r
+{\r
+ if(PMC->PMC_SCSR & PMC_SCSR_CPCK) {\r
+ return 1;\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+\r
+/**\r
+ * \brief Enable Coprocessor Bus Master Clocks.\r
+ */\r
+void pmc_enable_cpbmck(void)\r
+{\r
+ PMC->PMC_SCER = PMC_SCER_CPCK | PMC_SCER_CPKEY_PASSWD;\r
+}\r
+\r
+/**\r
+ * \brief Disable Coprocessor Bus Master Clocks.\r
+ */\r
+void pmc_disable_cpbmck(void)\r
+{\r
+ PMC->PMC_SCDR = PMC_SCDR_CPCK | PMC_SCDR_CPKEY_PASSWD;\r
+}\r
+\r
+/**\r
+ * \brief Check if the Coprocessor Bus Master Clocks is enabled.\r
+ *\r
+ * \retval 0 Coprocessor Bus Master Clocks is disabled.\r
+ * \retval 1 Coprocessor Bus Master Clocks is enabled.\r
+ */\r
+bool pmc_is_cpbmck_enabled(void)\r
+{\r
+ if(PMC->PMC_SCSR & PMC_SCSR_CPBMCK) {\r
+ return 1;\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+\r
+/**\r
+ * \brief Set the prescaler for the Coprocessor Master Clock.\r
+ *\r
+ * \param ul_pres Prescaler value.\r
+ */\r
+void pmc_cpck_set_prescaler(uint32_t ul_pres)\r
+{\r
+ PMC->PMC_MCKR =\r
+ (PMC->PMC_MCKR & (~PMC_MCKR_CPPRES_Msk)) | PMC_MCKR_CPPRES(ul_pres);\r
+}\r
+\r
+/**\r
+ * \brief Set the source for the Coprocessor Master Clock.\r
+ *\r
+ * \param ul_source Source selection value.\r
+ */\r
+void pmc_cpck_set_source(uint32_t ul_source)\r
+{\r
+ PMC->PMC_MCKR =\r
+ (PMC->PMC_MCKR & (~PMC_MCKR_CPCSS_Msk)) | ul_source;\r
+}\r
+#endif\r
+\r
+#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+/**\r
+ * \brief Switch UDP (USB) clock source selection to PLLA clock.\r
+ *\r
+ * \param ul_usbdiv Clock divisor.\r
+ */\r
+void pmc_switch_udpck_to_pllack(uint32_t ul_usbdiv)\r
+{\r
+ PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv);\r
+}\r
+#endif\r
+\r
+#if (SAM3S || SAM4S || SAMG55)\r
+/**\r
+ * \brief Switch UDP (USB) clock source selection to PLLB clock.\r
+ *\r
+ * \param ul_usbdiv Clock divisor.\r
+ */\r
+void pmc_switch_udpck_to_pllbck(uint32_t ul_usbdiv)\r
+{\r
+ PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv) | PMC_USB_USBS;\r
+}\r
+#endif\r
+\r
+#if (SAM3XA || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+/**\r
+ * \brief Switch UDP (USB) clock source selection to UPLL clock.\r
+ *\r
+ * \param ul_usbdiv Clock divisor.\r
+ */\r
+void pmc_switch_udpck_to_upllck(uint32_t ul_usbdiv)\r
+{\r
+ PMC->PMC_USB = PMC_USB_USBS | PMC_USB_USBDIV(ul_usbdiv);\r
+}\r
+#endif\r
+\r
+#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+/**\r
+ * \brief Enable UDP (USB) clock.\r
+ */\r
+void pmc_enable_udpck(void)\r
+{\r
+#if (SAM3S || SAM4S || SAM4E || SAMG55)\r
+ PMC->PMC_SCER = PMC_SCER_UDP;\r
+#elif (SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+ PMC->PMC_SCER = PMC_SCER_USBCLK;\r
+#else\r
+ PMC->PMC_SCER = PMC_SCER_UOTGCLK;\r
+# endif\r
+}\r
+\r
+/**\r
+ * \brief Disable UDP (USB) clock.\r
+ */\r
+void pmc_disable_udpck(void)\r
+{\r
+#if (SAM3S || SAM4S || SAM4E || SAMG55)\r
+ PMC->PMC_SCDR = PMC_SCDR_UDP;\r
+#elif (SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+ PMC->PMC_SCDR = PMC_SCDR_USBCLK;\r
+#else\r
+ PMC->PMC_SCDR = PMC_SCDR_UOTGCLK;\r
+# endif\r
+}\r
+#endif\r
+\r
+#if SAMG55\r
+/**\r
+ * \brief Switch UHP (USB) clock source selection to PLLA clock.\r
+ *\r
+ * \param ul_usbdiv Clock divisor.\r
+ */\r
+void pmc_switch_uhpck_to_pllack(uint32_t ul_usbdiv)\r
+{\r
+ PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv);\r
+}\r
+\r
+/**\r
+ * \brief Switch UHP (USB) clock source selection to PLLB clock.\r
+ *\r
+ * \param ul_usbdiv Clock divisor.\r
+ */\r
+void pmc_switch_uhpck_to_pllbck(uint32_t ul_usbdiv)\r
+{\r
+ PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv) | PMC_USB_USBS;\r
+}\r
+\r
+/**\r
+ * \brief Enable UHP (USB) clock.\r
+ */\r
+void pmc_enable_uhpck(void)\r
+{\r
+ PMC->PMC_SCER = PMC_SCER_UHP;\r
+}\r
+#endif\r
+\r
+/**\r
+ * \brief Enable PMC interrupts.\r
+ *\r
+ * \param ul_sources Interrupt sources bit map.\r
+ */\r
+void pmc_enable_interrupt(uint32_t ul_sources)\r
+{\r
+ PMC->PMC_IER = ul_sources;\r
+}\r
+\r
+/**\r
+ * \brief Disable PMC interrupts.\r
+ *\r
+ * \param ul_sources Interrupt sources bit map.\r
+ */\r
+void pmc_disable_interrupt(uint32_t ul_sources)\r
+{\r
+ PMC->PMC_IDR = ul_sources;\r
+}\r
+\r
+/**\r
+ * \brief Get PMC interrupt mask.\r
+ *\r
+ * \return The interrupt mask value.\r
+ */\r
+uint32_t pmc_get_interrupt_mask(void)\r
+{\r
+ return PMC->PMC_IMR;\r
+}\r
+\r
+/**\r
+ * \brief Get current status.\r
+ *\r
+ * \return The current PMC status.\r
+ */\r
+uint32_t pmc_get_status(void)\r
+{\r
+ return PMC->PMC_SR;\r
+}\r
+\r
+/**\r
+ * \brief Set the wake-up inputs for fast startup mode registers\r
+ * (event generation).\r
+ *\r
+ * \param ul_inputs Wake up inputs to enable.\r
+ */\r
+void pmc_set_fast_startup_input(uint32_t ul_inputs)\r
+{\r
+ ul_inputs &= PMC_FAST_STARTUP_Msk;\r
+ PMC->PMC_FSMR |= ul_inputs;\r
+}\r
+\r
+/**\r
+ * \brief Clear the wake-up inputs for fast startup mode registers\r
+ * (remove event generation).\r
+ *\r
+ * \param ul_inputs Wake up inputs to disable.\r
+ */\r
+void pmc_clr_fast_startup_input(uint32_t ul_inputs)\r
+{\r
+ ul_inputs &= PMC_FAST_STARTUP_Msk;\r
+ PMC->PMC_FSMR &= ~ul_inputs;\r
+}\r
+\r
+#if (SAM4C || SAM4CM || SAM4CP)\r
+/**\r
+ * \brief Set the wake-up inputs of coprocessor for fast startup mode registers\r
+ * (event generation).\r
+ *\r
+ * \param ul_inputs Wake up inputs to enable.\r
+ */\r
+void pmc_cp_set_fast_startup_input(uint32_t ul_inputs)\r
+{\r
+ ul_inputs &= PMC_FAST_STARTUP_Msk;\r
+ PMC->PMC_CPFSMR |= ul_inputs;\r
+}\r
+\r
+/**\r
+ * \brief Clear the wake-up inputs of coprocessor for fast startup mode registers\r
+ * (remove event generation).\r
+ *\r
+ * \param ul_inputs Wake up inputs to disable.\r
+ */\r
+void pmc_cp_clr_fast_startup_input(uint32_t ul_inputs)\r
+{\r
+ ul_inputs &= PMC_FAST_STARTUP_Msk;\r
+ PMC->PMC_CPFSMR &= ~ul_inputs;\r
+}\r
+#endif\r
+\r
+#if (!(SAMG51 || SAMG53 || SAMG54))\r
+/**\r
+ * \brief Enable Sleep Mode.\r
+ * Enter condition: (WFE or WFI) + (SLEEPDEEP bit = 0) + (LPM bit = 0)\r
+ *\r
+ * \param uc_type 0 for wait for interrupt, 1 for wait for event.\r
+ * \note For SAM4S, SAM4C, SAM4CM, SAM4CP, SAMV71 and SAM4E series,\r
+ * since only WFI is effective, uc_type = 1 will be treated as uc_type = 0.\r
+ */\r
+void pmc_enable_sleepmode(uint8_t uc_type)\r
+{\r
+#if !(SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+ PMC->PMC_FSMR &= (uint32_t) ~ PMC_FSMR_LPM; // Enter Sleep mode\r
+#endif\r
+ SCB->SCR &= (uint32_t) ~ SCB_SCR_SLEEPDEEP_Msk; // Deep sleep\r
+\r
+#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+ UNUSED(uc_type);\r
+ __WFI();\r
+#else\r
+ if (uc_type == 0) {\r
+ __WFI();\r
+ } else {\r
+ __WFE();\r
+ }\r
+#endif\r
+}\r
+#endif\r
+\r
+#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+static uint32_t ul_flash_in_wait_mode = PMC_WAIT_MODE_FLASH_DEEP_POWERDOWN;\r
+/**\r
+ * \brief Set the embedded flash state in wait mode\r
+ *\r
+ * \param ul_flash_state PMC_WAIT_MODE_FLASH_STANDBY flash in standby mode,\r
+ * PMC_WAIT_MODE_FLASH_DEEP_POWERDOWN flash in deep power down mode.\r
+ */\r
+void pmc_set_flash_in_wait_mode(uint32_t ul_flash_state)\r
+{\r
+ ul_flash_in_wait_mode = ul_flash_state;\r
+}\r
+\r
+/**\r
+ * \brief Enable Wait Mode. Enter condition: (WAITMODE bit = 1) + FLPM\r
+ *\r
+ * \note In this function, FLPM will retain, WAITMODE bit will be set,\r
+ * Generally, this function will be called by pmc_sleep() in order to\r
+ * complete all sequence entering wait mode.\r
+ * See \ref pmc_sleep() for entering different sleep modes.\r
+ */\r
+void pmc_enable_waitmode(void)\r
+{\r
+ uint32_t i;\r
+\r
+ /* Flash in wait mode */\r
+ i = PMC->PMC_FSMR;\r
+ i &= ~PMC_FSMR_FLPM_Msk;\r
+#if !(SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+ i |= ul_flash_in_wait_mode;\r
+#else\r
+ i |= PMC_WAIT_MODE_FLASH_IDLE;\r
+#endif\r
+ PMC->PMC_FSMR = i;\r
+\r
+ /* Set the WAITMODE bit = 1 */\r
+ PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_WAITMODE;\r
+\r
+ /* Waiting for Master Clock Ready MCKRDY = 1 */\r
+ while (!(PMC->PMC_SR & PMC_SR_MCKRDY));\r
+\r
+ /* Waiting for MOSCRCEN bit cleared is strongly recommended\r
+ * to ensure that the core will not execute undesired instructions\r
+ */\r
+ for (i = 0; i < 500; i++) {\r
+ __NOP();\r
+ }\r
+ while (!(PMC->CKGR_MOR & CKGR_MOR_MOSCRCEN));\r
+\r
+#if (!SAMG)\r
+ /* Restore Flash in idle mode */\r
+ i = PMC->PMC_FSMR;\r
+ i &= ~PMC_FSMR_FLPM_Msk;\r
+ i |= PMC_WAIT_MODE_FLASH_IDLE;\r
+ PMC->PMC_FSMR = i;\r
+#endif\r
+}\r
+#else\r
+/**\r
+ * \brief Enable Wait Mode. Enter condition: WFE + (SLEEPDEEP bit = 0) +\r
+ * (LPM bit = 1)\r
+ */\r
+void pmc_enable_waitmode(void)\r
+{\r
+ uint32_t i;\r
+\r
+ PMC->PMC_FSMR |= PMC_FSMR_LPM; /* Enter Wait mode */\r
+ SCB->SCR &= (uint32_t) ~ SCB_SCR_SLEEPDEEP_Msk; /* Deep sleep */\r
+\r
+ __WFE();\r
+\r
+ /* Waiting for MOSCRCEN bit cleared is strongly recommended\r
+ * to ensure that the core will not execute undesired instructions\r
+ */\r
+ for (i = 0; i < 500; i++) {\r
+ __NOP();\r
+ }\r
+ while (!(PMC->CKGR_MOR & CKGR_MOR_MOSCRCEN));\r
+\r
+}\r
+#endif\r
+\r
+#if (!(SAMG51 || SAMG53 || SAMG54))\r
+/**\r
+ * \brief Enable Backup Mode. Enter condition: WFE/(VROFF bit = 1) +\r
+ * (SLEEPDEEP bit = 1)\r
+ */\r
+void pmc_enable_backupmode(void)\r
+{\r
+#if (SAM4C || SAM4CM || SAM4CP)\r
+ uint32_t tmp = SUPC->SUPC_MR & ~(SUPC_MR_BUPPOREN | SUPC_MR_KEY_Msk);\r
+ SUPC->SUPC_MR = tmp | SUPC_MR_KEY_PASSWD;\r
+ while (SUPC->SUPC_SR & SUPC_SR_BUPPORS);\r
+#endif\r
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;\r
+#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+ SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_VROFF_STOP_VREG;\r
+ __WFE();\r
+ __WFI();\r
+#else\r
+ __WFE();\r
+#endif\r
+}\r
+#endif\r
+\r
+/**\r
+ * \brief Enable Clock Failure Detector.\r
+ */\r
+void pmc_enable_clock_failure_detector(void)\r
+{\r
+ uint32_t ul_reg = PMC->CKGR_MOR;\r
+\r
+ PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_CFDEN | ul_reg;\r
+}\r
+\r
+/**\r
+ * \brief Disable Clock Failure Detector.\r
+ */\r
+void pmc_disable_clock_failure_detector(void)\r
+{\r
+ uint32_t ul_reg = PMC->CKGR_MOR & (~CKGR_MOR_CFDEN);\r
+\r
+ PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | ul_reg;\r
+}\r
+\r
+#if (SAM4N || SAM4C || SAM4CM || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+/**\r
+ * \brief Enable Slow Crystal Oscillator Frequency Monitoring.\r
+ */\r
+void pmc_enable_sclk_osc_freq_monitor(void)\r
+{\r
+ uint32_t ul_reg = PMC->CKGR_MOR;\r
+\r
+ PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_XT32KFME | ul_reg;\r
+}\r
+\r
+/**\r
+ * \brief Disable Slow Crystal Oscillator Frequency Monitoring.\r
+ */\r
+void pmc_disable_sclk_osc_freq_monitor(void)\r
+{\r
+ uint32_t ul_reg = PMC->CKGR_MOR & (~CKGR_MOR_XT32KFME);\r
+\r
+ PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | ul_reg;\r
+}\r
+#endif\r
+\r
+/**\r
+ * \brief Enable or disable write protect of PMC registers.\r
+ *\r
+ * \param ul_enable 1 to enable, 0 to disable.\r
+ */\r
+void pmc_set_writeprotect(uint32_t ul_enable)\r
+{\r
+ if (ul_enable) {\r
+ PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;\r
+ } else {\r
+ PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;\r
+ }\r
+}\r
+\r
+/**\r
+ * \brief Return write protect status.\r
+ *\r
+ * \return Return write protect status.\r
+ */\r
+uint32_t pmc_get_writeprotect_status(void)\r
+{\r
+ return PMC->PMC_WPSR;\r
+}\r
+\r
+#if (SAMG53 || SAMG54 || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+/**\r
+ * \brief Enable the specified peripheral clock.\r
+ *\r
+ * \note The ID must NOT be shifted (i.e., 1 << ID_xxx).\r
+ *\r
+ * \param ul_id Peripheral ID (ID_xxx).\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Fail.\r
+ */\r
+uint32_t pmc_enable_sleepwalking(uint32_t ul_id)\r
+{\r
+ uint32_t temp;\r
+#if (SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+ if ((7 <= ul_id) && (ul_id<= 29)) {\r
+#else\r
+ if ((8 <= ul_id) && (ul_id<= 29)) {\r
+#endif\r
+ temp = pmc_get_active_status0();\r
+ if (temp & (1 << ul_id)) {\r
+ return 1;\r
+ }\r
+ PMC->PMC_SLPWK_ER0 = 1 << ul_id;\r
+ temp = pmc_get_active_status0();\r
+ if (temp & (1 << ul_id)) {\r
+ pmc_disable_sleepwalking(ul_id);\r
+ return 1;\r
+ }\r
+ return 0;\r
+ }\r
+#if (SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+ else if ((32 <= ul_id) && (ul_id<= 60)) {\r
+ ul_id -= 32;\r
+ temp = pmc_get_active_status1();\r
+ if (temp & (1 << ul_id)) {\r
+ return 1;\r
+ }\r
+ PMC->PMC_SLPWK_ER1 = 1 << ul_id;\r
+ temp = pmc_get_active_status1();\r
+ if (temp & (1 << ul_id)) {\r
+ pmc_disable_sleepwalking(ul_id);\r
+ return 1;\r
+ }\r
+ return 0;\r
+ }\r
+#endif\r
+ else {\r
+ return 1;\r
+ }\r
+}\r
+\r
+/**\r
+ * \brief Disable the sleepwalking of specified peripheral.\r
+ *\r
+ * \note The ID must NOT be shifted (i.e., 1 << ID_xxx).\r
+ *\r
+ * \param ul_id Peripheral ID (ID_xxx).\r
+ *\r
+ * \retval 0 Success.\r
+ * \retval 1 Invalid parameter.\r
+ */\r
+uint32_t pmc_disable_sleepwalking(uint32_t ul_id)\r
+{\r
+#if (SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+ if ((7 <= ul_id) && (ul_id<= 29)) {\r
+#else\r
+ if ((8 <= ul_id) && (ul_id<= 29)) {\r
+#endif\r
+ PMC->PMC_SLPWK_DR0 = 1 << ul_id;\r
+ return 0;\r
+ }\r
+#if (SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+ else if ((32 <= ul_id) && (ul_id<= 60)) {\r
+ ul_id -= 32;\r
+ PMC->PMC_SLPWK_DR1 = 1 << ul_id;\r
+ return 0;\r
+ }\r
+#endif\r
+ else {\r
+ return 1;\r
+ }\r
+}\r
+\r
+/**\r
+ * \brief Return peripheral sleepwalking enable status.\r
+ *\r
+ * \return the status register value.\r
+ */\r
+uint32_t pmc_get_sleepwalking_status0(void)\r
+{\r
+ return PMC->PMC_SLPWK_SR0;\r
+}\r
+\r
+/**\r
+ * \brief Return peripheral active status.\r
+ *\r
+ * \return the status register value.\r
+ */\r
+uint32_t pmc_get_active_status0(void)\r
+{\r
+ return PMC->PMC_SLPWK_ASR0;\r
+}\r
+\r
+#endif\r
+\r
+#if (SAMV71 || SAMV70 || SAME70 || SAMS70)\r
+/**\r
+ * \brief Return peripheral sleepwalking enable status.\r
+ *\r
+ * \return the status register value.\r
+ */\r
+uint32_t pmc_get_sleepwalking_status1(void)\r
+{\r
+ return PMC->PMC_SLPWK_SR1;\r
+}\r
+\r
+/**\r
+ * \brief Return peripheral active status.\r
+ *\r
+ * \return the status register value.\r
+ */\r
+uint32_t pmc_get_active_status1(void)\r
+{\r
+ return PMC->PMC_SLPWK_ASR1;\r
+}\r
+#endif\r
+\r
+/// @cond 0\r
+/**INDENT-OFF**/\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+/**INDENT-ON**/\r
+/// @endcond\r