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

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

ajout des capteurs CanGateway et Alasca

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