Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #include "chip.h"
00077
00078 #include <assert.h>
00079
00080
00081
00082
00083
00084 #define MASK_STATUS0 0xFFFFFFFC
00085 #define MASK_STATUS1 0xFFFFFFFF
00086
00087
00088
00089
00090
00091
00092
00093 static void _PMC_SwitchMck2PllaClock(void)
00094
00095 {
00096
00097 PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_PLLA_CLK;
00098
00099
00100 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00101 }
00102
00103
00104
00105
00106 static void _PMC_SwitchMck2MainClock(void)
00107 {
00108
00109 PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
00110
00111
00112 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00113
00114 PMC->PMC_MCKR = PMC_MCKR_CSS_MAIN_CLK;
00115
00116 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00117 }
00118
00119
00120
00121
00122 static void _PMC_SwitchMck2SlowClock(void)
00123 {
00124
00125 PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_SLOW_CLK;
00126
00127
00128 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00129 }
00130
00131
00132
00133
00134
00135
00136 static void _PMC_SetMckPrescaler(uint32_t prescaler)
00137 {
00138
00139 PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_PRES_Msk) | prescaler;
00140
00141
00142 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 void PMC_EnablePeripheral(uint32_t dwId)
00157 {
00158 assert(dwId < 63);
00159
00160 if (dwId < 32) {
00161 if ((PMC->PMC_PCSR0 & ((uint32_t)1 << dwId)) == ((uint32_t)1 << dwId)) {
00162 TRACE_DEBUG("PMC_EnablePeripheral: clock of peripheral" \
00163 " %u is already enabled\n\r", (unsigned int)dwId);
00164 } else
00165 PMC->PMC_PCER0 = 1 << dwId;
00166 } else {
00167 dwId -= 32;
00168
00169 if ((PMC->PMC_PCSR1 & ((uint32_t)1 << dwId)) == ((uint32_t)1 << dwId)) {
00170 TRACE_DEBUG("PMC_EnablePeripheral: clock of peripheral" \
00171 " %u is already enabled\n\r", (unsigned int)(dwId + 32));
00172 } else
00173 PMC->PMC_PCER1 = 1 << dwId;
00174 }
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 void PMC_DisablePeripheral(uint32_t dwId)
00186 {
00187 assert(dwId < 63);
00188
00189 if (dwId < 32) {
00190 if ((PMC->PMC_PCSR0 & ((uint32_t)1 << dwId)) != ((uint32_t)1 << dwId)) {
00191 TRACE_DEBUG("PMC_DisablePeripheral: clock of peripheral" \
00192 " %u is not enabled\n\r", (unsigned int)dwId);
00193 } else
00194 PMC->PMC_PCDR0 = 1 << dwId;
00195 } else {
00196 dwId -= 32;
00197
00198 if ((PMC->PMC_PCSR1 & ((uint32_t)1 << dwId)) != ((uint32_t)1 << dwId)) {
00199 TRACE_DEBUG("PMC_DisablePeripheral: clock of peripheral"
00200 " %u is not enabled\n\r", (unsigned int)(dwId + 32));
00201 } else
00202 PMC->PMC_PCDR1 = 1 << dwId;
00203 }
00204 }
00205
00206
00207
00208
00209 void PMC_EnableAllPeripherals(void)
00210 {
00211 PMC->PMC_PCER0 = MASK_STATUS0;
00212
00213 while ((PMC->PMC_PCSR0 & MASK_STATUS0) != MASK_STATUS0);
00214
00215 PMC->PMC_PCER1 = MASK_STATUS1;
00216
00217 while ((PMC->PMC_PCSR1 & MASK_STATUS1) != MASK_STATUS1);
00218
00219 TRACE_DEBUG("Enable all periph clocks\n\r");
00220 }
00221
00222
00223
00224
00225 void PMC_DisableAllPeripherals(void)
00226 {
00227 PMC->PMC_PCDR0 = MASK_STATUS0;
00228
00229 while ((PMC->PMC_PCSR0 & MASK_STATUS0) != 0);
00230
00231 PMC->PMC_PCDR1 = MASK_STATUS1;
00232
00233 while ((PMC->PMC_PCSR1 & MASK_STATUS1) != 0);
00234
00235 TRACE_DEBUG("Disable all periph clocks\n\r");
00236 }
00237
00238
00239
00240
00241
00242
00243 uint32_t PMC_IsPeriphEnabled(uint32_t dwId)
00244 {
00245 assert(dwId < ID_PERIPH_COUNT);
00246
00247 if (dwId < 32)
00248 return (PMC->PMC_PCSR0 & (1 << dwId));
00249 else
00250 return (PMC->PMC_PCSR1 & (1 << (dwId - 32)));
00251 }
00252
00253
00254
00255
00256
00257 void PMC_EnableExtOsc(void)
00258 {
00259 uint32_t read_MOR;
00260
00261
00262
00263
00264
00265 read_MOR = PMC->CKGR_MOR;
00266 read_MOR &= ~CKGR_MOR_MOSCRCF_Msk;
00267
00268 read_MOR |= (CKGR_MOR_KEY_PASSWD
00269 | CKGR_MOR_MOSCRCF_12_MHz
00270 | CKGR_MOR_MOSCXTEN
00271 | CKGR_MOR_MOSCRCEN
00272 | CKGR_MOR_MOSCXTST(DEFAUTL_MAIN_OSC_COUNT));
00273
00274
00275 PMC->CKGR_MOR = read_MOR;
00276
00277 while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));
00278
00279
00280 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00281
00282 read_MOR |= CKGR_MOR_MOSCSEL;
00283
00284
00285 PMC->CKGR_MOR = read_MOR;
00286
00287 while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
00288
00289
00290 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00291 }
00292
00293
00294
00295
00296 void PMC_DisableExtOsc(void)
00297 {
00298 uint32_t read_MOR;
00299
00300 read_MOR = PMC->CKGR_MOR;
00301 read_MOR &= ~CKGR_MOR_MOSCXTEN;
00302 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | read_MOR;
00303
00304 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00305 }
00306
00307
00308
00309
00310 void PMC_SelectExtOsc(void)
00311 {
00312
00313
00314 if ((PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) == CKGR_MOR_MOSCSEL) {
00315 PMC_DisableIntRC4_8_12MHz();
00316 return;
00317 }
00318
00319
00320 PMC->CKGR_MOR |= CKGR_MOR_MOSCXTEN | CKGR_MOR_KEY_PASSWD;
00321
00322
00323 while (!(PMC->CKGR_MCFR & CKGR_MCFR_MAINFRDY));
00324
00325
00326 PMC->CKGR_MOR |= CKGR_MOR_MOSCSEL | CKGR_MOR_KEY_PASSWD;
00327
00328
00329 while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
00330
00331
00332 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00333
00334 PMC_DisableIntRC4_8_12MHz();
00335 }
00336
00337
00338
00339
00340
00341 void PMC_SelectExtBypassOsc(void)
00342 {
00343 volatile uint32_t timeout;
00344
00345 if ((PMC->CKGR_MOR & CKGR_MOR_MOSCXTBY) != CKGR_MOR_MOSCXTBY) {
00346 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD |
00347 CKGR_MOR_MOSCRCEN |
00348 CKGR_MOR_MOSCXTST(0xFF) |
00349 CKGR_MOR_MOSCXTBY;
00350 PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCSEL;
00351
00352
00353 while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
00354
00355
00356 for (timeout = 0; timeout < 0xffff; timeout++);
00357
00358 while (!(PMC->CKGR_MCFR & CKGR_MCFR_MAINFRDY));
00359 }
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 void PMC_EnableIntRC4_8_12MHz(uint32_t freqSelect)
00369 {
00370
00371 PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN);
00372
00373
00374 while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));
00375
00376
00377 PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) |
00378 CKGR_MOR_KEY_PASSWD | freqSelect;
00379
00380
00381 while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));
00382
00383
00384 PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) |
00385 CKGR_MOR_KEY_PASSWD;
00386
00387
00388 while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
00389
00390
00391 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00392
00393 }
00394
00395
00396
00397
00398 void PMC_DisableIntRC4_8_12MHz(void)
00399 {
00400 uint32_t read_MOR;
00401
00402 read_MOR = PMC->CKGR_MOR;
00403
00404 read_MOR &= ~CKGR_MOR_MOSCRCF_Msk;
00405 read_MOR &= ~CKGR_MOR_MOSCRCEN;
00406 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | read_MOR;
00407
00408 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418 void PMC_SetPllaClock(uint32_t mul, uint32_t div)
00419 {
00420 if (mul != 0) {
00421
00422 PMC->CKGR_PLLAR = CKGR_PLLAR_ONE
00423 | CKGR_PLLAR_PLLACOUNT(DEFAUTL_PLLA_COUNT)
00424 | CKGR_PLLAR_MULA(mul - 1)
00425 | CKGR_PLLAR_DIVA(div);
00426
00427
00428 while (!(PMC->PMC_SR & PMC_SR_LOCKA));
00429 } else {
00430 PMC->CKGR_PLLAR = CKGR_PLLAR_ONE;
00431 }
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 void PMC_SetMckSelection(uint32_t clockSource, uint32_t prescaler)
00445 {
00446 switch (clockSource) {
00447 case PMC_MCKR_CSS_SLOW_CLK :
00448 _PMC_SwitchMck2SlowClock();
00449 _PMC_SetMckPrescaler(prescaler);
00450 break;
00451
00452 case PMC_MCKR_CSS_MAIN_CLK :
00453 _PMC_SwitchMck2MainClock();
00454 _PMC_SetMckPrescaler(prescaler);
00455 break;
00456
00457 case PMC_MCKR_CSS_PLLA_CLK :
00458 _PMC_SetMckPrescaler(prescaler);
00459 _PMC_SwitchMck2PllaClock();
00460 break;
00461 }
00462 }
00463
00464
00465
00466
00467 void PMC_DisableAllClocks(void)
00468 {
00469 uint32_t read_reg;
00470
00471 PMC->PMC_SCDR = PMC_SCDR_PCK0 | PMC_SCDR_PCK1 | PMC_SCDR_PCK2 | PMC_SCDR_PCK3 |
00472 PMC_SCDR_PCK4 | PMC_SCDR_PCK5 | PMC_SCDR_PCK6;
00473
00474 _PMC_SwitchMck2MainClock();
00475
00476 PMC->CKGR_PLLAR = PMC->CKGR_PLLAR & ~CKGR_PLLAR_MULA_Msk;
00477
00478 _PMC_SwitchMck2SlowClock();
00479
00480 read_reg = PMC->CKGR_MOR;
00481 read_reg = (read_reg & ~CKGR_MOR_MOSCRCEN) | CKGR_MOR_KEY_PASSWD;
00482
00483
00484 PMC->CKGR_MOR = read_reg;
00485
00486 PMC_DisableAllPeripherals();
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496 void PMC_ConfigureMckWithPlla(uint32_t mul, uint32_t div, uint32_t prescaler)
00497 {
00498
00499 _PMC_SwitchMck2MainClock();
00500
00501
00502 PMC_SetPllaClock(mul, div);
00503
00504
00505
00506 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
00507
00508
00509 PMC_SetMckSelection(PMC_MCKR_CSS_PLLA_CLK, prescaler);
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 void PMC_EnableXT32KFME(void)
00521 {
00522
00523 uint32_t read_MOR;
00524
00525
00526
00527
00528
00529 read_MOR = PMC->CKGR_MOR;
00530
00531 read_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_XT32KFME);
00532
00533
00534 PMC->CKGR_MOR = read_MOR;
00535
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545 void PMC_ConfigurePCK0(uint32_t MasterClk, uint32_t prescaler)
00546 {
00547 PMC->PMC_SCDR = PMC_SCDR_PCK0;
00548
00549 while ((PMC->PMC_SCSR)& PMC_SCSR_PCK0);
00550
00551 PMC->PMC_PCK[0] = MasterClk | prescaler;
00552 PMC->PMC_SCER = PMC_SCER_PCK0;
00553
00554 while (!((PMC->PMC_SR) & PMC_SR_PCKRDY0));
00555
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 void PMC_ConfigurePCK1(uint32_t MasterClk, uint32_t prescaler)
00567 {
00568 PMC->PMC_SCDR = PMC_SCDR_PCK1;
00569
00570 while ((PMC->PMC_SCSR)& PMC_SCSR_PCK1);
00571
00572 PMC->PMC_PCK[1] = MasterClk | prescaler;
00573 PMC->PMC_SCER = PMC_SCER_PCK1;
00574
00575 while (!((PMC->PMC_SR) & PMC_SR_PCKRDY1));
00576
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586 void PMC_ConfigurePCK2(uint32_t MasterClk, uint32_t prescaler)
00587 {
00588 PMC->PMC_SCDR = PMC_SCDR_PCK2;
00589
00590 while ((PMC->PMC_SCSR)& PMC_SCSR_PCK2);
00591
00592 PMC->PMC_PCK[2] = MasterClk | prescaler;
00593 PMC->PMC_SCER = PMC_SCER_PCK2;
00594
00595 while (!((PMC->PMC_SR) & PMC_SR_PCKRDY2));
00596
00597 }