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:
Tue Jan 06 20:45:26 2015 +0000
Revision:
33:6bc82b6b62e5
Child:
34:18bcf276d3bf
Updated IDs to match AMS, added a constants.h file.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pspatel321 33:6bc82b6b62e5 1 #include "CAN-xbee.h"
pspatel321 33:6bc82b6b62e5 2
pspatel321 33:6bc82b6b62e5 3 CANxbee::CANxbee(PinName tx, PinName rx, int _baud, int txSize, int rxSize) : serial(tx, rx, txSize, rxSize) {
pspatel321 33:6bc82b6b62e5 4 serial.baud(_baud);
pspatel321 33:6bc82b6b62e5 5 rx_i = 0;
pspatel321 33:6bc82b6b62e5 6 rxBuff[0] = 0;
pspatel321 33:6bc82b6b62e5 7 building = false;
pspatel321 33:6bc82b6b62e5 8 }
pspatel321 33:6bc82b6b62e5 9
pspatel321 33:6bc82b6b62e5 10 // Send a CAN message, first reformat it into a char array, then send over Xbees
pspatel321 33:6bc82b6b62e5 11 bool CANxbee::send(CANMessage &msg) {
pspatel321 33:6bc82b6b62e5 12 char buff[14]; // Build the string-ified CAN message here
pspatel321 33:6bc82b6b62e5 13 int size;
pspatel321 33:6bc82b6b62e5 14
pspatel321 33:6bc82b6b62e5 15 buff[0] = 'C';
pspatel321 33:6bc82b6b62e5 16 int i;
pspatel321 33:6bc82b6b62e5 17 if (msg.format == 0) { // Standard, 11-bit ID
pspatel321 33:6bc82b6b62e5 18 buff[1] = (0 << 0) | (msg.type << 1) | ((msg.len & 0xf) << 2);
pspatel321 33:6bc82b6b62e5 19 buff[2] = msg.id & 0xFF; // Lower byte of ID
pspatel321 33:6bc82b6b62e5 20 buff[3] = (msg.id & 0x7FF) >> 8;
pspatel321 33:6bc82b6b62e5 21 for (i = 0; (i < msg.len) && (i < 8); i++) {
pspatel321 33:6bc82b6b62e5 22 buff[i+4] = msg.data[i]; // Get data bytes
pspatel321 33:6bc82b6b62e5 23 }
pspatel321 33:6bc82b6b62e5 24 buff[i+4] = '\n'; // Terminate message
pspatel321 33:6bc82b6b62e5 25 size = i+4+1;
pspatel321 33:6bc82b6b62e5 26
pspatel321 33:6bc82b6b62e5 27 } else if (msg.format == 1) { // Extended, 29-bit ID
pspatel321 33:6bc82b6b62e5 28 buff[1] = (1 << 0) | (msg.type << 1) | ((msg.len & 0xf) << 2);
pspatel321 33:6bc82b6b62e5 29 buff[2] = msg.id & 0x000000FF; // Lower byte of ID
pspatel321 33:6bc82b6b62e5 30 buff[3] = msg.id & 0x0000FF00 >> 8;
pspatel321 33:6bc82b6b62e5 31 buff[4] = msg.id & 0x00FF0000 >> 16;
pspatel321 33:6bc82b6b62e5 32 buff[5] = msg.id & 0x1F000000 >> 24;
pspatel321 33:6bc82b6b62e5 33 for (i = 0; (i < msg.len) && (i < 8); i++) {
pspatel321 33:6bc82b6b62e5 34 buff[i+6] = msg.data[i]; // Get data bytes
pspatel321 33:6bc82b6b62e5 35 }
pspatel321 33:6bc82b6b62e5 36 buff[i+6] = '\n'; // Terminate message
pspatel321 33:6bc82b6b62e5 37 size = i+6+1;
pspatel321 33:6bc82b6b62e5 38 } else return false; // Bad message
pspatel321 33:6bc82b6b62e5 39
pspatel321 33:6bc82b6b62e5 40 bool success=false;
pspatel321 33:6bc82b6b62e5 41
pspatel321 33:6bc82b6b62e5 42 // Begin thread-safe section
pspatel321 33:6bc82b6b62e5 43 __disable_irq();
pspatel321 33:6bc82b6b62e5 44
pspatel321 33:6bc82b6b62e5 45 // Check if enough spaces in buffer
pspatel321 33:6bc82b6b62e5 46 if ((serial.txBufferGetSize(0) - serial.txBufferGetCount()) >= size) {
pspatel321 33:6bc82b6b62e5 47 for (int i = 0; i < size; i++) serial.putc(buff[i]); // Send the message out
pspatel321 33:6bc82b6b62e5 48 success = true;
pspatel321 33:6bc82b6b62e5 49 }
pspatel321 33:6bc82b6b62e5 50
pspatel321 33:6bc82b6b62e5 51 // End thread-safe section
pspatel321 33:6bc82b6b62e5 52 __enable_irq();
pspatel321 33:6bc82b6b62e5 53
pspatel321 33:6bc82b6b62e5 54 return success;
pspatel321 33:6bc82b6b62e5 55 }
pspatel321 33:6bc82b6b62e5 56
pspatel321 33:6bc82b6b62e5 57 // 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 58 bool CANxbee::receive(CANMessage &msg) {
pspatel321 33:6bc82b6b62e5 59 int newChar = serial.getcNb();
pspatel321 33:6bc82b6b62e5 60 if (newChar == -1) return false; // No new char
pspatel321 33:6bc82b6b62e5 61 char c = newChar & 0xFF; // Cast to char
pspatel321 33:6bc82b6b62e5 62 bool process=false;
pspatel321 33:6bc82b6b62e5 63
pspatel321 33:6bc82b6b62e5 64 char len=0;
pspatel321 33:6bc82b6b62e5 65 // Listen for a 'C', start of new message
pspatel321 33:6bc82b6b62e5 66 if (c == 'C' && !building) {
pspatel321 33:6bc82b6b62e5 67 rxBuff[rx_i] = 'C';
pspatel321 33:6bc82b6b62e5 68 rx_i++;
pspatel321 33:6bc82b6b62e5 69 building = true; // Now building a string
pspatel321 33:6bc82b6b62e5 70 return false;
pspatel321 33:6bc82b6b62e5 71 }
pspatel321 33:6bc82b6b62e5 72 // Keep building a new message until too big or encounter '\n'
pspatel321 33:6bc82b6b62e5 73 if (building) {
pspatel321 33:6bc82b6b62e5 74 rxBuff[rx_i] = c;
pspatel321 33:6bc82b6b62e5 75 rx_i++;
pspatel321 33:6bc82b6b62e5 76 if (c == '\n') { // Newline! process this string
pspatel321 33:6bc82b6b62e5 77 process = true;
pspatel321 33:6bc82b6b62e5 78 building = false; // Reset to keep capturing on next call
pspatel321 33:6bc82b6b62e5 79 len = rx_i;
pspatel321 33:6bc82b6b62e5 80 rx_i = 0;
pspatel321 33:6bc82b6b62e5 81 }
pspatel321 33:6bc82b6b62e5 82 else if (rx_i >= sizeof(rxBuff)) { // Too big, bad string
pspatel321 33:6bc82b6b62e5 83 rx_i = 0;
pspatel321 33:6bc82b6b62e5 84 building = false;
pspatel321 33:6bc82b6b62e5 85 return false;
pspatel321 33:6bc82b6b62e5 86 }
pspatel321 33:6bc82b6b62e5 87 }
pspatel321 33:6bc82b6b62e5 88 if (!process) return false;
pspatel321 33:6bc82b6b62e5 89
pspatel321 33:6bc82b6b62e5 90 // A string is ready, process it here
pspatel321 33:6bc82b6b62e5 91 if (rxBuff[0] != 'C') return false; // No start char, not valid
pspatel321 33:6bc82b6b62e5 92
pspatel321 33:6bc82b6b62e5 93 // Extract the data from the header byte
pspatel321 33:6bc82b6b62e5 94 bool extended = rxBuff[1] & 1;
pspatel321 33:6bc82b6b62e5 95 bool rtr = rxBuff[1] & 2;
pspatel321 33:6bc82b6b62e5 96 char DLC = rxBuff[1] >> 2;
pspatel321 33:6bc82b6b62e5 97 int id=0;
pspatel321 33:6bc82b6b62e5 98 if (DLC > 8) return false; // Bad DLC
pspatel321 33:6bc82b6b62e5 99 if (!extended) { // Standard ID
pspatel321 33:6bc82b6b62e5 100 if (len > 12 || len < 5) return false; // Too big/too small for standard size
pspatel321 33:6bc82b6b62e5 101 if (rxBuff[3] & 0x7 != rxBuff[3]) return false; // Last byte of ID bad
pspatel321 33:6bc82b6b62e5 102 if (len != 5 + DLC) return false; // Improper number of bytes
pspatel321 33:6bc82b6b62e5 103 id = rxBuff[2] | (rxBuff[3] << 8); // Build the ID
pspatel321 33:6bc82b6b62e5 104 for (int i = 0; i < DLC; i++) msg.data[i] = rxBuff[i+4]; // Build the data array
pspatel321 33:6bc82b6b62e5 105
pspatel321 33:6bc82b6b62e5 106 } else { // Extended ID
pspatel321 33:6bc82b6b62e5 107 if (len > 14 || len < 7) return false; // Too big/too small for extended size
pspatel321 33:6bc82b6b62e5 108 if (rxBuff[5] & 0x1F != rxBuff[5]) return false; // Last byte of ID bad
pspatel321 33:6bc82b6b62e5 109 if (len != 7 + DLC) return false; // Improper number of bytes
pspatel321 33:6bc82b6b62e5 110 id = rxBuff[2] | (rxBuff[3] << 8) | (rxBuff[4] << 16) | (rxBuff[5] << 24); // Build the ID
pspatel321 33:6bc82b6b62e5 111 for (int i = 0; i < DLC; i++) msg.data[i] = rxBuff[i+6]; // Build the data array
pspatel321 33:6bc82b6b62e5 112 }
pspatel321 33:6bc82b6b62e5 113 msg.id = id;
pspatel321 33:6bc82b6b62e5 114 msg.len = DLC;
pspatel321 33:6bc82b6b62e5 115 if (rtr) msg.type = CANRemote;
pspatel321 33:6bc82b6b62e5 116 else msg.type = CANData;
pspatel321 33:6bc82b6b62e5 117 if (extended) msg.format = CANExtended;
pspatel321 33:6bc82b6b62e5 118 else msg.format = CANStandard;
pspatel321 33:6bc82b6b62e5 119 return true; // Successfully parsed, passed all checks, arguement was updated
pspatel321 33:6bc82b6b62e5 120 }