Skip to content

gs_usb compatible firmware for candleLight, cantact and canable

License

Notifications You must be signed in to change notification settings

tuna-f1sh/candleLight_fw

 
 

Repository files navigation

candleLight_gsusb

Build

This is firmware for certain STM32F042x/STM32F072xB-based USB-CAN adapters, notably:

Of important note is that the common STM32F103 will NOT work with this firmware because its hardware cannot use both USB and CAN simultaneously. Beware also the smaller packages in the F042 series which map a USB and CAN_TX signal on the same pin and are therefore unusable !

This implements the interface of the mainline linux gs_usb kernel module and works out-of-the-box with linux distros packaging this module, e.g. Ubuntu.

Entreé Fork

My fork attempts to keep up with the upstream, whilst including the STUSB4500 USB-PD functionality. If one requires the latest upstream support and does not require USB-PD, entree is compatible with the cantact_fw target.

The target for this fork is entree_fw.

USB Power Delivery (USB-PD)

The on-board USB-C controller (STUSB4500) is configured for 5 V / 1A power delivery by default (PDO 2). One can configure the controller using the below CAN bus commands when using the candleLight_fw fork and with the internal CAN IDs switch set.

These commands are scraped from the recieved gs_usb Tx commands and will not be forwarded to the CAN bus when the switch is set. Ensure the DLC is 8 bytes, the ID is correct and byte seven is the Entreé key '0xAF'.

CAN Bus Side Control

The commands are also scraped from the can_recieved callback. For this to work, initiate a connection over USB to setup the desired CAN bit timing then send the 'Save CAN' command (0x06) with the NVM byte set. The CAN bus will now be enabled on power up before USB enumeration. To revert this behaviour, send the same command with the NVM byte unset.

ID Cmd 0 1 2 3 4 5 6 7 Action
0x010 VBUS EN 0x01 NVM (bool) SET (bool) 0x00 0x00 0x00 0x00 0xAF Set VBUS always enable (NVM) or try to enable VBUS by setting profile 1
0x010 Set PDO 0x02 NVM (bool) PROFILE VOLTAGE_L VOLTAGE_H CURRENT_L CURRENT_H 0xAF Set power delivery profile number (1-3) voltage (mV) and current (mA)
0x010 Set Profiles 0x03 NVM (bool) PROFILES 0x00 0x00 0x00 0x00 0xAF Set number of profile in use (1-3)
0x010 Set VBUS 0x04 VOLTAGE_L VOLTAGE_H 0x00 0x00 0x00 0x00 0xAF Request voltage on VBUS (volatile)
0x010 Get RDO 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0xAF Get enumerated profile number
0x010 Save CAN 0x06 NVM (bool) 0x00 0x00 0x00 0x00 0x00 0xAF Save current CAN bit timing to NVM and auto-enable at start-up for CAN bus side control.

Usage Notes

  • NVM flag will write to the NVM rather than volatile register. If a write is required, the STUSB4500 will be soft reset in order to re-enumerate the USB-PD profiles. The LEDs will flash rapidly 20 times when a NVM flash occurs. The volatile settings will also trigger a soft reset in order to re-enumerate. A soft reset will mean the CAN network will need re-creating on the host.
  • The NVM VBUS enable is the only concrete way to force VBUS; the volatile method attempts to enumerate a 5 V power delivery profile but this may not work with non-compliant devices.
  • When profile 2 is enumerated, the orange 'PD-OK' will illuminate. This can be changed to profile 3 with the solder link on the underside of the board.
  • Refer to the STUSB4500 programming guide for more information.
  • Excerise caution configuring these and use a USB-PD checker/multimeter to verify your configuration prior to powering a device!

Examples

Using SocketCAN cansend command.

# enable vbus always (regardless of USB-PD profile enumeration)
cansend can0 010#01010100000000AF
# set PD2 in NVM to 12000 mV / 1000 mA
cansend can0 010#020102E02EE803AF
# save CAN bit timing for auto enable without USB
cansend can0 010#06010000000000AF
# disable auto CAN bus enable
cansend can0 010#06000000000000AF
# read current negotiated profile (returns on same ID B0: CMD, B1: PROFILE)
cansend can0 010#05000000000000AF

Known issues

Be aware that there is a bug in the gs_usb module in linux<4.5 that can crash the kernel on device removal.

Here is a fixed version that should also work for older kernels: https://github.com/HubertD/socketcan_gs_usb

The Firmware also implements WCID USB descriptors and thus can be used on recent Windows versions without installing a driver.

