54 ,print_getenv("PCANHwType")\ |
69 ,print_getenv("PCANHwType")\ |
55 ,print_getenv("PCANIO_Port")\ |
70 ,print_getenv("PCANIO_Port")\ |
56 ,print_getenv("PCANInterupt") |
71 ,print_getenv("PCANInterupt") |
57 #endif |
72 #endif |
58 |
73 |
|
74 |
59 static s_BOARD *first_board = NULL; |
75 static s_BOARD *first_board = NULL; |
60 |
|
61 //Create the Event for the first board |
76 //Create the Event for the first board |
62 HANDLE hEvent1 = NULL; |
77 HANDLE hEvent1 = NULL; |
|
78 CRITICAL_SECTION InitLock1; |
|
79 CRITICAL_SECTION InitLock2; |
63 |
80 |
64 |
81 |
65 #ifdef PCAN2_HEADER_ |
82 #ifdef PCAN2_HEADER_ |
66 static s_BOARD *second_board = NULL; |
83 static s_BOARD *second_board = NULL; |
67 HANDLE hEvent2 = NULL; |
84 HANDLE hEvent2 = NULL; |
68 #endif |
85 #endif |
69 |
86 |
70 // Define for rtr CAN message |
87 // Define for rtr CAN message |
71 #define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR |
88 #define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR |
72 |
89 |
73 /***************************************************************************/ |
90 /***************************************************************************/ |
74 int TranslateBaudeRate(char* optarg){ |
91 static int TranslateBaudeRate(char* optarg) |
|
92 { |
75 if(!strcmp( optarg, "1M")) return CAN_BAUD_1M; |
93 if(!strcmp( optarg, "1M")) return CAN_BAUD_1M; |
76 if(!strcmp( optarg, "500K")) return CAN_BAUD_500K; |
94 if(!strcmp( optarg, "500K")) return CAN_BAUD_500K; |
77 if(!strcmp( optarg, "250K")) return CAN_BAUD_250K; |
95 if(!strcmp( optarg, "250K")) return CAN_BAUD_250K; |
78 if(!strcmp( optarg, "125K")) return CAN_BAUD_125K; |
96 if(!strcmp( optarg, "125K")) return CAN_BAUD_125K; |
79 if(!strcmp( optarg, "100K")) return CAN_BAUD_100K; |
97 if(!strcmp( optarg, "100K")) return CAN_BAUD_100K; |
83 if(!strcmp( optarg, "5K")) return CAN_BAUD_5K; |
101 if(!strcmp( optarg, "5K")) return CAN_BAUD_5K; |
84 if(!strcmp( optarg, "none")) return 0; |
102 if(!strcmp( optarg, "none")) return 0; |
85 return 0x0000; |
103 return 0x0000; |
86 } |
104 } |
87 |
105 |
88 UNS8 canInit (s_BOARD *board) |
106 static UNS8 canInit (s_BOARD *board) |
89 { |
107 { |
90 int baudrate; |
108 int baudrate; |
91 int ret = 0; |
109 int ret = 0; |
92 |
110 |
93 #ifdef PCAN2_HEADER_ |
111 #ifdef PCAN2_HEADER_ |
94 // if not the first handler |
112 // if not the first handler |
95 if(second_board == (s_BOARD *)board) { |
113 if(second_board == (s_BOARD *)board) { |
|
114 if(hEvent2==NULL) |
|
115 { /* Create the Event for the first board */ |
|
116 hEvent2 = CreateEvent(NULL, // lpEventAttributes |
|
117 FALSE, // bManualReset |
|
118 FALSE, // bInitialState |
|
119 ""); // lpName |
|
120 InitializeCriticalSection(&InitLock2); |
|
121 } |
|
122 |
|
123 EnterCriticalSection(&InitLock2); |
96 if(baudrate = TranslateBaudeRate(board->baudrate)) |
124 if(baudrate = TranslateBaudeRate(board->baudrate)) |
97 { |
125 { |
98 ret = CAN2_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params); |
126 ret = CAN2_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params); |
99 if(ret != CAN_ERR_OK) |
127 if(ret != CAN_ERR_OK) |
100 return 0; |
128 { |
101 } |
129 LeaveCriticalSection(&InitLock2); |
102 |
130 return 0; |
103 //Create the Event for the first board |
131 } |
104 if(hEvent2 != NULL){ |
|
105 hEvent2 = CreateEvent(NULL, // lpEventAttributes |
|
106 FALSE, // bManualReset |
|
107 FALSE, // bInitialState |
|
108 ""); // lpName |
|
109 } |
132 } |
110 //Set Event Handle for CANReadExt |
133 //Set Event Handle for CANReadExt |
111 CAN2_SetRcvEvent(hEvent2); |
134 CAN2_SetRcvEvent(hEvent2); |
|
135 LeaveCriticalSection(&InitLock2); |
112 } |
136 } |
113 else |
137 else |
114 #endif |
138 #endif |
115 if(first_board == (s_BOARD *)board) { |
139 if(first_board == (s_BOARD *)board) { |
|
140 //Create the Event for the first board |
|
141 if(hEvent1==NULL) |
|
142 { |
|
143 hEvent1 = CreateEvent(NULL, // lpEventAttributes |
|
144 FALSE, // bManualReset |
|
145 FALSE, // bInitialState |
|
146 ""); // lpName |
|
147 InitializeCriticalSection(&InitLock1); |
|
148 } |
|
149 |
|
150 EnterCriticalSection(&InitLock1); |
116 if(baudrate = TranslateBaudeRate(board->baudrate)) |
151 if(baudrate = TranslateBaudeRate(board->baudrate)) |
117 { |
152 { |
118 ret = CAN_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params); |
153 ret = CAN_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params); |
119 if(ret != CAN_ERR_OK) |
154 if(ret != CAN_ERR_OK) |
120 return 0; |
155 { |
121 } |
156 LeaveCriticalSection(&InitLock1); |
122 //Create the Event for the first board |
157 return 0; |
123 if(hEvent1 != NULL){ |
158 } |
124 hEvent1 = CreateEvent(NULL, // lpEventAttributes |
|
125 FALSE, // bManualReset |
|
126 FALSE, // bInitialState |
|
127 ""); // lpName |
|
128 } |
159 } |
129 //Set Event Handle for CANReadExt |
160 //Set Event Handle for CANReadExt |
130 CAN_SetRcvEvent(hEvent1); |
161 CAN_SetRcvEvent(hEvent1); |
|
162 LeaveCriticalSection(&InitLock1); |
131 } |
163 } |
132 return 1; |
164 return 1; |
133 } |
165 } |
134 |
166 |
135 /********* functions which permit to communicate with the board ****************/ |
167 /********* functions which permit to communicate with the board ****************/ |
136 UNS8 __stdcall canReceive_driver (CAN_HANDLE fd0, Message * m) |
168 UNS8 LIBAPI canReceive_driver(CAN_HANDLE fd0, Message * m) |
137 { |
169 { |
|
170 static int HeavyCounter = 0; |
138 int ret=0; |
171 int ret=0; |
139 UNS8 data; |
172 UNS8 data; |
140 TPCANMsg peakMsg; |
173 TPCANMsg peakMsg; |
|
174 #ifdef CAN_READ_EX |
141 TPCANTimestamp peakRcvTime; |
175 TPCANTimestamp peakRcvTime; |
|
176 #endif |
142 DWORD Res; |
177 DWORD Res; |
143 DWORD result; |
178 DWORD result; |
144 // loop until valid message or fatal error |
179 // loop until valid message or fatal error |
145 do{ |
180 do{ |
146 #ifdef PCAN2_HEADER_ |
181 #ifdef PCAN2_HEADER_ |
149 //wait for CAN msg... |
184 //wait for CAN msg... |
150 result = WaitForSingleObject(hEvent2, INFINITE); |
185 result = WaitForSingleObject(hEvent2, INFINITE); |
151 if (result == WAIT_OBJECT_0) |
186 if (result == WAIT_OBJECT_0) |
152 Res = CAN2_ReadEx(&peakMsg, &peakRcvTime); |
187 Res = CAN2_ReadEx(&peakMsg, &peakRcvTime); |
153 // Exit receive thread when handle is no more valid |
188 // Exit receive thread when handle is no more valid |
154 if(Res & CAN_ERR_ILLHANDLE) |
189 if(Res & CAN_ERRMASK_ILLHANDLE) |
155 return 1; |
190 return 1; |
156 } |
191 } |
157 else |
192 else |
158 #endif |
193 #endif |
159 |
194 |
160 // We read the queue looking for messages. |
195 // We read the queue looking for messages. |
161 if(first_board == (s_BOARD *)fd0) { |
196 if(first_board == (s_BOARD *)fd0) |
|
197 { |
|
198 #ifdef VERSION_2 |
162 result = WaitForSingleObject(hEvent1, INFINITE); |
199 result = WaitForSingleObject(hEvent1, INFINITE); |
163 if (result == WAIT_OBJECT_0) |
200 if (result == WAIT_OBJECT_0) |
|
201 #endif |
164 { |
202 { |
|
203 #ifdef CAN_READ_EX |
165 Res = CAN_ReadEx(&peakMsg, &peakRcvTime); |
204 Res = CAN_ReadEx(&peakMsg, &peakRcvTime); |
|
205 #else |
|
206 Res = CAN_Read(&peakMsg); |
|
207 #endif |
166 // Exit receive thread when handle is no more valid |
208 // Exit receive thread when handle is no more valid |
167 if(Res & CAN_ERR_ILLHANDLE) |
209 #ifdef CAN_ERRMASK_ILLHANDLE |
168 return 1; |
210 if(Res & CAN_ERRMASK_ILLHANDLE) return 1; |
|
211 #else |
|
212 if(Res & CAN_ERR_ILLHANDLE) return 1; |
|
213 #endif |
|
214 |
|
215 #ifndef VERSION_2 |
|
216 if(Res != CAN_ERR_OK) |
|
217 result = WaitForSingleObject(hEvent1, 1); //pooling |
|
218 #endif |
169 } |
219 } |
170 } |
220 } |
|
221 #ifdef VERSION_2 |
171 else |
222 else |
172 Res = CAN_ERR_BUSOFF; |
223 Res = CAN_ERR_BUSOFF; |
173 |
224 #endif |
|
225 |
174 // A message was received : we process the message(s) |
226 // A message was received : we process the message(s) |
175 if (Res == CAN_ERR_OK) |
227 if(Res == CAN_ERR_OK) |
176 { |
228 { |
177 // if something different that 11bit or rtr... problem |
229 switch(peakMsg.MSGTYPE) |
178 if (peakMsg.MSGTYPE & ~(MSGTYPE_STANDARD | MSGTYPE_RTR)) |
230 { |
179 { |
231 case MSGTYPE_STATUS: |
180 if (peakMsg.MSGTYPE == CAN_ERR_BUSOFF) |
232 switch(peakMsg.DATA[3]) |
181 { |
233 { |
182 printf ("!!! Peak board read : re-init\n"); |
234 case CAN_ERR_BUSHEAVY: |
183 canInit((s_BOARD*) fd0); |
235 break; |
184 usleep (10000); |
236 case CAN_ERR_BUSOFF: |
185 } |
237 printf ("Peak board read BUSOFF: re-init!!!\n"); |
186 |
238 canInit((s_BOARD*)fd0); |
187 // If status, return status if 29bit, return overrun |
239 usleep(33); |
188 return peakMsg.MSGTYPE == |
240 break; |
189 MSGTYPE_STATUS ? peakMsg.DATA[2] : CAN_ERR_OVERRUN; |
241 } |
190 } |
242 return peakMsg.DATA[3]; /* if something different that 11bit or rtr... problem */ |
191 m->cob_id = peakMsg.ID; |
243 |
192 |
244 case MSGTYPE_STANDARD: /* bits of MSGTYPE_ */ |
193 if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST) /* bits of MSGTYPE_ */ |
245 case MSGTYPE_EXTENDED: |
194 m->rtr = 0; |
246 m->rtr = 0; |
195 else |
247 break; |
196 m->rtr = 1; |
248 |
197 m->len = peakMsg.LEN; /* count of data bytes (0..8) */ |
249 case MSGTYPE_RTR: /* bits of MSGTYPE_ */ |
198 for (data = 0; data < peakMsg.LEN; data++) |
250 m->rtr = 1; |
199 m->data[data] = peakMsg.DATA[data]; /* data bytes, up to 8 */ |
251 break; |
|
252 |
|
253 default: return CAN_ERR_OVERRUN; /* If status, return status if 29bit, return overrun. */ |
|
254 |
|
255 } |
|
256 |
|
257 m->cob_id = peakMsg.ID; |
|
258 if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST) /* bits of MSGTYPE_ */ |
|
259 m->rtr = 0; |
|
260 else |
|
261 m->rtr = 1; |
|
262 m->len = peakMsg.LEN; /* count of data bytes (0..8) */ |
|
263 for (data = 0; data < peakMsg.LEN; data++) |
|
264 m->Data[data] = peakMsg.DATA[data]; /* data bytes, up to 8 */ |
200 #if defined DEBUG_MSG_CONSOLE_ON |
265 #if defined DEBUG_MSG_CONSOLE_ON |
201 MSG("in : "); |
266 MSG("in : "); |
202 print_message(m); |
267 print_message(m); |
203 #endif |
268 #endif |
204 } |
269 } |
211 { |
276 { |
212 printf ("canReceive returned error (%d)\n", Res); |
277 printf ("canReceive returned error (%d)\n", Res); |
213 return 1; |
278 return 1; |
214 } |
279 } |
215 } |
280 } |
216 }while(Res != CAN_ERR_OK); |
281 } while(Res != CAN_ERR_OK); |
217 return 0; |
282 return 0; |
218 } |
283 } |
219 |
284 |
220 /***************************************************************************/ |
285 /***************************************************************************/ |
221 UNS8 __stdcall canSend_driver (CAN_HANDLE fd0, Message const * m) |
286 UNS8 LIBAPI canSend_driver(CAN_HANDLE fd0, Message const *m) |
222 { |
287 { |
223 UNS8 data; |
288 UNS8 data; |
224 DWORD localerrno; |
|
225 TPCANMsg peakMsg; |
289 TPCANMsg peakMsg; |
226 peakMsg.ID = m->cob_id; /* 11/29 bit code */ |
290 peakMsg.ID = m->cob_id; /* 11/29 bit code */ |
227 if (m->rtr == 0) |
291 if (m->rtr == 0) |
228 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST; /* bits of MSGTYPE_ */ |
|
229 else |
|
230 { |
292 { |
231 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR; /* bits of MSGTYPE_ */ |
293 if(peakMsg.ID > 0x7FF) |
232 } |
294 peakMsg.MSGTYPE = MSGTYPE_EXTENDED; /* bits of MSGTYPE_ */ |
|
295 else |
|
296 peakMsg.MSGTYPE = MSGTYPE_STANDARD; /* bits of MSGTYPE_ */ |
|
297 } |
|
298 else |
|
299 peakMsg.MSGTYPE = MSGTYPE_RTR; /* bits of MSGTYPE_ */ |
|
300 |
233 peakMsg.LEN = m->len; |
301 peakMsg.LEN = m->len; |
234 /* count of data bytes (0..8) */ |
302 /* count of data bytes (0..8) */ |
235 for (data = 0; data < m->len; data++) |
303 for (data = 0; data < m->len; data++) |
236 peakMsg.DATA[data] = m->data[data]; /* data bytes, up to 8 */ |
304 peakMsg.DATA[data] = m->Data[data]; /* data bytes, up to 8 */ |
237 |
305 |
238 do |
306 do |
239 { |
307 { |
240 #ifdef PCAN2_HEADER_ |
308 #ifdef PCAN2_HEADER_ |
241 // if not the first handler |
309 // if not the first handler |
242 if(second_board == (s_BOARD *)fd0) |
310 if(second_board == (s_BOARD *)fd0) |
243 { |
311 { |
244 errno = localerrno = CAN2_Write (&peakMsg); |
312 errno = CAN2_Write (&peakMsg); |
245 } |
313 } |
246 else |
314 else |
247 #endif |
315 #endif |
248 if(first_board == (s_BOARD *)fd0) |
316 if(first_board == (s_BOARD *)fd0) |
249 { |
317 { |
250 errno = localerrno = CAN_Write (&peakMsg); |
318 errno = CAN_Write (&peakMsg); |
251 } |
319 } |
252 else |
320 else |
253 goto fail; |
321 goto fail; |
254 if (localerrno) |
322 if (errno) |
255 { |
323 { |
256 if (localerrno == CAN_ERR_BUSOFF) |
324 if (errno == CAN_ERR_BUSOFF) |
257 { |
325 { |
258 printf ("!!! Peak board write : re-init\n"); |
326 printf ("!!! Peak board write : re-init\n"); |
259 canInit((s_BOARD*)fd0); |
327 canInit((s_BOARD*)fd0); |
260 usleep (10000); |
328 usleep (10000); |
261 } |
329 } |
262 usleep (1000); |
330 usleep (1000); |
263 } |
331 } |
264 } |
332 } |
265 while (localerrno != CAN_ERR_OK); |
333 while (errno != CAN_ERR_OK); |
266 #if defined DEBUG_MSG_CONSOLE_ON |
334 #if defined DEBUG_MSG_CONSOLE_ON |
267 MSG("out : "); |
335 MSG("out : "); |
268 print_message(m); |
336 print_message(m); |
269 #endif |
337 #endif |
270 return 0; |
338 return 0; |
271 fail: |
339 fail: |
272 return 1; |
340 return 1; |
273 } |
341 } |
274 |
342 |
275 /***************************************************************************/ |
343 /***************************************************************************/ |
276 UNS8 __stdcall canChangeBaudRate_driver( CAN_HANDLE fd, char* baud) |
344 UNS8 LIBAPI canChangeBaudRate_driver(CAN_HANDLE fd, char* baud) |
277 { |
345 { |
278 printf("canChangeBaudRate not yet supported by this driver\n"); |
346 printf("canChangeBaudRate not yet supported by this driver\n"); |
279 return 0; |
347 return 0; |
280 } |
348 } |
281 |
349 |
282 /***************************************************************************/ |
350 /***************************************************************************/ |
283 CAN_HANDLE __stdcall canOpen_driver (s_BOARD * board) |
351 LIBPUBLIC CAN_HANDLE LIBAPI canOpen_driver(s_BOARD * board) |
284 { |
352 { |
285 char busname[64]; |
|
286 char* pEnd; |
353 char* pEnd; |
287 int ret; |
354 int ret; |
288 |
355 |
289 //printf ("Board Busname=%d.\n",strtol(board->busname, &pEnd,0)); |
356 //printf ("Board Busname=%d.\n",strtol(board->busname, &pEnd,0)); |
290 if (strtol(board->busname, &pEnd,0) == 0) |
357 if (strtol(board->busname, &pEnd,0) == 0) |
306 } |
373 } |
307 #endif |
374 #endif |
308 return NULL; |
375 return NULL; |
309 } |
376 } |
310 |
377 |
|
378 |
311 /***************************************************************************/ |
379 /***************************************************************************/ |
312 int __stdcall canClose_driver (CAN_HANDLE fd0) |
380 int LIBAPI canClose_driver(CAN_HANDLE fd0) |
313 { |
381 { |
314 #ifdef PCAN2_HEADER_ |
382 #ifdef PCAN2_HEADER_ |
315 // if not the first handler |
383 // if not the first handler |
316 if(second_board == (s_BOARD *)fd0) |
384 if(second_board == (s_BOARD *)fd0) |
317 { |
385 { |
318 CAN2_SetRcvEvent(NULL); |
386 CAN2_SetRcvEvent(NULL); |
319 CAN2_Close (); |
387 CAN2_Close (); |
320 if(hEvent2) |
388 if(hEvent2) |
321 { |
389 { |
322 SetEvent(hEvent2); |
390 SetEvent(hEvent2); |
323 CloseHandle(hEvent2); |
391 CloseHandle(hEvent2); |
324 hEvent2 = NULL; |
392 hEvent2 = NULL; |
325 } |
393 } |
326 second_board = (s_BOARD *)NULL; |
394 second_board = (s_BOARD *)NULL; |
327 }else |
395 }else |
328 #endif |
396 #endif |
329 if(first_board == (s_BOARD *)fd0) |
397 if(first_board == (s_BOARD *)fd0) |
330 { |
398 { |
331 CAN_SetRcvEvent(NULL); |
399 CAN_SetRcvEvent(NULL); |
332 CAN_Close (); |
400 CAN_Close (); |
333 if(hEvent1) |
401 if(hEvent1) |
334 { |
402 { |
335 SetEvent(hEvent1); |
403 SetEvent(hEvent1); |
336 CloseHandle(hEvent1); |
404 CloseHandle(hEvent1); |
337 hEvent1 = NULL; |
405 hEvent1 = NULL; |
338 } |
406 } |
339 first_board = (s_BOARD *)NULL; |
407 first_board = (s_BOARD *)NULL; |
340 } |
408 } |
341 return 0; |
409 return 0; |
342 } |
410 } |