]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - embedded/app/usbcan/lpc17xx_can.c
Some bugs related with transmission/reception fixed.
[lincan.git] / embedded / app / usbcan / lpc17xx_can.c
index e8ca58ecd4c103f9435216cfe713f919445ea29a..0d42658c16414049463e6df5265d64934ea25103 100644 (file)
@@ -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;
 
@@ -200,7 +180,18 @@ int lpc17xx_chip_config(struct canchip_t *chip){
 int lpc17xx_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
                                                        struct canmsg_t *msg)
 {
+       uint32_t i=0;   
        
+       // check status of TB1
+       while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1)){
+               if(i++<MAX_TRANSMIT_WAIT_LOOPS)
+                       continue;
+
+               // request command to abort transmission request
+               can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
+               return 0;
+       }       
+
        CAN_send(chip, msg);
 
        return 0;
@@ -219,6 +210,8 @@ int lpc17xx_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
                if(i++<MAX_TRANSMIT_WAIT_LOOPS)
                        continue;
 
+               CANMSG("Abort transmission request\n");
+
                // request command to abort transmission request
                can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
                break;
@@ -259,7 +252,6 @@ int lpc17xx_irq_handler(int irq, struct canchip_t *chip)
        uint32_t i;
        struct msgobj_t *obj;   
        obj = chip->msgobj[0];
-
        
        i = can_read_reg(chip, CAN_ICR_o);
 
@@ -357,6 +349,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
+       CANMSG("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 +407,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;       
 
 }
@@ -483,16 +513,6 @@ void CAN_send(struct canchip_t *chip, canmsg_t* msg){
        volatile uint32_t can_tfi1;
        uint32_t i=0;
 
-       // check status of TB1
-       while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1)){
-               if(i++<MAX_TRANSMIT_WAIT_LOOPS)
-                       continue;
-
-               // request command to abort transmission request
-               can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
-               return;
-       }       
-
        can_tfi1 = can_read_reg(chip, CAN_TFI1_o);
 
        can_tfi1 &= ~0x000F0000;
@@ -533,28 +553,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;