David Smart / CANMessage
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 #include "CANMessage.h"
00024 #include "Utilities.h"      // mbed <-> Visual Studio
00025 
00026 #include "FreeRunTimer.h"
00027 
00028 static FreeRunTimer timer;
00029 static bool timer_on;
00030 
00031 CANmsg::CANmsg() {
00032     if (!timer_on) {
00033         timer.start();
00034         timer_on = true;
00035     }
00036     timestamp = timer.read_us();
00037 }
00038 
00039 CANmsg::CANmsg(CANCHANNEL_T _ch, CANDIR_T _dir, CANMessage _msg) {
00040     if (!timer_on) {
00041         timer.start();
00042         timer_on = true;
00043     }
00044     timestamp = timer.read_us();
00045     ch = _ch;
00046     dir = _dir;
00047     id = _msg.id;
00048     len = _msg.len;
00049     for (int i=0; i<len; i++)
00050         data[i] = _msg.data[i];
00051     format = _msg.format;
00052     type = _msg.type;
00053 }
00054 
00055 //        0 1   2  3        4  5---------------------| 6   7 8
00056 //        t xtd 02 1CF00400 08 11 22 33 44 55 66 77 88 0   0 1234.567890
00057 //        If the first letter is not 't'ransmit or 'r'eceive, transmit is
00058 //          assumed
00059 //        xtd 02 1CF00400 08 11 22 33 44 55 66 77 88 0   0 1234.567890
00060 CANmsg::CANmsg(char *p) {
00061     if (!timer_on) {
00062         timer.start();
00063         timer_on = true;
00064     }
00065     ParseCANMessage(p);
00066 }
00067 
00068 CANmsg::~CANmsg() {
00069 }
00070 
00071 bool CANmsg::ParseCANMessage(char *p) {
00072     //int state = 0;
00073     //printf("\r\nParseCANMessage(%s)\r\n",p);
00074     char *token;
00075     char *search = " ,\t";  // any of these is a separator
00076     token = strtok(p, search);  // might now point to 't'|'r', or 'xtd'|'nrm'
00077     if (*token == 'r')
00078         dir = rcv;
00079     else
00080         dir = xmt;
00081     if (*token == 't' || *token == 'r') // transmit or receive
00082         token = strtok(NULL, search);    // advance past 't'|'r'
00083     if (mystrnicmp(token,"xtd",3) == 0)
00084         format = CANExtended;
00085     else if (mystrnicmp(token, "nrm", 3) == 0)
00086         format = CANStandard;
00087     token = strtok(NULL, search);
00088     ch = (CANCHANNEL_T)(atoi(token) - 1);
00089     token = strtok(NULL, search);
00090     id = hextoul(token);
00091     token = strtok(NULL, search);
00092     len = hextoul(token);
00093     for (int i=0; i<len; i++) {
00094         token = strtok(NULL, search);
00095         data[i] = (char)hextoul(token);
00096     }
00097     token = strtok(NULL, search);
00098     // fixedZero = atoi(token)
00099     token = strtok(NULL, search);
00100     // lostMessages = atoi(token);
00101     token = strtok(NULL, search);
00102     timestamp = timer.read_us();        // set it to "now"
00103     if (token)
00104         timestamp = (uint32_t)(1000000 * atof(token));
00105     return true;
00106 }
00107 
00108 void CANmsg::SetTimestamp() {
00109     timestamp = (uint32_t)timer.read_us();
00110 }
00111 
00112 // 12345678901234567890123456789012345678901234567890123456789012345
00113 // r xtd 01 1CF00400 08 11 22 33 44 55 66 77 88 0    0 0012.123456
00114 void CANmsg::FormatCANMessage(char *buffer, int buflen) {
00115     if (buflen >= 68) {    // 63+\r+\n+\0+2spare
00116         sprintf(buffer, "%c %s %02d %08X %02X ",
00117                 (dir == xmt ) ? 't' : 'r',
00118                 (format == CANExtended) ? "xtd" : "nrm",
00119                 ch + 1,
00120                 id,
00121                 len);
00122         for (int d=0; d<8; d++) {
00123             if (d < len)
00124                 sprintf(buffer + strlen(buffer), "%02X ", data[d]);
00125             else
00126                 strcat(buffer, "   ");
00127         }
00128         uint32_t uSec = timestamp % 1000000;    // integer math is faster than float
00129         uint32_t Sec = timestamp / 1000000;
00130         sprintf(buffer + strlen(buffer), "0   0 %04u.%06u", Sec, uSec);
00131     } else {
00132         strcpy(buffer,"ERROR, buf too small");
00133     }
00134 }