X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/cb551cc1582f3b51cf17e80730bee3c2f0701c3f..5282a3d5b5624f59a4a11b061368e523934fe5f0:/lincan/src/c_can.c diff --git a/lincan/src/c_can.c b/lincan/src/c_can.c index 6bef001..4c052c3 100644 --- a/lincan/src/c_can.c +++ b/lincan/src/c_can.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 */ #define __NO_VERSION__ @@ -28,11 +28,11 @@ can_spinlock_t c_can_if2lock=SPIN_LOCK_UNLOCKED; // spin lcok for the if2 regist * c_can_enable_configuration - enable chip configuration mode * @pchip: pointer to chip state structure */ -int c_can_enable_configuration(struct chip_t *pchip) +int c_can_enable_configuration(struct canchip_t *pchip) { int i=0; u16 flags; - DEBUGMSG("(c%d)calling c_can_enable_configuration(...)\n", pchip->chip_nr); + DEBUGMSG("(c%d)calling c_can_enable_configuration(...)\n", pchip->chip_idx); /* DEBUGMSG("Trying disable_irq(...) : "); //disable IRQ @@ -60,12 +60,12 @@ int c_can_enable_configuration(struct chip_t *pchip) } /////////////////////////////////////////////////////////////////////// -int c_can_disable_configuration(struct chip_t *pchip) +int c_can_disable_configuration(struct canchip_t *pchip) { int i=0; u16 flags; - DEBUGMSG("(c%d)calling c_can_disable_configuration(...)\n", pchip->chip_nr); + DEBUGMSG("(c%d)calling c_can_disable_configuration(...)\n", pchip->chip_idx); //read Control Register flags=c_can_read_reg_w(pchip, CCCR); @@ -90,10 +90,10 @@ int c_can_disable_configuration(struct chip_t *pchip) } /////////////////////////////////////////////////////////////////////// -int c_can_chip_config(struct chip_t *pchip) +int c_can_chip_config(struct canchip_t *pchip) { - DEBUGMSG("(c%d)calling c_can_chip_config(...)\n", pchip->chip_nr); + DEBUGMSG("(c%d)calling c_can_chip_config(...)\n", pchip->chip_idx); // Validate pointer if ( NULL == pchip ) return -1; @@ -140,7 +140,7 @@ int c_can_chip_config(struct chip_t *pchip) /* * Checks if the Busy-Bit in the IF1-Command-Request Register is set */ -int c_can_if1_busycheck(struct chip_t *pchip) +int c_can_if1_busycheck(struct canchip_t *pchip) { int i=0; @@ -166,7 +166,7 @@ int c_can_if1_busycheck(struct chip_t *pchip) /* * Checks if the Busy-Bit in the IF2-Command-Request Register is set */ -int c_can_if2_busycheck(struct chip_t *pchip) +int c_can_if2_busycheck(struct canchip_t *pchip) { int i=0; @@ -201,7 +201,7 @@ int c_can_if2_busycheck(struct chip_t *pchip) * 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 c_can_baud_rate(struct chip_t *pchip, int rate, int clock, +int c_can_baud_rate(struct canchip_t *pchip, int rate, int clock, int sjw, int sampl_pt, int flags) { int best_error = 1000000000, error; @@ -210,13 +210,11 @@ int c_can_baud_rate(struct chip_t *pchip, int rate, int clock, unsigned short tempCR = 0; - DEBUGMSG("(c%d)calling c_can_baud_rate(...)\n", pchip->chip_nr); + DEBUGMSG("(c%d)calling c_can_baud_rate(...)\n", pchip->chip_idx); if (c_can_enable_configuration(pchip)) return -ENODEV; - clock /=2; - /* tseg even = round down, odd = round up */ for (tseg=(0+0+2)*2; tseg<=(MAX_TSEG2+MAX_TSEG1+2)*2+1; tseg++) { @@ -237,7 +235,7 @@ int c_can_baud_rate(struct chip_t *pchip, int rate, int clock, if (best_error && (rate/best_error < 10)) { CANMSG("baud rate %d is not possible with %d Hz clock\n", - rate, 2*clock); + rate, clock); CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n", best_rate, best_brp, best_tseg, tseg1, tseg2); return -EINVAL; @@ -282,7 +280,7 @@ int c_can_mask(struct msgobj_t *pmsgobj, unsigned short readMaskCM; unsigned short writeMaskCM; - DEBUGMSG("(c%dm%d)calling c_can_mask(...)\n", pmsgobj->hostchip->chip_nr, pmsgobj->object); + DEBUGMSG("(c%dm%d)calling c_can_mask(...)\n", pmsgobj->hostchip->chip_idx, pmsgobj->object); readMaskCM = IFXCM_CNTRL | IFXCM_ARB | IFXCM_MASK; writeMaskCM = IFXCM_CNTRL | IFXCM_ARB | IFXCM_MASK | IFXCM_WRRD; @@ -355,7 +353,7 @@ int c_can_use_mask(struct msgobj_t *pmsgobj, char *boolstring = "false"; if (useflag) boolstring = "true"; #endif - DEBUGMSG("(c%dm%d)calling c_can_use_mask(...)\n", pmsgobj->hostchip->chip_nr, pmsgobj->object); + DEBUGMSG("(c%dm%d)calling c_can_use_mask(...)\n", pmsgobj->hostchip->chip_idx, pmsgobj->object); readMaskCM = IFXCM_CNTRL | IFXCM_ARB; writeMaskCM = IFXCM_CNTRL | IFXCM_ARB | IFXCM_WRRD;; @@ -406,14 +404,14 @@ int c_can_use_mask(struct msgobj_t *pmsgobj, } /////////////////////////////////////////////////////////////////////// -int c_can_clear_objects(struct chip_t *pchip) +int c_can_clear_objects(struct canchip_t *pchip) { unsigned short i = 0; unsigned short tempreg = 0; unsigned short maskCM = IFXCM_ARB; - DEBUGMSG("(c%d)calling c_can_clear_objects(...)\n", pchip->chip_nr); + DEBUGMSG("(c%d)calling c_can_clear_objects(...)\n", pchip->chip_idx); spin_lock( &c_can_if1lock ); spin_lock( &c_can_if2lock ); @@ -460,17 +458,12 @@ int c_can_clear_objects(struct chip_t *pchip) } /////////////////////////////////////////////////////////////////////// -int c_can_config_irqs(struct chip_t *pchip, +int c_can_config_irqs(struct canchip_t *pchip, u16 irqs) { u16 tempreg; - DEBUGMSG("(c%d)calling c_can_config_irqs(...)\n", pchip->chip_nr); - - /* - CANMSG("c_can_config_irqs not implemented\n"); - return -ENOSYS; - */ + DEBUGMSG("(c%d)calling c_can_config_irqs(...)\n", pchip->chip_idx); tempreg = c_can_read_reg_w(pchip, CCCR); //DEBUGMSG("-> CAN Control Register: 0x%.4lx\n",(long)tempreg); @@ -480,29 +473,37 @@ int c_can_config_irqs(struct chip_t *pchip, } /////////////////////////////////////////////////////////////////////// -int c_can_pre_read_config(struct chip_t *pchip, struct msgobj_t *pmsgobj) +int c_can_pre_read_config(struct canchip_t *pchip, struct msgobj_t *pmsgobj) { unsigned short readMaskCM = IFXCM_CNTRL | IFXCM_ARB; unsigned short writeMaskCM = IFXCM_CNTRL | IFXCM_ARB | IFXCM_WRRD; unsigned short mcreg = 0; u32 id=pmsgobj->rx_preconfig_id; - DEBUGMSG("(c%dm%d)calling c_can_pre_read_config(...)\n", pmsgobj->hostchip->chip_nr, pmsgobj->object); + DEBUGMSG("(c%dm%d)calling c_can_pre_read_config(...)\n", pmsgobj->hostchip->chip_idx, pmsgobj->object); spin_lock( &c_can_if1lock ); - //loading Message Object in IF1 - if (c_can_if1_busycheck(pmsgobj->hostchip)) return -ENODEV; + if (c_can_if1_busycheck(pmsgobj->hostchip)) + goto error_enodev; + c_can_write_reg_w(pmsgobj->hostchip, readMaskCM, CCIF1CM); c_can_write_reg_w(pmsgobj->hostchip, pmsgobj->object, CCIF1CR); + //setting Message Valid Bit to zero - if (c_can_if1_busycheck(pmsgobj->hostchip)) return -ENODEV; + if (c_can_if1_busycheck(pmsgobj->hostchip)) + goto error_enodev; + c_can_write_reg_w(pmsgobj->hostchip, 0, CCIF1A2); c_can_write_reg_w(pmsgobj->hostchip, writeMaskCM, CCIF1CM); c_can_write_reg_w(pmsgobj->hostchip, pmsgobj->object, CCIF1CR); + //Configuring Message-Object - if (c_can_if1_busycheck(pmsgobj->hostchip)) return -ENODEV; + /* Only access when the C_CAN controller is idle */ + if (c_can_if1_busycheck(pmsgobj->hostchip)) + goto error_enodev; + mcreg = c_can_read_reg_w(pmsgobj->hostchip, CCIF1CM); c_can_write_reg_w(pmsgobj->hostchip, ((mcreg & IFXMC_UMASK) | IFXMC_EOB | IFXMC_RXIE), CCIF1DMC); @@ -531,10 +532,16 @@ int c_can_pre_read_config(struct chip_t *pchip, struct msgobj_t *pmsgobj) #endif return 0; + +error_enodev: + CANMSG("Timeout in c_can_if1_busycheck\n"); + spin_unlock(&c_can_if1lock); + return -ENODEV; + } /////////////////////////////////////////////////////////////////////// -int c_can_pre_write_config(struct chip_t *chip, struct msgobj_t *obj, +int c_can_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg) { return 0; @@ -546,7 +553,7 @@ int c_can_pre_write_config(struct chip_t *chip, struct msgobj_t *obj, *In this version the method also sends the message. */ -int c_can_send_msg(struct chip_t *pchip, struct msgobj_t *pmsgobj, +int c_can_send_msg(struct canchip_t *pchip, struct msgobj_t *pmsgobj, struct canmsg_t *pmsg) { unsigned short readMaskCM = IFXCM_CNTRL | IFXCM_ARB | IFXCM_DA | IFXCM_DB; @@ -559,7 +566,7 @@ int c_can_send_msg(struct chip_t *pchip, struct msgobj_t *pmsgobj, unsigned short dataB1 = 0; unsigned short dataB2 = 0; - DEBUGMSG("(c%dm%d)calling c_can_send_msg(...)\n", pmsgobj->hostchip->chip_nr, pmsgobj->object); + DEBUGMSG("(c%dm%d)calling c_can_send_msg(...)\n", pmsgobj->hostchip->chip_idx, pmsgobj->object); spin_lock( &c_can_if2lock ); @@ -622,13 +629,13 @@ int c_can_send_msg(struct chip_t *pchip, struct msgobj_t *pmsgobj, } ////////////////////////////////////////////////////////////////////// -int c_can_remote_request(struct chip_t *pchip, struct msgobj_t *pmsgobj ) +int c_can_remote_request(struct canchip_t *pchip, struct msgobj_t *pmsgobj ) { unsigned short readMaskCM = IFXCM_CNTRL;// | IFXCM_ARB; //unsigned short writeMaskCM = IFXCM_CNTRL | IFXCM_ARB | IFXCM_WRRD; unsigned short mcreg = 0; - DEBUGMSG("(c%dm%d)calling c_can_remote_request(...)\n", pmsgobj->hostchip->chip_nr, pmsgobj->object); + DEBUGMSG("(c%dm%d)calling c_can_remote_request(...)\n", pmsgobj->hostchip->chip_idx, pmsgobj->object); //Remote request is only available when the message object is in receiving mode if (!can_msgobj_test_fl(pmsgobj,RX_MODE)) @@ -660,13 +667,13 @@ int c_can_remote_request(struct chip_t *pchip, struct msgobj_t *pmsgobj ) } /////////////////////////////////////////////////////////////////////// -int c_can_set_btregs(struct chip_t *pchip, +int c_can_set_btregs(struct canchip_t *pchip, u16 btr0, u16 btr1) { unsigned short tempCR = 0; - DEBUGMSG("(c%d)calling c_can_set_btregs(...)\n", pchip->chip_nr); + DEBUGMSG("(c%d)calling c_can_set_btregs(...)\n", pchip->chip_idx); // Validate pointer if ( NULL == pchip ) return -1; @@ -691,11 +698,11 @@ int c_can_set_btregs(struct chip_t *pchip, /* * Starts the Chip, by setting the CAN Enable Bit */ -int c_can_start_chip(struct chip_t *pchip) +int c_can_start_chip(struct canchip_t *pchip) { u16 flags = 0; - DEBUGMSG("(c%d)calling c_can_start_chip(...)\n", pchip->chip_nr); + DEBUGMSG("(c%d)calling c_can_start_chip(...)\n", pchip->chip_idx); // Validate pointer if ( NULL == pchip ) @@ -704,11 +711,10 @@ int c_can_start_chip(struct chip_t *pchip) return -1; } - // flags = c_can_read_reg_w(pchip, CCCE) | CE_EN; - // c_can_write_reg_w(pchip, flags, CCCE); - // +#ifdef C_CAN_WITH_CCCE flags = c_can_read_reg_w(pchip, CCCE) | CE_EN; c_can_write_reg_w(pchip, flags, CCCE); +#endif DEBUGMSG("-> ok\n"); #ifdef REGDUMP @@ -722,11 +728,11 @@ int c_can_start_chip(struct chip_t *pchip) /* * Stops the Chip, by deleting the CAN Enable Bit */ -int c_can_stop_chip(struct chip_t *pchip) +int c_can_stop_chip(struct canchip_t *pchip) { u16 flags = 0; - DEBUGMSG("(c%d)calling c_can_stop_chip(...)\n", pchip->chip_nr); + DEBUGMSG("(c%d)calling c_can_stop_chip(...)\n", pchip->chip_idx); // Validate pointer if ( NULL == pchip ) @@ -735,22 +741,47 @@ int c_can_stop_chip(struct chip_t *pchip) return -1; } +#ifdef C_CAN_WITH_CCCE flags = c_can_read_reg_w(pchip, CCCE) & ~CE_EN; c_can_write_reg_w(pchip, flags, CCCE); +#endif DEBUGMSG("-> ok\n"); return 0; } +int c_can_attach_to_chip(struct canchip_t *chip) +{ + return 0; +} + +int c_can_release_chip(struct canchip_t *chip) +{ + int temp; + + temp = c_can_read_reg_w(chip, CCCR); + + /* Disable IRQ generation */ + c_can_config_irqs(chip, 0); + + temp = c_can_read_reg_w(chip, CCCR); + + /* Power-down C_CAN, except this does nothing in the version 1.2 */ + c_can_stop_chip(chip); + + + return 0; +} + /////////////////////////////////////////////////////////////////////// /* *Check the TxOK bit of the Status Register and resets it afterwards. */ -int c_can_check_tx_stat(struct chip_t *pchip) +int c_can_check_tx_stat(struct canchip_t *pchip) { unsigned long tempstat = 0; - DEBUGMSG("(c%d)calling c_can_check_tx_stat(...)\n", pchip->chip_nr); + DEBUGMSG("(c%d)calling c_can_check_tx_stat(...)\n", pchip->chip_idx); // Validate pointer if ( NULL == pchip ) return -1; @@ -770,7 +801,7 @@ int c_can_check_tx_stat(struct chip_t *pchip) /////////////////////////////////////////////////////////////////////// -int c_can_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj) +int c_can_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj) { can_preempt_disable(); @@ -785,7 +816,7 @@ int c_can_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj) } /////////////////////////////////////////////////////////////////////// -int c_can_filtch_rq(struct chip_t *chip, struct msgobj_t *obj) +int c_can_filtch_rq(struct canchip_t *chip, struct msgobj_t *obj) { can_preempt_disable(); @@ -800,7 +831,7 @@ int c_can_filtch_rq(struct chip_t *chip, struct msgobj_t *obj) /////////////////////////////////////////////////////////////////////// -void c_can_registerdump(struct chip_t *pchip) +void c_can_registerdump(struct canchip_t *pchip) { CANMSG("------------------------------------\n"); CANMSG("---------C-CAN Register Dump--------\n"); @@ -820,8 +851,10 @@ void c_can_registerdump(struct chip_t *pchip) (long)(c_can_read_reg_w( pchip, CCTR))); CANMSG("Baud Rate Presc. Register: 0x%.4lx\n", (long)(c_can_read_reg_w( pchip, CCBRPE))); +#ifdef C_CAN_WITH_CCCE CANMSG("CAN Enable Register: 0x%.4lx\n", (long)(c_can_read_reg_w( pchip, CCCE))); +#endif CANMSG("Transm. Req. 1 Register: 0x%.4lx\n", (long)(c_can_read_reg_w( pchip, CCTREQ1))); CANMSG("Transm. Req. 2 Register: 0x%.4lx\n", @@ -884,6 +917,37 @@ void c_can_registerdump(struct chip_t *pchip) CANMSG("------------------------------------\n"); } + +void c_can_if1_registerdump(struct canchip_t *pchip) +{ + CANMSG("----------------------------------------\n"); + CANMSG("Error Counting Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCEC))); + CANMSG("---------C-CAN IF1 Register Dump--------\n"); + CANMSG("IF1 Command Req. Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCIF1CR))); + CANMSG("IF1 Command Mask Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCIF1CM))); + CANMSG("IF1 Mask 1 Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCIF1M1))); + CANMSG("IF1 Mask 2 Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCIF1M2))); + CANMSG("IF1 Arbitration 1 Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCIF1A1))); + CANMSG("IF1 Arbitration 2 Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCIF1A2))); + CANMSG("IF1 Message Control Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCIF1DMC))); + CANMSG("IF1 Data A1 Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCIF1DA1))); + CANMSG("IF1 Data A2 Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCIF1DA2))); + CANMSG("IF1 Data B1 Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCIF1DB1))); + CANMSG("IF1 Data B2 Register: 0x%.4lx\n", + (long)(c_can_read_reg_w( pchip, CCIF1DB2))); +} + /////////////////////////////////////////////////////////////////////// int c_can_register(struct chipspecops_t *chipspecops) @@ -905,40 +969,26 @@ int c_can_register(struct chipspecops_t *chipspecops) chipspecops->remote_request=c_can_remote_request; chipspecops->enable_configuration=c_can_enable_configuration; chipspecops->disable_configuration=c_can_disable_configuration; + chipspecops->attach_to_chip=c_can_attach_to_chip; + chipspecops->release_chip=c_can_release_chip; chipspecops->set_btregs=c_can_set_btregs; chipspecops->start_chip=c_can_start_chip; chipspecops->stop_chip=c_can_stop_chip; chipspecops->irq_handler=c_can_irq_handler; + chipspecops->irq_accept = NULL; return 0; } -/*int c_can_register(struct chip_t *pchip) +int c_can_fill_chipspecops(struct canchip_t *chip) { - DEBUGMSG("(c%d)call c_can_register\n", pchip->chip_nr); - - // Validate pointer - if ( NULL == pchip ) return -1; - - pchip->chip_config = c_can_chip_config; - pchip->set_baud_rate = c_can_baud_rate; - pchip->set_mask = c_can_mask; - pchip->set_use_mask = c_can_use_mask; - //pchip->set_message15_mask = c_can_extended_mask; - pchip->clear_objects = c_can_clear_objects; - pchip->config_irqs = c_can_config_irqs; - pchip->pre_read_config = c_can_pre_read_config; - //pchip->pre_write_config = c_can_pre_write_config; - pchip->send_msg = c_can_send_msg; - pchip->check_tx_stat = c_can_check_tx_stat; - pchip->remote_request = c_can_remote_request; - pchip->enable_configuration = c_can_enable_configuration; - pchip->disable_configuration = c_can_disable_configuration; - pchip->set_btregs = c_can_set_btregs; - pchip->start_chip = c_can_start_chip; - pchip->stop_chip = c_can_stop_chip; - pchip->register_dump = c_can_registerdump; - - DEBUGMSG("-> ok\n"); - return 0; + chip->chip_type="c_can"; + if(MAX_MSGOBJS >= 32) { + chip->max_objects = 32; + } else { + CANMSG("C_CAN requires 32 message objects per chip," + " but only %d is compiled maximum\n",MAX_MSGOBJS); + chip->max_objects = MAX_MSGOBJS; + } + c_can_register(chip->chipspecops); + return 0; } -*/