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.
#define MSGOBJ_FILTCH_REQUEST_b 5
#define MSGOBJ_RX_MODE_b 6
#define MSGOBJ_RX_MODE_EXT_b 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<<MSGOBJ_OPENED_b)
#define MSGOBJ_TX_REQUEST (1<<MSGOBJ_TX_REQUEST_b)
#define MSGOBJ_OPENED (1<<MSGOBJ_OPENED_b)
#define MSGOBJ_TX_REQUEST (1<<MSGOBJ_TX_REQUEST_b)
#define MSGOBJ_FILTCH_REQUEST (1<<MSGOBJ_FILTCH_REQUEST_b)
#define MSGOBJ_RX_MODE (1<<MSGOBJ_RX_MODE_b)
#define MSGOBJ_RX_MODE_EXT (1<<MSGOBJ_RX_MODE_EXT_b)
#define MSGOBJ_FILTCH_REQUEST (1<<MSGOBJ_FILTCH_REQUEST_b)
#define MSGOBJ_RX_MODE (1<<MSGOBJ_RX_MODE_b)
#define MSGOBJ_RX_MODE_EXT (1<<MSGOBJ_RX_MODE_EXT_b)
+#define MSGOBJ_TX_PENDING (1<<MSGOBJ_TX_PENDING_b)
#define can_msgobj_test_fl(obj,obj_fl) \
test_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
#define can_msgobj_test_fl(obj,obj_fl) \
test_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
/* Set mode, clock out, comparator */
can_write_reg(chip,sjaCDR_PELICAN|chip->sja_cdr_reg,SJACDR);
/* 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);
/* Set driver output configuration */
can_write_reg(chip,chip->sja_ocr_reg,SJAOCR);
+ can_msgobj_clear_fl(obj,TX_PENDING);
cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
if(cmd<0)
return;
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;
if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
obj->ret = -1;
return CANCHIP_IRQ_NONE;
}
return CANCHIP_IRQ_NONE;
}
+ status=can_read_reg(chip,SJASR);
+
return CANCHIP_IRQ_STUCK;
}
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;
}
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)){
obj->ret = 0;
can_msgobj_set_fl(obj,TX_REQUEST);
while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
}
if ((irq_register & (sjaIR_EI|sjaIR_BEI|sjaIR_EPI|sjaIR_DOI)) != 0) {
// Some error happened
}
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);
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);
irq_register=can_read_reg(chip,SJAIR);
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;
}
return CANCHIP_IRQ_HANDLED;
}
+ 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);
can_msgobj_set_fl(obj,TX_REQUEST);
while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
can_msgobj_clear_fl(obj,TX_REQUEST);