System Management code
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
inCommands/inCommands.cpp
- Committer:
- pspatel321
- Date:
- 2015-01-22
- Revision:
- 36:0afc0fc8f86b
- Parent:
- 34:18bcf276d3bf
- Child:
- 38:8efacce315ae
File content as of revision 36:0afc0fc8f86b:
#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_MODE_ID: if (msg.len != sizeof(char)) break; if (msg.data[0] & 1<<2) { // AIRs closed? CANdata.airsClosed = true; dcdc.set(1); } else { CANdata.airsClosed = false; dcdc.set(0); } break; case GLVBAT_SETSOC_ID: if (msg.len != sizeof(float)) break; glvBat.resetToSOC(*((float*)(&msg.data[0]))); break; case GLVBAT_SETAH_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)) // Serial input int inCommands::serviceSerial() { static int end = 0; // End of string position int c=0; if (pc.readable()) c = pc.getc(); 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 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((char*)tempData.inputStr) == 0) return 0; static char word[3][RX_SIZE+1]; // Hold 3 words 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 strtof 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; } } // Three word commands 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; } void inCommands::thread_getInputs(void const* args) { while(1) { inCommands::serviceCAN(); inCommands::receiveMsgXbee(); int ret = inCommands::serviceSerial(); if (ret == -1) tempData.parseGoodChar = 'x'; if (ret == 1) tempData.parseGoodChar = 251; osSignalSet((osThreadId)(tempData.wdtThreadId), 1<<2); // Signal watchdog thread } }