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@0:f0ce97992c5f, 2012-07-15 (annotated)
- Committer:
- WiredHome
- Date:
- Sun Jul 15 15:15:18 2012 +0000
- Revision:
- 0:f0ce97992c5f
- Child:
- 1:c56577ae52df
[mbed] converted /A_CANAdapter/CANUtilities/CANMessage
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
WiredHome | 0:f0ce97992c5f | 1 | /// @file CANMessage.h |
WiredHome | 0:f0ce97992c5f | 2 | /// This is the basic CAN message, and supports construction of, formatting and decoding. |
WiredHome | 0:f0ce97992c5f | 3 | /// |
WiredHome | 0:f0ce97992c5f | 4 | /// @version 1.0 |
WiredHome | 0:f0ce97992c5f | 5 | /// |
WiredHome | 0:f0ce97992c5f | 6 | /// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved. |
WiredHome | 0:f0ce97992c5f | 7 | /// Individuals may use this application for evaluation or non-commercial |
WiredHome | 0:f0ce97992c5f | 8 | /// purposes. Within this restriction, changes may be made to this application |
WiredHome | 0:f0ce97992c5f | 9 | /// as long as this copyright notice is retained. The user shall make |
WiredHome | 0:f0ce97992c5f | 10 | /// clear that their work is a derived work, and not the original. |
WiredHome | 0:f0ce97992c5f | 11 | /// Users of this application and sources accept this application "as is" and |
WiredHome | 0:f0ce97992c5f | 12 | /// shall hold harmless Smartware Computing, for any undesired results while |
WiredHome | 0:f0ce97992c5f | 13 | /// using this application - whether real or imagined. |
WiredHome | 0:f0ce97992c5f | 14 | /// |
WiredHome | 0:f0ce97992c5f | 15 | /// @author David Smart, Smartware Computing |
WiredHome | 0:f0ce97992c5f | 16 | /// |
WiredHome | 0:f0ce97992c5f | 17 | /// @note |
WiredHome | 0:f0ce97992c5f | 18 | /// Version History |
WiredHome | 0:f0ce97992c5f | 19 | /// 20110724 |
WiredHome | 0:f0ce97992c5f | 20 | /// \li Extending timestamp to 64 bits |
WiredHome | 0:f0ce97992c5f | 21 | /// |
WiredHome | 0:f0ce97992c5f | 22 | #include <mbed.h> |
WiredHome | 0:f0ce97992c5f | 23 | #include "CANMessage.h" |
WiredHome | 0:f0ce97992c5f | 24 | #include "Utilities.h" // mbed <-> Visual Studio |
WiredHome | 0:f0ce97992c5f | 25 | |
WiredHome | 0:f0ce97992c5f | 26 | #include "FreeRunTimer.h" |
WiredHome | 0:f0ce97992c5f | 27 | |
WiredHome | 0:f0ce97992c5f | 28 | static FreeRunTimer timer; |
WiredHome | 0:f0ce97992c5f | 29 | static bool timer_on; |
WiredHome | 0:f0ce97992c5f | 30 | |
WiredHome | 0:f0ce97992c5f | 31 | CANmsg::CANmsg() { |
WiredHome | 0:f0ce97992c5f | 32 | if (!timer_on) { |
WiredHome | 0:f0ce97992c5f | 33 | timer.start(); |
WiredHome | 0:f0ce97992c5f | 34 | timer_on = true; |
WiredHome | 0:f0ce97992c5f | 35 | } |
WiredHome | 0:f0ce97992c5f | 36 | timestamp = timer.read_us(); |
WiredHome | 0:f0ce97992c5f | 37 | } |
WiredHome | 0:f0ce97992c5f | 38 | |
WiredHome | 0:f0ce97992c5f | 39 | CANmsg::CANmsg(CANCHANNEL_T _ch, CANDIR_T _dir, CANMessage _msg) { |
WiredHome | 0:f0ce97992c5f | 40 | if (!timer_on) { |
WiredHome | 0:f0ce97992c5f | 41 | timer.start(); |
WiredHome | 0:f0ce97992c5f | 42 | timer_on = true; |
WiredHome | 0:f0ce97992c5f | 43 | } |
WiredHome | 0:f0ce97992c5f | 44 | timestamp = timer.read_us(); |
WiredHome | 0:f0ce97992c5f | 45 | ch = _ch; |
WiredHome | 0:f0ce97992c5f | 46 | dir = _dir; |
WiredHome | 0:f0ce97992c5f | 47 | id = _msg.id; |
WiredHome | 0:f0ce97992c5f | 48 | len = _msg.len; |
WiredHome | 0:f0ce97992c5f | 49 | for (int i=0; i<len; i++) |
WiredHome | 0:f0ce97992c5f | 50 | data[i] = _msg.data[i]; |
WiredHome | 0:f0ce97992c5f | 51 | format = _msg.format; |
WiredHome | 0:f0ce97992c5f | 52 | type = _msg.type; |
WiredHome | 0:f0ce97992c5f | 53 | } |
WiredHome | 0:f0ce97992c5f | 54 | |
WiredHome | 0:f0ce97992c5f | 55 | // 0 1 2 3 4 5---------------------| 6 7 8 |
WiredHome | 0:f0ce97992c5f | 56 | // t xtd 02 1CF00400 08 11 22 33 44 55 66 77 88 0 0 1234.567890 |
WiredHome | 0:f0ce97992c5f | 57 | // If the first letter is not 't'ransmit or 'r'eceive, transmit is |
WiredHome | 0:f0ce97992c5f | 58 | // assumed |
WiredHome | 0:f0ce97992c5f | 59 | // xtd 02 1CF00400 08 11 22 33 44 55 66 77 88 0 0 1234.567890 |
WiredHome | 0:f0ce97992c5f | 60 | CANmsg::CANmsg(char *p) { |
WiredHome | 0:f0ce97992c5f | 61 | if (!timer_on) { |
WiredHome | 0:f0ce97992c5f | 62 | timer.start(); |
WiredHome | 0:f0ce97992c5f | 63 | timer_on = true; |
WiredHome | 0:f0ce97992c5f | 64 | } |
WiredHome | 0:f0ce97992c5f | 65 | ParseCANMessage(p); |
WiredHome | 0:f0ce97992c5f | 66 | } |
WiredHome | 0:f0ce97992c5f | 67 | |
WiredHome | 0:f0ce97992c5f | 68 | CANmsg::~CANmsg() { |
WiredHome | 0:f0ce97992c5f | 69 | } |
WiredHome | 0:f0ce97992c5f | 70 | |
WiredHome | 0:f0ce97992c5f | 71 | bool CANmsg::ParseCANMessage(char *p) { |
WiredHome | 0:f0ce97992c5f | 72 | //int state = 0; |
WiredHome | 0:f0ce97992c5f | 73 | //printf("\r\nParseCANMessage(%s)\r\n",p); |
WiredHome | 0:f0ce97992c5f | 74 | char *token; |
WiredHome | 0:f0ce97992c5f | 75 | char *search = " ,\t"; // any of these is a separator |
WiredHome | 0:f0ce97992c5f | 76 | token = strtok(p, search); // might now point to 't'|'r', or 'xtd'|'nrm' |
WiredHome | 0:f0ce97992c5f | 77 | if (*token == 'r') |
WiredHome | 0:f0ce97992c5f | 78 | dir = rcv; |
WiredHome | 0:f0ce97992c5f | 79 | else |
WiredHome | 0:f0ce97992c5f | 80 | dir = xmt; |
WiredHome | 0:f0ce97992c5f | 81 | if (*token == 't' || *token == 'r') // transmit or receive |
WiredHome | 0:f0ce97992c5f | 82 | token = strtok(NULL, search); // advance past 't'|'r' |
WiredHome | 0:f0ce97992c5f | 83 | if (mystrnicmp(token,"xtd",3) == 0) |
WiredHome | 0:f0ce97992c5f | 84 | format = CANExtended; |
WiredHome | 0:f0ce97992c5f | 85 | else if (mystrnicmp(token, "nrm", 3) == 0) |
WiredHome | 0:f0ce97992c5f | 86 | format = CANStandard; |
WiredHome | 0:f0ce97992c5f | 87 | token = strtok(NULL, search); |
WiredHome | 0:f0ce97992c5f | 88 | ch = (CANCHANNEL_T)(atoi(token) - 1); |
WiredHome | 0:f0ce97992c5f | 89 | token = strtok(NULL, search); |
WiredHome | 0:f0ce97992c5f | 90 | id = hextoul(token); |
WiredHome | 0:f0ce97992c5f | 91 | token = strtok(NULL, search); |
WiredHome | 0:f0ce97992c5f | 92 | len = hextoul(token); |
WiredHome | 0:f0ce97992c5f | 93 | for (int i=0; i<len; i++) { |
WiredHome | 0:f0ce97992c5f | 94 | token = strtok(NULL, search); |
WiredHome | 0:f0ce97992c5f | 95 | data[i] = (char)hextoul(token); |
WiredHome | 0:f0ce97992c5f | 96 | } |
WiredHome | 0:f0ce97992c5f | 97 | token = strtok(NULL, search); |
WiredHome | 0:f0ce97992c5f | 98 | // fixedZero = atoi(token) |
WiredHome | 0:f0ce97992c5f | 99 | token = strtok(NULL, search); |
WiredHome | 0:f0ce97992c5f | 100 | // lostMessages = atoi(token); |
WiredHome | 0:f0ce97992c5f | 101 | token = strtok(NULL, search); |
WiredHome | 0:f0ce97992c5f | 102 | timestamp = timer.read_us(); // set it to "now" |
WiredHome | 0:f0ce97992c5f | 103 | if (token) |
WiredHome | 0:f0ce97992c5f | 104 | timestamp = (uint32_t)(1000000 * atof(token)); |
WiredHome | 0:f0ce97992c5f | 105 | return true; |
WiredHome | 0:f0ce97992c5f | 106 | } |
WiredHome | 0:f0ce97992c5f | 107 | |
WiredHome | 0:f0ce97992c5f | 108 | void CANmsg::SetTimestamp() { |
WiredHome | 0:f0ce97992c5f | 109 | timestamp = (uint32_t)timer.read_us(); |
WiredHome | 0:f0ce97992c5f | 110 | } |
WiredHome | 0:f0ce97992c5f | 111 | |
WiredHome | 0:f0ce97992c5f | 112 | // 12345678901234567890123456789012345678901234567890123456789012345 |
WiredHome | 0:f0ce97992c5f | 113 | // r xtd 01 1CF00400 08 11 22 33 44 55 66 77 88 0 0 0012.123456 |
WiredHome | 0:f0ce97992c5f | 114 | void CANmsg::FormatCANMessage(char *buffer, int buflen) { |
WiredHome | 0:f0ce97992c5f | 115 | if (buflen >= 68) { // 63+\r+\n+\0+2spare |
WiredHome | 0:f0ce97992c5f | 116 | sprintf(buffer, "%c %s %02d %08X %02X ", |
WiredHome | 0:f0ce97992c5f | 117 | (dir == xmt ) ? 't' : 'r', |
WiredHome | 0:f0ce97992c5f | 118 | (format == CANExtended) ? "xtd" : "nrm", |
WiredHome | 0:f0ce97992c5f | 119 | ch + 1, |
WiredHome | 0:f0ce97992c5f | 120 | id, |
WiredHome | 0:f0ce97992c5f | 121 | len); |
WiredHome | 0:f0ce97992c5f | 122 | for (int d=0; d<8; d++) { |
WiredHome | 0:f0ce97992c5f | 123 | if (d < len) |
WiredHome | 0:f0ce97992c5f | 124 | sprintf(buffer + strlen(buffer), "%02X ", data[d]); |
WiredHome | 0:f0ce97992c5f | 125 | else |
WiredHome | 0:f0ce97992c5f | 126 | strcat(buffer, " "); |
WiredHome | 0:f0ce97992c5f | 127 | } |
WiredHome | 0:f0ce97992c5f | 128 | uint32_t uSec = timestamp % 1000000; // integer math is faster than float |
WiredHome | 0:f0ce97992c5f | 129 | uint32_t Sec = timestamp / 1000000; |
WiredHome | 0:f0ce97992c5f | 130 | sprintf(buffer + strlen(buffer), "0 0 %04u.%06u", Sec, uSec); |
WiredHome | 0:f0ce97992c5f | 131 | } else { |
WiredHome | 0:f0ce97992c5f | 132 | strcpy(buffer,"ERROR, buf too small"); |
WiredHome | 0:f0ce97992c5f | 133 | } |
WiredHome | 0:f0ce97992c5f | 134 | } |