Penn Electric Racing / Mbed 2 deprecated SystemManagement

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:
33:6bc82b6b62e5
Child:
38:8efacce315ae
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 33:6bc82b6b62e5 1 #include "CAN-xbee.h"
pspatel321 33:6bc82b6b62e5 2
pspatel321 34:18bcf276d3bf 3 // Creates stringified version of CANMessage msg in char* buff (must be at least 15 chars)
pspatel321 34:18bcf276d3bf 4 // Returns -1 for bad message, or else returns size of char* buff including the terminating '\n'
pspatel321 34:18bcf276d3bf 5 int convert2array(CANMessage &msg, char* buff) {
pspatel321 34:18bcf276d3bf 6
pspatel321 34:18bcf276d3bf 7 // Check message integrity
pspatel321 34:18bcf276d3bf 8 if (msg.len > 8) return -1;
pspatel321 34:18bcf276d3bf 9 if ((msg.format == CANStandard) && ((msg.id & 0x7FF) != msg.id)) return -1;
pspatel321 34:18bcf276d3bf 10 if ((msg.format == CANExtended) && ((msg.id & 0x1FFFFFFF) != msg.id)) return -1;
pspatel321 34:18bcf276d3bf 11
pspatel321 34:18bcf276d3bf 12 int i = 0;
pspatel321 34:18bcf276d3bf 13 buff[i] = 'C'; // Start of message
pspatel321 34:18bcf276d3bf 14 i++;
pspatel321 34:18bcf276d3bf 15 /* buff[i] = (msg.format << 0) | (msg.type << 1) | ((msg.len & 0xf) << 2); // Header byte, message info on ID size, RTR, # data bytes
pspatel321 34:18bcf276d3bf 16 i++;
pspatel321 34:18bcf276d3bf 17 if (msg.format == CANStandard) {
pspatel321 34:18bcf276d3bf 18 buff[i++] = (msg.id & 0x0FF); // Lower byte of ID
pspatel321 34:18bcf276d3bf 19 buff[i++] = (msg.id & 0x700) >> 8; // Upper byte of ID
pspatel321 34:18bcf276d3bf 20 } else {
pspatel321 34:18bcf276d3bf 21 buff[i++] = (msg.id & 0x000000FF); // Lowest byte of ID
pspatel321 34:18bcf276d3bf 22 buff[i++] = (msg.id & 0x0000FF00) >> 8;
pspatel321 34:18bcf276d3bf 23 buff[i++] = (msg.id & 0x00FF0000) >> 16;
pspatel321 34:18bcf276d3bf 24 buff[i++] = (msg.id & 0x1F000000) >> 24; // Highest byte of ID
pspatel321 34:18bcf276d3bf 25 }
pspatel321 34:18bcf276d3bf 26 for (int j = 0; j < msg.len; j++) {
pspatel321 34:18bcf276d3bf 27 buff[i++] = msg.data[j];
pspatel321 34:18bcf276d3bf 28 }
pspatel321 34:18bcf276d3bf 29 buff[i++] = '\n';
pspatel321 34:18bcf276d3bf 30 */return i;
pspatel321 34:18bcf276d3bf 31 }
pspatel321 34:18bcf276d3bf 32
pspatel321 34:18bcf276d3bf 33 bool convert2msg(CANMessage &msg, char* buff) {
pspatel321 34:18bcf276d3bf 34 // Check for 'D' for done
pspatel321 34:18bcf276d3bf 35 if (buff[0] != 'D') return -1;
pspatel321 34:18bcf276d3bf 36
pspatel321 34:18bcf276d3bf 37 bool extended = buff[1] & 1;
pspatel321 34:18bcf276d3bf 38 bool rtr = buff[1] & 2;
pspatel321 34:18bcf276d3bf 39 char DLC = buff[1] >> 2;
pspatel321 34:18bcf276d3bf 40 if (DLC > 8) return false; // Bad length
pspatel321 34:18bcf276d3bf 41
pspatel321 34:18bcf276d3bf 42 // Standard frame, get id and data
pspatel321 34:18bcf276d3bf 43 if (!extended) {
pspatel321 34:18bcf276d3bf 44 if (buff[3] & 0x7 != buff[3]) return false; // Last byte of ID bad
pspatel321 34:18bcf276d3bf 45 msg.id = buff[2] | (int)(buff[3] << 8); // Build the ID
pspatel321 34:18bcf276d3bf 46 for (int i = 0; i < DLC; i++) msg.data[i] = buff[i+4]; // Build the data array
pspatel321 34:18bcf276d3bf 47
pspatel321 34:18bcf276d3bf 48 // Extended frame, get id and data
pspatel321 34:18bcf276d3bf 49 } else {
pspatel321 34:18bcf276d3bf 50 if (buff[5] & 0x1F != buff[5]) return false; // Last byte of ID bad
pspatel321 34:18bcf276d3bf 51 msg.id = buff[2] | (buff[3] << 8) | (buff[4] << 16) | (buff[5] << 24); // Build the ID
pspatel321 34:18bcf276d3bf 52 for (int i = 0; i < DLC; i++) msg.data[i] = buff[i+6]; // Build the data array
pspatel321 34:18bcf276d3bf 53 }
pspatel321 34:18bcf276d3bf 54 msg.len = DLC;
pspatel321 34:18bcf276d3bf 55 if (rtr) msg.type = CANRemote;
pspatel321 34:18bcf276d3bf 56 else msg.type = CANData;
pspatel321 34:18bcf276d3bf 57 if (extended) msg.format = CANExtended;
pspatel321 34:18bcf276d3bf 58 else msg.format = CANStandard;
pspatel321 34:18bcf276d3bf 59 return true; // Successfully parsed, passed all checks, arguement was updated
pspatel321 34:18bcf276d3bf 60 }
pspatel321 34:18bcf276d3bf 61
pspatel321 33:6bc82b6b62e5 62 CANxbee::CANxbee(PinName tx, PinName rx, int _baud, int txSize, int rxSize) : serial(tx, rx, txSize, rxSize) {
pspatel321 33:6bc82b6b62e5 63 serial.baud(_baud);
pspatel321 33:6bc82b6b62e5 64 rx_i = 0;
pspatel321 33:6bc82b6b62e5 65 rxBuff[0] = 0;
pspatel321 34:18bcf276d3bf 66 getChars = -1;
pspatel321 33:6bc82b6b62e5 67 }
pspatel321 33:6bc82b6b62e5 68
pspatel321 33:6bc82b6b62e5 69 // Send a CAN message, first reformat it into a char array, then send over Xbees
pspatel321 33:6bc82b6b62e5 70 bool CANxbee::send(CANMessage &msg) {
pspatel321 34:18bcf276d3bf 71 char buff[15]; // Build the string-ified CAN message here
pspatel321 34:18bcf276d3bf 72 int size = convert2array(msg, buff);
pspatel321 34:18bcf276d3bf 73 if (size == -1) return false; // Bad message, string not formed
pspatel321 33:6bc82b6b62e5 74 bool success=false;
pspatel321 33:6bc82b6b62e5 75
pspatel321 34:18bcf276d3bf 76 size=1;
pspatel321 34:18bcf276d3bf 77 int bytesLeft = serial.txBufferGetSize(0) - serial.txBufferGetCount();
pspatel321 34:18bcf276d3bf 78 Timer t;
pspatel321 33:6bc82b6b62e5 79
pspatel321 34:18bcf276d3bf 80 // Begin thread-safe section
pspatel321 34:18bcf276d3bf 81 NVIC_DisableIRQ(TIMER3_IRQn); // Timer3-->RTOS tick
pspatel321 34:18bcf276d3bf 82
pspatel321 34:18bcf276d3bf 83 if (bytesLeft >= size) {
pspatel321 33:6bc82b6b62e5 84 for (int i = 0; i < size; i++) serial.putc(buff[i]); // Send the message out
pspatel321 33:6bc82b6b62e5 85 success = true;
pspatel321 33:6bc82b6b62e5 86 }
pspatel321 33:6bc82b6b62e5 87
pspatel321 33:6bc82b6b62e5 88 // End thread-safe section
pspatel321 34:18bcf276d3bf 89 NVIC_EnableIRQ(TIMER3_IRQn); // Timer3-->RTOS tick
pspatel321 34:18bcf276d3bf 90
pspatel321 33:6bc82b6b62e5 91 return success;
pspatel321 33:6bc82b6b62e5 92 }
pspatel321 33:6bc82b6b62e5 93
pspatel321 33:6bc82b6b62e5 94 // Continuously call this function in main program, when it returns true, it holds a newly received CAN message that came via Xbee
pspatel321 33:6bc82b6b62e5 95 bool CANxbee::receive(CANMessage &msg) {
pspatel321 33:6bc82b6b62e5 96 int newChar = serial.getcNb();
pspatel321 33:6bc82b6b62e5 97 if (newChar == -1) return false; // No new char
pspatel321 33:6bc82b6b62e5 98 char c = newChar & 0xFF; // Cast to char
pspatel321 33:6bc82b6b62e5 99
pspatel321 34:18bcf276d3bf 100 // Listen for a 'C', start of new message as long as not already building message
pspatel321 34:18bcf276d3bf 101 if (c == 'C' && (rxBuff[0] != 'C')) {
pspatel321 34:18bcf276d3bf 102 rx_i = 0; // Reset to start of message
pspatel321 34:18bcf276d3bf 103 rxBuff[rx_i++] = 'C'; // Add the 'C', increment
pspatel321 33:6bc82b6b62e5 104 return false;
pspatel321 33:6bc82b6b62e5 105 }
pspatel321 34:18bcf276d3bf 106
pspatel321 34:18bcf276d3bf 107 // 'C' already found, now filling in contents of message
pspatel321 34:18bcf276d3bf 108 if (rxBuff[0] == 'C') {
pspatel321 34:18bcf276d3bf 109 if (getChars == -1) { // Get the header byte
pspatel321 34:18bcf276d3bf 110 rxBuff[rx_i++] = c; // Add to string, increment
pspatel321 34:18bcf276d3bf 111 bool extended = c & 1; // Is this an extended message? (4 ID bytes)
pspatel321 34:18bcf276d3bf 112 char DLC = c >> 2; // How long is the data section?
pspatel321 34:18bcf276d3bf 113 if (DLC > 8) { // Bad DLC, reset variables
pspatel321 34:18bcf276d3bf 114 getChars = -1;
pspatel321 34:18bcf276d3bf 115 rxBuff[0] = 0;
pspatel321 34:18bcf276d3bf 116 rx_i = 0;
pspatel321 34:18bcf276d3bf 117 return false;
pspatel321 34:18bcf276d3bf 118 }
pspatel321 34:18bcf276d3bf 119 getChars = DLC + extended?4:2; // Need to obtain getChars more characters to complete this message
pspatel321 34:18bcf276d3bf 120 } else { // This is not a header byte, add to contents of message
pspatel321 34:18bcf276d3bf 121 rxBuff[rx_i++] = c;
pspatel321 34:18bcf276d3bf 122 getChars--;
pspatel321 34:18bcf276d3bf 123 if (getChars <= 0) { // Just added the last char, done message, reset variables
pspatel321 34:18bcf276d3bf 124 rxBuff[0] = 'D'; // Mark 'D' for done
pspatel321 34:18bcf276d3bf 125 rx_i = 0;
pspatel321 34:18bcf276d3bf 126 getChars = -1;
pspatel321 34:18bcf276d3bf 127 }
pspatel321 33:6bc82b6b62e5 128 }
pspatel321 33:6bc82b6b62e5 129 }
pspatel321 34:18bcf276d3bf 130 if (rxBuff[0] != 'D') return false;
pspatel321 33:6bc82b6b62e5 131
pspatel321 33:6bc82b6b62e5 132 // A string is ready, process it here
pspatel321 34:18bcf276d3bf 133 if (convert2msg(msg, rxBuff)) return true;
pspatel321 34:18bcf276d3bf 134 else return false;
pspatel321 33:6bc82b6b62e5 135 }