System Management code
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
inCommands/inCommands.cpp@38:8efacce315ae, 2015-02-07 (annotated)
- Committer:
- pspatel321
- Date:
- Sat Feb 07 08:54:51 2015 +0000
- Revision:
- 38:8efacce315ae
- Parent:
- 36:0afc0fc8f86b
- Child:
- 39:ddf38df9699e
Updated with profiles, operating info, etc. Just like the other programs. Awaiting test in car.
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("XbeeBaud", XbeeBaud) |
pspatel321 | 38:8efacce315ae | 181 | CHANGE_VAR("XbeeTxSize", XbeeTxSize) |
pspatel321 | 38:8efacce315ae | 182 | CHANGE_VAR("XbeeRxSize", XbeeRxSize) |
pspatel321 | 38:8efacce315ae | 183 | CHANGE_VAR("CANack", CANnoAck) |
pspatel321 | 38:8efacce315ae | 184 | |
pspatel321 | 38:8efacce315ae | 185 | if (!parsed) return -1; |
pspatel321 | 38:8efacce315ae | 186 | |
pspatel321 | 38:8efacce315ae | 187 | CMP(1, "GLVnomCap") return glvBat.changeCapacity(param->nominalCapacity)?1:-1; |
pspatel321 | 38:8efacce315ae | 188 | CMP(1, "GLVtaps") return glvBat.size(param->glvBat_taps)?1:-1; |
pspatel321 | 38:8efacce315ae | 189 | CMP(1, "dcdcTaps") return dcdc.size(param->dcdc_taps)?1:-1; |
pspatel321 | 38:8efacce315ae | 190 | CMP(1, "CANtxSize") return can.txSize(param->CANtxSize)?1:-1; |
pspatel321 | 38:8efacce315ae | 191 | CMP(1, "CANrxSize") return can.rxSize(param->CANrxSize)?1:-1; |
pspatel321 | 38:8efacce315ae | 192 | CMP(1, "SerialBaud") pc.baud(param->SerialBaud); |
pspatel321 | 38:8efacce315ae | 193 | CMP(1, "SerialTx") return (pc.txBufferSetSize(param->SerialTxSize) == 0)?1:-1; |
pspatel321 | 38:8efacce315ae | 194 | CMP(1, "XbeeBaud") xbeeRelay.baud(param->XbeeBaud); |
pspatel321 | 38:8efacce315ae | 195 | CMP(1, "XbeeTxSize") return (xbeeRelay.txSize(param->XbeeTxSize))?1:-1; |
pspatel321 | 38:8efacce315ae | 196 | CMP(1, "XbeeRxSize") return (xbeeRelay.rxSize(param->XbeeRxSize))?1:-1; |
pspatel321 | 38:8efacce315ae | 197 | |
pspatel321 | 38:8efacce315ae | 198 | return 1; |
pspatel321 | 34:18bcf276d3bf | 199 | } |
pspatel321 | 36:0afc0fc8f86b | 200 | // Three word commands |
pspatel321 | 34:18bcf276d3bf | 201 | if (pieces == 3) { |
pspatel321 | 34:18bcf276d3bf | 202 | // Fan Duty |
pspatel321 | 34:18bcf276d3bf | 203 | CMP(1, "Fan") { |
pspatel321 | 34:18bcf276d3bf | 204 | float val1 = strtod(word[1], &next); |
pspatel321 | 34:18bcf276d3bf | 205 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 206 | float val2 = strtod(word[2], &next); |
pspatel321 | 34:18bcf276d3bf | 207 | if (*next == 0) { |
pspatel321 | 38:8efacce315ae | 208 | op->dcdc.request.fan1 = val1; |
pspatel321 | 38:8efacce315ae | 209 | op->dcdc.request.fan2 = val2; |
pspatel321 | 34:18bcf276d3bf | 210 | return 1; |
pspatel321 | 34:18bcf276d3bf | 211 | } |
pspatel321 | 34:18bcf276d3bf | 212 | } |
pspatel321 | 34:18bcf276d3bf | 213 | return -1; |
pspatel321 | 34:18bcf276d3bf | 214 | } |
pspatel321 | 34:18bcf276d3bf | 215 | |
pspatel321 | 34:18bcf276d3bf | 216 | // Pump Duty |
pspatel321 | 34:18bcf276d3bf | 217 | CMP(1, "Pump") { |
pspatel321 | 34:18bcf276d3bf | 218 | float val1 = strtod(word[1], &next); |
pspatel321 | 34:18bcf276d3bf | 219 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 220 | float val2 = strtod(word[2], &next); |
pspatel321 | 34:18bcf276d3bf | 221 | if (*next == 0) { |
pspatel321 | 38:8efacce315ae | 222 | op->dcdc.request.pump1 = val1; |
pspatel321 | 38:8efacce315ae | 223 | op->dcdc.request.pump2 = val2; |
pspatel321 | 38:8efacce315ae | 224 | return 1; |
pspatel321 | 38:8efacce315ae | 225 | } |
pspatel321 | 38:8efacce315ae | 226 | } |
pspatel321 | 38:8efacce315ae | 227 | return -1; |
pspatel321 | 38:8efacce315ae | 228 | } |
pspatel321 | 38:8efacce315ae | 229 | // Set the system time (RTC) |
pspatel321 | 38:8efacce315ae | 230 | CMP(1, "Time") { |
pspatel321 | 38:8efacce315ae | 231 | struct tm t; // Time & date struct |
pspatel321 | 38:8efacce315ae | 232 | int ret = sscanf(word[1], "%d/%d/%d", &t.tm_mon, &t.tm_mday, &t.tm_year); // Populate date |
pspatel321 | 38:8efacce315ae | 233 | t.tm_year = t.tm_year - 1900; // Year mod to fix 0 index |
pspatel321 | 38:8efacce315ae | 234 | t.tm_mon = t.tm_mon - 1; // Month mod to fix 0 index |
pspatel321 | 38:8efacce315ae | 235 | if (ret == 3) { // All 3 items found |
pspatel321 | 38:8efacce315ae | 236 | ret = sscanf(word[2], "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec); // Populate time |
pspatel321 | 38:8efacce315ae | 237 | if (ret == 3) { // All 3 items found |
pspatel321 | 38:8efacce315ae | 238 | set_time(mktime(&t)); // Set the RTC |
pspatel321 | 38:8efacce315ae | 239 | time_t diff = time(NULL) - op->SysTime; // Get change in time from old to new |
pspatel321 | 38:8efacce315ae | 240 | op->startTime += diff; // Shift the startTime to new timebase |
pspatel321 | 34:18bcf276d3bf | 241 | return 1; |
pspatel321 | 34:18bcf276d3bf | 242 | } |
pspatel321 | 34:18bcf276d3bf | 243 | } |
pspatel321 | 34:18bcf276d3bf | 244 | return -1; |
pspatel321 | 34:18bcf276d3bf | 245 | } |
pspatel321 | 38:8efacce315ae | 246 | |
pspatel321 | 38:8efacce315ae | 247 | // Profile manipulations between RAM and flash |
pspatel321 | 38:8efacce315ae | 248 | CMP(1, "Profile") { |
pspatel321 | 38:8efacce315ae | 249 | // Write, copy RAM to a flash sector |
pspatel321 | 38:8efacce315ae | 250 | CMP(2, "Write") { |
pspatel321 | 38:8efacce315ae | 251 | unsigned int index = strtoul(word[2], &next, 10); // Get index from command "profile write xxx" |
pspatel321 | 38:8efacce315ae | 252 | if (index <= NUM_STORED_PROFILES && index > 0 && *next == 0) { // Check within bounds |
pspatel321 | 38:8efacce315ae | 253 | bool s = Profile::saveProfile(index); // Write to flash |
pspatel321 | 38:8efacce315ae | 254 | if (s) { // Successful? |
pspatel321 | 38:8efacce315ae | 255 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 256 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 257 | return 1; |
pspatel321 | 38:8efacce315ae | 258 | } |
pspatel321 | 38:8efacce315ae | 259 | } |
pspatel321 | 38:8efacce315ae | 260 | return -1; |
pspatel321 | 38:8efacce315ae | 261 | } |
pspatel321 | 38:8efacce315ae | 262 | // Load, read from flash to RAM |
pspatel321 | 38:8efacce315ae | 263 | CMP(2, "Load") { |
pspatel321 | 38:8efacce315ae | 264 | CMP(3, "default") { // The hard-coded flash profile (found in FreezeFrame.cpp) |
pspatel321 | 38:8efacce315ae | 265 | Profile::loadProfile(0); // Copy default to RAM |
pspatel321 | 38:8efacce315ae | 266 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 267 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 268 | return 1; |
pspatel321 | 38:8efacce315ae | 269 | } |
pspatel321 | 38:8efacce315ae | 270 | CMP(3, "freeze") { // Get the profile portion of the last freeze frame captured |
pspatel321 | 38:8efacce315ae | 271 | if(Profile::loadProfile(-1)) { // Attemp to retrieve and copy to RAM |
pspatel321 | 38:8efacce315ae | 272 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 273 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 274 | return 1; |
pspatel321 | 38:8efacce315ae | 275 | } |
pspatel321 | 38:8efacce315ae | 276 | } |
pspatel321 | 38:8efacce315ae | 277 | int index = strtol(word[2], &next, 10); // Command was "profile load xxx" |
pspatel321 | 38:8efacce315ae | 278 | if (index <= NUM_STORED_PROFILES && index >= -1 && *next == 0) { // Valid index found? |
pspatel321 | 38:8efacce315ae | 279 | if (Profile::loadProfile(index)) { // Attempt to retrieve and copy to RAM |
pspatel321 | 38:8efacce315ae | 280 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 281 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 282 | return 1; |
pspatel321 | 38:8efacce315ae | 283 | } |
pspatel321 | 38:8efacce315ae | 284 | } |
pspatel321 | 38:8efacce315ae | 285 | return -1; |
pspatel321 | 38:8efacce315ae | 286 | } |
pspatel321 | 38:8efacce315ae | 287 | // View the profile only (NOT loaded to RAM, just display changed) |
pspatel321 | 38:8efacce315ae | 288 | CMP(2, "view") { |
pspatel321 | 38:8efacce315ae | 289 | CMP(3, "default") { // View the hard-coded flash profile |
pspatel321 | 38:8efacce315ae | 290 | if (Profile::getProfile(&tempData.viewProfile, 0)) { // Attempt to fetch pointer |
pspatel321 | 38:8efacce315ae | 291 | tempData.viewProfileNum = 0; // 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, "freeze") { // View the profile portion only of the last captured freeze frame |
pspatel321 | 38:8efacce315ae | 296 | if (Profile::getProfile(&tempData.viewProfile, -1)) { // Attempt to fetch pointer |
pspatel321 | 38:8efacce315ae | 297 | tempData.viewProfileNum = -1; // Mark the index of the fetched profile |
pspatel321 | 38:8efacce315ae | 298 | return 1; |
pspatel321 | 38:8efacce315ae | 299 | } |
pspatel321 | 38:8efacce315ae | 300 | } |
pspatel321 | 38:8efacce315ae | 301 | CMP(3, "live") { // Revert to normal, live view |
pspatel321 | 38:8efacce315ae | 302 | tempData.viewProfileNum = -2; // Mark live |
pspatel321 | 38:8efacce315ae | 303 | tempData.viewProfile = NULL; // Clear the pointer |
pspatel321 | 38:8efacce315ae | 304 | return 1; |
pspatel321 | 38:8efacce315ae | 305 | } |
pspatel321 | 38:8efacce315ae | 306 | |
pspatel321 | 38:8efacce315ae | 307 | int index = strtol(word[2], &next, 10); // Command was "profile view xxx" |
pspatel321 | 38:8efacce315ae | 308 | if (index <= NUM_STORED_PROFILES && index >= -1 && *next == 0) { // Valid index found? |
pspatel321 | 38:8efacce315ae | 309 | if (Profile::getProfile(&tempData.viewProfile, index)) { // Attempt to fetch pointer |
pspatel321 | 38:8efacce315ae | 310 | tempData.viewProfileNum = index; // Mark the index of the fetched profile |
pspatel321 | 38:8efacce315ae | 311 | return 1; |
pspatel321 | 38:8efacce315ae | 312 | } |
pspatel321 | 38:8efacce315ae | 313 | } |
pspatel321 | 38:8efacce315ae | 314 | return -1; |
pspatel321 | 38:8efacce315ae | 315 | } |
pspatel321 | 38:8efacce315ae | 316 | } |
pspatel321 | 34:18bcf276d3bf | 317 | } |
pspatel321 | 34:18bcf276d3bf | 318 | return -1; |
pspatel321 | 36:0afc0fc8f86b | 319 | } |
pspatel321 | 38:8efacce315ae | 320 | // Called when AMS AIRs Mode message stops coming in |
pspatel321 | 38:8efacce315ae | 321 | Timeout timer_AIRS_CLOSED; |
pspatel321 | 38:8efacce315ae | 322 | void timeout_AIRS_CLOSED() |
pspatel321 | 38:8efacce315ae | 323 | { |
pspatel321 | 38:8efacce315ae | 324 | op->signals &= ~AIRS_CLOSED; |
pspatel321 | 38:8efacce315ae | 325 | } |
pspatel321 | 38:8efacce315ae | 326 | |
pspatel321 | 38:8efacce315ae | 327 | // Called when Charger CAN messages stop coming in |
pspatel321 | 38:8efacce315ae | 328 | Timeout timer_CHARGER_DET; |
pspatel321 | 38:8efacce315ae | 329 | void timeout_CHARGER_DET() |
pspatel321 | 38:8efacce315ae | 330 | { |
pspatel321 | 38:8efacce315ae | 331 | op->signals &= ~CHARGER_DET; |
pspatel321 | 38:8efacce315ae | 332 | } |
pspatel321 | 38:8efacce315ae | 333 | |
pspatel321 | 38:8efacce315ae | 334 | // Called when PCM messages stop coming in |
pspatel321 | 38:8efacce315ae | 335 | Timeout timer_FANS; |
pspatel321 | 38:8efacce315ae | 336 | void timeout_FANS() |
pspatel321 | 38:8efacce315ae | 337 | { |
pspatel321 | 38:8efacce315ae | 338 | op->dcdc.request.fan1 = 0; |
pspatel321 | 38:8efacce315ae | 339 | op->dcdc.request.fan2 = 0; |
pspatel321 | 38:8efacce315ae | 340 | } |
pspatel321 | 38:8efacce315ae | 341 | Timeout timer_PUMPS; |
pspatel321 | 38:8efacce315ae | 342 | void timeout_PUMPS() |
pspatel321 | 38:8efacce315ae | 343 | { |
pspatel321 | 38:8efacce315ae | 344 | op->dcdc.request.pump1 = 0; |
pspatel321 | 38:8efacce315ae | 345 | op->dcdc.request.pump2 = 0; |
pspatel321 | 38:8efacce315ae | 346 | } |
pspatel321 | 38:8efacce315ae | 347 | |
pspatel321 | 38:8efacce315ae | 348 | #define REFRESH_TIMEOUT(NAME) \ |
pspatel321 | 38:8efacce315ae | 349 | timer_##NAME.detach(); \ |
pspatel321 | 38:8efacce315ae | 350 | timer_##NAME.attach(&timeout_##NAME, CAN_DEVICE_TIMEOUT); |
pspatel321 | 38:8efacce315ae | 351 | |
pspatel321 | 38:8efacce315ae | 352 | bool serviceCAN(CANMessage* fromXbee) |
pspatel321 | 38:8efacce315ae | 353 | { |
pspatel321 | 38:8efacce315ae | 354 | CANMessage msg; |
pspatel321 | 38:8efacce315ae | 355 | if (fromXbee != NULL) { |
pspatel321 | 38:8efacce315ae | 356 | memcpy((void*)&msg, (void*)fromXbee, sizeof(CANMessage)); |
pspatel321 | 38:8efacce315ae | 357 | } else { |
pspatel321 | 38:8efacce315ae | 358 | if (!can.rxRead(msg)) return false; |
pspatel321 | 38:8efacce315ae | 359 | } |
pspatel321 | 38:8efacce315ae | 360 | // Redirect global car reset |
pspatel321 | 38:8efacce315ae | 361 | if (msg.id == GLOBAL_CAR_RESET_RX_ID) msg.id = RESETCLEAR_RX_ID; |
pspatel321 | 38:8efacce315ae | 362 | |
pspatel321 | 38:8efacce315ae | 363 | switch (msg.id) { |
pspatel321 | 38:8efacce315ae | 364 | // Reset microntroller |
pspatel321 | 38:8efacce315ae | 365 | case (RESET_RX_ID): |
pspatel321 | 38:8efacce315ae | 366 | if (msg.len == 0) { // Length must = 0 |
pspatel321 | 38:8efacce315ae | 367 | NVIC_SystemReset(); |
pspatel321 | 38:8efacce315ae | 368 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 369 | } |
pspatel321 | 38:8efacce315ae | 370 | CAN_FAIL |
pspatel321 | 38:8efacce315ae | 371 | |
pspatel321 | 38:8efacce315ae | 372 | |
pspatel321 | 38:8efacce315ae | 373 | // Clear non-volatile fault flags, then reset microcontroller |
pspatel321 | 38:8efacce315ae | 374 | case (RESETCLEAR_RX_ID): |
pspatel321 | 38:8efacce315ae | 375 | if (msg.len == 0) { // Length must = 0 |
pspatel321 | 38:8efacce315ae | 376 | FreezeFrame::clearError(); |
pspatel321 | 38:8efacce315ae | 377 | NVIC_SystemReset(); |
pspatel321 | 38:8efacce315ae | 378 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 379 | } |
pspatel321 | 38:8efacce315ae | 380 | CAN_FAIL |
pspatel321 | 38:8efacce315ae | 381 | |
pspatel321 | 38:8efacce315ae | 382 | // Artificially capture a freeze frame |
pspatel321 | 38:8efacce315ae | 383 | case (CAPTURE_RX_ID): |
pspatel321 | 38:8efacce315ae | 384 | if (msg.len == 0) { // Length must = 0 |
pspatel321 | 38:8efacce315ae | 385 | if (!FreezeFrame::getError()) { // Only allow capture if freeze frame from the last error was read |
pspatel321 | 38:8efacce315ae | 386 | if (FreezeFrame::writeFrame()) { // Capture the RAM contents to flash |
pspatel321 | 38:8efacce315ae | 387 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 388 | } |
pspatel321 | 38:8efacce315ae | 389 | } |
pspatel321 | 38:8efacce315ae | 390 | } |
pspatel321 | 38:8efacce315ae | 391 | CAN_FAIL |
pspatel321 | 38:8efacce315ae | 392 | |
pspatel321 | 38:8efacce315ae | 393 | // Clear fault conditions |
pspatel321 | 38:8efacce315ae | 394 | case (CLEAR_RX_ID): |
pspatel321 | 38:8efacce315ae | 395 | if (msg.len == 1) { // One data byte |
pspatel321 | 38:8efacce315ae | 396 | if (msg.data[0] == 0) { // Clear only freeze frame error if = 0 |
pspatel321 | 38:8efacce315ae | 397 | FreezeFrame::clearError(); // Clear non-volatile freeze frame marker |
pspatel321 | 38:8efacce315ae | 398 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 399 | } |
pspatel321 | 38:8efacce315ae | 400 | if (msg.data[0] == 1) { // Clear everything if = 1 |
pspatel321 | 38:8efacce315ae | 401 | runTime::clearFaults(); |
pspatel321 | 38:8efacce315ae | 402 | op->faultCode = 0; |
pspatel321 | 38:8efacce315ae | 403 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 404 | } |
pspatel321 | 38:8efacce315ae | 405 | } |
pspatel321 | 38:8efacce315ae | 406 | CAN_FAIL |
pspatel321 | 38:8efacce315ae | 407 | |
pspatel321 | 38:8efacce315ae | 408 | // Set the time (RTC) |
pspatel321 | 38:8efacce315ae | 409 | case (TIME_RX_ID): |
pspatel321 | 38:8efacce315ae | 410 | if (msg.len == 6*sizeof(char)) { // 6 Bytes |
pspatel321 | 38:8efacce315ae | 411 | struct tm t; // Time & date struct |
pspatel321 | 38:8efacce315ae | 412 | t.tm_mon = msg.data[0]; // Month in byte[0] |
pspatel321 | 38:8efacce315ae | 413 | t.tm_mday = msg.data[1]; // Day |
pspatel321 | 38:8efacce315ae | 414 | t.tm_year = msg.data[2]; // Year (offset from 2000) |
pspatel321 | 38:8efacce315ae | 415 | t.tm_year = t.tm_year - 1900 + 2000; // Apply year index mod and offset |
pspatel321 | 38:8efacce315ae | 416 | t.tm_mon = t.tm_mon - 1; // Month index mod |
pspatel321 | 38:8efacce315ae | 417 | t.tm_hour = msg.data[3]; // Get hour of time in byte[3] (24 hr format) |
pspatel321 | 38:8efacce315ae | 418 | t.tm_min = msg.data[4]; // Minutes |
pspatel321 | 38:8efacce315ae | 419 | t.tm_sec = msg.data[5]; // Seconds |
pspatel321 | 38:8efacce315ae | 420 | set_time(mktime(&t)); // Set RTC |
pspatel321 | 38:8efacce315ae | 421 | time_t diff = time(NULL) - op->SysTime; // Old time to new time change |
pspatel321 | 38:8efacce315ae | 422 | op->startTime += diff; // Shift the startTime to new timebase |
pspatel321 | 38:8efacce315ae | 423 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 424 | } |
pspatel321 | 38:8efacce315ae | 425 | CAN_FAIL |
pspatel321 | 38:8efacce315ae | 426 | |
pspatel321 | 38:8efacce315ae | 427 | // RAM and flash profile manipulations |
pspatel321 | 38:8efacce315ae | 428 | case (PROFILE_RX_ID): |
pspatel321 | 38:8efacce315ae | 429 | if (msg.len == 2*sizeof(char)) { // 2 command bytes |
pspatel321 | 38:8efacce315ae | 430 | if (msg.data[0] == 0) { // Load profile from a flash location to RAM |
pspatel321 | 38:8efacce315ae | 431 | int index = msg.data[1]; // Second byte contains profile index |
pspatel321 | 38:8efacce315ae | 432 | if (msg.data[1] == 0xff) index = -1; // If freeze (special case) |
pspatel321 | 38:8efacce315ae | 433 | if (Profile::loadProfile(index)) { // Attempt to load (copy flash to RAM) |
pspatel321 | 38:8efacce315ae | 434 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 435 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 436 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 437 | } |
pspatel321 | 38:8efacce315ae | 438 | } |
pspatel321 | 38:8efacce315ae | 439 | if (msg.data[0] == 1) { // Write profile to flash from RAM |
pspatel321 | 38:8efacce315ae | 440 | int index = msg.data[1]; // Get which slot to write to from message |
pspatel321 | 38:8efacce315ae | 441 | if (msg.data[1] == 0xff) index = -1; // If freeze (special case) |
pspatel321 | 38:8efacce315ae | 442 | bool s = Profile::saveProfile(index); // Write profile to flash slot |
pspatel321 | 38:8efacce315ae | 443 | if (s) { |
pspatel321 | 38:8efacce315ae | 444 | op->profileIndex = Profile::usingProfile(); // Change the currently loaded profile marker |
pspatel321 | 38:8efacce315ae | 445 | op->profileModded = false; // Mark it as a fresh, unmodified profile |
pspatel321 | 38:8efacce315ae | 446 | CAN_SUCCESS |
pspatel321 | 38:8efacce315ae | 447 | } |
pspatel321 | 38:8efacce315ae | 448 | } |
pspatel321 | 38:8efacce315ae | 449 | } |
pspatel321 | 38:8efacce315ae | 450 | CAN_FAIL |
pspatel321 | 38:8efacce315ae | 451 | |
pspatel321 | 38:8efacce315ae | 452 | case FAN_CONTROL_ID: |
pspatel321 | 38:8efacce315ae | 453 | if (msg.len != 2*sizeof(float)) return false; |
pspatel321 | 38:8efacce315ae | 454 | REFRESH_TIMEOUT(FANS) |
pspatel321 | 38:8efacce315ae | 455 | op->dcdc.request.fan1 = *((float*)((void*)(&msg.data[0]))); |
pspatel321 | 38:8efacce315ae | 456 | op->dcdc.request.fan2 = *((float*)((void*)(&msg.data[4]))); |
pspatel321 | 38:8efacce315ae | 457 | return true; |
pspatel321 | 38:8efacce315ae | 458 | |
pspatel321 | 38:8efacce315ae | 459 | case PUMP_CONTROL_ID: |
pspatel321 | 38:8efacce315ae | 460 | if (msg.len != 2*sizeof(float)) return false; |
pspatel321 | 38:8efacce315ae | 461 | REFRESH_TIMEOUT(PUMPS) |
pspatel321 | 38:8efacce315ae | 462 | op->dcdc.request.pump1 = *((float*)((void*)(&msg.data[0]))); |
pspatel321 | 38:8efacce315ae | 463 | op->dcdc.request.pump2 = *((float*)((void*)(&msg.data[4]))); |
pspatel321 | 38:8efacce315ae | 464 | return true; |
pspatel321 | 38:8efacce315ae | 465 | |
pspatel321 | 38:8efacce315ae | 466 | case AMS_MODE_ID: |
pspatel321 | 38:8efacce315ae | 467 | if (msg.len != sizeof(char)) return false; |
pspatel321 | 38:8efacce315ae | 468 | REFRESH_TIMEOUT(AIRS_CLOSED) |
pspatel321 | 38:8efacce315ae | 469 | if (msg.data[0] & 1<<2) { // AIRs closed? |
pspatel321 | 38:8efacce315ae | 470 | op->signals |= AIRS_CLOSED; |
pspatel321 | 38:8efacce315ae | 471 | } else { |
pspatel321 | 38:8efacce315ae | 472 | op->signals &= ~AIRS_CLOSED; |
pspatel321 | 38:8efacce315ae | 473 | } |
pspatel321 | 38:8efacce315ae | 474 | return true; |
pspatel321 | 38:8efacce315ae | 475 | case CHARGER_ERR_ID: |
pspatel321 | 38:8efacce315ae | 476 | REFRESH_TIMEOUT(CHARGER_DET) |
pspatel321 | 38:8efacce315ae | 477 | op->signals |= CHARGER_DET; |
pspatel321 | 38:8efacce315ae | 478 | return true; |
pspatel321 | 38:8efacce315ae | 479 | default: |
pspatel321 | 38:8efacce315ae | 480 | break; |
pspatel321 | 38:8efacce315ae | 481 | } |
pspatel321 | 38:8efacce315ae | 482 | bool parsed=false; |
pspatel321 | 38:8efacce315ae | 483 | |
pspatel321 | 38:8efacce315ae | 484 | CAN_CHANGE(chargeCurrent, PROFILE_CHARGECURRENT_RX_ID ) |
pspatel321 | 38:8efacce315ae | 485 | CAN_CHANGE(dischargeCurrent, PROFILE_DISCHARGECURRENT_RX_ID ) |
pspatel321 | 38:8efacce315ae | 486 | CAN_CHANGE(nominalCapacity, PROFILE_NOMINALCAPACITY_RX_ID ) |
pspatel321 | 38:8efacce315ae | 487 | CAN_CHANGE(glvBat_taps, PROFILE_GLVBATTAPS_RX_ID ) |
pspatel321 | 38:8efacce315ae | 488 | CAN_CHANGE(dcdcThreshold, PROFILE_DCDCONTHRESHOLD_RX_ID ) |
pspatel321 | 38:8efacce315ae | 489 | CAN_CHANGE(dcdcOverCurrent, PROFILE_DCDCOVERCURRENT_RX_ID ) |
pspatel321 | 38:8efacce315ae | 490 | CAN_CHANGE(dcdcStartDelay, PROFILE_DCDCSTARTDELAY_RX_ID ) |
pspatel321 | 38:8efacce315ae | 491 | CAN_CHANGE(dcdcStopDelay, PROFILE_DCDCSTOPDELAY_RX_ID ) |
pspatel321 | 38:8efacce315ae | 492 | CAN_CHANGE(dcdc_taps, PROFILE_DCDC_TAPS_RX_ID ) |
pspatel321 | 38:8efacce315ae | 493 | CAN_CHANGE(imdStartDelay, PROFILE_IMDSTARTDELAY_RX_ID ) |
pspatel321 | 38:8efacce315ae | 494 | CAN_CHANGE(internalOverTemp, PROFILE_INTERNALOVERTEMP_RX_ID ) |
pspatel321 | 38:8efacce315ae | 495 | CAN_CHANGE(CANnoAck, PROFILE_CANNOACK_RX_ID ) |
pspatel321 | 38:8efacce315ae | 496 | CAN_CHANGE(extendedSerial, PROFILE_EXTENDSERIAL_RX_ID ) |
pspatel321 | 38:8efacce315ae | 497 | CAN_CHANGE(CANtxSize, PROFILE_CANTXSIZE_RX_ID ) |
pspatel321 | 38:8efacce315ae | 498 | CAN_CHANGE(CANrxSize, PROFILE_CANRXSIZE_RX_ID ) |
pspatel321 | 38:8efacce315ae | 499 | CAN_CHANGE(SerialBaud, PROFILE_SERIALBAUD_RX_ID ) |
pspatel321 | 38:8efacce315ae | 500 | CAN_CHANGE(SerialTxSize, PROFILE_SERIALTXSIZE_RX_ID ) |
pspatel321 | 38:8efacce315ae | 501 | CAN_CHANGE(XbeeBaud, PROFILE_XBEEBAUD_RX_ID ) |
pspatel321 | 38:8efacce315ae | 502 | CAN_CHANGE(XbeeTxSize, PROFILE_XBEETXSIZE_RX_ID ) |
pspatel321 | 38:8efacce315ae | 503 | CAN_CHANGE(XbeeRxSize, PROFILE_XBEERXSIZE_RX_ID ) |
pspatel321 | 38:8efacce315ae | 504 | |
pspatel321 | 38:8efacce315ae | 505 | if (!parsed) return false; |
pspatel321 | 38:8efacce315ae | 506 | |
pspatel321 | 38:8efacce315ae | 507 | if (msg.id == PROFILE_NOMINALCAPACITY_RX_ID ) return glvBat.changeCapacity(param->nominalCapacity)?1:-1; |
pspatel321 | 38:8efacce315ae | 508 | if (msg.id == PROFILE_GLVBATTAPS_RX_ID ) return glvBat.size(param->glvBat_taps)?1:-1; |
pspatel321 | 38:8efacce315ae | 509 | if (msg.id == PROFILE_DCDC_TAPS_RX_ID ) return dcdc.size(param->dcdc_taps)?1:-1; |
pspatel321 | 38:8efacce315ae | 510 | if (msg.id == PROFILE_CANTXSIZE_RX_ID ) return can.txSize(param->CANtxSize)?1:-1; |
pspatel321 | 38:8efacce315ae | 511 | if (msg.id == PROFILE_CANRXSIZE_RX_ID ) return can.rxSize(param->CANrxSize)?1:-1; |
pspatel321 | 38:8efacce315ae | 512 | if (msg.id == PROFILE_SERIALBAUD_RX_ID ) pc.baud(param->SerialBaud); |
pspatel321 | 38:8efacce315ae | 513 | if (msg.id == PROFILE_SERIALTXSIZE_RX_ID ) return (pc.txBufferSetSize(param->SerialTxSize) == 0)?1:-1; |
pspatel321 | 38:8efacce315ae | 514 | if (msg.id == PROFILE_XBEEBAUD_RX_ID ) xbeeRelay.baud(param->XbeeBaud); |
pspatel321 | 38:8efacce315ae | 515 | if (msg.id == PROFILE_XBEETXSIZE_RX_ID ) return (xbeeRelay.txSize(param->XbeeTxSize))?1:-1; |
pspatel321 | 38:8efacce315ae | 516 | if (msg.id == PROFILE_XBEERXSIZE_RX_ID ) return (xbeeRelay.rxSize(param->XbeeRxSize))?1:-1; |
pspatel321 | 38:8efacce315ae | 517 | |
pspatel321 | 38:8efacce315ae | 518 | return true; |
pspatel321 | 38:8efacce315ae | 519 | } |
pspatel321 | 38:8efacce315ae | 520 | // Check for incoming messages from the xbees, relay them to the CAN function and send them out on the bus |
pspatel321 | 38:8efacce315ae | 521 | bool receiveMsgXbee() |
pspatel321 | 38:8efacce315ae | 522 | { |
pspatel321 | 38:8efacce315ae | 523 | CANMessage msg; |
pspatel321 | 38:8efacce315ae | 524 | if (xbeeRelay.receive(msg)) { // Incoming CAN message string received |
pspatel321 | 38:8efacce315ae | 525 | if (!can.txWrite(msg)) op->faultCode |= CAN_FAULT; // Send it out on the CAN bus |
pspatel321 | 38:8efacce315ae | 526 | serviceCAN(&msg); // Send it into the local serviceCAN routine |
pspatel321 | 38:8efacce315ae | 527 | return true; |
pspatel321 | 38:8efacce315ae | 528 | } else return false; |
pspatel321 | 38:8efacce315ae | 529 | } |
pspatel321 | 38:8efacce315ae | 530 | |
pspatel321 | 36:0afc0fc8f86b | 531 | |
pspatel321 | 36:0afc0fc8f86b | 532 | void inCommands::thread_getInputs(void const* args) |
pspatel321 | 36:0afc0fc8f86b | 533 | { |
pspatel321 | 36:0afc0fc8f86b | 534 | while(1) { |
pspatel321 | 38:8efacce315ae | 535 | serviceCAN(0); |
pspatel321 | 38:8efacce315ae | 536 | receiveMsgXbee(); |
pspatel321 | 36:0afc0fc8f86b | 537 | |
pspatel321 | 38:8efacce315ae | 538 | int ret = serviceSerial(); |
pspatel321 | 36:0afc0fc8f86b | 539 | if (ret == -1) tempData.parseGoodChar = 'x'; |
pspatel321 | 36:0afc0fc8f86b | 540 | if (ret == 1) tempData.parseGoodChar = 251; |
pspatel321 | 36:0afc0fc8f86b | 541 | osSignalSet((osThreadId)(tempData.wdtThreadId), 1<<2); // Signal watchdog thread |
pspatel321 | 36:0afc0fc8f86b | 542 | } |
pspatel321 | 30:91af74a299e1 | 543 | } |