1 //###########################################################################
2 //
3 // FILE: F2837xD_SysCtrl.c
4 //
5 // TITLE: F2837xD Device System Control Initialization & Support Functions.
6 //
7 // DESCRIPTION:
8 //
9 // Example initialization of system resources.
10 //
11 //###########################################################################
12 // $TI Release: F2837xD Support Library v3.05.00.00 $
13 // $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
14 // $Copyright:
15 // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
16 //
17 // Redistribution and use in source and binary forms, with or without
18 // modification, are permitted provided that the following conditions
19 // are met:
20 //
21 // Redistributions of source code must retain the above copyright
22 // notice, this list of conditions and the following disclaimer.
23 //
24 // Redistributions in binary form must reproduce the above copyright
25 // notice, this list of conditions and the following disclaimer in the
26 // documentation and/or other materials provided with the
27 // distribution.
28 //
29 // Neither the name of Texas Instruments Incorporated nor the names of
30 // its contributors may be used to endorse or promote products derived
31 // from this software without specific prior written permission.
32 //
33 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
36 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
37 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
39 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
40 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
41 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
43 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 // $
45 //###########################################################################
46
47 //
48 // Included Files
49 //
50 #include "F2837xD_device.h"
51 #include "F2837xD_Examples.h"
52 #ifdef __cplusplus
53 using std::memcpy;
54 #endif
55
56 #define STATUS_FAIL 0
57 #define STATUS_SUCCESS 1
58 #define TMR1SYSCLKCTR 0xF0000000
59 #define TMR2INPCLKCTR 0x800
60
61 //
62 // Functions that will be run from RAM need to be assigned to a different
63 // section. This section will then be mapped to a load and run address using
64 // the linker cmd file.
65 //
66 // *IMPORTANT*
67 //
68 // IF RUNNING FROM FLASH, PLEASE COPY OVER THE SECTION ".TI.ramfunc" FROM
69 // FLASH TO RAM PRIOR TO CALLING InitSysCtrl(). THIS PREVENTS THE MCU FROM
70 // THROWING AN EXCEPTION WHEN A CALL TO DELAY_US() IS MADE.
71 //
72 #ifndef __cplusplus
73 #ifdef __TI_COMPILER_VERSION__
74 #if __TI_COMPILER_VERSION__ >= 15009000
75 #pragma CODE_SECTION(InitFlash, ".TI.ramfunc");
76 #pragma CODE_SECTION(FlashOff, ".TI.ramfunc");
77 #else
78 #pragma CODE_SECTION(InitFlash, "ramfuncs");
79 #pragma CODE_SECTION(FlashOff, "ramfuncs");
80 #endif
81 #endif
82 #endif
83
84 //
85 // InitSysCtrl - Initialization of system resources.
86 //
InitSysCtrl(void)87 void InitSysCtrl(void)
88 {
89 //
90 // Disable the watchdog
91 //
92 DisableDog();
93
94 #ifdef _FLASH
95 //
96 // Copy time critical code and Flash setup code to RAM. This includes the
97 // following functions: InitFlash()
98 //
99 // The RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart
100 // symbols are created by the linker. Refer to the device .cmd file.
101 //
102 memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
103
104 //
105 // Call Flash Initialization to setup flash waitstates. This function must
106 // reside in RAM.
107 //
108 InitFlash();
109 #endif
110
111 //
112 // *IMPORTANT*
113 //
114 // The Device_cal function, which copies the ADC & oscillator calibration
115 // values from TI reserved OTP into the appropriate trim registers, occurs
116 // automatically in the Boot ROM. If the boot ROM code is bypassed during
117 // the debug process, the following function MUST be called for the ADC and
118 // oscillators to function according to specification. The clocks to the
119 // ADC MUST be enabled before calling this function.
120 //
121 // See the device data manual and/or the ADC Reference Manual for more
122 // information.
123 //
124 #ifdef CPU1
125 EALLOW;
126
127 //
128 // Enable pull-ups on unbonded IOs as soon as possible to reduce power
129 // consumption.
130 //
131 GPIO_EnableUnbondedIOPullups();
132
133 CpuSysRegs.PCLKCR13.bit.ADC_A = 1;
134 CpuSysRegs.PCLKCR13.bit.ADC_B = 1;
135 CpuSysRegs.PCLKCR13.bit.ADC_C = 1;
136 CpuSysRegs.PCLKCR13.bit.ADC_D = 1;
137
138 //
139 // Check if device is trimmed
140 //
141 if(*((Uint16 *)0x5D1B6) == 0x0000){
142 //
143 // Device is not trimmed--apply static calibration values
144 //
145 AnalogSubsysRegs.ANAREFTRIMA.all = 31709;
146 AnalogSubsysRegs.ANAREFTRIMB.all = 31709;
147 AnalogSubsysRegs.ANAREFTRIMC.all = 31709;
148 AnalogSubsysRegs.ANAREFTRIMD.all = 31709;
149 }
150
151 CpuSysRegs.PCLKCR13.bit.ADC_A = 0;
152 CpuSysRegs.PCLKCR13.bit.ADC_B = 0;
153 CpuSysRegs.PCLKCR13.bit.ADC_C = 0;
154 CpuSysRegs.PCLKCR13.bit.ADC_D = 0;
155 EDIS;
156
157 //
158 // Initialize the PLL control: SYSPLLMULT and SYSCLKDIVSEL.
159 //
160 // Defined options to be passed as arguments to this function are defined
161 // in F2837xD_Examples.h.
162 //
163 // Note: The internal oscillator CANNOT be used as the PLL source if the
164 // PLLSYSCLK is configured to frequencies above 194 MHz.
165 //
166 // PLLSYSCLK = (XTAL_OSC) * (IMULT + FMULT) / (PLLSYSCLKDIV)
167 //
168 #ifdef _LAUNCHXL_F28379D
169 InitSysPll(XTAL_OSC,IMULT_40,FMULT_0,PLLCLK_BY_2);
170 #else
171 InitSysPll(XTAL_OSC, IMULT_20, FMULT_0, PLLCLK_BY_2);
172 #endif // _LAUNCHXL_F28379D
173
174 #endif // CPU1
175
176 //
177 // Turn on all peripherals
178 //
179 InitPeripheralClocks();
180 }
181
182 //
183 // InitPeripheralClocks - Initializes the clocks for the peripherals.
184 //
185 // Note: In order to reduce power consumption, turn off the clocks to any
186 // peripheral that is not specified for your part-number or is not used in the
187 // application
188 //
InitPeripheralClocks(void)189 void InitPeripheralClocks(void)
190 {
191 EALLOW;
192
193 CpuSysRegs.PCLKCR0.bit.CLA1 = 1;
194 CpuSysRegs.PCLKCR0.bit.DMA = 1;
195 CpuSysRegs.PCLKCR0.bit.CPUTIMER0 = 1;
196 CpuSysRegs.PCLKCR0.bit.CPUTIMER1 = 1;
197 CpuSysRegs.PCLKCR0.bit.CPUTIMER2 = 1;
198
199 #ifdef CPU1
200 CpuSysRegs.PCLKCR0.bit.HRPWM = 1;
201 #endif
202
203 CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
204
205 #ifdef CPU1
206 CpuSysRegs.PCLKCR1.bit.EMIF1 = 1;
207 CpuSysRegs.PCLKCR1.bit.EMIF2 = 1;
208 #endif
209
210 CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;
211 CpuSysRegs.PCLKCR2.bit.EPWM2 = 1;
212 CpuSysRegs.PCLKCR2.bit.EPWM3 = 1;
213 CpuSysRegs.PCLKCR2.bit.EPWM4 = 1;
214 CpuSysRegs.PCLKCR2.bit.EPWM5 = 1;
215 CpuSysRegs.PCLKCR2.bit.EPWM6 = 1;
216 CpuSysRegs.PCLKCR2.bit.EPWM7 = 1;
217 CpuSysRegs.PCLKCR2.bit.EPWM8 = 1;
218 CpuSysRegs.PCLKCR2.bit.EPWM9 = 1;
219 CpuSysRegs.PCLKCR2.bit.EPWM10 = 1;
220 CpuSysRegs.PCLKCR2.bit.EPWM11 = 1;
221 CpuSysRegs.PCLKCR2.bit.EPWM12 = 1;
222
223 CpuSysRegs.PCLKCR3.bit.ECAP1 = 1;
224 CpuSysRegs.PCLKCR3.bit.ECAP2 = 1;
225 CpuSysRegs.PCLKCR3.bit.ECAP3 = 1;
226 CpuSysRegs.PCLKCR3.bit.ECAP4 = 1;
227 CpuSysRegs.PCLKCR3.bit.ECAP5 = 1;
228 CpuSysRegs.PCLKCR3.bit.ECAP6 = 1;
229
230 CpuSysRegs.PCLKCR4.bit.EQEP1 = 1;
231 CpuSysRegs.PCLKCR4.bit.EQEP2 = 1;
232 CpuSysRegs.PCLKCR4.bit.EQEP3 = 1;
233
234 CpuSysRegs.PCLKCR6.bit.SD1 = 1;
235 CpuSysRegs.PCLKCR6.bit.SD2 = 1;
236
237 CpuSysRegs.PCLKCR7.bit.SCI_A = 1;
238 CpuSysRegs.PCLKCR7.bit.SCI_B = 1;
239 CpuSysRegs.PCLKCR7.bit.SCI_C = 1;
240 CpuSysRegs.PCLKCR7.bit.SCI_D = 1;
241
242 CpuSysRegs.PCLKCR8.bit.SPI_A = 1;
243 CpuSysRegs.PCLKCR8.bit.SPI_B = 1;
244 CpuSysRegs.PCLKCR8.bit.SPI_C = 1;
245
246 CpuSysRegs.PCLKCR9.bit.I2C_A = 1;
247 CpuSysRegs.PCLKCR9.bit.I2C_B = 1;
248
249 CpuSysRegs.PCLKCR10.bit.CAN_A = 1;
250 CpuSysRegs.PCLKCR10.bit.CAN_B = 1;
251
252 CpuSysRegs.PCLKCR11.bit.McBSP_A = 1;
253 CpuSysRegs.PCLKCR11.bit.McBSP_B = 1;
254
255 #ifdef CPU1
256 CpuSysRegs.PCLKCR11.bit.USB_A = 1;
257
258 CpuSysRegs.PCLKCR12.bit.uPP_A = 1;
259 #endif
260
261 CpuSysRegs.PCLKCR13.bit.ADC_A = 1;
262 CpuSysRegs.PCLKCR13.bit.ADC_B = 1;
263 CpuSysRegs.PCLKCR13.bit.ADC_C = 1;
264 CpuSysRegs.PCLKCR13.bit.ADC_D = 1;
265
266 CpuSysRegs.PCLKCR14.bit.CMPSS1 = 1;
267 CpuSysRegs.PCLKCR14.bit.CMPSS2 = 1;
268 CpuSysRegs.PCLKCR14.bit.CMPSS3 = 1;
269 CpuSysRegs.PCLKCR14.bit.CMPSS4 = 1;
270 CpuSysRegs.PCLKCR14.bit.CMPSS5 = 1;
271 CpuSysRegs.PCLKCR14.bit.CMPSS6 = 1;
272 CpuSysRegs.PCLKCR14.bit.CMPSS7 = 1;
273 CpuSysRegs.PCLKCR14.bit.CMPSS8 = 1;
274
275 CpuSysRegs.PCLKCR16.bit.DAC_A = 1;
276 CpuSysRegs.PCLKCR16.bit.DAC_B = 1;
277 CpuSysRegs.PCLKCR16.bit.DAC_C = 1;
278
279 EDIS;
280 }
281
282 //
283 // DisablePeripheralClocks - Gates-off all peripheral clocks.
284 //
DisablePeripheralClocks(void)285 void DisablePeripheralClocks(void)
286 {
287 EALLOW;
288
289 CpuSysRegs.PCLKCR0.all = 0;
290 CpuSysRegs.PCLKCR1.all = 0;
291 CpuSysRegs.PCLKCR2.all = 0;
292 CpuSysRegs.PCLKCR3.all = 0;
293 CpuSysRegs.PCLKCR4.all = 0;
294 CpuSysRegs.PCLKCR6.all = 0;
295 CpuSysRegs.PCLKCR7.all = 0;
296 CpuSysRegs.PCLKCR8.all = 0;
297 CpuSysRegs.PCLKCR9.all = 0;
298 CpuSysRegs.PCLKCR10.all = 0;
299 CpuSysRegs.PCLKCR11.all = 0;
300 CpuSysRegs.PCLKCR12.all = 0;
301 CpuSysRegs.PCLKCR13.all = 0;
302 CpuSysRegs.PCLKCR14.all = 0;
303 CpuSysRegs.PCLKCR16.all = 0;
304
305 EDIS;
306 }
307
308 //
309 // InitFlash - This function initializes the Flash Control registers.
310 //
311 // *CAUTION*
312 // This function MUST be executed out of RAM. Executing it out of OTP/Flash
313 // will yield unpredictable results.
314 //
315 #ifdef __cplusplus
316 #ifdef __TI_COMPILER_VERSION__
317 #if __TI_COMPILER_VERSION__ >= 15009000
318 #pragma CODE_SECTION(".TI.ramfunc");
319 #else
320 #pragma CODE_SECTION("ramfuncs");
321 #endif
322 #endif
323 #endif
InitFlash(void)324 void InitFlash(void)
325 {
326 EALLOW;
327
328 //
329 // The default value of VREADST is good enough for the flash to power up
330 // properly at the INTOSC frequency. Below VREADST configuration covers up
331 // to the max frequency possible for this device. This is required for
332 // proper flash wake up at the higher frequencies if users put it to sleep
333 // for power saving reason.
334 //
335 Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
336
337 //
338 // At reset bank and pump are in sleep. A Flash access will power up the
339 // bank and pump automatically.
340 //
341 // After a Flash access, bank and pump go to low power mode (configurable
342 // in FBFALLBACK/FPAC1 registers) if there is no further access to flash.
343 //
344 // Power up Flash bank and pump. This also sets the fall back mode of
345 // flash and pump as active.
346 //
347 Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0x1;
348 Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0x3;
349
350 //
351 // Disable Cache and prefetch mechanism before changing wait states
352 //
353 Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 0;
354 Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 0;
355
356 //
357 // Set waitstates according to frequency
358 //
359 // *CAUTION*
360 // Minimum waitstates required for the flash operating at a given CPU rate
361 // must be characterized by TI. Refer to the datasheet for the latest
362 // information.
363 //
364 #if CPU_FRQ_200MHZ
365 Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
366 #endif
367
368 #if CPU_FRQ_150MHZ
369 Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
370 #endif
371
372 #if CPU_FRQ_120MHZ
373 Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
374 #endif
375
376 //
377 // Enable Cache and prefetch mechanism to improve performance of code
378 // executed from Flash.
379 //
380 Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 1;
381 Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 1;
382
383 //
384 // At reset, ECC is enabled. If it is disabled by application software and
385 // if application again wants to enable ECC.
386 //
387 Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
388
389 EDIS;
390
391 //
392 // Force a pipeline flush to ensure that the write to the last register
393 // configured occurs before returning.
394 //
395 __asm(" RPT #7 || NOP");
396 }
397
398 //
399 // FlashOff - This function powers down the flash
400 //
401 // *CAUTION*
402 // This function MUST be executed out of RAM. Executing it out of OTP/Flash
403 // will yield unpredictable results. Also you must seize the flash pump in
404 // order to power it down.
405 //
406 #ifdef __cplusplus
407 #ifdef __TI_COMPILER_VERSION__
408 #if __TI_COMPILER_VERSION__ >= 15009000
409 #pragma CODE_SECTION(".TI.ramfunc");
410 #else
411 #pragma CODE_SECTION("ramfuncs");
412 #endif
413 #endif
414 #endif
FlashOff(void)415 void FlashOff(void)
416 {
417 EALLOW;
418
419 //
420 // Set VREADST to the proper value for the flash banks to power up properly
421 //
422 Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
423
424 //
425 // Power down bank
426 //
427 Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0;
428
429 //
430 // Power down pump
431 //
432 Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0;
433
434 EDIS;
435 }
436
437 //
438 // SeizeFlashPump - Wait until the flash pump is available. Then take control
439 // of it using the flash pump Semaphore.
440 //
SeizeFlashPump(void)441 void SeizeFlashPump(void)
442 {
443 EALLOW;
444 #ifdef CPU1
445 while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x2)
446 {
447 FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x2;
448 }
449 #elif defined(CPU2)
450 while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x1)
451 {
452 FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x1;
453 }
454 #endif
455 EDIS;
456 }
457
458 //
459 // ReleaseFlashPump - Release control of the flash pump using the flash pump
460 // semaphore.
461 //
ReleaseFlashPump(void)462 void ReleaseFlashPump(void)
463 {
464 EALLOW;
465 FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x0;
466 EDIS;
467 }
468
469 //
470 // ServiceDog - This function resets the watchdog timer.
471 //
472 // Enable this function for using ServiceDog in the application.
473 //
ServiceDog(void)474 void ServiceDog(void)
475 {
476 EALLOW;
477 WdRegs.WDKEY.bit.WDKEY = 0x0055;
478 WdRegs.WDKEY.bit.WDKEY = 0x00AA;
479 EDIS;
480 }
481
482 //
483 // DisableDog - This function disables the watchdog timer.
484 //
DisableDog(void)485 void DisableDog(void)
486 {
487 volatile Uint16 temp;
488
489 //
490 // Grab the clock config first so we don't clobber it
491 //
492 EALLOW;
493 temp = WdRegs.WDCR.all & 0x0007;
494 WdRegs.WDCR.all = 0x0068 | temp;
495 EDIS;
496 }
497
498 #ifdef CPU1
499 //
500 // InitSysPll()
501 // This function initializes the PLL registers.
502 // Note:
503 // - The internal oscillator CANNOT be used as the PLL source if the
504 // PLLSYSCLK is configured to frequencies above 194 MHz.
505 //
506 // - This function uses the Watchdog as a monitor for the PLL. The user
507 // watchdog settings will be modified and restored upon completion. Function
508 // allows for a minimum re lock attempt for 5 tries. Re lock attempt is carried
509 // out if either SLIP condition occurs or SYSCLK to Input Clock ratio is off by 10%
510 //
511 // - This function uses the following resources to support PLL initialization:
512 // o Watchdog
513 // o CPU Timer 1
514 // o CPU Timer 2
515 //
InitSysPll(Uint16 clock_source,Uint16 imult,Uint16 fmult,Uint16 divsel)516 void InitSysPll(Uint16 clock_source, Uint16 imult, Uint16 fmult, Uint16 divsel)
517 {
518 Uint16 SCSR, WDCR, WDWCR, intStatus, t1TCR, t1TPR, t1TPRH;
519 Uint16 t2TCR, t2TPR, t2TPRH, t2SRC, t2Prescale;
520 Uint32 t1PRD, t2PRD, ctr1;
521 float sysclkToInClkError, mult, div;
522 bool sysclkInvalidFreq=true;
523
524 if((clock_source == ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL) &&
525 (imult == ClkCfgRegs.SYSPLLMULT.bit.IMULT) &&
526 (fmult == ClkCfgRegs.SYSPLLMULT.bit.FMULT) &&
527 (divsel == ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV))
528 {
529 //
530 // Everything is set as required, so just return
531 //
532 return;
533 }
534
535 if(clock_source != ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL)
536 {
537 switch (clock_source)
538 {
539 case INT_OSC1:
540 SysIntOsc1Sel();
541 break;
542
543 case INT_OSC2:
544 SysIntOsc2Sel();
545 break;
546
547 case XTAL_OSC:
548 SysXtalOscSel();
549 break;
550 }
551 }
552
553 EALLOW;
554 if(imult != ClkCfgRegs.SYSPLLMULT.bit.IMULT ||
555 fmult != ClkCfgRegs.SYSPLLMULT.bit.FMULT)
556 {
557 Uint16 i;
558
559 //
560 // This bit is reset only by POR
561 //
562 if(DevCfgRegs.SYSDBGCTL.bit.BIT_0 == 1)
563 {
564 //
565 // The user can optionally insert handler code here. This will only
566 // be executed if a watchdog reset occurred after a failed system
567 // PLL initialization. See your device user's guide for more
568 // information.
569 //
570 // If the application has a watchdog reset handler, this bit should
571 // be checked to determine if the watchdog reset occurred because
572 // of the PLL.
573 //
574 // No action here will continue with retrying the PLL as normal.
575 //
576 // Failed PLL initialization is due to any of the following:
577 // - No PLL clock
578 // - SLIP condition
579 // - Wrong Frequency
580 //
581 }
582
583 //
584 // Bypass PLL and set dividers to /1
585 //
586 ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
587 asm(" RPT #20 || NOP");
588 ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = 0;
589
590 //
591 // Lock the PLL five times. This helps ensure a successful start.
592 // Five is the minimum recommended number. The user can increase this
593 // number according to allotted system initialization time.
594 //
595 for(i = 0; i < 5; i++)
596 {
597 //
598 // Turn off PLL
599 //
600 ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
601 asm(" RPT #20 || NOP");
602
603 //
604 // Write multiplier, which automatically turns on the PLL
605 //
606 ClkCfgRegs.SYSPLLMULT.all = ((fmult << 8U) | imult);
607
608 //
609 // Wait for the SYSPLL lock counter
610 //
611 while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1)
612 {
613 //
614 // Uncomment to service the watchdog
615 //
616 // ServiceDog();
617 }
618 }
619 }
620
621 //
622 // Set divider to produce slower output frequency to limit current increase
623 //
624 if(divsel != PLLCLK_BY_126)
625 {
626 ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel + 1;
627 }
628 else
629 {
630 ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel;
631 }
632
633 //
634 // *CAUTION*
635 // It is recommended to use the following watchdog code to monitor the PLL
636 // startup sequence. If your application has already cleared the watchdog
637 // SCRS[WDOVERRIDE] bit this cannot be done. It is recommended not to clear
638 // this bit until after the PLL has been initiated.
639 //
640
641 //
642 // Backup User Watchdog
643 //
644 SCSR = WdRegs.SCSR.all;
645 WDCR = WdRegs.WDCR.all;
646 WDWCR = WdRegs.WDWCR.all;
647
648 //
649 // Disable windowed functionality, reset counter
650 //
651 EALLOW;
652 WdRegs.WDWCR.all = 0x0;
653 WdRegs.WDKEY.bit.WDKEY = 0x55;
654 WdRegs.WDKEY.bit.WDKEY = 0xAA;
655
656 //
657 // Disable global interrupts
658 //
659 intStatus = __disable_interrupts();
660
661 //
662 // Configure for watchdog reset and to run at max frequency
663 //
664 WdRegs.SCSR.all = 0x0;
665 WdRegs.WDCR.all = 0x28;
666
667 //
668 // This bit is reset only by power-on-reset (POR) and will not be cleared
669 // by a WD reset
670 //
671 DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 1;
672
673 //
674 // Enable PLLSYSCLK is fed from system PLL clock
675 //
676 ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1;
677
678 //
679 // Delay to ensure system is clocking from PLL prior to clearing status bit
680 //
681 asm(" RPT #20 || NOP");
682
683 //
684 // Service watchdog
685 //
686 ServiceDog();
687
688 //
689 // Slip Bit Monitor and SYSCLK Frequency Check using timers
690 // Re-lock routine for SLIP condition or if SYSCLK and CLKSRC timer counts
691 // are off by +/- 10%.
692 // At a minimum, SYSCLK check is performed. Re lock attempt is carried out
693 // if SLIPS bit is set. This while loop is monitored by watchdog.
694 // In the event that the PLL does not successfully lock, the loop will be
695 // aborted by watchdog reset.
696 //
697 EALLOW;
698 while(sysclkInvalidFreq == true)
699 {
700 if(ClkCfgRegs.SYSPLLSTS.bit.SLIPS == 1)
701 {
702 //
703 // Bypass PLL
704 //
705 ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
706 asm(" RPT #20 || NOP");
707
708 //
709 // Turn off PLL
710 //
711 ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
712 asm(" RPT #20 || NOP");
713
714 //
715 // Write multipliers, which automatically turns on the PLL
716 //
717 ClkCfgRegs.SYSPLLMULT.all = ((fmult << 8U) | imult);
718
719 //
720 // Wait for the SYSPLL lock counter to expire
721 //
722 while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1);
723
724 //
725 // Enable PLLSYSCLK is fed from system PLL clock
726 //
727 ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1;
728
729 //
730 // Delay to ensure system is clocking from PLL
731 //
732 asm(" RPT #20 || NOP");
733 }
734
735 //
736 // Backup timer1 and timer2 settings
737 //
738 t1TCR = CpuTimer1Regs.TCR.all;
739 t1PRD = CpuTimer1Regs.PRD.all;
740 t1TPR = CpuTimer1Regs.TPR.all;
741 t1TPRH = CpuTimer1Regs.TPRH.all;
742 t2SRC = CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL;
743 t2Prescale = CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE;
744 t2TCR = CpuTimer2Regs.TCR.all;
745 t2PRD = CpuTimer2Regs.PRD.all;
746 t2TPR = CpuTimer2Regs.TPR.all;
747 t2TPRH = CpuTimer2Regs.TPRH.all;
748
749 //
750 // Set up timers 1 and 2
751 // Configure timer1 to count SYSCLK cycles
752 //
753 CpuTimer1Regs.TCR.bit.TSS = 1; // stop timer1
754 CpuTimer1Regs.PRD.all = TMR1SYSCLKCTR; // seed timer1 counter
755 CpuTimer1Regs.TPR.bit.TDDR = 0x0; // sysclock divider
756 CpuTimer1Regs.TCR.bit.TRB = 1; // reload timer with value in PRD
757 CpuTimer1Regs.TCR.bit.TIF = 1; // clear interrupt flag
758 CpuTimer1Regs.TCR.bit.TIE = 1; // enable interrupt
759
760 //
761 // Configure timer2 to count Input clock cycles
762 //
763 switch(clock_source)
764 {
765 case INT_OSC1:
766 // Clk Src = INT_OSC1
767 CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = 0x1;
768 break;
769 case INT_OSC2:
770 // Clk Src = INT_OSC2
771 CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = 0x2;
772 break;
773 case XTAL_OSC:
774 // Clk Src = XTAL
775 CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = 0x3;
776 break;
777
778 }
779 CpuTimer2Regs.TCR.bit.TIF = 1; // clear interrupt flag
780 CpuTimer2Regs.TCR.bit.TIE = 1; // enable interrupt
781 CpuTimer2Regs.TCR.bit.TSS = 1; // stop timer2
782 CpuTimer2Regs.PRD.all = TMR2INPCLKCTR; // seed timer2 counter
783 CpuTimer2Regs.TPR.bit.TDDR = 0x0; // sysclock divider
784 CpuTimer2Regs.TCR.bit.TRB = 1; // reload timer with value in PRD
785
786 //
787 // Stop/Start timer counters
788 //
789 CpuTimer1Regs.TCR.bit.TSS = 1; // stop timer1
790 CpuTimer2Regs.TCR.bit.TSS = 1; // stop timer2
791 CpuTimer1Regs.TCR.bit.TRB = 1; // reload timer1 with value in PRD
792 CpuTimer2Regs.TCR.bit.TRB = 1; // reload timer2 with value in PRD
793 CpuTimer2Regs.TCR.bit.TIF = 1; // clear timer2 interrupt flag
794 CpuTimer2Regs.TCR.bit.TSS = 0; // start timer2
795 CpuTimer1Regs.TCR.bit.TSS = 0; // start timer1
796
797 //
798 // Stop timers if either timer1 or timer2 counters overflow
799 //
800 while((CpuTimer2Regs.TCR.bit.TIF == 0) && (CpuTimer1Regs.TCR.bit.TIF == 0));
801
802 CpuTimer1Regs.TCR.bit.TSS = 1; // stop timer1
803 CpuTimer2Regs.TCR.bit.TSS = 1; // stop timer2
804
805 //
806 // Calculate elapsed counts on timer1
807 //
808 ctr1 = TMR1SYSCLKCTR - CpuTimer1Regs.TIM.all;
809
810 //
811 // Restore timer settings
812 //
813 CpuTimer1Regs.TCR.all = t1TCR;
814 CpuTimer1Regs.PRD.all = t1PRD;
815 CpuTimer1Regs.TPR.all = t1TPR;
816 CpuTimer1Regs.TPRH.all = t1TPRH;
817 CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = t2SRC;
818 CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE = t2Prescale;
819 CpuTimer2Regs.TCR.all = t2TCR;
820 CpuTimer2Regs.PRD.all = t2PRD;
821 CpuTimer2Regs.TPR.all = t2TPR;
822 CpuTimer2Regs.TPRH.all = t2TPRH;
823
824 //
825 // Calculate Clock Error:
826 // Error = (mult/div) - (timer1 count/timer2 count)
827 //
828 mult = (float)(imult) + (float)(fmult)/4;
829 div = (float)((!ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV) ? 1 : (ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV << 1));
830
831 sysclkToInClkError = (mult/div) - ((float)ctr1/(float)TMR2INPCLKCTR);
832
833 //
834 // sysclkInvalidFreq will be set to true if sysclkToInClkError is off by 10%
835 //
836 sysclkInvalidFreq = ((sysclkToInClkError > 0.10) || (sysclkToInClkError < -0.10));
837 }
838
839 //
840 // Clear bit
841 //
842 DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 0;
843
844 //
845 // Restore user watchdog, first resetting counter
846 //
847 WdRegs.WDKEY.bit.WDKEY = 0x55;
848 WdRegs.WDKEY.bit.WDKEY = 0xAA;
849
850 WDCR |= 0x28; // Setup WD key--KEY bits always read 0
851 WdRegs.WDCR.all = WDCR;
852 WdRegs.WDWCR.all = WDWCR;
853 WdRegs.SCSR.all = SCSR & 0xFFFE; // Mask write to bit 0 (W1toClr)
854
855 //
856 // Restore state of ST1[INTM]. This was set by the __disable_interrupts()
857 // intrinsic previously.
858 //
859 if(!(intStatus & 0x1))
860 {
861 EINT;
862 }
863
864 //
865 // Restore state of ST1[DBGM]. This was set by the __disable_interrupts()
866 // intrinsic previously.
867 //
868 if(!(intStatus & 0x2))
869 {
870 asm(" CLRC DBGM");
871 }
872
873 //
874 // 200 PLLSYSCLK delay to allow voltage regulator to stabilize prior
875 // to increasing entire system clock frequency.
876 //
877 asm(" RPT #200 || NOP");
878
879 //
880 // Set the divider to user value
881 //
882 ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel;
883
884 EDIS;
885 }
886 #endif // CPU1
887
888 //
889 // InitAuxPll - This function initializes the AUXPLL registers.
890 //
891 // Note: For this function to properly detect PLL startup,
892 // SYSCLK >= 2*AUXPLLCLK after the AUXPLL is selected as the clocking source.
893 //
894 // This function will use CPU Timer 2 to monitor a successful lock of the
895 // AUXPLL.
896 //
InitAuxPll(Uint16 clock_source,Uint16 imult,Uint16 fmult,Uint16 divsel)897 void InitAuxPll(Uint16 clock_source, Uint16 imult, Uint16 fmult, Uint16 divsel)
898 {
899 Uint16 i;
900 Uint16 counter = 0;
901 Uint16 started = 0;
902 Uint16 t2TCR, t2TPR, t2TPRH, t2SRC, t2Prescale, attempts;
903 Uint32 t2PRD;
904
905 if((clock_source == ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL) &&
906 (imult == ClkCfgRegs.AUXPLLMULT.bit.IMULT) &&
907 (fmult == ClkCfgRegs.AUXPLLMULT.bit.FMULT) &&
908 (divsel == ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV))
909 {
910 //
911 // Everything is set as required, so just return
912 //
913 return;
914 }
915
916 switch (clock_source)
917 {
918 case INT_OSC2:
919 AuxIntOsc2Sel();
920 break;
921
922 case XTAL_OSC:
923 AuxXtalOscSel();
924 break;
925
926 case AUXCLKIN:
927 AuxAuxClkSel();
928 break;
929 }
930
931 //
932 // Backup Timer 2 settings
933 //
934 t2SRC = CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL;
935 t2Prescale = CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE;
936 t2TCR = CpuTimer2Regs.TCR.all;
937 t2PRD = CpuTimer2Regs.PRD.all;
938 t2TPR = CpuTimer2Regs.TPR.all;
939 t2TPRH = CpuTimer2Regs.TPRH.all;
940
941 //
942 // Configure Timer 2 for AUXPLL as source in known configuration
943 //
944 EALLOW;
945 CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = 0x6;
946 CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE = 0x0; // Divide by 1
947
948 CpuTimer2Regs.TCR.bit.TSS = 1; // Stop timer
949 CpuTimer2Regs.PRD.all = 10; // Small PRD value to detect overflow
950 CpuTimer2Regs.TPR.all = 0;
951 CpuTimer2Regs.TPRH.all = 0;
952 CpuTimer2Regs.TCR.bit.TIE = 0; // Disable timer interrupts
953
954 //
955 // Set AUX Divide by 8 to ensure that AUXPLLCLK <= SYSCLK/2 while using
956 // Timer 2
957 //
958 ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = 0x3;
959 EDIS;
960
961 while((counter < 5) && (started == 0))
962 {
963 EALLOW;
964 ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 0; // Turn off AUXPLL
965 asm(" RPT #20 || NOP"); // Small delay for power down
966
967 //
968 // Set integer and fractional multiplier, which automatically turns on
969 // the PLL
970 //
971 ClkCfgRegs.AUXPLLMULT.all = ((fmult << 8U) | imult);
972
973 //
974 // Enable AUXPLL
975 //
976 ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 1;
977 EDIS;
978
979 //
980 // Wait for the AUXPLL lock counter
981 //
982 while(ClkCfgRegs.AUXPLLSTS.bit.LOCKS != 1)
983 {
984 //
985 // Uncomment to service the watchdog
986 //
987 // ServiceDog();
988 }
989
990 //
991 // Enable AUXPLLCLK to be fed from AUX PLL
992 //
993 EALLOW;
994 ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1;
995 asm(" RPT #20 || NOP");
996
997 //
998 // CPU Timer 2 will now be setup to be clocked from AUXPLLCLK. This is
999 // used to test that the PLL has successfully started.
1000 //
1001 CpuTimer2Regs.TCR.bit.TRB = 1; // Reload period value
1002 CpuTimer2Regs.TCR.bit.TSS = 0; // Start Timer
1003
1004 //
1005 // Check to see timer is counting properly
1006 //
1007 for(i = 0; i < 1000; i++)
1008 {
1009 //
1010 // Check overflow flag
1011 //
1012 if(CpuTimer2Regs.TCR.bit.TIF)
1013 {
1014 //
1015 // Clear overflow flag
1016 //
1017 CpuTimer2Regs.TCR.bit.TIF = 1;
1018
1019 //
1020 // Set flag to indicate PLL started and break out of for-loop
1021 //
1022 started = 1;
1023 break;
1024 }
1025 }
1026
1027 //
1028 // Stop timer
1029 //
1030 CpuTimer2Regs.TCR.bit.TSS = 1;
1031 counter++;
1032 EDIS;
1033 }
1034
1035 if(started == 0)
1036 {
1037 //
1038 // AUX PLL may not have started. Reset multiplier to 0 (bypass PLL).
1039 //
1040 EALLOW;
1041 ClkCfgRegs.AUXPLLMULT.all = 0;
1042 EDIS;
1043
1044 //
1045 // The user should put some handler code here based on how this
1046 // condition should be handled in their application.
1047 //
1048 asm(" ESTOP0");
1049 }
1050
1051 //
1052 // Slip Bit Monitor
1053 // Re-lock routine for SLIP condition
1054 //
1055 attempts = 0;
1056 while(ClkCfgRegs.AUXPLLSTS.bit.SLIPS && (attempts < 10))
1057 {
1058 EALLOW;
1059 //
1060 // Bypass AUXPLL
1061 //
1062 ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 0;
1063 asm(" RPT #20 || NOP");
1064
1065 //
1066 // Turn off AUXPLL
1067 //
1068 ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 0;
1069 asm(" RPT #20 || NOP");
1070
1071 //
1072 // Set integer and fractional multiplier, which automatically turns
1073 // on the PLL
1074 //
1075 ClkCfgRegs.AUXPLLMULT.all = ((fmult << 8U) | imult);
1076
1077 //
1078 // Wait for the AUXPLL lock counter
1079 //
1080 while(ClkCfgRegs.AUXPLLSTS.bit.LOCKS != 1);
1081
1082 //
1083 // Enable AUXPLLCLK to be fed from AUXPLL
1084 //
1085 ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1;
1086 asm(" RPT #20 || NOP");
1087
1088 attempts++;
1089 EDIS;
1090 }
1091
1092 //
1093 // Set divider to desired value
1094 //
1095 EALLOW;
1096 ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = divsel;
1097
1098 //
1099 // Restore Timer 2 configuration
1100 //
1101 CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = t2SRC;
1102 CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE = t2Prescale;
1103 CpuTimer2Regs.TCR.all = t2TCR;
1104 CpuTimer2Regs.PRD.all = t2PRD;
1105 CpuTimer2Regs.TPR.all = t2TPR;
1106 CpuTimer2Regs.TPRH.all = t2TPRH;
1107
1108 //
1109 // Reload period value
1110 //
1111 CpuTimer2Regs.TCR.bit.TRB = 1;
1112 EDIS;
1113 }
1114
1115 //
1116 // CsmUnlock - This function unlocks the CSM. User must replace 0xFFFF's with
1117 // current password for the DSP. Returns 1 if unlock is successful.
1118 //
CsmUnlock(void)1119 Uint16 CsmUnlock(void)
1120 {
1121 volatile Uint16 temp;
1122
1123 //
1124 // Load the key registers with the current password. The 0xFFFF's are dummy
1125 // passwords. User should replace them with the correct password for the
1126 // DSP.
1127 //
1128 EALLOW;
1129 DcsmZ1Regs.Z1_CSMKEY0 = 0xFFFFFFFF;
1130 DcsmZ1Regs.Z1_CSMKEY1 = 0xFFFFFFFF;
1131 DcsmZ1Regs.Z1_CSMKEY2 = 0xFFFFFFFF;
1132 DcsmZ1Regs.Z1_CSMKEY3 = 0xFFFFFFFF;
1133
1134 DcsmZ2Regs.Z2_CSMKEY0 = 0xFFFFFFFF;
1135 DcsmZ2Regs.Z2_CSMKEY1 = 0xFFFFFFFF;
1136 DcsmZ2Regs.Z2_CSMKEY2 = 0xFFFFFFFF;
1137 DcsmZ2Regs.Z2_CSMKEY3 = 0xFFFFFFFF;
1138 EDIS;
1139
1140 return(0);
1141 }
1142
1143 //
1144 // SysIntOsc1Sel - This function switches to Internal Oscillator 1.
1145 //
SysIntOsc1Sel(void)1146 void SysIntOsc1Sel(void)
1147 {
1148 EALLOW;
1149 ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 2; // Clk Src = INTOSC1
1150 ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1; // Turn off XTALOSC
1151 EDIS;
1152 }
1153
1154 //
1155 // SysIntOsc2Sel - This function switches to Internal oscillator 2.
1156 //
SysIntOsc2Sel(void)1157 void SysIntOsc2Sel(void)
1158 {
1159 EALLOW;
1160 ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0; // Turn on INTOSC2
1161 ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 0; // Clk Src = INTOSC2
1162 ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1; // Turn off XTALOSC
1163 EDIS;
1164 }
1165
1166 //
1167 // SysXtalOscSel - This function switches to External CRYSTAL oscillator.
1168 //
SysXtalOscSel(void)1169 void SysXtalOscSel(void)
1170 {
1171 EALLOW;
1172 ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0; // Turn on XTALOSC
1173 ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1; // Clk Src = XTAL
1174 EDIS;
1175 }
1176
1177 //
1178 // AuxIntOsc2Sel - This function switches to Internal oscillator 2.
1179 //
AuxIntOsc2Sel(void)1180 void AuxIntOsc2Sel(void)
1181 {
1182 EALLOW;
1183 ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0; // Turn on INTOSC2
1184 ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 0; // Clk Src = INTOSC2
1185 EDIS;
1186 }
1187
1188 //
1189 // AuxXtalOscSel - This function switches to External CRYSTAL oscillator.
1190 //
AuxXtalOscSel(void)1191 void AuxXtalOscSel(void)
1192 {
1193 EALLOW;
1194 ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0; // Turn on XTALOSC
1195 ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 1; // Clk Src = XTAL
1196 EDIS;
1197 }
1198
1199 //
1200 // AuxAUXCLKOscSel - This function switches to AUXCLKIN (from a GPIO).
1201 //
AuxAuxClkSel(void)1202 void AuxAuxClkSel(void)
1203 {
1204 EALLOW;
1205 ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 2; // Clk Src = XTAL
1206 EDIS;
1207 }
1208
1209 //
1210 // IDLE - Enter IDLE mode (single CPU).
1211 //
IDLE(void)1212 void IDLE(void)
1213 {
1214 EALLOW;
1215 CpuSysRegs.LPMCR.bit.LPM = LPM_IDLE;
1216 EDIS;
1217 asm(" IDLE");
1218 }
1219
1220 //
1221 // STANDBY - Enter STANDBY mode (single CPU).
1222 //
STANDBY(void)1223 void STANDBY(void)
1224 {
1225 EALLOW;
1226 CpuSysRegs.LPMCR.bit.LPM = LPM_STANDBY;
1227 EDIS;
1228 asm(" IDLE");
1229 }
1230
1231 //
1232 // HALT - Enter HALT mode (dual CPU). Puts CPU2 in IDLE mode first.
1233 //
HALT(void)1234 void HALT(void)
1235 {
1236 #if defined(CPU2)
1237 IDLE();
1238 #elif defined(CPU1)
1239 EALLOW;
1240 CpuSysRegs.LPMCR.bit.LPM = LPM_HALT;
1241 EDIS;
1242
1243 while(DevCfgRegs.LPMSTAT.bit.CPU2LPMSTAT != 0x1);
1244
1245 EALLOW;
1246 ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
1247 ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
1248 EDIS;
1249 asm(" IDLE");
1250 #endif
1251 }
1252
1253 //
1254 // HIB - Enter HIB mode (dual CPU). Puts CPU2 in STANDBY first. Alternately,
1255 // CPU2 may be in reset.
HIB(void)1256 void HIB(void)
1257 {
1258 #if defined(CPU2)
1259 STANDBY();
1260 #elif defined(CPU1)
1261 EALLOW;
1262 CpuSysRegs.LPMCR.bit.LPM = LPM_HIB;
1263 EDIS;
1264
1265 while((DevCfgRegs.LPMSTAT.bit.CPU2LPMSTAT == 0x0) &&
1266 (DevCfgRegs.RSTSTAT.bit.CPU2RES == 1));
1267
1268 DisablePeripheralClocks();
1269 EALLOW;
1270 ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
1271 ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
1272 EDIS;
1273 asm(" IDLE");
1274 #endif
1275 }
1276
1277