CANPort provides a higher level interface to a CAN communication channel, and provides timestamping, servicing additional hardware interfaces (optional activity LED, CAN transceiver slope control)

Committer:
WiredHome
Date:
Wed Aug 28 22:02:49 2019 +0000
Revision:
1:f0b4e47d948d
Parent:
0:7b81b19d9b10
Child:
3:4c780c641125
Minor updates based on mbed version.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 0:7b81b19d9b10 1 /// @file CANPort.cpp is where all the port level functionality resides
WiredHome 0:7b81b19d9b10 2 ///
WiredHome 0:7b81b19d9b10 3 /// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved.
WiredHome 0:7b81b19d9b10 4 /// Individuals may use this application for evaluation or non-commercial
WiredHome 0:7b81b19d9b10 5 /// purposes. Within this restriction, changes may be made to this application
WiredHome 0:7b81b19d9b10 6 /// as long as this copyright notice is retained. The user shall make
WiredHome 0:7b81b19d9b10 7 /// clear that their work is a derived work, and not the original.
WiredHome 0:7b81b19d9b10 8 /// Users of this application and sources accept this application "as is" and
WiredHome 0:7b81b19d9b10 9 /// shall hold harmless Smartware Computing, for any undesired results while
WiredHome 0:7b81b19d9b10 10 /// using this application - whether real or imagined.
WiredHome 0:7b81b19d9b10 11 ///
WiredHome 0:7b81b19d9b10 12 /// @author David Smart, Smartware Computing
WiredHome 0:7b81b19d9b10 13 ///
WiredHome 0:7b81b19d9b10 14 /// 20110718
WiredHome 0:7b81b19d9b10 15 /// Fixed a bug in the Receive handler - it was not propagating the message
WiredHome 0:7b81b19d9b10 16 /// out.
WiredHome 0:7b81b19d9b10 17 /// 20110605
WiredHome 0:7b81b19d9b10 18 /// Revised the SlopeControl so that it actually works for any change in value
WiredHome 0:7b81b19d9b10 19 /// where it was previously able to go low or high, but once as an input it
WiredHome 0:7b81b19d9b10 20 /// then would not go back to an output.
WiredHome 0:7b81b19d9b10 21 ///
WiredHome 0:7b81b19d9b10 22 #include "mbed.h"
WiredHome 0:7b81b19d9b10 23 #include "CANPort.h"
WiredHome 0:7b81b19d9b10 24 #include "Utilities.h"
WiredHome 0:7b81b19d9b10 25
WiredHome 0:7b81b19d9b10 26 #define FLASH_PERIOD (float)0.04
WiredHome 0:7b81b19d9b10 27 #define FLASH_TX_LEVEL 0.10
WiredHome 0:7b81b19d9b10 28 #define FLASH_RX_LEVEL 1.00
WiredHome 0:7b81b19d9b10 29
WiredHome 0:7b81b19d9b10 30
WiredHome 0:7b81b19d9b10 31 CANPort::CANPort(CANCHANNEL_T chNum, PinName rd, PinName td, PinName _activityPin, PinName _slopePin, CANSlopeControl_T slope) {
WiredHome 0:7b81b19d9b10 32 channel = chNum;
WiredHome 0:7b81b19d9b10 33 can = new CAN(rd, td);
WiredHome 0:7b81b19d9b10 34 if (_activityPin != NC) {
WiredHome 0:7b81b19d9b10 35 activityPin = new PwmOut(_activityPin);
WiredHome 0:7b81b19d9b10 36 activityPin->pulsewidth_us(100);
WiredHome 0:7b81b19d9b10 37 }
WiredHome 0:7b81b19d9b10 38 else
WiredHome 0:7b81b19d9b10 39 activityPin = NULL;
WiredHome 0:7b81b19d9b10 40 if (_slopePin != NC) {
WiredHome 0:7b81b19d9b10 41 slopePin = new DigitalInOut(_slopePin);
WiredHome 0:7b81b19d9b10 42 SetSlopeControl(slope);
WiredHome 0:7b81b19d9b10 43 } else
WiredHome 0:7b81b19d9b10 44 slopePin = NULL;
WiredHome 0:7b81b19d9b10 45 slopePinName = _slopePin;
WiredHome 0:7b81b19d9b10 46 txCounter = 0;
WiredHome 0:7b81b19d9b10 47 rxCounter = 0;
WiredHome 0:7b81b19d9b10 48 }
WiredHome 0:7b81b19d9b10 49
WiredHome 0:7b81b19d9b10 50
WiredHome 0:7b81b19d9b10 51 CANPort::~CANPort() {
WiredHome 0:7b81b19d9b10 52 if (slopePin)
WiredHome 0:7b81b19d9b10 53 delete slopePin;
WiredHome 0:7b81b19d9b10 54 if (activityPin)
WiredHome 0:7b81b19d9b10 55 delete activityPin;
WiredHome 0:7b81b19d9b10 56 if (can)
WiredHome 0:7b81b19d9b10 57 delete can;
WiredHome 0:7b81b19d9b10 58 slopePin = NULL;
WiredHome 0:7b81b19d9b10 59 activityPin = NULL;
WiredHome 0:7b81b19d9b10 60 can = NULL;
WiredHome 0:7b81b19d9b10 61 }
WiredHome 0:7b81b19d9b10 62
WiredHome 0:7b81b19d9b10 63
WiredHome 0:7b81b19d9b10 64 bool CANPort::TransmitMsg(CANmsg msg) {
WiredHome 0:7b81b19d9b10 65 bool success = false;
WiredHome 0:7b81b19d9b10 66
WiredHome 0:7b81b19d9b10 67 if (msg.dir == xmt) { // we have to have indicated our intent to transmit
WiredHome 0:7b81b19d9b10 68 msg.ch = channel;
WiredHome 0:7b81b19d9b10 69 if (can->write(CANMessage(msg.id, (char *)&msg.data, msg.len, CANData, msg.format))) {
WiredHome 0:7b81b19d9b10 70 txCounter++;
WiredHome 0:7b81b19d9b10 71 Flash(msg.dir);
WiredHome 0:7b81b19d9b10 72 success = true;
WiredHome 0:7b81b19d9b10 73 }
WiredHome 0:7b81b19d9b10 74 }
WiredHome 0:7b81b19d9b10 75 return success;
WiredHome 0:7b81b19d9b10 76 }
WiredHome 0:7b81b19d9b10 77
WiredHome 0:7b81b19d9b10 78
WiredHome 0:7b81b19d9b10 79 bool CANPort::ReceiveMsg(CANmsg &msg) {
WiredHome 0:7b81b19d9b10 80 bool success = false;
WiredHome 0:7b81b19d9b10 81 CANMessage _msg;
WiredHome 0:7b81b19d9b10 82
WiredHome 0:7b81b19d9b10 83 if (can->read(_msg)) {
WiredHome 0:7b81b19d9b10 84 /// @TODO This looks like a very inefficient method, but it works.
WiredHome 0:7b81b19d9b10 85 CANmsg Xmsg(channel, rcv, _msg);
WiredHome 0:7b81b19d9b10 86 msg = Xmsg;
WiredHome 0:7b81b19d9b10 87 rxCounter++;
WiredHome 0:7b81b19d9b10 88 Flash(msg.dir);
WiredHome 0:7b81b19d9b10 89 success = true;
WiredHome 0:7b81b19d9b10 90 }
WiredHome 0:7b81b19d9b10 91 return success;
WiredHome 0:7b81b19d9b10 92 }
WiredHome 0:7b81b19d9b10 93
WiredHome 0:7b81b19d9b10 94
WiredHome 0:7b81b19d9b10 95 void CANPort::Attach( void (*fptr)(void)) {
WiredHome 0:7b81b19d9b10 96 can->attach(fptr);
WiredHome 0:7b81b19d9b10 97 }
WiredHome 0:7b81b19d9b10 98
WiredHome 0:7b81b19d9b10 99
WiredHome 0:7b81b19d9b10 100 void CANPort::Extinguish(void) {
WiredHome 0:7b81b19d9b10 101 if (activityPin) {
WiredHome 0:7b81b19d9b10 102 *activityPin = 0.0;
WiredHome 0:7b81b19d9b10 103 }
WiredHome 0:7b81b19d9b10 104 }
WiredHome 0:7b81b19d9b10 105
WiredHome 0:7b81b19d9b10 106
WiredHome 0:7b81b19d9b10 107 void CANPort::Flash(CANDIR_T tx) {
WiredHome 0:7b81b19d9b10 108 if (activityPin) {
WiredHome 0:7b81b19d9b10 109 *activityPin = (tx == xmt) ? FLASH_TX_LEVEL : FLASH_RX_LEVEL; // dim for transmit, bright for receive
WiredHome 1:f0b4e47d948d 110 #if (MBED_MAJOR_VERSION >= 5) || (MBED_LIBRARY_VERSION > 127)
WiredHome 1:f0b4e47d948d 111 activityTimeout.attach(callback(this, &CANPort::Extinguish), FLASH_PERIOD);
WiredHome 1:f0b4e47d948d 112 #else
WiredHome 0:7b81b19d9b10 113 activityTimeout.attach(this, &CANPort::Extinguish, FLASH_PERIOD);
WiredHome 1:f0b4e47d948d 114 #endif
WiredHome 0:7b81b19d9b10 115 }
WiredHome 0:7b81b19d9b10 116 }
WiredHome 0:7b81b19d9b10 117
WiredHome 0:7b81b19d9b10 118
WiredHome 0:7b81b19d9b10 119 bool CANPort::SetAutoReset(bool enable) {
WiredHome 0:7b81b19d9b10 120 autoReset = enable;
WiredHome 0:7b81b19d9b10 121 return true;
WiredHome 0:7b81b19d9b10 122 }
WiredHome 0:7b81b19d9b10 123
WiredHome 0:7b81b19d9b10 124
WiredHome 0:7b81b19d9b10 125 bool CANPort::SetBusMode(CANBusMode_T mode) {
WiredHome 0:7b81b19d9b10 126 switch (mode) {
WiredHome 0:7b81b19d9b10 127 case MONITOR:
WiredHome 0:7b81b19d9b10 128 can->monitor(true);
WiredHome 0:7b81b19d9b10 129 busMode = mode;
WiredHome 0:7b81b19d9b10 130 break;
WiredHome 0:7b81b19d9b10 131 case ACTIVE:
WiredHome 0:7b81b19d9b10 132 can->monitor(false);
WiredHome 0:7b81b19d9b10 133 busMode = mode;
WiredHome 0:7b81b19d9b10 134 break;
WiredHome 0:7b81b19d9b10 135 default:
WiredHome 0:7b81b19d9b10 136 return false;
WiredHome 0:7b81b19d9b10 137 }
WiredHome 0:7b81b19d9b10 138 return true;
WiredHome 0:7b81b19d9b10 139 }
WiredHome 0:7b81b19d9b10 140
WiredHome 0:7b81b19d9b10 141
WiredHome 0:7b81b19d9b10 142 CANBusMode_T CANPort::GetBusMode() {
WiredHome 0:7b81b19d9b10 143 return busMode;
WiredHome 0:7b81b19d9b10 144 }
WiredHome 0:7b81b19d9b10 145
WiredHome 0:7b81b19d9b10 146
WiredHome 0:7b81b19d9b10 147 bool CANPort::SetSlopeControl(CANSlopeControl_T slope) {
WiredHome 0:7b81b19d9b10 148 if (slopePin) {
WiredHome 0:7b81b19d9b10 149 slopeMode = slope;
WiredHome 0:7b81b19d9b10 150 switch (slope) {
WiredHome 0:7b81b19d9b10 151 case HIGHSPEED:
WiredHome 0:7b81b19d9b10 152 slopePin->output();
WiredHome 0:7b81b19d9b10 153 slopePin->write(0);
WiredHome 0:7b81b19d9b10 154 break;
WiredHome 0:7b81b19d9b10 155 case NORMALSPEED:
WiredHome 0:7b81b19d9b10 156 slopePin->input();
WiredHome 0:7b81b19d9b10 157 slopePin->mode(PullNone);
WiredHome 0:7b81b19d9b10 158 break;
WiredHome 0:7b81b19d9b10 159 case STANDBY:
WiredHome 0:7b81b19d9b10 160 slopePin->output();
WiredHome 0:7b81b19d9b10 161 slopePin->write(1);
WiredHome 0:7b81b19d9b10 162 break;
WiredHome 0:7b81b19d9b10 163 default:
WiredHome 0:7b81b19d9b10 164 return false;
WiredHome 0:7b81b19d9b10 165 }
WiredHome 0:7b81b19d9b10 166 return true;
WiredHome 0:7b81b19d9b10 167 } else
WiredHome 0:7b81b19d9b10 168 return false;
WiredHome 0:7b81b19d9b10 169 }
WiredHome 0:7b81b19d9b10 170
WiredHome 0:7b81b19d9b10 171
WiredHome 0:7b81b19d9b10 172 CANSlopeControl_T CANPort::GetSlopeControl() {
WiredHome 0:7b81b19d9b10 173 return slopeMode;
WiredHome 0:7b81b19d9b10 174 }
WiredHome 0:7b81b19d9b10 175
WiredHome 0:7b81b19d9b10 176
WiredHome 0:7b81b19d9b10 177 bool CANPort::SetBitRate(int rate) {
WiredHome 0:7b81b19d9b10 178 if (can->frequency(rate)) {
WiredHome 0:7b81b19d9b10 179 bitRate = rate;
WiredHome 0:7b81b19d9b10 180 return true;
WiredHome 0:7b81b19d9b10 181 } else {
WiredHome 0:7b81b19d9b10 182 return false;
WiredHome 0:7b81b19d9b10 183 }
WiredHome 0:7b81b19d9b10 184 }
WiredHome 0:7b81b19d9b10 185
WiredHome 0:7b81b19d9b10 186
WiredHome 0:7b81b19d9b10 187 int CANPort::GetBitRate() {
WiredHome 0:7b81b19d9b10 188 return bitRate;
WiredHome 0:7b81b19d9b10 189 }
WiredHome 0:7b81b19d9b10 190
WiredHome 0:7b81b19d9b10 191
WiredHome 0:7b81b19d9b10 192 int CANPort::GetTxCounter() {
WiredHome 0:7b81b19d9b10 193 return txCounter;
WiredHome 0:7b81b19d9b10 194 }
WiredHome 0:7b81b19d9b10 195
WiredHome 0:7b81b19d9b10 196
WiredHome 0:7b81b19d9b10 197 int CANPort::GetRxCounter() {
WiredHome 0:7b81b19d9b10 198 return rxCounter;
WiredHome 0:7b81b19d9b10 199 }
WiredHome 0:7b81b19d9b10 200
WiredHome 0:7b81b19d9b10 201
WiredHome 0:7b81b19d9b10 202 int CANPort::GetTxErrorCounter() {
WiredHome 0:7b81b19d9b10 203 return can->tderror();
WiredHome 0:7b81b19d9b10 204 }
WiredHome 0:7b81b19d9b10 205
WiredHome 0:7b81b19d9b10 206
WiredHome 0:7b81b19d9b10 207 int CANPort::GetRxErrorCounter() {
WiredHome 0:7b81b19d9b10 208 return can->rderror();
WiredHome 0:7b81b19d9b10 209 }
WiredHome 0:7b81b19d9b10 210
WiredHome 0:7b81b19d9b10 211
WiredHome 0:7b81b19d9b10 212 bool CANPort::ResetChip() {
WiredHome 0:7b81b19d9b10 213 can->reset();
WiredHome 0:7b81b19d9b10 214 return true;
WiredHome 0:7b81b19d9b10 215 }
WiredHome 0:7b81b19d9b10 216
WiredHome 0:7b81b19d9b10 217
WiredHome 0:7b81b19d9b10 218 void CANPort::PrintInfo(Serial * stream) {
WiredHome 0:7b81b19d9b10 219 if (stream) {
WiredHome 0:7b81b19d9b10 220 stream->printf("\r\n");
WiredHome 0:7b81b19d9b10 221 stream->printf(" Register: CAN1 CAN2 Register: CAN1 CAN2\r\n");
WiredHome 0:7b81b19d9b10 222 stream->printf(" MOD: %08X %08X ", LPC_CAN1->MOD, LPC_CAN2->MOD);
WiredHome 0:7b81b19d9b10 223 stream->printf(" GSR: %08X %08X\r\n", LPC_CAN1->GSR, LPC_CAN2->GSR);
WiredHome 0:7b81b19d9b10 224 stream->printf(" ICR: %08X %08X ", LPC_CAN1->ICR, LPC_CAN2->ICR);
WiredHome 0:7b81b19d9b10 225 stream->printf(" IER: %08X %08X\r\n", LPC_CAN1->IER, LPC_CAN2->IER);
WiredHome 0:7b81b19d9b10 226 stream->printf(" BTR: %08X %08X ", LPC_CAN1->BTR, LPC_CAN2->BTR);
WiredHome 0:7b81b19d9b10 227 stream->printf(" EWL: %08X %08X\r\n", LPC_CAN1->EWL, LPC_CAN2->EWL);
WiredHome 0:7b81b19d9b10 228 stream->printf(" SR: %08X %08X ", LPC_CAN1->SR, LPC_CAN2->SR );
WiredHome 0:7b81b19d9b10 229 stream->printf(" RFS: %08X %08X\r\n", LPC_CAN1->RFS, LPC_CAN2->RFS);
WiredHome 0:7b81b19d9b10 230 stream->printf(" RID: %08X %08X ", LPC_CAN1->RID, LPC_CAN2->RID);
WiredHome 0:7b81b19d9b10 231 stream->printf(" RDA: %08X %08X\r\n", LPC_CAN1->RDA, LPC_CAN2->RDA);
WiredHome 0:7b81b19d9b10 232 stream->printf(" RDB: %08X %08X ", LPC_CAN1->RDB, LPC_CAN2->RDB);
WiredHome 0:7b81b19d9b10 233 stream->printf(" TFI1: %08X %08X\r\n", LPC_CAN1->TFI1, LPC_CAN2->TFI1);
WiredHome 0:7b81b19d9b10 234 stream->printf(" TID1: %08X %08X ", LPC_CAN1->TID1, LPC_CAN2->TID1);
WiredHome 0:7b81b19d9b10 235 stream->printf(" TDA1: %08X %08X\r\n", LPC_CAN1->TDA1, LPC_CAN2->TDA1);
WiredHome 0:7b81b19d9b10 236 stream->printf(" TDB1: %08X %08X ", LPC_CAN1->TDB1, LPC_CAN2->TDB1);
WiredHome 0:7b81b19d9b10 237 stream->printf(" TFI2: %08X %08X\r\n", LPC_CAN1->TFI2, LPC_CAN2->TFI2);
WiredHome 0:7b81b19d9b10 238 stream->printf(" TID2: %08X %08X ", LPC_CAN1->TID2, LPC_CAN2->TID2);
WiredHome 0:7b81b19d9b10 239 stream->printf(" TDA2: %08X %08X\r\n", LPC_CAN1->TDA2, LPC_CAN2->TDA2);
WiredHome 0:7b81b19d9b10 240 stream->printf(" TDB2: %08X %08X ", LPC_CAN1->TDB2, LPC_CAN2->TDB2);
WiredHome 0:7b81b19d9b10 241 stream->printf(" TFI3: %08X %08X\r\n", LPC_CAN1->TFI3, LPC_CAN2->TFI3);
WiredHome 0:7b81b19d9b10 242 stream->printf(" TID3: %08X %08X ", LPC_CAN1->TID3, LPC_CAN2->TID3);
WiredHome 0:7b81b19d9b10 243 stream->printf(" TDA3: %08X %08X\r\n", LPC_CAN1->TDA3, LPC_CAN2->TDA3);
WiredHome 0:7b81b19d9b10 244 stream->printf(" TDB3: %08X %08X ", LPC_CAN1->TDB3, LPC_CAN2->TDB3);
WiredHome 0:7b81b19d9b10 245 stream->printf("\r\n");
WiredHome 0:7b81b19d9b10 246 }
WiredHome 0:7b81b19d9b10 247 }