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 */
pmc_mck_set_prescaler(uint32_t ul_pres)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 */
pmc_mck_set_division(uint32_t ul_div)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 */
pmc_mck_set_source(uint32_t ul_source)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 */
pmc_switch_mck_to_sclk(uint32_t ul_pres)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 */
pmc_switch_mck_to_mainck(uint32_t ul_pres)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 */
pmc_switch_mck_to_pllack(uint32_t ul_pres)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 */
pmc_switch_mck_to_pllbck(uint32_t ul_pres)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 */
pmc_switch_mck_to_upllck(uint32_t ul_pres)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 */
pmc_switch_sclk_to_32kxtal(uint32_t ul_bypass)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 */
pmc_osc_is_ready_32kxtal(void)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 */
pmc_switch_mainck_to_fastrc(uint32_t ul_moscrcf)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 */
pmc_osc_enable_fastrc(uint32_t ul_rc)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 */
pmc_osc_disable_fastrc(void)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 */
pmc_osc_is_ready_fastrc(void)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 */
pmc_osc_enable_main_xtal(uint32_t ul_xtal_startup_time)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 */
pmc_osc_bypass_main_xtal(void)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 */
pmc_osc_disable_main_xtal(void)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 */
pmc_osc_is_bypassed_main_xtal(void)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 */
pmc_osc_is_ready_main_xtal(void)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 */
pmc_switch_mainck_to_xtal(uint32_t ul_bypass,uint32_t ul_xtal_startup_time)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 */
pmc_osc_disable_xtal(uint32_t ul_bypass)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 */
pmc_osc_is_ready_mainck(void)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 */
pmc_mainck_osc_select(uint32_t ul_xtal_rc)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 */
pmc_enable_pllack(uint32_t mula,uint32_t pllacount,uint32_t diva)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 */
pmc_disable_pllack(void)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 */
pmc_is_locked_pllack(void)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 */
pmc_enable_pllbck(uint32_t mulb,uint32_t pllbcount,uint32_t divb)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 */
pmc_disable_pllbck(void)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 */
pmc_is_locked_pllbck(void)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 */
pmc_enable_upll_clock(void)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 */
pmc_disable_upll_clock(void)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 */
pmc_is_locked_upll(void)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 */
pmc_enable_periph_clk(uint32_t ul_id)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 */
pmc_disable_periph_clk(uint32_t ul_id)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 */
pmc_enable_all_periph_clk(void)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 */
pmc_disable_all_periph_clk(void)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 */
pmc_is_periph_clk_enabled(uint32_t ul_id)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 */
pmc_pck_set_prescaler(uint32_t ul_id,uint32_t ul_pres)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 */
pmc_pck_set_source(uint32_t ul_id,uint32_t ul_source)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 */
pmc_switch_pck_to_sclk(uint32_t ul_id,uint32_t ul_pres)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 */
pmc_switch_pck_to_mainck(uint32_t ul_id,uint32_t ul_pres)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 */
pmc_switch_pck_to_pllack(uint32_t ul_id,uint32_t ul_pres)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 */
pmc_switch_pck_to_pllbck(uint32_t ul_id,uint32_t ul_pres)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 */
pmc_switch_pck_to_upllck(uint32_t ul_id,uint32_t ul_pres)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 */
pmc_switch_pck_to_mck(uint32_t ul_id,uint32_t ul_pres)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 */
pmc_enable_pck(uint32_t ul_id)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 */
pmc_disable_pck(uint32_t ul_id)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 */
pmc_enable_all_pck(void)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 */
pmc_disable_all_pck(void)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 */
pmc_is_pck_enabled(uint32_t ul_id)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 */
pmc_enable_cpck(void)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 */
pmc_disable_cpck(void)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 */
pmc_is_cpck_enabled(void)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 */
pmc_enable_cpbmck(void)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 */
pmc_disable_cpbmck(void)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 */
pmc_is_cpbmck_enabled(void)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 */
pmc_cpck_set_prescaler(uint32_t ul_pres)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 */
pmc_cpck_set_source(uint32_t ul_source)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 */
pmc_switch_udpck_to_pllack(uint32_t ul_usbdiv)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 */
pmc_switch_udpck_to_pllbck(uint32_t ul_usbdiv)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 */
pmc_switch_udpck_to_upllck(uint32_t ul_usbdiv)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 */
pmc_enable_udpck(void)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 */
pmc_disable_udpck(void)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 */
pmc_switch_uhpck_to_pllack(uint32_t ul_usbdiv)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 */
pmc_switch_uhpck_to_pllbck(uint32_t ul_usbdiv)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 */
pmc_enable_uhpck(void)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 */
pmc_enable_interrupt(uint32_t ul_sources)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 */
pmc_disable_interrupt(uint32_t ul_sources)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 */
pmc_get_interrupt_mask(void)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 */
pmc_get_status(void)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 */
pmc_set_fast_startup_input(uint32_t ul_inputs)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 */
pmc_clr_fast_startup_input(uint32_t ul_inputs)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 */
pmc_cp_set_fast_startup_input(uint32_t ul_inputs)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 */
pmc_cp_clr_fast_startup_input(uint32_t ul_inputs)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 */
pmc_enable_sleepmode(uint8_t uc_type)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 */
pmc_set_flash_in_wait_mode(uint32_t ul_flash_state)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 */
pmc_enable_waitmode(void)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 */
pmc_enable_waitmode(void)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 */
pmc_enable_backupmode(void)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 */
pmc_enable_clock_failure_detector(void)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 */
pmc_disable_clock_failure_detector(void)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 */
pmc_enable_sclk_osc_freq_monitor(void)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 */
pmc_disable_sclk_osc_freq_monitor(void)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 */
pmc_set_writeprotect(uint32_t ul_enable)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 */
pmc_get_writeprotect_status(void)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 */
pmc_enable_sleepwalking(uint32_t ul_id)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