CANMessage is the primitive CAN message object. It supports creation, parsing, formatting of messages. Can be easily integrated with CANPort and CANQueue libraries.
Diff: CANMessage.cpp
- Revision:
- 0:f0ce97992c5f
- Child:
- 1:c56577ae52df
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CANMessage.cpp Sun Jul 15 15:15:18 2012 +0000 @@ -0,0 +1,134 @@ +/// @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"); + } +}