00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "PCANController.hpp"
00029 #include <fcntl.h>
00030 #include <rtt/Logger.hpp>
00031
00032 namespace RTT
00033 {
00034 namespace CAN
00035 {
00036 PCANController::PCANController(int priority, unsigned int minor,
00037 WORD bitrate, int CANMsgType)
00038 : NonPeriodicActivity(ORO_SCHED_OTHER, priority), _handle(NULL),
00039 _status(CAN_ERR_OK), _bitrate(bitrate),
00040 _CANMsgType(CANMsgType),_channel(0),
00041 total_recv(0), total_trns(0), failed_recv(0), failed_trns(0),
00042 exit(false)
00043 {
00044 Logger::In in("PCANController");
00045
00046 char DeviceName[ 12 ];
00047 snprintf(DeviceName,12, "/dev/pcan%d", minor );
00048 log(Info) << "Trying to open " << DeviceName << endlog();
00049 _handle = LINUX_CAN_Open(DeviceName, O_RDWR);
00050 if (_handle != NULL){
00051
00052 CAN_Status(_handle);
00053
00054 char version_string[VERSIONSTRING_LEN];
00055 DWORD err = CAN_VersionInfo(_handle, version_string);
00056 if (!err)
00057 log(Info) << DeviceName << ": ok. Driver Version = " << version_string << endlog();
00058 else
00059 log(Warning) << DeviceName <<": warning. Error getting driver version info" << endlog();
00060 }
00061 else {
00062 log(Error) << DeviceName << ": failed. Could not open device." << endlog();
00063 }
00064 }
00065
00066 PCANController::~PCANController()
00067 {
00068 Logger::In in("PCANController");
00069 this->stop();
00070 if (_handle != NULL )
00071 _status = CAN_Close(_handle);
00072 else
00073 _status = !CAN_ERR_OK;
00074 if (_status != CAN_ERR_OK)
00075 log(Error) << "Error shutting down driver, status = " << status() << endlog();
00076
00077 }
00078
00079 HANDLE PCANController::handle() const {
00080 return _handle;
00081 }
00082
00083 bool PCANController::initialize() {
00084 Logger::In in("PCANController");
00085 if ( _handle == NULL )
00086 return false;
00087 exit = false;
00088 _status = CAN_Init(_handle, _bitrate, _CANMsgType);
00089 if (_status != CAN_ERR_OK)
00090 log(Warning) << "Error initializing driver, status = " << status() << endlog();
00091 return (_status == CAN_ERR_OK);
00092 }
00093
00094 void PCANController::loop()
00095 {
00096 while ( !exit ){
00097 this->readFromBuffer(_CANMsg);
00098 _bus->write(&_CANMsg);
00099 }
00100 }
00101
00102 bool PCANController::breakLoop()
00103 {
00104 exit = true;
00105 return true;
00106 }
00107
00108 void PCANController::finalize() {
00109 Logger::In in("PCANController");
00110 log(Info) << "PCAN Controller stopped. Last run statistics :"<<endlog();
00111 log(Info) << " Total Received : "<<total_recv<< ". Failed to Receive : "<< failed_recv<< endlog();
00112 log(Info) << " Total Transmitted : "<<total_trns<< ". Failed to Transmit : "<< failed_trns<< endlog();
00113 total_recv = failed_recv = total_trns = failed_trns = 0;
00114 }
00115
00116 void PCANController::addBus( unsigned int chan, CANBusInterface* bus)
00117 {
00118 _channel = chan; _bus = bus;
00119 controller[_channel] = this;
00120 bus->setController( this );
00121 }
00122
00123 void PCANController::process(const CANMessage* msg)
00124 {
00125 Logger::In in("PCANController");
00126
00127 TPCANMsg pcan_msg;
00128 for (unsigned int i=0; i < 8; i++){
00129 if ( i < msg->getDLC() )
00130 pcan_msg.DATA[i]=msg->getData(i);
00131 else
00132 pcan_msg.DATA[i]=0;
00133 }
00134
00135
00136
00137
00138 pcan_msg.LEN=msg->getDLC();
00139
00140
00141 if (msg->isExtended()){
00142 pcan_msg.MSGTYPE = MSGTYPE_EXTENDED;
00143 pcan_msg.ID=(DWORD) msg->getExtId();
00144
00145
00146
00147 }
00148 else{
00149 pcan_msg.MSGTYPE = MSGTYPE_STANDARD;
00150 pcan_msg.ID=(DWORD) msg->getStdId();
00151
00152
00153
00154
00155
00156 }
00157
00158 if (msg->isRemote())
00159 pcan_msg.MSGTYPE |= MSGTYPE_RTR;
00160
00161
00162
00163
00164
00165
00166
00167 _status = CAN_Write(_handle,&pcan_msg);
00168 if (_status == CAN_ERR_OK)
00169 ++total_trns;
00170 else{
00171 ++failed_trns;
00172
00173
00174 }
00175 }
00176
00177 unsigned int PCANController::nodeId() const
00178 {
00179 return 0;
00180 }
00181
00182 DWORD PCANController::status() const
00183 {
00184 return _status;
00185 }
00186
00187 bool PCANController::readFromBuffer( CANMessage& msg)
00188 {
00189 Logger::In in("PCANController");
00190 TPCANRdMsg pcan_msg;
00191 const int usecs = 100 * 1000;
00192 if ( (_status = LINUX_CAN_Read_Timeout(_handle, &pcan_msg, usecs) ) == CAN_ERR_OK ){
00193 msg.clear();
00194
00195 msg.setDLC(pcan_msg.Msg.LEN);
00196
00197 if ((pcan_msg.Msg.MSGTYPE & MSGTYPE_RTR) == MSGTYPE_RTR)
00198 msg.setRemote();
00199
00200 if ((pcan_msg.Msg.MSGTYPE & MSGTYPE_EXTENDED) == MSGTYPE_EXTENDED)
00201 {
00202 msg.setExtId((unsigned int) pcan_msg.Msg.ID);
00203
00204
00205
00206 }
00207 else
00208 msg.setStdId((unsigned int) pcan_msg.Msg.ID);
00209
00210 for (unsigned int i=0; i < 8; i++){
00211 msg.setData(i,pcan_msg.Msg.DATA[i]);
00212 }
00213 #if 0 // Some debugging code, printing each received CAN message
00214 log(Debug) << "Receiving CAN Message: Id=";
00215 if (msg.isStandard())
00216 log(Debug) << msg.getStdId();
00217 else
00218 log(Debug) << msg.getExtId();
00219 log(Debug) << ", DLC=" << msg.getDLC() << ", DATA = ";
00220 for (unsigned int i=0; i < 8; i++){
00221 log(Debug) << (unsigned int) msg.getData(i) << " ";
00222 }
00223 log(Debug) << endlog();
00224 #endif
00225
00226 msg.origin = this;
00227 ++total_recv;
00228 }
00229 else{
00230 if (_status == CAN_ERR_QRCVEMPTY){
00231
00232 }
00233 else {
00234
00235 ++failed_recv;
00236 }
00237 }
00238 return (_status == CAN_ERR_OK);
00239 }
00240
00241 PCANController* PCANController::controller[PCAN_CHANNEL_MAX];
00242 }
00243
00244 }