pic24_clockfreq.c
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
00067 #include "pic24_all.h"
00068
00069 #if !USE_CLOCK_TIMEOUT
00070
00071 void checkClockTimeout(void) {
00072 }
00073 #else
00074
00075
00076
00077
00078
00079
00080 #define CLOCKTIMEOUT_MAX 200000L
00081 #if ( defined(__PIC24H__) || defined(__dsPIC33F__) )
00082 #define FRC_FCY 40000000L
00083 #elif ( defined(__PIC24F__) || defined(__PIC24FK__) )
00084 #define FRC_FCY 16000000L
00085 #else
00086 #error Unknown processor.
00087 #endif
00088 #define FRC_BRGH 0
00089
00090
00091 static void configFrcUART(void) {
00092 float f_brg;
00093 uint16 UxBRG;
00094
00095 #if ( defined(__PIC24H__) || defined(__dsPIC33F__) )
00096 configClockFRCPLL_FCY40MHz();
00097 #elif ( defined(__PIC24F__) || defined(__PIC24FK__) )
00098
00099 configClockFRCPLL_FCY16MHz();
00100 #else
00101 #error Unknown processor
00102 #endif
00103
00104
00105 configDefaultUART(DEFAULT_BAUDRATE);
00106
00107 #if (FRC_BRGH == 0)
00108 f_brg = (((float) FRC_FCY)/((float) DEFAULT_BAUDRATE)/16.0) - 1.0;
00109 #else
00110 f_brg = (((float) FRC_FCY)/((float) DEFAULT_BAUDRATE)/4.0) - 1.0;
00111 #endif
00112 UxBRG = roundFloatToUint16(f_brg);
00113 switch (DEFAULT_UART) {
00114 #if (NUM_UART_MODS >= 1)
00115 case 1 :
00116 U1BRG = UxBRG;
00117 U1MODEbits.BRGH = FRC_BRGH;
00118 break;
00119 #endif
00120 #if (NUM_UART_MODS >= 2)
00121 case 2 :
00122 U2BRG = UxBRG;
00123 U2MODEbits.BRGH = FRC_BRGH;
00124 break;
00125 #endif
00126 #if (NUM_UART_MODS >= 3)
00127 case 3 :
00128 U3BRG = UxBRG;
00129 U3MODEbits.BRGH = FRC_BRGH;
00130 break;
00131 #endif
00132 #if (NUM_UART_MODS >= 4)
00133 case 4 :
00134 U4BRG = UxBRG;
00135 U4MODEbits.BRGH = FRC_BRGH;
00136 break;
00137 #endif
00138 default : ASSERT(0);
00139 }
00140 }
00141
00142 static void checkClockTimeout(void) {
00143 static uint32 u32_timeoutCount = 0;
00144
00145
00146
00147
00148 if (u32_timeoutCount == 0xFFFFFFFF) return;
00149
00150
00151
00152 u32_timeoutCount++;
00153 if (u32_timeoutCount < CLOCKTIMEOUT_MAX) return;
00154
00155
00156 u32_timeoutCount = 0xFFFFFFFF;
00157
00158 configFrcUART();
00159 outString("\n\n"
00160 "Your clock choice failed to initialize, have switched to internal Fast RC oscillator +PLL.\n"
00161 "Check your setting for the 'CLOCK_CONFIG' macro.\n"
00162 "Watch the compiler output window when pic24_clockfreq.c is compiled, a warning message\n"
00163 "will tell you the selected value for 'CLOCK_CONFIG'.\n"
00164 "In MPLAB, use Project->Build Options->Project, then click on MPLAB C30 tab to see if \n"
00165 "the macro is defined there. If the macro is selecting an external crystal (the primary oscillator),\n"
00166 "and your board does not have a crystal, you will get this message.\n"
00167 "Delete the macro definition from the MPLAB project if you want to use the default \n"
00168 "clock choice of FRC + PLL.\n"
00169 "You must recompile and reprogram with an appropriate CLOCK_CONFIG choice for this code to execute.\n");
00170
00171 while(1) {
00172 doHeartbeat();
00173 }
00174 }
00175 #endif
00176
00177
00178 void switchClock(uint8 u8_source) {
00179
00180
00181 OSCCONBITS OSCCONBITS_copy;
00182
00183
00184
00185
00186 ASSERT(u8_source < 8);
00187
00188
00189
00190
00191 asm("DISI #0x3FFF");
00192
00193
00194 OSCCONBITS_copy = OSCCONbits;
00195 OSCCONBITS_copy.NOSC = u8_source;
00196 OSCCONBITS_copy.OSWEN = 1;
00197
00198 __builtin_write_OSCCONH(BITS2BYTEH(OSCCONBITS_copy));
00199
00200 __builtin_write_OSCCONL(BITS2BYTEL(OSCCONBITS_copy));
00201 asm("DISI #0");
00202
00203 #ifndef SIM
00204
00205
00206
00207
00208 while (_OSWEN == 1) {
00209 checkClockTimeout();
00210 }
00211
00212
00213
00214 if ( (u8_source == GET_OSC_SEL_BITS(FNOSC_FRCPLL)) ||
00215 (u8_source == GET_OSC_SEL_BITS(FNOSC_PRIPLL)) ) {
00216 while (_LOCK == 0) {
00217 checkClockTimeout();
00218 }
00219 }
00220
00221
00222 while (_COSC != u8_source) checkClockTimeout();
00223 #endif
00224 }
00225
00226 #if IS_CLOCK_CONFIG(SIM_CLOCK)
00227 #warning Clock configured for simulation, FCY = 1 Mhz
00228 #endif
00229 #if GET_IS_SUPPORTED(SIM_CLOCK)
00230 void configClockSim(void) { }
00231 #endif
00232
00233
00234 #if IS_CLOCK_CONFIG(FRCPLL_FCY16MHz)
00235 #warning Clock configured for FRCPLL, FCY = 16 MHz
00236 #endif
00237 #if GET_IS_SUPPORTED(FRCPLL_FCY16MHz)
00238 void configClockFRCPLL_FCY16MHz(void) {
00239
00240
00241
00242 switchClock(GET_OSC_SEL_BITS(FNOSC_FRC));
00243
00244
00245
00246
00247 _RCDIV = 0;
00248 #ifdef _CPDIV
00249
00250
00251
00252
00253 _CPDIV = 0;
00254 #endif
00255 #ifdef _PLLDIV
00256
00257
00258
00259
00260
00261 _PLLDIV = 1;
00262 #elif defined(PLLDIV_NODIV)
00263 #warning Ensure that the PLLDIV value is set to divide by 2 in the configuration bits for FRCPLL_FCY16MHz clock option!!
00264 #endif
00265 #ifdef _PLLEN
00266 _PLLEN = 1;
00267 #warning PLL Enabled
00268 #endif
00269 switchClock(GET_OSC_SEL_BITS(FNOSC_FRCPLL));
00270 }
00271 #endif
00272
00273
00274 #if IS_CLOCK_CONFIG(FRC_FCY4MHz)
00275 #warning Clock configured for FRC, FCY = 4 MHz.
00276 #warning Baud rates of 19200 or lower recommended for this clock choice.
00277 #endif
00278 #if GET_IS_SUPPORTED(FRC_FCY4MHz)
00279 void configClockFRC_FCY4MHz(void) {
00280
00281 _RCDIV = 0;
00282 switchClock(GET_OSC_SEL_BITS(FNOSC_FRC));
00283 }
00284 #endif
00285
00286
00287 #if IS_CLOCK_CONFIG(PRI_NO_PLL_7372KHzCrystal)
00288 #warning Clock configured for a 7.372 MHz crystal primary oscillator, no PLL
00289 #endif
00290 #if GET_IS_SUPPORTED(PRI_NO_PLL_7372KHzCrystal)
00291 void configClockPRI_NO_PLL_7372KHzCrystal(void) {
00292 switchClock(GET_OSC_SEL_BITS(FNOSC_PRI));
00293 }
00294 #endif
00295
00296
00297 #if IS_CLOCK_CONFIG(FRC_FCY3685KHz)
00298 #warning Clock configured for FRC, FCY = 3.685 MHz
00299 #warning Baud rates of 9600 or lower recommended for this clock choice.
00300 #endif
00301 #if GET_IS_SUPPORTED(FRC_FCY3685KHz)
00302 void configClockFRC_FCY3685KHz(void) {
00303 switchClock(GET_OSC_SEL_BITS(FNOSC_FRC));
00304
00305
00306
00307
00308 _TUN = 0;
00309 }
00310 #endif
00311
00312
00313 #if IS_CLOCK_CONFIG(FRCPLL_FCY40MHz)
00314 #warning Clock configured for FRCPLL, FCY = 40 MHz
00315 #endif
00316 #if GET_IS_SUPPORTED(FRCPLL_FCY40MHz)
00317 void configClockFRCPLL_FCY40MHz(void) {
00318
00319
00320
00321 switchClock(GET_OSC_SEL_BITS(FNOSC_FRC));
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 _TUN = -19;
00339
00340
00341
00342
00343
00344
00345 _PLLPRE = 6;
00346
00347
00348 _PLLDIV = 185;
00349
00350
00351 _PLLPOST = 0;
00352 switchClock(GET_OSC_SEL_BITS(FNOSC_FRCPLL));
00353 }
00354 #endif
00355
00356 #if IS_CLOCK_CONFIG(PRIPLL_7372KHzCrystal_40MHzFCY)
00357 #warning Clock configured for PRIPLL using a 7.3727 Mhz primary oscillator, FCY = 40 MHz
00358 #endif
00359 #if GET_IS_SUPPORTED(PRIPLL_7372KHzCrystal_40MHzFCY)
00360 void configClockPRIPLL_7372KHzCrystal_40MHzFCY(void) {
00361
00362
00363
00364 switchClock(GET_OSC_SEL_BITS(FNOSC_FRC));
00365
00366 _PLLPRE = 4;
00367 _PLLDIV = 128;
00368 _PLLPOST = 0;
00369 switchClock(GET_OSC_SEL_BITS(FNOSC_PRIPLL));
00370 }
00371 #endif
00372
00373 #if IS_CLOCK_CONFIG(PRIPLL_8MHzCrystal_40MHzFCY)
00374 #warning Clock configured for PRIPLL using an 8.0 Mhz primary oscillator, FCY = 40 MHz
00375 #endif
00376 #if GET_IS_SUPPORTED(PRIPLL_8MHzCrystal_40MHzFCY)
00377 void configClockPRIPLL_8MHzCrystal_40MHzFCY(void) {
00378
00379
00380
00381
00382
00383
00384
00385
00386 switchClock(GET_OSC_SEL_BITS(FNOSC_FRC));
00387 _PLLPRE = 0;
00388 _PLLDIV = 38;
00389 _PLLPOST = 0;
00390 switchClock(GET_OSC_SEL_BITS(FNOSC_PRIPLL));
00391 }
00392 #endif
00393
00394 #if IS_CLOCK_CONFIG(PRIPLL_8MHzCrystal_16MHzFCY)
00395 #warning Clock configured for PRIPLL using a 8.0 Mhz primary oscillator, FCY = 16 MHz
00396 #endif
00397 #if GET_IS_SUPPORTED(PRIPLL_8MHzCrystal_16MHzFCY)
00398 void configClockPRIPLL_8MHzCrystal_16MHzFCY(void) {
00399
00400
00401
00402 switchClock(GET_OSC_SEL_BITS(FNOSC_FRC));
00403
00404
00405
00406
00407 _RCDIV = 0;
00408 #ifdef _CPDIV
00409
00410
00411
00412
00413 _CPDIV = 0;
00414 #endif
00415 #ifdef _PLLDIV
00416
00417
00418
00419
00420
00421 _PLLDIV = 1;
00422 #elif defined(PLLDIV_NODIV)
00423 #warning Ensure that the PLLDIV value is set to divide by 2 in the configuration bits for PRIPLL_8MHzCrystal_16MHzFCY clock option!!
00424 #endif
00425 #ifdef _PLLEN
00426 _PLLEN = 1;
00427 #warning PLL Enabled
00428 #endif
00429
00430 switchClock(GET_OSC_SEL_BITS(FNOSC_PRIPLL));
00431 }
00432 #endif
00433
00434 #if IS_CLOCK_CONFIG(PRI_8MHzCrystal_4MHzFCY)
00435 #warning Clock configured for PRI using a 8.0 Mhz primary oscillator, FCY = 4 MHz
00436 #endif
00437 #if GET_IS_SUPPORTED(PRI_8MHzCrystal_4MHzFCY)
00438 void configClockPRI_8MHzCrystal_4MHzFCY(void) {
00439
00440
00441
00442 switchClock(GET_OSC_SEL_BITS(FNOSC_PRI));
00443 }
00444 #endif