1 /******************************************************************************
\r
3 Cl2.C - PCAN and VCAN cards hardware access library
\r
5 (C) Copyright 1997 Unicontrols a.s.
\r
9 FIRMA : CVUT FEL, Dept. of Measurement
\r
11 DULEZITE UPOZORNENI:
\r
13 ARCHIVACNI INFORMACE:
\r
16 12.12.2000, J.B., cl2_receive_data - time stamp for even number of bytes corr.
\r
17 26.8.1998 - cl2_buf_size - corrected, new function return code CL2_BAD_PARAM
\r
18 cl2_clr_async_buffer - corrected
\r
20 ===============================================================================
\r
24 ******************************************************************************/
\r
26 /* Constnt used by CL2 functions */
\r
27 #define CL2_TMP_RF 0x0800
\r
28 #define CL2_TMP_EX 0x0400
\r
29 #define CL2_TMP_EX2 0x0004
\r
30 #define CL2_TMP_EXHIGH 0x80000000L
\r
34 #include "../include/canmsg.h"
\r
35 #include "../include/unican_types.h"
\r
36 #include "../include/unican_cl2.h"
\r
37 #include "linux/delay.h"
\r
40 /*******************************************************************************
\r
41 * cl2_init_card - initialize card to default parameters
\r
44 * Command installs card. The data in sCAN_CARD structure pointed
\r
45 * by *card are initialized to their predefined default values.
\r
46 * Command must be called before any operation with sCAN_CARD
\r
50 * CL2_OK - command completed succesfuly
\r
53 eCL2_RESULT cl2_init_card
\r
55 sCAN_CARD *card, /* Pointer to card structure */
\r
56 void *baseAddress, /* Card base address pointer */
\r
57 U16 intNumber /* Card interrupt number */
\r
62 card->intNumber = intNumber;
\r
63 card->baseAddressPtr = (U8*)baseAddress;
\r
64 card->rxBufBase = card->baseAddressPtr + CL2_RX_BUFFER_DEFAULT;
\r
65 card->asyncTxBufBase = card->baseAddressPtr + CL2_ASYNC_BUFFER_DEFAULT;
\r
66 card->syncTxBufBase = card->baseAddressPtr + CL2_SYNC_BUFFER_DEFAULT;
\r
67 card->rxBufPtr = card->rxBufBase;
\r
68 card->asyncTxBufPtr = card->asyncTxBufBase;
\r
69 card->syncTxBufPtr = card->syncTxBufBase;
\r
70 card->commandRegister = card->baseAddressPtr+CL2_COMMAND_REGISTER;
\r
71 card->dataPtr = card->baseAddressPtr + CL2_DATA_BUFFER;
\r
72 card->rxBufSize = CL2_RX_BUFFER_SIZE;
\r
73 card->syncTxBufSize = CL2_TX_SYNC_BUFFER_SIZE;
\r
74 card->asyncTxBufSize = CL2_TX_ASYNC_BUFFER_SIZE;
\r
76 for ( i = 0; i < 10; i++ ) card->rtrSub[i] = 0xFFFFFFFFL;
\r
78 } /* cl2_init_card */
\r
81 /*******************************************************************************
\r
82 * cl2_test_card - test card
\r
85 * Test whether the card is installed in system and working properly
\r
86 * or not. If this function fails (return value is CL2_HW_FAILURE)
\r
87 * check if the card is present and card base address.
\r
90 * CL2_OK - card is present and working properly
\r
91 * CL2_HW_FAILURE - card not found or card error
\r
94 eCL2_RESULT cl2_test_card
\r
96 sCAN_CARD *card /* Pointer to card structure */
\r
99 BOOLEAN1 isAA = FALSE, is55 = FALSE;
\r
101 U16 volatile tmpWord;
\r
103 /* timeout for card testing - 1000 read cycles */
\r
104 for ( i = 0; i < 10000; i++ )
\r
106 if ( isAA && is55 ) return CL2_OK;
\r
107 tmpWord = *((volatile U16*)(card->baseAddressPtr));
\r
108 /*printk("cl2_test_card: %08lx %04x\n", (long)card->baseAddressPtr, tmpWord);*/
\r
110 if ( (tmpWord & 0x00FF) == 0x00AA ) isAA = TRUE;
\r
111 if ( (tmpWord & 0x00FF) == 0x0055 ) is55 = TRUE;
\r
114 return CL2_HW_FAILURE;
\r
115 } /* cl2_test_card */
\r
118 /*******************************************************************************
\r
119 * cl2_reset_card - reset card
\r
122 * Card pointed by *card gets hardware reset. This command resets
\r
123 * card processor, card settings are restored to their default
\r
127 * CL2_OK - command completed successfuly
\r
130 eCL2_RESULT cl2_reset_card
\r
132 sCAN_CARD *card /* Pointer to card structure */
\r
135 *((U16*)(card->baseAddressPtr + CL2_RESET_REGISTER)) = 0x0000;
\r
137 } /* cl2_reset_card */
\r
140 /*******************************************************************************
\r
141 * cl2_get_version - read card version
\r
144 * Fucntion reads a value from card version register.
\r
147 * CL2_OK - command completed successfuly
\r
150 eCL2_RESULT cl2_get_version
\r
152 sCAN_CARD *card, /* Pointer to card structure */
\r
153 U16 *version /* returns card version */
\r
156 *version = *((U16*)(card->baseAddressPtr + CL2_VERSION_REGISTER));
\r
158 } /* cl2_get_version */
\r
161 /*******************************************************************************
\r
162 * cl2_gen_interrupt - request for interrupt
\r
163 * """""""""""""""""
\r
165 * CAN card is requested to generate interrupt if there is any reason
\r
166 * to do it. The condition for interrupt generation is defined by
\r
167 * cl2_int_mode command.
\r
170 * CL2_OK - command completed successfuly
\r
173 eCL2_RESULT cl2_gen_interrupt
\r
175 sCAN_CARD *card /* Pointer to card structure */
\r
178 *((U16*)(card->baseAddressPtr + CL2_GEN_INT_REGISTER)) = 0x0000;
\r
180 } /* cl2_gen_interrupt */
\r
183 /*******************************************************************************
\r
184 * cl2_start_it - start inhibit time
\r
187 * Command starts interrupt inhibit time. If there is any reason for
\r
188 * interrupt geneation, the card generates interrupt after end of
\r
189 * specified time interval. Time interval is set by cl2_set_iit command.
\r
192 * CL2_OK - command completed successfuly
\r
195 eCL2_RESULT cl2_start_it
\r
197 sCAN_CARD *card /* Pointer to card structure */
\r
200 *((U16*)(card->baseAddressPtr + CL2_START_IT_REGISTER)) = 0x0000;
\r
202 } /* cl2_start_it */
\r
205 /*******************************************************************************
\r
206 * cl2_clear_interrupt - clear interrupt
\r
207 * """""""""""""""""""
\r
209 * Comand clears interrupt (IRQ) generated by a card.
\r
212 * CL2_OK - command completed successfuly
\r
215 eCL2_RESULT cl2_clear_interrupt
\r
217 sCAN_CARD *card /* Pointer to card structure */
\r
220 *((U16*)(card->baseAddressPtr + CL2_CLEAR_INT_REGISTER)) = 0x0000;
\r
222 } /* cl2_clear_interrupt */
\r
225 /*******************************************************************************
\r
226 * cl2_int_mode - set interrupt mode
\r
229 * Command controls, which event will generate interrupt. Constants
\r
230 * CL2_INT_XXXX are used for setting of interrupt mode.
\r
233 * CL2_OK - command completed successfuly
\r
234 * CL2_BAD_PARAM - bad command parameter
\r
235 * CL2_COMMAND_BUSY - previous command not completed
\r
238 eCL2_RESULT cl2_int_mode
\r
240 sCAN_CARD *card, /* Pointer to card structure */
\r
241 U16 mode /* Interrupt mode */
\r
244 if ( mode > INT_MODE_ALL ) return CL2_BAD_PARAM;
\r
245 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
246 return CL2_COMMAND_BUSY;
\r
247 *((U16*)card->dataPtr) = mode;
\r
248 *((U16*)card->commandRegister) = ((U16)cmCL2_INT_MODE + CL2_COMMAND_VALID);
\r
250 } /* cl2_int_mode */
\r
253 /*******************************************************************************
\r
254 * cl2_iit_mode - inhibit interrupt time mode
\r
257 * Command enables/disables inhibit interupt time mode.
\r
260 * CL2_OK - command completed successfuly
\r
261 * CL2_COMMAND_BUSY - previous command not completed
\r
264 eCL2_RESULT cl2_iit_mode
\r
266 sCAN_CARD *card, /* Pointer to card structure */
\r
267 BOOLEAN1 onoff /* IIT mode - TRUE=on, FALSE=off */
\r
270 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID ) return
\r
272 *((U16*)card->dataPtr) = (U16)onoff;
\r
273 *((U16*)card->commandRegister) = ((U16)cmCL2_IIT_MODE + CL2_COMMAND_VALID);
\r
275 } /* cl2_iit_mode */
\r
278 /*******************************************************************************
\r
279 * cl2_sync_mode - sync mode
\r
282 * Command enables/disables transmission of SYNC frames.
\r
285 * CL2_OK - command completed successfuly
\r
286 * CL2_COMMAND_BUSY - previous command not completed
\r
289 eCL2_RESULT cl2_sync_mode
\r
291 sCAN_CARD *card, /* Pointer to card structure */
\r
292 BOOLEAN1 onoff /* Sync mode - TRUE=on, FALSE=off */
\r
295 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
296 return CL2_COMMAND_BUSY;
\r
297 *((U16*)card->dataPtr) = (U16)onoff;
\r
298 *((U16*)card->commandRegister) = ((U16)cmCL2_SYNC_MODE + CL2_COMMAND_VALID);
\r
300 } /* cl2_sync_mode */
\r
303 /*******************************************************************************
\r
304 * cl2_rtr_mode - rtr mode
\r
307 * Command enables/disables automatic transmission of RTR frames
\r
310 * CL2_OK - command completed successfuly
\r
311 * CL2_COMMAND_BUSY - previous command not completed
\r
314 eCL2_RESULT cl2_rtr_mode
\r
316 sCAN_CARD *card, /* Pointer to card structure */
\r
317 BOOLEAN1 onoff /* RTR mode - TRUE=on, FALSE=off */
\r
320 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
321 return CL2_COMMAND_BUSY;
\r
322 *((U16*)card->dataPtr) = (U16)onoff;
\r
323 *((U16*)card->commandRegister) = ((U16)cmCL2_RTR_MODE + CL2_COMMAND_VALID);
\r
325 } /* cl2_rtr_mode */
\r
328 /*******************************************************************************
\r
329 * cl2_buf_size - size of synchronous queue
\r
332 * Command sets the size of synchronous send buffer. The size is
\r
333 * in numbers of messages. Default buffer size is 32 messages.
\r
334 * The sum of synchronous_buffer_size and asynchronous_buffer_size
\r
335 * is constant and equal to 64. So, if the size od synchronous
\r
336 * buffer increases, the size of asynchronous buffer decreases and
\r
338 * NOTE: 1 message = 16 bytes
\r
341 * CL2_OK - command completed successfully
\r
342 * CL2_COMMAND_BUSY - previous command not completed
\r
343 * CL2_BAD_PARAM - bad command parameter (bufSize>64)
\r
346 eCL2_RESULT cl2_buf_size
\r
348 sCAN_CARD *card, /* Pointer to card structure */
\r
349 U16 bufSize /* Size of synchronous buffer */
\r
352 if ( bufSize > 64 ) return CL2_BAD_PARAM;
\r
353 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
354 return CL2_COMMAND_BUSY;
\r
355 *((U16*)card->dataPtr) = bufSize;
\r
356 *((U16*)card->commandRegister) = ((U16)cmCL2_BUF_SIZE + CL2_COMMAND_VALID);
\r
357 card->syncTxBufSize = bufSize;
\r
358 card->asyncTxBufSize = 64 - bufSize;
\r
359 card->syncTxBufPtr = card->syncTxBufBase;
\r
360 card->asyncTxBufPtr = card->asyncTxBufBase = card->syncTxBufBase+bufSize*16;
\r
362 } /* cl2_buf_size */
\r
365 /*******************************************************************************
\r
366 * cl2_set_iit - set value of inhibit interrupt time
\r
369 * Command sets value of inhibit interrupt time. If inhibit
\r
370 * interrupt time mode is enabled and started, generation of
\r
371 * interrupt (IRQ) is disabled during this time period.
\r
372 * Inhibit interrupt time can be set from 100 us to 6.5535 s
\r
375 * CL2_OK - command completed successfuly
\r
376 * CL2_COMMAND_BUSY - previous command not completed
\r
379 eCL2_RESULT cl2_set_iit
\r
381 sCAN_CARD *card, /* Pointer to card structure */
\r
382 U16 iit /* time period in x100 us */
\r
385 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
386 return CL2_COMMAND_BUSY;
\r
387 *((U16*)card->dataPtr) = iit;
\r
388 *((U16*)card->commandRegister) = ((U16)cmCL2_SET_IIT + CL2_COMMAND_VALID);
\r
390 } /* cl2_set_iit */
\r
393 /*******************************************************************************
\r
394 * cl2_start_firmware - start firmware
\r
395 * """"""""""""""""""
\r
397 * Command starts card firmware
\r
400 * CL2_OK - command completed successfuly
\r
401 * CL2_COMMAND_BUSY - previous command not completed
\r
404 eCL2_RESULT cl2_start_firmware
\r
406 sCAN_CARD *card /* Pointer to card structure */
\r
409 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
410 return CL2_COMMAND_BUSY;
\r
411 *((U16*)card->commandRegister) = ((U16)cmCL2_START_FIRMWARE +
\r
412 CL2_COMMAND_VALID);
\r
414 } /* cl2_start_firmware */
\r
417 /*******************************************************************************
\r
418 * cl2_set_rec_mode - set receive mode
\r
421 * Command sets card receive mode. This enable reception of standard
\r
422 * or extended frames according to CAN 2.0A and 2.0B specifications.
\r
423 * If value of mode is TRUE, card receives extended frames, if mode
\r
424 * is FALSE, card receives standard massage format (default).
\r
427 * CL2_OK - command completed successfuly
\r
428 * CL2_COMMAND_BUSY - previous command not completed
\r
431 eCL2_RESULT cl2_set_rec_mode
\r
433 sCAN_CARD *card, /* Pointer to card structure */
\r
434 BOOLEAN1 mode /* Mode - TRUE=ext, FALSE=std */
\r
437 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
438 return CL2_COMMAND_BUSY;
\r
439 *((U16*)card->dataPtr) = (U16)mode;
\r
440 *((U16*)card->commandRegister) = ((U16)cmCL2_SET_REC_MODE +
\r
441 CL2_COMMAND_VALID);
\r
443 } /* cl2_set_rec_mode */
\r
446 /*******************************************************************************
\r
447 * cl2_clr_rx_buffer - clear RX buffer
\r
448 * """""""""""""""""
\r
450 * Command clears receive (rx) buffer. All messages stored in
\r
451 * rx buffer will be lost.
\r
454 * CL2_OK - command completed successfuly
\r
455 * CL2_COMMAND_BUSY - previous command not completed
\r
458 eCL2_RESULT cl2_clr_rx_buffer
\r
460 sCAN_CARD *card /* Pointer to card structure */
\r
463 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
464 return CL2_COMMAND_BUSY;
\r
465 card->rxBufPtr = card->rxBufBase;
\r
466 *((U16*)card->commandRegister) = ((U16)cmCL2_CLR_RX_BUFFER +
\r
467 CL2_COMMAND_VALID);
\r
469 } /* cl2_clr_rx_buffer */
\r
472 /*******************************************************************************
\r
473 * cl2_clr_sync_buffer - clear synchronous buffer
\r
474 * """""""""""""""""""
\r
476 * Command clears synchronous send buffer. All messages stored
\r
477 * in synchronous buffer will be lost.
\r
480 * CL2_OK - command completed successfuly
\r
481 * CL2_COMMAND_BUSY - previous command not completed
\r
484 eCL2_RESULT cl2_clr_sync_buffer
\r
486 sCAN_CARD *card /* Pointer to card structure */
\r
489 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
490 return CL2_COMMAND_BUSY;
\r
491 card->syncTxBufPtr = card->syncTxBufBase;
\r
492 *((U16*)card->commandRegister) = ((U16)cmCL2_CLR_SYNC_BUFFER +
\r
493 CL2_COMMAND_VALID);
\r
495 } /* cl2_clr_sync_buffer */
\r
498 /*******************************************************************************
\r
499 * cl2_clr_async_buffer - clear asynchronous buffer
\r
500 * """"""""""""""""""""
\r
502 * Command clears asynchronnous send buffer. All messages stored
\r
503 * in async buffer will be lost.
\r
506 * CL2_OK - command completed successfuly
\r
507 * CL2_COMMAND_BUSY - previous command not completed
\r
510 eCL2_RESULT cl2_clr_async_buffer
\r
512 sCAN_CARD *card /* Pointer to card structure */
\r
515 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
516 return CL2_COMMAND_BUSY;
\r
517 card->asyncTxBufPtr = card->syncTxBufBase + card->syncTxBufSize*16;
\r
518 *((U16*)card->commandRegister) = ((U16)cmCL2_CLR_ASYNC_BUFFER +
\r
519 CL2_COMMAND_VALID);
\r
521 } /* cl2_clr_async_buffer */
\r
524 /*******************************************************************************
\r
525 * cl2_send_time_sync - send time synchronization
\r
526 * """"""""""""""""""
\r
528 * Command forces the card to start the High Resolution Synchronization
\r
529 * Protocol according to the CANopen Communication profile. The SYNC
\r
530 * mode has to be enabled (cl2_sync_mode) otherwise this command has
\r
534 * CL2_OK - command completed successfuly
\r
535 * CL2_COMMAND_BUSY - previous command not completed
\r
538 eCL2_RESULT cl2_send_time_sync
\r
540 sCAN_CARD *card /* Pointer to card structure */
\r
543 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID ) return
\r
545 *((U16*)card->commandRegister) = ((U16)cmCL2_SEND_TIME_SYNC +
\r
546 CL2_COMMAND_VALID);
\r
548 } /* cl2_send_time_sync */
\r
551 /*******************************************************************************
\r
552 * cl2_set_time_cobid - set time COB-ID
\r
553 * """"""""""""""""""
\r
555 * Command sets the COB-ID for high resolution synchronization
\r
556 * frame. The synchronization can be then made by means of
\r
557 * cl2_send_time_sync command.
\r
560 * CL2_OK - command completed successfuly
\r
561 * CL2_COMMAND_BUSY - previous command not completed
\r
564 eCL2_RESULT cl2_set_time_cobid
\r
566 sCAN_CARD *card, /* Pointer to card structure */
\r
567 U32 COBID /* HRS frame COB-ID */
\r
570 U16 cobidL, cobidH;
\r
571 U16 *ptr = (U16 *)card->dataPtr;
\r
573 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
574 return CL2_COMMAND_BUSY;
\r
576 if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */
\r
579 cobidL = (U16)(COBID & 0x0000FFFFL);
\r
580 cobidH = (U16)((COBID & 0xFFFF0000L)>>16);
\r
581 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
\r
583 cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));
\r
585 *ptr = CL2_TMP_EX2;
\r
590 cobidH = (U16)(COBID & 0x0000FFFFL);
\r
591 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
\r
597 *((U16*)card->commandRegister) = ((U16)cmCL2_SET_TIME_COBID +
\r
598 CL2_COMMAND_VALID);
\r
600 } /* cl2_set_time_cobid */
\r
603 /*******************************************************************************
\r
604 * cl2_set_receive_limit - set limit for receive signaling
\r
605 * """""""""""""""""""""
\r
607 * Command is used to set the receive limit signalized by bit
\r
608 * RL (in CL2.H CL2_X_DATA_IN_RBUF) of the Status Register.
\r
609 * This bit is set when more then the limit number of frames
\r
610 * was received since the last interrupt was generated (in interrupt
\r
611 * mode) or since the Status Register was last time read.
\r
615 * CL2_COMMAND_BUSY - previous command not completed
\r
616 * CL2_BAD_PARAM - bad command parameter
\r
618 eCL2_RESULT cl2_set_receive_limit
\r
620 sCAN_CARD *card, /* pointer to card structure */
\r
621 U16 limit /* limit of messages in receive buffer */
\r
624 if ( limit > 127 ) return CL2_BAD_PARAM;
\r
625 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
626 return CL2_COMMAND_BUSY;
\r
627 *((U16*)card->dataPtr) = limit;
\r
628 *((U16*)card->commandRegister) = ((U16)cmCL2_SET_RECEIVE_LIMIT +
\r
629 CL2_COMMAND_VALID);
\r
631 } /* cl2_set_receive_limit */
\r
634 /*******************************************************************************
\r
635 * cl2_download_rtr_list - download rtr list
\r
636 * """""""""""""""""""""
\r
638 * Command downloads a list of up to 64 RTR frames. These frames are
\r
639 * periodically transmitted by the card. The parameters, how often
\r
640 * frames are send and in which SYNC period is defined by period and
\r
641 * subperiod in sRTR_FRAME structure.
\r
644 * CL2_OK - command completed successfuly
\r
645 * CL2_COMMAND_BUSY - previous command not completed
\r
646 * CL2_BAD_PARAM - bad command parameter
\r
649 eCL2_RESULT cl2_download_rtr_list
\r
651 sCAN_CARD *card, /* Pointer to card structure */
\r
652 sRTR_LIST *rtrList /* RTR list */
\r
655 U16 *ptrTmp = (U16*)card->dataPtr;
\r
656 sRTR_FRAME *ptrRTR = rtrList->data;
\r
659 U16 cobidH, cobidL, i;
\r
661 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID ) return
\r
663 if ( rtrList->nb > 64 ) return CL2_BAD_PARAM;
\r
665 *ptrTmp++ = (U16)rtrList->nb;
\r
666 for ( i = 0; i < rtrList->nb; i++ )
\r
668 if ( ptrRTR->period < ptrRTR->subperiod ) return CL2_BAD_PARAM;
\r
669 if ( ptrRTR->subperiod == 0 ) ptrRTR->subperiod = 1;
\r
670 tmpU16 = (ptrRTR->period & 0x00FF) + ((ptrRTR->subperiod & 0x00FF)<<8);
\r
671 *ptrTmp++ = tmpU16;
\r
672 COBID = ptrRTR->cob_id;
\r
674 if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */
\r
677 cobidL = (U16)(COBID & 0x0000FFFFL);
\r
678 cobidH = (U16)((COBID & 0xFFFF0000L)>>16);
\r
679 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
\r
680 *ptrTmp++ = cobidH;
\r
681 cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));
\r
682 *ptrTmp++ = cobidL;
\r
687 cobidH = (U16)(COBID & 0x0000FFFFL);
\r
688 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
\r
689 *ptrTmp++ = cobidH;
\r
693 *ptrTmp++ = 0x0000; /* rezerva */
\r
697 *((U16*)card->commandRegister) = ((U16)cmCL2_DOWNLOAD_RTR_LIST +
\r
698 CL2_COMMAND_VALID);
\r
700 } /* cl2_download_rtrlist */
\r
703 /*******************************************************************************
\r
704 * cl2_subscribe_rtr - subscribe RTR frame
\r
705 * """""""""""""""""
\r
707 * Command subscribes RTR frame. Incoming RTR frames which were
\r
708 * subscribed are accepted, while other are ignored. Up to 10
\r
709 * RTR frames can be subscribed.
\r
712 * CL2_OK - command completed successfuly
\r
713 * CL2_COMMAND_BUSY - previous command not completed
\r
714 * CL2_BAD_PARAM - bad command parameter
\r
717 eCL2_RESULT cl2_subscribe_rtr
\r
719 sCAN_CARD *card, /* Pointer to card structure */
\r
720 sCAN_MESSAGE *canMessage, /* RTR frame */
\r
721 U16 RTRnumber /* number of RTR */
\r
724 U16 *ptrU16 = (U16*)card->dataPtr;
\r
726 U16 cobidH, cobidL;
\r
728 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
729 return CL2_COMMAND_BUSY;
\r
730 if ( RTRnumber > 9 ) return CL2_BAD_PARAM;
\r
732 card->rtrSub[RTRnumber] = canMessage->COB_ID;
\r
733 *ptrU16 = RTRnumber;
\r
735 COBID = canMessage->COB_ID;
\r
737 if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */
\r
740 cobidL = (U16)(COBID & 0x0000FFFFL);
\r
741 cobidH = (U16)((COBID & 0xFFFF0000L)>>16);
\r
742 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
\r
743 *ptrU16++ = cobidH;
\r
744 cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));
\r
745 *ptrU16++ = cobidL;
\r
746 *ptrU16 = (U16)CL2_EXT_FRAME;
\r
751 cobidH = (U16)(COBID & 0x0000FFFFL);
\r
752 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
\r
753 *ptrU16++ = cobidH;
\r
758 *((U16*)card->commandRegister) = ((U16)cmCL2_SUBSCRIBE_RTR +
\r
759 CL2_COMMAND_VALID);
\r
761 } /* cl2_subscribe_rtr */
\r
764 /*******************************************************************************
\r
765 * cl2_desubscribe_rtr - desubscribe rtr frame
\r
766 * """""""""""""""""""
\r
768 * Command desubscribes RTR frame. Card will not accept RTR frames
\r
769 * with this identifier.
\r
772 * CL2_OK - command completed successfuly
\r
773 * CL2_COMMAND_BUSY - previous command not completed
\r
774 * CL2_BAD_PARAM - bad command parameter
\r
777 eCL2_RESULT cl2_desubscribe_rtr
\r
779 sCAN_CARD *card, /* Pointer to card structure */
\r
780 sCAN_MESSAGE *canMessage /* RTR frame */
\r
785 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
786 return CL2_COMMAND_BUSY;
\r
788 for ( i = 0; i < 10; i++ )
\r
790 if ( card->rtrSub[i] == canMessage->COB_ID )
\r
792 card->rtrSub[i] = 0xFFFFFFFFL;
\r
797 if ( i >= 10 ) return CL2_BAD_PARAM;
\r
799 *((U16*)card->dataPtr) = i;
\r
800 *((U16*)card->commandRegister) = ((U16)cmCL2_DESUBSCRIBE_RTR +
\r
801 CL2_COMMAND_VALID);
\r
803 } /* cl2_desubscribe_rtr */
\r
807 /*******************************************************************************
\r
808 * cl2_set_sync_cobid - set COB-ID
\r
809 * """"""""""""""""""
\r
811 * Command sets COB-ID of SYNC frame. In active SYNC mode, the SYNC
\r
812 * frame with this COB-ID is periodically sent with period defined
\r
813 * by cl2_set_sync_period command.
\r
816 * CL2_OK - command completed successfuly
\r
817 * CL2_COMMAND_BUSY - previous command not completed
\r
820 eCL2_RESULT cl2_set_sync_cobid
\r
822 sCAN_CARD *card, /* Pointer to card structure */
\r
823 U32 COBID /* COB-ID */
\r
826 U16 cobidL, cobidH;
\r
827 U16 *ptr = (U16 *)card->dataPtr;
\r
829 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
830 return CL2_COMMAND_BUSY;
\r
832 if ( COBID & CL2_TMP_EXHIGH ) /* standard or extended format? */
\r
835 cobidL = (U16)(COBID & 0x0000FFFFL);
\r
836 cobidH = (U16)((COBID & 0xFFFF0000L)>>16);
\r
837 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
\r
839 cobidL = ((cobidL >> 8) & 0x00FF) | (((cobidL << 8) & 0xFF00));
\r
841 *ptr = CL2_TMP_EX2;
\r
846 cobidH = (U16)(COBID & 0x0000FFFFL);
\r
847 cobidH = ((cobidH >> 8) & 0x00FF) | (((cobidH << 8) & 0xFF00));
\r
853 *((U16*)card->commandRegister) = ((U16)cmCL2_SET_COBID + CL2_COMMAND_VALID);
\r
855 } /* cl2_set_sync_cobid */
\r
858 /*******************************************************************************
\r
859 * cl2_set_sync_period - set SYNC period
\r
860 * """""""""""""""""""
\r
862 * Coomand sets the SYNC frame send period in active SYNC mode in
\r
863 * x100 us. The period range is from 0 to 0xFFFF (SYNC period can
\r
864 * be set from 100us to 6.5535s).
\r
867 * CL2_OK - command completed successfuly
\r
868 * CL2_COMMAND_BUSY - previous command not completed
\r
871 eCL2_RESULT cl2_set_sync_period
\r
873 sCAN_CARD *card, /* Pointer to card structure */
\r
874 U16 period /* period in x100 us */
\r
877 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
878 return CL2_COMMAND_BUSY;
\r
879 *((U16*)card->dataPtr) = (U16)period;
\r
880 *((U16*)card->commandRegister) = ((U16)cmCL2_SET_SYNC_PERIOD +
\r
881 CL2_COMMAND_VALID);
\r
883 } /* cl2_set_sync_period */
\r
886 /*******************************************************************************
\r
887 * cl2_set_sync_window - set SYNC window
\r
888 * """""""""""""""""""
\r
890 * Command sets the SYNC window length. Only during this time period
\r
891 * after SYNC frame was send or receive the frames from the synchronous
\r
892 * send buffer can be sent.
\r
895 * CL2_OK - command completed successfuly
\r
896 * CL2_COMMAND_BUSY - previous command not completed
\r
899 eCL2_RESULT cl2_set_sync_window
\r
901 sCAN_CARD *card, /* Pointer to card structure */
\r
902 U16 window /* period in x100 us */
\r
905 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
906 return CL2_COMMAND_BUSY;
\r
907 *((U16*)card->dataPtr) = (U16)window;
\r
908 *((U16*)card->commandRegister) = ((U16)cmCL2_SET_SYNC_WINDOW +
\r
909 CL2_COMMAND_VALID);
\r
911 } /* cl2_set_sync_window */
\r
914 /*******************************************************************************
\r
915 * cl2_set_bitrate - set CAN bit-rate
\r
918 * Command switches the bus bit-rate. There are some predefined
\r
919 * constants CL2_BITRATE_XXXX.
\r
922 * CL2_OK - command completed successfuly
\r
923 * CL2_COMMAND_BUSY - previous command not completed
\r
926 eCL2_RESULT cl2_set_bitrate
\r
928 sCAN_CARD *card, /* Pointer to card structure */
\r
929 U16 bitrate /* CAN bitrate */
\r
932 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
933 return CL2_COMMAND_BUSY;
\r
934 *((U16*)card->dataPtr) = bitrate;
\r
935 *((U16*)card->commandRegister) = ((U16)cmCL2_SET_BITRATE +
\r
936 CL2_COMMAND_VALID);
\r
938 } /* cl2_set_bitrate */
\r
941 /*******************************************************************************
\r
942 * cl2_bus_reset - resets CAN controller
\r
945 * Command resets CAN controller
\r
948 * CL2_OK - command completed successfuly
\r
949 * CL2_COMMAND_BUSY - previously command not completed
\r
952 eCL2_RESULT cl2_bus_reset
\r
957 if ( *(U16*)card->commandRegister & CL2_COMMAND_VALID )
\r
958 return CL2_COMMAND_BUSY;
\r
959 *((U16*)card->commandRegister) = ((U16)cmCL2_BUS_RESET +
\r
960 CL2_COMMAND_VALID);
\r
962 } /* cl2_bus_reset */
\r
965 /*******************************************************************************
\r
966 * cl2_send_sync - sends synchronous frame
\r
969 * Command stores massage in synchronous send buffer.
\r
972 * CL2_OK - command completed successfuly
\r
973 * CL2_HW_QUEUE_FULL - synchronous send buffer is full
\r
974 * CL2_BAD_PARAM - bad command parameter
\r
975 * CL2_HW_FAILURE - error in HW configuration
\r
978 eCL2_RESULT cl2_send_sync
\r
980 sCAN_CARD *card, /* pointer to card */
\r
981 sCAN_MESSAGE *message /* massage to be sent */
\r
986 U16 *ptrU16 = (U16*)card->syncTxBufPtr;
\r
991 if ( card->syncTxBufSize==0 ) return CL2_HW_FAILURE;
\r
992 if ( message->dataLength > 8 ) return CL2_BAD_PARAM;
\r
993 if ( *ptrU16 & CL2_FRAME_VALID ) return CL2_HW_QUEUE_FULL;
\r
995 cobid = message->COB_ID;
\r
996 if ( (message->dataType & CL2_EXT_FRAME) || (cobid & CL2_TMP_EXHIGH) )
\r
999 cobidL = (U16)(cobid & 0x0000FFFFL);
\r
1000 cobidH = (U16)((cobid & 0xFFFF0000L)>>16);
\r
1003 { /* 2.0A frame */
\r
1006 cobidH = (U16)(cobid & 0x0000FFFFL);
\r
1009 tmpU16 = (cobidH & 0x00FF) + (cobidL & 0xFF00);
\r
1010 *ptrU16++ = tmpU16;
\r
1012 tmpU16 = (((U16)message->dataLength) << 12) + (cobidL & 0x00FF);
\r
1013 if ( !(message->dataType & CL2_REMOTE_FRAME) ) tmpU16 |= CL2_TMP_RF;
\r
1014 if ( (message->dataType & CL2_EXT_FRAME) ||
\r
1015 (message->COB_ID & CL2_TMP_EXHIGH) )
\r
1016 tmpU16 |= CL2_TMP_EX;
\r
1017 *ptrU16++ = tmpU16;
\r
1019 for ( i = 0; i < message->dataLength; )
\r
1021 tmpU16 = (U16)message->data[i]; i++;
\r
1022 if ( i == message->dataLength )
\r
1025 tmpU16 |= ((message->timeStamp & 0x00FF)<<8);
\r
1026 *ptrU16++ = tmpU16;
\r
1030 tmpU16 |= ((U16)message->data[i]<<8); i++;
\r
1031 *ptrU16++ = tmpU16;
\r
1036 tmpU16 = (message->timeStamp>>8) & 0x00FF;
\r
1041 *ptrU16 = message->timeStamp;
\r
1044 tmpU16 = (((U16)cobidH) & 0xFF00) | CL2_MESSAGE_VALID;
\r
1045 *(U16*)card->syncTxBufPtr = tmpU16;
\r
1047 if ( (card->syncTxBufBase + card->syncTxBufSize*16) <=
\r
1048 (card->syncTxBufPtr += 16) )
\r
1050 card->syncTxBufPtr = card->syncTxBufBase;
\r
1053 } /* cl2_send_sync */
\r
1056 /*******************************************************************************
\r
1057 * cl2_send_async - sends asynchronous frame
\r
1060 * Command stores message in asynchronous send buffer.
\r
1063 * CL2_OK - command completed successfuly
\r
1064 * CL2_HW_QUEUE_FULL - asynchronous buffer full
\r
1065 * CL2_HW_FAILURE - error in HW configuration
\r
1066 * CL2_BAD_PARAM - bad command parameter
\r
1069 eCL2_RESULT cl2_send_async
\r
1071 sCAN_CARD *card, /* pointer to card */
\r
1072 sCAN_MESSAGE *message /* message to be sent */
\r
1076 U16 cobidL,cobidH;
\r
1077 U16 *ptrU16 = (U16*)card->asyncTxBufPtr;
\r
1080 int timeStamp = 0;
\r
1082 if ( card->asyncTxBufSize==0 ) return CL2_HW_FAILURE;
\r
1083 if ( message->dataLength > 8 ) return CL2_BAD_PARAM;
\r
1084 if ( *ptrU16 & CL2_FRAME_VALID ) return CL2_HW_QUEUE_FULL;
\r
1086 cobid = message->COB_ID;
\r
1087 if ( (message->dataType & CL2_EXT_FRAME) || (cobid & CL2_TMP_EXHIGH) )
\r
1088 { /* 2.0B frame */
\r
1090 cobidL = (U16)(cobid & 0x0000FFFFL);
\r
1091 cobidH = (U16)((cobid & 0xFFFF0000L)>>16);
\r
1094 { /* 2.0A frame */
\r
1097 cobidH = (U16)(cobid & 0x0000FFFFL);
\r
1100 tmpU16 = (cobidH & 0x00FF ) + (cobidL & 0xFF00);
\r
1101 *ptrU16++ = tmpU16;
\r
1103 tmpU16 = (((U16)message->dataLength) << 12) + (cobidL & 0x00FF);
\r
1104 if ( !(message->dataType & CL2_REMOTE_FRAME) ) tmpU16 |= CL2_TMP_RF;
\r
1105 if ( (message->dataType & CL2_EXT_FRAME) ||
\r
1106 (message->COB_ID & CL2_TMP_EXHIGH ) )
\r
1107 tmpU16 |= CL2_TMP_EX;
\r
1108 *ptrU16++ = tmpU16;
\r
1110 for ( i = 0; i < message->dataLength; )
\r
1112 tmpU16 = (U16)message->data[i]; i++;
\r
1113 if ( i == message->dataLength )
\r
1116 tmpU16 |= ((message->timeStamp & 0x00FF)<<8);
\r
1117 *ptrU16++ = tmpU16;
\r
1121 tmpU16 |= ((U16)message->data[i]<<8); i++;
\r
1122 *ptrU16++ = tmpU16;
\r
1127 tmpU16 = (message->timeStamp>>8) & 0x00FF;
\r
1132 *ptrU16 = message->timeStamp;
\r
1135 tmpU16 = (((U16)cobidH) & 0xFF00) | CL2_MESSAGE_VALID;
\r
1136 *(U16*)card->asyncTxBufPtr = tmpU16;
\r
1138 if ( (card->asyncTxBufBase + card->asyncTxBufSize*16) <=
\r
1139 (card->asyncTxBufPtr += 16) )
\r
1141 card->asyncTxBufPtr = card->asyncTxBufBase;
\r
1144 } /* cl2_send_async */
\r
1147 /*******************************************************************************
\r
1148 * cl2_get_status - reads card status
\r
1151 * Command reads card status register. If data in status register
\r
1152 * are valid (status valid flag is set), the value of status is read
\r
1153 * and stored in status and sCAN_CARD structure.
\r
1156 * CL2_OK - command completed successfuly
\r
1157 * CL2_NO_REQUEST - status is not valid
\r
1160 eCL2_RESULT cl2_get_status
\r
1162 sCAN_CARD *card, /* pointer to card */
\r
1163 U16 *status /* card status word */
\r
1168 ptr = (U16*)(card->baseAddressPtr + CL2_STATUS_REGISTER);
\r
1170 if ( (*status & CL2_STATUS_VALID_FLAG) )
\r
1172 *ptr = *status & ~CL2_STATUS_VALID_FLAG;
\r
1173 card->status = *status;
\r
1176 return CL2_NO_REQUEST;
\r
1177 } /* cl2_get_status */
\r
1180 /*******************************************************************************
\r
1181 * cl2_get_error - reads card error
\r
1184 * Command reads card error register. If data in error register
\r
1185 * are valid (error register valid flag is set), the value of error
\r
1186 * register is read and stored in error and sCAN_CARD structure.
\r
1189 * Cl2_OK - command completed successfuly
\r
1192 eCL2_RESULT cl2_get_error
\r
1194 sCAN_CARD *card, /* pointer to card */
\r
1195 U16 *error /* card error word */
\r
1200 ptr = (U16*)(card->baseAddressPtr + CL2_ERROR_REGISTER);
\r
1202 card->error |= *error;
\r
1205 } /* cl2_get_error */
\r
1208 /*******************************************************************************
\r
1209 * cl2_receive_data - reads received frame
\r
1210 * """"""""""""""""
\r
1212 * Command reads new messages received by a card.
\r
1215 * CL2_OK - command commpleted successfuly
\r
1216 * CL2_NO_REQUEST - there is no new message
\r
1219 eCL2_RESULT cl2_receive_data
\r
1221 sCAN_CARD *card, /* Pointer to card structure */
\r
1222 sCAN_MESSAGE *canMessage /* Message */
\r
1225 U16 *ptrU16 = (U16*)card->rxBufPtr;
\r
1229 tmpU16 = *ptrU16++;
\r
1230 if ( !(tmpU16 & CL2_MESSAGE_VALID) ) return CL2_NO_REQUEST;
\r
1231 canMessage->COB_ID = ((U32)(tmpU16 & 0xFF00 )) << 16;
\r
1232 tmpU16 = *ptrU16++;
\r
1233 canMessage->COB_ID |= ((U32)( tmpU16 & 0x00FF )) << 16;
\r
1234 canMessage->COB_ID |= (U32)( tmpU16 & 0xFF00 );
\r
1235 tmpU16 = *ptrU16++;
\r
1236 canMessage->COB_ID |= (U32)( tmpU16 & 0x00FF );
\r
1237 canMessage->dataType = (U8)(( tmpU16 & 0xFF00 ) >> 8);
\r
1239 if ( canMessage->dataType & CL2_EXT_FRAME )
\r
1240 { /* 2.0B frame */
\r
1241 canMessage->COB_ID >>= 3;
\r
1242 /* canMessage->COB_ID |= CL2_TMP_EXHIGH; */
\r
1245 { /* 2.0A frame */
\r
1246 canMessage->COB_ID >>= 21;
\r
1248 canMessage->dataLength = (U8)( (tmpU16 >> 12) & 0x000F );
\r
1249 /* if ( !(tmpU16 & CL2_TMP_RF) ) canMessage->dataType |= CL2_REMOTE_FRAME; */
\r
1250 for ( i = 0; i < canMessage->dataLength; )
\r
1252 tmpU16 = *ptrU16++;
\r
1253 canMessage->data[i++] = (U8)( tmpU16 );
\r
1254 canMessage->data[i++] = (U8)( tmpU16 >> 8 );
\r
1256 if ( canMessage->dataLength & 0x01 )
\r
1258 canMessage->timeStamp = ( (*ptrU16 & 0x00FF) | (tmpU16 & 0xFF00) );
\r
1262 canMessage->timeStamp = *ptrU16 << 8 | *ptrU16 >> 8;
\r
1264 *(U16*)card->rxBufPtr = 0x0000;
\r
1266 /* increment rx-buffer pointer */
\r
1267 if ( (card->rxBufBase + card->rxBufSize*16 ) <= (card->rxBufPtr += 16) )
\r
1269 card->rxBufPtr = card->rxBufBase;
\r
1273 } /* cl2_receive_data */
\r
1276 /* **************************************************************** *
\r
1278 * **************************************************************** */
\r