X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/95c031e101c74ae6472a7e538f3128f67a490082..1d20caee804d28a792dcacbf8424dc23b80c6370:/lincan/src/sja1000.c diff --git a/lincan/src/sja1000.c b/lincan/src/sja1000.c index 27eebca..71c7095 100644 --- a/lincan/src/sja1000.c +++ b/lincan/src/sja1000.c @@ -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; }