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

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

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

File size: 15.1 KB
Line 
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
13#include "Pacpus/kernel/Log.h"
14#include "../CanFrame.h"
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{
401
402 XLevent e;
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);
408
409 unsigned int count = 1;
410 LOG_DEBUG(xlGetEventString(&e));
411 traceXLCommand("xlCanTransmit",
412 xlCanTransmit(this->port, this->accessMask, &count, &e));
413
414
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;
440
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
462
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.