System Management code

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

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