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)
CANPort.cpp@3:4c780c641125, 2019-09-19 (annotated)
- 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?
User | Revision | Line number | New 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 | } |