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