X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/a73d6ffea8948a9abc9bfb32728bb255cec18317..7d282b5f3c17776f056dbe3f1530403c829de17b:/embedded/app/usbcan/lpc17xx_can.c diff --git a/embedded/app/usbcan/lpc17xx_can.c b/embedded/app/usbcan/lpc17xx_can.c index e8ca58e..9157dcf 100644 --- a/embedded/app/usbcan/lpc17xx_can.c +++ b/embedded/app/usbcan/lpc17xx_can.c @@ -1,42 +1,6 @@ #include "can/lpc17xx_can.h" static void CAN_configPin(); -static void CAN_setBusTiming(struct canchip_t *chip); - -#define MAX_TRANSMIT_WAIT_LOOPS 20 - -/* - * CAN harware-dependent bit-timing constant - * - * Used for calculating and checking bit-timing parameters - */ - -struct can_bittiming_const { - char name[16]; /* Name of the CAN controller hardware */ - uint32_t tseg1_min; /* Time segement 1 = prop_seg + phase_seg1 */ - uint32_t tseg1_max; - uint32_t tseg2_min; /* Time segement 2 = phase_seg2 */ - uint32_t tseg2_max; - uint32_t sjw_max; /* Synchronisation jump width */ - uint32_t brp_min; /* Bit-rate prescaler */ - uint32_t brp_max; - uint32_t brp_inc; -}; - -static struct can_bittiming_const lpc17xx_can_bittiming_const = { - .name = "lpc17xx_can", - .tseg1_min = 1, - .tseg1_max = 16, - .tseg2_min = 1, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 1, - .brp_max = 1024, - .brp_inc = 1, -}; - -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- // board can-lmc1 specific functions: @@ -68,8 +32,12 @@ int can_lmc1_init_hw_data(struct candevice_t *candev){ int can_lmc1_init_chip_data(struct candevice_t *candev, int chipnr){ + struct can_bittiming_const *btc; + struct can_lmc1_chip_data *chip_data; + // used CAN1 peripherial -> CAN1 registers base candev->chip[chipnr]->chip_base_addr = CAN1_REGS_BASE; + // clock for CAN candev->chip[chipnr]->clock = system_frequency / 4; lpc17xx_fill_chipspecops(candev->chip[chipnr]); @@ -78,6 +46,21 @@ int can_lmc1_init_chip_data(struct candevice_t *candev, int chipnr){ if (candev->chip[chipnr]->chip_data==NULL) return -ENOMEM; + + chip_data = (struct can_lmc1_chip_data*) candev->chip[chipnr]->chip_data; + + btc = &chip_data->btc; + + // set bittiming constants + btc->tseg1_min = 1; + btc->tseg1_max = 16; + btc->tseg2_min = 1; + btc->tseg2_max = 8; + btc->sjw_max = 4; + btc->brp_min = 1; + btc->brp_max = 1024; + btc->brp_inc = 1; + return 0; } @@ -130,10 +113,9 @@ int lpc17xx_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw, int best_tseg=0, best_brp=0, best_rate=0, brp=0; int tseg=0, tseg1=0, tseg2=0; - struct can_bittiming_const *btc = &lpc17xx_can_bittiming_const; + struct can_lmc1_chip_data *chip_data = (struct can_lmc1_chip_data*) chip->chip_data; - // right ? - //clock /=2; + struct can_bittiming_const *btc = &chip_data->btc; /* tseg even = round down, odd = round up */ for (tseg=(0+0+2)*2; tseg<=(btc->tseg2_max+btc->tseg1_max+2)*2+1; tseg++) { @@ -174,8 +156,8 @@ int lpc17xx_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw, (100*(best_tseg-tseg2)/(best_tseg+1))); - CAN_set_bittiming(chip, best_brp, sjw, tseg1, tseg2); - + if(chip->chipspecops->set_bittiming(chip, ++best_brp, ++sjw, ++tseg1, ++tseg2) < 0) + return -EINVAL; return 0; } @@ -189,8 +171,6 @@ int lpc17xx_chip_config(struct canchip_t *chip){ if (!chip->baudrate) chip->baudrate=1000000; - printf("CAN CHIP INIT, baudrate: %d\n", (int) chip->baudrate); - if (lpc17xx_baud_rate(chip,chip->baudrate,chip->clock,0,75,0)) return -ENODEV; @@ -357,6 +337,42 @@ void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj) { } +int lpc17xx_set_bittiming(struct canchip_t *chip, int brp, int sjw, int tseg1, int tseg2){ + + uint8_t SAM = 0; // 0 = the bus is sampled once + + if((--brp)<0) + return -EINVAL; + + if((--sjw)<0) + return -EINVAL; + + if((--tseg1)<0) + return -EINVAL; + + if((--tseg2)<0) + return -EINVAL; + + + //debug print + printf("BRP: %d, SJW: %d, TSEG1: %d, TSEG2: %d \n", brp+1, sjw+1, tseg1+1, tseg2+1); + + can_disable_irq(chip->chip_irq); + + // enter reset mode + can_write_reg(chip, 1, CAN_MOD_o); + + // set bittiming register + can_write_reg(chip, ((SAM<<23)|(tseg2<<20)|(tseg1<<16)|(sjw<<14)|(brp<<0)), CAN_BTR_o); + + // return to normal operating + can_write_reg(chip, 0, CAN_MOD_o); + + can_enable_irq(chip->chip_irq); + + return 0; +} + int lpc17xx_fill_chipspecops(struct canchip_t *chip){ chip->max_objects=1; @@ -379,6 +395,8 @@ int lpc17xx_register(struct chipspecops_t *chipspecops){ chipspecops->wakeup_tx = lpc17xx_wakeup_tx; chipspecops->irq_handler = lpc17xx_irq_handler; + chipspecops->set_bittiming = lpc17xx_set_bittiming; + return 0; } @@ -533,28 +551,6 @@ void CAN_send(struct canchip_t *chip, canmsg_t* msg){ } -void CAN_set_bittiming(struct canchip_t *chip, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2){ - - uint8_t SAM = 0; // 0 = the bus is sampled once - - //debug print - printf("BRP: %d, SJW: %d, TSEG1: %d, TSEG2: %d \n", brp+1, sjw+1, tseg1+1, tseg2+1); - - can_disable_irq(chip->chip_irq); - // enter reset mode - can_write_reg(chip, 1, CAN_MOD_o); - - - can_write_reg(chip, ((SAM<<23)|(tseg2<<20)|(tseg1<<16)|(sjw<<14)|(brp<<0)), CAN_BTR_o); - - - // return to normal operating - can_write_reg(chip, 0, CAN_MOD_o); - - can_enable_irq(chip->chip_irq); -} - - void CAN_init(struct canchip_t *chip){ uint32_t tmp;