From 75d77a3d5177ad90a0e319102c776852df2bccb7 Mon Sep 17 00:00:00 2001 From: ppisa Date: Tue, 11 Oct 2005 15:41:38 +0000 Subject: [PATCH] SJA1000 driver interrupts processing modified to not rely on interrupt register for Rx and Tx. The information about free chip ready condition for Tx message is now obtained from status register. This solution enables us to equip SJA1000 driver by irq_accept method. Then only this part has to be run in real IRQ handler and rest of ISR can be done in other thread. This is required for possible porting to QNX as well. Change should helps to better recover form bus-off mode as well. --- lincan/include/constants.h | 2 ++ lincan/src/sja1000p.c | 29 +++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lincan/include/constants.h b/lincan/include/constants.h index 5559da0..b777cad 100644 --- a/lincan/include/constants.h +++ b/lincan/include/constants.h @@ -50,6 +50,7 @@ #define MSGOBJ_FILTCH_REQUEST_b 5 #define MSGOBJ_RX_MODE_b 6 #define MSGOBJ_RX_MODE_EXT_b 7 +#define MSGOBJ_TX_PENDING_b 8 #define MSGOBJ_OPENED (1<obj_flags) diff --git a/lincan/src/sja1000p.c b/lincan/src/sja1000p.c index 216a9b9..59fa68d 100644 --- a/lincan/src/sja1000p.c +++ b/lincan/src/sja1000p.c @@ -96,6 +96,10 @@ int sja1000p_chip_config(struct canchip_t *chip) /* Set mode, clock out, comparator */ can_write_reg(chip,sjaCDR_PELICAN|chip->sja_cdr_reg,SJACDR); + + /* Ensure, that interrupts are disabled even on the chip level now */ + can_write_reg(chip, sjaDISABLE_INTERRUPTS, SJAIER); + /* Set driver output configuration */ can_write_reg(chip,chip->sja_ocr_reg,SJAOCR); @@ -599,9 +603,11 @@ void sja1000p_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj) obj->tx_slot=NULL; } + can_msgobj_clear_fl(obj,TX_PENDING); cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot); if(cmd<0) return; + can_msgobj_set_fl(obj,TX_PENDING); if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) { obj->ret = -1; @@ -653,6 +659,8 @@ int sja1000p_irq_handler(int irq, struct canchip_t *chip) return CANCHIP_IRQ_NONE; } + status=can_read_reg(chip,SJASR); + do { if(!loop_cnt--) { @@ -660,13 +668,18 @@ int sja1000p_irq_handler(int irq, struct canchip_t *chip) return CANCHIP_IRQ_STUCK; } - if ((irq_register & sjaIR_RI) != 0) { - DEBUGMSG("sja1000_irq_handler: RI\n"); + /* (irq_register & sjaIR_RI) */ + /* old variant using SJAIR, collides with intended use with irq_accept */ + if (status & sjaSR_RBS) { + DEBUGMSG("sja1000_irq_handler: RI or RBS\n"); sja1000p_read(chip,obj); obj->ret = 0; } - if ((irq_register & sjaIR_TI) != 0) { - DEBUGMSG("sja1000_irq_handler: TI\n"); + + /* (irq_register & sjaIR_TI) */ + /* old variant using SJAIR, collides with intended use with irq_accept */ + if ((status & sjaSR_TBS) && can_msgobj_test_fl(obj,TX_PENDING)) { + DEBUGMSG("sja1000_irq_handler: TI or TX_PENDING and TBS\n"); obj->ret = 0; can_msgobj_set_fl(obj,TX_REQUEST); while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){ @@ -682,7 +695,6 @@ int sja1000p_irq_handler(int irq, struct canchip_t *chip) } if ((irq_register & (sjaIR_EI|sjaIR_BEI|sjaIR_EPI|sjaIR_DOI)) != 0) { // Some error happened - status=can_read_reg(chip,SJASR); error_code=can_read_reg(chip,SJAECC); CANMSG("Error: status register: 0x%x irq_register: 0x%02x error: 0x%02x\n", status, irq_register, error_code); @@ -715,7 +727,11 @@ int sja1000p_irq_handler(int irq, struct canchip_t *chip) irq_register=can_read_reg(chip,SJAIR); - } while(irq_register & (sjaIR_BEI|sjaIR_EPI|sjaIR_DOI|sjaIR_EI|sjaIR_TI|sjaIR_RI)); + status=can_read_reg(chip,SJASR); + + } while((irq_register & (sjaIR_BEI|sjaIR_EPI|sjaIR_DOI|sjaIR_EI|sjaIR_TI|sjaIR_RI)) || + ((status & sjaSR_TBS) && can_msgobj_test_fl(obj,TX_PENDING)) || + (status & sjaSR_RBS)); return CANCHIP_IRQ_HANDLED; } @@ -736,6 +752,7 @@ int sja1000p_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj) can_preempt_disable(); + can_msgobj_set_fl(obj,TX_PENDING); can_msgobj_set_fl(obj,TX_REQUEST); while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){ can_msgobj_clear_fl(obj,TX_REQUEST); -- 2.39.2