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