Transmitting the bit timing constants to a driver has been done.
authorJiri Vanek <vanekjir@fel.cvut.cz>
Sat, 14 Apr 2012 08:57:43 +0000 (10:57 +0200)
committerJiri Vanek <vanekjir@fel.cvut.cz>
Sat, 14 Apr 2012 08:57:43 +0000 (10:57 +0200)
embedded/app/usbcan/can/lpc17xx_can.h
embedded/app/usbcan/can/main.h
embedded/app/usbcan/lpc17xx_can.c
embedded/app/usbcan/usb/usb_vend.h
embedded/app/usbcan/usb_vend.c

index 202ed2a..4e50be1 100644 (file)
@@ -14,11 +14,12 @@ extern "C"
 {
 #endif
 
-
+// CAN1, CAN2 and CAN Acceptance filter base addresses
 #define CAN1_REGS_BASE 0x40044000UL
 #define CAN2_REGS_BASE 0x40048000UL
 #define CANAF_REGS_BASE        0x4003C000UL
 
+// offset of CAN registers
 #define CAN_MOD_o              0x0000
 #define CAN_CMR_o              0x0004
 #define CAN_GSR_o              0x0008
@@ -44,7 +45,7 @@ extern "C"
 #define CAN_TDA3_o             0x0058
 #define CAN_TDB3_o             0x005C
 
-
+// offset of CAN Acceptance filter registers
 #define CANAF_AFMR_o           0x0000
 #define CANAF_SFF_sa_o         0x0004
 #define CANAF_SFF_GRP_sa_o     0x0008
@@ -146,21 +147,39 @@ extern "C"
 
 // CAN1_RX_BIT a CAN1_TX_BIT jiz definovany v system_def.h
 
+//----------------------------------
+
+#define MAX_TRANSMIT_WAIT_LOOPS 20
 
 void CAN_init(struct canchip_t *chip);
 void CAN_send(struct canchip_t *chip, canmsg_t* msg);
 void CAN_recv(struct canchip_t *chip, canmsg_t* msg);
-void CAN_IRQHandler(void);
-void CAN_set_bittiming(struct canchip_t *chip, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2);
 
-//----------------------------------
+
+/*
+ * 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;
+};
 
 struct can_lmc1_chip_data
 {
        int flags;
+       struct can_bittiming_const btc;
 };
 
-#define CAN_LMC1_CHIP_CANBTR_SET       (1<<1)
 
 // board can-lmc1 specific functions:
 int can_lmc1_register(struct hwspecops_t *hwspecops);
index 995e675..b9fae26 100644 (file)
@@ -359,6 +359,8 @@ struct hwspecops_t {
  * @stop_chip: stops chip message processing
  * @irq_handler: interrupt service routine
  * @irq_accept: optional fast irq accept routine responsible for blocking further interrupts
+ *
+ * @set_bittiming: set bittiming parameters
  */
 struct chipspecops_t {
        int (*chip_config)(struct canchip_t *chip);
@@ -391,6 +393,8 @@ struct chipspecops_t {
        int (*stop_chip)(struct canchip_t *chip);
        int (*irq_handler)(int irq, struct canchip_t *chip);
        int (*irq_accept)(int irq, struct canchip_t *chip);
+
+       int (*set_bittiming)(struct canchip_t *chip, int brp, int sjw, int tseg1, int tseg2);
 };
 
 struct mem_addr {
index e8ca58e..9157dcf 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;
 
@@ -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;
index 8be5754..6542ecd 100644 (file)
 #define USBCAN_VENDOR_EXT_MASK_SET     (7)
 #define USBCAN_VENDOR_EXT_MASK_STATUS  (8)
 
-//lpc17xx debug
-#define USBCAN_VENDOR_SET_CANBTR       (9)
+#define USBCAN_VENDOR_SET_BITTIMING    (9)
+#define USBCAN_VENDOR_GET_BITTIMING_CONST      (10)
+
+#define USBCAN_BITTIMING_SIZE  16
+#define USBCAN_BITTIMING_CONST_SIZE            36
 
 int usbcan_vendor(usb_device_t *udev);
 
index 1f5d41f..fbe5be9 100644 (file)
@@ -14,9 +14,7 @@
   #include <byteswap.h>
 #endif
 
-// lpc17xx debug
 #include "./can/lpc17xx_can.h"
-// lpc17xx debug - end
 
 extern struct canuser_t *canuser;
 extern uint8_t vendor_ret;
@@ -101,29 +99,30 @@ nodata:
        return -1;
 }
 
-int set_canbtr_complete_fnc(struct usb_ep_t *ep, int status){
-  int dest_chip;
 
-       uint32_t brp, sjw, tseg1, tseg2;
 
-       struct can_lmc1_chip_data *chip_data=NULL;
+int set_bittiming_complete_fnc(struct usb_ep_t *ep, int status){
+  int dest_chip;
+
+       int32_t brp, sjw, tseg1, tseg2;
 
        usb_device_t *udev=ep->udev;
        unsigned char *data=ep->ptr - ep->actual;
 
-       if (udev->request.bRequest==USBCAN_VENDOR_SET_CANBTR){
+       if(ep->actual != USBCAN_BITTIMING_SIZE)
+               goto error;
+
+       if (udev->request.bRequest==USBCAN_VENDOR_SET_BITTIMING){
                dest_chip=(udev->request.wIndex);
                if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
                        goto error;
                if (!chips_p[dest_chip])
                        goto error;
-               if ((chip_data=((struct can_lmc1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL)
-                       goto nodata;
 
-               brp=*(uint32_t *)(data);
-               sjw=*(uint32_t *)(data+4);
-               tseg1=*(uint32_t *)(data+8);
-               tseg2=*(uint32_t *)(data+12);
+               brp=*(int32_t *)(data);
+               sjw=*(int32_t *)(data+4);
+               tseg1=*(int32_t *)(data+8);
+               tseg2=*(int32_t *)(data+12);
                #if __BYTE_ORDER == __BIG_ENDIAN
                brp  = bswap_32(brp);
                sjw  = bswap_32(sjw);
@@ -131,18 +130,70 @@ int set_canbtr_complete_fnc(struct usb_ep_t *ep, int status){
                tseg2  = bswap_32(tseg2);
                #endif
 
+
+               if (chips_p[dest_chip]->chipspecops->set_bittiming(chips_p[dest_chip], brp, sjw, tseg1, tseg2)<0)
+                       goto error;
+       }
+       return 0;
+
+error:
+       return -1;
+}
+
+int get_bittiming_const_complete_fnc(usb_device_t *udev){
+
+       int dest_chip;
+
+       struct can_lmc1_chip_data *chip_data=NULL;
+       struct can_bittiming_const *btc;
+
+       uint8_t buffer[USBCAN_BITTIMING_CONST_SIZE];
+       uint32_t *ptr;
+
+       if (udev->request.bRequest==USBCAN_VENDOR_GET_BITTIMING_CONST){
+
+               dest_chip=(udev->request.wIndex);
+               if ((dest_chip>=MAX_TOT_CHIPS)||(dest_chip<0))
+                       goto error;
+               if (!chips_p[dest_chip])
+                       goto error;
+               if ((chip_data=((struct can_lmc1_chip_data*)(chips_p[dest_chip]->chip_data)))==NULL){
+                       goto error;
+               }
+
+               btc = &chip_data->btc;
+               
+               ptr = (uint32_t*) buffer;
+
+               #if __BYTE_ORDER == __BIG_ENDIAN
+               *(ptr++) = bswap_32(chips_p[dest_chip]->clock);
+               *(ptr++) = bswap_32(btc->tseg1_min);
+               *(ptr++) = bswap_32(btc->tseg1_max);
+               *(ptr++) = bswap_32(btc->tseg2_min);
+               *(ptr++) = bswap_32(btc->tseg2_max);
+               *(ptr++) = bswap_32(btc->sjw_max);
+               *(ptr++) = bswap_32(btc->brp_min);
+               *(ptr++) = bswap_32(btc->brp_max);
+               *(ptr) = bswap_32(btc->brp_inc);
+               #else
+               *(ptr++) = chips_p[dest_chip]->clock;
+               *(ptr++) = btc->tseg1_min;
+               *(ptr++) = btc->tseg1_max;
+               *(ptr++) = btc->tseg2_min;
+               *(ptr++) = btc->tseg2_max;
+               *(ptr++) = btc->sjw_max;
+               *(ptr++) = btc->brp_min;
+               *(ptr++) = btc->brp_max;
+               *(ptr) = btc->brp_inc;
+               #endif
+
+               usb_send_control_data(udev, buffer, USBCAN_BITTIMING_CONST_SIZE);
                                
-               printf("BRP: %d, SJW: %d, TSEG1: %d, TSEG2: %d \n", brp, sjw, tseg1, tseg2);
-               CAN_set_bittiming(chips_p[dest_chip], brp--, sjw--, tseg1--, tseg2--);  
 
-//             if (chips_p[dest_chip]->chipspecops->baud_rate(chips_p[dest_chip], rate, chips_p[dest_chip]->clock, sjw, sampl_pt, flags)<0)
-//                     goto error;
-               chip_data->flags |= CAN_LMC1_CHIP_CANBTR_SET;
        }
        return 0;
+
 error:
-       chip_data->flags &= ~CAN_LMC1_CHIP_CANBTR_SET;
-nodata:
        return -1;
 }
 
@@ -160,11 +211,15 @@ int usbcan_vendor(usb_device_t *udev)
 
   switch ( udev->request.bRequest) {
                
-               //lpc17xx debug 
-               case USBCAN_VENDOR_SET_CANBTR:
-                       udev->ep0.complete_fnc=set_canbtr_complete_fnc;
+               //lpc17xx
+               case USBCAN_VENDOR_SET_BITTIMING:
+                       udev->ep0.complete_fnc=set_bittiming_complete_fnc;
+                       return 1;
+
+               case USBCAN_VENDOR_GET_BITTIMING_CONST:
+                       get_bittiming_const_complete_fnc(udev);
                        return 1;
-               //lpc17xx debug - end
+               //lpc17xx - end
 
                case USBCAN_VENDOR_EXT_MASK_SET:
                        udev->ep0.complete_fnc=set_ext_mask_complete_fnc;