]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/unican_cl2.c
One of many steps to support Unicontrols CAN cards.
[lincan.git] / lincan / src / unican_cl2.c
1 /******************************************************************************\r
2 \r
3 Cl2.C - PCAN and VCAN cards hardware access library\r
4 """""\r
5                    (C) Copyright 1997   Unicontrols a.s.\r
6 \r
7 PROJEKT            :    CANopen\r
8 AUTOR              :    F.Spurny\r
9 FIRMA              :    CVUT FEL, Dept. of Measurement\r
10 \r
11 DULEZITE UPOZORNENI:\r
12 \r
13 ARCHIVACNI INFORMACE:\r
14 Log: unican_cl2.c,v\r
15 \r
16 12.12.2000, J.B., cl2_receive_data - time stamp for even number of bytes corr.\r
17 26.8.1998 - cl2_buf_size - corrected, new function return code CL2_BAD_PARAM\r
18             cl2_clr_async_buffer - corrected\r
19 \r
20 ===============================================================================\r
21 \r
22 UCEL A FUNKCE:\r
23 \r
24 ******************************************************************************/\r
25 \r
26 /* Constnt used by CL2 functions */\r
27 #define CL2_TMP_RF                0x0800\r
28 #define CL2_TMP_EX                0x0400\r
29 #define CL2_TMP_EX2               0x0004\r
30 #define CL2_TMP_EXHIGH            0x80000000L\r
31 \r
32 \r
33 /* includes */\r
34 #include "../include/canmsg.h"\r
35 #include "../include/unican_types.h"\r
36 #include "../include/unican_cl2.h"\r
37 \r
38 \r
39 /*******************************************************************************\r
40 * cl2_init_card - initialize card to default parameters\r
41 * """""""""""""\r
42 *\r
43 * Command installs card. The data in sCAN_CARD structure pointed\r
44 * by *card are initialized to their predefined default values.\r
45 * Command must be called before any operation with sCAN_CARD\r
46 * structure.\r
47 *\r
48 * RETURNS:\r
49 *   CL2_OK - command completed succesfuly\r
50 *\r
51 */\r
52 eCL2_RESULT cl2_init_card\r
53    (\r
54    sCAN_CARD *card,     /* Pointer to card structure */\r
55    void *baseAddress,   /* Card base address pointer */\r
56    U16 intNumber        /* Card interrupt number */\r
57    )\r
58    {\r
59    int i;\r
60 \r
61    card->intNumber = intNumber;\r
62    card->baseAddressPtr = (U8*)baseAddress;\r
63    card->rxBufBase = card->baseAddressPtr + CL2_RX_BUFFER_DEFAULT;\r
64    card->asyncTxBufBase = card->baseAddressPtr + CL2_ASYNC_BUFFER_DEFAULT;\r
65    card->syncTxBufBase = card->baseAddressPtr + CL2_SYNC_BUFFER_DEFAULT;\r
66    card->rxBufPtr = card->rxBufBase;\r
67    card->asyncTxBufPtr = card->asyncTxBufBase;\r
68    card->syncTxBufPtr = card->syncTxBufBase;\r
69    card->commandRegister = card->baseAddressPtr+CL2_COMMAND_REGISTER;\r
70    card->dataPtr = card->baseAddressPtr + CL2_DATA_BUFFER;\r
71    card->rxBufSize = CL2_RX_BUFFER_SIZE;\r
72    card->syncTxBufSize = CL2_TX_SYNC_BUFFER_SIZE;\r
73    card->asyncTxBufSize = CL2_TX_ASYNC_BUFFER_SIZE;\r
74    card->status = 0;\r
75    for ( i = 0; i < 10; i++ ) card->rtrSub[i] = 0xFFFFFFFFL;\r
76    return CL2_OK;\r
77    } /* cl2_init_card */\r
78 \r
79 \r
80 /*******************************************************************************\r
81 * cl2_test_card - test card\r
82 * """""""""""""\r
83 *\r
84 * Test whether the card is installed in system and working properly\r
85 * or not. If this function fails (return value is CL2_HW_FAILURE)\r
86 * check if the card is present and card base address.\r
87 *\r
88 * RETURNS:\r
89 *   CL2_OK - card is present and working properly\r
90 *   CL2_HW_FAILURE - card not found or card error\r
91 *\r
92 */\r
93 eCL2_RESULT cl2_test_card\r
94    (\r
95    sCAN_CARD *card           /* Pointer to card structure */\r
96    )\r
97    {\r
98    BOOLEAN1 isAA = FALSE, is55 = FALSE;\r
99    int i;\r
100    U16 volatile tmpWord;\r
101 \r
102    /* timeout for card testing - 1000 read cycles */\r
103    for ( i = 0; i < 10000; i++ )\r
104    {\r
105      if ( isAA && is55 ) return CL2_OK;\r
106      tmpWord = *((U16*)(card->baseAddressPtr));\r
107      if ( (tmpWord & 0x00FF) == 0x00AA ) isAA = TRUE;\r
108      if ( (tmpWord & 0x00FF) == 0x0055 ) is55 = TRUE;\r
109    }\r
110 \r
111   return CL2_HW_FAILURE;\r
112    } /* cl2_test_card */\r
113 \r
114 \r
115 /*******************************************************************************\r
116 * cl2_reset_card - reset card\r
117 * """"""""""""""\r
118 *\r
119 * Card pointed by *card gets hardware reset. This command resets\r
120 * card processor, card settings are restored to their default\r
121 * values.\r
122 *\r
123 * RETURNS:\r
124 *   CL2_OK - command completed successfuly\r
125 *\r
126 */\r
127 eCL2_RESULT cl2_reset_card\r
128    (\r
129    sCAN_CARD *card           /* Pointer to card structure */\r
130    )\r
131    {\r
132    *((U16*)(card->baseAddressPtr + CL2_RESET_REGISTER)) = 0x0000;\r
133    return CL2_OK;\r
134    } /* cl2_reset_card */\r
135 \r
136 \r
137 /*******************************************************************************\r
138 * cl2_get_version - read card version\r
139 * """""""""""""""\r
140 *\r
141 * Fucntion reads a value from card version register.\r
142 *\r
143 * RETURNS:\r
144 *   CL2_OK - command completed successfuly\r
145 *\r
146 */\r
147 eCL2_RESULT cl2_get_version\r
148    (\r
149    sCAN_CARD *card,            /* Pointer to card structure */\r
150    U16 *version                /* returns card version */\r
151    )\r
152    {\r
153    *version = *((U16*)(card->baseAddressPtr + CL2_VERSION_REGISTER));\r
154    return CL2_OK;\r
155    } /* cl2_get_version */\r
156 \r
157 \r
158 /*******************************************************************************\r
159 * cl2_gen_interrupt - request for interrupt\r
160 * """""""""""""""""\r
161 *\r
162 * CAN card is requested to generate interrupt if there is any reason\r
163 * to do it. The condition for interrupt generation is defined by\r
164 * cl2_int_mode command.\r
165 *\r
166 * RETURNS:\r
167 *   CL2_OK - command completed successfuly\r
168 *\r
169 */\r
170 eCL2_RESULT cl2_gen_interrupt\r
171    (\r
172    sCAN_CARD *card           /* Pointer to card structure */\r
173    )\r
174    {\r
175    *((U16*)(card->baseAddressPtr + CL2_GEN_INT_REGISTER)) = 0x0000;\r
176    return CL2_OK;\r
177    } /* cl2_gen_interrupt */\r
178 \r
179 \r
180 /*******************************************************************************\r
181 * cl2_start_it - start inhibit time\r
182 * """"""""""""\r
183 *\r
184 * Command starts interrupt inhibit time. If there is any reason for\r
185 * interrupt geneation, the card generates interrupt after end of\r
186 * specified time interval. Time interval is set by cl2_set_iit command.\r
187 *\r
188 * RETURNS:\r
189 *   CL2_OK - command completed successfuly\r
190 *\r
191 */\r
192 eCL2_RESULT cl2_start_it\r
193    (\r
194    sCAN_CARD *card           /* Pointer to card structure */\r
195    )\r
196    {\r
197    *((U16*)(card->baseAddressPtr + CL2_START_IT_REGISTER)) = 0x0000;\r
198    return CL2_OK;\r
199    } /* cl2_start_it */\r
200 \r
201 \r
202 /*******************************************************************************\r
203 * cl2_clear_interrupt - clear interrupt\r
204 * """""""""""""""""""\r
205 *\r
206 * Comand clears interrupt (IRQ) generated by a card.\r
207 *\r
208 * RETURNS:\r
209 *   CL2_OK - command completed successfuly\r
210 *\r
211 */\r
212 eCL2_RESULT cl2_clear_interrupt\r
213    (\r
214    sCAN_CARD *card           /* Pointer to card structure */\r
215    )\r
216    {\r
217    *((U16*)(card->baseAddressPtr + CL2_CLEAR_INT_REGISTER)) = 0x0000;\r
218    return CL2_OK;\r
219    } /* cl2_clear_interrupt */\r
220 \r
221 \r
222 /*******************************************************************************\r
223 * cl2_int_mode - set interrupt mode\r
224 * """"""""""""\r
225 *\r
226 * Command controls, which event will generate interrupt. Constants\r
227 * CL2_INT_XXXX are used for setting of interrupt mode.\r
228 *\r
229 * RETURNS:\r
230 *   CL2_OK - command completed successfuly\r
231 *   CL2_BAD_PARAM - bad command parameter\r
232 *   CL2_COMMAND_BUSY - previous command not completed\r
233 *\r
234 */\r
235 eCL2_RESULT cl2_int_mode\r
236    (\r
237    sCAN_CARD *card,            /* Pointer to card structure */\r
238    U16 mode                    /* Interrupt mode */\r
239    )\r
240    {\r
241    if ( mode > INT_MODE_ALL ) return CL2_BAD_PARAM;\r
242    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
243       return CL2_COMMAND_BUSY;\r
244    *((U16*)card->dataPtr) = mode;\r
245    *((U16*)card->commandRegister) = ((U16)cmCL2_INT_MODE + CL2_COMMAND_VALID);\r
246    return CL2_OK;\r
247    } /* cl2_int_mode */\r
248 \r
249 \r
250 /*******************************************************************************\r
251 * cl2_iit_mode - inhibit interrupt time mode\r
252 * """"""""""""\r
253 *\r
254 * Command enables/disables inhibit interupt time mode.\r
255 *\r
256 * RETURNS:\r
257 *   CL2_OK - command completed successfuly\r
258 *   CL2_COMMAND_BUSY - previous command not completed\r
259 *\r
260 */\r
261 eCL2_RESULT cl2_iit_mode\r
262    (\r
263    sCAN_CARD *card,            /* Pointer to card structure */\r
264    BOOLEAN1 onoff              /* IIT mode - TRUE=on, FALSE=off */\r
265    )\r
266    {\r
267    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID ) return\r
268       CL2_COMMAND_BUSY;\r
269    *((U16*)card->dataPtr) = (U16)onoff;\r
270    *((U16*)card->commandRegister) = ((U16)cmCL2_IIT_MODE + CL2_COMMAND_VALID);\r
271    return CL2_OK;\r
272    } /* cl2_iit_mode */\r
273 \r
274 \r
275 /*******************************************************************************\r
276 * cl2_sync_mode - sync mode\r
277 * """""""""""""\r
278 *\r
279 * Command enables/disables transmission of SYNC frames.\r
280 *\r
281 * RETURNS:\r
282 *   CL2_OK - command completed successfuly\r
283 *   CL2_COMMAND_BUSY - previous command not completed\r
284 *\r
285 */\r
286 eCL2_RESULT cl2_sync_mode\r
287    (\r
288    sCAN_CARD *card,            /* Pointer to card structure */\r
289    BOOLEAN1 onoff              /* Sync mode - TRUE=on, FALSE=off */\r
290    )\r
291    {\r
292    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
293       return CL2_COMMAND_BUSY;\r
294    *((U16*)card->dataPtr) = (U16)onoff;\r
295    *((U16*)card->commandRegister) = ((U16)cmCL2_SYNC_MODE + CL2_COMMAND_VALID);\r
296    return CL2_OK;\r
297    } /* cl2_sync_mode */\r
298 \r
299 \r
300 /*******************************************************************************\r
301 * cl2_rtr_mode - rtr mode\r
302 * """"""""""""\r
303 *\r
304 * Command enables/disables automatic transmission of RTR frames\r
305 *\r
306 * RETURNS:\r
307 *   CL2_OK - command completed successfuly\r
308 *   CL2_COMMAND_BUSY - previous command not completed\r
309 *\r
310 */\r
311 eCL2_RESULT cl2_rtr_mode\r
312    (\r
313    sCAN_CARD *card,            /* Pointer to card structure */\r
314    BOOLEAN1 onoff              /* RTR mode - TRUE=on, FALSE=off */\r
315    )\r
316    {\r
317    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
318       return CL2_COMMAND_BUSY;\r
319    *((U16*)card->dataPtr) = (U16)onoff;\r
320    *((U16*)card->commandRegister) = ((U16)cmCL2_RTR_MODE + CL2_COMMAND_VALID);\r
321    return CL2_OK;\r
322    } /* cl2_rtr_mode */\r
323 \r
324 \r
325 /*******************************************************************************\r
326 * cl2_buf_size - size of synchronous queue\r
327 * """"""""""""\r
328 *\r
329 * Command sets the size of synchronous send buffer. The size is\r
330 * in numbers of messages. Default buffer size is 32 messages.\r
331 * The sum of synchronous_buffer_size and asynchronous_buffer_size\r
332 * is constant and equal to 64. So, if the size od synchronous\r
333 * buffer increases, the size of asynchronous buffer decreases and\r
334 * vice versa.\r
335 * NOTE: 1 message = 16 bytes\r
336 *\r
337 * RETURNS:\r
338 *   CL2_OK - command completed successfully\r
339 *   CL2_COMMAND_BUSY - previous command not completed\r
340 *   CL2_BAD_PARAM - bad command parameter (bufSize>64)\r
341 *\r
342 */\r
343 eCL2_RESULT cl2_buf_size\r
344    (\r
345    sCAN_CARD *card,            /* Pointer to card structure */\r
346    U16 bufSize                 /* Size of synchronous buffer */\r
347    )\r
348    {\r
349    if ( bufSize > 64 ) return CL2_BAD_PARAM;\r
350    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
351       return CL2_COMMAND_BUSY;\r
352    *((U16*)card->dataPtr) = bufSize;\r
353    *((U16*)card->commandRegister) = ((U16)cmCL2_BUF_SIZE + CL2_COMMAND_VALID);\r
354    card->syncTxBufSize = bufSize;\r
355    card->asyncTxBufSize = 64 - bufSize;\r
356    card->syncTxBufPtr = card->syncTxBufBase;\r
357    card->asyncTxBufPtr = card->asyncTxBufBase = card->syncTxBufBase+bufSize*16;\r
358    return CL2_OK;\r
359    } /* cl2_buf_size */\r
360 \r
361 \r
362 /*******************************************************************************\r
363 * cl2_set_iit - set value of inhibit interrupt time\r
364 * """""""""""\r
365 *\r
366 * Command sets value of inhibit interrupt time. If inhibit\r
367 * interrupt time mode is enabled and started, generation of\r
368 * interrupt (IRQ) is disabled during this time period.\r
369 * Inhibit interrupt time can be set from 100 us to 6.5535 s\r
370 *\r
371 * RETURNS:\r
372 *   CL2_OK - command completed successfuly\r
373 *   CL2_COMMAND_BUSY - previous command not completed\r
374 *\r
375 */\r
376 eCL2_RESULT cl2_set_iit\r
377    (\r
378    sCAN_CARD *card,            /* Pointer to card structure */\r
379    U16 iit                     /* time period in x100 us */\r
380    )\r
381    {\r
382    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
383       return CL2_COMMAND_BUSY;\r
384    *((U16*)card->dataPtr) = iit;\r
385    *((U16*)card->commandRegister) = ((U16)cmCL2_SET_IIT + CL2_COMMAND_VALID);\r
386    return CL2_OK;\r
387    } /* cl2_set_iit */\r
388 \r
389 \r
390 /*******************************************************************************\r
391 * cl2_start_firmware - start firmware\r
392 * """"""""""""""""""\r
393 *\r
394 * Command starts card firmware\r
395 *\r
396 * RETURNS:\r
397 *   CL2_OK - command completed successfuly\r
398 *   CL2_COMMAND_BUSY - previous command not completed\r
399 *\r
400 */\r
401 eCL2_RESULT cl2_start_firmware\r
402    (\r
403    sCAN_CARD *card            /* Pointer to card structure */\r
404    )\r
405    {\r
406    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
407       return CL2_COMMAND_BUSY;\r
408    *((U16*)card->commandRegister) = ((U16)cmCL2_START_FIRMWARE +\r
409                                     CL2_COMMAND_VALID);\r
410    return CL2_OK;\r
411    } /* cl2_start_firmware */\r
412 \r
413 \r
414 /*******************************************************************************\r
415 * cl2_set_rec_mode - set receive mode\r
416 * """"""""""""""""\r
417 *\r
418 * Command sets card receive mode. This enable reception of standard\r
419 * or extended frames according to CAN 2.0A and 2.0B specifications.\r
420 * If value of mode is TRUE, card receives extended frames, if mode\r
421 * is FALSE, card receives standard massage format (default).\r
422 *\r
423 * RETURNS:\r
424 *   CL2_OK - command completed successfuly\r
425 *   CL2_COMMAND_BUSY - previous command not completed\r
426 *\r
427 */\r
428 eCL2_RESULT cl2_set_rec_mode\r
429    (\r
430    sCAN_CARD *card,           /* Pointer to card structure */\r
431    BOOLEAN1 mode              /* Mode - TRUE=ext, FALSE=std */\r
432    )\r
433    {\r
434    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
435       return CL2_COMMAND_BUSY;\r
436    *((U16*)card->dataPtr) = (U16)mode;\r
437    *((U16*)card->commandRegister) = ((U16)cmCL2_SET_REC_MODE +\r
438                                     CL2_COMMAND_VALID);\r
439    return CL2_OK;\r
440    } /* cl2_set_rec_mode */\r
441 \r
442 \r
443 /*******************************************************************************\r
444 * cl2_clr_rx_buffer - clear RX buffer\r
445 * """""""""""""""""\r
446 *\r
447 * Command clears receive (rx) buffer. All messages stored in\r
448 * rx buffer will be lost.\r
449 *\r
450 * RETURNS:\r
451 *   CL2_OK - command completed successfuly\r
452 *   CL2_COMMAND_BUSY - previous command not completed\r
453 *\r
454 */\r
455 eCL2_RESULT cl2_clr_rx_buffer\r
456    (\r
457    sCAN_CARD *card           /* Pointer to card structure */\r
458    )\r
459    {\r
460    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
461       return CL2_COMMAND_BUSY;\r
462    card->rxBufPtr = card->rxBufBase;\r
463    *((U16*)card->commandRegister) = ((U16)cmCL2_CLR_RX_BUFFER +\r
464                                      CL2_COMMAND_VALID);\r
465    return CL2_OK;\r
466    } /* cl2_clr_rx_buffer */\r
467 \r
468 \r
469 /*******************************************************************************\r
470 * cl2_clr_sync_buffer - clear synchronous buffer\r
471 * """""""""""""""""""\r
472 *\r
473 * Command clears synchronous send buffer. All messages stored\r
474 * in synchronous buffer will be lost.\r
475 *\r
476 * RETURNS:\r
477 *   CL2_OK - command completed successfuly\r
478 *   CL2_COMMAND_BUSY - previous command not completed\r
479 *\r
480 */\r
481 eCL2_RESULT cl2_clr_sync_buffer\r
482    (\r
483    sCAN_CARD *card            /* Pointer to card structure */\r
484    )\r
485    {\r
486    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
487       return CL2_COMMAND_BUSY;\r
488    card->syncTxBufPtr = card->syncTxBufBase;\r
489    *((U16*)card->commandRegister) = ((U16)cmCL2_CLR_SYNC_BUFFER +\r
490                                     CL2_COMMAND_VALID);\r
491    return CL2_OK;\r
492    } /* cl2_clr_sync_buffer */\r
493 \r
494 \r
495 /*******************************************************************************\r
496 * cl2_clr_async_buffer - clear asynchronous buffer\r
497 * """"""""""""""""""""\r
498 *\r
499 * Command clears asynchronnous send buffer. All messages stored\r
500 * in async buffer will be lost.\r
501 *\r
502 * RETURNS:\r
503 *   CL2_OK - command completed successfuly\r
504 *   CL2_COMMAND_BUSY - previous command not completed\r
505 *\r
506 */\r
507 eCL2_RESULT cl2_clr_async_buffer\r
508    (\r
509    sCAN_CARD *card            /* Pointer to card structure */\r
510    )\r
511    {\r
512    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
513       return CL2_COMMAND_BUSY;\r
514    card->asyncTxBufPtr = card->syncTxBufBase + card->syncTxBufSize*16;\r
515    *((U16*)card->commandRegister) = ((U16)cmCL2_CLR_ASYNC_BUFFER +\r
516                                     CL2_COMMAND_VALID);\r
517    return CL2_OK;\r
518    } /* cl2_clr_async_buffer */\r
519 \r
520 \r
521 /*******************************************************************************\r
522 * cl2_send_time_sync - send time synchronization\r
523 * """"""""""""""""""\r
524 *\r
525 * Command forces the card to start the High Resolution Synchronization\r
526 * Protocol according to the CANopen Communication profile. The SYNC\r
527 * mode has to be enabled (cl2_sync_mode) otherwise this command has\r
528 * no effect.\r
529 *\r
530 * RETURNS:\r
531 *   CL2_OK - command completed successfuly\r
532 *   CL2_COMMAND_BUSY - previous command not completed\r
533 *\r
534 */\r
535 eCL2_RESULT cl2_send_time_sync\r
536    (\r
537    sCAN_CARD *card             /* Pointer to card structure */\r
538    )\r
539    {\r
540    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID ) return\r
541       CL2_COMMAND_BUSY;\r
542    *((U16*)card->commandRegister) = ((U16)cmCL2_SEND_TIME_SYNC +\r
543                                     CL2_COMMAND_VALID);\r
544    return CL2_OK;\r
545    } /* cl2_send_time_sync */\r
546 \r
547 \r
548 /*******************************************************************************\r
549 * cl2_set_time_cobid - set time COB-ID\r
550 * """"""""""""""""""\r
551 *\r
552 * Command sets the COB-ID for high resolution synchronization\r
553 * frame. The synchronization can be then made by means of\r
554 * cl2_send_time_sync command.\r
555 *\r
556 * RETURNS:\r
557 *   CL2_OK - command completed successfuly\r
558 *   CL2_COMMAND_BUSY - previous command not completed\r
559 *\r
560 */\r
561 eCL2_RESULT cl2_set_time_cobid\r
562    (\r
563    sCAN_CARD *card,           /* Pointer to card structure */\r
564    U32 COBID                  /* HRS frame COB-ID */\r
565    )\r
566    {\r
567    U16 cobidL, cobidH;\r
568    U16 *ptr = (U16 *)card->dataPtr;\r
569 \r
570    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
571       return CL2_COMMAND_BUSY;\r
572 \r
573    if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */\r
574    { /* 2.0B frame */\r
575      COBID <<= 3;\r
576      cobidL = (U16)(COBID & 0x0000FFFFL);\r
577      cobidH = (U16)((COBID & 0xFFFF0000L)>>16);\r
578      cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));\r
579      *ptr++ = cobidH;\r
580      cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));\r
581      *ptr++ = cobidL;\r
582      *ptr = CL2_TMP_EX2;\r
583    }\r
584    else\r
585    { /* 2.0A frame */\r
586      COBID <<= 5;\r
587      cobidH = (U16)(COBID & 0x0000FFFFL);\r
588      cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));\r
589      *ptr++ = cobidH;\r
590      *ptr++ = 0;\r
591      *ptr = 0;\r
592    }\r
593 \r
594    *((U16*)card->commandRegister) = ((U16)cmCL2_SET_TIME_COBID +\r
595                                      CL2_COMMAND_VALID);\r
596    return CL2_OK;\r
597    } /* cl2_set_time_cobid */\r
598 \r
599 \r
600 /*******************************************************************************\r
601 * cl2_set_receive_limit - set limit for receive signaling\r
602 * """""""""""""""""""""\r
603 *\r
604 * Command is used to set the receive limit signalized by bit\r
605 * RL (in CL2.H CL2_X_DATA_IN_RBUF) of the Status Register.\r
606 * This bit is set when more then the limit number of frames\r
607 * was received since the last interrupt was generated (in interrupt\r
608 * mode) or since the Status Register was last time read.\r
609 *\r
610 * RETURNS:\r
611 *   CL2_OK\r
612 *   CL2_COMMAND_BUSY - previous command not completed\r
613 *   CL2_BAD_PARAM - bad command parameter\r
614 */\r
615 eCL2_RESULT cl2_set_receive_limit\r
616    (\r
617    sCAN_CARD *card,  /* pointer to card structure */\r
618    U16 limit         /* limit of messages in receive buffer */\r
619    )\r
620    {\r
621    if ( limit > 127 ) return CL2_BAD_PARAM;\r
622    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
623       return CL2_COMMAND_BUSY;\r
624    *((U16*)card->dataPtr) = limit;\r
625    *((U16*)card->commandRegister) = ((U16)cmCL2_SET_RECEIVE_LIMIT +\r
626                                     CL2_COMMAND_VALID);\r
627    return CL2_OK;\r
628    } /* cl2_set_receive_limit */\r
629 \r
630 \r
631 /*******************************************************************************\r
632 * cl2_download_rtr_list - download rtr list\r
633 * """""""""""""""""""""\r
634 *\r
635 * Command downloads a list of up to 64 RTR frames. These frames are\r
636 * periodically transmitted by the card. The parameters, how often\r
637 * frames are send and in which SYNC period is defined by period and\r
638 * subperiod in sRTR_FRAME structure.\r
639 *\r
640 * RETURNS:\r
641 *   CL2_OK - command completed successfuly\r
642 *   CL2_COMMAND_BUSY - previous command not completed\r
643 *   CL2_BAD_PARAM - bad command parameter\r
644 *\r
645 */\r
646 eCL2_RESULT cl2_download_rtr_list\r
647    (\r
648    sCAN_CARD *card,           /* Pointer to card structure */\r
649    sRTR_LIST *rtrList         /* RTR list */\r
650    )\r
651    {\r
652    U16 *ptrTmp = (U16*)card->dataPtr;\r
653    sRTR_FRAME *ptrRTR = rtrList->data;\r
654    U16 tmpU16;\r
655    U32 COBID;\r
656    U16 cobidH, cobidL, i;\r
657 \r
658    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID ) return\r
659       CL2_COMMAND_BUSY;\r
660    if ( rtrList->nb > 64 ) return CL2_BAD_PARAM;\r
661 \r
662    *ptrTmp++ = (U16)rtrList->nb;\r
663    for ( i = 0; i < rtrList->nb; i++ )\r
664    {\r
665    if ( ptrRTR->period < ptrRTR->subperiod ) return CL2_BAD_PARAM;\r
666    if ( ptrRTR->subperiod == 0 ) ptrRTR->subperiod = 1;\r
667    tmpU16 = (ptrRTR->period & 0x00FF) + ((ptrRTR->subperiod & 0x00FF)<<8);\r
668    *ptrTmp++ = tmpU16;\r
669    COBID = ptrRTR->cob_id;\r
670 \r
671    if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */\r
672    { /* 2.0B frame */\r
673      COBID <<= 3;\r
674      cobidL = (U16)(COBID & 0x0000FFFFL);\r
675      cobidH = (U16)((COBID & 0xFFFF0000L)>>16);\r
676      cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));\r
677      *ptrTmp++ = cobidH;\r
678      cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));\r
679      *ptrTmp++ = cobidL;\r
680    }\r
681    else\r
682    { /* 2.0A frame */\r
683      COBID <<= 5;\r
684      cobidH = (U16)(COBID & 0x0000FFFFL);\r
685      cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));\r
686      *ptrTmp++ = cobidH;\r
687      *ptrTmp++ = 0;\r
688    }\r
689 \r
690    *ptrTmp++ = 0x0000;  /* rezerva */\r
691    ptrRTR++;\r
692    }\r
693 \r
694    *((U16*)card->commandRegister) = ((U16)cmCL2_DOWNLOAD_RTR_LIST +\r
695                                      CL2_COMMAND_VALID);\r
696    return CL2_OK;\r
697    } /* cl2_download_rtrlist */\r
698 \r
699 \r
700 /*******************************************************************************\r
701 * cl2_subscribe_rtr - subscribe RTR frame\r
702 * """""""""""""""""\r
703 *\r
704 * Command subscribes RTR frame. Incoming RTR frames which were\r
705 * subscribed are accepted, while other are ignored. Up to 10\r
706 * RTR frames can be subscribed.\r
707 *\r
708 * RETURNS:\r
709 *   CL2_OK - command completed successfuly\r
710 *   CL2_COMMAND_BUSY - previous command not completed\r
711 *   CL2_BAD_PARAM - bad command parameter\r
712 *\r
713 */\r
714 eCL2_RESULT cl2_subscribe_rtr\r
715    (\r
716    sCAN_CARD *card,            /* Pointer to card structure */\r
717    sCAN_MESSAGE *canMessage,   /* RTR frame */\r
718    U16 RTRnumber               /* number of RTR */\r
719    )\r
720    {\r
721    U16 *ptrU16 = (U16*)card->dataPtr;\r
722    U32 COBID;\r
723    U16 cobidH, cobidL;\r
724 \r
725    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
726       return CL2_COMMAND_BUSY;\r
727    if ( RTRnumber > 9 ) return CL2_BAD_PARAM;\r
728 \r
729    card->rtrSub[RTRnumber] = canMessage->COB_ID;\r
730    *ptrU16 = RTRnumber;\r
731    ptrU16++;\r
732    COBID = canMessage->COB_ID;\r
733 \r
734    if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */\r
735    { /* 2.0B frame */\r
736      COBID <<= 3;\r
737      cobidL = (U16)(COBID & 0x0000FFFFL);\r
738      cobidH = (U16)((COBID & 0xFFFF0000L)>>16);\r
739      cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));\r
740      *ptrU16++ = cobidH;\r
741      cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));\r
742      *ptrU16++ = cobidL;\r
743      *ptrU16 = (U16)CL2_EXT_FRAME;\r
744    }\r
745    else\r
746    { /* 2.0A frame */\r
747      COBID <<= 5;\r
748      cobidH = (U16)(COBID & 0x0000FFFFL);\r
749      cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));\r
750      *ptrU16++ = cobidH;\r
751      *ptrU16++ = 0;\r
752      *ptrU16 = 0;\r
753    }\r
754 \r
755    *((U16*)card->commandRegister) = ((U16)cmCL2_SUBSCRIBE_RTR +\r
756                                     CL2_COMMAND_VALID);\r
757    return CL2_OK;\r
758    } /* cl2_subscribe_rtr */\r
759 \r
760 \r
761 /*******************************************************************************\r
762 * cl2_desubscribe_rtr - desubscribe rtr frame\r
763 * """""""""""""""""""\r
764 *\r
765 * Command desubscribes RTR frame. Card will not accept RTR frames\r
766 * with this identifier.\r
767 *\r
768 * RETURNS:\r
769 *   CL2_OK - command completed successfuly\r
770 *   CL2_COMMAND_BUSY - previous command not completed\r
771 *   CL2_BAD_PARAM - bad command parameter\r
772 *\r
773 */\r
774 eCL2_RESULT cl2_desubscribe_rtr\r
775    (\r
776    sCAN_CARD *card,           /* Pointer to card structure */\r
777    sCAN_MESSAGE *canMessage   /* RTR frame */\r
778    )\r
779    {\r
780    U16 i;\r
781 \r
782    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
783       return CL2_COMMAND_BUSY;\r
784 \r
785    for ( i = 0; i < 10; i++ )\r
786    {\r
787      if ( card->rtrSub[i] == canMessage->COB_ID )\r
788      {\r
789        card->rtrSub[i] = 0xFFFFFFFFL;\r
790        break;\r
791      }\r
792    }\r
793 \r
794    if ( i >= 10 ) return CL2_BAD_PARAM;\r
795 \r
796    *((U16*)card->dataPtr) = i;\r
797    *((U16*)card->commandRegister) = ((U16)cmCL2_DESUBSCRIBE_RTR +\r
798                                     CL2_COMMAND_VALID);\r
799    return CL2_OK;\r
800    } /* cl2_desubscribe_rtr */\r
801 \r
802 \r
803 \r
804 /*******************************************************************************\r
805 * cl2_set_sync_cobid - set COB-ID\r
806 * """"""""""""""""""\r
807 *\r
808 * Command sets COB-ID of SYNC frame. In active SYNC mode, the SYNC\r
809 * frame with this COB-ID is periodically sent with period defined\r
810 * by cl2_set_sync_period command.\r
811 *\r
812 * RETURNS:\r
813 *   CL2_OK - command completed successfuly\r
814 *   CL2_COMMAND_BUSY - previous command not completed\r
815 *\r
816 */\r
817 eCL2_RESULT cl2_set_sync_cobid\r
818    (\r
819    sCAN_CARD *card,           /* Pointer to card structure */\r
820    U32 COBID                  /* COB-ID */\r
821    )\r
822    {\r
823    U16 cobidL, cobidH;\r
824    U16 *ptr = (U16 *)card->dataPtr;\r
825 \r
826    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
827       return CL2_COMMAND_BUSY;\r
828 \r
829    if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */\r
830    { /* 2.0B frame */\r
831      COBID <<= 3;\r
832      cobidL = (U16)(COBID & 0x0000FFFFL);\r
833      cobidH = (U16)((COBID & 0xFFFF0000L)>>16);\r
834      cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));\r
835      *ptr++ = cobidH;\r
836      cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));\r
837      *ptr++ = cobidL;\r
838      *ptr = CL2_TMP_EX2;\r
839    }\r
840    else\r
841    { /* 2.0A frame */\r
842      COBID <<= 5;\r
843      cobidH = (U16)(COBID & 0x0000FFFFL);\r
844      cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));\r
845      *ptr++ = cobidH;\r
846      *ptr++ = 0;\r
847      *ptr = 0;\r
848    }\r
849 \r
850    *((U16*)card->commandRegister) = ((U16)cmCL2_SET_COBID + CL2_COMMAND_VALID);\r
851    return CL2_OK;\r
852    } /* cl2_set_sync_cobid */\r
853 \r
854 \r
855 /*******************************************************************************\r
856 * cl2_set_sync_period - set SYNC period\r
857 * """""""""""""""""""\r
858 *\r
859 * Coomand sets the SYNC frame send period in active SYNC mode in\r
860 * x100 us. The period range is from 0 to 0xFFFF (SYNC period can\r
861 * be set from 100us to 6.5535s).\r
862 *\r
863 * RETURNS:\r
864 *   CL2_OK - command completed successfuly\r
865 *   CL2_COMMAND_BUSY - previous command not completed\r
866 *\r
867 */\r
868 eCL2_RESULT cl2_set_sync_period\r
869    (\r
870    sCAN_CARD *card,            /* Pointer to card structure */\r
871    U16 period                  /* period in x100 us */\r
872    )\r
873    {\r
874    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
875       return CL2_COMMAND_BUSY;\r
876    *((U16*)card->dataPtr) = (U16)period;\r
877    *((U16*)card->commandRegister) = ((U16)cmCL2_SET_SYNC_PERIOD +\r
878                                     CL2_COMMAND_VALID);\r
879    return CL2_OK;\r
880    } /* cl2_set_sync_period */\r
881 \r
882 \r
883 /*******************************************************************************\r
884 * cl2_set_sync_window - set SYNC window\r
885 * """""""""""""""""""\r
886 *\r
887 * Command sets the SYNC window length. Only during this time period\r
888 * after SYNC frame was send or receive the frames from the synchronous\r
889 * send buffer can be sent.\r
890 *\r
891 * RETURNS:\r
892 *   CL2_OK - command completed successfuly\r
893 *   CL2_COMMAND_BUSY - previous command not completed\r
894 *\r
895 */\r
896 eCL2_RESULT cl2_set_sync_window\r
897    (\r
898    sCAN_CARD *card,            /* Pointer to card structure */\r
899    U16 window                  /* period in x100 us */\r
900    )\r
901    {\r
902    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
903       return CL2_COMMAND_BUSY;\r
904    *((U16*)card->dataPtr) = (U16)window;\r
905    *((U16*)card->commandRegister) = ((U16)cmCL2_SET_SYNC_WINDOW +\r
906                                     CL2_COMMAND_VALID);\r
907    return CL2_OK;\r
908    } /* cl2_set_sync_window */\r
909 \r
910 \r
911 /*******************************************************************************\r
912 * cl2_set_bitrate - set CAN bit-rate\r
913 * """""""""""""""\r
914 *\r
915 * Command switches the bus bit-rate. There are some predefined\r
916 * constants CL2_BITRATE_XXXX.\r
917 *\r
918 * RETURNS:\r
919 *   CL2_OK - command completed successfuly\r
920 *   CL2_COMMAND_BUSY - previous command not completed\r
921 *\r
922 */\r
923 eCL2_RESULT cl2_set_bitrate\r
924    (\r
925    sCAN_CARD *card,            /* Pointer to card structure */\r
926    U16 bitrate                 /* CAN bitrate */\r
927    )\r
928    {\r
929    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
930       return CL2_COMMAND_BUSY;\r
931    *((U16*)card->dataPtr) = bitrate;\r
932    *((U16*)card->commandRegister) = ((U16)cmCL2_SET_BITRATE +\r
933                                     CL2_COMMAND_VALID);\r
934    return CL2_OK;\r
935    } /* cl2_set_bitrate */\r
936 \r
937 \r
938 /*******************************************************************************\r
939 * cl2_bus_reset - resets CAN controller\r
940 * """""""""""""\r
941 *\r
942 * Command resets CAN controller\r
943 *\r
944 * RETURNS:\r
945 *   CL2_OK - command completed successfuly\r
946 *   CL2_COMMAND_BUSY - previously command not completed\r
947 *\r
948 */\r
949 eCL2_RESULT cl2_bus_reset\r
950    (\r
951    sCAN_CARD *card\r
952    )\r
953    {\r
954    if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )\r
955       return CL2_COMMAND_BUSY;\r
956    *((U16*)card->commandRegister) = ((U16)cmCL2_BUS_RESET +\r
957                                     CL2_COMMAND_VALID);\r
958    return CL2_OK;\r
959    } /* cl2_bus_reset */\r
960 \r
961 \r
962 /*******************************************************************************\r
963 * cl2_send_sync - sends synchronous frame\r
964 * """""""""""""\r
965 *\r
966 * Command stores massage in synchronous send buffer.\r
967 *\r
968 * RETURNS:\r
969 *   CL2_OK - command completed successfuly\r
970 *   CL2_HW_QUEUE_FULL - synchronous send buffer is full\r
971 *   CL2_BAD_PARAM - bad command parameter\r
972 *   CL2_HW_FAILURE - error in HW configuration\r
973 *\r
974 */\r
975 eCL2_RESULT cl2_send_sync\r
976    (\r
977    sCAN_CARD *card,           /* pointer to card */\r
978    sCAN_MESSAGE *message      /* massage to be sent */\r
979    )\r
980    {\r
981    U32 cobid;\r
982    U16 cobidL,cobidH;\r
983    U16 *ptrU16 = (U16*)card->syncTxBufPtr;\r
984    U16 tmpU16;\r
985    int i;\r
986    int timeStamp = 0;\r
987 \r
988    if ( card->syncTxBufSize==0 ) return CL2_HW_FAILURE;\r
989    if ( message->dataLength > 8 ) return CL2_BAD_PARAM;\r
990    if ( *ptrU16 & CL2_FRAME_VALID ) return CL2_HW_QUEUE_FULL;\r
991 \r
992    cobid = message->COB_ID;\r
993    if ( (message->dataType & CL2_EXT_FRAME) || (cobid & CL2_TMP_EXHIGH) )\r
994    {  /* 2.0B frame */\r
995      cobid <<= 3;\r
996      cobidL = (U16)(cobid & 0x0000FFFFL);\r
997      cobidH = (U16)((cobid & 0xFFFF0000L)>>16);\r
998    }\r
999    else\r
1000    {  /* 2.0A frame */\r
1001      cobid <<= 5;\r
1002      cobidL = 0;\r
1003      cobidH = (U16)(cobid & 0x0000FFFFL);\r
1004    }\r
1005    ptrU16++;\r
1006    tmpU16 = (cobidH & 0x00FF) + (cobidL & 0xFF00);\r
1007    *ptrU16++ = tmpU16;\r
1008 \r
1009    tmpU16 = (((U16)message->dataLength) << 12) + (cobidL & 0x00FF);\r
1010    if ( !(message->dataType & CL2_REMOTE_FRAME) ) tmpU16 |= CL2_TMP_RF;\r
1011    if ( (message->dataType & CL2_EXT_FRAME) ||\r
1012         (message->COB_ID & CL2_TMP_EXHIGH) )\r
1013      tmpU16 |= CL2_TMP_EX;\r
1014    *ptrU16++ = tmpU16;\r
1015 \r
1016    for ( i = 0; i < message->dataLength; )\r
1017       {\r
1018       tmpU16 = (U16)message->data[i]; i++;\r
1019       if ( i == message->dataLength )\r
1020          {\r
1021          timeStamp = 1;\r
1022          tmpU16 |= ((message->timeStamp & 0x00FF)<<8);\r
1023          *ptrU16++ = tmpU16;\r
1024          }\r
1025       else\r
1026          {\r
1027          tmpU16 |= ((U16)message->data[i]<<8); i++;\r
1028          *ptrU16++ = tmpU16;\r
1029          }\r
1030       }\r
1031    if ( timeStamp )\r
1032       {\r
1033       tmpU16 = (message->timeStamp>>8) & 0x00FF;\r
1034       *ptrU16 = tmpU16;\r
1035       }\r
1036    else\r
1037       {\r
1038       *ptrU16 = message->timeStamp;\r
1039       }\r
1040 \r
1041    tmpU16 = (((U16)cobidH) & 0xFF00) | CL2_MESSAGE_VALID;\r
1042    *(U16*)card->syncTxBufPtr = tmpU16;\r
1043 \r
1044    if ( (card->syncTxBufBase + card->syncTxBufSize*16) <=\r
1045         (card->syncTxBufPtr += 16) )\r
1046      {\r
1047      card->syncTxBufPtr = card->syncTxBufBase;\r
1048      }\r
1049    return CL2_OK;\r
1050    } /* cl2_send_sync */\r
1051 \r
1052 \r
1053 /*******************************************************************************\r
1054 * cl2_send_async - sends asynchronous frame\r
1055 * """"""""""""""\r
1056 *\r
1057 * Command stores message in asynchronous send buffer.\r
1058 *\r
1059 * RETURNS:\r
1060 *   CL2_OK - command completed successfuly\r
1061 *   CL2_HW_QUEUE_FULL - asynchronous buffer full\r
1062 *   CL2_HW_FAILURE - error in HW configuration\r
1063 *   CL2_BAD_PARAM - bad command parameter\r
1064 *\r
1065 */\r
1066 eCL2_RESULT cl2_send_async\r
1067    (\r
1068    sCAN_CARD *card,           /* pointer to card */\r
1069    sCAN_MESSAGE *message      /* message to be sent */\r
1070    )\r
1071    {\r
1072    U32 cobid;\r
1073    U16 cobidL,cobidH;\r
1074    U16 *ptrU16 = (U16*)card->asyncTxBufPtr;\r
1075    U16 tmpU16;\r
1076    int i;\r
1077    int timeStamp = 0;\r
1078 \r
1079    if ( card->asyncTxBufSize==0 ) return CL2_HW_FAILURE;\r
1080    if ( message->dataLength > 8 ) return CL2_BAD_PARAM;\r
1081    if ( *ptrU16 & CL2_FRAME_VALID ) return CL2_HW_QUEUE_FULL;\r
1082 \r
1083    cobid = message->COB_ID;\r
1084    if ( (message->dataType & CL2_EXT_FRAME) || (cobid & CL2_TMP_EXHIGH) )\r
1085    {  /* 2.0B frame */\r
1086      cobid <<= 3;\r
1087      cobidL = (U16)(cobid & 0x0000FFFFL);\r
1088      cobidH = (U16)((cobid & 0xFFFF0000L)>>16);\r
1089    }\r
1090    else\r
1091    {  /* 2.0A frame */\r
1092      cobid <<= 5;\r
1093      cobidL = 0;\r
1094      cobidH = (U16)(cobid & 0x0000FFFFL);\r
1095    }\r
1096    ptrU16++;\r
1097    tmpU16 = (cobidH & 0x00FF ) + (cobidL & 0xFF00);\r
1098    *ptrU16++ = tmpU16;\r
1099 \r
1100    tmpU16 = (((U16)message->dataLength) << 12) + (cobidL & 0x00FF);\r
1101    if ( !(message->dataType & CL2_REMOTE_FRAME) ) tmpU16 |= CL2_TMP_RF;\r
1102    if ( (message->dataType & CL2_EXT_FRAME) ||\r
1103         (message->COB_ID & CL2_TMP_EXHIGH ) )\r
1104       tmpU16 |= CL2_TMP_EX;\r
1105    *ptrU16++ = tmpU16;\r
1106 \r
1107    for ( i = 0; i < message->dataLength; )\r
1108       {\r
1109       tmpU16 = (U16)message->data[i]; i++;\r
1110       if ( i == message->dataLength )\r
1111          {\r
1112          timeStamp = 1;\r
1113          tmpU16 |= ((message->timeStamp & 0x00FF)<<8);\r
1114          *ptrU16++ = tmpU16;\r
1115          }\r
1116       else\r
1117          {\r
1118          tmpU16 |= ((U16)message->data[i]<<8); i++;\r
1119          *ptrU16++ = tmpU16;\r
1120          }\r
1121       }\r
1122    if ( timeStamp )\r
1123       {\r
1124       tmpU16 = (message->timeStamp>>8) & 0x00FF;\r
1125       *ptrU16 = tmpU16;\r
1126       }\r
1127    else\r
1128       {\r
1129       *ptrU16 = message->timeStamp;\r
1130       }\r
1131 \r
1132    tmpU16 = (((U16)cobidH) & 0xFF00) | CL2_MESSAGE_VALID;\r
1133    *(U16*)card->asyncTxBufPtr = tmpU16;\r
1134 \r
1135    if ( (card->asyncTxBufBase + card->asyncTxBufSize*16) <=\r
1136         (card->asyncTxBufPtr += 16) )\r
1137       {\r
1138       card->asyncTxBufPtr = card->asyncTxBufBase;\r
1139       }\r
1140    return CL2_OK;\r
1141    } /* cl2_send_async */\r
1142 \r
1143 \r
1144 /*******************************************************************************\r
1145 * cl2_get_status - reads card status\r
1146 * """"""""""""""\r
1147 *\r
1148 * Command reads card status register. If data in status register\r
1149 * are valid (status valid flag is set), the value of status is read\r
1150 * and stored in status and sCAN_CARD structure.\r
1151 *\r
1152 * RETURNS:\r
1153 *   CL2_OK - command completed successfuly\r
1154 *   CL2_NO_REQUEST - status is not valid\r
1155 *\r
1156 */\r
1157 eCL2_RESULT cl2_get_status\r
1158    (\r
1159    sCAN_CARD *card,          /* pointer to card */\r
1160    U16 *status               /* card status word */\r
1161    )\r
1162    {\r
1163    U16 *ptr;\r
1164 \r
1165    ptr = (U16*)(card->baseAddressPtr + CL2_STATUS_REGISTER);\r
1166    *status = *ptr;\r
1167    if ( (*status & CL2_STATUS_VALID_FLAG) )\r
1168       {\r
1169       *ptr = *status & ~CL2_STATUS_VALID_FLAG;\r
1170       card->status = *status;\r
1171       return CL2_OK;\r
1172       }\r
1173    return CL2_NO_REQUEST;\r
1174    } /* cl2_get_status */\r
1175 \r
1176 \r
1177 /*******************************************************************************\r
1178 * cl2_get_error - reads card error\r
1179 * """""""""""""\r
1180 *\r
1181 * Command reads card error register. If data in error register\r
1182 * are valid (error register valid flag is set), the value of error\r
1183 * register is read and stored in error and sCAN_CARD structure.\r
1184 *\r
1185 * RETURNS:\r
1186 *   Cl2_OK - command completed successfuly\r
1187 *\r
1188 */\r
1189 eCL2_RESULT cl2_get_error\r
1190    (\r
1191    sCAN_CARD *card,          /* pointer to card */\r
1192    U16 *error                /* card error word */\r
1193    )\r
1194    {\r
1195    U16 *ptr;\r
1196 \r
1197    ptr = (U16*)(card->baseAddressPtr + CL2_ERROR_REGISTER);\r
1198    *error = *ptr;\r
1199    card->error |= *error;\r
1200    *ptr = 0x0000;\r
1201    return CL2_OK;\r
1202    } /* cl2_get_error */\r
1203 \r
1204 \r
1205 /*******************************************************************************\r
1206 * cl2_receive_data - reads received frame\r
1207 * """"""""""""""""\r
1208 *\r
1209 * Command reads new messages received by a card.\r
1210 *\r
1211 * RETURNS:\r
1212 *   CL2_OK - command commpleted successfuly\r
1213 *   CL2_NO_REQUEST - there is no new message\r
1214 *\r
1215 */\r
1216 eCL2_RESULT cl2_receive_data\r
1217    (\r
1218    sCAN_CARD *card,             /* Pointer to card structure */\r
1219    sCAN_MESSAGE *canMessage     /* Message */\r
1220    )\r
1221    {\r
1222    U16 *ptrU16 = (U16*)card->rxBufPtr;\r
1223    U16 tmpU16;\r
1224    U16 i;\r
1225 \r
1226    tmpU16 = *ptrU16++;\r
1227    if ( !(tmpU16 & CL2_MESSAGE_VALID) ) return CL2_NO_REQUEST;\r
1228    canMessage->COB_ID = ((U32)(tmpU16 & 0xFF00 )) << 16;\r
1229    tmpU16 = *ptrU16++;\r
1230    canMessage->COB_ID |= ((U32)( tmpU16 & 0x00FF )) << 16;\r
1231    canMessage->COB_ID |= (U32)( tmpU16 & 0xFF00 );\r
1232    tmpU16 = *ptrU16++;\r
1233    canMessage->COB_ID |= (U32)( tmpU16 & 0x00FF );\r
1234    canMessage->dataType = (U8)(( tmpU16 & 0xFF00 ) >> 8);\r
1235 \r
1236    if ( canMessage->dataType & CL2_EXT_FRAME )\r
1237    {  /* 2.0B frame */\r
1238      canMessage->COB_ID >>= 3;\r
1239      /* canMessage->COB_ID |= CL2_TMP_EXHIGH; */\r
1240    }\r
1241    else\r
1242    {  /* 2.0A frame */\r
1243      canMessage->COB_ID >>= 21;\r
1244    }\r
1245    canMessage->dataLength = (U8)( (tmpU16 >> 12) & 0x000F );\r
1246    /* if ( !(tmpU16 & CL2_TMP_RF) ) canMessage->dataType |= CL2_REMOTE_FRAME; */\r
1247    for ( i = 0; i < canMessage->dataLength; )\r
1248       {\r
1249       tmpU16 = *ptrU16++;\r
1250       canMessage->data[i++] = (U8)( tmpU16 );\r
1251       canMessage->data[i++] = (U8)( tmpU16 >> 8 );\r
1252       }\r
1253    if ( canMessage->dataLength & 0x01 )\r
1254       {  /* odd */\r
1255       canMessage->timeStamp = ( (*ptrU16 & 0x00FF) | (tmpU16 & 0xFF00) );\r
1256       }\r
1257    else  /* even */\r
1258       {\r
1259       canMessage->timeStamp = *ptrU16 << 8 | *ptrU16 >> 8;\r
1260       }\r
1261    *(U16*)card->rxBufPtr = 0x0000;\r
1262 \r
1263    /* increment rx-buffer pointer */\r
1264    if ( (card->rxBufBase + card->rxBufSize*16 ) <= (card->rxBufPtr += 16) )\r
1265       {\r
1266       card->rxBufPtr = card->rxBufBase;\r
1267       }\r
1268 \r
1269    return CL2_OK;\r
1270    } /* cl2_receive_data */\r
1271 \r
1272 \r
1273 /* **************************************************************** *\r
1274  * END OF CL2.C                                                     *\r
1275  * **************************************************************** */\r
1276 \r
1277 \r