Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00027
00028 #ifndef _icl_hardware_can_UsePeakCan_h_
00029 #define _icl_hardware_can_UsePeakCan_h_
00030
00031 #ifdef _SYSTEM_LINUX_
00032 # include <fcntl.h>
00033 # include <unistd.h>
00034 # include <sys/ioctl.h>
00035 # include <string.h>
00036 # include <errno.h>
00037 # include <libpcan.h>
00038 #endif
00039
00040 #include "icl_hardware_can/tCanMessage.h"
00041 #include "icl_hardware_can/UseCanNoLxrt.h"
00042 #include "Logging.h"
00043
00044 namespace icl_hardware {
00045 namespace can {
00046
00047 typedef HANDLE tCanDescriptor;
00048 inline bool CanDescriptorValid(tCanDescriptor can_device)
00049 {
00050 return can_device != 0;
00051 }
00052 inline tCanDescriptor InvalidCanDescriptor()
00053 {
00054 return 0;
00055 }
00056 inline const char* CanDriverName()
00057 {
00058 return "PEAK-CAN";
00059 }
00060
00061 inline WORD BaudRateSpecifier( unsigned int baud_rate )
00062 {
00063 switch( baud_rate )
00064 {
00065 case 1000:
00066 return CAN_BAUD_1M;
00067 case 500:
00068 return CAN_BAUD_500K;
00069 case 250:
00070 return CAN_BAUD_250K;
00071 case 100:
00072 return CAN_BAUD_100K;
00073 case 50:
00074 return CAN_BAUD_50K;
00075 case 20:
00076 return CAN_BAUD_20K;
00077 case 10:
00078 return CAN_BAUD_10K;
00079 case 5:
00080 return CAN_BAUD_5K;
00081
00082 default:
00083 LOGGING_ERROR( CAN, "Peak Can baud rate " << baud_rate << " not valid. Setting the baud rate to 1MB " << endl);
00084 return CAN_BAUD_1M;
00085 }
00086 }
00088
00107 inline tCanDescriptor CanDeviceOpen(const char * device_name, int flags,
00108 unsigned char acceptance_code, unsigned char acceptance_mask, unsigned int baud_rate,
00109 unsigned send_fifo_size, unsigned receive_fifo_size)
00110 {
00111 printf("flags:%i\n",flags);
00112 HANDLE handle;
00113 handle = LINUX_CAN_Open((char*) device_name, flags);
00114
00115
00116 sleep(1);
00117
00118 WORD br = BaudRateSpecifier( baud_rate );
00119
00120 if ( CAN_Init(handle, br , CAN_INIT_TYPE_ST ))
00121 {
00122 printf("Invalid CanDescriptor!\n");
00123 return InvalidCanDescriptor();
00124 }
00125 else
00126 {
00127 printf("Can Init successful!\n");
00128 return handle;
00129 }
00130 }
00131
00132 inline int CanDeviceClose(tCanDescriptor _can_device)
00133 {
00134 return CAN_Close(_can_device);
00135 }
00136
00137 inline int CanDeviceSend(tCanDescriptor _can_device, const tCanMessage &msg)
00138 {
00139 if (!_can_device)
00140 return -ENODEV;
00141
00142
00143
00144 TPCANMsg pmsg;
00145 pmsg.ID = msg.id;
00146 pmsg.MSGTYPE = MSGTYPE_STANDARD;
00147
00148 pmsg.LEN = msg.dlc;
00149 memcpy(pmsg.DATA, msg.data, pmsg.LEN);
00150
00151
00152
00153 return CAN_Write(_can_device, &pmsg);
00154 }
00155
00156 inline int CanDeviceReceive(tCanDescriptor _can_device, tCanMessage &msg)
00157 {
00158 if (!_can_device)
00159 return -ENODEV;
00160
00161
00162 TPCANRdMsg pmsg;
00163
00164
00165
00166
00173 int ret = LINUX_CAN_Read_Timeout(_can_device, &pmsg, 0);
00174
00175
00176
00177
00178
00179 if (ret < 0)
00180 {
00181 LOGGING_ERROR( CAN, "CAN DEVICE HANDLE CRITICAL ERROR. COULD NOT READ PROPERLY FROM DEVICE. Error Code: " << ret << endl);
00182 return -EIO;
00183 }
00184
00185
00186 if (ret == CAN_ERR_QRCVEMPTY)
00187 {
00188
00189 return -ENODATA;
00190 }
00191
00192
00193 if (pmsg.Msg.MSGTYPE == MSGTYPE_STATUS )
00194 {
00195
00196
00197
00198
00199 if (pmsg.Msg.DATA[3] == CAN_ERR_QRCVEMPTY)
00200 {
00201 return -ENODATA;
00202 }
00203
00204 LOGGING_ERROR( CAN, "CAN ERROR DETECTED: ");
00205
00206 switch (pmsg.Msg.DATA[3])
00207 {
00208 case CAN_ERR_OK:
00209 LOGGING_ERROR( CAN, "no error code given in an error message....check protocol" << endl);
00210 break;
00211 case CAN_ERR_XMTFULL:
00212 LOGGING_ERROR( CAN, "transmit Buffer is full" << endl);
00213 return -ENOBUFS;
00214 break;
00215 case CAN_ERR_OVERRUN:
00216 LOGGING_ERROR( CAN, "ovverrun in receive buffer" << endl);
00217 return -ENOBUFS;
00218 break;
00219 case CAN_ERR_BUSLIGHT:
00220 LOGGING_ERROR( CAN, "BUSLIGHT, errorcounter limit reached, please check your cable setup" << endl);
00221 return -EIO;
00222 break;
00223 case CAN_ERR_BUSHEAVY:
00224 LOGGING_ERROR( CAN, "BUSHEAVY, errorcounter limit reached, please check your cable setup" << endl);
00225 return -EIO;
00226 break;
00227 case CAN_ERR_BUSOFF:
00228 LOGGING_ERROR( CAN, "BUSOFF, 'bus off' state entered" << endl);
00229 return -EIO;
00230 break;
00231 case CAN_ERR_QOVERRUN:
00232 LOGGING_ERROR( CAN, "receive queue overrun" << endl);
00233 return -ENOBUFS;
00234 break;
00235 case CAN_ERR_QXMTFULL:
00236 LOGGING_ERROR( CAN, "transmit queue full" << endl);
00237 return -ENOBUFS;
00238 break;
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 default:
00265 LOGGING_ERROR( CAN, "Unknown error : "<< pmsg.Msg.DATA[3] << endl);
00266
00267
00268 return -ENODATA;
00269 break;
00270 }
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 msg.id = pmsg.Msg.ID;
00285 msg.dlc = pmsg.Msg.LEN;
00286 if (pmsg.Msg.MSGTYPE == MSGTYPE_EXTENDED || pmsg.Msg.MSGTYPE == MSGTYPE_STATUS)
00287 {
00288 msg.rtr = 0;
00289 }
00290 else
00291 {
00292
00293 msg.rtr = pmsg.Msg.MSGTYPE;
00294 }
00295
00296 memcpy(msg.data, pmsg.Msg.DATA, pmsg.Msg.LEN);
00297
00298
00299 return pmsg.Msg.LEN;
00300 }
00301
00302 inline int CanDeviceReset(tCanDescriptor _can_device)
00303 {
00304 if (!_can_device)
00305 return -ENODEV;
00306 return 0;
00307 }
00308
00309 }
00310 }
00311
00312 #endif