CANMessage is the primitive CAN message object. It supports creation, parsing, formatting of messages. Can be easily integrated with CANPort and CANQueue libraries.
CANMessage.cpp
- Committer:
- WiredHome
- Date:
- 2012-07-15
- Revision:
- 0:f0ce97992c5f
File content as of revision 0:f0ce97992c5f:
/// @file CANMessage.h /// This is the basic CAN message, and supports construction of, formatting and decoding. /// /// @version 1.0 /// /// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved. /// Individuals may use this application for evaluation or non-commercial /// purposes. Within this restriction, changes may be made to this application /// as long as this copyright notice is retained. The user shall make /// clear that their work is a derived work, and not the original. /// Users of this application and sources accept this application "as is" and /// shall hold harmless Smartware Computing, for any undesired results while /// using this application - whether real or imagined. /// /// @author David Smart, Smartware Computing /// /// @note /// Version History /// 20110724 /// \li Extending timestamp to 64 bits /// #include <mbed.h> #include "CANMessage.h" #include "Utilities.h" // mbed <-> Visual Studio #include "FreeRunTimer.h" static FreeRunTimer timer; static bool timer_on; CANmsg::CANmsg() { if (!timer_on) { timer.start(); timer_on = true; } timestamp = timer.read_us(); } CANmsg::CANmsg(CANCHANNEL_T _ch, CANDIR_T _dir, CANMessage _msg) { if (!timer_on) { timer.start(); timer_on = true; } timestamp = timer.read_us(); ch = _ch; dir = _dir; id = _msg.id; len = _msg.len; for (int i=0; i<len; i++) data[i] = _msg.data[i]; format = _msg.format; type = _msg.type; } // 0 1 2 3 4 5---------------------| 6 7 8 // t xtd 02 1CF00400 08 11 22 33 44 55 66 77 88 0 0 1234.567890 // If the first letter is not 't'ransmit or 'r'eceive, transmit is // assumed // xtd 02 1CF00400 08 11 22 33 44 55 66 77 88 0 0 1234.567890 CANmsg::CANmsg(char *p) { if (!timer_on) { timer.start(); timer_on = true; } ParseCANMessage(p); } CANmsg::~CANmsg() { } bool CANmsg::ParseCANMessage(char *p) { //int state = 0; //printf("\r\nParseCANMessage(%s)\r\n",p); char *token; char *search = " ,\t"; // any of these is a separator token = strtok(p, search); // might now point to 't'|'r', or 'xtd'|'nrm' if (*token == 'r') dir = rcv; else dir = xmt; if (*token == 't' || *token == 'r') // transmit or receive token = strtok(NULL, search); // advance past 't'|'r' if (mystrnicmp(token,"xtd",3) == 0) format = CANExtended; else if (mystrnicmp(token, "nrm", 3) == 0) format = CANStandard; token = strtok(NULL, search); ch = (CANCHANNEL_T)(atoi(token) - 1); token = strtok(NULL, search); id = hextoul(token); token = strtok(NULL, search); len = hextoul(token); for (int i=0; i<len; i++) { token = strtok(NULL, search); data[i] = (char)hextoul(token); } token = strtok(NULL, search); // fixedZero = atoi(token) token = strtok(NULL, search); // lostMessages = atoi(token); token = strtok(NULL, search); timestamp = timer.read_us(); // set it to "now" if (token) timestamp = (uint32_t)(1000000 * atof(token)); return true; } void CANmsg::SetTimestamp() { timestamp = (uint32_t)timer.read_us(); } // 12345678901234567890123456789012345678901234567890123456789012345 // r xtd 01 1CF00400 08 11 22 33 44 55 66 77 88 0 0 0012.123456 void CANmsg::FormatCANMessage(char *buffer, int buflen) { if (buflen >= 68) { // 63+\r+\n+\0+2spare sprintf(buffer, "%c %s %02d %08X %02X ", (dir == xmt ) ? 't' : 'r', (format == CANExtended) ? "xtd" : "nrm", ch + 1, id, len); for (int d=0; d<8; d++) { if (d < len) sprintf(buffer + strlen(buffer), "%02X ", data[d]); else strcat(buffer, " "); } uint32_t uSec = timestamp % 1000000; // integer math is faster than float uint32_t Sec = timestamp / 1000000; sprintf(buffer + strlen(buffer), "0 0 %04u.%06u", Sec, uSec); } else { strcpy(buffer,"ERROR, buf too small"); } }