From: Jiri Vanek Date: Sat, 14 Apr 2012 08:57:43 +0000 (+0200) Subject: Transmitting the bit timing constants to a driver has been done. X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/commitdiff_plain/7d282b5f3c17776f056dbe3f1530403c829de17b Transmitting the bit timing constants to a driver has been done. --- diff --git a/embedded/app/usbcan/can/lpc17xx_can.h b/embedded/app/usbcan/can/lpc17xx_can.h index 202ed2a..4e50be1 100644 --- a/embedded/app/usbcan/can/lpc17xx_can.h +++ b/embedded/app/usbcan/can/lpc17xx_can.h @@ -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); diff --git a/embedded/app/usbcan/can/main.h b/embedded/app/usbcan/can/main.h index 995e675..b9fae26 100644 --- a/embedded/app/usbcan/can/main.h +++ b/embedded/app/usbcan/can/main.h @@ -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 { 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; diff --git a/embedded/app/usbcan/usb/usb_vend.h b/embedded/app/usbcan/usb/usb_vend.h index 8be5754..6542ecd 100644 --- a/embedded/app/usbcan/usb/usb_vend.h +++ b/embedded/app/usbcan/usb/usb_vend.h @@ -12,8 +12,11 @@ #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); diff --git a/embedded/app/usbcan/usb_vend.c b/embedded/app/usbcan/usb_vend.c index 1f5d41f..fbe5be9 100644 --- a/embedded/app/usbcan/usb_vend.c +++ b/embedded/app/usbcan/usb_vend.c @@ -14,9 +14,7 @@ #include #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;