System Management code
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
outDiagnostics/outDiagnostics.cpp@39:ddf38df9699e, 2015-02-11 (annotated)
- Committer:
- pspatel321
- Date:
- Wed Feb 11 23:09:57 2015 +0000
- Revision:
- 39:ddf38df9699e
- Parent:
- 38:8efacce315ae
Updated CAN IDs for datalogging. Changed profile encoding.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pspatel321 | 30:91af74a299e1 | 1 | #include "outDiagnostics.h" |
pspatel321 | 38:8efacce315ae | 2 | #include "outMacros.h" |
pspatel321 | 30:91af74a299e1 | 3 | |
pspatel321 | 38:8efacce315ae | 4 | Timer serialLoop; |
pspatel321 | 38:8efacce315ae | 5 | Timer CANloop; |
pspatel321 | 38:8efacce315ae | 6 | int serialTime_ms = 0; |
pspatel321 | 38:8efacce315ae | 7 | int CANtime_ms = 0; |
pspatel321 | 38:8efacce315ae | 8 | const int max_charsPerLine = 80; // Max chars per line of printed information |
pspatel321 | 34:18bcf276d3bf | 9 | |
pspatel321 | 36:0afc0fc8f86b | 10 | // Use the txEmpty interrupt from MODSERIAL to pace the thread so it always runs as fast as possible |
pspatel321 | 38:8efacce315ae | 11 | osThreadId serialID=0; |
pspatel321 | 38:8efacce315ae | 12 | void empty(MODSERIAL_IRQ_INFO *q) |
pspatel321 | 38:8efacce315ae | 13 | { |
pspatel321 | 36:0afc0fc8f86b | 14 | osSignalSet(serialID, 1); |
pspatel321 | 34:18bcf276d3bf | 15 | } |
pspatel321 | 36:0afc0fc8f86b | 16 | // Output a string to the MODSERIAL tx buffer, wait when buffer full |
pspatel321 | 36:0afc0fc8f86b | 17 | void AddtoBuffer(char *str, bool newline=true) |
pspatel321 | 34:18bcf276d3bf | 18 | { |
pspatel321 | 36:0afc0fc8f86b | 19 | const int waitT = TX_SIZE * CHAR_TIME*1000; // Max wait time to empty the tx buffer = max time to send out all chars |
pspatel321 | 36:0afc0fc8f86b | 20 | int len = strlen(str); |
pspatel321 | 36:0afc0fc8f86b | 21 | int times = newline ? (len + 2) : (len); // If newline requested, add 2 chars for "\r\n" |
pspatel321 | 36:0afc0fc8f86b | 22 | for (int i = 0; i < times; i++) { |
pspatel321 | 36:0afc0fc8f86b | 23 | if (!pc.writeable()) { // Keep writing till it fills |
pspatel321 | 36:0afc0fc8f86b | 24 | osSignalSet((osThreadId)(tempData.wdtThreadId), 1<<3); // Check-in with watchdog thread |
pspatel321 | 36:0afc0fc8f86b | 25 | Thread::signal_wait(1, waitT); // Wait for empty signal from MODSERIAL tx empty interrupt, timeout in waitT ms |
pspatel321 | 34:18bcf276d3bf | 26 | } |
pspatel321 | 36:0afc0fc8f86b | 27 | if (i < len) pc.putc(str[i]); // Print the string |
pspatel321 | 36:0afc0fc8f86b | 28 | else if (i == len) pc.putc('\r'); // Add carriage return |
pspatel321 | 36:0afc0fc8f86b | 29 | else if (i > len) pc.putc('\n'); // Add newline |
pspatel321 | 34:18bcf276d3bf | 30 | } |
pspatel321 | 30:91af74a299e1 | 31 | } |
pspatel321 | 30:91af74a299e1 | 32 | |
pspatel321 | 34:18bcf276d3bf | 33 | // Print to internal string buffer, pad to maxLen chars and center it with char pad, str must be null terminated! |
pspatel321 | 34:18bcf276d3bf | 34 | void padCenter(int LineLen, char *str, char pad) |
pspatel321 | 34:18bcf276d3bf | 35 | { |
pspatel321 | 36:0afc0fc8f86b | 36 | static char line[max_charsPerLine+5]; // String buffer to work with one line at a time |
pspatel321 | 36:0afc0fc8f86b | 37 | int len = strlen(str); // Length of input string |
pspatel321 | 36:0afc0fc8f86b | 38 | int padL = (LineLen-len)/2; // How many pad chars needed on left side? |
pspatel321 | 36:0afc0fc8f86b | 39 | for (int i=0; i<padL; i++) line[i] = pad; // Fill in the left padding chars |
pspatel321 | 36:0afc0fc8f86b | 40 | strcpy(line+padL, str); // Copy to line string |
pspatel321 | 36:0afc0fc8f86b | 41 | for (int i = padL+len; i<LineLen; i++) line[i] = pad; // Fill remaining with padding chars |
pspatel321 | 36:0afc0fc8f86b | 42 | line[LineLen-1] = '\0'; // Add null terminator |
pspatel321 | 34:18bcf276d3bf | 43 | |
pspatel321 | 36:0afc0fc8f86b | 44 | AddtoBuffer(line); |
pspatel321 | 34:18bcf276d3bf | 45 | } |
pspatel321 | 34:18bcf276d3bf | 46 | |
pspatel321 | 34:18bcf276d3bf | 47 | // Generates the serial dashboard, uses MODSERIAL, self-paced (thread yields when buffer is full, resumes when empty) |
pspatel321 | 34:18bcf276d3bf | 48 | void outDiagnostics::thread_serialOut(void const *args) |
pspatel321 | 34:18bcf276d3bf | 49 | { |
pspatel321 | 38:8efacce315ae | 50 | serialID = Thread::gettid(); // Record thread ID so empty() can signal this thread |
pspatel321 | 38:8efacce315ae | 51 | char temp[max_charsPerLine+5]; // String buffer to sprintf into, max 1 line |
pspatel321 | 38:8efacce315ae | 52 | pc.attach(&empty, MODSERIAL::TxEmpty); // Attach the tx empty interrupt which paces this thread |
pspatel321 | 38:8efacce315ae | 53 | pc.printf("\033[2J"); // Clear the screen to get rid of reset message |
pspatel321 | 34:18bcf276d3bf | 54 | |
pspatel321 | 38:8efacce315ae | 55 | // Use these bools to track changes in display mode between iterations |
pspatel321 | 38:8efacce315ae | 56 | bool lastModeExtended = param->extendedSerial; |
pspatel321 | 38:8efacce315ae | 57 | bool inExtendedMode = param->extendedSerial; |
pspatel321 | 30:91af74a299e1 | 58 | |
pspatel321 | 38:8efacce315ae | 59 | // For determining where the data displayed is coming from |
pspatel321 | 38:8efacce315ae | 60 | bool freeze = false; // Not a freeze frame |
pspatel321 | 38:8efacce315ae | 61 | bool notLiveProfile = false; // Live data |
pspatel321 | 38:8efacce315ae | 62 | |
pspatel321 | 38:8efacce315ae | 63 | const char barSpace[4] = { ' ', 179, ' ', 0 }; // Commonly used string with char 179 |
pspatel321 | 38:8efacce315ae | 64 | OperatingInfo* dashOp = op; |
pspatel321 | 38:8efacce315ae | 65 | Profile* dashParam = param; |
pspatel321 | 38:8efacce315ae | 66 | |
pspatel321 | 34:18bcf276d3bf | 67 | serialLoop.reset(); |
pspatel321 | 38:8efacce315ae | 68 | serialLoop.start(); // Start the counter for tracking serial loop time |
pspatel321 | 34:18bcf276d3bf | 69 | |
pspatel321 | 30:91af74a299e1 | 70 | while(1) { |
pspatel321 | 38:8efacce315ae | 71 | serialTime_ms = serialLoop.read_ms(); // Update loop timer, reset for next loop |
pspatel321 | 34:18bcf276d3bf | 72 | serialLoop.reset(); |
pspatel321 | 30:91af74a299e1 | 73 | |
pspatel321 | 38:8efacce315ae | 74 | // Update display mode, change detection used at end of while(1) loop |
pspatel321 | 38:8efacce315ae | 75 | lastModeExtended = inExtendedMode; |
pspatel321 | 38:8efacce315ae | 76 | inExtendedMode = param->extendedSerial; |
pspatel321 | 38:8efacce315ae | 77 | |
pspatel321 | 38:8efacce315ae | 78 | // Determine whether to display freeze frame, change pointers accordingly |
pspatel321 | 38:8efacce315ae | 79 | if (tempData.freeze != NULL) { |
pspatel321 | 38:8efacce315ae | 80 | freeze = true; // Indicate showing freeze |
pspatel321 | 38:8efacce315ae | 81 | dashOp = &(tempData.freeze->op.op); // Point to freeze |
pspatel321 | 38:8efacce315ae | 82 | dashParam = &(tempData.freeze->param.param); // Point to freeze |
pspatel321 | 38:8efacce315ae | 83 | |
pspatel321 | 38:8efacce315ae | 84 | // Determine whether to display a non-live profile, change pointers accordingly |
pspatel321 | 38:8efacce315ae | 85 | } else if (tempData.viewProfile != NULL && tempData.viewProfileNum != -2) { |
pspatel321 | 38:8efacce315ae | 86 | dashParam = tempData.viewProfile; // Point to other profile |
pspatel321 | 38:8efacce315ae | 87 | notLiveProfile = true; // Indicate notLive |
pspatel321 | 38:8efacce315ae | 88 | |
pspatel321 | 38:8efacce315ae | 89 | // Show live data only |
pspatel321 | 38:8efacce315ae | 90 | } else { |
pspatel321 | 38:8efacce315ae | 91 | freeze = false; // Not freeze |
pspatel321 | 38:8efacce315ae | 92 | notLiveProfile = false; // Live profile |
pspatel321 | 38:8efacce315ae | 93 | dashOp = op; // Point to live RAM data |
pspatel321 | 38:8efacce315ae | 94 | dashParam = param; // Point to live RAM data |
pspatel321 | 38:8efacce315ae | 95 | } |
pspatel321 | 38:8efacce315ae | 96 | |
pspatel321 | 34:18bcf276d3bf | 97 | sprintf(temp, "\033[0;0H\033[0;0H"); |
pspatel321 | 38:8efacce315ae | 98 | AddtoBuffer(temp, false); // Move to 0,0, do not append newline |
pspatel321 | 38:8efacce315ae | 99 | |
pspatel321 | 34:18bcf276d3bf | 100 | DIVIDER_LINE |
pspatel321 | 34:18bcf276d3bf | 101 | TITLE(" Penn Electric Racing - REV0 System Management Controller Dashboard ") |
pspatel321 | 34:18bcf276d3bf | 102 | DIVIDER_LINE |
pspatel321 | 38:8efacce315ae | 103 | |
pspatel321 | 34:18bcf276d3bf | 104 | int tempLength=0; |
pspatel321 | 34:18bcf276d3bf | 105 | tempLength += sprintf(temp, "Command Input:%c %s%c", tempData.parseGoodChar, tempData.inputStr, 176); // Command input: print header, reply, input string, and cursor marker |
pspatel321 | 36:0afc0fc8f86b | 106 | for (int i = 0; i < max_charsPerLine - tempLength - 1; i++) { // Fill in the rest of the line with blanks |
pspatel321 | 34:18bcf276d3bf | 107 | tempLength += sprintf(temp+tempLength, " "); // Append spaces |
pspatel321 | 34:18bcf276d3bf | 108 | } |
pspatel321 | 36:0afc0fc8f86b | 109 | AddtoBuffer(temp); // Add this to the chunk |
pspatel321 | 38:8efacce315ae | 110 | |
pspatel321 | 38:8efacce315ae | 111 | const char profile[NUM_STORED_PROFILES+2][8] = {"Freeze", "Default", "1", "2", "3"}; |
pspatel321 | 38:8efacce315ae | 112 | if (inExtendedMode) { |
pspatel321 | 38:8efacce315ae | 113 | |
pspatel321 | 38:8efacce315ae | 114 | // Parameters Section |
pspatel321 | 38:8efacce315ae | 115 | snprintf(temp, max_charsPerLine, " Configuration Parameters %s%s%s%s", freeze?"(Viewing Freeze of Last Fault) ":"", (notLiveProfile && !freeze)?" (Viewing Profile ":"", (notLiveProfile && !freeze)?profile[tempData.viewProfileNum+1]:"", (notLiveProfile && !freeze)?") ":""); |
pspatel321 | 38:8efacce315ae | 116 | TITLE(temp) |
pspatel321 | 38:8efacce315ae | 117 | snprintf(temp, max_charsPerLine, "GLVchar: %5.2fA%sGLVdisch: %5.2fA%sGLVnomCap: %5.2fAh%sGLVtaps: %3d", dashParam->chargeCurrent,barSpace, dashParam->dischargeCurrent,barSpace, dashParam->nominalCapacity,barSpace, dashParam->glvBat_taps); |
pspatel321 | 38:8efacce315ae | 118 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 119 | snprintf(temp, max_charsPerLine, "dcdcThres: %5.2fA%sdcdcOver: %5.2fA%sdcdcStart: %5.2fs %sdcdcStop: %5.2fs", dashParam->dcdcThreshold,barSpace, dashParam->dcdcOverCurrent,barSpace, dashParam->dcdcStartDelay,barSpace, dashParam->dcdcStopDelay); |
pspatel321 | 38:8efacce315ae | 120 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 121 | snprintf(temp, max_charsPerLine, "dcdcTaps: %3d %simdStart: %5.1fs%samsStart: %5.1fs %sIntOverT: %5.1fC", dashParam->dcdc_taps,barSpace, dashParam->imdStartDelay,barSpace, dashParam->amsStartDelay,barSpace, dashParam->internalOverTemp); |
pspatel321 | 38:8efacce315ae | 122 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 123 | snprintf(temp, max_charsPerLine, "CANtxSize: %4d %sCANrxSize: %4d %sSerialBaud: %6d%sSerialTx: %5d", dashParam->CANtxSize,barSpace, dashParam->CANrxSize,barSpace, dashParam->SerialBaud,barSpace, dashParam->SerialTxSize); |
pspatel321 | 38:8efacce315ae | 124 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 125 | BLANK_LINE |
pspatel321 | 38:8efacce315ae | 126 | } |
pspatel321 | 38:8efacce315ae | 127 | snprintf(temp, max_charsPerLine, " Operating Info %s", freeze?"(Viewing Freeze of Last Fault) ":""); |
pspatel321 | 38:8efacce315ae | 128 | TITLE(temp) |
pspatel321 | 38:8efacce315ae | 129 | |
pspatel321 | 38:8efacce315ae | 130 | // Operating mode |
pspatel321 | 38:8efacce315ae | 131 | const char modeStr[3][8] = {"FAULT", "OKAY", "INVALID"}; |
pspatel321 | 38:8efacce315ae | 132 | tempLength = 0; |
pspatel321 | 38:8efacce315ae | 133 | tempLength += sprintf(temp+tempLength, "Sloop: %3dms CANloop: %3dms Time: %s", serialTime_ms, CANtime_ms, ctime(&dashOp->SysTime)); |
pspatel321 | 38:8efacce315ae | 134 | tempLength--; |
pspatel321 | 38:8efacce315ae | 135 | char modeN = dashOp->mode; |
pspatel321 | 38:8efacce315ae | 136 | if (modeN == FAULT) modeN=0; |
pspatel321 | 38:8efacce315ae | 137 | else if (modeN == OKAY) modeN=1; |
pspatel321 | 38:8efacce315ae | 138 | else modeN=2; |
pspatel321 | 38:8efacce315ae | 139 | tempLength += sprintf(temp+tempLength, " Uptime: %5ds", dashOp->SysTime - dashOp->startTime); |
pspatel321 | 34:18bcf276d3bf | 140 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 141 | tempLength = snprintf(temp, max_charsPerLine, "Profile: %7s%10s Mode: %7s%6s Faults: ", profile[dashOp->profileIndex+1], dashOp->profileModded?", MODIFIED":"", modeStr[modeN], dashOp->faultCode?"+ERROR":""); |
pspatel321 | 38:8efacce315ae | 142 | |
pspatel321 | 38:8efacce315ae | 143 | // Fault codes |
pspatel321 | 38:8efacce315ae | 144 | const char topErrStr[12][20] = {"WATCHDOG", "BROWNOUT", "CAN_FAULT", "INT_OVER_TEMP", "IMD_LATCH", "AMS_LATCH", "IMD_FAULT", "DCDC_FAULT", "GLVBAT_FAULT", "FREEZE_FRAME"}; |
pspatel321 | 38:8efacce315ae | 145 | int numFaults = 0; |
pspatel321 | 38:8efacce315ae | 146 | for (int i = 0; i < sizeof(dashOp->faultCode)*8; i++) { |
pspatel321 | 38:8efacce315ae | 147 | if (dashOp->faultCode & (1<<i)) numFaults++; |
pspatel321 | 38:8efacce315ae | 148 | } |
pspatel321 | 38:8efacce315ae | 149 | if (numFaults == 0) tempLength+=sprintf(temp+tempLength, "No Faults"); // Start new appending chain string, faults not present |
pspatel321 | 38:8efacce315ae | 150 | else tempLength+=sprintf(temp+tempLength, "(%d 0x%04x)", numFaults, dashOp->faultCode); // Start new appending chain string, faults present |
pspatel321 | 34:18bcf276d3bf | 151 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 152 | tempLength = 0; |
pspatel321 | 38:8efacce315ae | 153 | temp[0] = 0; |
pspatel321 | 34:18bcf276d3bf | 154 | |
pspatel321 | 38:8efacce315ae | 155 | // Print max number of strings that will fit per line, then dump line and continue till finished all error flags |
pspatel321 | 38:8efacce315ae | 156 | int num = 0; |
pspatel321 | 38:8efacce315ae | 157 | for (int i = 0; i < 29; i++) { |
pspatel321 | 38:8efacce315ae | 158 | if (dashOp->faultCode & (1<<i)) { // Fault found |
pspatel321 | 38:8efacce315ae | 159 | // Room for fault string? |
pspatel321 | 38:8efacce315ae | 160 | if (max_charsPerLine-tempLength > strlen(topErrStr[i])+2) { |
pspatel321 | 38:8efacce315ae | 161 | // Yes, append |
pspatel321 | 38:8efacce315ae | 162 | tempLength += sprintf(temp+tempLength, "%s ", topErrStr[i]); |
pspatel321 | 38:8efacce315ae | 163 | num++; |
pspatel321 | 38:8efacce315ae | 164 | } else { |
pspatel321 | 38:8efacce315ae | 165 | // No, Dump then start new line |
pspatel321 | 38:8efacce315ae | 166 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 167 | tempLength = 0; |
pspatel321 | 38:8efacce315ae | 168 | tempLength += sprintf(temp+tempLength, "%s ", topErrStr[i]); |
pspatel321 | 38:8efacce315ae | 169 | num++; |
pspatel321 | 38:8efacce315ae | 170 | } |
pspatel321 | 38:8efacce315ae | 171 | } |
pspatel321 | 38:8efacce315ae | 172 | if (num >= numFaults || numFaults == 0) { |
pspatel321 | 38:8efacce315ae | 173 | // Done printing all faults |
pspatel321 | 38:8efacce315ae | 174 | tempLength = 0; |
pspatel321 | 38:8efacce315ae | 175 | num = 0; |
pspatel321 | 38:8efacce315ae | 176 | if (numFaults != 0) { |
pspatel321 | 38:8efacce315ae | 177 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 178 | } |
pspatel321 | 38:8efacce315ae | 179 | break; |
pspatel321 | 38:8efacce315ae | 180 | } |
pspatel321 | 38:8efacce315ae | 181 | } |
pspatel321 | 34:18bcf276d3bf | 182 | BLANK_LINE |
pspatel321 | 38:8efacce315ae | 183 | snprintf(temp, max_charsPerLine, "ShtdwnCrct: %6s %s AIRs: %6s %s Charger: %4s %s IntTemp: %5.1f", (dashOp->signals & SHUTDOWN_CLOSED)?"CLOSED":"OPEN", barSpace, (dashOp->signals & AIRS_CLOSED)?"CLOSED":"OPEN", barSpace, (dashOp->signals & CHARGER_DET)?"DET":"NDET", barSpace, dashOp->internalTemp); |
pspatel321 | 34:18bcf276d3bf | 184 | ADD_SPRINTF_LINE |
pspatel321 | 30:91af74a299e1 | 185 | |
pspatel321 | 34:18bcf276d3bf | 186 | BLANK_LINE |
pspatel321 | 38:8efacce315ae | 187 | snprintf(temp, max_charsPerLine, " GLV Battery %s", freeze?"(Viewing Freeze of Last Fault) ":""); |
pspatel321 | 38:8efacce315ae | 188 | TITLE(temp) |
pspatel321 | 38:8efacce315ae | 189 | sprintf(temp, "Current: %4.3fA %s Cap: %4.3fAh %s Ah: %4.3fAh %s SOC: %5.3f", dashOp->glvBat.current, barSpace, dashOp->glvBat.capacity, barSpace, dashOp->glvBat.Ah, barSpace, dashOp->glvBat.SOC); |
pspatel321 | 38:8efacce315ae | 190 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 191 | // GLV Fault codes |
pspatel321 | 38:8efacce315ae | 192 | const char glvBatErrStr[12][20] = {"OVER_CHARGE_I", "OVER_DISCHARGE_I", "CAP_INIT", "SOC_INIT" }; |
pspatel321 | 38:8efacce315ae | 193 | numFaults = 0; |
pspatel321 | 38:8efacce315ae | 194 | for (int i = 0; i < sizeof(dashOp->glvBat.error)*8; i++) { |
pspatel321 | 38:8efacce315ae | 195 | if (dashOp->glvBat.error & (1<<i)) numFaults++; |
pspatel321 | 38:8efacce315ae | 196 | } |
pspatel321 | 38:8efacce315ae | 197 | if (numFaults == 0) tempLength+=sprintf(temp+tempLength, "No Faults"); // Start new appending chain string, faults not present |
pspatel321 | 38:8efacce315ae | 198 | else tempLength+=sprintf(temp+tempLength, "(%d 0x%04x)", numFaults, dashOp->glvBat.error); // Start new appending chain string, faults present |
pspatel321 | 38:8efacce315ae | 199 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 200 | tempLength = 0; |
pspatel321 | 38:8efacce315ae | 201 | temp[0] = 0; |
pspatel321 | 38:8efacce315ae | 202 | |
pspatel321 | 38:8efacce315ae | 203 | // Print max number of strings that will fit per line, then dump line and continue till finished all error flags |
pspatel321 | 38:8efacce315ae | 204 | num = 0; |
pspatel321 | 38:8efacce315ae | 205 | for (int i = 0; i < 29; i++) { |
pspatel321 | 38:8efacce315ae | 206 | if (dashOp->glvBat.error & (1<<i)) { // Fault found |
pspatel321 | 38:8efacce315ae | 207 | // Room for fault string? |
pspatel321 | 38:8efacce315ae | 208 | if (max_charsPerLine-tempLength > strlen(glvBatErrStr[i])+2) { |
pspatel321 | 38:8efacce315ae | 209 | // Yes, append |
pspatel321 | 38:8efacce315ae | 210 | tempLength += sprintf(temp+tempLength, "%s ", glvBatErrStr[i]); |
pspatel321 | 38:8efacce315ae | 211 | num++; |
pspatel321 | 38:8efacce315ae | 212 | } else { |
pspatel321 | 38:8efacce315ae | 213 | // No, Dump then start new line |
pspatel321 | 38:8efacce315ae | 214 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 215 | tempLength = 0; |
pspatel321 | 38:8efacce315ae | 216 | tempLength += sprintf(temp+tempLength, "%s ", glvBatErrStr[i]); |
pspatel321 | 38:8efacce315ae | 217 | num++; |
pspatel321 | 38:8efacce315ae | 218 | } |
pspatel321 | 38:8efacce315ae | 219 | } |
pspatel321 | 38:8efacce315ae | 220 | if (num >= numFaults || numFaults == 0) { |
pspatel321 | 38:8efacce315ae | 221 | // Done printing all faults |
pspatel321 | 38:8efacce315ae | 222 | tempLength = 0; |
pspatel321 | 38:8efacce315ae | 223 | num = 0; |
pspatel321 | 38:8efacce315ae | 224 | if (numFaults != 0) { |
pspatel321 | 38:8efacce315ae | 225 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 226 | } |
pspatel321 | 38:8efacce315ae | 227 | break; |
pspatel321 | 38:8efacce315ae | 228 | } |
pspatel321 | 38:8efacce315ae | 229 | } |
pspatel321 | 38:8efacce315ae | 230 | |
pspatel321 | 34:18bcf276d3bf | 231 | BLANK_LINE |
pspatel321 | 38:8efacce315ae | 232 | snprintf(temp, max_charsPerLine, " DC-DC Converter %s", freeze?"(Viewing Freeze of Last Fault) ":""); |
pspatel321 | 38:8efacce315ae | 233 | TITLE(temp) |
pspatel321 | 38:8efacce315ae | 234 | char DCDC = dashOp->dcdc.status; |
pspatel321 | 38:8efacce315ae | 235 | const char dcdcModesStr[5][12] = {"INVALID","POWER-UP","POWER-DOWN","SET-ON","SET-OFF"}; |
pspatel321 | 38:8efacce315ae | 236 | int dcdcMode = 0; |
pspatel321 | 38:8efacce315ae | 237 | if (DCDC & POWER_UP) dcdcMode = 1; |
pspatel321 | 38:8efacce315ae | 238 | else if (DCDC & POWER_DOWN) dcdcMode = 2; |
pspatel321 | 38:8efacce315ae | 239 | else if (DCDC & SET_ON) dcdcMode = 3; |
pspatel321 | 38:8efacce315ae | 240 | else if (!(DCDC & SET_ON)) dcdcMode = 4; |
pspatel321 | 38:8efacce315ae | 241 | sprintf(temp, "Active: %3s %s Mode: %10s %s Status: 0x%02x", (DCDC & CONV_ON)?"YES":"NO", barSpace, dcdcModesStr[dcdcMode], barSpace, DCDC); |
pspatel321 | 34:18bcf276d3bf | 242 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 243 | sprintf(temp, "Current: %5.2fA %s Overcurrent: %3s %s SensorFault: %3s", dashOp->dcdc.current,barSpace, (DCDC & OVER_CURRENT)?"ERR":"OK",barSpace, (DCDC & SENSOR_FAULT)?"ERR":"OK"); |
pspatel321 | 34:18bcf276d3bf | 244 | ADD_SPRINTF_LINE |
pspatel321 | 30:91af74a299e1 | 245 | |
pspatel321 | 34:18bcf276d3bf | 246 | BLANK_LINE |
pspatel321 | 38:8efacce315ae | 247 | snprintf(temp, max_charsPerLine, " DC-DC PWM Channels %s", freeze?"(Viewing Freeze of Last Fault) ":""); |
pspatel321 | 38:8efacce315ae | 248 | TITLE(temp) |
pspatel321 | 38:8efacce315ae | 249 | sprintf(temp, "Actual: FAN1: %5.3f FAN2: %5.3f %s PUMP1: %5.3f PUMP2: %5.3f", dashOp->dcdc.actual.fan1, dashOp->dcdc.actual.fan2, barSpace, dashOp->dcdc.actual.pump1, dashOp->dcdc.actual.pump2); |
pspatel321 | 38:8efacce315ae | 250 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 251 | sprintf(temp, "Requested: FAN1: %5.3f FAN2: %5.3f %s PUMP1: %5.3f PUMP2: %5.3f", dashOp->dcdc.request.fan1, dashOp->dcdc.request.fan2, barSpace, dashOp->dcdc.request.pump1, dashOp->dcdc.request.pump2); |
pspatel321 | 34:18bcf276d3bf | 252 | ADD_SPRINTF_LINE |
pspatel321 | 34:18bcf276d3bf | 253 | |
pspatel321 | 34:18bcf276d3bf | 254 | BLANK_LINE |
pspatel321 | 38:8efacce315ae | 255 | snprintf(temp, max_charsPerLine, " IMD %s", freeze?"(Viewing Freeze of Last Fault) ":""); |
pspatel321 | 38:8efacce315ae | 256 | TITLE(temp) |
pspatel321 | 39:ddf38df9699e | 257 | char imdStatN=6; |
pspatel321 | 39:ddf38df9699e | 258 | if (dashOp->imd.status & OFF) imdStatN=0; |
pspatel321 | 39:ddf38df9699e | 259 | if (dashOp->imd.status & NORMAL) imdStatN=1; |
pspatel321 | 39:ddf38df9699e | 260 | if (dashOp->imd.status & UNDERVOLT) imdStatN=2; |
pspatel321 | 39:ddf38df9699e | 261 | if (dashOp->imd.status & SPEEDSTART) imdStatN=3; |
pspatel321 | 39:ddf38df9699e | 262 | if (dashOp->imd.status & ERROR) imdStatN=4; |
pspatel321 | 39:ddf38df9699e | 263 | if (dashOp->imd.status & GROUNDERR) imdStatN=5; |
pspatel321 | 39:ddf38df9699e | 264 | const char IMDstr[7][12] = {"OFF","NORMAL","UNDERVOLT","SPEEDSTART","ERROR","GROUNDERR","INVALID"}; |
pspatel321 | 39:ddf38df9699e | 265 | sprintf(temp, "Status: %10s Resistance: %7.0fKohm Error: %3s", IMDstr[imdStatN], dashOp->imd.resistance/1.0e3, dashOp->imd.error?"ERR":"OK"); |
pspatel321 | 34:18bcf276d3bf | 266 | ADD_SPRINTF_LINE |
pspatel321 | 30:91af74a299e1 | 267 | |
pspatel321 | 34:18bcf276d3bf | 268 | BLANK_LINE |
pspatel321 | 38:8efacce315ae | 269 | snprintf(temp, max_charsPerLine, " Latch Monitors %s", freeze?"(Viewing Freeze of Last Fault) ":""); |
pspatel321 | 38:8efacce315ae | 270 | TITLE(temp) |
pspatel321 | 38:8efacce315ae | 271 | char AMSerr = dashOp->latch.ams; |
pspatel321 | 38:8efacce315ae | 272 | char IMDerr = dashOp->latch.imd; |
pspatel321 | 38:8efacce315ae | 273 | sprintf(temp, "AMS - OK: %4s Latch: %3s SoftFault: %3s HardFault: %3s", (AMSerr & OK_FAULT)?"LOW":"HIGH", (AMSerr & LATCHED_HARD)?"ERR":"OK", (AMSerr & LATCHED_SOFT)?"ERR":"OK", (AMSerr & HARD_FAULT)?"ERR":"OK"); |
pspatel321 | 38:8efacce315ae | 274 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 275 | sprintf(temp, "IMD - OK: %4s Latch: %3s SoftFault: %3s HardFault: %3s", (IMDerr & OK_FAULT)?"LOW":"HIGH", (IMDerr & LATCHED_HARD)?"ERR":"OK", (IMDerr & LATCHED_SOFT)?"ERR":"OK", (IMDerr & HARD_FAULT)?"ERR":"OK"); |
pspatel321 | 38:8efacce315ae | 276 | ADD_SPRINTF_LINE |
pspatel321 | 38:8efacce315ae | 277 | |
pspatel321 | 34:18bcf276d3bf | 278 | BLANK_LINE |
pspatel321 | 38:8efacce315ae | 279 | snprintf(temp, max_charsPerLine, " Shutdown Switches %s", freeze?"(Viewing Freeze of Last Fault) ":""); |
pspatel321 | 38:8efacce315ae | 280 | TITLE(temp) |
pspatel321 | 38:8efacce315ae | 281 | char switches = dashOp->switchState; |
pspatel321 | 30:91af74a299e1 | 282 | const char switchNames[12][26] = {"FUSE","AMS LATCH","IMD LATCH","PCM RELAY","BRAKE PLAUSIBILITY RELAY","LEFT E-STOP","INERTIA SWITCH","BRAKE OVER-TRAVEL SWITCH","COCKPIT E-STOP","RIGHT E-STOP","HVD","TSMS"}; |
pspatel321 | 30:91af74a299e1 | 283 | if (switches == 0) sprintf(temp, "All switches are CLOSED."); |
pspatel321 | 30:91af74a299e1 | 284 | else sprintf(temp, "%s is OPEN.", switchNames[switches-1]); |
pspatel321 | 30:91af74a299e1 | 285 | ADD_SPRINTF_LINE |
pspatel321 | 33:6bc82b6b62e5 | 286 | |
pspatel321 | 38:8efacce315ae | 287 | // Erase screen every few counts to remove glitches |
pspatel321 | 38:8efacce315ae | 288 | static int count = 0; |
pspatel321 | 38:8efacce315ae | 289 | if (count % 50 == 0 || lastModeExtended != inExtendedMode) { |
pspatel321 | 38:8efacce315ae | 290 | sprintf(temp, "\033[2J"); |
pspatel321 | 38:8efacce315ae | 291 | AddtoBuffer(temp, false); // Clear the screen |
pspatel321 | 31:7eaa5e881b56 | 292 | } |
pspatel321 | 31:7eaa5e881b56 | 293 | count++; |
pspatel321 | 30:91af74a299e1 | 294 | } |
pspatel321 | 30:91af74a299e1 | 295 | } |
pspatel321 | 30:91af74a299e1 | 296 | |
pspatel321 | 34:18bcf276d3bf | 297 | void outDiagnostics::thread_canOut(void const *args) |
pspatel321 | 34:18bcf276d3bf | 298 | { |
pspatel321 | 38:8efacce315ae | 299 | bool lastCANnoAck = param->CANnoAck; // Get initial noAck mode setting |
pspatel321 | 38:8efacce315ae | 300 | bool thisCANnoAck = param->CANnoAck; |
pspatel321 | 38:8efacce315ae | 301 | |
pspatel321 | 38:8efacce315ae | 302 | if (param->CANnoAck) { // Turn on noack mode |
pspatel321 | 38:8efacce315ae | 303 | can.mode(NoAck); |
pspatel321 | 38:8efacce315ae | 304 | } else { // Setup normal mode |
pspatel321 | 38:8efacce315ae | 305 | can.mode(Normal); |
pspatel321 | 38:8efacce315ae | 306 | } |
pspatel321 | 38:8efacce315ae | 307 | can.mode(FIFO); |
pspatel321 | 38:8efacce315ae | 308 | |
pspatel321 | 38:8efacce315ae | 309 | CANloop.reset(); |
pspatel321 | 38:8efacce315ae | 310 | CANloop.start(); |
pspatel321 | 38:8efacce315ae | 311 | |
pspatel321 | 30:91af74a299e1 | 312 | while(1) { |
pspatel321 | 30:91af74a299e1 | 313 | |
pspatel321 | 38:8efacce315ae | 314 | CANtime_ms = CANloop.read_ms(); |
pspatel321 | 38:8efacce315ae | 315 | CANloop.reset(); |
pspatel321 | 38:8efacce315ae | 316 | |
pspatel321 | 38:8efacce315ae | 317 | // Update last and this variables to check for changes in noAck mode |
pspatel321 | 38:8efacce315ae | 318 | lastCANnoAck = thisCANnoAck; |
pspatel321 | 38:8efacce315ae | 319 | thisCANnoAck = param->CANnoAck; |
pspatel321 | 38:8efacce315ae | 320 | if (thisCANnoAck && !lastCANnoAck) { // NoAck mode turn on |
pspatel321 | 38:8efacce315ae | 321 | can.mode(NoAck); |
pspatel321 | 38:8efacce315ae | 322 | can.mode(FIFO); |
pspatel321 | 38:8efacce315ae | 323 | can.txFlush(); // Must flush buffer when switching modes, or else buffer gets stuck |
pspatel321 | 38:8efacce315ae | 324 | } |
pspatel321 | 38:8efacce315ae | 325 | if (!thisCANnoAck && lastCANnoAck) { // NoAck mode turn off |
pspatel321 | 38:8efacce315ae | 326 | can.mode(Normal); |
pspatel321 | 38:8efacce315ae | 327 | can.mode(FIFO); |
pspatel321 | 38:8efacce315ae | 328 | can.txFlush(); // Must flush buffer when switching modes, or else buffer gets stuck |
pspatel321 | 38:8efacce315ae | 329 | } |
pspatel321 | 38:8efacce315ae | 330 | |
pspatel321 | 38:8efacce315ae | 331 | // OPERATING DIAGNOSTICS |
pspatel321 | 38:8efacce315ae | 332 | // Error Frame |
pspatel321 | 39:ddf38df9699e | 333 | CAN_SINGLE(faultCode, FAULTCODE_TX_ID) |
pspatel321 | 38:8efacce315ae | 334 | |
pspatel321 | 38:8efacce315ae | 335 | // Mode |
pspatel321 | 39:ddf38df9699e | 336 | CAN_SINGLE(mode, MODE_TX_ID) |
pspatel321 | 38:8efacce315ae | 337 | |
pspatel321 | 38:8efacce315ae | 338 | // Flags |
pspatel321 | 39:ddf38df9699e | 339 | CAN_SINGLE(signals, SIGNALS_TX_ID) |
pspatel321 | 38:8efacce315ae | 340 | |
pspatel321 | 38:8efacce315ae | 341 | // Profile |
pspatel321 | 39:ddf38df9699e | 342 | char byte=0; |
pspatel321 | 39:ddf38df9699e | 343 | byte = (op->profileIndex != -1)? 1 << op->profileIndex : 1<<6; |
pspatel321 | 39:ddf38df9699e | 344 | byte |= (op->profileModded) ? 1<<7 : 0; // Mark the last bit of the byte if the profile was modified (OR'd with profile id from above) |
pspatel321 | 39:ddf38df9699e | 345 | SEND_CAN_SINGLE(byte, PROFILE_TX_ID); |
pspatel321 | 38:8efacce315ae | 346 | |
pspatel321 | 38:8efacce315ae | 347 | // Time |
pspatel321 | 39:ddf38df9699e | 348 | CAN_PAIR(SysTime, startTime, TIME_TX_ID) |
pspatel321 | 34:18bcf276d3bf | 349 | |
pspatel321 | 31:7eaa5e881b56 | 350 | // Internal temperature |
pspatel321 | 39:ddf38df9699e | 351 | CAN_SINGLE(internalTemp, TEMP_TX_ID) |
pspatel321 | 31:7eaa5e881b56 | 352 | |
pspatel321 | 31:7eaa5e881b56 | 353 | // GLV Battery |
pspatel321 | 39:ddf38df9699e | 354 | CAN_SINGLE(glvBat.current, GLV_CURRENT_TX_ID) |
pspatel321 | 39:ddf38df9699e | 355 | CAN_SINGLE(glvBat.capacity, GLV_CAPACITY_TX_ID) |
pspatel321 | 39:ddf38df9699e | 356 | CAN_SINGLE(glvBat.Ah, GLV_AH_TX_ID) |
pspatel321 | 39:ddf38df9699e | 357 | CAN_SINGLE(glvBat.SOC, GLV_SOC_TX_ID) |
pspatel321 | 39:ddf38df9699e | 358 | CAN_SINGLE(glvBat.error, GLV_ERROR_TX_ID) |
pspatel321 | 38:8efacce315ae | 359 | |
pspatel321 | 31:7eaa5e881b56 | 360 | // DC-DC Converter |
pspatel321 | 39:ddf38df9699e | 361 | CAN_SINGLE(dcdc.current, DCDC_CURRENT_TX_ID) |
pspatel321 | 39:ddf38df9699e | 362 | CAN_SINGLE(dcdc.status, DCDC_STATUS_TX_ID) |
pspatel321 | 31:7eaa5e881b56 | 363 | |
pspatel321 | 34:18bcf276d3bf | 364 | // PWM Channels |
pspatel321 | 39:ddf38df9699e | 365 | CAN_PAIR(dcdc.actual.fan1, dcdc.actual.fan2, PWM_FAN_TX_ID) |
pspatel321 | 39:ddf38df9699e | 366 | CAN_PAIR(dcdc.actual.pump1, dcdc.actual.pump2, PWM_PUMP_TX_ID) |
pspatel321 | 31:7eaa5e881b56 | 367 | |
pspatel321 | 31:7eaa5e881b56 | 368 | // IMD |
pspatel321 | 39:ddf38df9699e | 369 | CAN_SINGLE(imd.status, IMD_STATUS_TX_ID) |
pspatel321 | 39:ddf38df9699e | 370 | CAN_SINGLE(imd.resistance, IMD_RESIST_TX_ID) |
pspatel321 | 31:7eaa5e881b56 | 371 | |
pspatel321 | 31:7eaa5e881b56 | 372 | // Latches |
pspatel321 | 39:ddf38df9699e | 373 | CAN_SINGLE(latch.imd, IMD_LATCH_TX_ID) |
pspatel321 | 39:ddf38df9699e | 374 | CAN_SINGLE(latch.ams, AMS_LATCH_TX_ID) |
pspatel321 | 31:7eaa5e881b56 | 375 | |
pspatel321 | 31:7eaa5e881b56 | 376 | // Shutdown Switches |
pspatel321 | 39:ddf38df9699e | 377 | uint16_t tmp=0; |
pspatel321 | 39:ddf38df9699e | 378 | if (op->switchState != 0) tmp |= 1 << (op->switchState-1); |
pspatel321 | 39:ddf38df9699e | 379 | SEND_CAN_SINGLE(tmp, SWITCHES_TX_ID); |
pspatel321 | 38:8efacce315ae | 380 | |
pspatel321 | 36:0afc0fc8f86b | 381 | osSignalSet((osThreadId)(tempData.wdtThreadId), 1<<4); // Signal watchdog thread |
pspatel321 | 33:6bc82b6b62e5 | 382 | Thread::wait(CAN_LOOP*1000); |
pspatel321 | 34:18bcf276d3bf | 383 | } |
pspatel321 | 30:91af74a299e1 | 384 | } |