1 /** 2 * \file 3 * 4 * \brief Power Management Controller (PMC) driver for SAM. 5 * 6 * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. 7 * 8 * \asf_license_start 9 * 10 * \page License 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions are met: 14 * 15 * 1. Redistributions of source code must retain the above copyright notice, 16 * this list of conditions and the following disclaimer. 17 * 18 * 2. Redistributions in binary form must reproduce the above copyright notice, 19 * this list of conditions and the following disclaimer in the documentation 20 * and/or other materials provided with the distribution. 21 * 22 * 3. The name of Atmel may not be used to endorse or promote products derived 23 * from this software without specific prior written permission. 24 * 25 * 4. This software may only be redistributed and used in connection with an 26 * Atmel microcontroller product. 27 * 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 * 40 * \asf_license_stop 41 * 42 */ 43 /* 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> 45 */ 46 47 #include "pmc.h" 48 49 #if (SAM3N) 50 # define MAX_PERIPH_ID 31 51 #elif (SAM3XA) 52 # define MAX_PERIPH_ID 44 53 #elif (SAM3U) 54 # define MAX_PERIPH_ID 29 55 #elif (SAM3S || SAM4S) 56 # define MAX_PERIPH_ID 34 57 #elif (SAM4E) 58 # define MAX_PERIPH_ID 47 59 #elif (SAMV71) 60 # define MAX_PERIPH_ID 63 61 #elif (SAMV70) 62 # define MAX_PERIPH_ID 63 63 #elif (SAME70) 64 # define MAX_PERIPH_ID 63 65 #elif (SAMS70) 66 # define MAX_PERIPH_ID 63 67 #elif (SAM4N) 68 # define MAX_PERIPH_ID 31 69 #elif (SAM4C || SAM4CM || SAM4CP) 70 # define MAX_PERIPH_ID 43 71 #elif (SAMG51) 72 # define MAX_PERIPH_ID 47 73 #elif (SAMG53) 74 # define MAX_PERIPH_ID 47 75 #elif (SAMG54) 76 # define MAX_PERIPH_ID 47 77 #elif (SAMG55) 78 # define MAX_PERIPH_ID 50 79 #endif 80 81 /// @cond 0 82 /**INDENT-OFF**/ 83 #ifdef __cplusplus 84 extern "C" { 85 #endif 86 /**INDENT-ON**/ 87 /// @endcond 88 89 /** 90 * \defgroup sam_drivers_pmc_group Power Management Controller (PMC) 91 * 92 * \par Purpose 93 * 94 * The Power Management Controller (PMC) optimizes power consumption by 95 * controlling all system and user peripheral clocks. The PMC enables/disables 96 * the clock inputs to many of the peripherals and the Cortex-M Processor. 97 * 98 * @{ 99 */ 100 101 /** 102 * \brief Set the prescaler of the MCK. 103 * 104 * \param ul_pres Prescaler value. 105 */ 106 void pmc_mck_set_prescaler(uint32_t ul_pres) 107 { 108 PMC->PMC_MCKR = 109 (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; 110 while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); 111 } 112 113 #if SAMV71 || SAMV70 || SAME70 || SAMS70 114 /** 115 * \brief Set the division of the MCK. 116 * 117 * \param ul_div Division value. 118 */ 119 void pmc_mck_set_division(uint32_t ul_div) 120 { 121 switch (ul_div) { 122 case 1: 123 ul_div = PMC_MCKR_MDIV_EQ_PCK; 124 break; 125 case 2: 126 ul_div = PMC_MCKR_MDIV_PCK_DIV2; 127 break; 128 case 3: 129 ul_div = PMC_MCKR_MDIV_PCK_DIV3; 130 break; 131 case 4: 132 ul_div = PMC_MCKR_MDIV_PCK_DIV4; 133 break; 134 default: 135 ul_div = PMC_MCKR_MDIV_EQ_PCK; 136 break; 137 } 138 PMC->PMC_MCKR = 139 (PMC->PMC_MCKR & (~PMC_MCKR_MDIV_Msk)) | ul_div; 140 while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); 141 } 142 #endif 143 144 /** 145 * \brief Set the source of the MCK. 146 * 147 * \param ul_source Source selection value. 148 */ 149 void pmc_mck_set_source(uint32_t ul_source) 150 { 151 PMC->PMC_MCKR = 152 (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | ul_source; 153 while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); 154 } 155 156 /** 157 * \brief Switch master clock source selection to slow clock. 158 * 159 * \param ul_pres Processor clock prescaler. 160 * 161 * \retval 0 Success. 162 * \retval 1 Timeout error. 163 */ 164 uint32_t pmc_switch_mck_to_sclk(uint32_t ul_pres) 165 { 166 uint32_t ul_timeout; 167 168 PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | 169 PMC_MCKR_CSS_SLOW_CLK; 170 for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); 171 --ul_timeout) { 172 if (ul_timeout == 0) { 173 return 1; 174 } 175 } 176 177 PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; 178 for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); 179 --ul_timeout) { 180 if (ul_timeout == 0) { 181 return 1; 182 } 183 } 184 185 return 0; 186 } 187 188 /** 189 * \brief Switch master clock source selection to main clock. 190 * 191 * \param ul_pres Processor clock prescaler. 192 * 193 * \retval 0 Success. 194 * \retval 1 Timeout error. 195 */ 196 uint32_t pmc_switch_mck_to_mainck(uint32_t ul_pres) 197 { 198 uint32_t ul_timeout; 199 200 PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | 201 PMC_MCKR_CSS_MAIN_CLK; 202 for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); 203 --ul_timeout) { 204 if (ul_timeout == 0) { 205 return 1; 206 } 207 } 208 209 PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; 210 for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); 211 --ul_timeout) { 212 if (ul_timeout == 0) { 213 return 1; 214 } 215 } 216 217 return 0; 218 } 219 220 /** 221 * \brief Switch master clock source selection to PLLA clock. 222 * 223 * \param ul_pres Processor clock prescaler. 224 * 225 * \retval 0 Success. 226 * \retval 1 Timeout error. 227 */ 228 uint32_t pmc_switch_mck_to_pllack(uint32_t ul_pres) 229 { 230 uint32_t ul_timeout; 231 232 PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; 233 for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); 234 --ul_timeout) { 235 if (ul_timeout == 0) { 236 return 1; 237 } 238 } 239 240 PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | 241 PMC_MCKR_CSS_PLLA_CLK; 242 243 for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); 244 --ul_timeout) { 245 if (ul_timeout == 0) { 246 return 1; 247 } 248 } 249 250 return 0; 251 } 252 253 #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55) 254 /** 255 * \brief Switch master clock source selection to PLLB clock. 256 * 257 * \param ul_pres Processor clock prescaler. 258 * 259 * \retval 0 Success. 260 * \retval 1 Timeout error. 261 */ 262 uint32_t pmc_switch_mck_to_pllbck(uint32_t ul_pres) 263 { 264 uint32_t ul_timeout; 265 266 PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; 267 for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); 268 --ul_timeout) { 269 if (ul_timeout == 0) { 270 return 1; 271 } 272 } 273 274 PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | 275 PMC_MCKR_CSS_PLLB_CLK; 276 for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); 277 --ul_timeout) { 278 if (ul_timeout == 0) { 279 return 1; 280 } 281 } 282 283 return 0; 284 } 285 #endif 286 287 #if (SAM3XA || SAM3U || SAMV71 || SAMV70 || SAME70 || SAMS70) 288 /** 289 * \brief Switch master clock source selection to UPLL clock. 290 * 291 * \param ul_pres Processor clock prescaler. 292 * 293 * \retval 0 Success. 294 * \retval 1 Timeout error. 295 */ 296 uint32_t pmc_switch_mck_to_upllck(uint32_t ul_pres) 297 { 298 uint32_t ul_timeout; 299 300 PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; 301 for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); 302 --ul_timeout) { 303 if (ul_timeout == 0) { 304 return 1; 305 } 306 } 307 308 PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | 309 PMC_MCKR_CSS_UPLL_CLK; 310 for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); 311 --ul_timeout) { 312 if (ul_timeout == 0) { 313 return 1; 314 } 315 } 316 317 return 0; 318 } 319 #endif 320 321 /** 322 * \brief Switch slow clock source selection to external 32k (Xtal or Bypass). 323 * 324 * \note Switching SCLK back to 32krc is only possible by shutting down the 325 * VDDIO power supply. 326 * 327 * \param ul_bypass 0 for Xtal, 1 for bypass. 328 */ 329 void pmc_switch_sclk_to_32kxtal(uint32_t ul_bypass) 330 { 331 /* Set Bypass mode if required */ 332 if (ul_bypass == 1) { 333 SUPC->SUPC_MR |= SUPC_MR_KEY_PASSWD | 334 SUPC_MR_OSCBYPASS; 335 } 336 337 SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL; 338 } 339 340 /** 341 * \brief Check if the external 32k Xtal is ready. 342 * 343 * \retval 1 External 32k Xtal is ready. 344 * \retval 0 External 32k Xtal is not ready. 345 */ 346 uint32_t pmc_osc_is_ready_32kxtal(void) 347 { 348 return ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) 349 && (PMC->PMC_SR & PMC_SR_OSCSELS)); 350 } 351 352 /** 353 * \brief Switch main clock source selection to internal fast RC. 354 * 355 * \param ul_moscrcf Fast RC oscillator(4/8/12Mhz). 356 * 357 * \retval 0 Success. 358 * \retval 1 Timeout error. 359 * \retval 2 Invalid frequency. 360 */ 361 void pmc_switch_mainck_to_fastrc(uint32_t ul_moscrcf) 362 { 363 /* Enable Fast RC oscillator but DO NOT switch to RC now */ 364 PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN); 365 366 /* Wait the Fast RC to stabilize */ 367 while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); 368 369 /* Change Fast RC oscillator frequency */ 370 PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) | 371 CKGR_MOR_KEY_PASSWD | ul_moscrcf; 372 373 /* Wait the Fast RC to stabilize */ 374 while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); 375 376 /* Switch to Fast RC */ 377 PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) | 378 CKGR_MOR_KEY_PASSWD; 379 } 380 381 /** 382 * \brief Enable fast RC oscillator. 383 * 384 * \param ul_rc Fast RC oscillator(4/8/12Mhz). 385 */ 386 void pmc_osc_enable_fastrc(uint32_t ul_rc) 387 { 388 /* Enable Fast RC oscillator but DO NOT switch to RC */ 389 PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN); 390 /* Wait the Fast RC to stabilize */ 391 while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); 392 393 /* Change Fast RC oscillator frequency */ 394 PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) | 395 CKGR_MOR_KEY_PASSWD | ul_rc; 396 /* Wait the Fast RC to stabilize */ 397 while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); 398 } 399 400 /** 401 * \brief Disable the internal fast RC. 402 */ 403 void pmc_osc_disable_fastrc(void) 404 { 405 /* Disable Fast RC oscillator */ 406 PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCEN & 407 ~CKGR_MOR_MOSCRCF_Msk) 408 | CKGR_MOR_KEY_PASSWD; 409 } 410 411 /** 412 * \brief Check if the main fastrc is ready. 413 * 414 * \retval 0 Xtal is not ready, otherwise ready. 415 */ 416 uint32_t pmc_osc_is_ready_fastrc(void) 417 { 418 return (PMC->PMC_SR & PMC_SR_MOSCRCS); 419 } 420 421 /** 422 * \brief Enable main XTAL oscillator. 423 * 424 * \param ul_xtal_startup_time Xtal start-up time, in number of slow clocks. 425 */ 426 void pmc_osc_enable_main_xtal(uint32_t ul_xtal_startup_time) 427 { 428 uint32_t mor = PMC->CKGR_MOR; 429 mor &= ~(CKGR_MOR_MOSCXTBY|CKGR_MOR_MOSCXTEN); 430 mor |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN | 431 CKGR_MOR_MOSCXTST(ul_xtal_startup_time); 432 PMC->CKGR_MOR = mor; 433 /* Wait the main Xtal to stabilize */ 434 while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)); 435 } 436 437 /** 438 * \brief Bypass main XTAL. 439 */ 440 void pmc_osc_bypass_main_xtal(void) 441 { 442 uint32_t mor = PMC->CKGR_MOR; 443 mor &= ~(CKGR_MOR_MOSCXTBY|CKGR_MOR_MOSCXTEN); 444 mor |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTBY; 445 /* Enable Crystal oscillator but DO NOT switch now. Keep MOSCSEL to 0 */ 446 PMC->CKGR_MOR = mor; 447 /* The MOSCXTS in PMC_SR is automatically set */ 448 } 449 450 /** 451 * \brief Disable the main Xtal. 452 */ 453 void pmc_osc_disable_main_xtal(void) 454 { 455 uint32_t mor = PMC->CKGR_MOR; 456 mor &= ~(CKGR_MOR_MOSCXTBY|CKGR_MOR_MOSCXTEN); 457 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | mor; 458 } 459 460 /** 461 * \brief Check if the main crystal is bypassed. 462 * 463 * \retval 0 Xtal is bypassed, otherwise not. 464 */ 465 uint32_t pmc_osc_is_bypassed_main_xtal(void) 466 { 467 return (PMC->CKGR_MOR & CKGR_MOR_MOSCXTBY); 468 } 469 470 /** 471 * \brief Check if the main crystal is ready. 472 * 473 * \note If main crystal is bypassed, it's always ready. 474 * 475 * \retval 0 main crystal is not ready, otherwise ready. 476 */ 477 uint32_t pmc_osc_is_ready_main_xtal(void) 478 { 479 return (PMC->PMC_SR & PMC_SR_MOSCXTS); 480 } 481 482 /** 483 * \brief Switch main clock source selection to external Xtal/Bypass. 484 * 485 * \note The function may switch MCK to SCLK if MCK source is MAINCK to avoid 486 * any system crash. 487 * 488 * \note If used in Xtal mode, the Xtal is automatically enabled. 489 * 490 * \param ul_bypass 0 for Xtal, 1 for bypass. 491 * 492 * \retval 0 Success. 493 * \retval 1 Timeout error. 494 */ 495 void pmc_switch_mainck_to_xtal(uint32_t ul_bypass, 496 uint32_t ul_xtal_startup_time) 497 { 498 /* Enable Main Xtal oscillator */ 499 if (ul_bypass) { 500 PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | 501 CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTBY | 502 CKGR_MOR_MOSCSEL; 503 } else { 504 PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) | 505 CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN | 506 CKGR_MOR_MOSCXTST(ul_xtal_startup_time); 507 /* Wait the Xtal to stabilize */ 508 while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)); 509 510 PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCSEL; 511 } 512 } 513 514 /** 515 * \brief Disable the external Xtal. 516 * 517 * \param ul_bypass 0 for Xtal, 1 for bypass. 518 */ 519 void pmc_osc_disable_xtal(uint32_t ul_bypass) 520 { 521 /* Disable xtal oscillator */ 522 if (ul_bypass) { 523 PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) | 524 CKGR_MOR_KEY_PASSWD; 525 } else { 526 PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | 527 CKGR_MOR_KEY_PASSWD; 528 } 529 } 530 531 /** 532 * \brief Check if the MAINCK is ready. Depending on MOSCEL, MAINCK can be one 533 * of Xtal, bypass or internal RC. 534 * 535 * \retval 1 Xtal is ready. 536 * \retval 0 Xtal is not ready. 537 */ 538 uint32_t pmc_osc_is_ready_mainck(void) 539 { 540 return PMC->PMC_SR & PMC_SR_MOSCSELS; 541 } 542 543 /** 544 * \brief Select Main Crystal or internal RC as main clock source. 545 * 546 * \note This function will not enable/disable RC or Main Crystal. 547 * 548 * \param ul_xtal_rc 0 internal RC is selected, otherwise Main Crystal. 549 */ 550 void pmc_mainck_osc_select(uint32_t ul_xtal_rc) 551 { 552 uint32_t mor = PMC->CKGR_MOR; 553 if (ul_xtal_rc) { 554 mor |= CKGR_MOR_MOSCSEL; 555 } else { 556 mor &= ~CKGR_MOR_MOSCSEL; 557 } 558 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | mor; 559 } 560 561 /** 562 * \brief Enable PLLA clock. 563 * 564 * \param mula PLLA multiplier. 565 * \param pllacount PLLA counter. 566 * \param diva Divider. 567 */ 568 void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva) 569 { 570 /* first disable the PLL to unlock the lock */ 571 pmc_disable_pllack(); 572 573 #if (SAM4C || SAM4CM || SAM4CP || SAMG) 574 PMC->CKGR_PLLAR = CKGR_PLLAR_PLLAEN(diva) | 575 CKGR_PLLAR_PLLACOUNT(pllacount) | CKGR_PLLAR_MULA(mula); 576 #else 577 PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_DIVA(diva) | 578 CKGR_PLLAR_PLLACOUNT(pllacount) | CKGR_PLLAR_MULA(mula); 579 #endif 580 while ((PMC->PMC_SR & PMC_SR_LOCKA) == 0); 581 } 582 583 /** 584 * \brief Disable PLLA clock. 585 */ 586 void pmc_disable_pllack(void) 587 { 588 #if (SAM4C || SAM4CM || SAM4CP || SAMG) 589 PMC->CKGR_PLLAR = CKGR_PLLAR_MULA(0); 590 #else 591 PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0); 592 #endif 593 } 594 595 /** 596 * \brief Is PLLA locked? 597 * 598 * \retval 0 Not locked. 599 * \retval 1 Locked. 600 */ 601 uint32_t pmc_is_locked_pllack(void) 602 { 603 return (PMC->PMC_SR & PMC_SR_LOCKA); 604 } 605 606 #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55) 607 /** 608 * \brief Enable PLLB clock. 609 * 610 * \param mulb PLLB multiplier. 611 * \param pllbcount PLLB counter. 612 * \param divb Divider. 613 */ 614 void pmc_enable_pllbck(uint32_t mulb, uint32_t pllbcount, uint32_t divb) 615 { 616 /* first disable the PLL to unlock the lock */ 617 pmc_disable_pllbck(); 618 619 #if SAMG55 620 PMC->CKGR_PLLAR = CKGR_PLLAR_PLLAEN(divb) | 621 CKGR_PLLAR_PLLACOUNT(pllbcount) | CKGR_PLLAR_MULA(mulb); 622 #else 623 PMC->CKGR_PLLBR = 624 CKGR_PLLBR_DIVB(divb) | CKGR_PLLBR_PLLBCOUNT(pllbcount) 625 | CKGR_PLLBR_MULB(mulb); 626 #endif 627 while ((PMC->PMC_SR & PMC_SR_LOCKB) == 0); 628 } 629 630 /** 631 * \brief Disable PLLB clock. 632 */ 633 void pmc_disable_pllbck(void) 634 { 635 PMC->CKGR_PLLBR = CKGR_PLLBR_MULB(0); 636 } 637 638 /** 639 * \brief Is PLLB locked? 640 * 641 * \retval 0 Not locked. 642 * \retval 1 Locked. 643 */ 644 uint32_t pmc_is_locked_pllbck(void) 645 { 646 return (PMC->PMC_SR & PMC_SR_LOCKB); 647 } 648 #endif 649 650 #if (SAM3XA || SAM3U || SAMV71 || SAMV70 || SAME70 || SAMS70) 651 /** 652 * \brief Enable UPLL clock. 653 */ 654 void pmc_enable_upll_clock(void) 655 { 656 PMC->CKGR_UCKR = CKGR_UCKR_UPLLCOUNT(3) | CKGR_UCKR_UPLLEN; 657 658 /* Wait UTMI PLL Lock Status */ 659 while (!(PMC->PMC_SR & PMC_SR_LOCKU)); 660 } 661 662 /** 663 * \brief Disable UPLL clock. 664 */ 665 void pmc_disable_upll_clock(void) 666 { 667 PMC->CKGR_UCKR &= ~CKGR_UCKR_UPLLEN; 668 } 669 670 /** 671 * \brief Is UPLL locked? 672 * 673 * \retval 0 Not locked. 674 * \retval 1 Locked. 675 */ 676 uint32_t pmc_is_locked_upll(void) 677 { 678 return (PMC->PMC_SR & PMC_SR_LOCKU); 679 } 680 #endif 681 682 /** 683 * \brief Enable the specified peripheral clock. 684 * 685 * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). 686 * 687 * \param ul_id Peripheral ID (ID_xxx). 688 * 689 * \retval 0 Success. 690 * \retval 1 Invalid parameter. 691 */ 692 uint32_t pmc_enable_periph_clk(uint32_t ul_id) 693 { 694 if (ul_id > MAX_PERIPH_ID) { 695 return 1; 696 } 697 698 if (ul_id < 32) { 699 if ((PMC->PMC_PCSR0 & (1u << ul_id)) != (1u << ul_id)) { 700 PMC->PMC_PCER0 = 1 << ul_id; 701 } 702 #if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70) 703 } else { 704 ul_id -= 32; 705 if ((PMC->PMC_PCSR1 & (1u << ul_id)) != (1u << ul_id)) { 706 PMC->PMC_PCER1 = 1 << ul_id; 707 } 708 #endif 709 } 710 711 return 0; 712 } 713 714 /** 715 * \brief Disable the specified peripheral clock. 716 * 717 * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). 718 * 719 * \param ul_id Peripheral ID (ID_xxx). 720 * 721 * \retval 0 Success. 722 * \retval 1 Invalid parameter. 723 */ 724 uint32_t pmc_disable_periph_clk(uint32_t ul_id) 725 { 726 if (ul_id > MAX_PERIPH_ID) { 727 return 1; 728 } 729 730 if (ul_id < 32) { 731 if ((PMC->PMC_PCSR0 & (1u << ul_id)) == (1u << ul_id)) { 732 PMC->PMC_PCDR0 = 1 << ul_id; 733 } 734 #if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 \ 735 || SAMV70 || SAME70 || SAMS70) 736 } else { 737 ul_id -= 32; 738 if ((PMC->PMC_PCSR1 & (1u << ul_id)) == (1u << ul_id)) { 739 PMC->PMC_PCDR1 = 1 << ul_id; 740 } 741 #endif 742 } 743 return 0; 744 } 745 746 /** 747 * \brief Enable all peripheral clocks. 748 */ 749 void pmc_enable_all_periph_clk(void) 750 { 751 PMC->PMC_PCER0 = PMC_MASK_STATUS0; 752 while ((PMC->PMC_PCSR0 & PMC_MASK_STATUS0) != PMC_MASK_STATUS0); 753 754 #if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMV71 \ 755 || SAMV70 || SAME70 || SAMS70) 756 PMC->PMC_PCER1 = PMC_MASK_STATUS1; 757 while ((PMC->PMC_PCSR1 & PMC_MASK_STATUS1) != PMC_MASK_STATUS1); 758 #endif 759 } 760 761 /** 762 * \brief Disable all peripheral clocks. 763 */ 764 void pmc_disable_all_periph_clk(void) 765 { 766 PMC->PMC_PCDR0 = PMC_MASK_STATUS0; 767 while ((PMC->PMC_PCSR0 & PMC_MASK_STATUS0) != 0); 768 769 #if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMV71 \ 770 || SAMV70 || SAME70 || SAMS70) 771 PMC->PMC_PCDR1 = PMC_MASK_STATUS1; 772 while ((PMC->PMC_PCSR1 & PMC_MASK_STATUS1) != 0); 773 #endif 774 } 775 776 /** 777 * \brief Check if the specified peripheral clock is enabled. 778 * 779 * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). 780 * 781 * \param ul_id Peripheral ID (ID_xxx). 782 * 783 * \retval 0 Peripheral clock is disabled or unknown. 784 * \retval 1 Peripheral clock is enabled. 785 */ 786 uint32_t pmc_is_periph_clk_enabled(uint32_t ul_id) 787 { 788 if (ul_id > MAX_PERIPH_ID) { 789 return 0; 790 } 791 792 #if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMV71 \ 793 || SAMV70 || SAME70 || SAMS70) 794 if (ul_id < 32) { 795 #endif 796 if ((PMC->PMC_PCSR0 & (1u << ul_id))) { 797 return 1; 798 } else { 799 return 0; 800 } 801 #if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMV71 \ 802 || SAMV70 || SAME70 || SAMS70) 803 } else { 804 ul_id -= 32; 805 if ((PMC->PMC_PCSR1 & (1u << ul_id))) { 806 return 1; 807 } else { 808 return 0; 809 } 810 } 811 #endif 812 } 813 814 /** 815 * \brief Set the prescaler for the specified programmable clock. 816 * 817 * \param ul_id Peripheral ID. 818 * \param ul_pres Prescaler value. 819 */ 820 void pmc_pck_set_prescaler(uint32_t ul_id, uint32_t ul_pres) 821 { 822 PMC->PMC_PCK[ul_id] = 823 (PMC->PMC_PCK[ul_id] & ~PMC_PCK_PRES_Msk) | ul_pres; 824 while ((PMC->PMC_SCER & (PMC_SCER_PCK0 << ul_id)) 825 && !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id))); 826 } 827 828 /** 829 * \brief Set the source oscillator for the specified programmable clock. 830 * 831 * \param ul_id Peripheral ID. 832 * \param ul_source Source selection value. 833 */ 834 void pmc_pck_set_source(uint32_t ul_id, uint32_t ul_source) 835 { 836 PMC->PMC_PCK[ul_id] = 837 (PMC->PMC_PCK[ul_id] & ~PMC_PCK_CSS_Msk) | ul_source; 838 while ((PMC->PMC_SCER & (PMC_SCER_PCK0 << ul_id)) 839 && !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id))); 840 } 841 842 /** 843 * \brief Switch programmable clock source selection to slow clock. 844 * 845 * \param ul_id Id of the programmable clock. 846 * \param ul_pres Programmable clock prescaler. 847 * 848 * \retval 0 Success. 849 * \retval 1 Timeout error. 850 */ 851 uint32_t pmc_switch_pck_to_sclk(uint32_t ul_id, uint32_t ul_pres) 852 { 853 uint32_t ul_timeout; 854 855 PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_SLOW_CLK | ul_pres; 856 for (ul_timeout = PMC_TIMEOUT; 857 !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) { 858 if (ul_timeout == 0) { 859 return 1; 860 } 861 } 862 863 return 0; 864 } 865 866 /** 867 * \brief Switch programmable clock source selection to main clock. 868 * 869 * \param ul_id Id of the programmable clock. 870 * \param ul_pres Programmable clock prescaler. 871 * 872 * \retval 0 Success. 873 * \retval 1 Timeout error. 874 */ 875 uint32_t pmc_switch_pck_to_mainck(uint32_t ul_id, uint32_t ul_pres) 876 { 877 uint32_t ul_timeout; 878 879 PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_MAIN_CLK | ul_pres; 880 for (ul_timeout = PMC_TIMEOUT; 881 !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) { 882 if (ul_timeout == 0) { 883 return 1; 884 } 885 } 886 887 return 0; 888 } 889 890 /** 891 * \brief Switch programmable clock source selection to PLLA clock. 892 * 893 * \param ul_id Id of the programmable clock. 894 * \param ul_pres Programmable clock prescaler. 895 * 896 * \retval 0 Success. 897 * \retval 1 Timeout error. 898 */ 899 uint32_t pmc_switch_pck_to_pllack(uint32_t ul_id, uint32_t ul_pres) 900 { 901 uint32_t ul_timeout; 902 903 PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_PLLA_CLK | ul_pres; 904 for (ul_timeout = PMC_TIMEOUT; 905 !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) { 906 if (ul_timeout == 0) { 907 return 1; 908 } 909 } 910 911 return 0; 912 } 913 914 #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55) 915 /** 916 * \brief Switch programmable clock source selection to PLLB clock. 917 * 918 * \param ul_id Id of the programmable clock. 919 * \param ul_pres Programmable clock prescaler. 920 * 921 * \retval 0 Success. 922 * \retval 1 Timeout error. 923 */ 924 uint32_t pmc_switch_pck_to_pllbck(uint32_t ul_id, uint32_t ul_pres) 925 { 926 uint32_t ul_timeout; 927 928 PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_PLLB_CLK | ul_pres; 929 for (ul_timeout = PMC_TIMEOUT; 930 !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); 931 --ul_timeout) { 932 if (ul_timeout == 0) { 933 return 1; 934 } 935 } 936 937 return 0; 938 } 939 #endif 940 941 #if (SAM3XA || SAM3U || SAMV71 || SAMV70 || SAME70 || SAMS70) 942 /** 943 * \brief Switch programmable clock source selection to UPLL clock. 944 * 945 * \param ul_id Id of the programmable clock. 946 * \param ul_pres Programmable clock prescaler. 947 * 948 * \retval 0 Success. 949 * \retval 1 Timeout error. 950 */ 951 uint32_t pmc_switch_pck_to_upllck(uint32_t ul_id, uint32_t ul_pres) 952 { 953 uint32_t ul_timeout; 954 955 PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_UPLL_CLK | ul_pres; 956 for (ul_timeout = PMC_TIMEOUT; 957 !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); 958 --ul_timeout) { 959 if (ul_timeout == 0) { 960 return 1; 961 } 962 } 963 964 return 0; 965 } 966 #endif 967 968 /** 969 * \brief Switch programmable clock source selection to mck. 970 * 971 * \param ul_id Id of the programmable clock. 972 * \param ul_pres Programmable clock prescaler. 973 * 974 * \retval 0 Success. 975 * \retval 1 Timeout error. 976 */ 977 uint32_t pmc_switch_pck_to_mck(uint32_t ul_id, uint32_t ul_pres) 978 { 979 uint32_t ul_timeout; 980 981 PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_MCK | ul_pres; 982 for (ul_timeout = PMC_TIMEOUT; 983 !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) { 984 if (ul_timeout == 0) { 985 return 1; 986 } 987 } 988 989 return 0; 990 } 991 992 /** 993 * \brief Enable the specified programmable clock. 994 * 995 * \param ul_id Id of the programmable clock. 996 */ 997 void pmc_enable_pck(uint32_t ul_id) 998 { 999 PMC->PMC_SCER = PMC_SCER_PCK0 << ul_id; 1000 } 1001 1002 /** 1003 * \brief Disable the specified programmable clock. 1004 * 1005 * \param ul_id Id of the programmable clock. 1006 */ 1007 void pmc_disable_pck(uint32_t ul_id) 1008 { 1009 PMC->PMC_SCDR = PMC_SCER_PCK0 << ul_id; 1010 } 1011 1012 /** 1013 * \brief Enable all programmable clocks. 1014 */ 1015 void pmc_enable_all_pck(void) 1016 { 1017 PMC->PMC_SCER = PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2; 1018 } 1019 1020 /** 1021 * \brief Disable all programmable clocks. 1022 */ 1023 void pmc_disable_all_pck(void) 1024 { 1025 PMC->PMC_SCDR = PMC_SCDR_PCK0 | PMC_SCDR_PCK1 | PMC_SCDR_PCK2; 1026 } 1027 1028 /** 1029 * \brief Check if the specified programmable clock is enabled. 1030 * 1031 * \param ul_id Id of the programmable clock. 1032 * 1033 * \retval 0 Programmable clock is disabled or unknown. 1034 * \retval 1 Programmable clock is enabled. 1035 */ 1036 uint32_t pmc_is_pck_enabled(uint32_t ul_id) 1037 { 1038 if (ul_id > 2) { 1039 return 0; 1040 } 1041 1042 return (PMC->PMC_SCSR & (PMC_SCSR_PCK0 << ul_id)); 1043 } 1044 1045 #if (SAM4C || SAM4CM || SAM4CP) 1046 /** 1047 * \brief Enable Coprocessor Clocks. 1048 */ 1049 void pmc_enable_cpck(void) 1050 { 1051 PMC->PMC_SCER = PMC_SCER_CPCK | PMC_SCER_CPKEY_PASSWD; 1052 } 1053 1054 /** 1055 * \brief Disable Coprocessor Clocks. 1056 */ 1057 void pmc_disable_cpck(void) 1058 { 1059 PMC->PMC_SCDR = PMC_SCDR_CPCK | PMC_SCDR_CPKEY_PASSWD; 1060 } 1061 1062 /** 1063 * \brief Check if the Coprocessor Clocks is enabled. 1064 * 1065 * \retval 0 Coprocessor Clocks is disabled. 1066 * \retval 1 Coprocessor Clocks is enabled. 1067 */ 1068 bool pmc_is_cpck_enabled(void) 1069 { 1070 if(PMC->PMC_SCSR & PMC_SCSR_CPCK) { 1071 return 1; 1072 } else { 1073 return 0; 1074 } 1075 } 1076 1077 /** 1078 * \brief Enable Coprocessor Bus Master Clocks. 1079 */ 1080 void pmc_enable_cpbmck(void) 1081 { 1082 PMC->PMC_SCER = PMC_SCER_CPCK | PMC_SCER_CPKEY_PASSWD; 1083 } 1084 1085 /** 1086 * \brief Disable Coprocessor Bus Master Clocks. 1087 */ 1088 void pmc_disable_cpbmck(void) 1089 { 1090 PMC->PMC_SCDR = PMC_SCDR_CPCK | PMC_SCDR_CPKEY_PASSWD; 1091 } 1092 1093 /** 1094 * \brief Check if the Coprocessor Bus Master Clocks is enabled. 1095 * 1096 * \retval 0 Coprocessor Bus Master Clocks is disabled. 1097 * \retval 1 Coprocessor Bus Master Clocks is enabled. 1098 */ 1099 bool pmc_is_cpbmck_enabled(void) 1100 { 1101 if(PMC->PMC_SCSR & PMC_SCSR_CPBMCK) { 1102 return 1; 1103 } else { 1104 return 0; 1105 } 1106 } 1107 1108 /** 1109 * \brief Set the prescaler for the Coprocessor Master Clock. 1110 * 1111 * \param ul_pres Prescaler value. 1112 */ 1113 void pmc_cpck_set_prescaler(uint32_t ul_pres) 1114 { 1115 PMC->PMC_MCKR = 1116 (PMC->PMC_MCKR & (~PMC_MCKR_CPPRES_Msk)) | PMC_MCKR_CPPRES(ul_pres); 1117 } 1118 1119 /** 1120 * \brief Set the source for the Coprocessor Master Clock. 1121 * 1122 * \param ul_source Source selection value. 1123 */ 1124 void pmc_cpck_set_source(uint32_t ul_source) 1125 { 1126 PMC->PMC_MCKR = 1127 (PMC->PMC_MCKR & (~PMC_MCKR_CPCSS_Msk)) | ul_source; 1128 } 1129 #endif 1130 1131 #if (SAM3S || SAM3XA || SAM4S || SAM4E || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70) 1132 /** 1133 * \brief Switch UDP (USB) clock source selection to PLLA clock. 1134 * 1135 * \param ul_usbdiv Clock divisor. 1136 */ 1137 void pmc_switch_udpck_to_pllack(uint32_t ul_usbdiv) 1138 { 1139 PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv); 1140 } 1141 #endif 1142 1143 #if (SAM3S || SAM4S || SAMG55) 1144 /** 1145 * \brief Switch UDP (USB) clock source selection to PLLB clock. 1146 * 1147 * \param ul_usbdiv Clock divisor. 1148 */ 1149 void pmc_switch_udpck_to_pllbck(uint32_t ul_usbdiv) 1150 { 1151 PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv) | PMC_USB_USBS; 1152 } 1153 #endif 1154 1155 #if (SAM3XA || SAMV71 || SAMV70 || SAME70 || SAMS70) 1156 /** 1157 * \brief Switch UDP (USB) clock source selection to UPLL clock. 1158 * 1159 * \param ul_usbdiv Clock divisor. 1160 */ 1161 void pmc_switch_udpck_to_upllck(uint32_t ul_usbdiv) 1162 { 1163 PMC->PMC_USB = PMC_USB_USBS | PMC_USB_USBDIV(ul_usbdiv); 1164 } 1165 #endif 1166 1167 #if (SAM3S || SAM3XA || SAM4S || SAM4E || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70) 1168 /** 1169 * \brief Enable UDP (USB) clock. 1170 */ 1171 void pmc_enable_udpck(void) 1172 { 1173 #if (SAM3S || SAM4S || SAM4E || SAMG55) 1174 PMC->PMC_SCER = PMC_SCER_UDP; 1175 #elif (SAMV71 || SAMV70 || SAME70 || SAMS70) 1176 PMC->PMC_SCER = PMC_SCER_USBCLK; 1177 #else 1178 PMC->PMC_SCER = PMC_SCER_UOTGCLK; 1179 # endif 1180 } 1181 1182 /** 1183 * \brief Disable UDP (USB) clock. 1184 */ 1185 void pmc_disable_udpck(void) 1186 { 1187 #if (SAM3S || SAM4S || SAM4E || SAMG55) 1188 PMC->PMC_SCDR = PMC_SCDR_UDP; 1189 #elif (SAMV71 || SAMV70 || SAME70 || SAMS70) 1190 PMC->PMC_SCDR = PMC_SCDR_USBCLK; 1191 #else 1192 PMC->PMC_SCDR = PMC_SCDR_UOTGCLK; 1193 # endif 1194 } 1195 #endif 1196 1197 #if SAMG55 1198 /** 1199 * \brief Switch UHP (USB) clock source selection to PLLA clock. 1200 * 1201 * \param ul_usbdiv Clock divisor. 1202 */ 1203 void pmc_switch_uhpck_to_pllack(uint32_t ul_usbdiv) 1204 { 1205 PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv); 1206 } 1207 1208 /** 1209 * \brief Switch UHP (USB) clock source selection to PLLB clock. 1210 * 1211 * \param ul_usbdiv Clock divisor. 1212 */ 1213 void pmc_switch_uhpck_to_pllbck(uint32_t ul_usbdiv) 1214 { 1215 PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv) | PMC_USB_USBS; 1216 } 1217 1218 /** 1219 * \brief Enable UHP (USB) clock. 1220 */ 1221 void pmc_enable_uhpck(void) 1222 { 1223 PMC->PMC_SCER = PMC_SCER_UHP; 1224 } 1225 #endif 1226 1227 /** 1228 * \brief Enable PMC interrupts. 1229 * 1230 * \param ul_sources Interrupt sources bit map. 1231 */ 1232 void pmc_enable_interrupt(uint32_t ul_sources) 1233 { 1234 PMC->PMC_IER = ul_sources; 1235 } 1236 1237 /** 1238 * \brief Disable PMC interrupts. 1239 * 1240 * \param ul_sources Interrupt sources bit map. 1241 */ 1242 void pmc_disable_interrupt(uint32_t ul_sources) 1243 { 1244 PMC->PMC_IDR = ul_sources; 1245 } 1246 1247 /** 1248 * \brief Get PMC interrupt mask. 1249 * 1250 * \return The interrupt mask value. 1251 */ 1252 uint32_t pmc_get_interrupt_mask(void) 1253 { 1254 return PMC->PMC_IMR; 1255 } 1256 1257 /** 1258 * \brief Get current status. 1259 * 1260 * \return The current PMC status. 1261 */ 1262 uint32_t pmc_get_status(void) 1263 { 1264 return PMC->PMC_SR; 1265 } 1266 1267 /** 1268 * \brief Set the wake-up inputs for fast startup mode registers 1269 * (event generation). 1270 * 1271 * \param ul_inputs Wake up inputs to enable. 1272 */ 1273 void pmc_set_fast_startup_input(uint32_t ul_inputs) 1274 { 1275 ul_inputs &= PMC_FAST_STARTUP_Msk; 1276 PMC->PMC_FSMR |= ul_inputs; 1277 } 1278 1279 /** 1280 * \brief Clear the wake-up inputs for fast startup mode registers 1281 * (remove event generation). 1282 * 1283 * \param ul_inputs Wake up inputs to disable. 1284 */ 1285 void pmc_clr_fast_startup_input(uint32_t ul_inputs) 1286 { 1287 ul_inputs &= PMC_FAST_STARTUP_Msk; 1288 PMC->PMC_FSMR &= ~ul_inputs; 1289 } 1290 1291 #if (SAM4C || SAM4CM || SAM4CP) 1292 /** 1293 * \brief Set the wake-up inputs of coprocessor for fast startup mode registers 1294 * (event generation). 1295 * 1296 * \param ul_inputs Wake up inputs to enable. 1297 */ 1298 void pmc_cp_set_fast_startup_input(uint32_t ul_inputs) 1299 { 1300 ul_inputs &= PMC_FAST_STARTUP_Msk; 1301 PMC->PMC_CPFSMR |= ul_inputs; 1302 } 1303 1304 /** 1305 * \brief Clear the wake-up inputs of coprocessor for fast startup mode registers 1306 * (remove event generation). 1307 * 1308 * \param ul_inputs Wake up inputs to disable. 1309 */ 1310 void pmc_cp_clr_fast_startup_input(uint32_t ul_inputs) 1311 { 1312 ul_inputs &= PMC_FAST_STARTUP_Msk; 1313 PMC->PMC_CPFSMR &= ~ul_inputs; 1314 } 1315 #endif 1316 1317 #if (!(SAMG51 || SAMG53 || SAMG54)) 1318 /** 1319 * \brief Enable Sleep Mode. 1320 * Enter condition: (WFE or WFI) + (SLEEPDEEP bit = 0) + (LPM bit = 0) 1321 * 1322 * \param uc_type 0 for wait for interrupt, 1 for wait for event. 1323 * \note For SAM4S, SAM4C, SAM4CM, SAM4CP, SAMV71 and SAM4E series, 1324 * since only WFI is effective, uc_type = 1 will be treated as uc_type = 0. 1325 */ 1326 void pmc_enable_sleepmode(uint8_t uc_type) 1327 { 1328 #if !(SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70) 1329 PMC->PMC_FSMR &= (uint32_t) ~ PMC_FSMR_LPM; // Enter Sleep mode 1330 #endif 1331 SCB->SCR &= (uint32_t) ~ SCB_SCR_SLEEPDEEP_Msk; // Deep sleep 1332 1333 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70) 1334 UNUSED(uc_type); 1335 __WFI(); 1336 #else 1337 if (uc_type == 0) { 1338 __WFI(); 1339 } else { 1340 __WFE(); 1341 } 1342 #endif 1343 } 1344 #endif 1345 1346 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70) 1347 static uint32_t ul_flash_in_wait_mode = PMC_WAIT_MODE_FLASH_DEEP_POWERDOWN; 1348 /** 1349 * \brief Set the embedded flash state in wait mode 1350 * 1351 * \param ul_flash_state PMC_WAIT_MODE_FLASH_STANDBY flash in standby mode, 1352 * PMC_WAIT_MODE_FLASH_DEEP_POWERDOWN flash in deep power down mode. 1353 */ 1354 void pmc_set_flash_in_wait_mode(uint32_t ul_flash_state) 1355 { 1356 ul_flash_in_wait_mode = ul_flash_state; 1357 } 1358 1359 /** 1360 * \brief Enable Wait Mode. Enter condition: (WAITMODE bit = 1) + FLPM 1361 * 1362 * \note In this function, FLPM will retain, WAITMODE bit will be set, 1363 * Generally, this function will be called by pmc_sleep() in order to 1364 * complete all sequence entering wait mode. 1365 * See \ref pmc_sleep() for entering different sleep modes. 1366 */ 1367 void pmc_enable_waitmode(void) 1368 { 1369 uint32_t i; 1370 1371 /* Flash in wait mode */ 1372 i = PMC->PMC_FSMR; 1373 i &= ~PMC_FSMR_FLPM_Msk; 1374 i |= ul_flash_in_wait_mode; 1375 PMC->PMC_FSMR = i; 1376 1377 /* Set the WAITMODE bit = 1 */ 1378 PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_WAITMODE; 1379 1380 /* Waiting for Master Clock Ready MCKRDY = 1 */ 1381 while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); 1382 1383 /* Waiting for MOSCRCEN bit cleared is strongly recommended 1384 * to ensure that the core will not execute undesired instructions 1385 */ 1386 for (i = 0; i < 500; i++) { 1387 __NOP(); 1388 } 1389 while (!(PMC->CKGR_MOR & CKGR_MOR_MOSCRCEN)); 1390 1391 #if (!SAMG) 1392 /* Restore Flash in idle mode */ 1393 i = PMC->PMC_FSMR; 1394 i &= ~PMC_FSMR_FLPM_Msk; 1395 i |= PMC_WAIT_MODE_FLASH_IDLE; 1396 PMC->PMC_FSMR = i; 1397 #endif 1398 } 1399 #else 1400 /** 1401 * \brief Enable Wait Mode. Enter condition: WFE + (SLEEPDEEP bit = 0) + 1402 * (LPM bit = 1) 1403 */ 1404 void pmc_enable_waitmode(void) 1405 { 1406 uint32_t i; 1407 1408 PMC->PMC_FSMR |= PMC_FSMR_LPM; /* Enter Wait mode */ 1409 SCB->SCR &= (uint32_t) ~ SCB_SCR_SLEEPDEEP_Msk; /* Deep sleep */ 1410 1411 __WFE(); 1412 1413 /* Waiting for MOSCRCEN bit cleared is strongly recommended 1414 * to ensure that the core will not execute undesired instructions 1415 */ 1416 for (i = 0; i < 500; i++) { 1417 __NOP(); 1418 } 1419 while (!(PMC->CKGR_MOR & CKGR_MOR_MOSCRCEN)); 1420 1421 } 1422 #endif 1423 1424 #if (!(SAMG51 || SAMG53 || SAMG54)) 1425 /** 1426 * \brief Enable Backup Mode. Enter condition: WFE/(VROFF bit = 1) + 1427 * (SLEEPDEEP bit = 1) 1428 */ 1429 void pmc_enable_backupmode(void) 1430 { 1431 #if (SAM4C || SAM4CM || SAM4CP) 1432 uint32_t tmp = SUPC->SUPC_MR & ~(SUPC_MR_BUPPOREN | SUPC_MR_KEY_Msk); 1433 SUPC->SUPC_MR = tmp | SUPC_MR_KEY_PASSWD; 1434 while (SUPC->SUPC_SR & SUPC_SR_BUPPORS); 1435 #endif 1436 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 1437 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70) 1438 SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_VROFF_STOP_VREG; 1439 __WFE(); 1440 __WFI(); 1441 #else 1442 __WFE(); 1443 #endif 1444 } 1445 #endif 1446 1447 /** 1448 * \brief Enable Clock Failure Detector. 1449 */ 1450 void pmc_enable_clock_failure_detector(void) 1451 { 1452 uint32_t ul_reg = PMC->CKGR_MOR; 1453 1454 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_CFDEN | ul_reg; 1455 } 1456 1457 /** 1458 * \brief Disable Clock Failure Detector. 1459 */ 1460 void pmc_disable_clock_failure_detector(void) 1461 { 1462 uint32_t ul_reg = PMC->CKGR_MOR & (~CKGR_MOR_CFDEN); 1463 1464 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | ul_reg; 1465 } 1466 1467 #if (SAM4N || SAM4C || SAM4CM || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70) 1468 /** 1469 * \brief Enable Slow Crystal Oscillator Frequency Monitoring. 1470 */ 1471 void pmc_enable_sclk_osc_freq_monitor(void) 1472 { 1473 uint32_t ul_reg = PMC->CKGR_MOR; 1474 1475 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_XT32KFME | ul_reg; 1476 } 1477 1478 /** 1479 * \brief Disable Slow Crystal Oscillator Frequency Monitoring. 1480 */ 1481 void pmc_disable_sclk_osc_freq_monitor(void) 1482 { 1483 uint32_t ul_reg = PMC->CKGR_MOR & (~CKGR_MOR_XT32KFME); 1484 1485 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | ul_reg; 1486 } 1487 #endif 1488 1489 /** 1490 * \brief Enable or disable write protect of PMC registers. 1491 * 1492 * \param ul_enable 1 to enable, 0 to disable. 1493 */ 1494 void pmc_set_writeprotect(uint32_t ul_enable) 1495 { 1496 if (ul_enable) { 1497 PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN; 1498 } else { 1499 PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD; 1500 } 1501 } 1502 1503 /** 1504 * \brief Return write protect status. 1505 * 1506 * \return Return write protect status. 1507 */ 1508 uint32_t pmc_get_writeprotect_status(void) 1509 { 1510 return PMC->PMC_WPSR; 1511 } 1512 1513 #if (SAMG53 || SAMG54 || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70) 1514 /** 1515 * \brief Enable the specified peripheral clock. 1516 * 1517 * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). 1518 * 1519 * \param ul_id Peripheral ID (ID_xxx). 1520 * 1521 * \retval 0 Success. 1522 * \retval 1 Fail. 1523 */ 1524 uint32_t pmc_enable_sleepwalking(uint32_t ul_id) 1525 { 1526 uint32_t temp; 1527 #if (SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70) 1528 if ((7 <= ul_id) && (ul_id<= 29)) { 1529 #else 1530 if ((8 <= ul_id) && (ul_id<= 29)) { 1531 #endif 1532 temp = pmc_get_active_status0(); 1533 if (temp & (1 << ul_id)) { 1534 return 1; 1535 } 1536 PMC->PMC_SLPWK_ER0 = 1 << ul_id; 1537 temp = pmc_get_active_status0(); 1538 if (temp & (1 << ul_id)) { 1539 pmc_disable_sleepwalking(ul_id); 1540 return 1; 1541 } 1542 return 0; 1543 } 1544 #if (SAMV71 || SAMV70 || SAME70 || SAMS70) 1545 else if ((32 <= ul_id) && (ul_id<= 60)) { 1546 ul_id -= 32; 1547 temp = pmc_get_active_status1(); 1548 if (temp & (1 << ul_id)) { 1549 return 1; 1550 } 1551 PMC->PMC_SLPWK_ER1 = 1 << ul_id; 1552 temp = pmc_get_active_status1(); 1553 if (temp & (1 << ul_id)) { 1554 pmc_disable_sleepwalking(ul_id); 1555 return 1; 1556 } 1557 return 0; 1558 } 1559 #endif 1560 else { 1561 return 1; 1562 } 1563 } 1564 1565 /** 1566 * \brief Disable the sleepwalking of specified peripheral. 1567 * 1568 * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). 1569 * 1570 * \param ul_id Peripheral ID (ID_xxx). 1571 * 1572 * \retval 0 Success. 1573 * \retval 1 Invalid parameter. 1574 */ 1575 uint32_t pmc_disable_sleepwalking(uint32_t ul_id) 1576 { 1577 #if (SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70) 1578 if ((7 <= ul_id) && (ul_id<= 29)) { 1579 #else 1580 if ((8 <= ul_id) && (ul_id<= 29)) { 1581 #endif 1582 PMC->PMC_SLPWK_DR0 = 1 << ul_id; 1583 return 0; 1584 } 1585 #if (SAMV71 || SAMV70 || SAME70 || SAMS70) 1586 else if ((32 <= ul_id) && (ul_id<= 60)) { 1587 ul_id -= 32; 1588 PMC->PMC_SLPWK_DR1 = 1 << ul_id; 1589 return 0; 1590 } 1591 #endif 1592 else { 1593 return 1; 1594 } 1595 } 1596 1597 /** 1598 * \brief Return peripheral sleepwalking enable status. 1599 * 1600 * \return the status register value. 1601 */ 1602 uint32_t pmc_get_sleepwalking_status0(void) 1603 { 1604 return PMC->PMC_SLPWK_SR0; 1605 } 1606 1607 /** 1608 * \brief Return peripheral active status. 1609 * 1610 * \return the status register value. 1611 */ 1612 uint32_t pmc_get_active_status0(void) 1613 { 1614 return PMC->PMC_SLPWK_ASR0; 1615 } 1616 1617 #endif 1618 1619 #if (SAMV71 || SAMV70 || SAME70 || SAMS70) 1620 /** 1621 * \brief Return peripheral sleepwalking enable status. 1622 * 1623 * \return the status register value. 1624 */ 1625 uint32_t pmc_get_sleepwalking_status1(void) 1626 { 1627 return PMC->PMC_SLPWK_SR1; 1628 } 1629 1630 /** 1631 * \brief Return peripheral active status. 1632 * 1633 * \return the status register value. 1634 */ 1635 uint32_t pmc_get_active_status1(void) 1636 { 1637 return PMC->PMC_SLPWK_ASR1; 1638 } 1639 #endif 1640 1641 /// @cond 0 1642 /**INDENT-OFF**/ 1643 #ifdef __cplusplus 1644 } 1645 #endif 1646 /**INDENT-ON**/ 1647 /// @endcond 1648