X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/c6d6f58c34e1b6a4c03d1e86d1abf48eeb6f5624..258e4a224adc90317b3d11622a3076ba6d61b0d2:/lincan/src/sja1000.c diff --git a/lincan/src/sja1000.c b/lincan/src/sja1000.c index 9211511..dfc47a2 100644 --- a/lincan/src/sja1000.c +++ b/lincan/src/sja1000.c @@ -4,7 +4,7 @@ * Rewritten for new CAN queues by Pavel Pisa - OCERA team member * email:pisa@cmp.felk.cvut.cz * This software is released under the GPL-License. - * Version lincan-0.2 9 Jul 2003 + * Version lincan-0.3 17 Jun 2004 */ #include "../include/can.h" @@ -20,19 +20,19 @@ int sja1000_enable_configuration(struct chip_t *chip) int i=0; unsigned flags; - disable_irq(chip->chip_irq); + can_disable_irq(chip->chip_irq); flags=can_read_reg(chip,SJACR); - while ((!(flags & CR_RR)) && (i<=10)) { - can_write_reg(chip,flags|CR_RR,SJACR); + while ((!(flags & sjaCR_RR)) && (i<=10)) { + can_write_reg(chip,flags|sjaCR_RR,SJACR); udelay(100); i++; flags=can_read_reg(chip,SJACR); } if (i>=10) { CANMSG("Reset error\n"); - enable_irq(chip->chip_irq); + can_enable_irq(chip->chip_irq); return -ENODEV; } @@ -46,8 +46,8 @@ int sja1000_disable_configuration(struct chip_t *chip) flags=can_read_reg(chip,SJACR); - while ( (flags & CR_RR) && (i<=10) ) { - can_write_reg(chip,flags & (CR_RIE|CR_TIE|CR_EIE|CR_OIE),SJACR); + while ( (flags & sjaCR_RR) && (i<=10) ) { + can_write_reg(chip,flags & (sjaCR_RIE|sjaCR_TIE|sjaCR_EIE|sjaCR_OIE),SJACR); udelay(100); i++; flags=can_read_reg(chip,SJACR); @@ -57,7 +57,7 @@ int sja1000_disable_configuration(struct chip_t *chip) return -ENODEV; } - enable_irq(chip->chip_irq); + can_enable_irq(chip->chip_irq); return 0; } @@ -81,7 +81,7 @@ int sja1000_chip_config(struct chip_t *chip) return -ENODEV; /* Enable hardware interrupts */ - can_write_reg(chip,(CR_RIE|CR_TIE|CR_EIE|CR_OIE),SJACR); + can_write_reg(chip,(sjaCR_RIE|sjaCR_TIE|sjaCR_EIE|sjaCR_OIE),SJACR); sja1000_disable_configuration(chip); @@ -177,9 +177,9 @@ int sja1000_baud_rate(struct chip_t *chip, int rate, int clock, int sjw, can_write_reg(chip, sjw<<6 | best_brp, SJABTR0); can_write_reg(chip, ((flags & BTR1_SAM) != 0)<<7 | tseg2<<4 | tseg1, SJABTR1); -// can_write_reg(chip, OCR_MODE_NORMAL | OCR_TX0_LH | OCR_TX1_ZZ, SJAOCR); +// can_write_reg(chip, sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH | sjaOCR_TX1_ZZ, SJAOCR); /* BASIC mode, bypass input comparator */ -// can_write_reg(chip, CDR_CBP| /* CDR_CLK_OFF | */ 7, SJACDR); +// can_write_reg(chip, sjaCDR_CBP| /* sjaCDR_CLK_OFF | */ 7, SJACDR); sja1000_disable_configuration(chip); @@ -192,7 +192,7 @@ int sja1000_pre_read_config(struct chip_t *chip, struct msgobj_t *obj) i=can_read_reg(chip,SJASR); - if (!(i&SR_RBS)) { + if (!(i&sjaSR_RBS)) { //Temp for (i=0; i<0x20; i++) CANMSG("0x%x is 0x%x\n",i,can_read_reg(chip,i)); @@ -206,7 +206,7 @@ int sja1000_pre_read_config(struct chip_t *chip, struct msgobj_t *obj) sja1000_irq_read_handler(chip, obj); // enable interrupts - can_write_reg(chip, CR_OIE | CR_EIE | CR_TIE | CR_RIE, SJACR); + can_write_reg(chip, sjaCR_OIE | sjaCR_EIE | sjaCR_TIE | sjaCR_RIE, SJACR); return 1; @@ -223,20 +223,20 @@ int sja1000_pre_write_config(struct chip_t *chip, struct msgobj_t *obj, sja1000_start_chip(chip); //sja1000 goes automatically into reset mode on errors /* Wait until Transmit Buffer Status is released */ - while ( !(can_read_reg(chip, SJASR) & SR_TBS) && + while ( !(can_read_reg(chip, SJASR) & sjaSR_TBS) && i++length; if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH; - id = (msg->id<<5) | ((msg->flags&MSG_RTR)?ID0_RTR:0) | len; + id = (msg->id<<5) | ((msg->flags&MSG_RTR)?sjaID0_RTR:0) | len; can_write_reg(chip, id>>8, SJATXID1); can_write_reg(chip, id & 0xff , SJATXID0); @@ -258,14 +258,14 @@ int sja1000_pre_write_config(struct chip_t *chip, struct msgobj_t *obj, int sja1000_send_msg(struct chip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg) { - can_write_reg(chip, CMR_TR, SJACMR); + can_write_reg(chip, sjaCMR_TR, SJACMR); return 0; } int sja1000_check_tx_stat(struct chip_t *chip) { - if (can_read_reg(chip,SJASR) & SR_TCS) + if (can_read_reg(chip,SJASR) & sjaSR_TCS) return 0; else return 1; @@ -289,7 +289,7 @@ int sja1000_start_chip(struct chip_t *chip) { unsigned short flags = 0; - flags = can_read_reg(chip, SJACR) & (CR_RIE|CR_TIE|CR_EIE|CR_OIE); + flags = can_read_reg(chip, SJACR) & (sjaCR_RIE|sjaCR_TIE|sjaCR_EIE|sjaCR_OIE); can_write_reg(chip, flags, SJACR); return 0; @@ -299,8 +299,8 @@ int sja1000_stop_chip(struct chip_t *chip) { unsigned short flags = 0; - flags = can_read_reg(chip, SJACR) & (CR_RIE|CR_TIE|CR_EIE|CR_OIE); - can_write_reg(chip, flags|CR_RR, SJACR); + flags = can_read_reg(chip, SJACR) & (sjaCR_RIE|sjaCR_TIE|sjaCR_EIE|sjaCR_OIE); + can_write_reg(chip, flags|sjaCR_RR, SJACR); return 0; } @@ -331,10 +331,9 @@ int sja1000_config_irqs(struct chip_t *chip, short irqs) } -irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +int sja1000_irq_handler(int irq, struct chip_t *chip) { unsigned irq_register; - struct chip_t *chip=(struct chip_t *)dev_id; struct msgobj_t *obj=chip->msgobj[0]; irq_register=can_read_reg(chip, SJAIR); @@ -342,26 +341,26 @@ irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs) // DEBUGMSG("sja1000_irq_handler: SJASR:%02x\n", // can_read_reg(chip, SJASR)); - if ((irq_register & (IR_WUI|IR_DOI|IR_EI|IR_TI|IR_RI)) == 0) - return IRQ_NONE; + if ((irq_register & (sjaIR_WUI|sjaIR_DOI|sjaIR_EI|sjaIR_TI|sjaIR_RI)) == 0) + return CANCHIP_IRQ_NONE; - if ((irq_register & IR_RI) != 0) + if ((irq_register & sjaIR_RI) != 0) sja1000_irq_read_handler(chip, obj); - if ((irq_register & IR_TI) != 0) { - set_bit(OBJ_TX_REQUEST,&obj->flags); - while(!test_and_set_bit(OBJ_TX_LOCK,&obj->flags)){ - clear_bit(OBJ_TX_REQUEST,&obj->flags); + 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) & SR_TBS) + if (can_read_reg(chip, SJASR) & sjaSR_TBS) sja1000_irq_write_handler(chip, obj); - clear_bit(OBJ_TX_LOCK,&obj->flags); - if(!test_bit(OBJ_TX_REQUEST,&obj->flags)) break; + can_msgobj_clear_fl(obj,TX_LOCK); + if(!can_msgobj_test_fl(obj,TX_REQUEST)) break; } } - if ((irq_register & (IR_EI|IR_DOI)) != 0) { + 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 @@ -376,7 +375,7 @@ irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs) } } - return IRQ_HANDLED; + return CANCHIP_IRQ_HANDLED; } void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *obj) @@ -386,8 +385,7 @@ void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *obj) do { id = can_read_reg(chip, SJARXID0) | (can_read_reg(chip, SJARXID1)<<8); obj->rx_msg.length = len = id & 0x0f; - obj->rx_msg.flags = id&ID0_RTR ? MSG_RTR : 0; - obj->rx_msg.timestamp = 0; + obj->rx_msg.flags = id&sjaID0_RTR ? MSG_RTR : 0; obj->rx_msg.cob = 0; obj->rx_msg.id = id>>5; @@ -395,10 +393,13 @@ void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *obj) for (i=0; irx_msg.data[i]=can_read_reg(chip, SJARXDAT0 + i); - can_write_reg(chip, CMR_RRB, SJACMR); + 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) & SR_RBS); + } while(can_read_reg(chip, SJASR) & sjaSR_RBS); } void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj) @@ -408,6 +409,9 @@ void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj) 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); } @@ -446,26 +450,20 @@ void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj) */ int sja1000_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj) { - /* dummy lock to prevent preemption fully portable way */ - spinlock_t dummy_lock; - - /* preempt_disable() */ - spin_lock_init(&dummy_lock); - spin_lock(&dummy_lock); + can_preempt_disable(); - set_bit(OBJ_TX_REQUEST,&obj->flags); - while(!test_and_set_bit(OBJ_TX_LOCK,&obj->flags)){ - clear_bit(OBJ_TX_REQUEST,&obj->flags); + 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) & SR_TBS) + if (can_read_reg(chip, SJASR) & sjaSR_TBS) sja1000_irq_write_handler(chip, obj); - clear_bit(OBJ_TX_LOCK,&obj->flags); - if(!test_bit(OBJ_TX_REQUEST,&obj->flags)) break; + can_msgobj_clear_fl(obj,TX_LOCK); + if(!can_msgobj_test_fl(obj,TX_REQUEST)) break; } - /* preempt_enable(); */ - spin_unlock(&dummy_lock); + can_preempt_enable(); return 0; } @@ -492,3 +490,12 @@ int sja1000_register(struct chipspecops_t *chipspecops) chipspecops->irq_handler = sja1000_irq_handler; return 0; } + +int sja1000_fill_chipspecops(struct chip_t *chip) +{ + chip->chip_type="sja1000"; + chip->max_objects=1; + sja1000_register(chip->chipspecops); + return 0; +} +