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:
Sat Feb 07 08:54:51 2015 +0000
Revision:
38:8efacce315ae
Parent:
34:18bcf276d3bf
Updated with profiles, operating info, etc. Just like the other programs.  Awaiting test in car.

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