System Management code

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

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?

UserRevisionLine numberNew 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 }