1 /*****************************************************************************
2 *
3 * \file
4 *
5 * \brief High-level library abstracting features such as oscillators/pll/dfll
6 * configuration, clock configuration, System-sensible parameters
7 * configuration, buses clocks configuration, sleep mode, reset.
8 *
9 * Copyright (c) 2009-2018 Microchip Technology Inc. and its subsidiaries.
10 *
11 * \asf_license_start
12 *
13 * \page License
14 *
15 * Subject to your compliance with these terms, you may use Microchip
16 * software and any derivatives exclusively with Microchip products.
17 * It is your responsibility to comply with third party license terms applicable
18 * to your use of third party software (including open source software) that
19 * may accompany Microchip software.
20 *
21 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
22 * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
23 * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
24 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
25 * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
26 * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
27 * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
28 * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
29 * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
30 * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
31 * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
32 *
33 * \asf_license_stop
34 *
35 *****************************************************************************/
36 /*
37 * Support and FAQ: visit <a href="https://www.microchip.com/support/">Microchip Support</a>
38 */
39
40 #include "power_clocks_lib.h"
41
42
43 //! Device-specific data
44 #if UC3L
45 static long int pcl_configure_clocks_uc3l(pcl_freq_param_t *param); // FORWARD declaration
46 #endif
47
48 #if UC3C
49 static long int pcl_configure_clocks_uc3c(pcl_freq_param_t *param); // FORWARD declaration
50 #endif
51
52 #if UC3D
53 static long int pcl_configure_clocks_uc3d(pcl_freq_param_t *param); // FORWARD declaration
54 #endif
55
pcl_configure_clocks(pcl_freq_param_t * param)56 long int pcl_configure_clocks(pcl_freq_param_t *param)
57 {
58 #ifndef AVR32_PM_VERSION_RESETVALUE
59 // Implementation for UC3A, UC3A3, UC3B parts.
60 return(pm_configure_clocks(param));
61 #else
62 #if (defined AVR32_PM_410_H_INCLUDED ) || (defined AVR32_PM_412_H_INCLUDED )
63 #if UC3D
64 // Implementation for UC3D parts.
65 return(pcl_configure_clocks_uc3d(param));
66 #else
67 // Implementation for UC3C parts.
68 return(pcl_configure_clocks_uc3c(param));
69 #endif
70 #else
71 // Implementation for UC3L parts.
72 return(pcl_configure_clocks_uc3l(param));
73 #endif
74 #endif
75 }
76
77
78 //! Device-specific implementation
79 #if UC3L
80 // FORWARD declaration
81 static long int pcl_configure_synchronous_clocks( pm_clk_src_t main_clk_src,
82 unsigned long main_clock_freq_hz,
83 pcl_freq_param_t *param);
84
pcl_configure_clocks_rcsys(pcl_freq_param_t * param)85 long int pcl_configure_clocks_rcsys(pcl_freq_param_t *param)
86 {
87 // Supported main clock sources: PCL_MC_RCSYS
88
89 // Supported synchronous clocks frequencies if RCSYS is the main clock source:
90 // 115200Hz, 57600Hz, 28800Hz, 14400Hz, 7200Hz, 3600Hz, 1800Hz, 900Hz, 450Hz.
91
92 // NOTE: by default, this implementation doesn't perform thorough checks on the
93 // input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
94
95 #ifdef AVR32SFW_INPUT_CHECK
96 // Verify that fCPU >= fPBx
97 if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f))
98 return(-1);
99 #endif
100
101 #ifdef AVR32SFW_INPUT_CHECK
102 // Verify that the target frequencies are reachable.
103 if((param->cpu_f > SCIF_SLOWCLOCK_FREQ_HZ) || (param->pba_f > SCIF_SLOWCLOCK_FREQ_HZ)
104 || (param->pbb_f > SCIF_SLOWCLOCK_FREQ_HZ))
105 return(-1);
106 #endif
107
108 return(pcl_configure_synchronous_clocks(PM_CLK_SRC_SLOW, SCIF_SLOWCLOCK_FREQ_HZ, param));
109 }
110
111
pcl_configure_clocks_rc120m(pcl_freq_param_t * param)112 long int pcl_configure_clocks_rc120m(pcl_freq_param_t *param)
113 {
114 // Supported main clock sources: PCL_MC_RC120M
115
116 // Supported synchronous clocks frequencies if RC120M is the main clock source:
117 // 30MHz, 15MHz, 7.5MHz, 3.75MHz, 1.875MHz, 937.5kHz, 468.75kHz.
118
119 // NOTE: by default, this implementation doesn't perform thorough checks on the
120 // input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
121
122 #ifdef AVR32SFW_INPUT_CHECK
123 // Verify that fCPU >= fPBx
124 if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f))
125 return(-1);
126 #endif
127
128 #ifdef AVR32SFW_INPUT_CHECK
129 // Verify that the target frequencies are reachable.
130 if((param->cpu_f > SCIF_RC120M_FREQ_HZ) || (param->pba_f > SCIF_RC120M_FREQ_HZ)
131 || (param->pbb_f > SCIF_RC120M_FREQ_HZ))
132 return(-1);
133 #endif
134
135 // Start the 120MHz internal RCosc (RC120M) clock
136 scif_start_rc120M();
137
138 return(pcl_configure_synchronous_clocks(PM_CLK_SRC_RC120M, SCIF_RC120M_FREQ_HZ, param));
139 }
140
141
pcl_configure_clocks_osc0(pcl_freq_param_t * param)142 long int pcl_configure_clocks_osc0(pcl_freq_param_t *param)
143 {
144 // Supported main clock sources: PCL_MC_OSC0
145
146 // Supported synchronous clocks frequencies if OSC0 is the main clock source:
147 // (these obviously depend on the OSC0 frequency; we'll take 16MHz as an example)
148 // 16MHz, 8MHz, 4MHz, 2MHz, 1MHz, 500kHz, 250kHz, 125kHz, 62.5kHz.
149
150 // NOTE: by default, this implementation doesn't perform thorough checks on the
151 // input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
152
153 unsigned long main_clock_freq;
154
155
156 #ifdef AVR32SFW_INPUT_CHECK
157 // Verify that fCPU >= fPBx
158 if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f))
159 return(-1);
160 #endif
161
162 main_clock_freq = param->osc0_f;
163 #ifdef AVR32SFW_INPUT_CHECK
164 // Verify that the target frequencies are reachable.
165 if((param->cpu_f > main_clock_freq) || (param->pba_f > main_clock_freq)
166 || (param->pbb_f > main_clock_freq))
167 return(-1);
168 #endif
169 // Configure OSC0 in crystal mode, external crystal with a fcrystal Hz frequency.
170 scif_configure_osc_crystalmode(SCIF_OSC0, main_clock_freq);
171 // Enable the OSC0
172 scif_enable_osc(SCIF_OSC0, param->osc0_startup, true);
173
174 return(pcl_configure_synchronous_clocks(PM_CLK_SRC_OSC0, main_clock_freq, param));
175 }
176
177
pcl_configure_clocks_dfll0(pcl_freq_param_t * param)178 long int pcl_configure_clocks_dfll0(pcl_freq_param_t *param)
179 {
180 // Supported main clock sources: PCL_MC_DFLL
181
182 // Supported synchronous clocks frequencies if DFLL is the main clock source:
183 // (these obviously depend on the DFLL target frequency; we'll take 100MHz as an example)
184 // 50MHz, 25MHz, 12.5MHz, 6.25MHz, 3.125MHz, 1562.5kHz, 781.25kHz, 390.625kHz.
185
186 // NOTE: by default, this implementation doesn't perform thorough checks on the
187 // input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
188
189 unsigned long main_clock_freq;
190 scif_gclk_opt_t *pgc_dfllif_ref_opt;
191
192
193 #ifdef AVR32SFW_INPUT_CHECK
194 // Verify that fCPU >= fPBx
195 if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f))
196 return(-1);
197 #endif
198
199 main_clock_freq = param->dfll_f;
200 #ifdef AVR32SFW_INPUT_CHECK
201 // Verify that the target DFLL output frequency is in the correct range.
202 if((main_clock_freq > SCIF_DFLL_MAXFREQ_HZ) || (main_clock_freq < SCIF_DFLL_MINFREQ_HZ))
203 return(-1);
204 // Verify that the target frequencies are reachable.
205 if((param->cpu_f > main_clock_freq) || (param->pba_f > main_clock_freq)
206 || (param->pbb_f > main_clock_freq))
207 return(-1);
208 #endif
209 pgc_dfllif_ref_opt = (scif_gclk_opt_t *)param->pextra_params;
210 // Implementation note: this implementation configures the DFLL in closed-loop
211 // mode (because it gives the best accuracy) which enables the generic clock CLK_DFLLIF_REF
212 // as a reference (RCSYS being used as the generic clock source, undivided).
213 scif_dfll0_closedloop_configure_and_start(pgc_dfllif_ref_opt, main_clock_freq, true);
214
215 return(pcl_configure_synchronous_clocks(PM_CLK_SRC_DFLL0, main_clock_freq, param));
216 }
217
218
pcl_configure_clocks_uc3l(pcl_freq_param_t * param)219 static long int pcl_configure_clocks_uc3l(pcl_freq_param_t *param)
220 {
221 // Supported main clock sources: PCL_MC_RCSYS, PCL_MC_OSC0, PCL_MC_DFLL0, PCL_MC_RC120M
222
223 // Supported synchronous clocks frequencies if RCSYS is the main clock source:
224 // 115200Hz, 57600Hz, 28800Hz, 14400Hz, 7200Hz, 3600Hz, 1800Hz, 900Hz, 450Hz.
225
226 // Supported synchronous clocks frequencies if RC120M is the main clock source:
227 // 30MHz, 15MHz, 7.5MHz, 3.75MHz, 1.875MHz, 937.5kHz, 468.75kHz.
228
229 // Supported synchronous clocks frequencies if OSC0 is the main clock source:
230 // (these obviously depend on the OSC0 frequency; we'll take 16MHz as an example)
231 // 16MHz, 8MHz, 4MHz, 2MHz, 1MHz, 500kHz, 250kHz, 125kHz, 62.5kHz.
232
233 // Supported synchronous clocks frequencies if DFLL is the main clock source:
234 // (these obviously depend on the DFLL target frequency; we'll take 100MHz as an example)
235 // 50MHz, 25MHz, 12.5MHz, 6.25MHz, 3.125MHz, 1562.5kHz, 781.25kHz, 390.625kHz.
236
237 // NOTE: by default, this implementation doesn't perform thorough checks on the
238 // input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK.
239
240
241 #ifdef AVR32SFW_INPUT_CHECK
242 // Verify that fCPU >= fPBx
243 if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f))
244 return(-1);
245 #endif
246
247 if(PCL_MC_RCSYS == param->main_clk_src)
248 {
249 return(pcl_configure_clocks_rcsys(param));
250 }
251 else if(PCL_MC_RC120M == param->main_clk_src)
252 {
253 return(pcl_configure_clocks_rc120m(param));
254 }
255 else if(PCL_MC_OSC0 == param->main_clk_src)
256 {
257 return(pcl_configure_clocks_osc0(param));
258 }
259 else // PCL_MC_DFLL0 == param->main_clk_src
260 {
261 return(pcl_configure_clocks_dfll0(param));
262 }
263 }
264
pcl_configure_synchronous_clocks(pm_clk_src_t main_clk_src,unsigned long main_clock_freq_hz,pcl_freq_param_t * param)265 static long int pcl_configure_synchronous_clocks(pm_clk_src_t main_clk_src, unsigned long main_clock_freq_hz, pcl_freq_param_t *param)
266 {
267 //#
268 //# Set the Synchronous clock division ratio for each clock domain
269 //#
270 pm_set_all_cksel(main_clock_freq_hz, param->cpu_f, param->pba_f, param->pbb_f);
271
272 //#
273 //# Set the Flash wait state and the speed read mode (depending on the target CPU frequency).
274 //#
275 #if UC3L
276 flashcdw_set_flash_waitstate_and_readmode(param->cpu_f);
277 #elif UC3C
278 flashc_set_flash_waitstate_and_readmode(param->cpu_f);
279 #endif
280
281
282 //#
283 //# Switch the main clock source to the selected clock.
284 //#
285 pm_set_mclk_source(main_clk_src);
286
287 return PASS;
288 }
289
290 #endif // UC3L device-specific implementation
291
292 //! UC3C Device-specific implementation
293 #if UC3C
pcl_configure_clocks_uc3c(pcl_freq_param_t * param)294 static long int pcl_configure_clocks_uc3c(pcl_freq_param_t *param)
295 {
296 #define PM_MAX_MUL ((1 << AVR32_SCIF_PLLMUL_SIZE) - 1)
297 #define AVR32_PM_PBA_MAX_FREQ 66000000
298 #define AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ 240000000
299 #define AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ 160000000
300
301 // Implementation for UC3C parts.
302 // Supported frequencies:
303 // Fosc0 mul div PLL div2_en cpu_f pba_f Comment
304 // 12 15 1 192 1 12 12
305 // 12 9 3 40 1 20 20 PLL out of spec
306 // 12 15 1 192 1 24 12
307 // 12 9 1 120 1 30 15
308 // 12 9 3 40 0 40 20 PLL out of spec
309 // 12 15 1 192 1 48 12
310 // 12 15 1 192 1 48 24
311 // 12 8 1 108 1 54 27
312 // 12 9 1 120 1 60 15
313 // 12 9 1 120 1 60 30
314 // 12 10 1 132 1 66 16.5
315 //
316 unsigned long in_cpu_f = param->cpu_f;
317 unsigned long in_osc0_f = param->osc0_f;
318 unsigned long mul, div, div2_en = 0, div2_cpu = 0, div2_pba = 0;
319 unsigned long pll_freq, rest;
320 bool b_div2_pba, b_div2_cpu;
321
322 // Configure OSC0 in crystal mode, external crystal with a FOSC0 Hz frequency.
323 scif_configure_osc_crystalmode(SCIF_OSC0, in_osc0_f);
324 // Enable the OSC0
325 scif_enable_osc(SCIF_OSC0, param->osc0_startup, true);
326 // Set the main clock source as being OSC0.
327 pm_set_mclk_source(PM_CLK_SRC_OSC0);
328
329 // Start with CPU freq config
330 if (in_cpu_f == in_osc0_f)
331 {
332 param->cpu_f = in_osc0_f;
333 param->pba_f = in_osc0_f;
334 return PASS;
335 }
336 else if (in_cpu_f < in_osc0_f)
337 {
338 // TBD
339 }
340
341 rest = in_cpu_f % in_osc0_f;
342
343 for (div = 1; div < 32; div++)
344 {
345 if ((div * rest) % in_osc0_f == 0)
346 break;
347 }
348 if (div == 32)
349 return FAIL;
350
351 mul = (in_cpu_f * div) / in_osc0_f;
352
353 if (mul > PM_MAX_MUL)
354 return FAIL;
355
356 // export 2power from PLL div to div2_cpu
357 while (!(div % 2))
358 {
359 div /= 2;
360 div2_cpu++;
361 }
362
363 // Here we know the mul and div parameter of the PLL config.
364 // . Check out if the PLL has a valid in_cpu_f.
365 // . Try to have for the PLL frequency (VCO output) the highest possible value
366 // to reduce jitter.
367 while (in_osc0_f * 2 * mul / div < AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ)
368 {
369 if (2 * mul > PM_MAX_MUL)
370 break;
371 mul *= 2;
372 div2_cpu++;
373 }
374
375 if (div2_cpu != 0)
376 {
377 div2_cpu--;
378 div2_en = 1;
379 }
380
381 pll_freq = in_osc0_f * mul / (div * (1 << div2_en));
382
383 // Update real CPU Frequency
384 param->cpu_f = pll_freq / (1 << div2_cpu);
385 mul--;
386
387 scif_pll_opt_t opt;
388
389 opt.osc = SCIF_OSC0, // Sel Osc0 or Osc1
390 opt.lockcount = 16, // lockcount in main clock for the PLL wait lock
391 opt.div = div, // DIV=1 in the formula
392 opt.mul = mul, // MUL=7 in the formula
393 opt.pll_div2 = div2_en, // pll_div2 Divide the PLL output frequency by 2 (this settings does not change the FVCO value)
394 opt.pll_wbwdisable = 0, //pll_wbwdisable 1 Disable the Wide-Bandith Mode (Wide-Bandwith mode allow a faster startup time and out-of-lock time). 0 to enable the Wide-Bandith Mode.
395 opt.pll_freq = (pll_freq < AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ) ? 1 : 0, // Set to 1 for VCO frequency range 80-180MHz, set to 0 for VCO frequency range 160-240Mhz.
396
397 scif_pll_setup(SCIF_PLL0, &opt); // lockcount in main clock for the PLL wait lock
398
399 /* Enable PLL0 */
400 scif_pll_enable(SCIF_PLL0);
401
402 /* Wait for PLL0 locked */
403 scif_wait_for_pll_locked(SCIF_PLL0) ;
404
405 rest = pll_freq;
406 while (rest > AVR32_PM_PBA_MAX_FREQ ||
407 rest != param->pba_f)
408 {
409 div2_pba++;
410 rest = pll_freq / (1 << div2_pba);
411 if (rest < param->pba_f)
412 break;
413 }
414
415 // Update real PBA Frequency
416 param->pba_f = pll_freq / (1 << div2_pba);
417
418
419 if (div2_cpu)
420 {
421 b_div2_cpu = true;
422 div2_cpu--;
423 }
424 else
425 b_div2_cpu = false;
426
427 if (div2_pba)
428 {
429 b_div2_pba = true;
430 div2_pba--;
431 }
432 else
433 b_div2_pba = false;
434
435 if (b_div2_cpu == true )
436 {
437 pm_set_clk_domain_div(PM_CLK_DOMAIN_0, (pm_divratio_t) div2_cpu); // CPU
438 pm_set_clk_domain_div(PM_CLK_DOMAIN_1, (pm_divratio_t) div2_cpu); // HSB
439 pm_set_clk_domain_div(PM_CLK_DOMAIN_3, (pm_divratio_t) div2_cpu); // PBB
440 }
441 if (b_div2_pba == true )
442 {
443 pm_set_clk_domain_div(PM_CLK_DOMAIN_2, (pm_divratio_t) div2_pba); // PBA
444 pm_set_clk_domain_div(PM_CLK_DOMAIN_4, (pm_divratio_t) div2_pba); // PBC
445 }
446
447 // Set Flashc Wait State
448 flashc_set_flash_waitstate_and_readmode(param->cpu_f);
449
450 // Set the main clock source as being PLL0.
451 pm_set_mclk_source(PM_CLK_SRC_PLL0);
452
453 return PASS;
454 }
455 #endif // UC3C device-specific implementation
456
457 #if UC3D
pcl_configure_clocks_uc3d(pcl_freq_param_t * param)458 static long int pcl_configure_clocks_uc3d(pcl_freq_param_t *param)
459 {
460 #define PM_MAX_MUL ((1 << AVR32_SCIF_PLLMUL_SIZE) - 1)
461 #define AVR32_PM_PBA_MAX_FREQ 48000000
462 #define AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ 240000000
463 #define AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ 160000000
464
465 // Implementation for UC3C parts.
466 // Supported frequencies:
467 // Fosc0 mul div PLL div2_en cpu_f pba_f Comment
468 // 12 15 1 192 1 12 12
469 // 12 9 3 40 1 20 20 PLL out of spec
470 // 12 15 1 192 1 24 12
471 // 12 9 1 120 1 30 15
472 // 12 9 3 40 0 40 20 PLL out of spec
473 // 12 15 1 192 1 48 12
474 // 12 15 1 192 1 48 24
475 // 12 8 1 108 1 54 27
476 // 12 9 1 120 1 60 15
477 // 12 9 1 120 1 60 30
478 // 12 10 1 132 1 66 16.5
479 //
480 unsigned long in_cpu_f = param->cpu_f;
481 unsigned long in_osc0_f = param->osc0_f;
482 unsigned long mul, div, div2_en = 0, div2_cpu = 0, div2_pba = 0;
483 unsigned long pll_freq, rest;
484 Bool b_div2_pba, b_div2_cpu;
485
486 // Configure OSC0 in crystal mode, external crystal with a FOSC0 Hz frequency.
487 scif_configure_osc_crystalmode(SCIF_OSC0, in_osc0_f);
488 // Enable the OSC0
489 scif_enable_osc(SCIF_OSC0, param->osc0_startup, true);
490 // Set the main clock source as being OSC0.
491 pm_set_mclk_source(PM_CLK_SRC_OSC0);
492
493 // Start with CPU freq config
494 if (in_cpu_f == in_osc0_f)
495 {
496 param->cpu_f = in_osc0_f;
497 param->pba_f = in_osc0_f;
498 return PASS;
499 }
500 else if (in_cpu_f < in_osc0_f)
501 {
502 // TBD
503 }
504
505 rest = in_cpu_f % in_osc0_f;
506
507 for (div = 1; div < 32; div++)
508 {
509 if ((div * rest) % in_osc0_f == 0)
510 break;
511 }
512 if (div == 32)
513 return FAIL;
514
515 mul = (in_cpu_f * div) / in_osc0_f;
516
517 if (mul > PM_MAX_MUL)
518 return FAIL;
519
520 // export 2power from PLL div to div2_cpu
521 while (!(div % 2))
522 {
523 div /= 2;
524 div2_cpu++;
525 }
526
527 // Here we know the mul and div parameter of the PLL config.
528 // . Check out if the PLL has a valid in_cpu_f.
529 // . Try to have for the PLL frequency (VCO output) the highest possible value
530 // to reduce jitter.
531 while (in_osc0_f * 2 * mul / div < AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ)
532 {
533 if (2 * mul > PM_MAX_MUL)
534 break;
535 mul *= 2;
536 div2_cpu++;
537 }
538
539 if (div2_cpu != 0)
540 {
541 div2_cpu--;
542 div2_en = 1;
543 }
544
545 pll_freq = in_osc0_f * mul / (div * (1 << div2_en));
546
547 // Update real CPU Frequency
548 param->cpu_f = pll_freq / (1 << div2_cpu);
549 mul--;
550
551 scif_pll_opt_t opt;
552
553 opt.osc = SCIF_OSC0, // Sel Osc0 or Osc1
554 opt.lockcount = 16, // lockcount in main clock for the PLL wait lock
555 opt.div = div, // DIV=1 in the formula
556 opt.mul = mul, // MUL=7 in the formula
557 opt.pll_div2 = div2_en, // pll_div2 Divide the PLL output frequency by 2 (this settings does not change the FVCO value)
558 opt.pll_wbwdisable = 0, //pll_wbwdisable 1 Disable the Wide-Bandith Mode (Wide-Bandwith mode allow a faster startup time and out-of-lock time). 0 to enable the Wide-Bandith Mode.
559 opt.pll_freq = (pll_freq < AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ) ? 1 : 0, // Set to 1 for VCO frequency range 80-180MHz, set to 0 for VCO frequency range 160-240Mhz.
560
561
562 scif_pll_setup(SCIF_PLL0, &opt); // lockcount in main clock for the PLL wait lock
563
564 /* Enable PLL0 */
565 scif_pll_enable(SCIF_PLL0);
566
567 /* Wait for PLL0 locked */
568 scif_wait_for_pll_locked(SCIF_PLL0) ;
569
570 rest = pll_freq;
571 while (rest > AVR32_PM_PBA_MAX_FREQ ||
572 rest != param->pba_f)
573 {
574 div2_pba++;
575 rest = pll_freq / (1 << div2_pba);
576 if (rest < param->pba_f)
577 break;
578 }
579
580 // Update real PBA Frequency
581 param->pba_f = pll_freq / (1 << div2_pba);
582
583
584 if (div2_cpu)
585 {
586 b_div2_cpu = true;
587 div2_cpu--;
588 }
589 else
590 b_div2_cpu = false;
591
592 if (div2_pba)
593 {
594 b_div2_pba = true;
595 div2_pba--;
596 }
597 else
598 b_div2_pba = false;
599
600 if (b_div2_cpu == true )
601 {
602 pm_set_clk_domain_div(PM_CLK_DOMAIN_0, (pm_divratio_t) div2_cpu); // CPU
603 pm_set_clk_domain_div(PM_CLK_DOMAIN_1, (pm_divratio_t) div2_cpu); // HSB
604 pm_set_clk_domain_div(PM_CLK_DOMAIN_3, (pm_divratio_t) div2_cpu); // PBB
605 }
606 if (b_div2_pba == true )
607 {
608 pm_set_clk_domain_div(PM_CLK_DOMAIN_2, (pm_divratio_t) div2_pba); // PBA
609
610 }
611
612 // Set Flashc Wait State
613 flashcdw_set_flash_waitstate_and_readmode(param->cpu_f);
614
615 // Set the main clock source as being PLL0.
616 pm_set_mclk_source(PM_CLK_SRC_PLL0);
617
618 return PASS;
619 }
620 #endif // UC3D device-specific implementation
621
pcl_switch_to_osc(pcl_osc_t osc,unsigned int fcrystal,unsigned int startup)622 long int pcl_switch_to_osc(pcl_osc_t osc, unsigned int fcrystal, unsigned int startup)
623 {
624 #ifndef AVR32_PM_VERSION_RESETVALUE
625 // Implementation for UC3A, UC3A3, UC3B parts.
626 if(PCL_OSC0 == osc)
627 {
628 // Configure OSC0 in crystal mode, external crystal with a FOSC0 Hz frequency,
629 // enable the OSC0, set the main clock source as being OSC0.
630 pm_switch_to_osc0(&AVR32_PM, fcrystal, startup);
631 }
632 else
633 {
634 return PCL_NOT_SUPPORTED;
635 }
636 #else
637 // Implementation for UC3C, UC3L parts.
638 #if AVR32_PM_VERSION_RESETVALUE < 0x400
639 return PCL_NOT_SUPPORTED;
640 #else
641 if(PCL_OSC0 == osc)
642 {
643 // Configure OSC0 in crystal mode, external crystal with a fcrystal Hz frequency.
644 scif_configure_osc_crystalmode(SCIF_OSC0, fcrystal);
645 // Enable the OSC0
646 scif_enable_osc(SCIF_OSC0, startup, true);
647 // Set the Flash wait state and the speed read mode (depending on the target CPU frequency).
648 #if UC3L || UC3D
649 flashcdw_set_flash_waitstate_and_readmode(fcrystal);
650 #elif UC3C
651 flashc_set_flash_waitstate_and_readmode(fcrystal);
652 #endif
653 // Set the main clock source as being OSC0.
654 pm_set_mclk_source(PM_CLK_SRC_OSC0);
655 }
656 else
657 {
658 return PCL_NOT_SUPPORTED;
659 }
660 #endif
661 #endif
662 return PASS;
663 }
664
pcl_configure_usb_clock(void)665 long int pcl_configure_usb_clock(void)
666 {
667 #ifndef AVR32_PM_VERSION_RESETVALUE
668 // Implementation for UC3A, UC3A3, UC3B parts.
669 pm_configure_usb_clock();
670 return PASS;
671 #else
672 #if UC3C
673 const scif_pll_opt_t opt = {
674 .osc = SCIF_OSC0, // Sel Osc0 or Osc1
675 .lockcount = 16, // lockcount in main clock for the PLL wait lock
676 .div = 1, // DIV=1 in the formula
677 .mul = 5, // MUL=7 in the formula
678 .pll_div2 = 1, // pll_div2 Divide the PLL output frequency by 2 (this settings does not change the FVCO value)
679 .pll_wbwdisable = 0, //pll_wbwdisable 1 Disable the Wide-Bandith Mode (Wide-Bandwith mode allow a faster startup time and out-of-lock time). 0 to enable the Wide-Bandith Mode.
680 .pll_freq = 1, // Set to 1 for VCO frequency range 80-180MHz, set to 0 for VCO frequency range 160-240Mhz.
681 };
682
683 /* Setup PLL1 on Osc0, mul=7 ,no divisor, lockcount=16, ie. 16Mhzx6 = 96MHz output */
684 scif_pll_setup(SCIF_PLL1, &opt); // lockcount in main clock for the PLL wait lock
685
686 /* Enable PLL1 */
687 scif_pll_enable(SCIF_PLL1);
688
689 /* Wait for PLL1 locked */
690 scif_wait_for_pll_locked(SCIF_PLL1) ;
691
692 // Implementation for UC3C parts.
693 // Setup the generic clock for USB
694 scif_gc_setup(
695 #if (defined AVR32_USBB)
696 AVR32_SCIF_GCLK_USB,
697 #else
698 AVR32_SCIF_GCLK_USBC,
699 #endif
700 SCIF_GCCTRL_PLL1,
701 AVR32_SCIF_GC_NO_DIV_CLOCK,
702 0);
703 // Now enable the generic clock
704 scif_gc_enable(
705 #if (defined AVR32_USBB)
706 AVR32_SCIF_GCLK_USB
707 #else
708 AVR32_SCIF_GCLK_USBC
709 #endif
710 );
711 return PASS;
712 #else
713 return PCL_NOT_SUPPORTED;
714 #endif
715 #endif
716 }
717
718
719 #if UC3L
720 #else
pcl_write_gplp(unsigned long gplp,unsigned long value)721 void pcl_write_gplp(unsigned long gplp, unsigned long value)
722 {
723 #ifndef AVR32_PM_VERSION_RESETVALUE
724 // Implementation for UC3A, UC3A3, UC3B parts.
725 pm_write_gplp(&AVR32_PM,gplp,value);
726 #else
727 scif_write_gplp(gplp,value);
728 #endif
729 }
730
pcl_read_gplp(unsigned long gplp)731 unsigned long pcl_read_gplp(unsigned long gplp)
732 {
733 #ifndef AVR32_PM_VERSION_RESETVALUE
734 // Implementation for UC3A, UC3A3, UC3B parts.
735 return pm_read_gplp(&AVR32_PM,gplp);
736 #else
737 return scif_read_gplp(gplp);
738 #endif
739 }
740 #endif
741