00001 |void InitSysPll(Uint16 clock_source, Uint16 imult,||00001 |void InitSysPll(Uint16 clock_source, Uint16 imult, 00002 |{ ||00002 |{ 00003 L| Uint16 SCSR, WDCR, WDWCR, intStatus, t1TCR, t||00003 R| Uint16 SCSR, WDCR, WDWCR, intStatus; 00004 L| Uint16 t2TCR, t2TPR, t2TPRH, t2SRC, t2Prescale|| | 00005 L| Uint32 t1PRD, t2PRD, ctr1; || | 00006 L| float sysclkToInClkError, mult, div; || | 00007 L| bool sysclkInvalidFreq=true; || | 00008 L| || | 00009 | if((clock_source == ClkCfgRegs.CLKSRCCTL1.bit.||00004 | if((clock_source == ClkCfgRegs.CLKSRCCTL1.bit. 00010 | (imult == ClkCfgRegs.SYSPLLMULT.bit.||00005 | (imult == ClkCfgRegs.SYSPLLMULT.bit. 00011 | (fmult == ClkCfgRegs.SYSPLLMULT.bit.||00006 | (fmult == ClkCfgRegs.SYSPLLMULT.bit. 00012 | (divsel == ClkCfgRegs.SYSCLKDIVSEL.bi||00007 | (divsel == ClkCfgRegs.SYSCLKDIVSEL.bi 00013 | { ||00008 | { 00014 | // ||00009 | // 00015 | // Everything is set as required, so just ||00010 | // Everything is set as required, so just 00016 | // ||00011 | // 00017 | return; ||00012 | return; 00018 | } ||00013 | } 00019 | ||00014 | 00020 | if(clock_source != ClkCfgRegs.CLKSRCCTL1.bit.O||00015 | if(clock_source != ClkCfgRegs.CLKSRCCTL1.bit.O 00021 | { ||00016 | { 00022 | switch (clock_source) ||00017 | switch (clock_source) 00023 | { ||00018 | { 00024 | case INT_OSC1: ||00019 | case INT_OSC1: 00025 | SysIntOsc1Sel(); ||00020 | SysIntOsc1Sel(); 00026 | break; ||00021 | break; 00027 | ||00022 | 00028 | case INT_OSC2: ||00023 | case INT_OSC2: 00029 | SysIntOsc2Sel(); ||00024 | SysIntOsc2Sel(); 00030 | break; ||00025 | break; 00031 | ||00026 | 00032 | case XTAL_OSC: ||00027 | case XTAL_OSC: 00033 | SysXtalOscSel(); ||00028 | SysXtalOscSel(); 00034 | break; ||00029 | break; 00035 | } ||00030 | } 00036 | } ||00031 | } 00037 | ||00032 | 00038 | EALLOW; ||00033 | EALLOW; 00039 | if(imult != ClkCfgRegs.SYSPLLMULT.bit.IMULT ||||00034 | if(imult != ClkCfgRegs.SYSPLLMULT.bit.IMULT || 00040 | fmult != ClkCfgRegs.SYSPLLMULT.bit.FMULT) ||00035 | fmult != ClkCfgRegs.SYSPLLMULT.bit.FMULT) 00041 | { ||00036 | { 00042 | Uint16 i; ||00037 | Uint16 i; 00043 | ||00038 | 00044 | // ||00039 | // 00045 | // This bit is reset only by POR ||00040 | // This bit is reset only by POR 00046 | // ||00041 | // 00047 | if(DevCfgRegs.SYSDBGCTL.bit.BIT_0 == 1) ||00042 | if(DevCfgRegs.SYSDBGCTL.bit.BIT_0 == 1) 00048 | { ||00043 | { 00049 | // ||00044 | // 00050 | // The user can optionally insert hand||00045 | // The user can optionally insert hand 00051 | // be executed if a watchdog reset occ||00046 | // be executed if a watchdog reset occ 00052 | // PLL initialization. See your device||00047 | // PLL initialization. See your device 00053 | // information. ||00048 | // information. 00054 | // ||00049 | // 00055 | // If the application has a watchdog r||00050 | // If the application has a watchdog r 00056 | // be checked to determine if the watc||00051 | // be checked to determine if the watc 00057 | // of the PLL. ||00052 | // of the PLL. 00058 | // ||00053 | // 00059 | // No action here will continue with r||00054 | // No action here will continue with r 00060 | // ||00055 | // 00061 L| // Failed PLL initialization is due to|| | 00062 L| // - No PLL clock || | 00063 L| // - SLIP condition || | 00064 L| // - Wrong Frequency || | 00065 L| // || | 00066 | } ||00056 | } 00067 | ||00057 | 00068 | // ||00058 | // 00069 | // Bypass PLL and set dividers to /1 ||00059 | // Bypass PLL and set dividers to /1 00070 | // ||00060 | // 00071 | ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0; ||00061 | ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0; 00072 | asm(" RPT #20 || NOP"); ||00062 | asm(" RPT #20 || NOP"); 00073 | ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV =||00063 | ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = 00074 | ||00064 | 00075 | // ||00065 | // 00076 | // Lock the PLL five times. This helps ens||00066 | // Lock the PLL five times. This helps ens 00077 | // Five is the minimum recommended number.||00067 | // Five is the minimum recommended number. 00078 | // number according to allotted system ini||00068 | // number according to allotted system ini 00079 | // ||00069 | // 00080 | for(i = 0; i < 5; i++) ||00070 | for(i = 0; i < 5; i++) 00081 | { ||00071 | { 00082 | // ||00072 | // 00083 | // Turn off PLL ||00073 | // Turn off PLL 00084 | // ||00074 | // 00085 | ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0; ||00075 | ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0; 00086 | asm(" RPT #20 || NOP"); ||00076 | asm(" RPT #20 || NOP"); 00087 | ||00077 | 00088 | // ||00078 | // 00089 | // Write multiplier, which automatical||00079 | // Write multiplier, which automatical 00090 | // ||00080 | // 00091 | ClkCfgRegs.SYSPLLMULT.all = ((fmult <<||00081 | ClkCfgRegs.SYSPLLMULT.all = ((fmult << 00092 | ||00082 | 00093 | // ||00083 | // 00094 | // Wait for the SYSPLL lock counter ||00084 | // Wait for the SYSPLL lock counter 00095 | // ||00085 | // 00096 | while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS !||00086 | while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS ! 00097 | { ||00087 | { 00098 | // ||00088 | // 00099 | // Uncomment to service the watchd||00089 | // Uncomment to service the watchd 00100 | // ||00090 | // 00101 | // ServiceDog(); ||00091 | // ServiceDog(); 00102 | } ||00092 | } 00103 | } ||00093 | } 00104 | } ||00094 | } 00105 | ||00095 | 00106 | // ||00096 | // 00107 | // Set divider to produce slower output freque||00097 | // Set divider to produce slower output freque 00108 | // ||00098 | // 00109 | if(divsel != PLLCLK_BY_126) ||00099 | if(divsel != PLLCLK_BY_126) 00110 | { ||00100 | { 00111 | ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV ||00101 | ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV 00112 | }else ||00102 | }else 00113 | { ||00103 | { 00114 | ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV ||00104 | ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV 00115 | } ||00105 | } 00116 | ||00106 | 00117 | // ||00107 | // 00118 | // *CAUTION* ||00108 | // *CAUTION* 00119 | // It is recommended to use the following watc||00109 | // It is recommended to use the following watc 00120 | // startup sequence. If your application has a||00110 | // startup sequence. If your application has a 00121 | // SCRS[WDOVERRIDE] bit this cannot be done. I||00111 | // SCRS[WDOVERRIDE] bit this cannot be done. I 00122 | // this bit until after the PLL has been initi||00112 | // this bit until after the PLL has been initi 00123 | // ||00113 | // 00124 | ||00114 | 00125 | // ||00115 | // 00126 | // Backup User Watchdog ||00116 | // Backup User Watchdog 00127 | // ||00117 | // 00128 | SCSR = WdRegs.SCSR.all; ||00118 | SCSR = WdRegs.SCSR.all; 00129 | WDCR = WdRegs.WDCR.all; ||00119 | WDCR = WdRegs.WDCR.all; 00130 | WDWCR = WdRegs.WDWCR.all; ||00120 | WDWCR = WdRegs.WDWCR.all; 00131 | ||00121 | 00132 | // ||00122 | // 00133 | // Disable windowed functionality, reset count||00123 | // Disable windowed functionality, reset count 00134 | // ||00124 | // 00135 | EALLOW; ||00125 | EALLOW; 00136 | WdRegs.WDWCR.all = 0x0; ||00126 | WdRegs.WDWCR.all = 0x0; 00137 | WdRegs.WDKEY.bit.WDKEY = 0x55; ||00127 | WdRegs.WDKEY.bit.WDKEY = 0x55; 00138 | WdRegs.WDKEY.bit.WDKEY = 0xAA; ||00128 | WdRegs.WDKEY.bit.WDKEY = 0xAA; 00139 | ||00129 | 00140 | // ||00130 | // 00141 | // Disable global interrupts ||00131 | // Disable global interrupts 00142 | // ||00132 | // 00143 | intStatus = __disable_interrupts(); ||00133 | intStatus = __disable_interrupts(); 00144 | ||00134 | 00145 | // ||00135 | // 00146 | // Configure for watchdog reset and to run at ||00136 | // Configure for watchdog reset and to run at 00147 | // ||00137 | // 00148 | WdRegs.SCSR.all = 0x0; ||00138 | WdRegs.SCSR.all = 0x0; 00149 | WdRegs.WDCR.all = 0x28; ||00139 | WdRegs.WDCR.all = 0x28; 00150 | ||00140 | 00151 | // ||00141 | // 00152 | // This bit is reset only by power-on-reset (P||00142 | // This bit is reset only by power-on-reset (P 00153 | // by a WD reset ||00143 | // by a WD reset 00154 | // ||00144 | // 00155 | DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 1; ||00145 | DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 1; 00156 | ||00146 | 00157 | // ||00147 | // 00158 | // Enable PLLSYSCLK is fed from system PLL clo||00148 | // Enable PLLSYSCLK is fed from system PLL clo 00159 | // ||00149 | // 00160 | ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1; ||00150 | ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1; 00161 | ||00151 | 00162 | // ||00152 | // 00163 | // Delay to ensure system is clocking from PLL||00153 | // Delay to ensure system is clocking from PLL 00164 | // ||00154 | // 00165 | asm(" RPT #20 || NOP"); ||00155 | asm(" RPT #20 || NOP"); 00166 | ||00156 | 00167 | // ||00157 | // 00168 L| // Service watchdog || | 00324 M| // Clear bit ||00158 R| // Clear bit 00169 | // ||00159 | // 00170 L| ServiceDog(); || | 00326 M| DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 0; ||00160 R| DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 0; 00171 | ||00161 | 00172 | // ||00162 | // 00173 L| // Slip Bit Monitor and SYSCLK Frequency Check|| | 00174 L| // Re-lock routine for SLIP condition or if SY|| | 00175 L| // are off by +/- 10%. || | 00176 L| // At a minimum, SYSCLK check is performed. R|| | 00177 L| // if SLIPS bit is set. This while loop is mon|| | 00178 L| // In the event that the PLL does not successf|| | 00179 L| // aborted by watchdog reset. || | 00180 L| // || | 00181 L| EALLOW; || | 00182 L| while(sysclkInvalidFreq == true) || | 00183 L| { || | 00184 L| if(ClkCfgRegs.SYSPLLSTS.bit.SLIPS == 1) || | 00185 L| { || | 00186 L| // || | 00187 L| // Bypass PLL || | 00188 L| // || | 00189 L| ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0|| | 00190 L| asm(" RPT #20 || NOP"); || | 00191 L| || | 00192 L| // || | 00193 L| // Turn off PLL || | 00194 L| // || | 00195 L| ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0; || | 00196 L| asm(" RPT #20 || NOP"); || | 00197 L| || | 00198 L| // || | 00199 L| // Write multipliers, which automatica|| | 00200 L| // || | 00201 L| ClkCfgRegs.SYSPLLMULT.all = ((fmult <<|| | 00202 L| || | 00203 L| // || | 00204 L| // Wait for the SYSPLL lock counter to|| | 00205 L| // || | 00206 L| while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS !|| | 00207 L| || | 00208 L| // || | 00209 L| // Enable PLLSYSCLK is fed from system|| | 00210 L| // || | 00211 L| ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1|| | 00212 L| || | 00213 L| // || | 00214 L| // Delay to ensure system is clocking || | 00215 L| // || | 00216 L| asm(" RPT #20 || NOP"); || | 00217 L| } || | 00218 L| || | 00219 L| // || | 00220 L| // Backup timer1 and timer2 settings || | 00221 L| // || | 00222 L| t1TCR = CpuTimer1Regs.TCR.all; || | 00223 L| t1PRD = CpuTimer1Regs.PRD.all; || | 00224 L| t1TPR = CpuTimer1Regs.TPR.all; || | 00225 L| t1TPRH = CpuTimer1Regs.TPRH.all; || | 00226 L| t2SRC = CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKS|| | 00227 L| t2Prescale = CpuSysRegs.TMR2CLKCTL.bit.TMR|| | 00228 L| t2TCR = CpuTimer2Regs.TCR.all; || | 00229 L| t2PRD = CpuTimer2Regs.PRD.all; || | 00230 L| t2TPR = CpuTimer2Regs.TPR.all; || | 00231 L| t2TPRH = CpuTimer2Regs.TPRH.all; || | 00232 L| || | 00233 L| // || | 00234 L| // Set up timers 1 and 2 || | 00235 L| // Configure timer1 to count SYSCLK cycles|| | 00236 L| // || | 00237 L| CpuTimer1Regs.TCR.bit.TSS = 1; || | 00238 L| CpuTimer1Regs.PRD.all = TMR1SYSCLKCTR; || | 00239 L| CpuTimer1Regs.TPR.bit.TDDR = 0x0; || | 00240 L| CpuTimer1Regs.TCR.bit.TRB = 1; || | 00241 L| CpuTimer1Regs.TCR.bit.TIF = 1; || | 00242 L| CpuTimer1Regs.TCR.bit.TIE = 1; || | 00243 L| || | 00244 L| // || | 00245 L| // Configure timer2 to count Input clock c|| | 00246 L| // || | 00247 L| switch(clock_source) || | 00248 L| { || | 00249 L| case INT_OSC1: || | 00250 L| // Clk Src = INT_OSC1 || | 00251 L| CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKS|| | 00252 L| break; || | 00253 L| case INT_OSC2: || | 00254 L| // Clk Src = INT_OSC2 || | 00255 L| CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKS|| | 00256 L| break; || | 00257 L| case XTAL_OSC: || | 00258 L| // Clk Src = XTAL || | 00259 L| CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKS|| | 00260 L| break; || | 00261 L| || | 00262 L| } || | 00263 L| CpuTimer2Regs.TCR.bit.TIF = 1; || | 00264 L| CpuTimer2Regs.TCR.bit.TIE = 1; || | 00265 L| CpuTimer2Regs.TCR.bit.TSS = 1; || | 00266 L| CpuTimer2Regs.PRD.all = TMR2INPCLKCTR; || | 00267 L| CpuTimer2Regs.TPR.bit.TDDR = 0x0; || | 00268 L| CpuTimer2Regs.TCR.bit.TRB = 1; || | 00269 L| || | 00270 L| // || | 00271 L| // Stop/Start timer counters || | 00272 L| // || | 00273 L| CpuTimer1Regs.TCR.bit.TSS = 1; || | 00274 L| CpuTimer2Regs.TCR.bit.TSS = 1; || | 00275 L| CpuTimer1Regs.TCR.bit.TRB = 1; || | 00276 L| CpuTimer2Regs.TCR.bit.TRB = 1; || | 00277 L| CpuTimer2Regs.TCR.bit.TIF = 1; || | 00278 L| CpuTimer2Regs.TCR.bit.TSS = 0; || | 00279 L| CpuTimer1Regs.TCR.bit.TSS = 0; || | 00280 L| || | 00281 L| // || | 00282 L| // Stop timers if either timer1 or timer2 || | 00283 L| // || | 00284 L| while((CpuTimer2Regs.TCR.bit.TIF == 0) && || | 00285 L| || | 00286 L| CpuTimer1Regs.TCR.bit.TSS = 1; || | 00287 L| CpuTimer2Regs.TCR.bit.TSS = 1; || | 00288 L| || | 00289 L| // || | 00290 L| // Calculate elapsed counts on timer1 || | 00291 L| // || | 00292 L| ctr1 = TMR1SYSCLKCTR - CpuTimer1Regs.TIM.a|| | 00293 L| || | 00294 L| // || | 00295 L| // Restore timer settings || | 00296 L| // || | 00297 L| CpuTimer1Regs.TCR.all = t1TCR; || | 00298 L| CpuTimer1Regs.PRD.all = t1PRD; || | 00299 L| CpuTimer1Regs.TPR.all = t1TPR; || | 00300 L| CpuTimer1Regs.TPRH.all = t1TPRH; || | 00301 L| CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = || | 00302 L| CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE || | 00303 L| CpuTimer2Regs.TCR.all = t2TCR; || | 00304 L| CpuTimer2Regs.PRD.all = t2PRD; || | 00305 L| CpuTimer2Regs.TPR.all = t2TPR; || | 00306 L| CpuTimer2Regs.TPRH.all = t2TPRH; || | 00307 L| || | 00308 L| // || | 00309 L| // Calculate Clock Error: || | 00310 L| // Error = (mult/div) - (timer1 count/time|| | 00311 L| // || | 00312 L| mult = (float)(imult) + (float)(fmult)/4; || | 00313 L| div = (float)((!ClkCfgRegs.SYSCLKDIVSEL.bi|| | 00314 L| || | 00315 L| sysclkToInClkError = (mult/div) - ((float)|| | 00316 L| || | 00317 L| // || | 00318 L| // sysclkInvalidFreq will be set to true i|| | 00319 L| // || | 00320 L| sysclkInvalidFreq = ((sysclkToInClkError >|| | 00321 L| } || | 00322 L| || | 00323 L| // || | 00324 L| // Clear bit ||00158 M| // Clear bit 00325 L| // || | 00326 L| DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 0; ||00160 M| DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 0; 00327 L| || | 00328 L| // || | 00329 | // Restore user watchdog, first resetting coun||00163 | // Restore user watchdog, first resetting coun 00330 | // ||00164 | // 00331 | WdRegs.WDKEY.bit.WDKEY = 0x55; ||00165 | WdRegs.WDKEY.bit.WDKEY = 0x55; 00332 | WdRegs.WDKEY.bit.WDKEY = 0xAA; ||00166 | WdRegs.WDKEY.bit.WDKEY = 0xAA; 00333 | ||00167 | 00334 | WDCR |= 0x28; // Setup WD ||00168 | WDCR |= 0x28; // Setup WD 00335 | WdRegs.WDCR.all = WDCR; ||00169 | WdRegs.WDCR.all = WDCR; 00336 | WdRegs.WDWCR.all = WDWCR; ||00170 | WdRegs.WDWCR.all = WDWCR; 00337 | WdRegs.SCSR.all = SCSR & 0xFFFE; // Mask writ||00171 | WdRegs.SCSR.all = SCSR & 0xFFFE; // Mask writ 00338 | ||00172 | 00339 | // ||00173 | // 00340 | // Restore state of ST1[INTM]. This was set by||00174 | // Restore state of ST1[INTM]. This was set by 00341 | // intrinsic previously. ||00175 | // intrinsic previously. 00342 | // ||00176 | // 00343 | if(!(intStatus & 0x1)) ||00177 | if(!(intStatus & 0x1)) 00344 | { ||00178 | { 00345 | EINT; ||00179 | EINT; 00346 | } ||00180 | } 00347 | ||00181 | 00348 | // ||00182 | // 00349 | // Restore state of ST1[DBGM]. This was set by||00183 | // Restore state of ST1[DBGM]. This was set by 00350 | // intrinsic previously. ||00184 | // intrinsic previously. 00351 | // ||00185 | // 00352 | if(!(intStatus & 0x2)) ||00186 | if(!(intStatus & 0x2)) 00353 | { ||00187 | { 00354 | asm(" CLRC DBGM"); ||00188 | asm(" CLRC DBGM"); 00355 | } ||00189 | } 00356 | ||00190 | 00357 | // ||00191 | // 00358 | // 200 PLLSYSCLK delay to allow voltage regula||00192 | // 200 PLLSYSCLK delay to allow voltage regula 00359 | // to increasing entire system clock frequency||00193 | // to increasing entire system clock frequency 00360 | // ||00194 | // 00361 | asm(" RPT #200 || NOP"); ||00195 | asm(" RPT #200 || NOP"); 00362 | ||00196 | 00363 | // ||00197 | // 00364 | // Set the divider to user value ||00198 | // Set the divider to user value 00365 | // ||00199 | // 00366 | ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = div||00200 | ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = div 00367 L| || | 00368 | EDIS; ||00201 | EDIS; 00369 |} ||00202 |}