System Management code
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
inCommands/inCommands.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 | 34:18bcf276d3bf | 1 | #include "inCommands.h" |
pspatel321 | 38:8efacce315ae | 2 | #include "runTime.h" |
pspatel321 | 38:8efacce315ae | 3 | #include "inMacros.h" |
pspatel321 | 34:18bcf276d3bf | 4 | |
pspatel321 | 34:18bcf276d3bf | 5 | // Compare string to a word in the serial input, shorter to type |
pspatel321 | 34:18bcf276d3bf | 6 | #define CMP(w, string) if (!strcasecmp(word[w-1], string)) |
pspatel321 | 36:0afc0fc8f86b | 7 | |
pspatel321 | 34:18bcf276d3bf | 8 | // Serial input |
pspatel321 | 38:8efacce315ae | 9 | int serviceSerial() |
pspatel321 | 34:18bcf276d3bf | 10 | { |
pspatel321 | 38:8efacce315ae | 11 | static int end = 0; // End of string position |
pspatel321 | 34:18bcf276d3bf | 12 | |
pspatel321 | 36:0afc0fc8f86b | 13 | int c=0; |
pspatel321 | 36:0afc0fc8f86b | 14 | if (pc.readable()) c = pc.getc(); |
pspatel321 | 38:8efacce315ae | 15 | if (c == -1 || c == 0) return 0; |
pspatel321 | 38:8efacce315ae | 16 | |
pspatel321 | 34:18bcf276d3bf | 17 | char b = c; // Casted to char type |
pspatel321 | 34:18bcf276d3bf | 18 | bool process = false; // Is string complete (ready to parse)? |
pspatel321 | 34:18bcf276d3bf | 19 | |
pspatel321 | 34:18bcf276d3bf | 20 | if (b == '\n' || b == '\r') { // Enter key was pressed, dump for processing |
pspatel321 | 34:18bcf276d3bf | 21 | tempData.inputStr[end] = 0; // Null terminate |
pspatel321 | 34:18bcf276d3bf | 22 | end = 0; // Reset to start |
pspatel321 | 34:18bcf276d3bf | 23 | process = true; // Flag for processing |
pspatel321 | 34:18bcf276d3bf | 24 | |
pspatel321 | 34:18bcf276d3bf | 25 | } else if (b == '\b' || b == 127) { // Backspace or delete |
pspatel321 | 34:18bcf276d3bf | 26 | if (end > 0) end--; // Move back one char |
pspatel321 | 34:18bcf276d3bf | 27 | tempData.inputStr[end] = 0; // Erase char |
pspatel321 | 34:18bcf276d3bf | 28 | |
pspatel321 | 34:18bcf276d3bf | 29 | } else if (b > 31 && b < 127) { // New valid displayable char |
pspatel321 | 36:0afc0fc8f86b | 30 | tempData.inputStr[end++] = b; // Add to buffer |
pspatel321 | 34:18bcf276d3bf | 31 | tempData.inputStr[end] = 0; // Add null terminator |
pspatel321 | 34:18bcf276d3bf | 32 | if (end >= RX_SIZE) { |
pspatel321 | 34:18bcf276d3bf | 33 | end = 0; // Reset end location |
pspatel321 | 34:18bcf276d3bf | 34 | process = true; // Flag for processing |
pspatel321 | 34:18bcf276d3bf | 35 | } |
pspatel321 | 34:18bcf276d3bf | 36 | } |
pspatel321 | 34:18bcf276d3bf | 37 | // Continue to parsing section only if flagged as complete and string not empty |
pspatel321 | 36:0afc0fc8f86b | 38 | if (!process || strlen((char*)tempData.inputStr) == 0) return 0; |
pspatel321 | 38:8efacce315ae | 39 | |
pspatel321 | 36:0afc0fc8f86b | 40 | static char word[3][RX_SIZE+1]; // Hold 3 words |
pspatel321 | 34:18bcf276d3bf | 41 | int pieces = sscanf(tempData.inputStr, "%s %s %s", word[0], word[1], word[2]); // Populate words |
pspatel321 | 34:18bcf276d3bf | 42 | tempData.inputStr[0] = 0; // Empty the string displayed on screen |
pspatel321 | 36:0afc0fc8f86b | 43 | char *next; // Used by strtof and strtoul |
pspatel321 | 34:18bcf276d3bf | 44 | |
pspatel321 | 34:18bcf276d3bf | 45 | // One word commands |
pspatel321 | 34:18bcf276d3bf | 46 | if (pieces == 1) { |
pspatel321 | 34:18bcf276d3bf | 47 | // Reset the microcontroller |
pspatel321 | 34:18bcf276d3bf | 48 | CMP(1, "reset") { |
pspatel321 | 34:18bcf276d3bf | 49 | NVIC_SystemReset(); |
pspatel321 | 34:18bcf276d3bf | 50 | return 1; |
pspatel321 | 34:18bcf276d3bf | 51 | } |
pspatel321 | 38:8efacce315ae | 52 | // Clear non-volatile fault flags, then reset the microcontroller |
pspatel321 | 38:8efacce315ae | 53 | CMP(1, "resetClear") { |
pspatel321 | 38:8efacce315ae | 54 | runTime::clearFaults(); |
pspatel321 | 38:8efacce315ae | 55 | NVIC_SystemReset(); |
pspatel321 | 38:8efacce315ae | 56 | return 1; |
pspatel321 | 38:8efacce315ae | 57 | } |
pspatel321 | 38:8efacce315ae | 58 | return -1; |
pspatel321 | 34:18bcf276d3bf | 59 | } |
pspatel321 | 36:0afc0fc8f86b | 60 | // Two word commands |
pspatel321 | 34:18bcf276d3bf | 61 | if (pieces == 2) { |
pspatel321 | 38:8efacce315ae | 62 | // Change the serial dashboard display mode |
pspatel321 | 38:8efacce315ae | 63 | CMP(1, "display") { |
pspatel321 | 38:8efacce315ae | 64 | CMP(2, "compact") { |
pspatel321 | 38:8efacce315ae | 65 | if (param->change_extendedSerial(0)) { |
pspatel321 | 38:8efacce315ae | 66 | op->profileModded=true; |
pspatel321 | 38:8efacce315ae | 67 | return 1; // Change function defined by macro |
pspatel321 | 38:8efacce315ae | 68 | } |
pspatel321 | 38:8efacce315ae | 69 | } |
pspatel321 | 38:8efacce315ae | 70 | CMP(2, "extended") { |
pspatel321 | 38:8efacce315ae | 71 | if (param->change_extendedSerial(1)) { |
pspatel321 | 38:8efacce315ae | 72 | op->profileModded=true; |
pspatel321 | 38:8efacce315ae | 73 | return 1; // Change function defined by macro |
pspatel321 | 38:8efacce315ae | 74 | } |
pspatel321 | 38:8efacce315ae | 75 | } |
pspatel321 | 38:8efacce315ae | 76 | } |
pspatel321 | 38:8efacce315ae | 77 | // Change ACK setting for CAN (noAck allows testing of CAN without other nodes) |
pspatel321 | 38:8efacce315ae | 78 | CMP(1, "CANack") { |
pspatel321 | 38:8efacce315ae | 79 | CMP(2, "noack") { // NoAck test mode |
pspatel321 | 38:8efacce315ae | 80 | if (param->change_CANnoAck(1)) { |
pspatel321 | 38:8efacce315ae | 81 | op->profileModded=true; |
pspatel321 | 38:8efacce315ae | 82 | return 1; |
pspatel321 | 38:8efacce315ae | 83 | } |
pspatel321 | 38:8efacce315ae | 84 | } |
pspatel321 | 38:8efacce315ae | 85 | CMP(2, "ack") { // Normal CAN protocol |
pspatel321 | 38:8efacce315ae | 86 | if (param->change_CANnoAck(0)) { |
pspatel321 | 38:8efacce315ae | 87 | op->profileModded=true; |
pspatel321 | 38:8efacce315ae | 88 | return 1; |
pspatel321 | 38:8efacce315ae | 89 | } |
pspatel321 | 38:8efacce315ae | 90 | } |
pspatel321 | 38:8efacce315ae | 91 | return -1; |
pspatel321 | 38:8efacce315ae | 92 | } |
pspatel321 | 38:8efacce315ae | 93 | // Artificially capture a freeze frame, save to flash |
pspatel321 | 38:8efacce315ae | 94 | CMP(1, "capture") { |
pspatel321 | 38:8efacce315ae | 95 | CMP(2, "freeze") { |
pspatel321 | 38:8efacce315ae | 96 | if (!FreezeFrame::getError()) { // Only allow capture if spot available (last error frame was cleared manually) |
pspatel321 | 38:8efacce315ae | 97 | if (FreezeFrame::writeFrame()) { // Copy RAM frame to freezree sector in flash |
pspatel321 | 38:8efacce315ae | 98 | return 1; |
pspatel321 | 38:8efacce315ae | 99 | } |
pspatel321 | 38:8efacce315ae | 100 | } |
pspatel321 | 38:8efacce315ae | 101 | } |
pspatel321 | 38:8efacce315ae | 102 | return -1; |
pspatel321 | 38:8efacce315ae | 103 | } |
pspatel321 | 38:8efacce315ae | 104 | // Clear fault conditions |
pspatel321 | 38:8efacce315ae | 105 | CMP(1, "clear") { |
pspatel321 | 38:8efacce315ae | 106 | CMP(2, "freeze") { // Clear the freeze frame (mark as read) |
pspatel321 | 38:8efacce315ae | 107 | FreezeFrame::clearError(); // Clear the non-volatile error marker |
pspatel321 | 34:18bcf276d3bf | 108 | return 1; |
pspatel321 | 34:18bcf276d3bf | 109 | } |
pspatel321 | 38:8efacce315ae | 110 | CMP(2, "faults") { // Clear everything |
pspatel321 | 38:8efacce315ae | 111 | runTime::clearFaults(); |
pspatel321 | 38:8efacce315ae | 112 | return 1; |
pspatel321 | 38:8efacce315ae | 113 | } |
pspatel321 | 38:8efacce315ae | 114 | return -1; |
pspatel321 | 38:8efacce315ae | 115 | } |
pspatel321 | 38:8efacce315ae | 116 | // Change the display contents |
pspatel321 | 38:8efacce315ae | 117 | CMP(1, "view") { |
pspatel321 | 38:8efacce315ae | 118 | CMP(2, "freeze") { // View the last stored freeze frame |
pspatel321 | 38:8efacce315ae | 119 | if (FreezeFrame::getFrame(&tempData.freeze)) { // Fetch the pointer from flash |
pspatel321 | 38:8efacce315ae | 120 | return 1; |
pspatel321 | 38:8efacce315ae | 121 | } |
pspatel321 | 38:8efacce315ae | 122 | } |
pspatel321 | 38:8efacce315ae | 123 | CMP(2, "live") { // View live data from RAM |
pspatel321 | 38:8efacce315ae | 124 | tempData.freeze = NULL; // Zero the pointer |
pspatel321 | 34:18bcf276d3bf | 125 | return 1; |
pspatel321 | 34:18bcf276d3bf | 126 | } |
pspatel321 | 34:18bcf276d3bf | 127 | return -1; |
pspatel321 | 34:18bcf276d3bf | 128 | } |
pspatel321 | 34:18bcf276d3bf | 129 | // Artificially update the SOC (battery life %) |
pspatel321 | 34:18bcf276d3bf | 130 | CMP(1, "SOC") { |
pspatel321 | 34:18bcf276d3bf | 131 | CMP(2, "Reset") { // Command was "SOC reset" - reset to 100%, do this after a full charge |
pspatel321 | 34:18bcf276d3bf | 132 | glvBat.resetToSOC(1); |
pspatel321 | 34:18bcf276d3bf | 133 | return 1; |
pspatel321 | 34:18bcf276d3bf | 134 | } |
pspatel321 | 34:18bcf276d3bf | 135 | float soc = strtod(word[1], &next); // Command was "SOC xxx" where xxx is float between 0 and 1 |
pspatel321 | 34:18bcf276d3bf | 136 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 137 | if (glvBat.resetToSOC(soc)) return 1; |
pspatel321 | 34:18bcf276d3bf | 138 | } |
pspatel321 | 34:18bcf276d3bf | 139 | return -1; |
pspatel321 | 34:18bcf276d3bf | 140 | } |
pspatel321 | 34:18bcf276d3bf | 141 | // Artificially update the AmpHours count (linked with SOC) |
pspatel321 | 34:18bcf276d3bf | 142 | CMP(1, "Ah") { |
pspatel321 | 34:18bcf276d3bf | 143 | CMP(2, "Reset") { // Command was "Amphours reset", equivalent to "SOC reset" |
pspatel321 | 34:18bcf276d3bf | 144 | glvBat.resetToSOC(1); |
pspatel321 | 34:18bcf276d3bf | 145 | return 1; |
pspatel321 | 34:18bcf276d3bf | 146 | } |
pspatel321 | 34:18bcf276d3bf | 147 | float ah = strtod(word[1], &next); // Command was "Amphours xxx" where xxx is a float in amphours |
pspatel321 | 34:18bcf276d3bf | 148 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 149 | if (glvBat.resetToAh(ah)) return 1; |
pspatel321 | 34:18bcf276d3bf | 150 | } |
pspatel321 | 34:18bcf276d3bf | 151 | return -1; |
pspatel321 | 34:18bcf276d3bf | 152 | } |
pspatel321 | 34:18bcf276d3bf | 153 | // Change the battery capacity setting for calculating Amphours |
pspatel321 | 34:18bcf276d3bf | 154 | CMP(1, "Capacity") { |
pspatel321 | 34:18bcf276d3bf | 155 | float cap = strtod(word[1], &next); // Command was "SOC xxx" where xxx is float between 0 and 1 |
pspatel321 | 34:18bcf276d3bf | 156 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 157 | if (glvBat.changeCapacity(cap)) return 1; |
pspatel321 | 34:18bcf276d3bf | 158 | } |
pspatel321 | 36:0afc0fc8f86b | 159 | return -1; |
pspatel321 | 34:18bcf276d3bf | 160 | } |
pspatel321 | 38:8efacce315ae | 161 | |
pspatel321 | 38:8efacce315ae | 162 | bool parsed=false; |
pspatel321 | 38:8efacce315ae | 163 | |
pspatel321 | 38:8efacce315ae | 164 | CHANGE_VAR("GLVchar", chargeCurrent) |
pspatel321 | 38:8efacce315ae | 165 | CHANGE_VAR("GLVdisch", dischargeCurrent) |
pspatel321 | 38:8efacce315ae | 166 | CHANGE_VAR("GLVnomCap", nominalCapacity) |
pspatel321 | 38:8efacce315ae | 167 | CHANGE_VAR("GLVtaps", glvBat_taps) |
pspatel321 | 38:8efacce315ae | 168 | CHANGE_VAR("dcdcThres", dcdcThreshold) |
pspatel321 | 38:8efacce315ae | 169 | CHANGE_VAR("dcdcOver", dcdcOverCurrent) |
pspatel321 | 38:8efacce315ae | 170 | CHANGE_VAR("dcdcStart", dcdcStartDelay) |
pspatel321 | 38:8efacce315ae | 171 | CHANGE_VAR("dcdcStop", dcdcStopDelay) |
pspatel321 | 38:8efacce315ae | 172 | CHANGE_VAR("dcdcTaps", dcdc_taps) |
pspatel321 | 38:8efacce315ae | 173 | CHANGE_VAR("imdStart", imdStartDelay) |
pspatel321 | 38:8efacce315ae | 174 | CHANGE_VAR("amsStart", amsStartDelay) |
pspatel321 | 38:8efacce315ae | 175 | CHANGE_VAR("IntOverT", internalOverTemp) |
pspatel321 | 38:8efacce315ae | 176 | CHANGE_VAR("CANtxSize", CANtxSize) |
pspatel321 | 38:8efacce315ae | 177 | CHANGE_VAR("CANrxSize", CANrxSize) |
pspatel321 | 38:8efacce315ae | 178 | CHANGE_VAR("SerialBaud", SerialBaud) |
pspatel321 | 38:8efacce315ae | 179 | CHANGE_VAR("SerialTx", SerialTxSize) |
pspatel321 | 38:8efacce315ae | 180 | CHANGE_VAR("CANack", CANnoAck) |
pspatel321 | 38:8efacce315ae | 181 | |
pspatel321 | 38:8efacce315ae | 182 | if (!parsed) return -1; |
pspatel321 | 38:8efacce315ae | 183 | |
pspatel321 | 38:8efacce315ae | 184 | CMP(1, "GLVnomCap") return glvBat.changeCapacity(param->nominalCapacity)?1:-1; |
pspatel321 | 38:8efacce315ae | 185 | CMP(1, "GLVtaps") return glvBat.size(param->glvBat_taps)?1:-1; |
pspatel321 | 38:8efacce315ae | 186 | CMP(1, "dcdcTaps") return dcdc.size(param->dcdc_taps)?1:-1; |
pspatel321 | 38:8efacce315ae | 187 | CMP(1, "CANtxSize") return can.txSize(param->CANtxSize)?1:-1; |
pspatel321 | 38:8efacce315ae | 188 | CMP(1, "CANrxSize") return can.rxSize(param->CANrxSize)?1:-1; |
pspatel321 | 38:8efacce315ae | 189 | CMP(1, "SerialBaud") pc.baud(param->SerialBaud); |
pspatel321 | 38:8efacce315ae | 190 | CMP(1, "SerialTx") return (pc.txBufferSetSize(param->SerialTxSize) == 0)?1:-1; |
pspatel321 | 38:8efacce315ae | 191 | |
pspatel321 | 38:8efacce315ae | 192 | return 1; |
pspatel321 | 34:18bcf276d3bf | 193 | } |
pspatel321 | 36:0afc0fc8f86b | 194 | // Three word commands |
pspatel321 | 34:18bcf276d3bf | 195 | if (pieces == 3) { |
pspatel321 | 34:18bcf276d3bf | 196 | // Fan Duty |
pspatel321 | 34:18bcf276d3bf | 197 | CMP(1, "Fan") { |
pspatel321 | 34:18bcf276d3bf | 198 | float val1 = strtod(word[1], &next); |
pspatel321 | 34:18bcf276d3bf | 199 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 200 | float val2 = strtod(word[2], &next); |
pspatel321 | 34:18bcf276d3bf | 201 | if (*next == 0) { |
pspatel321 | 38:8efacce315ae | 202 | op->dcdc.request.fan1 = val1; |
pspatel321 | 38:8efacce315ae | 203 | op->dcdc.request.fan2 = val2; |
pspatel321 | 34:18bcf276d3bf | 204 | return 1; |
pspatel321 | 34:18bcf276d3bf | 205 | } |
pspatel321 | 34:18bcf276d3bf | 206 | } |
pspatel321 | 34:18bcf276d3bf | 207 | return -1; |
pspatel321 | 34:18bcf276d3bf | 208 | } |
pspatel321 | 34:18bcf276d3bf | 209 | |
pspatel321 | 34:18bcf276d3bf | 210 | // Pump Duty |
pspatel321 | 34:18bcf276d3bf | 211 | CMP(1, "Pump") { |
pspatel321 | 34:18bcf276d3bf | 212 | float val1 = strtod(word[1], &next); |
pspatel321 | 34:18bcf276d3bf | 213 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 214 | float val2 = strtod(word[2], &next); |
pspatel321 | 34:18bcf276d3bf | 215 | if (*next == 0) { |
pspatel321 | 38:8efacce315ae | 216 | op->dcdc.request.pump1 = val1; |
pspatel321 | 38:8efacce315ae | 217 | op->dcdc.request.pump2 = val2; |
pspatel321 | 38:8efacce315ae | 218 | return 1; |
pspatel321 | 38:8efacce315ae | 219 | } |
pspatel321 | 38:8efacce315ae | 220 | } |
pspatel321 | 38:8efacce315ae | 221 | return -1; |
pspatel321 | 38:8efacce315ae | 222 | } |
pspatel321 | 38:8efacce315ae | 223 | // Set the system time (RTC) |
pspatel321 | 38:8efacce315ae | 224 | CMP(1, "Time") { |
pspatel321 | 38:8efacce315ae | 225 | struct tm t; // Time & date struct |
pspatel321 | 38:8efacce315ae | 226 | int ret = sscanf(word[1], "%d/%d/%d", &t.tm_mon, &t.tm_mday, &t.tm_year); // Populate date |
pspatel321 | 38:8efacce315ae | 227 | t.tm_year = t.tm_year - 1900; // Year mod to fix 0 index |
pspatel321 | 38:8efacce315ae | 228 | t.tm_mon = t.tm_mon - 1; // Month mod to fix 0 index |
pspatel321 | 38:8efacce315ae | 229 | if (ret == 3) { // All 3 items found |
pspatel321 | 38:8efacce315ae | 230 | ret = sscanf(word[2], "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec); // Populate time |
pspatel321 | 38:8efacce315ae | 231 | if (ret == 3) { // All 3 items found |
pspatel321 | 38:8efacce315ae | 232 | set_time(mktime(&t)); // Set the RTC |
pspatel321 | 38:8efacce315ae | 233 | time_t diff = time(NULL) - op->SysTime; // Get change in time from old to new |
pspatel321 | 38:8efacce315ae | 234 | op->startTime += diff; // Shift the startTime to new timebase |
pspatel321 | 34:18bcf276d3bf | 235 | return 1; |
pspatel321 | 34:18bcf276d3bf | 236 | } |
pspatel321 | 34:18bcf276d3bf | 237 | } |
pspatel321 | 34:18bcf276d3bf | 238 | return -1; |
pspatel321 | 34:18bcf276d3bf | 239 | } |
pspatel321 | 38:8efacce315ae | 240 | |
pspatel321 | 38:8efacce315ae | 241 | // Profile manipulations between RAM and flash |
pspatel321 | 38:8efacce315ae | 242 | CMP(1, "Profile") { |
pspatel321 | 38:8efacce315ae | 243 | // Write, copy RAM to a flash sector |
pspatel321 | 38:8efacce315ae | 244 | CMP(2, "Write") { |
pspatel321 | 38:8efacce315ae | 245 | unsigned int index = strtoul(word[2], &next, 10); // Get index from command "profile write xxx" |
pspatel321 | 38:8efacce315ae | 246 | if (index <= NUM_STORED_PROFILES && index > 0 && *next == 0) { // Check within bounds |
pspatel321 | 38:8efacce315ae | 247 | bool s = Profile::saveProfile(index); // Write to flash |
pspatel321 | 38:8efacce315ae | 248 | if (s) { // Successful? |
pspatel321 | 38:8efacce315ae | 249 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 250 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 251 | return 1; |
pspatel321 | 38:8efacce315ae | 252 | } |
pspatel321 | 38:8efacce315ae | 253 | } |
pspatel321 | 38:8efacce315ae | 254 | return -1; |
pspatel321 | 38:8efacce315ae | 255 | } |
pspatel321 | 38:8efacce315ae | 256 | // Load, read from flash to RAM |
pspatel321 | 38:8efacce315ae | 257 | CMP(2, "Load") { |
pspatel321 | 38:8efacce315ae | 258 | CMP(3, "default") { // The hard-coded flash profile (found in FreezeFrame.cpp) |
pspatel321 | 38:8efacce315ae | 259 | Profile::loadProfile(0); // Copy default to RAM |
pspatel321 | 38:8efacce315ae | 260 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 261 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 262 | return 1; |
pspatel321 | 38:8efacce315ae | 263 | } |
pspatel321 | 38:8efacce315ae | 264 | CMP(3, "freeze") { // Get the profile portion of the last freeze frame captured |
pspatel321 | 38:8efacce315ae | 265 | if(Profile::loadProfile(-1)) { // Attemp to retrieve and copy to RAM |
pspatel321 | 38:8efacce315ae | 266 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 267 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 268 | return 1; |
pspatel321 | 38:8efacce315ae | 269 | } |
pspatel321 | 38:8efacce315ae | 270 | } |
pspatel321 | 38:8efacce315ae | 271 | int index = strtol(word[2], &next, 10); // Command was "profile load xxx" |
pspatel321 | 38:8efacce315ae | 272 | if (index <= NUM_STORED_PROFILES && index >= -1 && *next == 0) { // Valid index found? |
pspatel321 | 38:8efacce315ae | 273 | if (Profile::loadProfile(index)) { // Attempt to retrieve and copy to RAM |
pspatel321 | 38:8efacce315ae | 274 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 275 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 276 | return 1; |
pspatel321 | 38:8efacce315ae | 277 | } |
pspatel321 | 38:8efacce315ae | 278 | } |
pspatel321 | 38:8efacce315ae | 279 | return -1; |
pspatel321 | 38:8efacce315ae | 280 | } |
pspatel321 | 38:8efacce315ae | 281 | // View the profile only (NOT loaded to RAM, just display changed) |
pspatel321 | 38:8efacce315ae | 282 | CMP(2, "view") { |
pspatel321 | 38:8efacce315ae | 283 | CMP(3, "default") { // View the hard-coded flash profile |
pspatel321 | 38:8efacce315ae | 284 | if (Profile::getProfile(&tempData.viewProfile, 0)) { // Attempt to fetch pointer |
pspatel321 | 38:8efacce315ae | 285 | tempData.viewProfileNum = 0; // Mark the index of the fetched profile |
pspatel321 | 38:8efacce315ae | 286 | return 1; |
pspatel321 | 38:8efacce315ae | 287 | } |
pspatel321 | 38:8efacce315ae | 288 | } |
pspatel321 | 38:8efacce315ae | 289 | CMP(3, "freeze") { // View the profile portion only of the last captured freeze frame |
pspatel321 | 38:8efacce315ae | 290 | if (Profile::getProfile(&tempData.viewProfile, -1)) { // Attempt to fetch pointer |
pspatel321 | 38:8efacce315ae | 291 | tempData.viewProfileNum = -1; // Mark the index of the fetched profile |
pspatel321 | 38:8efacce315ae | 292 | return 1; |
pspatel321 | 38:8efacce315ae | 293 | } |
pspatel321 | 38:8efacce315ae | 294 | } |
pspatel321 | 38:8efacce315ae | 295 | CMP(3, "live") { // Revert to normal, live view |
pspatel321 | 38:8efacce315ae | 296 | tempData.viewProfileNum = -2; // Mark live |
pspatel321 | 38:8efacce315ae | 297 | tempData.viewProfile = NULL; // Clear the pointer |
pspatel321 | 38:8efacce315ae | 298 | return 1; |
pspatel321 | 38:8efacce315ae | 299 | } |
pspatel321 | 38:8efacce315ae | 300 | |
pspatel321 | 38:8efacce315ae | 301 | int index = strtol(word[2], &next, 10); // Command was "profile view xxx" |
pspatel321 | 38:8efacce315ae | 302 | if (index <= NUM_STORED_PROFILES && index >= -1 && *next == 0) { // Valid index found? |
pspatel321 | 38:8efacce315ae | 303 | if (Profile::getProfile(&tempData.viewProfile, index)) { // Attempt to fetch pointer |
pspatel321 | 38:8efacce315ae | 304 | tempData.viewProfileNum = index; // Mark the index of the fetched profile |
pspatel321 | 38:8efacce315ae | 305 | return 1; |
pspatel321 | 38:8efacce315ae | 306 | } |
pspatel321 | 38:8efacce315ae | 307 | } |
pspatel321 | 38:8efacce315ae | 308 | return -1; |
pspatel321 | 38:8efacce315ae | 309 | } |
pspatel321 | 38:8efacce315ae | 310 | } |
pspatel321 | 34:18bcf276d3bf | 311 | } |
pspatel321 | 34:18bcf276d3bf | 312 | return -1; |
pspatel321 | 36:0afc0fc8f86b | 313 | } |
pspatel321 | 38:8efacce315ae | 314 | // Called when AMS AIRs Mode message stops coming in |
pspatel321 | 38:8efacce315ae | 315 | Timeout timer_AIRS_CLOSED; |
pspatel321 | 38:8efacce315ae | 316 | void timeout_AIRS_CLOSED() |
pspatel321 | 38:8efacce315ae | 317 | { |
pspatel321 | 38:8efacce315ae | 318 | op->signals &= ~AIRS_CLOSED; |
pspatel321 | 38:8efacce315ae | 319 | } |
pspatel321 | 38:8efacce315ae | 320 | |
pspatel321 | 38:8efacce315ae | 321 | // Called when Charger CAN messages stop coming in |
pspatel321 | 38:8efacce315ae | 322 | Timeout timer_CHARGER_DET; |
pspatel321 | 38:8efacce315ae | 323 | void timeout_CHARGER_DET() |
pspatel321 | 38:8efacce315ae | 324 | { |
pspatel321 | 38:8efacce315ae | 325 | op->signals &= ~CHARGER_DET; |
pspatel321 | 38:8efacce315ae | 326 | } |
pspatel321 | 38:8efacce315ae | 327 | |
pspatel321 | 38:8efacce315ae | 328 | // Called when PCM messages stop coming in |
pspatel321 | 38:8efacce315ae | 329 | Timeout timer_FANS; |
pspatel321 | 38:8efacce315ae | 330 | void timeout_FANS() |
pspatel321 | 38:8efacce315ae | 331 | { |
pspatel321 | 38:8efacce315ae | 332 | op->dcdc.request.fan1 = 0; |
pspatel321 | 38:8efacce315ae | 333 | op->dcdc.request.fan2 = 0; |
pspatel321 | 38:8efacce315ae | 334 | } |
pspatel321 | 38:8efacce315ae | 335 | Timeout timer_PUMPS; |
pspatel321 | 38:8efacce315ae | 336 | void timeout_PUMPS() |
pspatel321 | 38:8efacce315ae | 337 | { |
pspatel321 | 38:8efacce315ae | 338 | op->dcdc.request.pump1 = 0; |
pspatel321 | 38:8efacce315ae | 339 | op->dcdc.request.pump2 = 0; |
pspatel321 | 38:8efacce315ae | 340 | } |
pspatel321 | 38:8efacce315ae | 341 | |
pspatel321 | 38:8efacce315ae | 342 | #define REFRESH_TIMEOUT(NAME) \ |
pspatel321 | 38:8efacce315ae | 343 | timer_##NAME.detach(); \ |
pspatel321 | 38:8efacce315ae | 344 | timer_##NAME.attach(&timeout_##NAME, CAN_DEVICE_TIMEOUT); |
pspatel321 | 38:8efacce315ae | 345 | |
pspatel321 | 38:8efacce315ae | 346 | bool serviceCAN(CANMessage* fromXbee) |
pspatel321 | 38:8efacce315ae | 347 | { |
pspatel321 | 38:8efacce315ae | 348 | CANMessage msg; |
pspatel321 | 38:8efacce315ae | 349 | if (fromXbee != NULL) { |
pspatel321 | 38:8efacce315ae | 350 | memcpy((void*)&msg, (void*)fromXbee, sizeof(CANMessage)); |
pspatel321 | 38:8efacce315ae | 351 | } else { |
pspatel321 | 38:8efacce315ae | 352 | if (!can.rxRead(msg)) return false; |
pspatel321 | 38:8efacce315ae | 353 | } |
pspatel321 | 39:ddf38df9699e | 354 | xbee.receive(msg); |
pspatel321 | 39:ddf38df9699e | 355 | |
pspatel321 | 38:8efacce315ae | 356 | // Redirect global car reset |
pspatel321 | 38:8efacce315ae | 357 | if (msg.id == GLOBAL_CAR_RESET_RX_ID) msg.id = RESETCLEAR_RX_ID; |
pspatel321 | 38:8efacce315ae | 358 | |
pspatel321 | 38:8efacce315ae | 359 | switch (msg.id) { |
pspatel321 | 38:8efacce315ae | 360 | // Reset microntroller |
pspatel321 | 38:8efacce315ae | 361 | case (RESET_RX_ID): |
pspatel321 | 38:8efacce315ae | 362 | if (msg.len == 0) { // Length must = 0 |
pspatel321 | 38:8efacce315ae | 363 | NVIC_SystemReset(); |
pspatel321 | 38:8efacce315ae | 364 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 365 | } |
pspatel321 | 38:8efacce315ae | 366 | CAN_FAIL |
pspatel321 | 38:8efacce315ae | 367 | |
pspatel321 | 39:ddf38df9699e | 368 | |
pspatel321 | 39:ddf38df9699e | 369 | // Clear non-volatile fault flags, then reset microcontroller |
pspatel321 | 38:8efacce315ae | 370 | case (RESETCLEAR_RX_ID): |
pspatel321 | 38:8efacce315ae | 371 | if (msg.len == 0) { // Length must = 0 |
pspatel321 | 38:8efacce315ae | 372 | FreezeFrame::clearError(); |
pspatel321 | 38:8efacce315ae | 373 | NVIC_SystemReset(); |
pspatel321 | 38:8efacce315ae | 374 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 375 | } |
pspatel321 | 38:8efacce315ae | 376 | CAN_FAIL |
pspatel321 | 39:ddf38df9699e | 377 | |
pspatel321 | 39:ddf38df9699e | 378 | // Clear fault conditions |
pspatel321 | 38:8efacce315ae | 379 | case (CLEAR_RX_ID): |
pspatel321 | 39:ddf38df9699e | 380 | if (msg.len == 0) { // No data byte |
pspatel321 | 39:ddf38df9699e | 381 | runTime::clearFaults(); |
pspatel321 | 39:ddf38df9699e | 382 | op->faultCode = 0; |
pspatel321 | 39:ddf38df9699e | 383 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 384 | } |
pspatel321 | 38:8efacce315ae | 385 | CAN_FAIL |
pspatel321 | 38:8efacce315ae | 386 | |
pspatel321 | 38:8efacce315ae | 387 | // Set the time (RTC) |
pspatel321 | 38:8efacce315ae | 388 | case (TIME_RX_ID): |
pspatel321 | 38:8efacce315ae | 389 | if (msg.len == 6*sizeof(char)) { // 6 Bytes |
pspatel321 | 38:8efacce315ae | 390 | struct tm t; // Time & date struct |
pspatel321 | 38:8efacce315ae | 391 | t.tm_mon = msg.data[0]; // Month in byte[0] |
pspatel321 | 38:8efacce315ae | 392 | t.tm_mday = msg.data[1]; // Day |
pspatel321 | 38:8efacce315ae | 393 | t.tm_year = msg.data[2]; // Year (offset from 2000) |
pspatel321 | 38:8efacce315ae | 394 | t.tm_year = t.tm_year - 1900 + 2000; // Apply year index mod and offset |
pspatel321 | 38:8efacce315ae | 395 | t.tm_mon = t.tm_mon - 1; // Month index mod |
pspatel321 | 38:8efacce315ae | 396 | t.tm_hour = msg.data[3]; // Get hour of time in byte[3] (24 hr format) |
pspatel321 | 38:8efacce315ae | 397 | t.tm_min = msg.data[4]; // Minutes |
pspatel321 | 38:8efacce315ae | 398 | t.tm_sec = msg.data[5]; // Seconds |
pspatel321 | 38:8efacce315ae | 399 | set_time(mktime(&t)); // Set RTC |
pspatel321 | 38:8efacce315ae | 400 | time_t diff = time(NULL) - op->SysTime; // Old time to new time change |
pspatel321 | 38:8efacce315ae | 401 | op->startTime += diff; // Shift the startTime to new timebase |
pspatel321 | 38:8efacce315ae | 402 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 403 | } |
pspatel321 | 38:8efacce315ae | 404 | CAN_FAIL |
pspatel321 | 38:8efacce315ae | 405 | |
pspatel321 | 38:8efacce315ae | 406 | // RAM and flash profile manipulations |
pspatel321 | 38:8efacce315ae | 407 | case (PROFILE_RX_ID): |
pspatel321 | 38:8efacce315ae | 408 | if (msg.len == 2*sizeof(char)) { // 2 command bytes |
pspatel321 | 39:ddf38df9699e | 409 | int index=-2; |
pspatel321 | 39:ddf38df9699e | 410 | for (int i = 0; i < NUM_STORED_PROFILES+1; i++) { // Get the profile number |
pspatel321 | 39:ddf38df9699e | 411 | if (msg.data[1] == (1<<i)) index=i; |
pspatel321 | 39:ddf38df9699e | 412 | } |
pspatel321 | 39:ddf38df9699e | 413 | if (msg.data[1] == 1<<6) index=-1; // Special case for Freeze |
pspatel321 | 39:ddf38df9699e | 414 | if (index == -2) { // Not matched to anything, fail |
pspatel321 | 39:ddf38df9699e | 415 | CAN_FAIL |
pspatel321 | 39:ddf38df9699e | 416 | } |
pspatel321 | 38:8efacce315ae | 417 | if (msg.data[0] == 0) { // Load profile from a flash location to RAM |
pspatel321 | 38:8efacce315ae | 418 | if (Profile::loadProfile(index)) { // Attempt to load (copy flash to RAM) |
pspatel321 | 38:8efacce315ae | 419 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 420 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 421 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 422 | } |
pspatel321 | 38:8efacce315ae | 423 | } |
pspatel321 | 38:8efacce315ae | 424 | if (msg.data[0] == 1) { // Write profile to flash from RAM |
pspatel321 | 38:8efacce315ae | 425 | bool s = Profile::saveProfile(index); // Write profile to flash slot |
pspatel321 | 38:8efacce315ae | 426 | if (s) { |
pspatel321 | 38:8efacce315ae | 427 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 428 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 429 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 430 | } |
pspatel321 | 38:8efacce315ae | 431 | } |
pspatel321 | 38:8efacce315ae | 432 | } |
pspatel321 | 38:8efacce315ae | 433 | CAN_FAIL |
pspatel321 | 38:8efacce315ae | 434 | |
pspatel321 | 39:ddf38df9699e | 435 | case FAN_CONTROL_RX_ID: |
pspatel321 | 38:8efacce315ae | 436 | if (msg.len != 2*sizeof(float)) return false; |
pspatel321 | 38:8efacce315ae | 437 | REFRESH_TIMEOUT(FANS) |
pspatel321 | 38:8efacce315ae | 438 | op->dcdc.request.fan1 = *((float*)((void*)(&msg.data[0]))); |
pspatel321 | 38:8efacce315ae | 439 | op->dcdc.request.fan2 = *((float*)((void*)(&msg.data[4]))); |
pspatel321 | 38:8efacce315ae | 440 | return true; |
pspatel321 | 38:8efacce315ae | 441 | |
pspatel321 | 39:ddf38df9699e | 442 | case PUMP_CONTROL_RX_ID: |
pspatel321 | 38:8efacce315ae | 443 | if (msg.len != 2*sizeof(float)) return false; |
pspatel321 | 38:8efacce315ae | 444 | REFRESH_TIMEOUT(PUMPS) |
pspatel321 | 38:8efacce315ae | 445 | op->dcdc.request.pump1 = *((float*)((void*)(&msg.data[0]))); |
pspatel321 | 38:8efacce315ae | 446 | op->dcdc.request.pump2 = *((float*)((void*)(&msg.data[4]))); |
pspatel321 | 38:8efacce315ae | 447 | return true; |
pspatel321 | 38:8efacce315ae | 448 | |
pspatel321 | 39:ddf38df9699e | 449 | case AMS_MODE_RX_ID: |
pspatel321 | 38:8efacce315ae | 450 | if (msg.len != sizeof(char)) return false; |
pspatel321 | 38:8efacce315ae | 451 | REFRESH_TIMEOUT(AIRS_CLOSED) |
pspatel321 | 39:ddf38df9699e | 452 | if (msg.data[0] & 1<<3) { // AIRs closed? |
pspatel321 | 38:8efacce315ae | 453 | op->signals |= AIRS_CLOSED; |
pspatel321 | 38:8efacce315ae | 454 | } else { |
pspatel321 | 38:8efacce315ae | 455 | op->signals &= ~AIRS_CLOSED; |
pspatel321 | 38:8efacce315ae | 456 | } |
pspatel321 | 38:8efacce315ae | 457 | return true; |
pspatel321 | 39:ddf38df9699e | 458 | case CHARGER_ERR_RX_ID: |
pspatel321 | 38:8efacce315ae | 459 | REFRESH_TIMEOUT(CHARGER_DET) |
pspatel321 | 38:8efacce315ae | 460 | op->signals |= CHARGER_DET; |
pspatel321 | 38:8efacce315ae | 461 | return true; |
pspatel321 | 38:8efacce315ae | 462 | default: |
pspatel321 | 38:8efacce315ae | 463 | break; |
pspatel321 | 38:8efacce315ae | 464 | } |
pspatel321 | 38:8efacce315ae | 465 | bool parsed=false; |
pspatel321 | 38:8efacce315ae | 466 | |
pspatel321 | 38:8efacce315ae | 467 | CAN_CHANGE(chargeCurrent, PROFILE_CHARGECURRENT_RX_ID ) |
pspatel321 | 38:8efacce315ae | 468 | CAN_CHANGE(dischargeCurrent, PROFILE_DISCHARGECURRENT_RX_ID ) |
pspatel321 | 38:8efacce315ae | 469 | CAN_CHANGE(nominalCapacity, PROFILE_NOMINALCAPACITY_RX_ID ) |
pspatel321 | 38:8efacce315ae | 470 | CAN_CHANGE(glvBat_taps, PROFILE_GLVBATTAPS_RX_ID ) |
pspatel321 | 38:8efacce315ae | 471 | CAN_CHANGE(dcdcThreshold, PROFILE_DCDCONTHRESHOLD_RX_ID ) |
pspatel321 | 38:8efacce315ae | 472 | CAN_CHANGE(dcdcOverCurrent, PROFILE_DCDCOVERCURRENT_RX_ID ) |
pspatel321 | 38:8efacce315ae | 473 | CAN_CHANGE(dcdcStartDelay, PROFILE_DCDCSTARTDELAY_RX_ID ) |
pspatel321 | 38:8efacce315ae | 474 | CAN_CHANGE(dcdcStopDelay, PROFILE_DCDCSTOPDELAY_RX_ID ) |
pspatel321 | 38:8efacce315ae | 475 | CAN_CHANGE(dcdc_taps, PROFILE_DCDC_TAPS_RX_ID ) |
pspatel321 | 38:8efacce315ae | 476 | CAN_CHANGE(imdStartDelay, PROFILE_IMDSTARTDELAY_RX_ID ) |
pspatel321 | 39:ddf38df9699e | 477 | CAN_CHANGE(amsStartDelay, PROFILE_AMSSTARTDELAY_RX_ID ) |
pspatel321 | 38:8efacce315ae | 478 | CAN_CHANGE(internalOverTemp, PROFILE_INTERNALOVERTEMP_RX_ID ) |
pspatel321 | 38:8efacce315ae | 479 | CAN_CHANGE(CANnoAck, PROFILE_CANNOACK_RX_ID ) |
pspatel321 | 38:8efacce315ae | 480 | CAN_CHANGE(extendedSerial, PROFILE_EXTENDSERIAL_RX_ID ) |
pspatel321 | 38:8efacce315ae | 481 | CAN_CHANGE(CANtxSize, PROFILE_CANTXSIZE_RX_ID ) |
pspatel321 | 38:8efacce315ae | 482 | CAN_CHANGE(CANrxSize, PROFILE_CANRXSIZE_RX_ID ) |
pspatel321 | 38:8efacce315ae | 483 | CAN_CHANGE(SerialBaud, PROFILE_SERIALBAUD_RX_ID ) |
pspatel321 | 38:8efacce315ae | 484 | CAN_CHANGE(SerialTxSize, PROFILE_SERIALTXSIZE_RX_ID ) |
pspatel321 | 38:8efacce315ae | 485 | |
pspatel321 | 38:8efacce315ae | 486 | if (!parsed) return false; |
pspatel321 | 38:8efacce315ae | 487 | |
pspatel321 | 38:8efacce315ae | 488 | if (msg.id == PROFILE_NOMINALCAPACITY_RX_ID ) return glvBat.changeCapacity(param->nominalCapacity)?1:-1; |
pspatel321 | 38:8efacce315ae | 489 | if (msg.id == PROFILE_GLVBATTAPS_RX_ID ) return glvBat.size(param->glvBat_taps)?1:-1; |
pspatel321 | 38:8efacce315ae | 490 | if (msg.id == PROFILE_DCDC_TAPS_RX_ID ) return dcdc.size(param->dcdc_taps)?1:-1; |
pspatel321 | 38:8efacce315ae | 491 | if (msg.id == PROFILE_CANTXSIZE_RX_ID ) return can.txSize(param->CANtxSize)?1:-1; |
pspatel321 | 38:8efacce315ae | 492 | if (msg.id == PROFILE_CANRXSIZE_RX_ID ) return can.rxSize(param->CANrxSize)?1:-1; |
pspatel321 | 38:8efacce315ae | 493 | if (msg.id == PROFILE_SERIALBAUD_RX_ID ) pc.baud(param->SerialBaud); |
pspatel321 | 38:8efacce315ae | 494 | if (msg.id == PROFILE_SERIALTXSIZE_RX_ID ) return (pc.txBufferSetSize(param->SerialTxSize) == 0)?1:-1; |
pspatel321 | 38:8efacce315ae | 495 | |
pspatel321 | 38:8efacce315ae | 496 | return true; |
pspatel321 | 38:8efacce315ae | 497 | } |
pspatel321 | 38:8efacce315ae | 498 | // Check for incoming messages from the xbees, relay them to the CAN function and send them out on the bus |
pspatel321 | 39:ddf38df9699e | 499 | /* |
pspatel321 | 38:8efacce315ae | 500 | bool receiveMsgXbee() |
pspatel321 | 38:8efacce315ae | 501 | { |
pspatel321 | 38:8efacce315ae | 502 | CANMessage msg; |
pspatel321 | 38:8efacce315ae | 503 | if (xbeeRelay.receive(msg)) { // Incoming CAN message string received |
pspatel321 | 38:8efacce315ae | 504 | if (!can.txWrite(msg)) op->faultCode |= CAN_FAULT; // Send it out on the CAN bus |
pspatel321 | 38:8efacce315ae | 505 | serviceCAN(&msg); // Send it into the local serviceCAN routine |
pspatel321 | 38:8efacce315ae | 506 | return true; |
pspatel321 | 38:8efacce315ae | 507 | } else return false; |
pspatel321 | 39:ddf38df9699e | 508 | }*/ |
pspatel321 | 36:0afc0fc8f86b | 509 | |
pspatel321 | 36:0afc0fc8f86b | 510 | void inCommands::thread_getInputs(void const* args) |
pspatel321 | 36:0afc0fc8f86b | 511 | { |
pspatel321 | 36:0afc0fc8f86b | 512 | while(1) { |
pspatel321 | 38:8efacce315ae | 513 | serviceCAN(0); |
pspatel321 | 39:ddf38df9699e | 514 | //receiveMsgXbee(); |
pspatel321 | 36:0afc0fc8f86b | 515 | |
pspatel321 | 38:8efacce315ae | 516 | int ret = serviceSerial(); |
pspatel321 | 36:0afc0fc8f86b | 517 | if (ret == -1) tempData.parseGoodChar = 'x'; |
pspatel321 | 36:0afc0fc8f86b | 518 | if (ret == 1) tempData.parseGoodChar = 251; |
pspatel321 | 36:0afc0fc8f86b | 519 | osSignalSet((osThreadId)(tempData.wdtThreadId), 1<<2); // Signal watchdog thread |
pspatel321 | 36:0afc0fc8f86b | 520 | } |
pspatel321 | 30:91af74a299e1 | 521 | } |