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
00039 #include "pic24_all.h"
00040 #include <stdio.h>
00041
00042
00043 #if !USE_HEARTBEAT
00044
00045 void configHeartbeat(void) {
00046 }
00047 void doHeartbeat(void) {
00048 }
00049
00050 void toggleHeartbeat(void) {
00051 }
00052 #else
00053
00054 uint32 u32_heartbeatCount;
00055 uint32 u32_heartbeatMax;
00056
00057
00058 void configHeartbeat(void) {
00059 CONFIG_HB_LED();
00060
00061
00062
00063
00064 u32_heartbeatMax = CYCLES_PER_MS * 10;
00065 u32_heartbeatCount = 0;
00066 HB_LED = 0;
00067 doHeartbeat();
00068 }
00069
00074 void doHeartbeat(void) {
00075 u32_heartbeatCount++;
00076 if (u32_heartbeatCount > u32_heartbeatMax) {
00077 toggleHeartbeat();
00078 u32_heartbeatCount = 0;
00079 }
00080 }
00081
00082
00083 void toggleHeartbeat(void) {
00084 HB_LED = !HB_LED;
00085 }
00086
00087 #endif
00088
00093 _PERSISTENT const char* sz_lastError;
00094 _PERSISTENT char* sz_lastTimeoutError;
00095
00096 #ifndef __PIC24F__
00097
00104 _PERSISTENT INTTREGBITS INTTREGBITS_last;
00110 #define u16_INTTREGlast BITS2WORD(INTTREGBITS_last)
00111 #else
00112 uint16 u16_INTTREGlast;
00113 #endif
00114
00120 void _ISR _DefaultInterrupt(void) {
00121 #ifndef __PIC24F__
00122
00123
00124 u16_INTTREGlast = INTTREG;
00125 #else
00126
00127
00128 u16_INTTREGlast = 1;
00129 #endif
00130 reportError("Unhandled interrupt, ");
00131 }
00132
00133
00141 void reportError(const char* sz_errorMessage) {
00142
00143 if (sz_lastError == NULL) {
00144 sz_lastError = sz_errorMessage;
00145 asm ("reset");
00146 }
00147 }
00148
00149 uint32 readProgramMemory(uint32 address) {
00150 uint16 offset = address;
00151 TBLPAG = address >> 16;
00152 return ( ((uint32) __builtin_tblrdh(offset)) << 16) |
00153 __builtin_tblrdl(offset);
00154 }
00155
00156 void checkDeviceAndRevision(void) {
00157 #ifdef SIM
00158 outString("**** SIMULATION MODE: cannot read device and revision ID ****\n");
00159 #else
00160 uint32 devID = readProgramMemory(DEV_ID_LOCATION);
00161 uint32 revision = readProgramMemory(REVISION_LOCATION);
00162 uint8 correctChip = 1;
00163 char* devIDStr = "unknown";
00164 char* revisionStr = "unknown";
00165
00166 if (devID == DEV_ID)
00167 devIDStr = DEV_ID_STR;
00168 else
00169 correctChip = 0;
00170
00171 switch (revision) {
00172 case EXPECTED_REVISION1 :
00173 revisionStr = EXPECTED_REVISION1_STR;
00174 break;
00175 #ifdef EXPECTED_REVISION2
00176 case EXPECTED_REVISION2 :
00177 revisionStr = EXPECTED_REVISION2_STR;
00178 break;
00179 #endif
00180 #ifdef EXPECTED_REVISION3
00181 case EXPECTED_REVISION3 :
00182 revisionStr = EXPECTED_REVISION3_STR;
00183 break;
00184 #endif
00185 #ifdef EXPECTED_REVISION4
00186 case EXPECTED_REVISION4 :
00187 revisionStr = EXPECTED_REVISION4_STR;
00188 break;
00189 #endif
00190 #ifdef EXPECTED_REVISION5
00191 case EXPECTED_REVISION5 :
00192 revisionStr = EXPECTED_REVISION5_STR;
00193 break;
00194 #endif
00195 default :
00196 correctChip = 0;
00197 break;
00198 }
00199
00200 outString("Device ID = ");
00201 outUint32(devID);
00202 outString(" (");
00203 outString(devIDStr);
00204 outString("), revision ");
00205 outUint32(revision);
00206 outString(" (");
00207 outString(revisionStr);
00208 outString(")\n");
00209
00210 if (!correctChip)
00211 outString("\n\n"
00212 "*****************************************************\n"
00213 "* WARNING - this program was compiled for the wrong *\n"
00214 "* chip or for an unknown revision of this chip! *\n"
00215 "* This program may produce unexpected behvior! Edit *\n"
00216 "* the header files to properly define this chip or *\n"
00217 "* revision and to insure correct operation. *\n"
00218 "* *\n"
00219 "* NOTE: If this was compiled for the correct chip, *\n"
00220 "* and only occurs at power-on (not during a MCLR *\n"
00221 "* reset, verify that AVDD and AVSS are connected. *\n"
00222 "* On the PIC24H32GP202, not connecting AVDD *\n"
00223 "* produces this message only at power-up. *\n"
00224 "*****************************************************\n");
00225 #endif
00226 }
00227
00228 void checkOscOption(void) {
00229 uint8 u8_x;
00230
00231 u8_x = _COSC;
00232 switch (u8_x) {
00233 case 0:
00234 outString("Fast RC Osc\n");
00235 break;
00236 case 1:
00237 outString("Fast RC Osc with PLL\n");
00238 break;
00239 case 2:
00240 outString("Primary Osc (XT, HS, EC)\n");
00241 break;
00242 case 3:
00243 outString("Primary Osc (XT, HS, EC) with PLL\n");
00244 break;
00245 case 4:
00246 outString("Secondary Osc\n");
00247 break;
00248 case 5:
00249 outString("Low Power RC Osc\n");
00250 break;
00251 #if defined(__PIC24H__)
00252 case 6:
00253 outString("Fast RC Osc/16\n");
00254 break;
00255 case 7:
00256 outString("Fast RC Osc/N\n");
00257 break;
00258 #elif defined(__PIC24F__)
00259 case 7 :
00260 outString("Fast RC Osc with Postscale");
00261 break;
00262 #else
00263 #error Unknown processor
00264 #endif
00265 default :
00266 reportError("Unknown oscillator type.");
00267 break;
00268 }
00269 }
00270
00275 void printResetCause(void) {
00276 uint8 u8_resetIdentified;
00277
00278 u8_resetIdentified = 0;
00279 if (_SLEEP) {
00280 outString("\nDevice has been in sleep mode\n");
00281 _SLEEP = 0;
00282 }
00283 if (_IDLE) {
00284 outString("\nDevice has been in idle mode\n");
00285 _IDLE = 0;
00286 }
00287 outString("\nReset cause: ");
00288 if (_POR) {
00289 u8_resetIdentified = 1;
00290 outString("Power-on.\n");
00291 _POR = 0;
00292 _BOR = 0;
00293
00294
00295
00296 sz_lastError = NULL;
00297 sz_lastTimeoutError = NULL;
00298 u16_INTTREGlast = 0;
00299 } else {
00300
00301 if (_SWR) {
00302 outString("Software Reset.\n");
00303 u8_resetIdentified = 1;
00304 _SWR = 0;
00305 _EXTR = 0;
00306 }
00307 if (_WDTO) {
00308 u8_resetIdentified = 1;
00309 outString("Watchdog Timeout: ");
00310 if (sz_lastTimeoutError != NULL) {
00311 outString(sz_lastTimeoutError);
00312 }
00313 outString("\n");
00314 _WDTO = 0;
00315 _EXTR = 0;
00316 }
00317 if (_EXTR) {
00318 u8_resetIdentified = 1;
00319 outString("MCLR assertion.\n");
00320 _EXTR = 0;
00321 }
00322 if (_BOR) {
00323 u8_resetIdentified = 1;
00324 outString("Brown-out.\n");
00325 _BOR = 0;
00326 }
00327 if (_TRAPR) {
00328 u8_resetIdentified = 1;
00329 outString("Trap Conflict.\n");
00330 _TRAPR = 0;
00331 }
00332 if (_IOPUWR) {
00333 u8_resetIdentified = 1;
00334 outString("Illegal Condition.\n");
00335 _IOPUWR = 0;
00336 }
00337 #ifdef _CM
00338 if (_CM) {
00339 u8_resetIdentified = 1;
00340 outString("Configuration Mismatch.\n");
00341 _CM = 0;
00342 }
00343 #endif
00344 }
00345
00346 if (!u8_resetIdentified) {
00347 outString("Unknown reset.\n");
00348 }
00349 if (sz_lastError != NULL) {
00350 outString("Error trapped: ");
00351 outString(sz_lastError);
00352 if (u16_INTTREGlast != 0) {
00353 #ifndef __PIC24F__
00354 outString("Priority: ");
00355 outUint8(INTTREGBITS_last.ILR);
00356 outString(", Vector number: ");
00357 outUint8(INTTREGBITS_last.VECNUM);
00358 #else
00359 outString("Unknown priority/vector");
00360 #endif
00361 }
00362 outString("\n\n");
00363 sz_lastError = NULL;
00364 u16_INTTREGlast = 0;
00365 }
00366
00367 checkDeviceAndRevision();
00368 checkOscOption();
00369 }
00370
00385
00386 #if (defined(__PIC24HJ32GP202__) || \
00387 defined(__PIC24FJ64GA002__))
00388 void configPinsForLowPower(void) {
00389
00390 TRISB = 0xFFFF;
00391 TRISA = 0xFFFF;
00392
00393 #if defined(__PIC24F__)
00394 AD1PCFG = 0xFFFF;
00395 #elif defined(__PIC24H__)
00396 AD1PCFGL = 0xFFFF;
00397 #else
00398 #error Unknown processor
00399 #endif
00400
00401
00402
00403
00404
00407 #if (FNOSC_SEL == FNOSC_PRI) || (FNOSC_SEL == FNOSC_PRIPLL)
00408 #if (POSCMD_SEL == POSCMD_EC)
00409
00410
00411
00412
00414 CNPU2 = 0xBFFF;
00415 #else
00416
00417
00418
00419
00420 CNPU2 = 0x9FFF;
00421 #endif // #if (POSCMD_SEL == POSCMD_EC)
00422 #else // The primary oscillator is not selected
00423
00424 CNPU2 = 0xFFFF;
00425 #endif
00426
00427
00428
00429 #if (FNOSC_SEL == FNOSC_SOSC)
00430
00431
00433 CNPU1 = 0xFFFC;
00434 #else
00435 CNPU1 = 0xFFFF;
00436 #endif
00437 }
00438 #else
00439 #warning Using dummy function for configPinsForLowPower() in 'common/pic24_util.c'
00440 void configPinsForLowPower(void) {
00441 }
00442 #endif
00443
00444
00454 void configBasic(const char* sz_helloMsg) {
00455 configHeartbeat();
00456 configClock();
00457 configDefaultUART(DEFAULT_BAUDRATE);
00458 printResetCause();
00459 outString(sz_helloMsg);
00460 }
00461