System Management code
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
inCommands/inCommands.cpp@34:18bcf276d3bf, 2015-01-07 (annotated)
- Committer:
- pspatel321
- Date:
- Wed Jan 07 03:25:50 2015 +0000
- Revision:
- 34:18bcf276d3bf
- Parent:
- serviceCAN/serviceCAN.cpp@33:6bc82b6b62e5
- Child:
- 36:0afc0fc8f86b
Added serial input. Updated glvBat coulomb counter to match AMS, brought in changes to outDiag and inCommands from AMS.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pspatel321 | 34:18bcf276d3bf | 1 | #include "inCommands.h" |
pspatel321 | 30:91af74a299e1 | 2 | |
pspatel321 | 34:18bcf276d3bf | 3 | bool inCommands::serviceCAN(CANMessage* fromXbee) |
pspatel321 | 33:6bc82b6b62e5 | 4 | { |
pspatel321 | 30:91af74a299e1 | 5 | CANMessage msg; |
pspatel321 | 33:6bc82b6b62e5 | 6 | if (fromXbee != NULL) { |
pspatel321 | 33:6bc82b6b62e5 | 7 | memcpy((void*)&msg, (void*)fromXbee, sizeof(CANMessage)); |
pspatel321 | 33:6bc82b6b62e5 | 8 | } else { |
pspatel321 | 33:6bc82b6b62e5 | 9 | if (!can.rxRead(msg)) return false; |
pspatel321 | 33:6bc82b6b62e5 | 10 | } |
pspatel321 | 33:6bc82b6b62e5 | 11 | |
pspatel321 | 33:6bc82b6b62e5 | 12 | switch (msg.id) { |
pspatel321 | 33:6bc82b6b62e5 | 13 | case FAN_CONTROL_ID: |
pspatel321 | 33:6bc82b6b62e5 | 14 | if (msg.len != 2*sizeof(float)) break; |
pspatel321 | 33:6bc82b6b62e5 | 15 | memcpy((void*)&CANdata.dcdcFan1Duty, &msg.data[0], sizeof(float)); |
pspatel321 | 33:6bc82b6b62e5 | 16 | memcpy((void*)&CANdata.dcdcFan2Duty, &msg.data[4], sizeof(float)); |
pspatel321 | 33:6bc82b6b62e5 | 17 | dcdc.setPwm(FAN1, CANdata.dcdcFan1Duty); |
pspatel321 | 33:6bc82b6b62e5 | 18 | dcdc.setPwm(FAN2, CANdata.dcdcFan2Duty); |
pspatel321 | 33:6bc82b6b62e5 | 19 | break; |
pspatel321 | 33:6bc82b6b62e5 | 20 | |
pspatel321 | 33:6bc82b6b62e5 | 21 | case PUMP_CONTROL_ID: |
pspatel321 | 33:6bc82b6b62e5 | 22 | if (msg.len != 2*sizeof(float)) break; |
pspatel321 | 33:6bc82b6b62e5 | 23 | memcpy((void*)&CANdata.dcdcPump1Duty, &msg.data[0], sizeof(float)); |
pspatel321 | 33:6bc82b6b62e5 | 24 | memcpy((void*)&CANdata.dcdcPump2Duty, &msg.data[4], sizeof(float)); |
pspatel321 | 33:6bc82b6b62e5 | 25 | dcdc.setPwm(PUMP1, CANdata.dcdcPump1Duty); |
pspatel321 | 33:6bc82b6b62e5 | 26 | dcdc.setPwm(PUMP2, CANdata.dcdcPump2Duty); |
pspatel321 | 33:6bc82b6b62e5 | 27 | break; |
pspatel321 | 33:6bc82b6b62e5 | 28 | |
pspatel321 | 33:6bc82b6b62e5 | 29 | case DCDC_CONTROL_ID: |
pspatel321 | 33:6bc82b6b62e5 | 30 | if (msg.len != sizeof(char)) break; |
pspatel321 | 33:6bc82b6b62e5 | 31 | if (msg.data[0] == 1) dcdc.set(1); |
pspatel321 | 33:6bc82b6b62e5 | 32 | else dcdc.set(0); |
pspatel321 | 33:6bc82b6b62e5 | 33 | break; |
pspatel321 | 33:6bc82b6b62e5 | 34 | |
pspatel321 | 33:6bc82b6b62e5 | 35 | case AMS_RELAYS_ID: |
pspatel321 | 33:6bc82b6b62e5 | 36 | if (msg.len != sizeof(char)) break; |
pspatel321 | 33:6bc82b6b62e5 | 37 | if ((msg.data[0] & (1<<3|1<<4|1<<5)) == (1<<3|1<<4|1<<5)) { // AIRs closed? 1<<3=posAIR, 1<<4=negAIR, 1<<5=tractiveEnable signal |
pspatel321 | 33:6bc82b6b62e5 | 38 | CANdata.airsClosed = true; |
pspatel321 | 33:6bc82b6b62e5 | 39 | dcdc.set(1); |
pspatel321 | 33:6bc82b6b62e5 | 40 | } else { |
pspatel321 | 33:6bc82b6b62e5 | 41 | CANdata.airsClosed = false; |
pspatel321 | 33:6bc82b6b62e5 | 42 | dcdc.set(0); |
pspatel321 | 33:6bc82b6b62e5 | 43 | } |
pspatel321 | 33:6bc82b6b62e5 | 44 | break; |
pspatel321 | 33:6bc82b6b62e5 | 45 | |
pspatel321 | 33:6bc82b6b62e5 | 46 | case GLVBAT_CLEARSOC_ID: |
pspatel321 | 33:6bc82b6b62e5 | 47 | if (msg.len != sizeof(float)) break; |
pspatel321 | 33:6bc82b6b62e5 | 48 | glvBat.resetToSOC(*((float*)(&msg.data[0]))); |
pspatel321 | 33:6bc82b6b62e5 | 49 | break; |
pspatel321 | 33:6bc82b6b62e5 | 50 | |
pspatel321 | 33:6bc82b6b62e5 | 51 | case GLVBAT_CLEARAH_ID: |
pspatel321 | 33:6bc82b6b62e5 | 52 | if (msg.len != sizeof(float)) break; |
pspatel321 | 33:6bc82b6b62e5 | 53 | glvBat.resetToAh(*((float*)(&msg.data[0]))); |
pspatel321 | 33:6bc82b6b62e5 | 54 | break; |
pspatel321 | 33:6bc82b6b62e5 | 55 | |
pspatel321 | 33:6bc82b6b62e5 | 56 | case GLVBAT_SETCAPAC_ID: |
pspatel321 | 33:6bc82b6b62e5 | 57 | if (msg.len != sizeof(float)) break; |
pspatel321 | 33:6bc82b6b62e5 | 58 | glvBat.changeCapacity(*((float*)(&msg.data[0]))); |
pspatel321 | 33:6bc82b6b62e5 | 59 | break; |
pspatel321 | 33:6bc82b6b62e5 | 60 | case STEERING_RESET_ID: |
pspatel321 | 33:6bc82b6b62e5 | 61 | NVIC_SystemReset(); |
pspatel321 | 33:6bc82b6b62e5 | 62 | break; |
pspatel321 | 33:6bc82b6b62e5 | 63 | default: |
pspatel321 | 33:6bc82b6b62e5 | 64 | break; |
pspatel321 | 33:6bc82b6b62e5 | 65 | } |
pspatel321 | 33:6bc82b6b62e5 | 66 | |
pspatel321 | 33:6bc82b6b62e5 | 67 | return true; |
pspatel321 | 33:6bc82b6b62e5 | 68 | |
pspatel321 | 33:6bc82b6b62e5 | 69 | } |
pspatel321 | 34:18bcf276d3bf | 70 | // Check for incoming messages from the xbees, relay them to the CAN function and send them out on the bus |
pspatel321 | 34:18bcf276d3bf | 71 | bool inCommands::receiveMsgXbee() |
pspatel321 | 33:6bc82b6b62e5 | 72 | { |
pspatel321 | 33:6bc82b6b62e5 | 73 | CANMessage msg; |
pspatel321 | 33:6bc82b6b62e5 | 74 | if (xbeeRelay.receive(msg)) { // Incoming CAN message string received |
pspatel321 | 33:6bc82b6b62e5 | 75 | if (!can.txWrite(msg)) data.canFault = true; // Send it out on the CAN bus |
pspatel321 | 33:6bc82b6b62e5 | 76 | serviceCAN(&msg); // Send it into the local serviceCAN routine |
pspatel321 | 31:7eaa5e881b56 | 77 | return true; |
pspatel321 | 33:6bc82b6b62e5 | 78 | } else return false; |
pspatel321 | 34:18bcf276d3bf | 79 | } |
pspatel321 | 34:18bcf276d3bf | 80 | |
pspatel321 | 34:18bcf276d3bf | 81 | // Compare string to a word in the serial input, shorter to type |
pspatel321 | 34:18bcf276d3bf | 82 | #define CMP(w, string) if (!strcasecmp(word[w-1], string)) |
pspatel321 | 34:18bcf276d3bf | 83 | static char word[3][RX_SIZE+1]; |
pspatel321 | 34:18bcf276d3bf | 84 | // Serial input |
pspatel321 | 34:18bcf276d3bf | 85 | int inCommands::serviceSerial() |
pspatel321 | 34:18bcf276d3bf | 86 | { |
pspatel321 | 34:18bcf276d3bf | 87 | |
pspatel321 | 34:18bcf276d3bf | 88 | static int end = 0; // End of string position |
pspatel321 | 34:18bcf276d3bf | 89 | int c = pc.getcNb(); // Get char from RX buffer (returns an int) |
pspatel321 | 34:18bcf276d3bf | 90 | if (c == -1) return -2; // Invalid char, no char available |
pspatel321 | 34:18bcf276d3bf | 91 | char b = c; // Casted to char type |
pspatel321 | 34:18bcf276d3bf | 92 | bool process = false; // Is string complete (ready to parse)? |
pspatel321 | 34:18bcf276d3bf | 93 | |
pspatel321 | 34:18bcf276d3bf | 94 | if (b == '\n' || b == '\r') { // Enter key was pressed, dump for processing |
pspatel321 | 34:18bcf276d3bf | 95 | tempData.inputStr[end] = 0; // Null terminate |
pspatel321 | 34:18bcf276d3bf | 96 | end = 0; // Reset to start |
pspatel321 | 34:18bcf276d3bf | 97 | process = true; // Flag for processing |
pspatel321 | 34:18bcf276d3bf | 98 | |
pspatel321 | 34:18bcf276d3bf | 99 | } else if (b == '\b' || b == 127) { // Backspace or delete |
pspatel321 | 34:18bcf276d3bf | 100 | if (end > 0) end--; // Move back one char |
pspatel321 | 34:18bcf276d3bf | 101 | tempData.inputStr[end] = 0; // Erase char |
pspatel321 | 34:18bcf276d3bf | 102 | |
pspatel321 | 34:18bcf276d3bf | 103 | } else if (b > 31 && b < 127) { // New valid displayable char |
pspatel321 | 34:18bcf276d3bf | 104 | tempData.inputStr[end] = b; // Add to buffer |
pspatel321 | 34:18bcf276d3bf | 105 | end++; // Increment end |
pspatel321 | 34:18bcf276d3bf | 106 | tempData.inputStr[end] = 0; // Add null terminator |
pspatel321 | 34:18bcf276d3bf | 107 | if (end >= RX_SIZE) { |
pspatel321 | 34:18bcf276d3bf | 108 | end = 0; // Reset end location |
pspatel321 | 34:18bcf276d3bf | 109 | process = true; // Flag for processing |
pspatel321 | 34:18bcf276d3bf | 110 | } |
pspatel321 | 34:18bcf276d3bf | 111 | } |
pspatel321 | 34:18bcf276d3bf | 112 | |
pspatel321 | 34:18bcf276d3bf | 113 | // Continue to parsing section only if flagged as complete and string not empty |
pspatel321 | 34:18bcf276d3bf | 114 | if (!process || strlen(tempData.inputStr) == 0) return 0; |
pspatel321 | 34:18bcf276d3bf | 115 | |
pspatel321 | 34:18bcf276d3bf | 116 | int pieces = sscanf(tempData.inputStr, "%s %s %s", word[0], word[1], word[2]); // Populate words |
pspatel321 | 34:18bcf276d3bf | 117 | tempData.inputStr[0] = 0; // Empty the string displayed on screen |
pspatel321 | 34:18bcf276d3bf | 118 | |
pspatel321 | 34:18bcf276d3bf | 119 | char *next; // Used by strtod and strtoul |
pspatel321 | 34:18bcf276d3bf | 120 | |
pspatel321 | 34:18bcf276d3bf | 121 | // One word commands |
pspatel321 | 34:18bcf276d3bf | 122 | if (pieces == 1) { |
pspatel321 | 34:18bcf276d3bf | 123 | // Reset the microcontroller |
pspatel321 | 34:18bcf276d3bf | 124 | CMP(1, "reset") { |
pspatel321 | 34:18bcf276d3bf | 125 | NVIC_SystemReset(); |
pspatel321 | 34:18bcf276d3bf | 126 | return 1; |
pspatel321 | 34:18bcf276d3bf | 127 | } |
pspatel321 | 34:18bcf276d3bf | 128 | // Two word commands |
pspatel321 | 34:18bcf276d3bf | 129 | } |
pspatel321 | 34:18bcf276d3bf | 130 | if (pieces == 2) { |
pspatel321 | 34:18bcf276d3bf | 131 | // Manual DC-DC on/off control |
pspatel321 | 34:18bcf276d3bf | 132 | CMP(1, "dcdc") { |
pspatel321 | 34:18bcf276d3bf | 133 | CMP(2, "on") { |
pspatel321 | 34:18bcf276d3bf | 134 | dcdc.set(1); |
pspatel321 | 34:18bcf276d3bf | 135 | return 1; |
pspatel321 | 34:18bcf276d3bf | 136 | } |
pspatel321 | 34:18bcf276d3bf | 137 | CMP(2, "off") { |
pspatel321 | 34:18bcf276d3bf | 138 | dcdc.set(0); |
pspatel321 | 34:18bcf276d3bf | 139 | return 1; |
pspatel321 | 34:18bcf276d3bf | 140 | } |
pspatel321 | 34:18bcf276d3bf | 141 | return -1; |
pspatel321 | 34:18bcf276d3bf | 142 | } |
pspatel321 | 34:18bcf276d3bf | 143 | // Artificially update the SOC (battery life %) |
pspatel321 | 34:18bcf276d3bf | 144 | CMP(1, "SOC") { |
pspatel321 | 34:18bcf276d3bf | 145 | CMP(2, "Reset") { // Command was "SOC reset" - reset to 100%, do this after a full charge |
pspatel321 | 34:18bcf276d3bf | 146 | glvBat.resetToSOC(1); |
pspatel321 | 34:18bcf276d3bf | 147 | return 1; |
pspatel321 | 34:18bcf276d3bf | 148 | } |
pspatel321 | 34:18bcf276d3bf | 149 | float soc = strtod(word[1], &next); // Command was "SOC xxx" where xxx is float between 0 and 1 |
pspatel321 | 34:18bcf276d3bf | 150 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 151 | if (glvBat.resetToSOC(soc)) return 1; |
pspatel321 | 34:18bcf276d3bf | 152 | } |
pspatel321 | 34:18bcf276d3bf | 153 | return -1; |
pspatel321 | 34:18bcf276d3bf | 154 | } |
pspatel321 | 34:18bcf276d3bf | 155 | // Artificially update the AmpHours count (linked with SOC) |
pspatel321 | 34:18bcf276d3bf | 156 | CMP(1, "Ah") { |
pspatel321 | 34:18bcf276d3bf | 157 | CMP(2, "Reset") { // Command was "Amphours reset", equivalent to "SOC reset" |
pspatel321 | 34:18bcf276d3bf | 158 | glvBat.resetToSOC(1); |
pspatel321 | 34:18bcf276d3bf | 159 | return 1; |
pspatel321 | 34:18bcf276d3bf | 160 | } |
pspatel321 | 34:18bcf276d3bf | 161 | float ah = strtod(word[1], &next); // Command was "Amphours xxx" where xxx is a float in amphours |
pspatel321 | 34:18bcf276d3bf | 162 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 163 | if (glvBat.resetToAh(ah)) return 1; |
pspatel321 | 34:18bcf276d3bf | 164 | } |
pspatel321 | 34:18bcf276d3bf | 165 | return -1; |
pspatel321 | 34:18bcf276d3bf | 166 | } |
pspatel321 | 34:18bcf276d3bf | 167 | // Change the battery capacity setting for calculating Amphours |
pspatel321 | 34:18bcf276d3bf | 168 | CMP(1, "Capacity") { |
pspatel321 | 34:18bcf276d3bf | 169 | float cap = strtod(word[1], &next); // Command was "SOC xxx" where xxx is float between 0 and 1 |
pspatel321 | 34:18bcf276d3bf | 170 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 171 | if (glvBat.changeCapacity(cap)) return 1; |
pspatel321 | 34:18bcf276d3bf | 172 | } |
pspatel321 | 34:18bcf276d3bf | 173 | return -1; |
pspatel321 | 34:18bcf276d3bf | 174 | } |
pspatel321 | 34:18bcf276d3bf | 175 | } |
pspatel321 | 34:18bcf276d3bf | 176 | if (pieces == 3) { |
pspatel321 | 34:18bcf276d3bf | 177 | // Fan Duty |
pspatel321 | 34:18bcf276d3bf | 178 | CMP(1, "Fan") { |
pspatel321 | 34:18bcf276d3bf | 179 | float val1 = strtod(word[1], &next); |
pspatel321 | 34:18bcf276d3bf | 180 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 181 | float val2 = strtod(word[2], &next); |
pspatel321 | 34:18bcf276d3bf | 182 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 183 | dcdc.setPwm(FAN1, val1); |
pspatel321 | 34:18bcf276d3bf | 184 | dcdc.setPwm(FAN2, val2); |
pspatel321 | 34:18bcf276d3bf | 185 | return 1; |
pspatel321 | 34:18bcf276d3bf | 186 | } |
pspatel321 | 34:18bcf276d3bf | 187 | } |
pspatel321 | 34:18bcf276d3bf | 188 | return -1; |
pspatel321 | 34:18bcf276d3bf | 189 | } |
pspatel321 | 34:18bcf276d3bf | 190 | |
pspatel321 | 34:18bcf276d3bf | 191 | // Pump Duty |
pspatel321 | 34:18bcf276d3bf | 192 | CMP(1, "Pump") { |
pspatel321 | 34:18bcf276d3bf | 193 | float val1 = strtod(word[1], &next); |
pspatel321 | 34:18bcf276d3bf | 194 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 195 | float val2 = strtod(word[2], &next); |
pspatel321 | 34:18bcf276d3bf | 196 | if (*next == 0) { |
pspatel321 | 34:18bcf276d3bf | 197 | dcdc.setPwm(FAN1, val1); |
pspatel321 | 34:18bcf276d3bf | 198 | dcdc.setPwm(FAN2, val2); |
pspatel321 | 34:18bcf276d3bf | 199 | return 1; |
pspatel321 | 34:18bcf276d3bf | 200 | } |
pspatel321 | 34:18bcf276d3bf | 201 | } |
pspatel321 | 34:18bcf276d3bf | 202 | return -1; |
pspatel321 | 34:18bcf276d3bf | 203 | } |
pspatel321 | 34:18bcf276d3bf | 204 | } |
pspatel321 | 34:18bcf276d3bf | 205 | return -1; |
pspatel321 | 30:91af74a299e1 | 206 | } |