1 /**************************************************************************/
2 /* File: c_can_irq.c - generic IRQ C_CAN Bosch IP core handling */
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) 2004 Sebastian Stolzenberg <stolzi@sebastian-stolzenberg.de> */
8 /* Funded by OCERA and FRESCOR IST projects */
9 /* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
10 /* and Ake Hedman, eurosource <akhe@eurosource.se> */
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 /**************************************************************************/
37 #include "../include/can.h"
38 #include "../include/can_sysdep.h"
39 #include "../include/main.h"
40 #include "../include/c_can.h"
43 unsigned short wdata[4];
44 unsigned char bdata[8];
48 inline void c_can_irq_read_handler(struct canchip_t *pchip, int idxobj,
51 inline void c_can_irq_write_handler(struct canchip_t *pchip, int idxobj);
53 void c_can_irq_rtr_handler(struct canchip_t *pchip, int idxobj, u32 msgid);
55 u16 readMaskCM = IFXCM_ARB | IFXCM_CNTRL | IFXCM_CLRINTPND
56 | IFXCM_TRND | IFXCM_DA | IFXCM_DB;
58 u16 msgLstReadMaskCM = IFXCM_CNTRL;
59 u16 msgLstWriteMaskCM = IFXCM_CNTRL | IFXCM_WRRD;
61 ///////////////////////////////////////////////////////////////////////////////
62 // c_can_irq_write_handler
64 // Send a message from the output fifo ( if any ).
67 inline void c_can_irq_write_handler(struct canchip_t *pchip, int idxobj)
70 struct msgobj_t *pmsgobj = pchip->msgobj[idxobj];
72 DEBUGMSG("(c%dm%d)calling c_can_irq_write_handler(...)\n",
73 pchip->chip_idx, pmsgobj->object);
75 if (pmsgobj->tx_slot) {
76 /* Do local transmitted message distribution if enabled */
78 /* fill CAN message timestamp */
79 can_filltimestamp(&pmsgobj->tx_slot->msg.timestamp);
81 pmsgobj->tx_slot->msg.flags |= MSG_LOCAL;
82 canque_filter_msg2edges(pmsgobj->qends,
83 &pmsgobj->tx_slot->msg);
85 /* Free transmitted slot */
86 canque_free_outslot(pmsgobj->qends, pmsgobj->tx_qedge,
88 pmsgobj->tx_slot = NULL;
90 // Get ready to send next message
91 spin_lock(&c_can_spwlock);
94 canque_test_outslot(pmsgobj->qends, &pmsgobj->tx_qedge,
97 DEBUGMSG("(c%dm%d)Nothin to write\n",
98 pchip->chip_idx, pmsgobj->object);
99 spin_unlock(&c_can_spwlock);
103 if (pchip->chipspecops->
104 send_msg(pchip, pmsgobj, &pmsgobj->tx_slot->msg)) {
106 canque_notify_inends(pmsgobj->tx_qedge,
107 CANQUEUE_NOTIFY_ERRTX_SEND);
108 canque_free_outslot(pmsgobj->qends, pmsgobj->tx_qedge,
110 pmsgobj->tx_slot = NULL;
111 spin_unlock(&c_can_spwlock);
112 DEBUGMSG("(c%dm%d)c_can_irq_handler: Unable to send message\n",
113 pchip->chip_idx, pmsgobj->object);
116 // Another message sent
117 #ifdef CAN_WITH_STATISTICS
118 pchip->stat.cntTxPkt++;
119 pchip->stat.cntTxData += pmsgobj->tx_slot->length;
120 #endif /*CAN_WITH_STATISTICS */
122 spin_unlock(&c_can_spwlock);
124 // Wake up any waiting writer
128 ///////////////////////////////////////////////////////////////////////////////
129 // c_can_irq_read_handler
131 // Message received form the line. Write it in the input fifo->
134 inline void c_can_irq_read_handler(struct canchip_t *pchip,
135 int idxobj, u32 msgid)
140 union c_can_data readData;
141 struct msgobj_t *pmsgobj = pchip->msgobj[idxobj];
143 DEBUGMSG("(c%dm%d)calling c_can_irq_read_handler(...)\n",
144 pchip->chip_idx, pmsgobj->object);
148 #ifdef CAN_WITH_STATISTICS
149 pchip->stat.cntRxFifoOvr++;
150 #endif /*CAN_WITH_STATISTICS */
152 msgCntlReg = c_can_read_reg_w(pchip, CCIF1DMC);
154 pmsgobj->rx_msg.length = msgCntlReg & 0x000F;
157 pmsgobj->rx_msg.id = (u32) msgid;
159 // Fetch message bytes
160 if (pmsgobj->rx_msg.length > 0)
161 readData.wdata[0] = c_can_read_reg_w(pchip, CCIF1DA1);
162 if (pmsgobj->rx_msg.length > 2)
163 readData.wdata[1] = c_can_read_reg_w(pchip, CCIF1DA2);
164 if (pmsgobj->rx_msg.length > 4)
165 readData.wdata[2] = c_can_read_reg_w(pchip, CCIF1DB1);
166 if (pmsgobj->rx_msg.length > 6)
167 readData.wdata[3] = c_can_read_reg_w(pchip, CCIF1DB2);
169 for (i = 0; i < pmsgobj->rx_msg.length; i++) {
170 pmsgobj->rx_msg.data[i] = readData.bdata[i];
172 DEBUGMSG("(c%dm%d)Received Message:\n",
173 pchip->chip_idx, pmsgobj->object);
174 DEBUGMSG(" id = %ld\n", pmsgobj->rx_msg.id);
175 DEBUGMSG(" length = %d\n", pmsgobj->rx_msg.length);
176 for (i = 0; i < pmsgobj->rx_msg.length; i++)
177 DEBUGMSG(" data[%d] = 0x%.2x\n", i,
178 pmsgobj->rx_msg.data[i]);
180 /* fill CAN message timestamp */
181 can_filltimestamp(&pmsgobj->rx_msg.timestamp);
183 canque_filter_msg2edges(pmsgobj->qends, &pmsgobj->rx_msg);
185 #ifdef CAN_WITH_STATISTICS
186 // Another received packet
187 pchip->stat.cntRxPkt++;
189 // Add databytes read to statistics block
190 pchip->stat.cntRxData += pmsgobj->rx_msg.length;
191 #endif /*CAN_WITH_STATISTICS */
193 // Check if new data arrived
194 if (c_can_if1_busycheck(pchip)) ;
195 c_can_write_reg_w(pchip, readMaskCM, CCIF1CM);
196 c_can_write_reg_w(pchip, idxobj + 1, CCIF1CR);
197 if (c_can_if1_busycheck(pchip)) ;
198 if (!((bDataAvail = c_can_read_reg_w(pchip, CCIF1DMC)) &
203 if (bDataAvail & IFXMC_MSGLST) {
204 CANMSG("(c%dm%d)c-can fifo full: Message lost!\n",
205 pchip->chip_idx, pmsgobj->object);
212 ///////////////////////////////////////////////////////////////////////////////
213 // c_can_irq_update_filter
215 // update acceptance filter for given object.
218 void c_can_irq_update_filter(struct canchip_t *pchip, struct msgobj_t *obj)
220 struct canfilt_t filt;
222 if(canqueue_ends_filt_conjuction(obj->qends, &filt)) {
223 obj->rx_preconfig_id=filt.id;
225 if (filt.flags&MSG_EXT)
226 can_msgobj_set_fl(obj,RX_MODE_EXT);
228 can_msgobj_clear_fl(obj,RX_MODE_EXT);
230 c_can_mask(obj, filt.mask, 0);
232 c_can_pre_read_config(pchip, obj);
234 CANMSG("c_can_irq_update_filter: obj #%d\n",obj->object);
238 ///////////////////////////////////////////////////////////////////////////////
239 // c_can_irq_sync_activities
241 // ensure, that not requests for object activities are serialized.
244 void c_can_irq_sync_activities(struct canchip_t *pchip, struct msgobj_t *obj)
246 while (!can_msgobj_test_and_set_fl(obj, TX_LOCK)) {
248 if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) {
250 int idxobj = obj->object-1;
253 DEBUGMSG("c_can_irq_sync_activities wrong idxobj\n");
258 cctreqx = c_can_read_reg_w(pchip, CCTREQ1);
260 cctreqx = c_can_read_reg_w(pchip, CCTREQ2);
262 if (!(cctreqx & (1 << (idxobj & 0xf)))) {
263 can_msgobj_clear_fl(obj, TX_REQUEST);
264 c_can_irq_write_handler(pchip, idxobj);
269 if(can_msgobj_test_and_clear_fl(obj,FILTCH_REQUEST)) {
270 c_can_irq_update_filter(pchip, obj);
274 can_msgobj_clear_fl(obj, TX_LOCK);
278 if (can_msgobj_test_fl(obj, TX_REQUEST))
280 if (can_msgobj_test_fl(obj, FILTCH_REQUEST) && !obj->tx_slot)
286 ///////////////////////////////////////////////////////////////////////////////
290 int c_can_irq_handler(int irq, struct canchip_t *pchip)
292 struct rtr_id *rtr_search = hardware_p->rtr_queue;
294 int id0 = 0, id1 = 0;
300 irqreg = c_can_read_reg_w(pchip, CCINTR);
303 DEBUGMSG("\n(c%d)IRQ handler: addr=%.8lx spurious interrupt\n",
305 (long)(pchip-> /*v */ chip_base_addr /* + CCSR */ ));
306 return CANCHIP_IRQ_NONE;
309 DEBUGMSG("\n(c%d)IRQ handler: addr=%.8lx irqreg=0x%.4x\n",
311 (long)(pchip-> /*v */ chip_base_addr /* + CCSR */ ),
315 c_can_registerdump(pchip);
319 // Handle change in status register
321 if (irqreg == INT_STAT) {
322 chip_status = c_can_read_reg_w(pchip, CCSR);
323 DEBUGMSG("(c%d)Status register: 0x%x\n",
324 pchip->chip_idx, chip_status);
326 if (chip_status & SR_EWARN) {
327 // There is an abnormal # of errors
328 #ifdef CAN_WITH_STATISTICS
329 pchip->stat.cntWarnings++;
330 #endif /*CAN_WITH_STATISTICS */
331 errcount = c_can_read_reg_w(pchip, CCEC);
333 ("(c%d)stat: c_can_irq_handler: Abnormal number of Errors Warning\n"
334 " txErr=%d, rxErr=%d\n",
335 pchip->chip_idx, (errcount & 0x00ff),
336 ((errcount & 0x7f00) >> 8));
339 // this code deactivates the chip if the transmiterrorcounter grew above 127
340 if ((pchip->stat.cntWarnings > 100) && ((errcount&0x00ff) > 127))
342 CANMSG("(c%d)to much Errornumber warnings (>100), deactivating chip",
344 pchip->config_irqs(pchip, 0);
345 pchip->enable_configuration(pchip);
346 pchip->clear_objects(pchip);
347 pchip->flags &= ~CHANNEL_CONFIGURED;
352 if (chip_status & SR_EPASS) {
353 // There is an abnormal # of errors
354 #ifdef CAN_WITH_STATISTICS
355 pchip->stat.cntErrPassive++;
356 #endif /*CAN_WITH_STATISTICS */
358 ("(c%d)stat: c_can_irq_handler: Chip entering Error Passive Mode\n",
362 if (chip_status & SR_BOFF) {
363 // We have a bus off condition
364 #ifdef CAN_WITH_STATISTICS
365 pchip->stat.cntBusOff++;
366 #endif /*CAN_WITH_STATISTICS */
367 //pchip->fifo->tx_in_progress = 0;
370 ("(c%d)stat: c_can_irq_handler: Bus Off\n",
372 /*if (pchip->stat.cntBusOff > 100)
374 CANMSG("(c%d)to much busoff warnings (>100), deactivating chip",
376 pchip->config_irqs(pchip, 0);
377 pchip->enable_configuration(pchip);
378 pchip->clear_objects(pchip);
379 pchip->flags &= ~CHANNEL_CONFIGURED;
383 CANMSG("(c%d)try to reconnect",
386 disable_configuration(pchip);
389 if (chip_status & SR_TXOK) {
391 ("(c%d)stat: Transmitted a Message successfully\n",
393 c_can_write_reg_w(pchip, chip_status & ~SR_TXOK,
397 if (chip_status & SR_RXOK) {
399 ("(c%d)stat: Received a Message successfully\n",
401 c_can_write_reg_w(pchip, chip_status & ~SR_RXOK,
404 #ifdef CAN_WITH_STATISTICS
405 // Errors to statistics
406 switch (chip_status & 0x07) {
407 case SRLEC_NE: // No error
409 case SRLEC_SE: // Stuff error
410 pchip->stat.cntStuffErr++;
412 case SRLEC_FE: // Form error
413 pchip->stat.cntFormErr++;
415 case SRLEC_AE: // Ack error
416 pchip->stat.cntAckErr++;
418 case SRLEC_B1: // Bit 1 error
419 pchip->stat.cntBit1Err++;
421 case SRLEC_B0: // Bit 0 error
422 pchip->stat.cntBit0Err++;
424 case SRLEC_CR: // CRC error
425 pchip->stat.cntCrcErr++;
430 #endif /*CAN_WITH_STATISTICS */
431 //return; // continue?
433 if (irqreg >= 1 && irqreg <= 32) {
434 struct msgobj_t *pmsgobj;
439 pmsgobj = pchip->msgobj[idxobj];
441 //DEBUGMSG( "Interrupt handler: addr=%lx devid=%lx irqreq=%x status=0x%x\n",
442 // (unsigned long)pchip->vbase_addr + iIRQ,
443 // (unsigned long)dev_id,
447 spin_lock(&c_can_if1lock);
450 if (c_can_if1_busycheck(pchip)) ; /*?????????? */
451 c_can_write_reg_w(pchip, msgLstReadMaskCM,
453 c_can_write_reg_w(pchip, idxobj + 1, CCIF1CR);
455 if (c_can_if1_busycheck(pchip)) ; /*?????????? */
456 tempCntlReg = c_can_read_reg_w(pchip, CCIF1DMC);
458 if (tempCntlReg & IFXMC_MSGLST) {
459 CANMSG("(c%dm%d)Chip lost a message\n",
462 #ifdef CAN_WITH_STATISTICS
463 pchip->stat.cntMsgLst++;
464 #endif /*CAN_WITH_STATISTICS */
466 //Reset Message Lost Bit
468 tempCntlReg & (~IFXMC_MSGLST);
469 c_can_write_reg_w(pchip, tempCntlReg,
471 c_can_write_reg_w(pchip,
474 c_can_write_reg_w(pchip, idxobj + 1,
477 //transfer Message Object to IF1 Buffer
478 if (c_can_if1_busycheck(pchip)) ;
480 c_can_write_reg_w(pchip, readMaskCM, CCIF1CM);
481 c_can_write_reg_w(pchip, idxobj + 1, CCIF1CR);
483 if (c_can_if1_busycheck(pchip)) ;
484 if (c_can_read_reg_w(pchip, CCIF1A2) &
486 DEBUGMSG("c_can_irq_write_handler idxobj=%d, msgid=%d\n",idxobj,msgid);
487 spin_unlock(&c_can_if1lock);
488 c_can_irq_write_handler(pchip, idxobj);
490 if(!pmsgobj->tx_slot){
491 if(can_msgobj_test_and_clear_fl(pmsgobj, FILTCH_REQUEST)) {
492 c_can_irq_update_filter(pchip, pmsgobj);
496 if (can_msgobj_test_fl
497 (pmsgobj, RX_MODE_EXT)) {
499 c_can_read_reg_w(pchip,
504 CCIF1A2) & 0x1FFF) << 16;
510 CCIF1A2) & 0x1FFC) >> 2)
513 spin_unlock(&c_can_if1lock);
515 spin_lock(&hardware_p->rtr_lock);
516 while (rtr_search != NULL) {
517 if (rtr_search->id == msgid) {
520 rtr_search = rtr_search->next;
522 spin_unlock(&hardware_p->rtr_lock);
524 spin_lock(&c_can_if1lock);
526 //transfer Message Object to IF1 Buffer
527 if (c_can_if1_busycheck(pchip)) ;
528 c_can_write_reg_w(pchip, readMaskCM,
530 c_can_write_reg_w(pchip, idxobj + 1,
533 if (c_can_if1_busycheck(pchip)) ;
535 if ((rtr_search != NULL)
536 && (rtr_search->id == msgid)) {
537 c_can_irq_rtr_handler(pchip,
541 c_can_irq_read_handler(pchip,
545 spin_unlock(&c_can_if1lock);
550 //if (irqreg >= 1 && irqreg <= 32)
552 // Get irq status again
553 irqreg = c_can_read_reg_w(pchip, CCINTR);
555 return CANCHIP_IRQ_HANDLED;
558 ///////////////////////////////////////////////////////////////////////////////
559 // c_can_irq_rtr_handler
562 void c_can_irq_rtr_handler(struct canchip_t *pchip, int idxobj, u32 msgid)
565 struct rtr_id *prtr_search = hardware_p->rtr_queue;
566 union c_can_data rtrData;
568 spin_lock(&hardware_p->rtr_lock);
570 prtr_search->rtr_message->id = msgid;
571 prtr_search->rtr_message->length =
572 (c_can_read_reg_w(pchip, CCIF1DMC) & 0x000f);
574 // Fetch message bytes
575 if (prtr_search->rtr_message->length > 0)
576 rtrData.wdata[0] = c_can_read_reg_w(pchip, CCIF1DA1);
577 if (prtr_search->rtr_message->length > 2)
578 rtrData.wdata[1] = c_can_read_reg_w(pchip, CCIF1DA2);
579 if (prtr_search->rtr_message->length > 4)
580 rtrData.wdata[2] = c_can_read_reg_w(pchip, CCIF1DB1);
581 if (prtr_search->rtr_message->length > 6)
582 rtrData.wdata[3] = c_can_read_reg_w(pchip, CCIF1DB2);
584 for (i = 0; i < prtr_search->rtr_message->length; i++) {
585 prtr_search->rtr_message->data[i] = rtrData.bdata[i];
588 spin_unlock(&hardware_p->rtr_lock);
589 wake_up_interruptible(&prtr_search->rtr_wq);