xref: /btstack/port/samv71-xplained-atwilc3000/ASF/sam/drivers/pmc/pmc.h (revision 1b2596b5303dd8caeea8565532c93cca8dab8cc4)
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 #ifndef PMC_H_INCLUDED
48 #define PMC_H_INCLUDED
49 
50 #include "compiler.h"
51 
52 /// @cond 0
53 /**INDENT-OFF**/
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 /**INDENT-ON**/
58 /// @endcond
59 
60 /** Bit mask for peripheral clocks (PCER0) */
61 #define PMC_MASK_STATUS0        (0xFFFFFFFC)
62 
63 /** Bit mask for peripheral clocks (PCER1) */
64 #define PMC_MASK_STATUS1        (0xFFFFFFFF)
65 
66 /** Loop counter timeout value */
67 #define PMC_TIMEOUT             (2048)
68 
69 /** Key to unlock CKGR_MOR register */
70 #ifndef CKGR_MOR_KEY_PASSWD
71 #define CKGR_MOR_KEY_PASSWD    CKGR_MOR_KEY(0x37U)
72 #endif
73 
74 /** Key used to write SUPC registers */
75 #ifndef SUPC_CR_KEY_PASSWD
76 #define SUPC_CR_KEY_PASSWD    SUPC_CR_KEY(0xA5U)
77 #endif
78 
79 #ifndef SUPC_MR_KEY_PASSWD
80 #define SUPC_MR_KEY_PASSWD    SUPC_MR_KEY(0xA5U)
81 #endif
82 
83 /** Mask to access fast startup input */
84 #define PMC_FAST_STARTUP_Msk    (0x7FFFFu)
85 
86 /** PMC_WPMR Write Protect KEY, unlock it */
87 #ifndef PMC_WPMR_WPKEY_PASSWD
88 #define PMC_WPMR_WPKEY_PASSWD    PMC_WPMR_WPKEY((uint32_t) 0x504D43)
89 #endif
90 
91 /** Using external oscillator */
92 #define PMC_OSC_XTAL            0
93 
94 /** Oscillator in bypass mode */
95 #define PMC_OSC_BYPASS          1
96 
97 #define PMC_PCK_0               0 /* PCK0 ID */
98 #define PMC_PCK_1               1 /* PCK1 ID */
99 #define PMC_PCK_2               2 /* PCK2 ID */
100 #if SAMG55
101 #define PMC_PCK_3               3 /* PCK3 ID */
102 #define PMC_PCK_4               4 /* PCK4 ID */
103 #define PMC_PCK_5               5 /* PCK5 ID */
104 #define PMC_PCK_6               6 /* PCK6 ID */
105 #define PMC_PCK_7               7 /* PCK7 ID */
106 #endif
107 
108 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70)
109 /** Flash state in Wait Mode */
110 #define PMC_WAIT_MODE_FLASH_STANDBY         PMC_FSMR_FLPM_FLASH_STANDBY
111 #define PMC_WAIT_MODE_FLASH_DEEP_POWERDOWN  PMC_FSMR_FLPM_FLASH_DEEP_POWERDOWN
112 #define PMC_WAIT_MODE_FLASH_IDLE            PMC_FSMR_FLPM_FLASH_IDLE
113 #endif
114 
115 /** Convert startup time from us to MOSCXTST */
116 #define pmc_us_to_moscxtst(startup_us, slowck_freq)      \
117 	((startup_us * slowck_freq / 8 / 1000000) < 0x100 ?  \
118 		(startup_us * slowck_freq / 8 / 1000000) : 0xFF)
119 
120 /**
121  * \name Master clock (MCK) Source and Prescaler configuration
122  *
123  * \note The following functions may be used to select the clock source and
124  * prescaler for the master clock.
125  */
126 //@{
127 
128 void pmc_mck_set_prescaler(uint32_t ul_pres);
129 #if SAMV71 || SAMV70 || SAME70 || SAMS70
130 void pmc_mck_set_division(uint32_t ul_div);
131 #endif
132 void pmc_mck_set_source(uint32_t ul_source);
133 uint32_t pmc_switch_mck_to_sclk(uint32_t ul_pres);
134 uint32_t pmc_switch_mck_to_mainck(uint32_t ul_pres);
135 uint32_t pmc_switch_mck_to_pllack(uint32_t ul_pres);
136 #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55)
137 uint32_t pmc_switch_mck_to_pllbck(uint32_t ul_pres);
138 #endif
139 #if (SAM3XA || SAM3U || SAMV71 || SAMV70 || SAME70 || SAMS70)
140 uint32_t pmc_switch_mck_to_upllck(uint32_t ul_pres);
141 #endif
142 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70)
143 void pmc_set_flash_in_wait_mode(uint32_t ul_flash_state);
144 #endif
145 
146 
147 //@}
148 
149 /**
150  * \name Slow clock (SLCK) oscillator and configuration
151  *
152  */
153 //@{
154 
155 void pmc_switch_sclk_to_32kxtal(uint32_t ul_bypass);
156 uint32_t pmc_osc_is_ready_32kxtal(void);
157 
158 //@}
159 
160 /**
161  * \name Main Clock (MAINCK) oscillator and configuration
162  *
163  */
164 //@{
165 
166 void pmc_switch_mainck_to_fastrc(uint32_t ul_moscrcf);
167 void pmc_osc_enable_fastrc(uint32_t ul_rc);
168 void pmc_osc_disable_fastrc(void);
169 uint32_t pmc_osc_is_ready_fastrc(void);
170 void pmc_osc_enable_main_xtal(uint32_t ul_xtal_startup_time);
171 void pmc_osc_bypass_main_xtal(void);
172 void pmc_osc_disable_main_xtal(void);
173 uint32_t pmc_osc_is_bypassed_main_xtal(void);
174 uint32_t pmc_osc_is_ready_main_xtal(void);
175 void pmc_switch_mainck_to_xtal(uint32_t ul_bypass,
176 		uint32_t ul_xtal_startup_time);
177 void pmc_osc_disable_xtal(uint32_t ul_bypass);
178 uint32_t pmc_osc_is_ready_mainck(void);
179 void pmc_mainck_osc_select(uint32_t ul_xtal_rc);
180 
181 //@}
182 
183 /**
184  * \name PLL oscillator and configuration
185  *
186  */
187 //@{
188 
189 void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva);
190 void pmc_disable_pllack(void);
191 uint32_t pmc_is_locked_pllack(void);
192 
193 #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55)
194 void pmc_enable_pllbck(uint32_t mulb, uint32_t pllbcount, uint32_t divb);
195 void pmc_disable_pllbck(void);
196 uint32_t pmc_is_locked_pllbck(void);
197 #endif
198 
199 #if (SAM3XA || SAM3U || SAMV71 || SAMV70 || SAME70 || SAMS70)
200 void pmc_enable_upll_clock(void);
201 void pmc_disable_upll_clock(void);
202 uint32_t pmc_is_locked_upll(void);
203 #endif
204 
205 //@}
206 
207 /**
208  * \name Peripherals clock configuration
209  *
210  */
211 //@{
212 
213 uint32_t pmc_enable_periph_clk(uint32_t ul_id);
214 uint32_t pmc_disable_periph_clk(uint32_t ul_id);
215 void pmc_enable_all_periph_clk(void);
216 void pmc_disable_all_periph_clk(void);
217 uint32_t pmc_is_periph_clk_enabled(uint32_t ul_id);
218 
219 //@}
220 
221 /**
222  * \name Programmable clock Source and Prescaler configuration
223  *
224  * The following functions may be used to select the clock source and
225  * prescaler for the specified programmable clock.
226  */
227 //@{
228 
229 void pmc_pck_set_prescaler(uint32_t ul_id, uint32_t ul_pres);
230 void pmc_pck_set_source(uint32_t ul_id, uint32_t ul_source);
231 uint32_t pmc_switch_pck_to_sclk(uint32_t ul_id, uint32_t ul_pres);
232 uint32_t pmc_switch_pck_to_mainck(uint32_t ul_id, uint32_t ul_pres);
233 uint32_t pmc_switch_pck_to_pllack(uint32_t ul_id, uint32_t ul_pres);
234 #if (SAM4C || SAM4CM || SAM4CP)
235 void pmc_enable_cpck(void);
236 void pmc_disable_cpck(void);
237 bool pmc_is_cpck_enabled(void);
238 void pmc_enable_cpbmck(void);
239 void pmc_disable_cpbmck(void);
240 bool pmc_is_cpbmck_enabled(void);
241 void pmc_cpck_set_prescaler(uint32_t ul_pres);
242 void pmc_cpck_set_source(uint32_t ul_source);
243 #endif
244 #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55)
245 uint32_t pmc_switch_pck_to_pllbck(uint32_t ul_id, uint32_t ul_pres);
246 #endif
247 #if (SAM3XA || SAM3U || SAMV71 || SAMV70 || SAME70 || SAMS70)
248 uint32_t pmc_switch_pck_to_upllck(uint32_t ul_id, uint32_t ul_pres);
249 #endif
250 uint32_t pmc_switch_pck_to_mck(uint32_t ul_id, uint32_t ul_pres);
251 void pmc_enable_pck(uint32_t ul_id);
252 void pmc_disable_pck(uint32_t ul_id);
253 void pmc_enable_all_pck(void);
254 void pmc_disable_all_pck(void);
255 uint32_t pmc_is_pck_enabled(uint32_t ul_id);
256 
257 //@}
258 
259 /**
260  * \name USB clock configuration
261  *
262  */
263 //@{
264 
265 #if (SAM3S || SAM3XA || SAM4S || SAM4E || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)
266 void pmc_switch_udpck_to_pllack(uint32_t ul_usbdiv);
267 #endif
268 #if (SAM3S || SAM4S || SAMG55)
269 void pmc_switch_udpck_to_pllbck(uint32_t ul_usbdiv);
270 #endif
271 #if (SAM3XA || SAMV71 || SAMV70 || SAME70 || SAMS70)
272 void pmc_switch_udpck_to_upllck(uint32_t ul_usbdiv);
273 #endif
274 #if (SAM3S || SAM3XA || SAM4S || SAM4E || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)
275 void pmc_enable_udpck(void);
276 void pmc_disable_udpck(void);
277 #endif
278 #if SAMG55
279 void pmc_switch_uhpck_to_pllack(uint32_t ul_usbdiv);
280 void pmc_switch_uhpck_to_pllbck(uint32_t ul_usbdiv);
281 void pmc_enable_uhpck(void);
282 #endif
283 
284 //@}
285 
286 /**
287  * \name Interrupt and status management
288  *
289  */
290 //@{
291 
292 void pmc_enable_interrupt(uint32_t ul_sources);
293 void pmc_disable_interrupt(uint32_t ul_sources);
294 uint32_t pmc_get_interrupt_mask(void);
295 uint32_t pmc_get_status(void);
296 
297 //@}
298 
299 /**
300  * \name Power management
301  *
302  * The following functions are used to configure sleep mode and additional
303  * wake up inputs.
304  */
305 //@{
306 
307 void pmc_set_fast_startup_input(uint32_t ul_inputs);
308 void pmc_clr_fast_startup_input(uint32_t ul_inputs);
309 #if (SAM4C || SAM4CM || SAM4CP)
310 void pmc_cp_set_fast_startup_input(uint32_t ul_inputs);
311 void pmc_cp_clr_fast_startup_input(uint32_t ul_inputs);
312 #endif
313 #if (!(SAMG51 || SAMG53 || SAMG54))
314 void pmc_enable_sleepmode(uint8_t uc_type);
315 #endif
316 void pmc_enable_waitmode(void);
317 #if (!(SAMG51 || SAMG53 || SAMG54))
318 void pmc_enable_backupmode(void);
319 #endif
320 //@}
321 
322 /**
323  * \name Failure detector
324  *
325  */
326 //@{
327 
328 void pmc_enable_clock_failure_detector(void);
329 void pmc_disable_clock_failure_detector(void);
330 
331 //@}
332 
333 #if (SAM4N || SAM4C || SAM4CM || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70)
334 /**
335  * \name Slow Crystal Oscillator Frequency Monitoring
336  *
337  */
338 //@{
339 
340 void pmc_enable_sclk_osc_freq_monitor(void);
341 void pmc_disable_sclk_osc_freq_monitor(void);
342 
343 //@}
344 #endif
345 
346 /**
347  * \name Write protection
348  *
349  */
350 //@{
351 
352 void pmc_set_writeprotect(uint32_t ul_enable);
353 uint32_t pmc_get_writeprotect_status(void);
354 
355 //@}
356 
357 #if (SAMG53 || SAMG54 || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)
358 /**
359  * \name Sleepwalking configuration
360  *
361  */
362 //@{
363 
364 uint32_t pmc_enable_sleepwalking(uint32_t ul_id);
365 uint32_t pmc_disable_sleepwalking(uint32_t ul_id);
366 uint32_t pmc_get_sleepwalking_status0(void);
367 uint32_t pmc_get_active_status0(void);
368 #if (SAMV71 || SAMV70 || SAME70 || SAMS70)
369 uint32_t pmc_get_sleepwalking_status1(void);
370 uint32_t pmc_get_active_status1(void);
371 #endif
372 //@}
373 #endif
374 
375 /// @cond 0
376 /**INDENT-OFF**/
377 #ifdef __cplusplus
378 }
379 #endif
380 /**INDENT-ON**/
381 /// @endcond
382 
383 //! @}
384 
385 /**
386  * \page sam_pmc_quickstart Quick start guide for the SAM PMC module
387  *
388  * This is the quick start guide for the \ref sam_drivers_pmc_group "PMC module",
389  * with step-by-step instructions on how to configure and use the driver in a
390  * selection of use cases.
391  *
392  * The use cases contain several code fragments. The code fragments in the
393  * steps for setup can be copied into a custom initialization function, while
394  * the steps for usage can be copied into, e.g., the main application function.
395  *
396  * \section pmc_use_cases PMC use cases
397  * - \ref pmc_basic_use_case Basic use case - Switch Main Clock sources
398  * - \ref pmc_use_case_2 Advanced use case - Configure Programmable Clocks
399  *
400  * \section pmc_basic_use_case Basic use case - Switch Main Clock sources
401  * In this use case, the PMC module is configured for a variety of system clock
402  * sources and speeds. A LED is used to visually indicate the current clock
403  * speed as the source is switched.
404  *
405  * \section pmc_basic_use_case_setup Setup
406  *
407  * \subsection pmc_basic_use_case_setup_prereq Prerequisites
408  * -# \ref gpio_group "General Purpose I/O Management (gpio)"
409  *
410  * \subsection pmc_basic_use_case_setup_code Code
411  * The following function needs to be added to the user application, to flash a
412  * board LED a variable number of times at a rate given in CPU ticks.
413  *
414  * \code
415 	 #define FLASH_TICK_COUNT   0x00012345
416 
417 	 void flash_led(uint32_t tick_count, uint8_t flash_count)
418 	 {
419 	     SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
420 	     SysTick->LOAD = tick_count;
421 
422 	     while (flash_count--)
423 	     {
424 	         gpio_toggle_pin(LED0_GPIO);
425 	         while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
426 	         gpio_toggle_pin(LED0_GPIO);
427 	         while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
428 	     }
429 	 }
430 \endcode
431  *
432  * \section pmc_basic_use_case_usage Use case
433  *
434  * \subsection pmc_basic_use_case_usage_code Example code
435  * Add to application C-file:
436  * \code
437 	for (;;)
438 	{
439 	    pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz);
440 	    flash_led(FLASH_TICK_COUNT, 5);
441 	    pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz);
442 	    flash_led(FLASH_TICK_COUNT, 5);
443 	    pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz);
444 	    flash_led(FLASH_TICK_COUNT, 5);
445 	    pmc_switch_mainck_to_xtal(0);
446 	    flash_led(FLASH_TICK_COUNT, 5);
447 	}
448 \endcode
449  *
450  * \subsection pmc_basic_use_case_usage_flow Workflow
451  * -# Wrap the code in an infinite loop:
452  *   \code
453 	for (;;)
454 \endcode
455  * -# Switch the Master CPU frequency to the internal 12MHz RC oscillator, flash
456  *    a LED on the board several times:
457  *   \code
458 	pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz);
459 	flash_led(FLASH_TICK_COUNT, 5);
460 \endcode
461  * -# Switch the Master CPU frequency to the internal 8MHz RC oscillator, flash
462  *    a LED on the board several times:
463  *   \code
464 	pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz);
465 	flash_led(FLASH_TICK_COUNT, 5);
466 \endcode
467  * -# Switch the Master CPU frequency to the internal 4MHz RC oscillator, flash
468  *    a LED on the board several times:
469  *   \code
470 	pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz);
471 	flash_led(FLASH_TICK_COUNT, 5);
472 \endcode
473  * -# Switch the Master CPU frequency to the external crystal oscillator, flash
474  *    a LED on the board several times:
475  *   \code
476 	pmc_switch_mainck_to_xtal(0, BOARD_OSC_STARTUP_US);
477 	flash_led(FLASH_TICK_COUNT, 5);
478 \endcode
479  *
480  * \section pmc_use_case_2 Use case #2 - Configure Programmable Clocks
481  * In this use case, the PMC module is configured to start the Slow Clock from
482  * an attached 32KHz crystal, and start one of the Programmable Clock modules
483  * sourced from the Slow Clock divided down with a prescale factor of 64.
484  *
485  * \section pmc_use_case_2_setup Setup
486  *
487  * \subsection pmc_use_case_2_setup_prereq Prerequisites
488  * -# \ref pio_group "Parallel Input/Output Controller (pio)"
489  *
490  * \subsection pmc_use_case_2_setup_code Code
491  * The following code must be added to the user application:
492  * \code
493 	pio_set_peripheral(PIOA, PIO_PERIPH_B, PIO_PA17);
494 \endcode
495  *
496  * \subsection pmc_use_case_2_setup_code_workflow Workflow
497  * -# Configure the PCK1 pin to output on a specific port pin (in this case,
498  *    PIOA pin 17) of the microcontroller.
499  *   \code
500 	pio_set_peripheral(PIOA, PIO_PERIPH_B, PIO_PA17);
501 \endcode
502  *   \note The peripheral selection and pin will vary according to your selected
503  *       SAM device model. Refer to the "Peripheral Signal Multiplexing on I/O
504  *       Lines" of your device's datasheet.
505  *
506  * \section pmc_use_case_2_usage Use case
507  * The generated PCK1 clock output can be viewed on an oscilloscope attached to
508  * the correct pin of the microcontroller.
509  *
510  * \subsection pmc_use_case_2_usage_code Example code
511  * Add to application C-file:
512  * \code
513 	  pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL);
514 	  pmc_switch_pck_to_sclk(PMC_PCK_1, PMC_PCK_PRES_CLK_64);
515 	  pmc_enable_pck(PMC_PCK_1);
516 
517 	  for (;;)
518 	  {
519 	      // Do Nothing
520 	  }
521 \endcode
522  *
523  * \subsection pmc_use_case_2_usage_flow Workflow
524  * -# Switch the Slow Clock source input to an external 32KHz crystal:
525  *   \code
526 	pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL);
527 \endcode
528  * -# Switch the Programmable Clock module PCK1 source clock to the Slow Clock,
529  *    with a prescaler of 64:
530  *   \code
531 	pmc_switch_pck_to_sclk(PMC_PCK_1, PMC_PCK_PRES_CLK_64);
532 \endcode
533  * -# Enable Programmable Clock module PCK1:
534  *   \code
535 	pmc_enable_pck(PMC_PCK_1);
536 \endcode
537  * -# Enter an infinite loop:
538  *   \code
539 	for (;;)
540 	{
541 	   // Do Nothing
542 	}
543 \endcode
544  */
545 
546 #endif /* PMC_H_INCLUDED */
547