]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/CORTEX_M7_SAME70_Xplained_AtmelStudio/src/ASF/sam/drivers/pmc/pmc.c
Rename DummyTCB_t to StaticTCB_t.
[freertos] / FreeRTOS / Demo / CORTEX_M7_SAME70_Xplained_AtmelStudio / src / ASF / sam / drivers / pmc / pmc.c
diff --git a/FreeRTOS/Demo/CORTEX_M7_SAME70_Xplained_AtmelStudio/src/ASF/sam/drivers/pmc/pmc.c b/FreeRTOS/Demo/CORTEX_M7_SAME70_Xplained_AtmelStudio/src/ASF/sam/drivers/pmc/pmc.c
new file mode 100644 (file)
index 0000000..0b500d7
--- /dev/null
@@ -0,0 +1,1651 @@
+/**\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