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

Committer:
WiredHome
Date:
Wed Aug 28 22:02:43 2019 +0000
Revision:
1:c56577ae52df
Parent:
0:f0ce97992c5f
Child:
2:4307b498b508
Minor updates based on mbed version.

Who changed what in which revision?

UserRevisionLine numberNew 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 1:c56577ae52df 23
WiredHome 0:f0ce97992c5f 24 #include "CANMessage.h"
WiredHome 1:c56577ae52df 25 #include "Utilities.h" // missing functions...
WiredHome 1:c56577ae52df 26
WiredHome 1:c56577ae52df 27 //#include "FreeRunTimer.h"
WiredHome 1:c56577ae52df 28
WiredHome 1:c56577ae52df 29 static Timer timer;
WiredHome 1:c56577ae52df 30 static bool timer_on;
WiredHome 0:f0ce97992c5f 31
WiredHome 1:c56577ae52df 32 static char mytolower(char a) {
WiredHome 1:c56577ae52df 33 if (a >= 'A' && a <= 'Z')
WiredHome 1:c56577ae52df 34 return (a - 'A' + 'a');
WiredHome 1:c56577ae52df 35 else
WiredHome 1:c56577ae52df 36 return a;
WiredHome 1:c56577ae52df 37 }
WiredHome 1:c56577ae52df 38
WiredHome 1:c56577ae52df 39 static int mystrnicmp(const char *l, const char *r, size_t n) {
WiredHome 1:c56577ae52df 40 int result = 0;
WiredHome 0:f0ce97992c5f 41
WiredHome 1:c56577ae52df 42 if (n != 0) {
WiredHome 1:c56577ae52df 43 do {
WiredHome 1:c56577ae52df 44 result = mytolower(*l++) - mytolower(*r++);
WiredHome 1:c56577ae52df 45 } while ((result == 0) && (*l != '\0') && (--n > 0));
WiredHome 1:c56577ae52df 46 }
WiredHome 1:c56577ae52df 47 if (result < -1)
WiredHome 1:c56577ae52df 48 result = -1;
WiredHome 1:c56577ae52df 49 else if (result > 1)
WiredHome 1:c56577ae52df 50 result = 1;
WiredHome 1:c56577ae52df 51 return result;
WiredHome 1:c56577ae52df 52 }
WiredHome 0:f0ce97992c5f 53
WiredHome 0:f0ce97992c5f 54 CANmsg::CANmsg() {
WiredHome 0:f0ce97992c5f 55 if (!timer_on) {
WiredHome 0:f0ce97992c5f 56 timer.start();
WiredHome 0:f0ce97992c5f 57 timer_on = true;
WiredHome 0:f0ce97992c5f 58 }
WiredHome 0:f0ce97992c5f 59 timestamp = timer.read_us();
WiredHome 0:f0ce97992c5f 60 }
WiredHome 0:f0ce97992c5f 61
WiredHome 0:f0ce97992c5f 62 CANmsg::CANmsg(CANCHANNEL_T _ch, CANDIR_T _dir, CANMessage _msg) {
WiredHome 0:f0ce97992c5f 63 if (!timer_on) {
WiredHome 0:f0ce97992c5f 64 timer.start();
WiredHome 0:f0ce97992c5f 65 timer_on = true;
WiredHome 0:f0ce97992c5f 66 }
WiredHome 0:f0ce97992c5f 67 timestamp = timer.read_us();
WiredHome 0:f0ce97992c5f 68 ch = _ch;
WiredHome 0:f0ce97992c5f 69 dir = _dir;
WiredHome 0:f0ce97992c5f 70 id = _msg.id;
WiredHome 0:f0ce97992c5f 71 len = _msg.len;
WiredHome 0:f0ce97992c5f 72 for (int i=0; i<len; i++)
WiredHome 0:f0ce97992c5f 73 data[i] = _msg.data[i];
WiredHome 0:f0ce97992c5f 74 format = _msg.format;
WiredHome 0:f0ce97992c5f 75 type = _msg.type;
WiredHome 0:f0ce97992c5f 76 }
WiredHome 0:f0ce97992c5f 77
WiredHome 0:f0ce97992c5f 78 // 0 1 2 3 4 5---------------------| 6 7 8
WiredHome 0:f0ce97992c5f 79 // t xtd 02 1CF00400 08 11 22 33 44 55 66 77 88 0 0 1234.567890
WiredHome 0:f0ce97992c5f 80 // If the first letter is not 't'ransmit or 'r'eceive, transmit is
WiredHome 0:f0ce97992c5f 81 // assumed
WiredHome 0:f0ce97992c5f 82 // xtd 02 1CF00400 08 11 22 33 44 55 66 77 88 0 0 1234.567890
WiredHome 0:f0ce97992c5f 83 CANmsg::CANmsg(char *p) {
WiredHome 0:f0ce97992c5f 84 if (!timer_on) {
WiredHome 0:f0ce97992c5f 85 timer.start();
WiredHome 0:f0ce97992c5f 86 timer_on = true;
WiredHome 0:f0ce97992c5f 87 }
WiredHome 0:f0ce97992c5f 88 ParseCANMessage(p);
WiredHome 0:f0ce97992c5f 89 }
WiredHome 0:f0ce97992c5f 90
WiredHome 0:f0ce97992c5f 91 CANmsg::~CANmsg() {
WiredHome 0:f0ce97992c5f 92 }
WiredHome 0:f0ce97992c5f 93
WiredHome 0:f0ce97992c5f 94 bool CANmsg::ParseCANMessage(char *p) {
WiredHome 0:f0ce97992c5f 95 //int state = 0;
WiredHome 0:f0ce97992c5f 96 //printf("\r\nParseCANMessage(%s)\r\n",p);
WiredHome 0:f0ce97992c5f 97 char *token;
WiredHome 0:f0ce97992c5f 98 char *search = " ,\t"; // any of these is a separator
WiredHome 0:f0ce97992c5f 99 token = strtok(p, search); // might now point to 't'|'r', or 'xtd'|'nrm'
WiredHome 0:f0ce97992c5f 100 if (*token == 'r')
WiredHome 0:f0ce97992c5f 101 dir = rcv;
WiredHome 0:f0ce97992c5f 102 else
WiredHome 0:f0ce97992c5f 103 dir = xmt;
WiredHome 0:f0ce97992c5f 104 if (*token == 't' || *token == 'r') // transmit or receive
WiredHome 0:f0ce97992c5f 105 token = strtok(NULL, search); // advance past 't'|'r'
WiredHome 0:f0ce97992c5f 106 if (mystrnicmp(token,"xtd",3) == 0)
WiredHome 0:f0ce97992c5f 107 format = CANExtended;
WiredHome 0:f0ce97992c5f 108 else if (mystrnicmp(token, "nrm", 3) == 0)
WiredHome 0:f0ce97992c5f 109 format = CANStandard;
WiredHome 0:f0ce97992c5f 110 token = strtok(NULL, search);
WiredHome 0:f0ce97992c5f 111 ch = (CANCHANNEL_T)(atoi(token) - 1);
WiredHome 0:f0ce97992c5f 112 token = strtok(NULL, search);
WiredHome 0:f0ce97992c5f 113 id = hextoul(token);
WiredHome 0:f0ce97992c5f 114 token = strtok(NULL, search);
WiredHome 0:f0ce97992c5f 115 len = hextoul(token);
WiredHome 0:f0ce97992c5f 116 for (int i=0; i<len; i++) {
WiredHome 0:f0ce97992c5f 117 token = strtok(NULL, search);
WiredHome 0:f0ce97992c5f 118 data[i] = (char)hextoul(token);
WiredHome 0:f0ce97992c5f 119 }
WiredHome 0:f0ce97992c5f 120 token = strtok(NULL, search);
WiredHome 0:f0ce97992c5f 121 // fixedZero = atoi(token)
WiredHome 0:f0ce97992c5f 122 token = strtok(NULL, search);
WiredHome 0:f0ce97992c5f 123 // lostMessages = atoi(token);
WiredHome 0:f0ce97992c5f 124 token = strtok(NULL, search);
WiredHome 0:f0ce97992c5f 125 timestamp = timer.read_us(); // set it to "now"
WiredHome 0:f0ce97992c5f 126 if (token)
WiredHome 0:f0ce97992c5f 127 timestamp = (uint32_t)(1000000 * atof(token));
WiredHome 0:f0ce97992c5f 128 return true;
WiredHome 0:f0ce97992c5f 129 }
WiredHome 0:f0ce97992c5f 130
WiredHome 0:f0ce97992c5f 131 void CANmsg::SetTimestamp() {
WiredHome 0:f0ce97992c5f 132 timestamp = (uint32_t)timer.read_us();
WiredHome 0:f0ce97992c5f 133 }
WiredHome 0:f0ce97992c5f 134
WiredHome 0:f0ce97992c5f 135 // 12345678901234567890123456789012345678901234567890123456789012345
WiredHome 1:c56577ae52df 136 // r xtd 01 1CF00400 08 11 22 33 44 55 66 77 88 0 0 12.123456
WiredHome 0:f0ce97992c5f 137 void CANmsg::FormatCANMessage(char *buffer, int buflen) {
WiredHome 0:f0ce97992c5f 138 if (buflen >= 68) { // 63+\r+\n+\0+2spare
WiredHome 0:f0ce97992c5f 139 sprintf(buffer, "%c %s %02d %08X %02X ",
WiredHome 0:f0ce97992c5f 140 (dir == xmt ) ? 't' : 'r',
WiredHome 0:f0ce97992c5f 141 (format == CANExtended) ? "xtd" : "nrm",
WiredHome 0:f0ce97992c5f 142 ch + 1,
WiredHome 0:f0ce97992c5f 143 id,
WiredHome 0:f0ce97992c5f 144 len);
WiredHome 0:f0ce97992c5f 145 for (int d=0; d<8; d++) {
WiredHome 0:f0ce97992c5f 146 if (d < len)
WiredHome 0:f0ce97992c5f 147 sprintf(buffer + strlen(buffer), "%02X ", data[d]);
WiredHome 0:f0ce97992c5f 148 else
WiredHome 0:f0ce97992c5f 149 strcat(buffer, " ");
WiredHome 0:f0ce97992c5f 150 }
WiredHome 0:f0ce97992c5f 151 uint32_t uSec = timestamp % 1000000; // integer math is faster than float
WiredHome 0:f0ce97992c5f 152 uint32_t Sec = timestamp / 1000000;
WiredHome 1:c56577ae52df 153 sprintf(buffer + strlen(buffer), "0 0 %6u.%06u", Sec, uSec);
WiredHome 0:f0ce97992c5f 154 } else {
WiredHome 0:f0ce97992c5f 155 strcpy(buffer,"ERROR, buf too small");
WiredHome 0:f0ce97992c5f 156 }
WiredHome 0:f0ce97992c5f 157 }