Building

Building requires arm-none-eabi-gcc toolchain.

sudo apt-get install gcc-arm-none-eabi

mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/gcc-arm-none-eabi-8-2019-q3-update.cmake

# or,
# cmake-gui ..
# don't forget to specify the cmake toolchain file before configuring.
#
# compile all targets :

make

# OR, each board target is a cmake option and can be disabled before running 'make';
# OR, compile a single target , e.g.
make cantact_fw

#
# to list possible targets :
make help

Download Binaries

Prebuilt binaries can be downloaded by clicking CI. On the workflow overview page, select the latest workflow that ran on master branch. The firmware artifacts can downloaded by clicking them at the bottom of the page.

Flashing

Flashing candleLight on linux: (source: https://cantact.io/cantact/users-guide.html)

  • Flashing requires the dfu-util tool. On Ubuntu, this can be installed with sudo apt install dfu-util.
  • compile as above, or download the current binary release: gsusb_cantact_8b2b2b4.bin
  • If dfu-util fails due to permission issues on Linux, you may need additional udev rules. Consult your distro's documentation and see 70-candle-usb.rules provided here.

recommended simple method

  • If compiling with cmake, make flash-<targetname_fw>, e.g. make flash-canable_fw, to invoke dfu-util.

method for reflashing a specific device by serial

  • when multiple devices are connected, dfu-util may be unable to choose which one to flash.
  • Obtain device's serial # by looking at dfu-util -l
  • adapt the following command accordingly : dfu-util -D CORRECT_FIRMWARE.bin -S "serial_number_here", -a 0 -s 0x08000000:leave
  • note, the :leave suffix above may not be supported by older builds of dfu-util and is simply a convenient way to reboot into the normal firmware.

fail-safe method (or if flashing a blank device)

  • Disconnect the USB connector from the CANtact, short the BOOT pins, then reconnect the USB connector. The device should enumerate as "STM32 BOOTLOADER".

  • invoke dfu-util manually with: sudo dfu-util --dfuse-address -d 0483:df11 -c 1 -i 0 -a 0 -s 0x08000000 -D CORRECT_FIRMWARE.bin where CORRECT_FIRMWARE is the name of the desired .bin.

  • Disconnect the USB connector, un-short the BOOT pins, and reconnect.

Associating persistent device names

With udev on linux, it is possible to assign a device name to a certain serial number (see udev manpages and systemd.link). This can be useful when multiple devices are connected at the same time.

An example configuration :

 $ cat /etc/systemd/network/60-persistent-candev.link
[Match]
Property=ID_MODEL=cannette_gs_usb ID_SERIAL_SHORT="003800254250431420363230"

[Link]
# from systemd.link manpage:
# Note that specifying a name that the kernel might use for another interface (for example "eth0") is dangerous because the name assignment done by udev will race with the assignment done by the kernel, and only one
#   interface may use the name. Depending on the order of operations, either udev or the kernel will win, making the naming unpredictable. It is best to use some different prefix

Name=cannette99

( The serial number can be found with the lsusb utility). After reloading systemd units and resetting this board :

 $ ip a
....
59: cannette99: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
    link/can
 $

Hacking

Submitting pull requests

  • Each commit must not contain unrelated changes (e.g. functional and whitespace changes)
  • Project must be compilable (with default options) and functional, at each commit.
  • Squash any "WIP" or other temporary commits.
  • Make sure your editor is not messing up whitespace or line-ends.
  • We include both a .editorconfig and uncrustify.cfg which should help with whitespace.

Typical command to run uncrustify on all source files (ignoring HAL and third-party libs): uncrustify -c ./uncrustify.cfg --replace $(find include src -name "*.[ch]")

Optionally append --no-backup to avoid creating .orig files.

Profiling

Not great on cortex-M0 cores (F042, F072 targets etc) since they lack hardware support (ITM and SWO). However, it's possible to randomly sample the program counter and get some coarse profiling info.

For example, openocd has the profile command (see https://openocd.org/doc/html/General-Commands.html#Misc-Commands), e.g.

profile 5 test.out 0x8000000 0x8100000

(from inside gdb, the command needs to be prefixed with monitor to forward it to openocd, i.e. monitor profile 5 ......

The .out file can then be processed with gprof <firmware_name> -l test.out

Links to related projects

  • Cangaroo open source can bus analyzer software
  • Candle.NET .NET wrapper for the candle API

About

gs_usb compatible firmware for candleLight, cantact and canable

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C 99.8%
  • Other 0.2%