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:
Thu Sep 19 21:46:28 2019 +0000
Revision:
3:4c780c641125
Parent:
1:f0b4e47d948d
Clean up CANPort to have access to underlying CAN methods.

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 3:4c780c641125 31 CANPort::CANPort(CANCHANNEL_T chNum, PinName rd, PinName td, PinName _activityPin, PinName _slopePin, CANSlopeControl_T slope)
WiredHome 3:4c780c641125 32 : CAN(rd,td) {
WiredHome 0:7b81b19d9b10 33 channel = chNum;
WiredHome 3:4c780c641125 34 //can = new CAN(rd, td);
WiredHome 0:7b81b19d9b10 35 if (_activityPin != NC) {
WiredHome 0:7b81b19d9b10 36 activityPin = new PwmOut(_activityPin);
WiredHome 0:7b81b19d9b10 37 activityPin->pulsewidth_us(100);
WiredHome 0:7b81b19d9b10 38 }
WiredHome 0:7b81b19d9b10 39 else
WiredHome 0:7b81b19d9b10 40 activityPin = NULL;
WiredHome 0:7b81b19d9b10 41 if (_slopePin != NC) {
WiredHome 0:7b81b19d9b10 42 slopePin = new DigitalInOut(_slopePin);
WiredHome 0:7b81b19d9b10 43 SetSlopeControl(slope);
WiredHome 0:7b81b19d9b10 44 } else
WiredHome 0:7b81b19d9b10 45 slopePin = NULL;
WiredHome 0:7b81b19d9b10 46 slopePinName = _slopePin;
WiredHome 0:7b81b19d9b10 47 txCounter = 0;
WiredHome 0:7b81b19d9b10 48 rxCounter = 0;
WiredHome 0:7b81b19d9b10 49 }
WiredHome 0:7b81b19d9b10 50
WiredHome 0:7b81b19d9b10 51
WiredHome 0:7b81b19d9b10 52 CANPort::~CANPort() {
WiredHome 0:7b81b19d9b10 53 if (slopePin)
WiredHome 0:7b81b19d9b10 54 delete slopePin;
WiredHome 0:7b81b19d9b10 55 if (activityPin)
WiredHome 0:7b81b19d9b10 56 delete activityPin;
WiredHome 3:4c780c641125 57 //if (can)
WiredHome 3:4c780c641125 58 // delete can;
WiredHome 0:7b81b19d9b10 59 slopePin = NULL;
WiredHome 0:7b81b19d9b10 60 activityPin = NULL;
WiredHome 3:4c780c641125 61 //can = NULL;
WiredHome 0:7b81b19d9b10 62 }
WiredHome 0:7b81b19d9b10 63
WiredHome 0:7b81b19d9b10 64
WiredHome 0:7b81b19d9b10 65 bool CANPort::TransmitMsg(CANmsg msg) {
WiredHome 0:7b81b19d9b10 66 bool success = false;
WiredHome 0:7b81b19d9b10 67
WiredHome 0:7b81b19d9b10 68 if (msg.dir == xmt) { // we have to have indicated our intent to transmit
WiredHome 0:7b81b19d9b10 69 msg.ch = channel;
WiredHome 3:4c780c641125 70 if ( write(CANMessage(msg.id, (char *)&msg.data, msg.len, CANData, msg.format))) {
WiredHome 0:7b81b19d9b10 71 txCounter++;
WiredHome 0:7b81b19d9b10 72 Flash(msg.dir);
WiredHome 0:7b81b19d9b10 73 success = true;
WiredHome 0:7b81b19d9b10 74 }
WiredHome 0:7b81b19d9b10 75 }
WiredHome 0:7b81b19d9b10 76 return success;
WiredHome 0:7b81b19d9b10 77 }
WiredHome 0:7b81b19d9b10 78
WiredHome 0:7b81b19d9b10 79
WiredHome 0:7b81b19d9b10 80 bool CANPort::ReceiveMsg(CANmsg &msg) {
WiredHome 0:7b81b19d9b10 81 bool success = false;
WiredHome 0:7b81b19d9b10 82 CANMessage _msg;
WiredHome 0:7b81b19d9b10 83
WiredHome 3:4c780c641125 84 if (read(_msg)) {
WiredHome 0:7b81b19d9b10 85 /// @TODO This looks like a very inefficient method, but it works.
WiredHome 0:7b81b19d9b10 86 CANmsg Xmsg(channel, rcv, _msg);
WiredHome 0:7b81b19d9b10 87 msg = Xmsg;
WiredHome 0:7b81b19d9b10 88 rxCounter++;
WiredHome 0:7b81b19d9b10 89 Flash(msg.dir);
WiredHome 0:7b81b19d9b10 90 success = true;
WiredHome 0:7b81b19d9b10 91 }
WiredHome 0:7b81b19d9b10 92 return success;
WiredHome 0:7b81b19d9b10 93 }
WiredHome 0:7b81b19d9b10 94
WiredHome 0:7b81b19d9b10 95
WiredHome 3:4c780c641125 96 //void CANPort::Attach( void (*fptr)(void) ) {
WiredHome 3:4c780c641125 97 // can->attach(fptr);
WiredHome 3:4c780c641125 98 //}
WiredHome 0:7b81b19d9b10 99
WiredHome 0:7b81b19d9b10 100
WiredHome 0:7b81b19d9b10 101 void CANPort::Extinguish(void) {
WiredHome 0:7b81b19d9b10 102 if (activityPin) {
WiredHome 0:7b81b19d9b10 103 *activityPin = 0.0;
WiredHome 0:7b81b19d9b10 104 }
WiredHome 0:7b81b19d9b10 105 }
WiredHome 0:7b81b19d9b10 106
WiredHome 0:7b81b19d9b10 107
WiredHome 0:7b81b19d9b10 108 void CANPort::Flash(CANDIR_T tx) {
WiredHome 0:7b81b19d9b10 109 if (activityPin) {
WiredHome 0:7b81b19d9b10 110 *activityPin = (tx == xmt) ? FLASH_TX_LEVEL : FLASH_RX_LEVEL; // dim for transmit, bright for receive
WiredHome 1:f0b4e47d948d 111 #if (MBED_MAJOR_VERSION >= 5) || (MBED_LIBRARY_VERSION > 127)
WiredHome 1:f0b4e47d948d 112 activityTimeout.attach(callback(this, &CANPort::Extinguish), FLASH_PERIOD);
WiredHome 1:f0b4e47d948d 113 #else
WiredHome 0:7b81b19d9b10 114 activityTimeout.attach(this, &CANPort::Extinguish, FLASH_PERIOD);
WiredHome 1:f0b4e47d948d 115 #endif
WiredHome 0:7b81b19d9b10 116 }
WiredHome 0:7b81b19d9b10 117 }
WiredHome 0:7b81b19d9b10 118
WiredHome 0:7b81b19d9b10 119
WiredHome 0:7b81b19d9b10 120 bool CANPort::SetAutoReset(bool enable) {
WiredHome 0:7b81b19d9b10 121 autoReset = enable;
WiredHome 0:7b81b19d9b10 122 return true;
WiredHome 0:7b81b19d9b10 123 }
WiredHome 0:7b81b19d9b10 124
WiredHome 0:7b81b19d9b10 125
WiredHome 0:7b81b19d9b10 126 bool CANPort::SetBusMode(CANBusMode_T mode) {
WiredHome 0:7b81b19d9b10 127 switch (mode) {
WiredHome 0:7b81b19d9b10 128 case MONITOR:
WiredHome 3:4c780c641125 129 monitor(true);
WiredHome 0:7b81b19d9b10 130 busMode = mode;
WiredHome 0:7b81b19d9b10 131 break;
WiredHome 0:7b81b19d9b10 132 case ACTIVE:
WiredHome 3:4c780c641125 133 monitor(false);
WiredHome 0:7b81b19d9b10 134 busMode = mode;
WiredHome 0:7b81b19d9b10 135 break;
WiredHome 0:7b81b19d9b10 136 default:
WiredHome 0:7b81b19d9b10 137 return false;
WiredHome 0:7b81b19d9b10 138 }
WiredHome 0:7b81b19d9b10 139 return true;
WiredHome 0:7b81b19d9b10 140 }
WiredHome 0:7b81b19d9b10 141
WiredHome 0:7b81b19d9b10 142
WiredHome 3:4c780c641125 143 CANPort::CANBusMode_T CANPort::GetBusMode() {
WiredHome 0:7b81b19d9b10 144 return busMode;
WiredHome 0:7b81b19d9b10 145 }
WiredHome 0:7b81b19d9b10 146
WiredHome 0:7b81b19d9b10 147
WiredHome 0:7b81b19d9b10 148 bool CANPort::SetSlopeControl(CANSlopeControl_T slope) {
WiredHome 0:7b81b19d9b10 149 if (slopePin) {
WiredHome 0:7b81b19d9b10 150 slopeMode = slope;
WiredHome 0:7b81b19d9b10 151 switch (slope) {
WiredHome 0:7b81b19d9b10 152 case HIGHSPEED:
WiredHome 0:7b81b19d9b10 153 slopePin->output();
WiredHome 0:7b81b19d9b10 154 slopePin->write(0);
WiredHome 0:7b81b19d9b10 155 break;
WiredHome 0:7b81b19d9b10 156 case NORMALSPEED:
WiredHome 0:7b81b19d9b10 157 slopePin->input();
WiredHome 0:7b81b19d9b10 158 slopePin->mode(PullNone);
WiredHome 0:7b81b19d9b10 159 break;
WiredHome 0:7b81b19d9b10 160 case STANDBY:
WiredHome 0:7b81b19d9b10 161 slopePin->output();
WiredHome 0:7b81b19d9b10 162 slopePin->write(1);
WiredHome 0:7b81b19d9b10 163 break;
WiredHome 0:7b81b19d9b10 164 default:
WiredHome 0:7b81b19d9b10 165 return false;
WiredHome 0:7b81b19d9b10 166 }
WiredHome 0:7b81b19d9b10 167 return true;
WiredHome 0:7b81b19d9b10 168 } else
WiredHome 0:7b81b19d9b10 169 return false;
WiredHome 0:7b81b19d9b10 170 }
WiredHome 0:7b81b19d9b10 171
WiredHome 0:7b81b19d9b10 172
WiredHome 3:4c780c641125 173 CANPort::CANSlopeControl_T CANPort::GetSlopeControl() {
WiredHome 0:7b81b19d9b10 174 return slopeMode;
WiredHome 0:7b81b19d9b10 175 }
WiredHome 0:7b81b19d9b10 176
WiredHome 0:7b81b19d9b10 177
WiredHome 3:4c780c641125 178 bool CANPort::SetBitRate(uint32_t rate) {
WiredHome 3:4c780c641125 179 if (frequency(rate)) {
WiredHome 0:7b81b19d9b10 180 bitRate = rate;
WiredHome 0:7b81b19d9b10 181 return true;
WiredHome 0:7b81b19d9b10 182 } else {
WiredHome 0:7b81b19d9b10 183 return false;
WiredHome 0:7b81b19d9b10 184 }
WiredHome 0:7b81b19d9b10 185 }
WiredHome 0:7b81b19d9b10 186
WiredHome 0:7b81b19d9b10 187
WiredHome 3:4c780c641125 188 uint32_t CANPort::GetBitRate() {
WiredHome 0:7b81b19d9b10 189 return bitRate;
WiredHome 0:7b81b19d9b10 190 }
WiredHome 0:7b81b19d9b10 191
WiredHome 0:7b81b19d9b10 192
WiredHome 0:7b81b19d9b10 193 int CANPort::GetTxCounter() {
WiredHome 0:7b81b19d9b10 194 return txCounter;
WiredHome 0:7b81b19d9b10 195 }
WiredHome 0:7b81b19d9b10 196
WiredHome 0:7b81b19d9b10 197
WiredHome 0:7b81b19d9b10 198 int CANPort::GetRxCounter() {
WiredHome 0:7b81b19d9b10 199 return rxCounter;
WiredHome 0:7b81b19d9b10 200 }
WiredHome 0:7b81b19d9b10 201
WiredHome 0:7b81b19d9b10 202
WiredHome 0:7b81b19d9b10 203 int CANPort::GetTxErrorCounter() {
WiredHome 3:4c780c641125 204 return tderror();
WiredHome 0:7b81b19d9b10 205 }
WiredHome 0:7b81b19d9b10 206
WiredHome 0:7b81b19d9b10 207
WiredHome 0:7b81b19d9b10 208 int CANPort::GetRxErrorCounter() {
WiredHome 3:4c780c641125 209 return rderror();
WiredHome 0:7b81b19d9b10 210 }
WiredHome 0:7b81b19d9b10 211
WiredHome 0:7b81b19d9b10 212
WiredHome 0:7b81b19d9b10 213 bool CANPort::ResetChip() {
WiredHome 3:4c780c641125 214 reset();
WiredHome 0:7b81b19d9b10 215 return true;
WiredHome 0:7b81b19d9b10 216 }
WiredHome 0:7b81b19d9b10 217
WiredHome 0:7b81b19d9b10 218
WiredHome 0:7b81b19d9b10 219 void CANPort::PrintInfo(Serial * stream) {
WiredHome 0:7b81b19d9b10 220 if (stream) {
WiredHome 0:7b81b19d9b10 221 stream->printf("\r\n");
WiredHome 0:7b81b19d9b10 222 stream->printf(" Register: CAN1 CAN2 Register: CAN1 CAN2\r\n");
WiredHome 0:7b81b19d9b10 223 stream->printf(" MOD: %08X %08X ", LPC_CAN1->MOD, LPC_CAN2->MOD);
WiredHome 0:7b81b19d9b10 224 stream->printf(" GSR: %08X %08X\r\n", LPC_CAN1->GSR, LPC_CAN2->GSR);
WiredHome 0:7b81b19d9b10 225 stream->printf(" ICR: %08X %08X ", LPC_CAN1->ICR, LPC_CAN2->ICR);
WiredHome 0:7b81b19d9b10 226 stream->printf(" IER: %08X %08X\r\n", LPC_CAN1->IER, LPC_CAN2->IER);
WiredHome 0:7b81b19d9b10 227 stream->printf(" BTR: %08X %08X ", LPC_CAN1->BTR, LPC_CAN2->BTR);
WiredHome 0:7b81b19d9b10 228 stream->printf(" EWL: %08X %08X\r\n", LPC_CAN1->EWL, LPC_CAN2->EWL);
WiredHome 0:7b81b19d9b10 229 stream->printf(" SR: %08X %08X ", LPC_CAN1->SR, LPC_CAN2->SR );
WiredHome 0:7b81b19d9b10 230 stream->printf(" RFS: %08X %08X\r\n", LPC_CAN1->RFS, LPC_CAN2->RFS);
WiredHome 0:7b81b19d9b10 231 stream->printf(" RID: %08X %08X ", LPC_CAN1->RID, LPC_CAN2->RID);
WiredHome 0:7b81b19d9b10 232 stream->printf(" RDA: %08X %08X\r\n", LPC_CAN1->RDA, LPC_CAN2->RDA);
WiredHome 0:7b81b19d9b10 233 stream->printf(" RDB: %08X %08X ", LPC_CAN1->RDB, LPC_CAN2->RDB);
WiredHome 0:7b81b19d9b10 234 stream->printf(" TFI1: %08X %08X\r\n", LPC_CAN1->TFI1, LPC_CAN2->TFI1);
WiredHome 0:7b81b19d9b10 235 stream->printf(" TID1: %08X %08X ", LPC_CAN1->TID1, LPC_CAN2->TID1);
WiredHome 0:7b81b19d9b10 236 stream->printf(" TDA1: %08X %08X\r\n", LPC_CAN1->TDA1, LPC_CAN2->TDA1);
WiredHome 0:7b81b19d9b10 237 stream->printf(" TDB1: %08X %08X ", LPC_CAN1->TDB1, LPC_CAN2->TDB1);
WiredHome 0:7b81b19d9b10 238 stream->printf(" TFI2: %08X %08X\r\n", LPC_CAN1->TFI2, LPC_CAN2->TFI2);
WiredHome 0:7b81b19d9b10 239 stream->printf(" TID2: %08X %08X ", LPC_CAN1->TID2, LPC_CAN2->TID2);
WiredHome 0:7b81b19d9b10 240 stream->printf(" TDA2: %08X %08X\r\n", LPC_CAN1->TDA2, LPC_CAN2->TDA2);
WiredHome 0:7b81b19d9b10 241 stream->printf(" TDB2: %08X %08X ", LPC_CAN1->TDB2, LPC_CAN2->TDB2);
WiredHome 0:7b81b19d9b10 242 stream->printf(" TFI3: %08X %08X\r\n", LPC_CAN1->TFI3, LPC_CAN2->TFI3);
WiredHome 0:7b81b19d9b10 243 stream->printf(" TID3: %08X %08X ", LPC_CAN1->TID3, LPC_CAN2->TID3);
WiredHome 0:7b81b19d9b10 244 stream->printf(" TDA3: %08X %08X\r\n", LPC_CAN1->TDA3, LPC_CAN2->TDA3);
WiredHome 0:7b81b19d9b10 245 stream->printf(" TDB3: %08X %08X ", LPC_CAN1->TDB3, LPC_CAN2->TDB3);
WiredHome 0:7b81b19d9b10 246 stream->printf("\r\n");
WiredHome 0:7b81b19d9b10 247 }
WiredHome 0:7b81b19d9b10 248 }