Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
CAN-xbee.cpp
00001 #include "CAN-xbee.h" 00002 00003 // Creates stringified version of CANMessage msg in char* buff (must be at least 15 chars) 00004 // Returns -1 for bad message, or else returns size of char* buff including the terminating '\n' 00005 int convert2array(CANMessage &msg, char* buff) { 00006 00007 // Check message integrity 00008 if (msg.len > 8) return -1; 00009 if ((msg.format == CANStandard) && ((msg.id & 0x7FF) != msg.id)) return -1; 00010 if ((msg.format == CANExtended) && ((msg.id & 0x1FFFFFFF) != msg.id)) return -1; 00011 00012 int i = 0; 00013 buff[i++] = 'C'; // Start of message 00014 buff[i++] = (msg.format << 0) | (msg.type << 1) | ((msg.len & 0xf) << 2); // Header byte, message info on ID size, RTR, # data bytes 00015 if (msg.format == CANStandard) { 00016 buff[i++] = (msg.id & 0x0FF); // Lower byte of ID 00017 buff[i++] = (msg.id & 0x700) >> 8; // Upper byte of ID 00018 } else { 00019 buff[i++] = (msg.id & 0x000000FF); // Lowest byte of ID 00020 buff[i++] = (msg.id & 0x0000FF00) >> 8; 00021 buff[i++] = (msg.id & 0x00FF0000) >> 16; 00022 buff[i++] = (msg.id & 0x1F000000) >> 24; // Highest byte of ID 00023 } 00024 for (int j = 0; j < msg.len; j++) { 00025 buff[i++] = msg.data[j]; 00026 } 00027 buff[i++] = '\n'; 00028 return i; 00029 } 00030 00031 bool convert2msg(CANMessage &msg, char* buff) { 00032 // Check for 'D' for done 00033 if (buff[0] != 'D') return -1; 00034 00035 bool extended = buff[1] & 1; 00036 bool rtr = buff[1] & 2; 00037 char DLC = buff[1] >> 2; 00038 if (DLC > 8) return false; // Bad length 00039 00040 // Standard frame, get id and data 00041 if (!extended) { 00042 if (buff[3] & 0x7 != buff[3]) return false; // Last byte of ID bad 00043 msg.id = buff[2] | (int)(buff[3] << 8); // Build the ID 00044 for (int i = 0; i < DLC; i++) msg.data[i] = buff[i+4]; // Build the data array 00045 00046 // Extended frame, get id and data 00047 } else { 00048 if (buff[5] & 0x1F != buff[5]) return false; // Last byte of ID bad 00049 msg.id = buff[2] | (buff[3] << 8) | (buff[4] << 16) | (buff[5] << 24); // Build the ID 00050 for (int i = 0; i < DLC; i++) msg.data[i] = buff[i+6]; // Build the data array 00051 } 00052 msg.len = DLC; 00053 if (rtr) msg.type = CANRemote; 00054 else msg.type = CANData; 00055 if (extended) msg.format = CANExtended; 00056 else msg.format = CANStandard; 00057 return true; // Successfully parsed, passed all checks, arguement was updated 00058 } 00059 00060 CANxbee::CANxbee(PinName tx, PinName rx, int _baud, int txSize, int rxSize) : serial(tx, rx, txSize, rxSize) { 00061 serial.baud(_baud); 00062 rx_i = 0; 00063 rxBuff[0] = 0; 00064 getChars = -1; 00065 } 00066 00067 // Send a CAN message, first reformat it into a char array, then send over Xbees 00068 bool CANxbee::send(CANMessage &msg, unsigned int* length) { 00069 char buff[15]; // Build the string-ified CAN message here 00070 int size = convert2array(msg, buff); 00071 *length = 0; 00072 if (size == -1) return false; // Bad message, string not formed 00073 00074 int bytesLeft = serial.txBufferGetSize(0) - serial.txBufferGetCount(); 00075 00076 if (bytesLeft >= size) { 00077 for (int i = 0; i < size; i++) serial.putc(buff[i]); // Send the message out 00078 *length = size; 00079 return true; 00080 } 00081 return false; 00082 } 00083 00084 // Continuously call this function in main program, when it returns true, it holds a newly received CAN message that came via Xbee 00085 bool CANxbee::receive(CANMessage &msg) { 00086 int newChar = serial.getcNb(); 00087 if (newChar == -1) return false; // No new char 00088 char c = newChar & 0xFF; // Cast to char 00089 00090 // Listen for a 'C', start of new message as long as not already building message 00091 if (c == 'C' && (rxBuff[0] != 'C')) { 00092 rx_i = 0; // Reset to start of message 00093 rxBuff[rx_i++] = 'C'; // Add the 'C', increment 00094 return false; 00095 } 00096 00097 // 'C' already found, now filling in contents of message 00098 if (rxBuff[0] == 'C') { 00099 if (getChars == -1) { // Get the header byte 00100 rxBuff[rx_i++] = c; // Add to string, increment 00101 bool extended = c & 1; // Is this an extended message? (4 ID bytes) 00102 char DLC = c >> 2; // How long is the data section? 00103 if (DLC > 8) { // Bad DLC, reset variables 00104 getChars = -1; 00105 rxBuff[0] = 0; 00106 rx_i = 0; 00107 return false; 00108 } 00109 getChars = DLC + extended?4:2; // Need to obtain getChars more characters to complete this message 00110 } else { // This is not a header byte, add to contents of message 00111 rxBuff[rx_i++] = c; 00112 getChars--; 00113 if (getChars <= 0) { // Just added the last char, done message, reset variables 00114 rxBuff[0] = 'D'; // Mark 'D' for done 00115 rx_i = 0; 00116 getChars = -1; 00117 } 00118 } 00119 } 00120 if (rxBuff[0] != 'D') return false; 00121 00122 // A string is ready, process it here 00123 if (convert2msg(msg, rxBuff)) return true; 00124 else return false; 00125 }
Generated on Fri Jul 15 2022 06:07:18 by
1.7.2
