pic24_util.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
00039 #include "pic24_all.h"
00040 #include <stdio.h>
00041
00042
00043 #if !USE_HEARTBEAT && !defined(__DOXYGEN__)
00044
00045 void configHeartbeat(void) {
00046 }
00047
00048 void doHeartbeat(void) {
00049 }
00050
00051 void toggleHeartbeat(void) {
00052 }
00053 #else
00054
00067 uint32 u32_heartbeatCount;
00071 static uint32 u32_heartbeatMax;
00072
00073
00078 void configHeartbeat(void) {
00079 CONFIG_HB_LED();
00080
00081
00082
00083
00084 u32_heartbeatMax = CYCLES_PER_MS * 10;
00085 u32_heartbeatCount = 0;
00086 HB_LED = 0;
00087 doHeartbeat();
00088 }
00089
00094 void doHeartbeat(void) {
00095 u32_heartbeatCount++;
00096 if (u32_heartbeatCount > u32_heartbeatMax) {
00097 toggleHeartbeat();
00098 u32_heartbeatCount = 0;
00099 }
00100 }
00101
00102
00106 void toggleHeartbeat(void) {
00107 HB_LED = !HB_LED;
00108 }
00110 #endif
00111
00116 static _PERSISTENT const char* sz_lastError;
00120 _PERSISTENT char* sz_lastTimeoutError;
00121
00122 #ifndef __PIC24F__
00123
00130 static _PERSISTENT INTTREGBITS INTTREGBITS_last;
00136 #define u16_INTTREGlast BITS2WORD(INTTREGBITS_last)
00137 #else
00138 static uint16 u16_INTTREGlast;
00139 #endif
00140
00146 void _ISR _DefaultInterrupt(void) {
00147 #ifndef __PIC24F__
00148
00149
00150 u16_INTTREGlast = INTTREG;
00151 #else
00152
00153
00154 u16_INTTREGlast = 1;
00155 #endif
00156 reportError("Unhandled interrupt, ");
00157 }
00158
00159
00167 void reportError(const char* sz_errorMessage) {
00168
00169 if (sz_lastError == NULL) {
00170 sz_lastError = sz_errorMessage;
00171 asm ("reset");
00172 }
00173 }
00174
00180 uint32 readProgramMemory(uint32 u32_address) {
00181 uint16 u16_offset = u32_address;
00182 TBLPAG = u32_address >> 16;
00183 return ( ((uint32) __builtin_tblrdh(u16_offset)) << 16) |
00184 __builtin_tblrdl(u16_offset);
00185 }
00186
00192 void checkDeviceAndRevision(void) {
00193 #ifdef SIM
00194 outString("**** SIMULATION MODE: cannot read device and revision ID ****\n");
00195 #else
00196 uint32 devID = readProgramMemory(DEV_ID_LOCATION);
00197 uint32 revision = readProgramMemory(REVISION_LOCATION);
00198 uint8 correctChip = 1;
00199 char* devIDStr = "unknown";
00200 char* revisionStr = "unknown";
00201
00202 if (devID == DEV_ID)
00203 devIDStr = DEV_ID_STR;
00204 else
00205 correctChip = 0;
00206
00207 switch (revision) {
00208 case EXPECTED_REVISION1 :
00209 revisionStr = EXPECTED_REVISION1_STR;
00210 break;
00211 #ifdef EXPECTED_REVISION2
00212 case EXPECTED_REVISION2 :
00213 revisionStr = EXPECTED_REVISION2_STR;
00214 break;
00215 #endif
00216 #ifdef EXPECTED_REVISION3
00217 case EXPECTED_REVISION3 :
00218 revisionStr = EXPECTED_REVISION3_STR;
00219 break;
00220 #endif
00221 #ifdef EXPECTED_REVISION4
00222 case EXPECTED_REVISION4 :
00223 revisionStr = EXPECTED_REVISION4_STR;
00224 break;
00225 #endif
00226 #ifdef EXPECTED_REVISION5
00227 case EXPECTED_REVISION5 :
00228 revisionStr = EXPECTED_REVISION5_STR;
00229 break;
00230 #endif
00231 default :
00232 correctChip = 0;
00233 break;
00234 }
00235
00236 outString("Device ID = ");
00237 outUint32(devID);
00238 outString(" (");
00239 outString(devIDStr);
00240 outString("), revision ");
00241 outUint32(revision);
00242 outString(" (");
00243 outString(revisionStr);
00244 outString(")\n");
00245
00246 if (!correctChip)
00247 outString("\n\n"
00248 "*****************************************************\n"
00249 "* WARNING - this program was compiled for the wrong *\n"
00250 "* chip or for an unknown revision of this chip! *\n"
00251 "* This program may produce unexpected behvior! Edit *\n"
00252 "* the header files to properly define this chip or *\n"
00253 "* revision and to insure correct operation. *\n"
00254 "* *\n"
00255 "* NOTE: If this was compiled for the correct chip, *\n"
00256 "* and only occurs at power-on (not during a MCLR *\n"
00257 "* reset, verify that AVDD and AVSS are connected. *\n"
00258 "* On the PIC24H32GP202, not connecting AVDD *\n"
00259 "* produces this message only at power-up. *\n"
00260 "*****************************************************\n");
00261 #endif
00262 }
00263
00267 void checkOscOption(void) {
00268 uint8 u8_x;
00269
00270 u8_x = _COSC;
00271 switch (u8_x) {
00272 case 0:
00273 outString("Fast RC Osc\n");
00274 break;
00275 case 1:
00276 outString("Fast RC Osc with PLL\n");
00277 break;
00278 case 2:
00279 outString("Primary Osc (XT, HS, EC)\n");
00280 break;
00281 case 3:
00282 outString("Primary Osc (XT, HS, EC) with PLL\n");
00283 break;
00284 case 4:
00285 outString("Secondary Osc\n");
00286 break;
00287 case 5:
00288 outString("Low Power RC Osc\n");
00289 break;
00290 #if defined(__PIC24H__) || defined(__dsPIC33F__)
00291 case 6:
00292 outString("Fast RC Osc/16\n");
00293 break;
00294 case 7:
00295 outString("Fast RC Osc/N\n");
00296 break;
00297 #elif ( defined(__PIC24F__) || defined(__PIC24FK__) )
00298 case 7 :
00299 outString("Fast RC Osc with Postscale");
00300 break;
00301 #else
00302 #error Unknown processor
00303 #endif
00304 default :
00305 reportError("Unknown oscillator type.");
00306 break;
00307 }
00308 }
00309
00314 void printResetCause(void) {
00315 uint8 u8_resetIdentified;
00316
00317 u8_resetIdentified = 0;
00318 if (_SLEEP) {
00319 outString("\nDevice has been in sleep mode\n");
00320 _SLEEP = 0;
00321 }
00322 if (_IDLE) {
00323 outString("\nDevice has been in idle mode\n");
00324 _IDLE = 0;
00325 }
00326 outString("\nReset cause: ");
00327 if (_POR) {
00328 u8_resetIdentified = 1;
00329 outString("Power-on.\n");
00330 _POR = 0;
00331 _BOR = 0;
00332
00333
00334
00335 sz_lastError = NULL;
00336 sz_lastTimeoutError = NULL;
00337 u16_INTTREGlast = 0;
00338 } else {
00339
00340 if (_SWR) {
00341 outString("Software Reset.\n");
00342 u8_resetIdentified = 1;
00343 _SWR = 0;
00344 _EXTR = 0;
00345 }
00346 if (_WDTO) {
00347 u8_resetIdentified = 1;
00348 outString("Watchdog Timeout: ");
00349 if (sz_lastTimeoutError != NULL) {
00350 outString(sz_lastTimeoutError);
00351 }
00352 outString("\n");
00353 _WDTO = 0;
00354 _EXTR = 0;
00355 }
00356 if (_EXTR) {
00357 u8_resetIdentified = 1;
00358 outString("MCLR assertion.\n");
00359 _EXTR = 0;
00360 }
00361 if (_BOR) {
00362 u8_resetIdentified = 1;
00363 outString("Brown-out.\n");
00364 _BOR = 0;
00365 }
00366 if (_TRAPR) {
00367 u8_resetIdentified = 1;
00368 outString("Trap Conflict.\n");
00369 _TRAPR = 0;
00370 }
00371 if (_IOPUWR) {
00372 u8_resetIdentified = 1;
00373 outString("Illegal Condition.\n");
00374 _IOPUWR = 0;
00375 }
00376 #ifdef _CM
00377 if (_CM) {
00378 u8_resetIdentified = 1;
00379 outString("Configuration Mismatch.\n");
00380 _CM = 0;
00381 }
00382 #endif
00383 }
00384
00385 if (!u8_resetIdentified) {
00386 outString("Unknown reset.\n");
00387 }
00388 if (sz_lastError != NULL) {
00389 outString("Error trapped: ");
00390 outString(sz_lastError);
00391 if (u16_INTTREGlast != 0) {
00392 #if ( defined(__PIC24H__) || defined(__dsPIC33F__) )
00393 outString("Priority: ");
00394 outUint8(INTTREGBITS_last.ILR);
00395 outString(", Vector number: ");
00396 outUint8(INTTREGBITS_last.VECNUM);
00397 #else
00398 outString("Unknown priority/vector");
00399 #endif
00400 }
00401 outString("\n\n");
00402 sz_lastError = NULL;
00403 u16_INTTREGlast = 0;
00404 }
00405
00406 checkDeviceAndRevision();
00407 checkOscOption();
00408 }
00409
00424
00425 #if (defined(__PIC24HJ32GP202__) || \
00426 defined(__PIC24FJ64GA002__))
00427 void configPinsForLowPower(void) {
00428
00429 TRISB = 0xFFFF;
00430 TRISA = 0xFFFF;
00431
00432 #if defined(__PIC24F__)
00433 AD1PCFG = 0xFFFF;
00434 #elif defined(__PIC24H__)
00435 AD1PCFGL = 0xFFFF;
00436 #else
00437 #error Unknown processor
00438 #endif
00439
00440
00441
00442
00443
00446 #if (FNOSC_SEL == FNOSC_PRI) || (FNOSC_SEL == FNOSC_PRIPLL)
00447 #if (POSCMD_SEL == POSCMD_EC)
00448
00449
00450
00451
00453 CNPU2 = 0xBFFF;
00454 #else
00455
00456
00457
00458
00459 CNPU2 = 0x9FFF;
00460 #endif // #if (POSCMD_SEL == POSCMD_EC)
00461 #else // The primary oscillator is not selected
00462
00463 CNPU2 = 0xFFFF;
00464 #endif
00465
00466
00467
00468 #if (FNOSC_SEL == FNOSC_SOSC)
00469
00470
00472 CNPU1 = 0xFFFC;
00473 #else
00474 CNPU1 = 0xFFFF;
00475 #endif
00476 }
00477 #else
00478 #warning Using dummy function for configPinsForLowPower() in 'common/pic24_util.c'
00479 void configPinsForLowPower(void) {
00480 }
00481 #endif
00482
00483
00493 void configBasic(const char* sz_helloMsg) {
00494 configHeartbeat();
00495 configClock();
00496 configDefaultUART(DEFAULT_BAUDRATE);
00497 printResetCause();
00498 outString(sz_helloMsg);
00499 }
00500
00501
00506 uint32 roundFloatToUint32(float f_x) {
00507 uint32 u32_y;
00508
00509 u32_y = f_x;
00510 if ((f_x - u32_y) < 0.5) return u32_y;
00511 else return u32_y+1;
00512 }
00513
00515 uint16 roundFloatToUint16(float f_x) {
00516 uint16 u16_y;
00517
00518 u16_y = f_x;
00519 if ((f_x - u16_y) < 0.5) return u16_y;
00520 else return u16_y+1;
00521 }
00522
00523