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