-/* c_can_irq.c - Hynix HMS30c7202 ARM IRQ handling code
- * Linux CAN-bus device driver.
- * Written by Sebastian Stolzenberg email:stolzi@sebastian-stolzenberg.de
- * Based on code from Arnaud Westenberg email:arnaud@wanadoo.nl
- * and Ake Hedman, eurosource, akhe@eurosource.se
- * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
- * email:pisa@cmp.felk.cvut.cz
- * This software is released under the GPL-License.
- * Version lincan-0.3 17 Jun 2004
- */
+/**************************************************************************/
+/* File: c_can_irq.c - generic IRQ C_CAN Bosch IP core handling */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Copyright (C) 2004 Sebastian Stolzenberg <stolzi@sebastian-stolzenberg.de> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* and Ake Hedman, eurosource <akhe@eurosource.se> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
#include "../include/can.h"
#include "../include/can_sysdep.h"
// while
}
-void c_can_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj)
+///////////////////////////////////////////////////////////////////////////////
+// c_can_irq_update_filter
+//
+// update acceptance filter for given object.
+//
+
+void c_can_irq_update_filter(struct canchip_t *pchip, struct msgobj_t *obj)
+{
+ struct canfilt_t filt;
+
+ if(canqueue_ends_filt_conjuction(obj->qends, &filt)) {
+ obj->rx_preconfig_id=filt.id;
+
+ if (filt.flags&MSG_EXT)
+ can_msgobj_set_fl(obj,RX_MODE_EXT);
+ else
+ can_msgobj_clear_fl(obj,RX_MODE_EXT);
+
+ c_can_mask(obj, filt.mask, 0);
+
+ c_can_pre_read_config(pchip, obj);
+
+ CANMSG("c_can_irq_update_filter: obj #%d\n",obj->object);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// c_can_irq_sync_activities
+//
+// ensure, that not requests for object activities are serialized.
+//
+
+void c_can_irq_sync_activities(struct canchip_t *pchip, struct msgobj_t *obj)
{
while (!can_msgobj_test_and_set_fl(obj, TX_LOCK)) {
- /*if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) {
- if(canobj_read_reg(chip,obj,iMSGCTL1)&TXRQ_RES)
- i82527_irq_write_handler(chip, obj);
- }
+ if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) {
+ int cctreqx;
+ int idxobj = obj->object-1;
+
+ if(idxobj<0) {
+ DEBUGMSG("c_can_irq_sync_activities wrong idxobj\n");
+ break;
+ }
+
+ if(idxobj < 16)
+ cctreqx = c_can_read_reg_w(pchip, CCTREQ1);
+ else
+ cctreqx = c_can_read_reg_w(pchip, CCTREQ2);
- if(!obj->tx_slot) {
- if(can_msgobj_test_and_clear_fl(obj,FILTCH_REQUEST)) {
- i82527_irq_update_filter(chip, obj);
- }
- } */
- /* FIXME: these functionality has to be implemented to start TX */
+ if (!(cctreqx & (1 << (idxobj & 0xf)))) {
+ can_msgobj_clear_fl(obj, TX_REQUEST);
+ c_can_irq_write_handler(pchip, idxobj);
+ }
+ }
+
+ if(!obj->tx_slot) {
+ if(can_msgobj_test_and_clear_fl(obj,FILTCH_REQUEST)) {
+ c_can_irq_update_filter(pchip, obj);
+ }
+ }
can_msgobj_clear_fl(obj, TX_LOCK);
+
+ mb();
+
if (can_msgobj_test_fl(obj, TX_REQUEST))
continue;
if (can_msgobj_test_fl(obj, FILTCH_REQUEST) && !obj->tx_slot)
#endif /*CAN_WITH_STATISTICS */
//return; // continue?
} else {
- if (irqreg > 0 && irqreg < 33) {
+ if (irqreg >= 1 && irqreg <= 32) {
struct msgobj_t *pmsgobj;
int idxobj;
}
//transfer Message Object to IF1 Buffer
if (c_can_if1_busycheck(pchip)) ;
+
c_can_write_reg_w(pchip, readMaskCM, CCIF1CM);
c_can_write_reg_w(pchip, idxobj + 1, CCIF1CR);
if (c_can_if1_busycheck(pchip)) ;
if (c_can_read_reg_w(pchip, CCIF1A2) &
IFXARB2_DIR) {
+ DEBUGMSG("c_can_irq_write_handler idxobj=%d, msgid=%d\n",idxobj,msgid);
spin_unlock(&c_can_if1lock);
c_can_irq_write_handler(pchip, idxobj);
+
+ if(!pmsgobj->tx_slot){
+ if(can_msgobj_test_and_clear_fl(pmsgobj, FILTCH_REQUEST)) {
+ c_can_irq_update_filter(pchip, pmsgobj);
+ }
+ }
} else {
if (can_msgobj_test_fl
(pmsgobj, RX_MODE_EXT)) {
}
spin_unlock(&c_can_if1lock);
- //}
}
//else
}
- //if
+ //if (irqreg >= 1 && irqreg <= 32)
}
// Get irq status again
irqreg = c_can_read_reg_w(pchip, CCINTR);