1 /**************************************************************************/
2 /* File: unican_cl2.c - Unicontrols PCAN,PCAN-PCI, VCAN core support */
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> */
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. */
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: */
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 /**************************************************************************/
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
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"
53 /*******************************************************************************
54 * cl2_init_card - initialize card to default parameters
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
63 * CL2_OK - command completed succesfuly
66 eCL2_RESULT cl2_init_card
68 sCAN_CARD *card, /* Pointer to card structure */
69 void *baseAddress, /* Card base address pointer */
70 U16 intNumber /* Card interrupt number */
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;
89 for ( i = 0; i < 10; i++ ) card->rtrSub[i] = 0xFFFFFFFFL;
94 /*******************************************************************************
95 * cl2_test_card - test card
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.
103 * CL2_OK - card is present and working properly
104 * CL2_HW_FAILURE - card not found or card error
107 eCL2_RESULT cl2_test_card
109 sCAN_CARD *card /* Pointer to card structure */
112 BOOLEAN1 isAA = FALSE, is55 = FALSE;
114 U16 volatile tmpWord;
116 /* timeout for card testing - 1000 read cycles */
117 for ( i = 0; i < 10000; i++ )
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);*/
123 if ( (tmpWord & 0x00FF) == 0x00AA ) isAA = TRUE;
124 if ( (tmpWord & 0x00FF) == 0x0055 ) is55 = TRUE;
127 return CL2_HW_FAILURE;
128 } /* cl2_test_card */
131 /*******************************************************************************
132 * cl2_reset_card - reset card
135 * Card pointed by *card gets hardware reset. This command resets
136 * card processor, card settings are restored to their default
140 * CL2_OK - command completed successfuly
143 eCL2_RESULT cl2_reset_card
145 sCAN_CARD *card /* Pointer to card structure */
148 unican_writew(0x0000, card->baseAddressPtr + CL2_RESET_REGISTER);
150 } /* cl2_reset_card */
153 /*******************************************************************************
154 * cl2_get_version - read card version
157 * Fucntion reads a value from card version register.
160 * CL2_OK - command completed successfuly
163 eCL2_RESULT cl2_get_version
165 sCAN_CARD *card, /* Pointer to card structure */
166 U16 *version /* returns card version */
169 *version = unican_readw(card->baseAddressPtr + CL2_VERSION_REGISTER);
171 } /* cl2_get_version */
174 /*******************************************************************************
175 * cl2_gen_interrupt - request for interrupt
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.
183 * CL2_OK - command completed successfuly
186 eCL2_RESULT cl2_gen_interrupt
188 sCAN_CARD *card /* Pointer to card structure */
191 unican_writew(0x0000, card->baseAddressPtr + CL2_GEN_INT_REGISTER);
193 } /* cl2_gen_interrupt */
196 /*******************************************************************************
197 * cl2_start_it - start inhibit time
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.
205 * CL2_OK - command completed successfuly
208 eCL2_RESULT cl2_start_it
210 sCAN_CARD *card /* Pointer to card structure */
213 unican_writew(0x0000, card->baseAddressPtr + CL2_START_IT_REGISTER);
218 /*******************************************************************************
219 * cl2_clear_interrupt - clear interrupt
220 * """""""""""""""""""
222 * Comand clears interrupt (IRQ) generated by a card.
225 * CL2_OK - command completed successfuly
228 eCL2_RESULT cl2_clear_interrupt
230 sCAN_CARD *card /* Pointer to card structure */
233 unican_writew(0x0000, card->baseAddressPtr + CL2_CLEAR_INT_REGISTER);
235 } /* cl2_clear_interrupt */
238 /*******************************************************************************
239 * cl2_int_mode - set interrupt mode
242 * Command controls, which event will generate interrupt. Constants
243 * CL2_INT_XXXX are used for setting of interrupt mode.
246 * CL2_OK - command completed successfuly
247 * CL2_BAD_PARAM - bad command parameter
248 * CL2_COMMAND_BUSY - previous command not completed
251 eCL2_RESULT cl2_int_mode
253 sCAN_CARD *card, /* Pointer to card structure */
254 U16 mode /* Interrupt mode */
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);
266 /*******************************************************************************
267 * cl2_iit_mode - inhibit interrupt time mode
270 * Command enables/disables inhibit interupt time mode.
273 * CL2_OK - command completed successfuly
274 * CL2_COMMAND_BUSY - previous command not completed
277 eCL2_RESULT cl2_iit_mode
279 sCAN_CARD *card, /* Pointer to card structure */
280 BOOLEAN1 onoff /* IIT mode - TRUE=on, FALSE=off */
283 if ( unican_readw(card->commandRegister) & CL2_COMMAND_VALID ) return
285 unican_writew((U16)onoff, card->dataPtr);
286 unican_writew(((U16)cmCL2_IIT_MODE + CL2_COMMAND_VALID), card->commandRegister);
291 /*******************************************************************************
292 * cl2_sync_mode - sync mode
295 * Command enables/disables transmission of SYNC frames.
298 * CL2_OK - command completed successfuly
299 * CL2_COMMAND_BUSY - previous command not completed
302 eCL2_RESULT cl2_sync_mode
304 sCAN_CARD *card, /* Pointer to card structure */
305 BOOLEAN1 onoff /* Sync mode - TRUE=on, FALSE=off */
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);
313 } /* cl2_sync_mode */
316 /*******************************************************************************
317 * cl2_rtr_mode - rtr mode
320 * Command enables/disables automatic transmission of RTR frames
323 * CL2_OK - command completed successfuly
324 * CL2_COMMAND_BUSY - previous command not completed
327 eCL2_RESULT cl2_rtr_mode
329 sCAN_CARD *card, /* Pointer to card structure */
330 BOOLEAN1 onoff /* RTR mode - TRUE=on, FALSE=off */
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);
341 /*******************************************************************************
342 * cl2_buf_size - size of synchronous queue
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
351 * NOTE: 1 message = 16 bytes
354 * CL2_OK - command completed successfully
355 * CL2_COMMAND_BUSY - previous command not completed
356 * CL2_BAD_PARAM - bad command parameter (bufSize>64)
359 eCL2_RESULT cl2_buf_size
361 sCAN_CARD *card, /* Pointer to card structure */
362 U16 bufSize /* Size of synchronous buffer */
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;
378 /*******************************************************************************
379 * cl2_set_iit - set value of inhibit interrupt time
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
388 * CL2_OK - command completed successfuly
389 * CL2_COMMAND_BUSY - previous command not completed
392 eCL2_RESULT cl2_set_iit
394 sCAN_CARD *card, /* Pointer to card structure */
395 U16 iit /* time period in x100 us */
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);
406 /*******************************************************************************
407 * cl2_start_firmware - start firmware
410 * Command starts card firmware
413 * CL2_OK - command completed successfuly
414 * CL2_COMMAND_BUSY - previous command not completed
417 eCL2_RESULT cl2_start_firmware
419 sCAN_CARD *card /* Pointer to card structure */
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);
426 } /* cl2_start_firmware */
429 /*******************************************************************************
430 * cl2_set_rec_mode - set receive mode
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).
439 * CL2_OK - command completed successfuly
440 * CL2_COMMAND_BUSY - previous command not completed
443 eCL2_RESULT cl2_set_rec_mode
445 sCAN_CARD *card, /* Pointer to card structure */
446 BOOLEAN1 mode /* Mode - TRUE=ext, FALSE=std */
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);
454 } /* cl2_set_rec_mode */
457 /*******************************************************************************
458 * cl2_clr_rx_buffer - clear RX buffer
461 * Command clears receive (rx) buffer. All messages stored in
462 * rx buffer will be lost.
465 * CL2_OK - command completed successfuly
466 * CL2_COMMAND_BUSY - previous command not completed
469 eCL2_RESULT cl2_clr_rx_buffer
471 sCAN_CARD *card /* Pointer to card structure */
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);
479 } /* cl2_clr_rx_buffer */
482 /*******************************************************************************
483 * cl2_clr_sync_buffer - clear synchronous buffer
484 * """""""""""""""""""
486 * Command clears synchronous send buffer. All messages stored
487 * in synchronous buffer will be lost.
490 * CL2_OK - command completed successfuly
491 * CL2_COMMAND_BUSY - previous command not completed
494 eCL2_RESULT cl2_clr_sync_buffer
496 sCAN_CARD *card /* Pointer to card structure */
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);
504 } /* cl2_clr_sync_buffer */
507 /*******************************************************************************
508 * cl2_clr_async_buffer - clear asynchronous buffer
509 * """"""""""""""""""""
511 * Command clears asynchronnous send buffer. All messages stored
512 * in async buffer will be lost.
515 * CL2_OK - command completed successfuly
516 * CL2_COMMAND_BUSY - previous command not completed
519 eCL2_RESULT cl2_clr_async_buffer
521 sCAN_CARD *card /* Pointer to card structure */
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);
529 } /* cl2_clr_async_buffer */
532 /*******************************************************************************
533 * cl2_send_time_sync - send time synchronization
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
542 * CL2_OK - command completed successfuly
543 * CL2_COMMAND_BUSY - previous command not completed
546 eCL2_RESULT cl2_send_time_sync
548 sCAN_CARD *card /* Pointer to card structure */
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);
555 } /* cl2_send_time_sync */
558 /*******************************************************************************
559 * cl2_set_time_cobid - set time COB-ID
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.
567 * CL2_OK - command completed successfuly
568 * CL2_COMMAND_BUSY - previous command not completed
571 eCL2_RESULT cl2_set_time_cobid
573 sCAN_CARD *card, /* Pointer to card structure */
574 U32 COBID /* HRS frame COB-ID */
578 U16 *ptr = (U16 *)card->dataPtr;
580 if ( unican_readw(card->commandRegister) & CL2_COMMAND_VALID )
581 return CL2_COMMAND_BUSY;
583 if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */
586 cobidL = (U16)(COBID & 0x0000FFFFL);
587 cobidH = (U16)((COBID & 0xFFFF0000L)>>16);
588 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
590 cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));
597 cobidH = (U16)(COBID & 0x0000FFFFL);
598 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
604 unican_writew((U16)cmCL2_SET_TIME_COBID + CL2_COMMAND_VALID, card->commandRegister);
606 } /* cl2_set_time_cobid */
609 /*******************************************************************************
610 * cl2_set_receive_limit - set limit for receive signaling
611 * """""""""""""""""""""
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.
621 * CL2_COMMAND_BUSY - previous command not completed
622 * CL2_BAD_PARAM - bad command parameter
624 eCL2_RESULT cl2_set_receive_limit
626 sCAN_CARD *card, /* pointer to card structure */
627 U16 limit /* limit of messages in receive buffer */
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);
636 } /* cl2_set_receive_limit */
639 /*******************************************************************************
640 * cl2_download_rtr_list - download rtr list
641 * """""""""""""""""""""
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.
649 * CL2_OK - command completed successfuly
650 * CL2_COMMAND_BUSY - previous command not completed
651 * CL2_BAD_PARAM - bad command parameter
654 eCL2_RESULT cl2_download_rtr_list
656 sCAN_CARD *card, /* Pointer to card structure */
657 sRTR_LIST *rtrList /* RTR list */
660 U16 *ptrTmp = (U16*)card->dataPtr;
661 sRTR_FRAME *ptrRTR = rtrList->data;
664 U16 cobidH, cobidL, i;
666 if ( unican_readw(card->commandRegister) & CL2_COMMAND_VALID ) return
668 if ( rtrList->nb > 64 ) return CL2_BAD_PARAM;
670 *ptrTmp++ = (U16)rtrList->nb;
671 for ( i = 0; i < rtrList->nb; i++ )
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);
677 COBID = ptrRTR->cob_id;
679 if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */
682 cobidL = (U16)(COBID & 0x0000FFFFL);
683 cobidH = (U16)((COBID & 0xFFFF0000L)>>16);
684 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
686 cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));
692 cobidH = (U16)(COBID & 0x0000FFFFL);
693 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
698 *ptrTmp++ = 0x0000; /* rezerva */
702 unican_writew((U16)cmCL2_DOWNLOAD_RTR_LIST + CL2_COMMAND_VALID, card->commandRegister);
704 } /* cl2_download_rtrlist */
707 /*******************************************************************************
708 * cl2_subscribe_rtr - subscribe RTR frame
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.
716 * CL2_OK - command completed successfuly
717 * CL2_COMMAND_BUSY - previous command not completed
718 * CL2_BAD_PARAM - bad command parameter
721 eCL2_RESULT cl2_subscribe_rtr
723 sCAN_CARD *card, /* Pointer to card structure */
724 sCAN_MESSAGE *canMessage, /* RTR frame */
725 U16 RTRnumber /* number of RTR */
728 U16 *ptrU16 = (U16*)card->dataPtr;
732 if ( unican_readw(card->commandRegister) & CL2_COMMAND_VALID )
733 return CL2_COMMAND_BUSY;
734 if ( RTRnumber > 9 ) return CL2_BAD_PARAM;
736 card->rtrSub[RTRnumber] = canMessage->COB_ID;
739 COBID = canMessage->COB_ID;
741 if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */
744 cobidL = (U16)(COBID & 0x0000FFFFL);
745 cobidH = (U16)((COBID & 0xFFFF0000L)>>16);
746 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
748 cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));
750 *ptrU16 = (U16)CL2_EXT_FRAME;
755 cobidH = (U16)(COBID & 0x0000FFFFL);
756 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
762 unican_writew((U16)cmCL2_SUBSCRIBE_RTR + CL2_COMMAND_VALID, card->commandRegister);
764 } /* cl2_subscribe_rtr */
767 /*******************************************************************************
768 * cl2_desubscribe_rtr - desubscribe rtr frame
769 * """""""""""""""""""
771 * Command desubscribes RTR frame. Card will not accept RTR frames
772 * with this identifier.
775 * CL2_OK - command completed successfuly
776 * CL2_COMMAND_BUSY - previous command not completed
777 * CL2_BAD_PARAM - bad command parameter
780 eCL2_RESULT cl2_desubscribe_rtr
782 sCAN_CARD *card, /* Pointer to card structure */
783 sCAN_MESSAGE *canMessage /* RTR frame */
788 if ( unican_readw(card->commandRegister) & CL2_COMMAND_VALID )
789 return CL2_COMMAND_BUSY;
791 for ( i = 0; i < 10; i++ )
793 if ( card->rtrSub[i] == canMessage->COB_ID )
795 card->rtrSub[i] = 0xFFFFFFFFL;
800 if ( i >= 10 ) return CL2_BAD_PARAM;
802 unican_writew(i, card->dataPtr);
803 unican_writew((U16)cmCL2_DESUBSCRIBE_RTR + CL2_COMMAND_VALID, card->commandRegister);
805 } /* cl2_desubscribe_rtr */
809 /*******************************************************************************
810 * cl2_set_sync_cobid - set COB-ID
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.
818 * CL2_OK - command completed successfuly
819 * CL2_COMMAND_BUSY - previous command not completed
822 eCL2_RESULT cl2_set_sync_cobid
824 sCAN_CARD *card, /* Pointer to card structure */
825 U32 COBID /* COB-ID */
829 U16 *ptr = (U16 *)card->dataPtr;
831 if ( unican_readw(card->commandRegister) & CL2_COMMAND_VALID )
832 return CL2_COMMAND_BUSY;
834 if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */
837 cobidL = (U16)(COBID & 0x0000FFFFL);
838 cobidH = (U16)((COBID & 0xFFFF0000L)>>16);
839 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
841 cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));
848 cobidH = (U16)(COBID & 0x0000FFFFL);
849 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
855 unican_writew(((U16)cmCL2_SET_COBID + CL2_COMMAND_VALID), card->commandRegister);
857 } /* cl2_set_sync_cobid */
860 /*******************************************************************************
861 * cl2_set_sync_period - set SYNC period
862 * """""""""""""""""""
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).
869 * CL2_OK - command completed successfuly
870 * CL2_COMMAND_BUSY - previous command not completed
873 eCL2_RESULT cl2_set_sync_period
875 sCAN_CARD *card, /* Pointer to card structure */
876 U16 period /* period in x100 us */
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);
884 } /* cl2_set_sync_period */
887 /*******************************************************************************
888 * cl2_set_sync_window - set SYNC window
889 * """""""""""""""""""
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.
896 * CL2_OK - command completed successfuly
897 * CL2_COMMAND_BUSY - previous command not completed
900 eCL2_RESULT cl2_set_sync_window
902 sCAN_CARD *card, /* Pointer to card structure */
903 U16 window /* period in x100 us */
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);
911 } /* cl2_set_sync_window */
914 /*******************************************************************************
915 * cl2_set_bitrate - set CAN bit-rate
918 * Command switches the bus bit-rate. There are some predefined
919 * constants CL2_BITRATE_XXXX.
922 * CL2_OK - command completed successfuly
923 * CL2_COMMAND_BUSY - previous command not completed
926 eCL2_RESULT cl2_set_bitrate
928 sCAN_CARD *card, /* Pointer to card structure */
929 U16 bitrate /* CAN bitrate */
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);
937 } /* cl2_set_bitrate */
940 /*******************************************************************************
941 * cl2_bus_reset - resets CAN controller
944 * Command resets CAN controller
947 * CL2_OK - command completed successfuly
948 * CL2_COMMAND_BUSY - previously command not completed
951 eCL2_RESULT cl2_bus_reset
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);
960 } /* cl2_bus_reset */
963 /*******************************************************************************
964 * cl2_send_sync - sends synchronous frame
967 * Command stores massage in synchronous send buffer.
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
976 eCL2_RESULT cl2_send_sync
978 sCAN_CARD *card, /* pointer to card */
979 sCAN_MESSAGE *message /* massage to be sent */
984 U16 *ptrU16 = (U16*)card->syncTxBufPtr;
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;
993 cobid = message->COB_ID;
994 if ( (message->dataType & CL2_EXT_FRAME) || (cobid & CL2_TMP_EXHIGH) )
997 cobidL = (U16)(cobid & 0x0000FFFFL);
998 cobidH = (U16)((cobid & 0xFFFF0000L)>>16);
1004 cobidH = (U16)(cobid & 0x0000FFFFL);
1007 tmpU16 = (cobidH & 0x00FF) + (cobidL & 0xFF00);
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;
1017 for ( i = 0; i < message->dataLength; )
1019 tmpU16 = (U16)message->data[i]; i++;
1020 if ( i == message->dataLength )
1023 tmpU16 |= ((message->timeStamp & 0x00FF)<<8);
1028 tmpU16 |= ((U16)message->data[i]<<8); i++;
1034 tmpU16 = (message->timeStamp>>8) & 0x00FF;
1039 *ptrU16 = message->timeStamp;
1042 tmpU16 = (((U16)cobidH) & 0xFF00) | CL2_MESSAGE_VALID;
1043 unican_writew(tmpU16, card->syncTxBufPtr);
1045 if ( (card->syncTxBufBase + card->syncTxBufSize*16) <=
1046 (card->syncTxBufPtr += 16) )
1048 card->syncTxBufPtr = card->syncTxBufBase;
1051 } /* cl2_send_sync */
1054 /*******************************************************************************
1055 * cl2_send_async - sends asynchronous frame
1058 * Command stores message in asynchronous send buffer.
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
1067 eCL2_RESULT cl2_send_async
1069 sCAN_CARD *card, /* pointer to card */
1070 sCAN_MESSAGE *message /* message to be sent */
1075 U16 *ptrU16 = (U16*)card->asyncTxBufPtr;
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;
1084 cobid = message->COB_ID;
1085 if ( (message->dataType & CL2_EXT_FRAME) || (cobid & CL2_TMP_EXHIGH) )
1088 cobidL = (U16)(cobid & 0x0000FFFFL);
1089 cobidH = (U16)((cobid & 0xFFFF0000L)>>16);
1095 cobidH = (U16)(cobid & 0x0000FFFFL);
1098 tmpU16 = (cobidH & 0x00FF ) + (cobidL & 0xFF00);
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;
1108 for ( i = 0; i < message->dataLength; )
1110 tmpU16 = (U16)message->data[i]; i++;
1111 if ( i == message->dataLength )
1114 tmpU16 |= ((message->timeStamp & 0x00FF)<<8);
1119 tmpU16 |= ((U16)message->data[i]<<8); i++;
1125 tmpU16 = (message->timeStamp>>8) & 0x00FF;
1130 *ptrU16 = message->timeStamp;
1133 tmpU16 = (((U16)cobidH) & 0xFF00) | CL2_MESSAGE_VALID;
1134 unican_writew(tmpU16, card->asyncTxBufPtr);
1136 if ( (card->asyncTxBufBase + card->asyncTxBufSize*16) <=
1137 (card->asyncTxBufPtr += 16) )
1139 card->asyncTxBufPtr = card->asyncTxBufBase;
1142 } /* cl2_send_async */
1145 /*******************************************************************************
1146 * cl2_get_status - reads card status
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.
1154 * CL2_OK - command completed successfuly
1155 * CL2_NO_REQUEST - status is not valid
1158 eCL2_RESULT cl2_get_status
1160 sCAN_CARD *card, /* pointer to card */
1161 U16 *status /* card status word */
1166 ptr = (U16*)(card->baseAddressPtr + CL2_STATUS_REGISTER);
1168 if ( (*status & CL2_STATUS_VALID_FLAG) )
1170 *ptr = *status & ~CL2_STATUS_VALID_FLAG;
1171 card->status = *status;
1174 return CL2_NO_REQUEST;
1175 } /* cl2_get_status */
1178 /*******************************************************************************
1179 * cl2_get_error - reads card error
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.
1187 * Cl2_OK - command completed successfuly
1190 eCL2_RESULT cl2_get_error
1192 sCAN_CARD *card, /* pointer to card */
1193 U16 *error /* card error word */
1198 ptr = (U16*)(card->baseAddressPtr + CL2_ERROR_REGISTER);
1200 card->error |= *error;
1203 } /* cl2_get_error */
1206 /*******************************************************************************
1207 * cl2_receive_data - reads received frame
1210 * Command reads new messages received by a card.
1213 * CL2_OK - command commpleted successfuly
1214 * CL2_NO_REQUEST - there is no new message
1217 eCL2_RESULT cl2_receive_data
1219 sCAN_CARD *card, /* Pointer to card structure */
1220 sCAN_MESSAGE *canMessage /* Message */
1223 U16 *ptrU16 = (U16*)card->rxBufPtr;
1228 if ( !(tmpU16 & CL2_MESSAGE_VALID) ) return CL2_NO_REQUEST;
1229 canMessage->COB_ID = ((U32)(tmpU16 & 0xFF00 )) << 16;
1231 canMessage->COB_ID |= ((U32)( tmpU16 & 0x00FF )) << 16;
1232 canMessage->COB_ID |= (U32)( tmpU16 & 0xFF00 );
1234 canMessage->COB_ID |= (U32)( tmpU16 & 0x00FF );
1235 canMessage->dataType = (U8)(( tmpU16 & 0xFF00 ) >> 8);
1237 if ( canMessage->dataType & CL2_EXT_FRAME )
1239 canMessage->COB_ID >>= 3;
1240 /* canMessage->COB_ID |= CL2_TMP_EXHIGH; */
1244 canMessage->COB_ID >>= 21;
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; )
1251 canMessage->data[i++] = (U8)( tmpU16 );
1252 canMessage->data[i++] = (U8)( tmpU16 >> 8 );
1254 if ( canMessage->dataLength & 0x01 )
1256 canMessage->timeStamp = ( (*ptrU16 & 0x00FF) | (tmpU16 & 0xFF00) );
1260 canMessage->timeStamp = *ptrU16 << 8 | *ptrU16 >> 8;
1262 unican_writew(0x0000, card->rxBufPtr);
1264 /* increment rx-buffer pointer */
1265 if ( (card->rxBufBase + card->rxBufSize*16 ) <= (card->rxBufPtr += 16) )
1267 card->rxBufPtr = card->rxBufBase;
1271 } /* cl2_receive_data */
1274 /* **************************************************************** *
1276 * **************************************************************** */