source: pacpussensors/trunk/CanGateway/driver/XLVectorCanDriver.cpp@ 107

Last change on this file since 107 was 89, checked in by DHERBOMEZ Gérald, 9 years ago

Add KVASER CAN driver support for CanGateway component. Tested only for Windows.

File size: 15.1 KB
RevLine 
[1]1/// @date created 2006/08/07 - 14:14
2/// @author Gerald Dherbomez
3/// @version $Id: XLVectorCanDriver.cpp 888 2010-11-16 07:59:53Z gdherbom $
4
5#include "XLVectorCanDriver.h"
6
7#include <cassert>
8#include <cstdio>
9#include <iomanip>
10#include <iostream>
11#include <string>
12
[2]13#include "Pacpus/kernel/Log.h"
14#include "../CanFrame.h"
[1]15
16using namespace pacpus;
17using namespace std;
18
19DECLARE_STATIC_LOGGER("pacpus.base.XLVectorCanDriver");
20
21#define WAIT_RECEIVING_FRAME_TIMEOUT 1000
22
23#define RX_QUEUE_SIZE 4096
24#define QUEUE_LEVEL 1
25
26bool checkXlStatus(const XLstatus status) {
27 if ( status != XL_SUCCESS ) {
28 XLstringType error = xlGetErrorString(status);
29 LOG_ERROR(error);
30 return false;
31 } else {
32 return true;
33 }
34
35}
36
37XLstatus traceXLCommand(char * cmd, XLstatus status)
38{
39 LOG_TRACE(cmd << " : " << xlGetErrorString(status));
40 checkXlStatus(status);
41 return status;
42}
43
44/**
45* Constructor which enables to initialize the different attributes of the class with default values.
46* @see ~XLVectorCanDriver (void)
47* @see XLVectorCanDriver (unsigned int gHwTypeT, Vaccess gChannelMaskT, unsigned int gCanIdT, unsigned int gBitRateT,int gHwChannelT)
48*/
49
50XLVectorCanDriver::XLVectorCanDriver(int channel, unsigned int bitRate)
51{
52 LOG_INFO("Notice : VECTOR XL CAN Driver used\n");
53 /*
54 gPortHandle = INVALID_PORTHANDLE;
55 gChannelMask = 0x3;
56 gPermissionMask = 0;
57 gCanId = 0x2A9;
58 gBitRate = bitRate;
59 gHwType = HWTYPE_CANAC2PCI;
60 gHwChannel = channel;
61 gEventHandle = 0;
62 */
63 traceXLCommand("xlOpenDriver", xlOpenDriver());
64 // initialize("canXL", XL_HWTYPE_CANBOARDXL, 0, channel, bitRate); // TODO - Fix this hardcoded hardware value
65 initialize("canXL", -1, 0, channel, bitRate);
66}
67
68
69/**
70* Constructor which enables to initialize the different attributes of the class with default values.
71* @see ~XLVectorCanDriver (void)
72* @see XLVectorCanDriver (unsigned int gHwTypeT, Vaccess gChannelMaskT, unsigned int gCanIdT, unsigned int gBitRateT,int gHwChannelT)
73*/
74
75XLVectorCanDriver::XLVectorCanDriver (void)
76{
77 LOG_INFO("Notice : VECTOR XL CAN Driver used\n");
78 /*
79 gPortHandle = INVALID_PORTHANDLE;
80 gChannelMask = 0x3;
81 gPermissionMask = 0;
82 gCanId = 0x2A9;
83 gBitRate = 500000;
84 gHwType = HWTYPE_CANAC2PCI;
85 gHwChannel = 0;
86 gEventHandle = 0;*/
87
88 initialize("canXL", -1, 0, 0, 500000);
89}
90
91
92void XLVectorCanDriver::displayHardware() {
93 XLdriverConfig driverConfig;
94 traceXLCommand("xlGetDriverConfig", xlGetDriverConfig(&driverConfig));
95
96 LOG_INFO("----------------------------------------------------------");
97 LOG_INFO("- " << setfill('0') << setw(2) << driverConfig.channelCount << " channels Hardware Configuration -");
98 LOG_INFO("----------------------------------------------------------");
99
100 char str[XL_MAX_LENGTH + 1] = "";
101
102 for (unsigned int i = 0; i < driverConfig.channelCount; ++i) {
103 XLchannelConfig channel = driverConfig.channel[i];
104 LOG_INFO("- Ch:" << setfill('0') << setw(2) << channel.channelIndex << ", "
105 << "CM:0x" << hex << setfill('0') << setw(3) << channel.channelMask << ", ");
106
107 strncpy_s(str, channel.name, 23);
108 printf(" %23s,", str);
109 memset(str, 0, sizeof(str));
110
111 if (channel.transceiverType != XL_TRANSCEIVER_TYPE_NONE) {
112 strncpy_s(str, channel.transceiverName, 13);
113 printf("%13s -\n", str);
114 } else {
115 printf(" no Cab! -\n", str);
116 }
117 }
118
119 LOG_INFO("----------------------------------------------------------");
120}
121
122/**
123* Constructor which enables to initialize the different attributes of the class with values given in parameters.
124* @see ~XLVectorCanDriver (void)
125* @see XLVectorCanDriver (void)
126*/
127XLVectorCanDriver::XLVectorCanDriver(const std::string &name, const int hwType, const int hwIndex, const int hwChannel, unsigned long bitrate)
128{
129 initialize(name, hwType, hwIndex, hwChannel, bitrate);
130}
131
132void XLVectorCanDriver::initialize(const std::string &name, const int hwType, const int hwIndex, const int hwChannel, unsigned long bitrate)
133{
134 printf("Notice : VECTOR XL CAN Driver used\n");
135 displayHardware();
136 /*gPortHandle = INVALID_PORTHANDLE;
137 gChannelMask = gChannelMaskT;
138 gPermissionMask = 0;
139 gCanId = gCanIdT;
140 gBitRate = gBitRateT;
141 gHwType = gHwTypeT;
142 gHwChannel = gHwChannelT;
143 gEventHandle = 0;*/
144
145 this->accessMask = xlGetChannelMask(hwType, hwIndex, hwChannel);
146 if(!this->accessMask) {
147 traceXLCommand("xlGetChannelMask", XL_ERR_HW_NOT_PRESENT);
148 } else {
149 traceXLCommand("xlGetChannelMask", XL_SUCCESS);
150 }
151 XLaccess permissionMask = this->accessMask;
152
153 traceXLCommand("xlOpenPort",
154 xlOpenPort(&this->port, const_cast<char*>(name.c_str()), this->accessMask,
155 &permissionMask, RX_QUEUE_SIZE, XL_INTERFACE_VERSION, XL_BUS_TYPE_CAN));
156 if ( this->port == XL_INVALID_PORTHANDLE ) {
157 checkXlStatus(XL_ERR_HW_NOT_PRESENT);
158 }
159
160 if (this->accessMask == permissionMask) {
161 traceXLCommand("xlCanSetChannelBitrate",
162 xlCanSetChannelBitrate(this->port, this->accessMask, bitrate));
163 } else {
164 LOG_DEBUG("No init access");
165 }
166 traceXLCommand("xlSetNotification",
167 xlSetNotification(this->port, &this->msgEvent, QUEUE_LEVEL));
168 traceXLCommand("xlCanSetReceiveMode",
169 xlCanSetReceiveMode(this->port, 1, 1));
170 traceXLCommand("xlActivateChannel",
171 xlActivateChannel(this->port, this->accessMask, XL_BUS_TYPE_CAN,
172 XL_ACTIVATE_RESET_CLOCK));
173}
174
175
176/**
177* Constructor which enables to select the channel and to initialize the different attributes of the class with default values..
178* @see ~XLVectorCanDriver (void)
179* @see XLVectorCanDriver (void)
180*/
181
182XLVectorCanDriver::XLVectorCanDriver(int channel)
183{
184 printf("Notice : VECTOR XL CAN Driver used\n");
185
186 /*
187 gPortHandle = INVALID_PORTHANDLE;
188 gChannelMask = 0x3;
189 gPermissionMask = 0;
190 gCanId = 0x2A9;
191 gBitRate = 1000000;
192 gHwType = HWTYPE_CANAC2PCI;
193 gHwChannel = channel;
194 gEventHandle = 0;
195 */
196
197 initialize("can", 0, 0, channel, 500);
198}
199
200
201
202/**
203* Destructor which clean up the different attributs of the class.
204* @see XLVectorCanDriver (void)
205* @see XLVectorCanDriver (unsigned int gHwTypeT, Vaccess gChannelMaskT, unsigned int gCanIdT, unsigned int gBitRateT,int gHwChannelT)
206*/
207XLVectorCanDriver::~XLVectorCanDriver (void)
208{
209 traceXLCommand("xlDeactivateChannel",
210 xlDeactivateChannel(this->port, this->accessMask));
211 traceXLCommand("xlClosePort",
212 xlClosePort(this->port));
213 this->port = XL_INVALID_PORTHANDLE;
214}
215
216
217/**
218* Member used to initialise the configuration of the CAN Card.
219* @see cleanUpPort (void)
220* @return a Vstatus variable which contain the error code of the function. On success, it return VSUCCESS. On failure, it return Vstatus error code which is defined in VCanD.h
221*/
222short XLVectorCanDriver::initPort (void)
223{
224 /*
225 Vstatus vErr;
226 VsetAcceptance acc;
227
228 // Open the driver
229 vErr = ncdOpenDriver ();
230 if (vErr)
231 {
232 printf ("ERROR:initport %s!\n", ncdGetErrorString (vErr));
233 return vErr;
234 }
235
236 // Select the channel
237 gChannelMask = ncdGetChannelMask (gHwType,0,gHwChannel);
238 if (!gChannelMask)
239 {
240 printf ("ERROR: (initport) Channel not present!\n");
241 printf ("ERROR:(initport) %s!\n", ncdGetErrorString (VERROR));
242 return vErr;
243 }
244
245 // Select the index
246 int gChannelIndex = ncdGetChannelIndex (gHwType,0,gHwChannel);
247 if ( gChannelIndex == -1 )
248 {
249 printf ("ERROR: (initport) Channel not present!\n");
250 printf ("ERROR:(initport) %s!\n", ncdGetErrorString (VERROR));
251 return vErr;
252 }
253
254 // Open a port
255 vErr = ncdOpenPort (&gPortHandle,"PACPUS_CANDriver",gChannelMask,gChannelMask,&gPermissionMask,1024);
256 if (vErr != VSUCCESS)
257 {
258 printf ("ERROR:(init port) %s!\n", ncdGetErrorString (vErr));
259 return vErr;
260 }
261
262 // Only if permission to initialize the channel
263 if (gPermissionMask)
264 {
265 // Set the bus timing
266 vErr = ncdSetChannelBitrate (gPortHandle,gPermissionMask,gBitRate);
267 if (vErr)
268 {
269 printf ("ERROR: %s!\n", ncdGetErrorString (vErr));
270 if (gPortHandle!=INVALID_PORTHANDLE)
271 {
272 ncdClosePort (gPortHandle);
273 gPortHandle = INVALID_PORTHANDLE;
274 }
275 return vErr;
276 }
277 }
278 else if (gBitRate)
279 {
280 printf ("WARNING: No init access! Bitrate ignored.\n");
281 }
282
283 // Enable the TX and disable the TXRQ notifications
284 vErr = ncdSetChannelMode (gPortHandle,gChannelMask,1,0);
285 if (vErr)
286 {
287 printf ("ERROR:(init port) %s!\n", ncdGetErrorString (vErr));
288 if (gPortHandle!=INVALID_PORTHANDLE)
289 {
290 ncdClosePort (gPortHandle);
291 gPortHandle = INVALID_PORTHANDLE;
292 }
293 return vErr;
294 }
295
296 // create a synchronisation object
297 gEventHandle = CreateEvent (NULL, FALSE, FALSE, NULL);
298 vErr = ncdSetNotification (gPortHandle, (unsigned long*)&gEventHandle, 1);
299 if (vErr)
300 {
301 printf ("ERROR(init port): %s!\n", ncdGetErrorString (vErr));
302 ncdDeactivateChannel (gPortHandle, gChannelMask);
303 cleanUpPort ();
304 return vErr;
305 }
306
307 // Open the acceptance filter
308 acc.mask = 0x000; // relevant=1
309 acc.code = 0x000;
310
311 vErr = ncdSetChannelAcceptance (gPortHandle,gChannelMask,&acc);
312 if (vErr)
313 {
314 printf ("ERROR: %s!\n", ncdGetErrorString (vErr));
315 if (gPortHandle!=INVALID_PORTHANDLE)
316 {
317 ncdClosePort (gPortHandle);
318 gPortHandle = INVALID_PORTHANDLE;
319 }
320 return vErr;
321 }
322
323 // Go on bus
324 vErr = ncdActivateChannel (gPortHandle,gChannelMask);
325 if (vErr)
326 {
327 printf ("ERROR: %s!\n", ncdGetErrorString (vErr));
328 ncdDeactivateChannel (gPortHandle, gChannelMask);
329 cleanUpPort ();
330 return vErr;
331 }
332
333 // Reset the clocks of all channels connected to the port
334 vErr = ncdResetClock(gPortHandle);
335 if (vErr)
336 {
337 printf ("ERROR: %s!\n", ncdGetErrorString (vErr));
338 ncdDeactivateChannel (gPortHandle, gChannelMask);
339 cleanUpPort ();
340 return vErr;
341 }
342
343 return VSUCCESS;
344 */
345 traceXLCommand("xlOpenDriver", xlOpenDriver());
346 return 0;
347}
348
349
350/**
351* Member used to clean up the configuration of the CAN Card.
352* @see initPort (void)
353* @return a Vstatus variable which contain the error code of the function. On success, it return VSUCCESS. On failure, it return Vstatus error code which is defined in VCanD.h
354*/
355short XLVectorCanDriver::cleanUpPort (void)
356{
357 /*
358 Vstatus vErr;
359 vErr = ncdDeactivateChannel(gPortHandle, gChannelMask);
360 if (vErr)
361 {
362 printf ("ERROR: (cleanUpPort) Channel not correctly deactivated!\n Driver not correctly closed!\n");
363 printf ("ERROR: %s!\n", ncdGetErrorString (vErr));
364 return vErr;
365 }
366 vErr = ncdClosePort (gPortHandle);
367 if (vErr)
368 {
369 printf ("ERROR: (cleanUpPort) Port not correctly closed!\n Driver not correctly closed!\n");
370 printf ("ERROR: %s!\n", ncdGetErrorString (vErr));
371 return vErr;
372 }
373 gPortHandle = INVALID_PORTHANDLE;
374 vErr = ncdCloseDriver ();
375 if (vErr)
376 {
377 printf ("ERROR: (cleanUpPort) Driver not correctly closed!\n");
378 printf ("ERROR: %s!\n", ncdGetErrorString (vErr));
379 return vErr;
380 }
381
382 return VSUCCESS;
383 */
384 traceXLCommand("xlCloseDriver", xlCloseDriver());
385
386 return 0;
387}
388
389
390/**
391* Member which permit to send a frame on the CAN bus and test if the frame is well acknowledged.
392* @param flags a character which contain the flags of the sent frame.
393* @param dlc a character which defined the number of characters of the sent frame.
394* @param data a table of characters with the data of the sent frame.
395* @see receiveFrame (unsigned char * flags, unsigned char * dlc, unsigned char ** data)
396* @return a Vstatus variable which contain the error code of the function. On success, it return VSUCCESS. On failure, it return Vstatus error code which is defined in VCanD.h
397*/
398//Vstatus XLVectorCanDriver::sendFrame (unsigned char flags, unsigned char dlc, unsigned char * data, int identifiant)
399short XLVectorCanDriver::sendFrame (struct CanFrame frame)
400{
[40]401
402 XLevent e;
[1]403 e.tag = XL_TRANSMIT_MSG;
404 e.tagData.msg.id = frame.id;
405 e.tagData.msg.flags = 0;
406 e.tagData.msg.dlc = frame.dlc;
407 memcpy(e.tagData.msg.data, frame.data, frame.dlc);
[40]408
[1]409 unsigned int count = 1;
410 LOG_DEBUG(xlGetEventString(&e));
411 traceXLCommand("xlCanTransmit",
412 xlCanTransmit(this->port, this->accessMask, &count, &e));
413
[89]414
[1]415
416 return 1;
417}
418
419
420/**
421* Member which permit to receive of a frame on the CAN bus.
422* @param flags a character pointer which contain the flags of the received frame.
423* @param dlc a character pointer which defined the number of characters of the received frame.
424* @param data a pointer of table of characters with the data of the received frame.
425* @see sendFrame (unsigned char flags, unsigned char dlc, unsigned char * data)
426* @return a Vstatus variable which contain the error code of the function. On success, it return VSUCCESS. On failure, it return Vstatus error code which is defined in VCanD.h
427*/
428//Vstatus XLVectorCanDriver::receiveFrame (unsigned char * flags, unsigned char * dlc, unsigned char * data, int * identifiant)
429short XLVectorCanDriver::receiveFrame (struct CanFrame &frame)
430{
431
432
433 XLhandle handle;
434 traceXLCommand("xlSetNotification",
435 xlSetNotification(this->port, &handle, 1));
436 XLevent e;
437 unsigned int count = 1;
438
439 int queueSize;
[89]440
[1]441 traceXLCommand("xlGetReceiveQueueLevel",
442 xlGetReceiveQueueLevel(this->port, &queueSize));
443 if ( queueSize < 1 ) {
444 if (WaitForSingleObject(handle, WAIT_RECEIVING_FRAME_TIMEOUT) == WAIT_TIMEOUT)
445 {
446 LOG_TRACE("waitReceivingFrame : no frame receiving in the last " << WAIT_RECEIVING_FRAME_TIMEOUT/1000 << " seconds.");
447 return 1;
448 }
449 }
450
451 if (xlReceive(this->port, &count, &e) == XL_SUCCESS) {
452 LOG_TRACE(xlGetEventString(&e));
453 //found = (e.tagData.msg.id & id) == id;
454 frame.id = e.tagData.msg.id;
455 frame.dlc = static_cast<uint8_t>(e.tagData.msg.dlc);
456 memcpy(frame.data,e.tagData.msg.data, frame.dlc);
457 return 0;
458 } else {
459 return 1;
460 }
461
[89]462
[1]463}
464
465
466/**
467* Member which wait the reception of a frame on the CAN bus.
468* @see sendFrame (unsigned char flags, unsigned char dlc, unsigned char * data)
469* @see receiveFrame (unsigned char * flags, unsigned char * dlc, unsigned char ** data)
470*/
471void XLVectorCanDriver::waitReceivingFrame(void)
472{
473
474 if (WaitForSingleObject (msgEvent,WAIT_RECEIVING_FRAME_TIMEOUT) == WAIT_TIMEOUT)
475 {
476 LOG_TRACE("waitReceivingFrame - Error : no frame receiving in the " << WAIT_RECEIVING_FRAME_TIMEOUT/1000 << " %d last seconds");
477 }
478 /*
479 if (WaitForSingleObject (gEventHandle,WAIT_RECEIVING_FRAME_TIMEOUT) == WAIT_TIMEOUT)
480 {
481 printf("waitReceivingFrame - Error : no frame receiving in the %d last seconds\n", WAIT_RECEIVING_FRAME_TIMEOUT/1000);
482 }
483 */
484}
485
486/*
487Vstatus XLVectorCanDriver::AcceptId(int id)
488{
489 if(ncdAddAcceptanceRange(gPortHandle,gChannelMask,id,id)!=VSUCCESS)
490 {
491 printf("erreur lors de la configuration du filtre");
492 return VERROR;
493 }
494 else
495 return VSUCCESS;
496}
497*/
498
499
500/*
501Vstatus XLVectorCanDriver::AcceptIdRange(int deb,int fin)
502{
503 if(ncdAddAcceptanceRange(gPortHandle,gChannelMask,deb,fin)!=VSUCCESS)
504 {
505 printf("erreur lors de la configuration du filtre");
506 return VERROR;
507 }
508 else
509 return VSUCCESS;
510}
511*/
Note: See TracBrowser for help on using the repository browser.