]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/i82527.c
First part of IRQ handling changes
[lincan.git] / lincan / src / i82527.c
index 68979489e8095731baa5c0670ee54a948c77be61..3aed30beb49af7f2def0b3c261781cf944ef6fd5 100644 (file)
@@ -4,7 +4,7 @@
  * 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.2  9 Jul 2003
+ * Version lincan-0.3  17 Jun 2004
  */
 
 #include "../include/can.h"
@@ -280,18 +280,29 @@ int i82527_config_irqs(struct chip_t *chip, short irqs)
 
 int i82527_pre_read_config(struct chip_t *chip, struct msgobj_t *obj)
 {
-       if (extended) {
+       unsigned long id=obj->rx_preconfig_id;
+
+       can_msgobj_set_fl(obj,RX_MODE);
+
+       if (extended || can_msgobj_test_fl(obj,RX_MODE_EXT)) {
+               id<<=3;
+               canobj_write_reg(chip,obj,id,iMSGID3);
+               canobj_write_reg(chip,obj,id>>8,iMSGID2);
+               canobj_write_reg(chip,obj,id>>16,iMSGID1);
+               canobj_write_reg(chip,obj,id>>24,iMSGID0);
                canobj_write_reg(chip,obj,MCFG_XTD,iMSGCFG);
-       }
-       else {
+       } else {
+               id<<=5;
+               canobj_write_reg(chip,obj,id,iMSGID1);
+               canobj_write_reg(chip,obj,id>>8,iMSGID0);
                canobj_write_reg(chip,obj,0x00,iMSGCFG);
        }
+
        canobj_write_reg(chip,obj,(NEWD_RES|MLST_RES|TXRQ_RES|RMPD_RES), iMSGCTL1);
        canobj_write_reg(chip,obj,(MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES),iMSGCTL0);
 
        DEBUGMSG("i82527_pre_read_config: configured obj at 0x%08lx\n",obj->obj_base_addr);
 
-       
        return 0;
 }
 
@@ -304,6 +315,8 @@ int i82527_pre_write_config(struct chip_t *chip, struct msgobj_t *obj,
        len = msg->length;
        if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
 
+       can_msgobj_clear_fl(obj,RX_MODE);
+
        canobj_write_reg(chip,obj,(MVAL_SET|TXIE_SET|RXIE_RES|INTPD_RES),iMSGCTL0);
        canobj_write_reg(chip,obj,(RMPD_RES|TXRQ_RES|CPUU_SET|NEWD_RES),iMSGCTL1);
 
@@ -412,6 +425,9 @@ void i82527_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj)
        if(obj->tx_slot){
                /* Do local transmitted message distribution if enabled */
                if (processlocal){
+                       /* fill CAN message timestamp */
+                       can_filltimestamp(&obj->tx_slot->msg.timestamp);
+
                        obj->tx_slot->msg.flags |= MSG_LOCAL;
                        canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
                }
@@ -501,6 +517,9 @@ void i82527_irq_read_handler(struct chip_t *chip, struct msgobj_t *obj, int objn
                }
                
 
+               /* fill CAN message timestamp */
+               can_filltimestamp(&obj->rx_msg.timestamp);
+
                canque_filter_msg2edges(obj->qends, &obj->rx_msg);
                
                if (msgctl1 & NEWD_SET)
@@ -549,33 +568,21 @@ static inline
 void i82527_irq_update_filter(struct chip_t *chip, struct msgobj_t *obj)
 {
        struct canfilt_t filt;
-       unsigned long id;
 
        if(canqueue_ends_filt_conjuction(obj->qends, &filt)) {
+               obj->rx_preconfig_id=filt.id;
                canobj_write_reg(chip,obj,(MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),iMSGCTL0);
                if(obj->object == 15) {
                        i82527_message15_mask(chip,filt.id,filt.mask);
                }
-               if (filt.flags&MSG_EXT) {
-                       id=filt.id<<3;
-                       canobj_write_reg(chip,obj,id,iMSGID3);
-                       canobj_write_reg(chip,obj,id>>8,iMSGID2);
-                       canobj_write_reg(chip,obj,id>>16,iMSGID1);
-                       canobj_write_reg(chip,obj,id>>24,iMSGID0);
-                       canobj_write_reg(chip,obj,MCFG_XTD,iMSGCFG);
-               }
-               else {
-                       id=filt.id<<5;
-                       canobj_write_reg(chip,obj,id,iMSGID1);
-                       canobj_write_reg(chip,obj,id>>8,iMSGID0);
-                       canobj_write_reg(chip,obj,0x00,iMSGCFG);
-               }
+               if (filt.flags&MSG_EXT)
+                       can_msgobj_set_fl(obj,RX_MODE_EXT);
+               else
+                       can_msgobj_clear_fl(obj,RX_MODE_EXT);
 
-               canobj_write_reg(chip,obj,(NEWD_RES|MLST_RES|TXRQ_RES|RMPD_RES), iMSGCTL1);
-               canobj_write_reg(chip,obj,(MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES),iMSGCTL0);
+               i82527_pre_read_config(chip, obj);
 
                CANMSG("i82527_irq_update_filter: obj at 0x%08lx\n",obj->obj_base_addr);
-               
        }
 }
 
@@ -604,13 +611,12 @@ void i82527_irq_sync_activities(struct chip_t *chip, struct msgobj_t *obj)
        }
 }
 
-can_irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+int i82527_irq_handler(int irq, struct chip_t *chip)
 {
        unsigned char msgcfg;
 
        unsigned irq_register;
        unsigned object;
-       struct chip_t *chip=(struct chip_t *)dev_id;
        struct msgobj_t *obj;
 
        /*put_reg=device->hwspecops->write_register;*/
@@ -620,7 +626,7 @@ can_irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 
        if(!irq_register) {
                DEBUGMSG("i82527: spurious IRQ\n");
-               return CAN_IRQ_NONE;
+               return CANCHIP_IRQ_NONE;
        }
 
 
@@ -631,7 +637,7 @@ can_irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
                if (irq_register == 0x01) {
                        DEBUGMSG("Status register: 0x%x\n",can_read_reg(chip, iSTAT));
                        continue;
-                       /*return CAN_IRQ_NONE;*/
+                       /*return CANCHIP_IRQ_NONE;*/
                }
                
                if (irq_register == 0x02)
@@ -639,7 +645,7 @@ can_irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
                else if(irq_register < 14)
                        object = irq_register-3;
                else
-                       return CAN_IRQ_NONE;
+                       return CANCHIP_IRQ_NONE;
 
                obj=chip->msgobj[object];
                
@@ -657,7 +663,7 @@ can_irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 
        } while((irq_register=i82527_seg_read_reg(chip, iIRQ)) != 0);
 
-       return CAN_IRQ_HANDLED;
+       return CANCHIP_IRQ_HANDLED;
 }
 
 void i82527_irq_rtr_handler(struct chip_t *chip, struct msgobj_t *obj,
@@ -717,8 +723,6 @@ int i82527_filtch_rq(struct chip_t *chip, struct msgobj_t *obj)
 
        can_preempt_enable();
        return 0;
-
-       return 0;
 }
 
 int i82527_register(struct chipspecops_t *chipspecops)
@@ -745,3 +749,11 @@ int i82527_register(struct chipspecops_t *chipspecops)
        chipspecops->irq_handler = i82527_irq_handler;
        return 0;
 }
+
+int i82527_fill_chipspecops(struct chip_t *chip)
+{
+       chip->chip_type="i82527";
+       chip->max_objects=15;
+       i82527_register(chip->chipspecops);
+       return 0;
+}