#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:
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]);
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;
}
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++) {
(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;
}
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;
}
+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;
chipspecops->wakeup_tx = lpc17xx_wakeup_tx;
chipspecops->irq_handler = lpc17xx_irq_handler;
+ chipspecops->set_bittiming = lpc17xx_set_bittiming;
+
return 0;
}
}
-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;