CANMessage is the primitive CAN message object. It supports creation, parsing, formatting of messages. Can be easily integrated with CANPort and CANQueue libraries.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CANMessage.cpp Source File

CANMessage.cpp

00001 /// @file CANMessage.h
00002 /// This is the basic CAN message, and supports construction of, formatting and decoding.
00003 ///
00004 /// @version 1.0
00005 ///
00006 /// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved.
00007 ///     Individuals may use this application for evaluation or non-commercial
00008 ///     purposes. Within this restriction, changes may be made to this application
00009 ///     as long as this copyright notice is retained. The user shall make
00010 ///     clear that their work is a derived work, and not the original.
00011 ///     Users of this application and sources accept this application "as is" and
00012 ///     shall hold harmless Smartware Computing, for any undesired results while
00013 ///     using this application - whether real or imagined.
00014 ///
00015 /// @author David Smart, Smartware Computing
00016 ///
00017 /// @note
00018 /// Version History
00019 /// 20110724
00020 /// \li Extending timestamp to 64 bits
00021 ///
00022 #include <mbed.h>
00023 
00024 #include "CANMessage.h"
00025 #include "Utilities.h"      // missing functions...
00026 
00027 static Timer timer;
00028 static bool timer_on;
00029 
00030 static char mytolower(char a) {
00031     if (a >= 'A' && a <= 'Z')
00032         return (a - 'A' + 'a');
00033     else
00034         return a;
00035 }
00036 
00037 static int mystrnicmp(const char *l, const char *r, size_t n) {
00038     int result = 0;
00039 
00040     if (n != 0) {
00041         do {
00042             result = mytolower(*l++) - mytolower(*r++);
00043         } while ((result == 0) && (*l != '\0') && (--n > 0));
00044     }
00045     if (result < -1)
00046         result = -1;
00047     else if (result > 1)
00048         result = 1;
00049     return result;
00050 }
00051 
00052 CANmsg::CANmsg() {
00053     if (!timer_on) {
00054         timer.start();
00055         timer_on = true;
00056     }
00057     timestamp = (uint32_t)timer.read_us(); // read_high_resolution_us();
00058 }
00059 
00060 CANmsg::CANmsg(CANCHANNEL_T _ch, CANDIR_T _dir, CANMessage _msg) {
00061     if (!timer_on) {
00062         timer.start();
00063         timer_on = true;
00064     }
00065     timestamp = (uint32_t)timer.read_us(); // read_high_resolution_us();
00066     ch = _ch;
00067     dir = _dir;
00068     id = _msg.id;
00069     len = _msg.len;
00070     for (int i=0; i<len; i++)
00071         data[i] = _msg.data[i];
00072     format = _msg.format;
00073     type = _msg.type;
00074 }
00075 
00076 //        0 1   2  3        4  5---------------------| 6   7 8
00077 //        t xtd 02 1CF00400 08 11 22 33 44 55 66 77 88 0   0 1234.567890
00078 //        If the first letter is not 't'ransmit or 'r'eceive, transmit is
00079 //          assumed
00080 //        xtd 02 1CF00400 08 11 22 33 44 55 66 77 88 0   0 1234.567890
00081 CANmsg::CANmsg(char *p) {
00082     if (!timer_on) {
00083         timer.start();
00084         timer_on = true;
00085     }
00086     ParseCANMessage(p);
00087 }
00088 
00089 CANmsg::~CANmsg() {
00090 }
00091 
00092 bool CANmsg::ParseCANMessage(char *p) {
00093     //int state = 0;
00094     //printf("\r\nParseCANMessage(%s)\r\n",p);
00095     char *token;
00096     char *search = " ,\t";  // any of these is a separator
00097     token = strtok(p, search);  // might now point to 't'|'r', or 'xtd'|'nrm'
00098     if (*token == 'r')
00099         dir = rcv;
00100     else
00101         dir = xmt;
00102     if (*token == 't' || *token == 'r') // transmit or receive
00103         token = strtok(NULL, search);    // advance past 't'|'r'
00104     if (mystrnicmp(token,"xtd",3) == 0)
00105         format = CANExtended;
00106     else if (mystrnicmp(token, "nrm", 3) == 0)
00107         format = CANStandard;
00108     token = strtok(NULL, search);
00109     ch = (CANCHANNEL_T)(atoi(token) - 1);
00110     token = strtok(NULL, search);
00111     id = hextoul(token);
00112     token = strtok(NULL, search);
00113     len = hextoul(token);
00114     for (int i=0; i<len; i++) {
00115         token = strtok(NULL, search);
00116         data[i] = (char)hextoul(token);
00117     }
00118     token = strtok(NULL, search);
00119     // fixedZero = atoi(token)
00120     token = strtok(NULL, search);
00121     // lostMessages = atoi(token);
00122     token = strtok(NULL, search);
00123     timestamp = (uint32_t)timer.read_us(); // read_high_resolution_us();        // set it to "now"
00124     if (token)
00125         timestamp = (uint32_t)(1000000 * atof(token));
00126     return true;
00127 }
00128 
00129 void CANmsg::SetTimestamp() {
00130     timestamp = (uint32_t)timer.read_us(); // read_high_resolution_us();
00131 }
00132 
00133 // 12345678901234567890123456789012345678901234567890123456789012345
00134 // r xtd 01 1CF00400 08 11 22 33 44 55 66 77 88 0    0     12.123456
00135 void CANmsg::FormatCANMessage(char *buffer, int buflen) {
00136     if (buflen >= 68) {    // 63+\r+\n+\0+2spare
00137         if (format >= 128) {
00138             sprintf(buffer, "%c %s %02d %8s %02X ",
00139                     (dir == xmt ) ? 't' : 'r',
00140                     "ERR",
00141                     ch + 1,
00142                     (format == 128) ? "active" : "passive",
00143                     8);
00144             for (int d=0; d<8; d++) {
00145                 sprintf(buffer + strlen(buffer), "%02X ", 0);
00146             }
00147         } else {
00148             sprintf(buffer, "%c %s %02d %08X %02X ",
00149                     (dir == xmt ) ? 't' : 'r',
00150                     (format == CANExtended) ? "xtd" : "nrm",
00151                     ch + 1,
00152                     id,
00153                     len);
00154             for (int d=0; d<8; d++) {
00155                 if (d < len)
00156                     sprintf(buffer + strlen(buffer), "%02X ", data[d]);
00157                 else
00158                     strcat(buffer, "   ");
00159             }
00160         }
00161         uint32_t uSec = timestamp % 1000000;    // integer math is faster than float
00162         uint32_t Sec = timestamp / 1000000;
00163         sprintf(buffer + strlen(buffer), "0   0 %6u.%06u", Sec, uSec);
00164     } else {
00165         strcpy(buffer,"ERROR, buf too small");
00166     }
00167 }