System Management code

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

inCommands/inCommands.cpp

Committer:
pspatel321
Date:
2015-01-07
Revision:
34:18bcf276d3bf
Parent:
serviceCAN/serviceCAN.cpp@ 33:6bc82b6b62e5
Child:
36:0afc0fc8f86b

File content as of revision 34:18bcf276d3bf:

#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;
}