]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/sja1000.c
changed usb vendor and product id.
[lincan.git] / lincan / src / sja1000.c
index 27eebcabfd9a9c9bd67498f78140f4df84f060fc..71c7095adad847292cfa9f37cd14865eaa20061e 100644 (file)
@@ -305,6 +305,19 @@ int sja1000_stop_chip(struct canchip_t *chip)
        return 0;
 }
 
+int sja1000_attach_to_chip(struct canchip_t *chip)
+{
+       return 0;
+}
+
+int sja1000_release_chip(struct canchip_t *chip)
+{
+       sja1000_stop_chip(chip);
+       can_write_reg(chip,sjaCR_RR,SJACR);
+
+       return 0;
+}
+
 int sja1000_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
 {
        CANMSG("sja1000_remote_request not implemented\n");
@@ -335,6 +348,7 @@ int sja1000_irq_handler(int irq, struct canchip_t *chip)
 {
        unsigned irq_register;
        struct msgobj_t *obj=chip->msgobj[0];
+       int loop_cnt=CHIP_MAX_IRQLOOP;
 
        irq_register=can_read_reg(chip, SJAIR);
 //     DEBUGMSG("sja1000_irq_handler: SJAIR:%02x\n",irq_register);
@@ -344,37 +358,48 @@ int sja1000_irq_handler(int irq, struct canchip_t *chip)
        if ((irq_register & (sjaIR_WUI|sjaIR_DOI|sjaIR_EI|sjaIR_TI|sjaIR_RI)) == 0)
                return CANCHIP_IRQ_NONE;
 
-       if ((irq_register & sjaIR_RI) != 0) 
-               sja1000_irq_read_handler(chip, obj);
+       do {
+
+               if(!loop_cnt--) {
+                       CANMSG("sja1000_irq_handler IRQ %d stuck\n",irq);
+                       return CANCHIP_IRQ_STUCK;
+               }
+
+               if ((irq_register & sjaIR_RI) != 0) 
+                       sja1000_irq_read_handler(chip, obj);
 
-       if ((irq_register & sjaIR_TI) != 0) { 
-               can_msgobj_set_fl(obj,TX_REQUEST);
-               while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
-                       can_msgobj_clear_fl(obj,TX_REQUEST);
+               if ((irq_register & sjaIR_TI) != 0) { 
+                       can_msgobj_set_fl(obj,TX_REQUEST);
+                       while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+                               can_msgobj_clear_fl(obj,TX_REQUEST);
 
-                       if (can_read_reg(chip, SJASR) & sjaSR_TBS)
-                               sja1000_irq_write_handler(chip, obj);
+                               if (can_read_reg(chip, SJASR) & sjaSR_TBS)
+                                       sja1000_irq_write_handler(chip, obj);
 
-                       can_msgobj_clear_fl(obj,TX_LOCK);
-                       if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
+                               can_msgobj_clear_fl(obj,TX_LOCK);
+                               if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
+                       }
                }
-       }
 
-       if ((irq_register & (sjaIR_EI|sjaIR_DOI)) != 0) { 
-               // Some error happened
+               if ((irq_register & (sjaIR_EI|sjaIR_DOI)) != 0) { 
+                       // Some error happened
 // FIXME: chip should be brought to usable state. Transmission cancelled if in progress.
 // Reset flag set to 0 if chip is already off the bus. Full state report
-               CANMSG("Error: status register: 0x%x irq_register: 0x%02x\n",
-                       can_read_reg(chip, SJASR), irq_register);
-               obj->ret=-1;
-
-               if(obj->tx_slot){
-                       canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_BUS);
-                       /*canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
-                       obj->tx_slot=NULL;*/
+                       CANMSG("Error: status register: 0x%x irq_register: 0x%02x\n",
+                               can_read_reg(chip, SJASR), irq_register);
+                       obj->ret=-1;
+
+                       if(obj->tx_slot){
+                               canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_BUS);
+                               /*canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+                               obj->tx_slot=NULL;*/
+                       }
                }
-       }
 
+               irq_register=can_read_reg(chip, SJAIR);
+
+       } while(irq_register & (sjaIR_WUI|sjaIR_DOI|sjaIR_EI|sjaIR_TI|sjaIR_RI));
+       
        return CANCHIP_IRQ_HANDLED;
 }
 
@@ -485,9 +510,12 @@ int sja1000_register(struct chipspecops_t *chipspecops)
        chipspecops->enable_configuration = sja1000_enable_configuration;
        chipspecops->disable_configuration = sja1000_disable_configuration;
        chipspecops->set_btregs = sja1000_set_btregs;
+       chipspecops->attach_to_chip=sja1000_attach_to_chip;
+       chipspecops->release_chip=sja1000_release_chip;
        chipspecops->start_chip = sja1000_start_chip;
        chipspecops->stop_chip = sja1000_stop_chip;
        chipspecops->irq_handler = sja1000_irq_handler;
+       chipspecops->irq_handler = NULL;
        return 0;
 }