Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
CANPort.cpp
00001 /// @file CANPort.cpp is where all the port level functionality resides 00002 /// 00003 /// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved. 00004 /// Individuals may use this application for evaluation or non-commercial 00005 /// purposes. Within this restriction, changes may be made to this application 00006 /// as long as this copyright notice is retained. The user shall make 00007 /// clear that their work is a derived work, and not the original. 00008 /// Users of this application and sources accept this application "as is" and 00009 /// shall hold harmless Smartware Computing, for any undesired results while 00010 /// using this application - whether real or imagined. 00011 /// 00012 /// @author David Smart, Smartware Computing 00013 /// 00014 /// 20110718 00015 /// Fixed a bug in the Receive handler - it was not propagating the message 00016 /// out. 00017 /// 20110605 00018 /// Revised the SlopeControl so that it actually works for any change in value 00019 /// where it was previously able to go low or high, but once as an input it 00020 /// then would not go back to an output. 00021 /// 00022 #include "mbed.h" 00023 #include "CANPort.h" 00024 #include "Utilities.h" 00025 00026 #define FLASH_PERIOD (float)0.04 00027 #define FLASH_TX_LEVEL 0.10 00028 #define FLASH_RX_LEVEL 1.00 00029 00030 00031 CANPort::CANPort(CANCHANNEL_T chNum, PinName rd, PinName td, PinName _activityPin, PinName _slopePin, CANSlopeControl_T slope) 00032 : CAN(rd,td) { 00033 channel = chNum; 00034 //can = new CAN(rd, td); 00035 if (_activityPin != NC) { 00036 activityPin = new PwmOut(_activityPin); 00037 activityPin->pulsewidth_us(100); 00038 } 00039 else 00040 activityPin = NULL; 00041 if (_slopePin != NC) { 00042 slopePin = new DigitalInOut(_slopePin); 00043 SetSlopeControl(slope); 00044 } else 00045 slopePin = NULL; 00046 slopePinName = _slopePin; 00047 txCounter = 0; 00048 rxCounter = 0; 00049 } 00050 00051 00052 CANPort::~CANPort() { 00053 if (slopePin) 00054 delete slopePin; 00055 if (activityPin) 00056 delete activityPin; 00057 //if (can) 00058 // delete can; 00059 slopePin = NULL; 00060 activityPin = NULL; 00061 //can = NULL; 00062 } 00063 00064 00065 bool CANPort::TransmitMsg(CANmsg msg) { 00066 bool success = false; 00067 00068 if (msg.dir == xmt) { // we have to have indicated our intent to transmit 00069 msg.ch = channel; 00070 if ( write(CANMessage(msg.id, (char *)&msg.data, msg.len, CANData, msg.format))) { 00071 txCounter++; 00072 Flash(msg.dir); 00073 success = true; 00074 } 00075 } 00076 return success; 00077 } 00078 00079 00080 bool CANPort::ReceiveMsg(CANmsg &msg) { 00081 bool success = false; 00082 CANMessage _msg; 00083 00084 if (read(_msg)) { 00085 /// @TODO This looks like a very inefficient method, but it works. 00086 CANmsg Xmsg(channel, rcv, _msg); 00087 msg = Xmsg; 00088 rxCounter++; 00089 Flash(msg.dir); 00090 success = true; 00091 } 00092 return success; 00093 } 00094 00095 00096 //void CANPort::Attach( void (*fptr)(void) ) { 00097 // can->attach(fptr); 00098 //} 00099 00100 00101 void CANPort::Extinguish(void) { 00102 if (activityPin) { 00103 *activityPin = 0.0; 00104 } 00105 } 00106 00107 00108 void CANPort::Flash(CANDIR_T tx) { 00109 if (activityPin) { 00110 *activityPin = (tx == xmt) ? FLASH_TX_LEVEL : FLASH_RX_LEVEL; // dim for transmit, bright for receive 00111 #if (MBED_MAJOR_VERSION >= 5) || (MBED_LIBRARY_VERSION > 127) 00112 activityTimeout.attach(callback(this, &CANPort::Extinguish), FLASH_PERIOD); 00113 #else 00114 activityTimeout.attach(this, &CANPort::Extinguish, FLASH_PERIOD); 00115 #endif 00116 } 00117 } 00118 00119 00120 bool CANPort::SetAutoReset(bool enable) { 00121 autoReset = enable; 00122 return true; 00123 } 00124 00125 00126 bool CANPort::SetBusMode(CANBusMode_T mode) { 00127 switch (mode) { 00128 case MONITOR: 00129 monitor(true); 00130 busMode = mode; 00131 break; 00132 case ACTIVE: 00133 monitor(false); 00134 busMode = mode; 00135 break; 00136 default: 00137 return false; 00138 } 00139 return true; 00140 } 00141 00142 00143 CANPort::CANBusMode_T CANPort::GetBusMode() { 00144 return busMode; 00145 } 00146 00147 00148 bool CANPort::SetSlopeControl(CANSlopeControl_T slope) { 00149 if (slopePin) { 00150 slopeMode = slope; 00151 switch (slope) { 00152 case HIGHSPEED: 00153 slopePin->output(); 00154 slopePin->write(0); 00155 break; 00156 case NORMALSPEED: 00157 slopePin->input(); 00158 slopePin->mode(PullNone); 00159 break; 00160 case STANDBY: 00161 slopePin->output(); 00162 slopePin->write(1); 00163 break; 00164 default: 00165 return false; 00166 } 00167 return true; 00168 } else 00169 return false; 00170 } 00171 00172 00173 CANPort::CANSlopeControl_T CANPort::GetSlopeControl() { 00174 return slopeMode; 00175 } 00176 00177 00178 bool CANPort::SetBitRate(uint32_t rate) { 00179 if (frequency(rate)) { 00180 bitRate = rate; 00181 return true; 00182 } else { 00183 return false; 00184 } 00185 } 00186 00187 00188 uint32_t CANPort::GetBitRate() { 00189 return bitRate; 00190 } 00191 00192 00193 int CANPort::GetTxCounter() { 00194 return txCounter; 00195 } 00196 00197 00198 int CANPort::GetRxCounter() { 00199 return rxCounter; 00200 } 00201 00202 00203 int CANPort::GetTxErrorCounter() { 00204 return tderror(); 00205 } 00206 00207 00208 int CANPort::GetRxErrorCounter() { 00209 return rderror(); 00210 } 00211 00212 00213 bool CANPort::ResetChip() { 00214 reset(); 00215 return true; 00216 } 00217 00218 00219 void CANPort::PrintInfo(Serial * stream) { 00220 if (stream) { 00221 stream->printf("\r\n"); 00222 stream->printf(" Register: CAN1 CAN2 Register: CAN1 CAN2\r\n"); 00223 stream->printf(" MOD: %08X %08X ", LPC_CAN1->MOD, LPC_CAN2->MOD); 00224 stream->printf(" GSR: %08X %08X\r\n", LPC_CAN1->GSR, LPC_CAN2->GSR); 00225 stream->printf(" ICR: %08X %08X ", LPC_CAN1->ICR, LPC_CAN2->ICR); 00226 stream->printf(" IER: %08X %08X\r\n", LPC_CAN1->IER, LPC_CAN2->IER); 00227 stream->printf(" BTR: %08X %08X ", LPC_CAN1->BTR, LPC_CAN2->BTR); 00228 stream->printf(" EWL: %08X %08X\r\n", LPC_CAN1->EWL, LPC_CAN2->EWL); 00229 stream->printf(" SR: %08X %08X ", LPC_CAN1->SR, LPC_CAN2->SR ); 00230 stream->printf(" RFS: %08X %08X\r\n", LPC_CAN1->RFS, LPC_CAN2->RFS); 00231 stream->printf(" RID: %08X %08X ", LPC_CAN1->RID, LPC_CAN2->RID); 00232 stream->printf(" RDA: %08X %08X\r\n", LPC_CAN1->RDA, LPC_CAN2->RDA); 00233 stream->printf(" RDB: %08X %08X ", LPC_CAN1->RDB, LPC_CAN2->RDB); 00234 stream->printf(" TFI1: %08X %08X\r\n", LPC_CAN1->TFI1, LPC_CAN2->TFI1); 00235 stream->printf(" TID1: %08X %08X ", LPC_CAN1->TID1, LPC_CAN2->TID1); 00236 stream->printf(" TDA1: %08X %08X\r\n", LPC_CAN1->TDA1, LPC_CAN2->TDA1); 00237 stream->printf(" TDB1: %08X %08X ", LPC_CAN1->TDB1, LPC_CAN2->TDB1); 00238 stream->printf(" TFI2: %08X %08X\r\n", LPC_CAN1->TFI2, LPC_CAN2->TFI2); 00239 stream->printf(" TID2: %08X %08X ", LPC_CAN1->TID2, LPC_CAN2->TID2); 00240 stream->printf(" TDA2: %08X %08X\r\n", LPC_CAN1->TDA2, LPC_CAN2->TDA2); 00241 stream->printf(" TDB2: %08X %08X ", LPC_CAN1->TDB2, LPC_CAN2->TDB2); 00242 stream->printf(" TFI3: %08X %08X\r\n", LPC_CAN1->TFI3, LPC_CAN2->TFI3); 00243 stream->printf(" TID3: %08X %08X ", LPC_CAN1->TID3, LPC_CAN2->TID3); 00244 stream->printf(" TDA3: %08X %08X\r\n", LPC_CAN1->TDA3, LPC_CAN2->TDA3); 00245 stream->printf(" TDB3: %08X %08X ", LPC_CAN1->TDB3, LPC_CAN2->TDB3); 00246 stream->printf("\r\n"); 00247 } 00248 }
Generated on Thu Jul 14 2022 10:08:49 by
 1.7.2
 1.7.2