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