diff --git a/.travis.yml b/.travis.yml index 4ea1aab..e4ac192 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,4 +20,4 @@ before_script: script: make BUILD_NUMBER=$TRAVIS_BUILD_NUMBER after_success: - "artifacts upload --target-paths=builds/b$TRAVIS_BUILD_NUMBER build/CANtact*" \ No newline at end of file + "artifacts upload --target-paths=builds/b$TRAVIS_BUILD_NUMBER build/CANtact*" \ No newline at end of file diff --git a/Inc/can.h b/Inc/can.h index 3b767cc..639c2fe 100644 --- a/Inc/can.h +++ b/Inc/can.h @@ -2,9 +2,15 @@ #define _CAN_H enum can_bitrate { - CAN_BITRATE_500K, - CAN_BITRATE_250K, + CAN_BITRATE_10K, + CAN_BITRATE_20K, + CAN_BITRATE_50K, + CAN_BITRATE_100K, CAN_BITRATE_125K, + CAN_BITRATE_250K, + CAN_BITRATE_500K, + CAN_BITRATE_750K, + CAN_BITRATE_1000K, }; enum can_bus_state { diff --git a/Makefile b/Makefile index 2e80422..5a67eb8 100644 --- a/Makefile +++ b/Makefile @@ -86,7 +86,11 @@ CFLAGS += -mcpu=$(CPU) -mthumb CFLAGS += $(USER_CFLAGS) # default action: build the user application -all: $(BUILD_DIR)/$(TARGET).hex +all: $(BUILD_DIR)/$(TARGET).bin $(BUILD_DIR)/$(TARGET).hex + +flash: all + sudo dfu-util -d 0483:df11 -c 1 -i 0 -a 0 -s 0x08000000 -D $(BUILD_DIR)/$(TARGET).bin + ####################################### # build the st micro peripherial library @@ -149,6 +153,9 @@ $(BUILD_DIR)/$(TARGET).hex: $(BUILD_DIR)/$(TARGET).elf $(OBJCOPY) -O ihex $(BUILD_DIR)/$(TARGET).elf $@ $(OBJCOPY) -O binary $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).bin +$(BUILD_DIR)/$(TARGET).bin: $(BUILD_DIR)/$(TARGET).elf + $(OBJCOPY) -O binary $(BUILD_DIR)/$(TARGET).elf $@ + $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) $(USB_OBJECTS) $(CUBELIB) $(CC) -o $@ $(CFLAGS) $(OBJECTS) $(USB_OBJECTS) \ $(LDFLAGS) -Xlinker \ diff --git a/README.md b/README.md index 2080234..14a0022 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ With OpenOCD running, arm-none-eabi-gdb can be used to load code and debug. ## Contributors - [Ethan Zonca](https://github.com/normaldotcom) - Makefile fixes and code size optimization +- [onejope](https://github.com/onejope) - Fixes to extended ID handling +- Phil Wise - Added dfu-util compatibility to Makefile ## License diff --git a/Src/can.c b/Src/can.c index d26879e..1ba3636 100644 --- a/Src/can.c +++ b/Src/can.c @@ -3,6 +3,7 @@ CAN_HandleTypeDef hcan; CAN_FilterConfTypeDef filter; +uint32_t prescaler; enum can_bus_state bus_state; void can_init(void) { @@ -19,60 +20,89 @@ void can_init(void) { filter.BankNumber = 0; filter.FilterActivation = ENABLE; + // default to 125 kbit/s + prescaler = 48; hcan.Instance = CAN; - hcan.Init.Prescaler = 48; - hcan.Init.Mode = CAN_MODE_NORMAL; - hcan.Init.SJW = CAN_SJW_1TQ; - hcan.Init.BS1 = CAN_BS1_4TQ; - hcan.Init.BS2 = CAN_BS2_3TQ; - hcan.Init.TTCM = DISABLE; - hcan.Init.ABOM = DISABLE; - hcan.Init.AWUM = DISABLE; - hcan.Init.NART = DISABLE; - hcan.Init.RFLM = DISABLE; - hcan.Init.TXFP = DISABLE; - bus_state = OFF_BUS; - //status = HAL_CAN_Init(&hcan); } void can_enable(void) { uint32_t status; if (bus_state == OFF_BUS) { + hcan.Init.Prescaler = prescaler; hcan.Init.Mode = CAN_MODE_NORMAL; - hcan.pTxMsg = NULL; - status = HAL_CAN_Init(&hcan); - status = HAL_CAN_ConfigFilter(&hcan, &filter); - bus_state = ON_BUS; + hcan.Init.SJW = CAN_SJW_1TQ; + hcan.Init.BS1 = CAN_BS1_4TQ; + hcan.Init.BS2 = CAN_BS2_3TQ; + hcan.Init.TTCM = DISABLE; + hcan.Init.ABOM = DISABLE; + hcan.Init.AWUM = DISABLE; + hcan.Init.NART = DISABLE; + hcan.Init.RFLM = DISABLE; + hcan.Init.TXFP = DISABLE; + hcan.pTxMsg = NULL; + status = HAL_CAN_Init(&hcan); + status = HAL_CAN_ConfigFilter(&hcan, &filter); + bus_state = ON_BUS; } } void can_disable(void) { uint32_t status; if (bus_state == ON_BUS) { - // do a bxCAN reset (set RESET bit to 1) - hcan.Instance->MCR |= CAN_MCR_RESET; - bus_state = OFF_BUS; + // do a bxCAN reset (set RESET bit to 1) + hcan.Instance->MCR |= CAN_MCR_RESET; + bus_state = OFF_BUS; } HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); } void can_set_bitrate(enum can_bitrate bitrate) { if (bus_state == ON_BUS) { - // cannot set bitrate while on bus - return; + // cannot set bitrate while on bus + return; } switch (bitrate) { - case CAN_BITRATE_500K: - hcan.Init.Prescaler = 12; - break; - case CAN_BITRATE_250K: - hcan.Init.Prescaler = 24; - break; - case CAN_BITRATE_125K: - hcan.Init.Prescaler = 48; - break; + case CAN_BITRATE_10K: + prescaler = 600; + break; + case CAN_BITRATE_20K: + prescaler = 300; + break; + case CAN_BITRATE_50K: + prescaler = 120; + break; + case CAN_BITRATE_100K: + prescaler = 60; + break; + case CAN_BITRATE_125K: + prescaler = 48; + break; + case CAN_BITRATE_250K: + prescaler = 24; + break; + case CAN_BITRATE_500K: + prescaler = 12; + break; + case CAN_BITRATE_750K: + prescaler = 8; + break; + case CAN_BITRATE_1000K: + prescaler = 6; + break; + } +} + +void can_set_silent(uint8_t silent) { + if (bus_state == ON_BUS) { + // cannot set silent mode while on bus + return; + } + if (silent) { + hcan.Init.Mode = CAN_MODE_SILENT; + } else { + hcan.Init.Mode = CAN_MODE_NORMAL; } } @@ -100,7 +130,7 @@ uint32_t can_rx(CanRxMsgTypeDef *rx_msg, uint32_t timeout) { uint8_t is_can_msg_pending(uint8_t fifo) { if (bus_state == OFF_BUS) { - return 0; + return 0; } return (__HAL_CAN_MSG_PENDING(&hcan, fifo) > 0); } diff --git a/Src/slcan.c b/Src/slcan.c index 4be0259..25a5b05 100644 --- a/Src/slcan.c +++ b/Src/slcan.c @@ -80,33 +80,67 @@ int8_t slcan_parse_str(char *buf, uint8_t len) { // open channel command can_enable(); return 0; + } else if (buf[0] == 'C') { // close channel command can_disable(); return 0; + } else if (buf[0] == 'S') { // set bitrate command switch(buf[1]) { - case 0: - can_set_bitrate(CAN_BITRATE_125K); - break; - case 1: - can_set_bitrate(CAN_BITRATE_250K); - break; - case 2: - can_set_bitrate(CAN_BITRATE_500K); - break; - default: - // invalid setting - return -1; + case 0: + can_set_bitrate(CAN_BITRATE_10K); + break; + case 1: + can_set_bitrate(CAN_BITRATE_20K); + break; + case 2: + can_set_bitrate(CAN_BITRATE_50K); + break; + case 3: + can_set_bitrate(CAN_BITRATE_100K); + break; + case 4: + can_set_bitrate(CAN_BITRATE_125K); + break; + case 5: + can_set_bitrate(CAN_BITRATE_250K); + break; + case 6: + can_set_bitrate(CAN_BITRATE_500K); + break; + case 7: + can_set_bitrate(CAN_BITRATE_750K); + break; + case 8: + can_set_bitrate(CAN_BITRATE_1000K); + break; + default: + // invalid setting + return -1; } return 0; + + } else if (buf[0] == 'm' || buf[0] == 'M') { + // set mode command + if (buf[1] == 1) { + // mode 1: silent + can_set_silent(1); + } else { + // default to normal mode + can_set_silent(0); + } + return 0; + } else if (buf[0] == 't' || buf[0] == 'T') { // transmit data frame command frame.RTR = CAN_RTR_DATA; + } else if (buf[0] == 'r' || buf[0] == 'R') { - frame.RTR = CAN_RTR_REMOTE; // transmit remote frame command + frame.RTR = CAN_RTR_REMOTE; + } else { // error, unknown command return -1; @@ -121,14 +155,25 @@ int8_t slcan_parse_str(char *buf, uint8_t len) { return -1; } - uint8_t id_len = frame.IDE == CAN_ID_EXT ? SLCAN_EXT_ID_LEN : SLCAN_STD_ID_LEN; frame.StdId = 0; - i = 1; - while (i <= id_len) { - frame.StdId += buf[i++]; - frame.StdId *= 16; + frame.ExtId = 0; + if (frame.IDE == CAN_ID_EXT) { + uint8_t id_len = SLCAN_EXT_ID_LEN; + i = 1; + while (i <= id_len) { + frame.ExtId *= 16; + frame.ExtId += buf[i++]; + } } - frame.StdId /= 16; + else { + uint8_t id_len = SLCAN_STD_ID_LEN; + i = 1; + while (i <= id_len) { + frame.StdId *= 16; + frame.StdId += buf[i++]; + } + } + frame.DLC = buf[i++]; if (frame.DLC < 0 || frame.DLC > 8) { diff --git a/Src/stm32f0xx_hal_msp.c b/Src/stm32f0xx_hal_msp.c index db1355d..0ab31d2 100644 --- a/Src/stm32f0xx_hal_msp.c +++ b/Src/stm32f0xx_hal_msp.c @@ -81,12 +81,6 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan) HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* USER CODE BEGIN CAN_MspInit 1 */ - GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM; - GPIO_InitStruct.Alternate = 0; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* USER CODE END CAN_MspInit 1 */ } diff --git a/windows-driver/cantact.inf b/windows-driver/cantact.inf new file mode 100644 index 0000000..8013005 --- /dev/null +++ b/windows-driver/cantact.inf @@ -0,0 +1,64 @@ +; Windows CANtact CDC ACM Setup File +; Copyright (c) 2000 Microsoft Corporation + +[DefaultInstall] +CopyINF="cantact.inf" + +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%MFGNAME% +DriverVer=7/1/2012,10.0.0.0 + +[Manufacturer] +%MFGNAME%=DeviceList, NTx86, NTamd64, NTia64 + +[SourceDisksNames] + +[SourceDisksFiles] + +[DestinationDirs] +DefaultDestDir=12 + +[DriverInstall] +Include=mdmcpq.inf +CopyFiles=FakeModemCopyFileSection +AddReg=DriverInstall.AddReg + +[DriverInstall.Services] +Include=mdmcpq.inf +AddService=usbser, 0x00000002, LowerFilter_Service_Inst + +[DriverInstall.AddReg] +HKR,,EnumPropPages32,,"msports.dll,SerialPortPropPageProvider" + +;------------------------------------------------------------------------------ +; Vendor and Product ID Definitions +;------------------------------------------------------------------------------ +; When developing your USB device, the VID and PID used in the PC side +; application program and the firmware on the microcontroller must match. +; Modify the below line to use your VID and PID. Use the format as shown below. +; Note: One INF file can be used for multiple devices with different VID and PIDs. +; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. +;------------------------------------------------------------------------------ +[DeviceList] +%DESCRIPTION%=DriverInstall, USB\VID_AD50&PID_60C4 + +[DeviceList.NTx86] +%DESCRIPTION%=DriverInstall, USB\VID_AD50&PID_60C4 + +[DeviceList.NTamd64] +%DESCRIPTION%=DriverInstall, USB\VID_AD50&PID_60C4 + +[DeviceList.NTia64] +%DESCRIPTION%=DriverInstall, USB\VID_AD50&PID_60C4 + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ +;Modify these strings to customize your device +;------------------------------------------------------------------------------ +[Strings] +MFGNAME="http://www.cantact.io" +DESCRIPTION="CANtact USB/CAN Device" \ No newline at end of file