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

Last change on this file since 17 was 2, checked in by DHERBOMEZ Gérald, 11 years ago

correction of minor bugs (include and link). Build on Windows OK.

File size: 18.0 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{
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 Vstatus vErr;
416 Vevent event;
417 Vevent * pEvent = NULL;
418
419 // Create frame to send
420 event.tag = V_TRANSMIT_MSG;
421 event.tagData.msg.id = frame.id;
422 event.tagData.msg.flags = 0;
423 event.tagData.msg.dlc = frame.dlc;
424
425 for (int i = 0; i < frame.dlc; i++)
426 event.tagData.msg.data[i] = frame.data[i];
427
428 // Send the frame
429 vErr = ncdTransmit (gPortHandle, gChannelMask, &event);
430
431 //printf("sendFrame ncdTransmit -- vErr=%d, event=0x%x\n", vErr, event);
432
433 if (vErr==VERR_QUEUE_IS_FULL)
434 {
435 printf("!");
436 }
437
438 else if (vErr)
439 {
440 printf ("ERROR:(send frame) %s!\n", ncdGetErrorString (vErr));
441 // ncdDeactivateChannel (gPortHandle, gChannelMask);
442 // cleanUpPort ();
443 return vErr;
444 }
445
446 return VSUCCESS;
447
448 // Wait the acknowledgement frame
449 waitReceivingFrame();
450
451 // Read the acknowledgement frame in the buffer
452 vErr = ncdReceive1 (gPortHandle,&pEvent);
453 //printf("sendFrame ncdReceive1 -- vErr=%d, pEvent=0x%x\n", vErr, pEvent);
454
455 if ( (pEvent==NULL) && (vErr==VERR_QUEUE_IS_EMPTY) )
456 {
457 printf ("%s\n",ncdGetErrorString (vErr));
458 printf ("%s!\n",ncdGetErrorString (vErr));
459 // ncdDeactivateChannel (gPortHandle, gChannelMask);
460 // cleanUpPort ();
461 return vErr;
462 }
463
464 // If frame is well acknoledged
465 if (pEvent->tagData.msg.flags & 0x40)
466 return VSUCCESS;
467 else
468 {
469 //printf("%x ",pEvent->tagData.msg.flags);
470 //printf (" no acknolegement of frame!\n");
471
472 return VERROR;
473 }*/
474
475 return 1;
476}
477
478
479/**
480* Member which permit to receive of a frame on the CAN bus.
481* @param flags a character pointer which contain the flags of the received frame.
482* @param dlc a character pointer which defined the number of characters of the received frame.
483* @param data a pointer of table of characters with the data of the received frame.
484* @see sendFrame (unsigned char flags, unsigned char dlc, unsigned char * data)
485* @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
486*/
487//Vstatus XLVectorCanDriver::receiveFrame (unsigned char * flags, unsigned char * dlc, unsigned char * data, int * identifiant)
488short XLVectorCanDriver::receiveFrame (struct CanFrame &frame)
489{
490
491
492 XLhandle handle;
493 traceXLCommand("xlSetNotification",
494 xlSetNotification(this->port, &handle, 1));
495 XLevent e;
496 unsigned int count = 1;
497
498 int queueSize;
499 //bool found = false;
500 //DWORD begin = timeGetTime();
501 //while ( !found ) {
502 /*DWORD now = timeGetTime();
503 /DEBUG("begin: %ld, now: %ld", begin, now);
504 if ( now - begin >= timeout ) {
505 return NULL;
506 }
507*/
508 traceXLCommand("xlGetReceiveQueueLevel",
509 xlGetReceiveQueueLevel(this->port, &queueSize));
510 if ( queueSize < 1 ) {
511 if (WaitForSingleObject(handle, WAIT_RECEIVING_FRAME_TIMEOUT) == WAIT_TIMEOUT)
512 {
513 LOG_TRACE("waitReceivingFrame : no frame receiving in the last " << WAIT_RECEIVING_FRAME_TIMEOUT/1000 << " seconds.");
514 return 1;
515 }
516 }
517
518 if (xlReceive(this->port, &count, &e) == XL_SUCCESS) {
519 LOG_TRACE(xlGetEventString(&e));
520 //found = (e.tagData.msg.id & id) == id;
521 frame.id = e.tagData.msg.id;
522 frame.dlc = static_cast<uint8_t>(e.tagData.msg.dlc);
523 memcpy(frame.data,e.tagData.msg.data, frame.dlc);
524 return 0;
525 } else {
526 return 1;
527 }
528 //}
529
530 //return new CanMessage(e);
531
532
533 /*
534 int L ;
535 Vstatus vErr;
536 Vevent * pEvent = NULL;
537
538 do {
539 // Read frame in the buffer
540 ncdGetReceiveQueueLevel( gPortHandle , &L );
541 if( L <= 0 )
542 {
543 if (WaitForSingleObject (gEventHandle,WAIT_RECEIVING_FRAME_TIMEOUT) == WAIT_TIMEOUT)
544 {
545 //printf("no frame receiving in the %d last seconds\n", WAIT_RECEIVING_FRAME_TIMEOUT/1000);
546 return VERR_QUEUE_IS_EMPTY;
547 }
548 }
549
550 vErr = ncdReceive1 (gPortHandle,&pEvent);
551 if( vErr == VERROR )
552 {
553 printf ("receiveframe ERROR - ERROR: %s\n", ncdGetErrorString (vErr));
554 // ncdDeactivateChannel (gPortHandle, gChannelMask);
555 // cleanUpPort ();
556
557 return vErr;
558 }
559
560 } while((( pEvent==NULL ) && ( vErr==VERR_QUEUE_IS_EMPTY )) || ( vErr == VERROR ));
561
562 // Return the flags field, dlc field and data field of the sent frame
563 //frame.flags = pEvent->tagData.msg.flags;
564 frame.dlc = pEvent->tagData.msg.dlc;
565 frame.id = pEvent->tagData.msg.id;
566 if( ( frame.dlc > 8 ) || ( frame.dlc < 0 ))
567 frame.dlc = 8;
568
569 memcpy(frame.data,pEvent->tagData.msg.data, frame.dlc);
570
571 return VSUCCESS;*/
572
573}
574
575
576/**
577* Member which wait the reception of a frame on the CAN bus.
578* @see sendFrame (unsigned char flags, unsigned char dlc, unsigned char * data)
579* @see receiveFrame (unsigned char * flags, unsigned char * dlc, unsigned char ** data)
580*/
581void XLVectorCanDriver::waitReceivingFrame(void)
582{
583
584 if (WaitForSingleObject (msgEvent,WAIT_RECEIVING_FRAME_TIMEOUT) == WAIT_TIMEOUT)
585 {
586 LOG_TRACE("waitReceivingFrame - Error : no frame receiving in the " << WAIT_RECEIVING_FRAME_TIMEOUT/1000 << " %d last seconds");
587 }
588 /*
589 if (WaitForSingleObject (gEventHandle,WAIT_RECEIVING_FRAME_TIMEOUT) == WAIT_TIMEOUT)
590 {
591 printf("waitReceivingFrame - Error : no frame receiving in the %d last seconds\n", WAIT_RECEIVING_FRAME_TIMEOUT/1000);
592 }
593 */
594}
595
596/*
597Vstatus XLVectorCanDriver::AcceptId(int id)
598{
599 if(ncdAddAcceptanceRange(gPortHandle,gChannelMask,id,id)!=VSUCCESS)
600 {
601 printf("erreur lors de la configuration du filtre");
602 return VERROR;
603 }
604 else
605 return VSUCCESS;
606}
607*/
608
609
610/*
611Vstatus XLVectorCanDriver::AcceptIdRange(int deb,int fin)
612{
613 if(ncdAddAcceptanceRange(gPortHandle,gChannelMask,deb,fin)!=VSUCCESS)
614 {
615 printf("erreur lors de la configuration du filtre");
616 return VERROR;
617 }
618 else
619 return VSUCCESS;
620}
621*/
Note: See TracBrowser for help on using the repository browser.