X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/c6d6f58c34e1b6a4c03d1e86d1abf48eeb6f5624..3a2bb63f0bb8de2aafb346b53b945c59b3f87a41:/lincan/src/sja1000p.c diff --git a/lincan/src/sja1000p.c b/lincan/src/sja1000p.c index bc2fcc3..3087db5 100644 --- a/lincan/src/sja1000p.c +++ b/lincan/src/sja1000p.c @@ -6,7 +6,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" @@ -23,21 +23,21 @@ int sja1000p_enable_configuration(struct chip_t *chip) int i=0; enum sja1000_PeliCAN_MOD flags; - disable_irq(chip->chip_irq); + can_disable_irq(chip->chip_irq); flags=can_read_reg(chip,SJAMOD); - while ((!(flags & MOD_RM)) && (i<=10)) { - can_write_reg(chip, MOD_RM, SJAMOD); -// TODO: configurable MOD_AFM (32/16 bit acceptance filter) -// config MOD_LOM (listen only) + while ((!(flags & sjaMOD_RM)) && (i<=10)) { + can_write_reg(chip, sjaMOD_RM, SJAMOD); +// TODO: configurable sjaMOD_AFM (32/16 bit acceptance filter) +// config sjaMOD_LOM (listen only) udelay(100); i++; flags=can_read_reg(chip, SJAMOD); } if (i>=10) { CANMSG("Reset error\n"); - enable_irq(chip->chip_irq); + can_enable_irq(chip->chip_irq); return -ENODEV; } @@ -55,11 +55,11 @@ int sja1000p_disable_configuration(struct chip_t *chip) flags=can_read_reg(chip,SJAMOD); - while ( (flags & MOD_RM) && (i<=50) ) { + while ( (flags & sjaMOD_RM) && (i<=50) ) { // could be as long as 11*128 bit times after buss-off can_write_reg(chip, 0, SJAMOD); -// TODO: configurable MOD_AFM (32/16 bit acceptance filter) -// config MOD_LOM (listen only) +// TODO: configurable sjaMOD_AFM (32/16 bit acceptance filter) +// config sjaMOD_LOM (listen only) udelay(100); i++; flags=can_read_reg(chip, SJAMOD); @@ -69,7 +69,7 @@ int sja1000p_disable_configuration(struct chip_t *chip) return -ENODEV; } - enable_irq(chip->chip_irq); + can_enable_irq(chip->chip_irq); return 0; } @@ -95,7 +95,7 @@ int sja1000p_chip_config(struct chip_t *chip) return -ENODEV; /* Set mode, clock out, comparator */ - can_write_reg(chip,CDR_PELICAN|chip->sja_cdr_reg,SJACDR); + can_write_reg(chip,sjaCDR_PELICAN|chip->sja_cdr_reg,SJACDR); /* Set driver output configuration */ can_write_reg(chip,chip->sja_ocr_reg,SJAOCR); @@ -122,7 +122,7 @@ int sja1000p_chip_config(struct chip_t *chip) return -ENODEV; /* Enable hardware interrupts */ - can_write_reg(chip, ENABLE_INTERRUPTS, SJAIER); + can_write_reg(chip, sjaENABLE_INTERRUPTS, SJAIER); sja1000p_disable_configuration(chip); @@ -186,7 +186,7 @@ int sja1000p_baud_rate(struct chip_t *chip, int rate, int clock, int sjw, clock /=2; /* tseg even = round down, odd = round up */ - for (tseg=(0+0+2)*2; tseg<=(MAX_TSEG2+MAX_TSEG1+2)*2+1; tseg++) { + for (tseg=(0+0+2)*2; tseg<=(sjaMAX_TSEG2+sjaMAX_TSEG1+2)*2+1; tseg++) { brp = clock/((1+tseg/2)*rate)+tseg%2; if (brp == 0 || brp > 64) continue; @@ -210,11 +210,11 @@ int sja1000p_baud_rate(struct chip_t *chip, int rate, int clock, int sjw, tseg2 = best_tseg-(sampl_pt*(best_tseg+1))/100; if (tseg2 < 0) tseg2 = 0; - if (tseg2 > MAX_TSEG2) - tseg2 = MAX_TSEG2; + if (tseg2 > sjaMAX_TSEG2) + tseg2 = sjaMAX_TSEG2; tseg1 = best_tseg-tseg2-2; - if (tseg1>MAX_TSEG1) { - tseg1 = MAX_TSEG1; + if (tseg1>sjaMAX_TSEG1) { + tseg1 = sjaMAX_TSEG1; tseg2 = best_tseg-tseg1-2; } @@ -244,7 +244,7 @@ void sja1000p_read(struct chip_t *chip, struct msgobj_t *obj) { int i, flags, len, datastart; do { flags = can_read_reg(chip,SJAFRM); - if(flags&FRM_FF) { + if(flags&sjaFRM_FF) { obj->rx_msg.id = (can_read_reg(chip,SJAID0)<<21) + (can_read_reg(chip,SJAID1)<<13) + @@ -258,20 +258,23 @@ void sja1000p_read(struct chip_t *chip, struct msgobj_t *obj) { datastart = SJADATS; } obj->rx_msg.flags = - ((flags & FRM_RTR) ? MSG_RTR : 0) | - ((flags & FRM_FF) ? MSG_EXT : 0); - len = flags & FRM_DLC_M; + ((flags & sjaFRM_RTR) ? MSG_RTR : 0) | + ((flags & sjaFRM_FF) ? MSG_EXT : 0); + len = flags & sjaFRM_DLC_M; obj->rx_msg.length = len; if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH; for(i=0; i< len; i++) { obj->rx_msg.data[i]=can_read_reg(chip,datastart+i); } + /* fill CAN message timestamp */ + can_filltimestamp(&obj->rx_msg.timestamp); + canque_filter_msg2edges(obj->qends, &obj->rx_msg); - can_write_reg(chip, CMR_RRB, SJACMR); + can_write_reg(chip, sjaCMR_RRB, SJACMR); - } while (can_read_reg(chip, SJASR) & SR_RBS); + } while (can_read_reg(chip, SJASR) & sjaSR_RBS); } /** @@ -288,7 +291,7 @@ int sja1000p_pre_read_config(struct chip_t *chip, struct msgobj_t *obj) int status; status=can_read_reg(chip,SJASR); - if(status & SR_BS) { + if(status & sjaSR_BS) { /* Try to recover from error condition */ DEBUGMSG("sja1000p_pre_read_config bus-off recover 0x%x\n",status); sja1000p_enable_configuration(chip); @@ -298,13 +301,13 @@ int sja1000p_pre_read_config(struct chip_t *chip, struct msgobj_t *obj) sja1000p_disable_configuration(chip); } - if (!(status&SR_RBS)) { + if (!(status&sjaSR_RBS)) { return 0; } - can_write_reg(chip, DISABLE_INTERRUPTS, SJAIER); //disable interrupts for a moment + can_write_reg(chip, sjaDISABLE_INTERRUPTS, SJAIER); //disable interrupts for a moment sja1000p_read(chip, obj); - can_write_reg(chip, ENABLE_INTERRUPTS, SJAIER); //enable interrupts + can_write_reg(chip, sjaENABLE_INTERRUPTS, SJAIER); //enable interrupts return 1; } @@ -331,12 +334,12 @@ int sja1000p_pre_write_config(struct chip_t *chip, struct msgobj_t *obj, int len; /* Wait until Transmit Buffer Status is released */ - while ( !((status=can_read_reg(chip, SJASR)) & SR_TBS) && + while ( !((status=can_read_reg(chip, SJASR)) & sjaSR_TBS) && i++length; if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH; - /* len &= FRM_DLC_M; ensured by above condition already */ - can_write_reg(chip, ((msg->flags&MSG_EXT)?FRM_FF:0) | - ((msg->flags & MSG_RTR) ? FRM_RTR : 0) | len, SJAFRM); + /* len &= sjaFRM_DLC_M; ensured by above condition already */ + can_write_reg(chip, ((msg->flags&MSG_EXT)?sjaFRM_FF:0) | + ((msg->flags & MSG_RTR) ? sjaFRM_RTR : 0) | len, SJAFRM); if(msg->flags&MSG_EXT) { id=msg->id<<3; can_write_reg(chip, id & 0xff, SJAID3); @@ -404,7 +407,7 @@ int sja1000p_pre_write_config(struct chip_t *chip, struct msgobj_t *obj, int sja1000p_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; } @@ -420,7 +423,7 @@ int sja1000p_send_msg(struct chip_t *chip, struct msgobj_t *obj, */ int sja1000p_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; @@ -460,7 +463,7 @@ int sja1000p_start_chip(struct chip_t *chip) { enum sja1000_PeliCAN_MOD flags; - flags = can_read_reg(chip, SJAMOD) & (MOD_LOM|MOD_STM|MOD_AFM|MOD_SM); + flags = can_read_reg(chip, SJAMOD) & (sjaMOD_LOM|sjaMOD_STM|sjaMOD_AFM|sjaMOD_SM); can_write_reg(chip, flags, SJAMOD); return 0; @@ -477,8 +480,8 @@ int sja1000p_stop_chip(struct chip_t *chip) { enum sja1000_PeliCAN_MOD flags; - flags = can_read_reg(chip, SJAMOD) & (MOD_LOM|MOD_STM|MOD_AFM|MOD_SM); - can_write_reg(chip, flags|MOD_RM, SJAMOD); + flags = can_read_reg(chip, SJAMOD) & (sjaMOD_LOM|sjaMOD_STM|sjaMOD_AFM|sjaMOD_SM); + can_write_reg(chip, flags|sjaMOD_RM, SJAMOD); return 0; } @@ -559,6 +562,9 @@ void sja1000p_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); } @@ -605,7 +611,7 @@ void sja1000p_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj) * message queues. * File: src/sja1000p.c */ -irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +can_irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { int irq_register, status, error_code; struct chip_t *chip=(struct chip_t *)dev_id; @@ -616,35 +622,35 @@ irqreturn_t sja1000p_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_BEI|IR_EPI|IR_DOI|IR_EI|IR_TI|IR_RI)) == 0) - return IRQ_NONE; + if ((irq_register & (sjaIR_BEI|sjaIR_EPI|sjaIR_DOI|sjaIR_EI|sjaIR_TI|sjaIR_RI)) == 0) + return CAN_IRQ_NONE; - if(!obj->flags & OBJ_BUFFERS_ALLOCATED) { - CANMSG("sja1000p_irq_handler: called with device closed, irq_register 0x%02x\n", irq_register); - return IRQ_NONE; + if(!(chip->flags&CHIP_CONFIGURED)) { + CANMSG("sja1000p_irq_handler: called for non-configured device, irq_register 0x%02x\n", irq_register); + return CAN_IRQ_NONE; } - if ((irq_register & IR_RI) != 0) { + if ((irq_register & sjaIR_RI) != 0) { DEBUGMSG("sja1000_irq_handler: RI\n"); sja1000p_read(chip,obj); obj->ret = 0; } - if ((irq_register & IR_TI) != 0) { + if ((irq_register & sjaIR_TI) != 0) { DEBUGMSG("sja1000_irq_handler: TI\n"); obj->ret = 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); + 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) sja1000p_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; DEBUGMSG("TX looping in sja1000_irq_handler\n"); } } - if ((irq_register & (IR_EI|IR_BEI|IR_EPI|IR_DOI)) != 0) { + 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); @@ -659,10 +665,10 @@ irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs) /* no such device or address - no ACK received */ } if(obj->tx_retry_cnt++>MAX_RETR) { - can_write_reg(chip, CMR_AT, SJACMR); // cancel any transmition + can_write_reg(chip, sjaCMR_AT, SJACMR); // cancel any transmition obj->tx_retry_cnt = 0; } - if(status&SR_BS) { + if(status&sjaSR_BS) { CANMSG("bus-off, resetting sja1000p\n"); can_write_reg(chip, 0, SJAMOD); } @@ -677,7 +683,7 @@ irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs) obj->tx_retry_cnt=0; } - return IRQ_HANDLED; + return CAN_IRQ_HANDLED; } /** @@ -685,34 +691,32 @@ irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs) * @chip: pointer to chip state structure * @obj: pointer to message object structure * + * Function is responsible for initiating message transmition. + * It is responsible for clearing of object TX_REQUEST flag + * * Return Value: negative value reports error. * File: src/sja1000p.c */ int sja1000p_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){ obj->tx_retry_cnt=0; sja1000p_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; DEBUGMSG("TX looping in sja1000p_wakeup_tx\n"); } - /* preempt_enable(); */ - spin_unlock(&dummy_lock); + can_preempt_enable(); return 0; } @@ -740,3 +744,19 @@ int sja1000p_register(struct chipspecops_t *chipspecops) chipspecops->irq_handler=sja1000p_irq_handler; return 0; } + +/** + * sja1000p_fill_chipspecops - fills chip specific operations + * @chip: pointer to chip representation structure + * + * The function fills chip specific operations for sja1000 (PeliCAN) chip. + * + * Return Value: returns negative number in the case of fail + */ +int sja1000p_fill_chipspecops(struct chip_t *chip) +{ + chip->chip_type="sja1000p"; + chip->max_objects=1; + sja1000p_register(chip->chipspecops); + return 0; +}