![](/media/cache/group/underwritten_car_negative.png.50x50_q85.png)
System Management code
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
Diff: inCommands/inCommands.cpp
- Revision:
- 34:18bcf276d3bf
- Parent:
- 33:6bc82b6b62e5
- Child:
- 36:0afc0fc8f86b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inCommands/inCommands.cpp Wed Jan 07 03:25:50 2015 +0000 @@ -0,0 +1,206 @@ +#include "inCommands.h" + +bool inCommands::serviceCAN(CANMessage* fromXbee) +{ + CANMessage msg; + if (fromXbee != NULL) { + memcpy((void*)&msg, (void*)fromXbee, sizeof(CANMessage)); + } else { + if (!can.rxRead(msg)) return false; + } + + switch (msg.id) { + case FAN_CONTROL_ID: + if (msg.len != 2*sizeof(float)) break; + memcpy((void*)&CANdata.dcdcFan1Duty, &msg.data[0], sizeof(float)); + memcpy((void*)&CANdata.dcdcFan2Duty, &msg.data[4], sizeof(float)); + dcdc.setPwm(FAN1, CANdata.dcdcFan1Duty); + dcdc.setPwm(FAN2, CANdata.dcdcFan2Duty); + break; + + case PUMP_CONTROL_ID: + if (msg.len != 2*sizeof(float)) break; + memcpy((void*)&CANdata.dcdcPump1Duty, &msg.data[0], sizeof(float)); + memcpy((void*)&CANdata.dcdcPump2Duty, &msg.data[4], sizeof(float)); + dcdc.setPwm(PUMP1, CANdata.dcdcPump1Duty); + dcdc.setPwm(PUMP2, CANdata.dcdcPump2Duty); + break; + + case DCDC_CONTROL_ID: + if (msg.len != sizeof(char)) break; + if (msg.data[0] == 1) dcdc.set(1); + else dcdc.set(0); + break; + + case AMS_RELAYS_ID: + if (msg.len != sizeof(char)) break; + 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 + CANdata.airsClosed = true; + dcdc.set(1); + } else { + CANdata.airsClosed = false; + dcdc.set(0); + } + break; + + case GLVBAT_CLEARSOC_ID: + if (msg.len != sizeof(float)) break; + glvBat.resetToSOC(*((float*)(&msg.data[0]))); + break; + + case GLVBAT_CLEARAH_ID: + if (msg.len != sizeof(float)) break; + glvBat.resetToAh(*((float*)(&msg.data[0]))); + break; + + case GLVBAT_SETCAPAC_ID: + if (msg.len != sizeof(float)) break; + glvBat.changeCapacity(*((float*)(&msg.data[0]))); + break; + case STEERING_RESET_ID: + NVIC_SystemReset(); + break; + default: + break; + } + + return true; + +} +// Check for incoming messages from the xbees, relay them to the CAN function and send them out on the bus +bool inCommands::receiveMsgXbee() +{ + CANMessage msg; + if (xbeeRelay.receive(msg)) { // Incoming CAN message string received + if (!can.txWrite(msg)) data.canFault = true; // Send it out on the CAN bus + serviceCAN(&msg); // Send it into the local serviceCAN routine + return true; + } else return false; +} + +// Compare string to a word in the serial input, shorter to type +#define CMP(w, string) if (!strcasecmp(word[w-1], string)) +static char word[3][RX_SIZE+1]; +// Serial input +int inCommands::serviceSerial() +{ + + static int end = 0; // End of string position + int c = pc.getcNb(); // Get char from RX buffer (returns an int) + if (c == -1) return -2; // Invalid char, no char available + char b = c; // Casted to char type + bool process = false; // Is string complete (ready to parse)? + + if (b == '\n' || b == '\r') { // Enter key was pressed, dump for processing + tempData.inputStr[end] = 0; // Null terminate + end = 0; // Reset to start + process = true; // Flag for processing + + } else if (b == '\b' || b == 127) { // Backspace or delete + if (end > 0) end--; // Move back one char + tempData.inputStr[end] = 0; // Erase char + + } else if (b > 31 && b < 127) { // New valid displayable char + tempData.inputStr[end] = b; // Add to buffer + end++; // Increment end + tempData.inputStr[end] = 0; // Add null terminator + if (end >= RX_SIZE) { + end = 0; // Reset end location + process = true; // Flag for processing + } + } + + // Continue to parsing section only if flagged as complete and string not empty + if (!process || strlen(tempData.inputStr) == 0) return 0; + + int pieces = sscanf(tempData.inputStr, "%s %s %s", word[0], word[1], word[2]); // Populate words + tempData.inputStr[0] = 0; // Empty the string displayed on screen + + char *next; // Used by strtod and strtoul + + // One word commands + if (pieces == 1) { + // Reset the microcontroller + CMP(1, "reset") { + NVIC_SystemReset(); + return 1; + } + // Two word commands + } + if (pieces == 2) { + // Manual DC-DC on/off control + CMP(1, "dcdc") { + CMP(2, "on") { + dcdc.set(1); + return 1; + } + CMP(2, "off") { + dcdc.set(0); + return 1; + } + return -1; + } + // Artificially update the SOC (battery life %) + CMP(1, "SOC") { + CMP(2, "Reset") { // Command was "SOC reset" - reset to 100%, do this after a full charge + glvBat.resetToSOC(1); + return 1; + } + float soc = strtod(word[1], &next); // Command was "SOC xxx" where xxx is float between 0 and 1 + if (*next == 0) { + if (glvBat.resetToSOC(soc)) return 1; + } + return -1; + } + // Artificially update the AmpHours count (linked with SOC) + CMP(1, "Ah") { + CMP(2, "Reset") { // Command was "Amphours reset", equivalent to "SOC reset" + glvBat.resetToSOC(1); + return 1; + } + float ah = strtod(word[1], &next); // Command was "Amphours xxx" where xxx is a float in amphours + if (*next == 0) { + if (glvBat.resetToAh(ah)) return 1; + } + return -1; + } + // Change the battery capacity setting for calculating Amphours + CMP(1, "Capacity") { + float cap = strtod(word[1], &next); // Command was "SOC xxx" where xxx is float between 0 and 1 + if (*next == 0) { + if (glvBat.changeCapacity(cap)) return 1; + } + return -1; + } + } + if (pieces == 3) { + // Fan Duty + CMP(1, "Fan") { + float val1 = strtod(word[1], &next); + if (*next == 0) { + float val2 = strtod(word[2], &next); + if (*next == 0) { + dcdc.setPwm(FAN1, val1); + dcdc.setPwm(FAN2, val2); + return 1; + } + } + return -1; + } + + // Pump Duty + CMP(1, "Pump") { + float val1 = strtod(word[1], &next); + if (*next == 0) { + float val2 = strtod(word[2], &next); + if (*next == 0) { + dcdc.setPwm(FAN1, val1); + dcdc.setPwm(FAN2, val2); + return 1; + } + } + return -1; + } + } + return -1; +} \ No newline at end of file