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