X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/2a4663dd0b20d96d1ffe20993dd0c63ed2ca9f20..a682f9de48bcce43fba6141fbdb4d451914e0bb4:/lincan/src/sja1000.c diff --git a/lincan/src/sja1000.c b/lincan/src/sja1000.c index 5b549c4..127c453 100644 --- a/lincan/src/sja1000.c +++ b/lincan/src/sja1000.c @@ -12,10 +12,10 @@ #include "../include/main.h" #include "../include/sja1000.h" -void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *obj); -void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj); +void sja1000_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj); +void sja1000_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj); -int sja1000_enable_configuration(struct chip_t *chip) +int sja1000_enable_configuration(struct canchip_t *chip) { int i=0; unsigned flags; @@ -39,7 +39,7 @@ int sja1000_enable_configuration(struct chip_t *chip) return 0; } -int sja1000_disable_configuration(struct chip_t *chip) +int sja1000_disable_configuration(struct canchip_t *chip) { int i=0; unsigned flags; @@ -62,7 +62,7 @@ int sja1000_disable_configuration(struct chip_t *chip) return 0; } -int sja1000_chip_config(struct chip_t *chip) +int sja1000_chip_config(struct canchip_t *chip) { if (sja1000_enable_configuration(chip)) return -ENODEV; @@ -88,7 +88,7 @@ int sja1000_chip_config(struct chip_t *chip) return 0; } -int sja1000_standard_mask(struct chip_t *chip, unsigned short code, unsigned short mask) +int sja1000_standard_mask(struct canchip_t *chip, unsigned short code, unsigned short mask) { unsigned char write_code, write_mask; @@ -123,7 +123,7 @@ int sja1000_standard_mask(struct chip_t *chip, unsigned short code, unsigned sho * param sampl_pt sample point in % (0-100) sets (TSEG1+2)/(TSEG1+TSEG2+3) ratio * param flags fields BTR1_SAM, OCMODE, OCPOL, OCTP, OCTN, CLK_OFF, CBP */ -int sja1000_baud_rate(struct chip_t *chip, int rate, int clock, int sjw, +int sja1000_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw, int sampl_pt, int flags) { int best_error = 1000000000, error; @@ -186,7 +186,7 @@ int sja1000_baud_rate(struct chip_t *chip, int rate, int clock, int sjw, return 0; } -int sja1000_pre_read_config(struct chip_t *chip, struct msgobj_t *obj) +int sja1000_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj) { int i; @@ -214,7 +214,7 @@ int sja1000_pre_read_config(struct chip_t *chip, struct msgobj_t *obj) #define MAX_TRANSMIT_WAIT_LOOPS 10 -int sja1000_pre_write_config(struct chip_t *chip, struct msgobj_t *obj, +int sja1000_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg) { int i=0, id=0; @@ -255,7 +255,7 @@ int sja1000_pre_write_config(struct chip_t *chip, struct msgobj_t *obj, return 0; } -int sja1000_send_msg(struct chip_t *chip, struct msgobj_t *obj, +int sja1000_send_msg(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg) { can_write_reg(chip, sjaCMR_TR, SJACMR); @@ -263,7 +263,7 @@ int sja1000_send_msg(struct chip_t *chip, struct msgobj_t *obj, return 0; } -int sja1000_check_tx_stat(struct chip_t *chip) +int sja1000_check_tx_stat(struct canchip_t *chip) { if (can_read_reg(chip,SJASR) & sjaSR_TCS) return 0; @@ -271,7 +271,7 @@ int sja1000_check_tx_stat(struct chip_t *chip) return 1; } -int sja1000_set_btregs(struct chip_t *chip, unsigned short btr0, +int sja1000_set_btregs(struct canchip_t *chip, unsigned short btr0, unsigned short btr1) { if (sja1000_enable_configuration(chip)) @@ -285,7 +285,7 @@ int sja1000_set_btregs(struct chip_t *chip, unsigned short btr0, return 0; } -int sja1000_start_chip(struct chip_t *chip) +int sja1000_start_chip(struct canchip_t *chip) { unsigned short flags = 0; @@ -295,7 +295,7 @@ int sja1000_start_chip(struct chip_t *chip) return 0; } -int sja1000_stop_chip(struct chip_t *chip) +int sja1000_stop_chip(struct canchip_t *chip) { unsigned short flags = 0; @@ -305,37 +305,37 @@ int sja1000_stop_chip(struct chip_t *chip) return 0; } -int sja1000_remote_request(struct chip_t *chip, struct msgobj_t *obj) +int sja1000_remote_request(struct canchip_t *chip, struct msgobj_t *obj) { CANMSG("sja1000_remote_request not implemented\n"); return -ENOSYS; } -int sja1000_extended_mask(struct chip_t *chip, unsigned long code, +int sja1000_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask) { CANMSG("sja1000_extended_mask not implemented\n"); return -ENOSYS; } -int sja1000_clear_objects(struct chip_t *chip) +int sja1000_clear_objects(struct canchip_t *chip) { CANMSG("sja1000_clear_objects not implemented\n"); return -ENOSYS; } -int sja1000_config_irqs(struct chip_t *chip, short irqs) +int sja1000_config_irqs(struct canchip_t *chip, short irqs) { CANMSG("sja1000_config_irqs not implemented\n"); return -ENOSYS; } -can_irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +int sja1000_irq_handler(int irq, struct canchip_t *chip) { unsigned irq_register; - struct chip_t *chip=(struct chip_t *)dev_id; 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); @@ -343,43 +343,54 @@ can_irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs) // can_read_reg(chip, SJASR)); if ((irq_register & (sjaIR_WUI|sjaIR_DOI|sjaIR_EI|sjaIR_TI|sjaIR_RI)) == 0) - return CAN_IRQ_NONE; + 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_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_RI) != 0) + sja1000_irq_read_handler(chip, obj); - if (can_read_reg(chip, SJASR) & sjaSR_TBS) - sja1000_irq_write_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); - can_msgobj_clear_fl(obj,TX_LOCK); - if(!can_msgobj_test_fl(obj,TX_REQUEST)) break; + 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; + } } - } - 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;*/ + } } - } - return CAN_IRQ_HANDLED; + irq_register=can_read_reg(chip, SJAIR); + + } while(irq_register & (sjaIR_WUI|sjaIR_DOI|sjaIR_EI|sjaIR_TI|sjaIR_RI)); + + return CANCHIP_IRQ_HANDLED; } -void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *obj) +void sja1000_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj) { int i=0, id=0, len; @@ -387,12 +398,6 @@ void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *obj) id = can_read_reg(chip, SJARXID0) | (can_read_reg(chip, SJARXID1)<<8); obj->rx_msg.length = len = id & 0x0f; obj->rx_msg.flags = id&sjaID0_RTR ? MSG_RTR : 0; - #ifdef CAN_MSG_VERSION_2 - obj->rx_msg.timestamp.tv_sec = 0; - obj->rx_msg.timestamp.tv_usec = 0; - #else /* CAN_MSG_VERSION_2 */ - obj->rx_msg.timestamp = 0; - #endif /* CAN_MSG_VERSION_2 */ obj->rx_msg.cob = 0; obj->rx_msg.id = id>>5; @@ -402,17 +407,23 @@ void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *obj) can_write_reg(chip, sjaCMR_RRB, SJACMR); + /* fill CAN message timestamp */ + can_filltimestamp(&obj->rx_msg.timestamp); + canque_filter_msg2edges(obj->qends, &obj->rx_msg); } while(can_read_reg(chip, SJASR) & sjaSR_RBS); } -void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj) +void sja1000_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj) { int cmd; 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); } @@ -449,7 +460,7 @@ void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj) * Return Value: negative value reports error. * File: src/sja1000.c */ -int sja1000_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj) +int sja1000_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj) { can_preempt_disable(); @@ -492,7 +503,7 @@ int sja1000_register(struct chipspecops_t *chipspecops) return 0; } -int sja1000_fill_chipspecops(struct chip_t *chip) +int sja1000_fill_chipspecops(struct canchip_t *chip) { chip->chip_type="sja1000"; chip->max_objects=1;