OpenXC CAN Translator

_images/logo.png
Version:4.1
Web:http://openxcplatform.com
Documentation:http://vi-firmware.openxcplatform.com
Source:http://github.com/openxc/cantranslator

About

The CAN translation module code runs on an Arduino-compatible microcontroller connected to one or more CAN buses. It receives either all CAN messages or a filtered subset, performs any unit conversion or factoring required and outputs a generic version to a USB interface.

The firmware supports multiple microcontrollers.

Setup

Installation

If you’ve downloaded a pre-built binary for a specific vehicle, see the Flashing a Pre-compiled Binary section for instructions on how to flash your CAN translator. Most users do not need to set up the full development described in these docs.

Flashing a Pre-compiled Binary

Updates to the CAN translator firmware may be distributed as pre-compiled binaries, e.g. if they are distributed by an OEM who does not wish to make the CAN signals public. A binary firmware may be distributed either as a .hex or .bin file.

For the moment, all of the pre-compiled firmare are built to run with a bootloader on the microcontroller.

Quick Start
Windows
  1. Install Cygwin and in the installer, select the following packages:
git, curl, libsasl2, ca-certificates, patchutils
  1. Start a Cygwin Terminal.
  2. Configure the terminal to ignore Windows-style line endings in scripts:
$ echo "set -o igncr && export SHELLOPTS" >> ~/.bashrc && source ~/.bashrc
  1. Continue to the all platforms section.
OS X

If you already have Git installed, you can skip ahead to the all platforms section

  1. Open the Terminal app.
  2. Install Homebrew: ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"
  3. Install Git with Homebrew (brew install git).
  4. Continue to the all platforms section.
Linux
  1. Install Git from your distribution’s package manager.

    Ubuntu:

$ sudo apt-get install git

Arch Linux:

$ [sudo] pacman -S git
  1. Continue to the all platforms section.
All Platforms
  1. If your network uses an Internet proxy (e.g. a corporate network) set the http_proxy and https_proxy environment variables:
$ export http_proxy=<your proxy>
$ export https_proxy=<your proxy>
  1. Clone the cantranslator repository:
$ git clone https://github.com/openxc/cantranslator
  1. Continue on to platform specific documentation.

Building from Source

Before you can compile, you will need to define your CAN messages.

The build process uses GNU Make and works with Linux (tested in Arch Linux and Ubuntu), OS X and Cygwin in Windows. For documentation on how to build for each platform, see the supported platform details.

Makefile Options

These options are passed as shell environment variables to the Makefile, e.g.

$ DEBUG=1 make
DEBUG - Set to 1 to compile with debugging symbols and to enable
debug logging. See the platform docs for details on how to read this output.
PLATFORM - Select the target microcontroller platform
(see the platform specific pages for valid options).

NETWORK - By default, TCP output of OpenXC vehicle data is disabled. Set this to 1 to enable TCP output on boards that have an Network interface (only the chipKIT Max32 right now).

BOOTLOADER - By default, the firmware is built to run on a microcontroller with a bootloader, allowing you to update the firmware without specialized hardware. If you want to build to run on bare-metal hardware (i.e. start at the top of flash memory) set this to 0.

Note

When running make to compile, try adding the -j4 flag to build jobs in parallel - the speedup can be quite dramatic.

Troubleshooting

If the compilation didn’t work:

  • Make sure the submodules are up to date - run git submodule update --init and then git status and make sure there are no modified files in the working directory.
  • Did you download the .zip file of the cantranslator project from GitHub? Use git to clone the repository instead - the library dependencies are stored as git submodules and do not work when using the zip file.
  • If you get a lot of errors about undefined reference to getSignals()' and other functions, you need to make sure you defined your CAN messages - read through CAN Message Definition before trying to compile.

Testing

Windows USB Device Driver

On Windows, a driver is required to use the CAN translator’s USB interface. A driver is available in the conf/windows-driver folder. The driver supports both 32- and 64-bit Windows. The driver is generated using the libusb-win32 project.

Python Library

The OpenXC Python library, in particular the openxc-dashboard tool, is useful for testing the CAN translator with a regular computer, to verify the data received from a vehicle before introducing an Android device. Documentation for this tool (and the list of required dependencies) is available on the OpenXC vehicle interface testing page.

Emulator

The repository includes a rudimentary CAN bus emulator:

$ make clean
$ make emulator

The emulator generates fakes values for many OpenXC signals and sends them over USB as if it were plugged into a live CAN bus.

Test Suite

The non-embedded platform specific code in this repository includes a unit test suite. It’s a good idea to run the test suite before committing any changes to the git repository.

Dependencies

The test suite uses the check library.

Ubuntu
$ sudo apt-get install check
OS X

Install Homebrew, then check:

$ brew install check
Arch Linux
$ sudo pacman -S check
Running the Suite
cantranslator/src $ make clean && make test -s
Debugging information
Viewing Debugging data

To view debugging information, first compile the firmware with the debugging flag:

$ make clean
$ DEBUG=1 make
$ make flash

When compiled with DEBUG=1, two things happen:

  • Debug symbols are available in the .elf file generated in the build directory.
  • Log messages will be output over a UART port (no hardware flow control is required) - see supported platforms for details.

View this output using an FTDI cable and any of the many available serial terminal monitoring programs, e.g. screen, minicom, etc.

Bootloaders

For those who don’t have special microcontroller programming hardware, we strive to make the vehicle interface firmware compatible with USB bootloaders. This allows reflashing the firmware by copying a file over to a simulated USB drive, or by using the popular avrdude tool.

For bootloader details, see the supported boards.

Dependencies

In order to build the CAN translator firmware from source, you need a few dependencies:

If instead of the chipKIT, you are compiling for the Blueboard (based on the NXP LPC1768/69), instead of MPIDE you will need:

  • GCC for ARM toolchain
  • OpenOCD
  • JTAG programmer compatible with openocd - we’ve tested the Olimex ARM-OCD-USB programmer.

The easiest way to install these dependencies is to use the script/bootstrap.sh script in the cantranslator repository. Run the script in Linux, Cygwin in Windows or OS X and if there are no errors you should be ready to go:

$ script/bootstrap.sh

If there are errors, continue reading in this section to install whatever piece failed manually.

Source Code

Clone the repository from GitHub:

$ git clone https://github.com/openxc/cantranslator

Some of the library dependencies are included in this repository as git submodules, so before you go further run:

$ git submodule update --init

If this doesn’t print out anything or gives you an error, make sure you cloned this repository from GitHub with git and that you didn’t download a zip file. The zip file is missing all of the git metadata, so submodules will not work.

MPIDE

Building the source for the CAN translator for the chipKIT microcontroller requires MPIDE (the development environment and compiler toolchain for chipKIT provided by Digilent). Installing MPIDE can be a bit quirky on some platforms, so if you’re having trouble take a look at the installation guide for MPIDE.

Although we just installed MPIDE, building via the GUI is not supported. We use GNU Make to compile and upload code to the device. You still need to download and install MPIDE, as it contains the PIC32 compiler.

You need to set an environment variable (e.g. in $HOME/.bashrc) to let the project know where you installed MPIDE (make sure to change these defaults if your system is different!):

# Path to the extracted MPIDE folder (this is correct for OS X)
export MPIDE_DIR=/Applications/Mpide.app/Contents/Resources/Java

Remember that if you use export, the environment variables are only set in the terminal that you run the commands. If you want them active in all terminals (and you probably do), you need to add these export ... lines to the file ~/.bashrc (in Linux) or ~/.bash_profile (in OS X) and start a new terminal.

Digilent / Microchip Libraries

It also requires some libraries from Microchip that we are unfortunately unable to include or link to as a submodule from the source because of licensing issues:

  • Microchip USB device library (download DSD-0000318 from the bottom of the Network Shield page)
  • Microchip CAN library (included in the same DSD-0000318 package as the USB device library)

You can read and accept Microchip’s license and download both libraries on the Digilent download page.

Once you’ve downloaded the .zip file, extract it into the libs directory in this project. It should look like this:

- /Users/me/projects/cantranslator/
---- libs/
-------- chipKITUSBDevice/
         chipKitCAN/
        ... other libraries
FTDI Driver

If you’re using Mac OS X or Windows, make sure to install the FTDI driver that comes with the MPIDE download. The chipKIT uses a different FTDI chip than the Arduino, so even if you’ve used the Arduino before, you still need to install this driver.

OpenOCD
Arch Linux
$ pacman -S openocd
OS X

Install Homebrew. Then:

$ brew install libftdi libusb
$ brew install --enable-ft2232_libftdi openocd

Remove the Olimex sections from the FTDI kernel module, and then reload it:

$ sudo sed -i "" -e "/Olimex OpenOCD JTAG A/{N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;d;}" /System/Library/Extensions/FTDIUSBSerialDriver.kext/Contents/Info.plist
$ sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext/
$ sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext/
GCC for ARM Toolchain

Download the binary version of the toolchain for your platform (Linux, OS X or Windows) from this Launchpad site.

Arch Linux

In Arch Linux you can alternatively install the gcc-arm-none-eabi package from the AUR.

Quick Start

Linux
  1. Install Git from your distribution’s package manager.

    Ubuntu:

$ sudo apt-get install git

Arch Linux:

$ [sudo] pacman -S git
  1. Continue to the all platforms section.
Windows
  1. Install Cygwin and in the installer, select the following packages:
gcc4, patchutils, git, unzip, python, python-argparse, check, curl, libsasl2, ca-certificates, python-setuptools
  1. Start a Cygwin Terminal.
  2. Configure the terminal to ignore Windows-style line endings in scripts:
$ set -o igncr && export SHELLOPTS
  1. Install the FTDI driver (the bootstrap script tries to take care of this, but some developers are reporting that it doesn’t actaully get installed)
  2. Continue to the all platforms section.
OS X
  1. Open the Terminal app.
  2. Install Homebrew: ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"
  3. Install Git with Homebrew (brew install git).
  4. Continue to the all platforms section.
All Platforms
  1. If your network uses an Internet proxy (e.g. a corporate network) set the http_proxy and https_proxy environment variables:
$ export http_proxy=<your proxy>
$ export https_proxy=<your proxy>
  1. Clone the cantranslator repository:
$ git clone https://github.com/openxc/cantranslator
  1. Run the bootstrap.sh script:
$ cd cantranslator
$ script/bootstrap.sh
  1. If there were no errors, you are ready to compile. If there are errors, follow the recommendations in the error messages. You may need to manually install the dependencies if your environment is not in a predictable state.

The bootstrap.sh script is tested in Cygwin, OS X Mountain Lion, Ubuntu 12.04 and Arch Linux - other operating systems may need to install the dependencies manually.

Supported Platforms

The firmware supports compiling for the Microchip’s PIC32 microcontroller and NXP’s LPC1768/69 (and possibly other ARM Cortex M3 micros).

The code base is expanding very organically from supporting only one board to supporting multiple architectures and board variants. The strategy we have now:

  • Switch between “platforms” with the PLATFORM flag - a platform encapsulates a micro architecture and a board variant.
  • Implement different architecture-specific code in a subfolder for the micro
  • Switch pins for board variants in in those same architecture-specific files (like in lights.cpp)

PIC32

Two PIC32 boards are supported:

Troubleshooting PIC32 Boards
No data received over USB?
If you have UART enabled for a while, then disconnect the UART receiver (i.e. pull the status pin low and stop touching RTS/CTS), it can cause the firmware to block trying to write data to UART. Power cycle the board or leave the UART receiver attached even if nobody is reading data (i.e. keep the CTS/RTS lines active).
USB data arriving in bursts?
Are you also reading data over UART, or do you have something pulling the UART connect pin high? It’s not always possible to read both USB and UART at full data rates at the same time.

LPC176x

NGX Blueboard LPC1768-H

To build for the Blueboard, compile with the flag PLATFORM=BLUEBOARD.

UART

On the LPC17xx, UART1 is used for OpenXC output at the 230000 baud rate. Like on the chipKIT, hardware flow control (RTS/CTS) is enabled, so CTS must be pulled low by the receiving device before data will be sent.

  • Pin 2.0 - UART1 TX, connect this to the RX line of the receiver.
  • Pin 2.1 - UART1 RX, connect this to the TX line of the receiver.
  • Pin 2.2 - UART1 CTS, connect this to the RTS line of the receiver.
  • Pin 2.7 - UART1 RTS, connect this to the CTS line of the receiver.

UART data is sent only if pin 0.18 is pulled high. If you are using a Bluetooth module like the BlueSMiRF from SparkFun, you need to hard-wire 5v into pin 0.18 to actually enabling UART. Other hardware implementations (like the Ford prototype) may be able to hook the Bluetooth connection status to this pin instead, to make the status of UART more dynamic.

Debug Logging

On the Blueboard LPC1768H, logging will be on UART0 at 115200 baud:

  • Pin 0.2 - UART0 TX, connect this to the RX line of the receiver
  • Pin 0.3 - UART0 RX, connect this to the TX line of the receiver
LED Lights

LEDs are not currently supported on the Blueboard.

CrossChasm C5 Interface

CrossChasm’s C5 OBD interface is compatible with the OpenXC cantranslator firmware. To build for the C5, compile with the flag PLATFORM=CROSSCHASM_C5.

CrossChasm has made the C5 available for purchase from their website, and it comes pre-loaded with the correct bootloader, so you don’t need any additional hardware to load the OpenXC firmware.

The C5 connects to the CAN1 bus pins on the OBD-II connector.

Flashing a Pre-compiled Firmware

Assuming your C5 has the bootloader already flashed, once you have the USB cable attached to your computer and to the C5, follow the same steps to upload as for the chipKIT Max32.

The C5 units offered directly from the CrossChasm website are pre-programmed with the bootloader.

Bootloader

The C5 can be flashed with the same PIC32 avrdude bootloader, as the chipKIT.

The OpenXC fork of the bootloader (the previous link) defines a CROSSCHASM_C5 configuration that exposes a CDC/ACM serial port function over USB. Once the bootloader is flashed, there is a 5 second window when the unit powers on when it will accept bootloader commands.

In Linux and OS X it will show up as something like /dev/ACM0, and you can treat this just as if it were a serial device.

In Windows, you will need to install the stk500v2.inf <https://raw.github.com/openxc/PIC32-avrdude-bootloader/master/Stk500v2.inf> driver before the CDC/ACM modem will show up - download that file, right click and choose Install. The C5 should now show up as a COM port for for 5 seconds on bootup.

The C5 units offered directly from the CrossChasm website are pre-programmed with the bootloader.

If you need to reflash the bootloader yourself, a ready-to-go .hex file is available in the GitHub repository and you can flash it with MPLAB IDE/IPE and an ICSP programmer like the Microchip PICkit 3. You can also build it from source in MPLAB by using the CrossChasm C5 configuration.

Compiling

The instructions for compiling from source are identical to the chipKIT Max32 except that PLATFORM=CROSSCHASM_C5 instead of CHIPKIT.

If you will not be using the avrdude bootloader and will be flashing directly via ICSP, make sure to also compile with BOOTLOADER=0 to enable the program to run on bare metal.

USB

The micro-USB port on the board is used to send and receive OpenXC messages.

UART

On the C5, UART1A is used for OpenXC output at the 230000 baud rate. Hardware flow control (RTS/CTS) is enabled, so CTS must be pulled low by the receiving device before data will be sent.

TODO add pinout of expansion header, probably a picture

UART data is sent only if pin 0.58 (or PORTB BIT 4, RB4) is pulled high (to 5vv). If you are using a Bluetooth module like the BlueSMiRF from SparkFun, you need to hard-wire 5v into this pin to actually enabling UART. To disable UART, pull this pin low or leave it floating.

Debug Logging

On the C5, logging is on UART3A at 115200 baud (if the firmware was compiled with DEBUG=1).

LED Lights

The C5 has 2 user controllable LEDs. When CAN activity is detected, the green LED will be enabled. When USB or Bluetooth is connected, the blue LED will be enabled.

Ford Prototype Vehicle Interface

To build for the Ford prototype, compile with the flag PLATFORM=FORDBOARD.

Flashing a Pre-compiled Firmware

Pre-compiled binaries (built with the BOOTLOADER flag enabled, see all compiler flags) are compatible with the OpenLPC USB bootloader - follow the instructions for Flashing User Code to update the vehicle interface.

Bootloader

The OpenLPC USB bootloader is tested and working, and enables the LPC17xx to appear as a USB drive. See the documentation in that repository for instructions on how to flash the bootloader (a JTAG programmer is required).

Compiling
USB Bootloader

If you are running a supported bootloader, you don’t need any special programming hardware. Compile the firmware to run under the bootloader:

$ make clean
$ PLATFORM=FORDBOARD BOOTLOADER=1 make -j4

The compiled firmware will be located at build/lpc17xx/cantranslator-lpc17xx.bin. See the bootloaders page for instructions on how to load the firmware.

Bare Metal

Once the dependencies are installed, attach a JTAG adapter to your computer and the CAN translator, then compile and flash:

$ make clean
$ PLATFORM=FORDBOARD make -j4
$ PLATFORM=FORDBOARD make flash

The config files in this repository assume your JTAG adapter is the Olimex ARM-USB-OCD unit. If you have a different unit, modify the src/lpc17xx/lpc17xx.mk Makefile to load your programmer’s OpenOCD configuration.

UART

The software configuration is identical to the Blueboard. The Ford prototype includes an RN-41 on the PCB attached to the RX, TX, CTS and RTS pins, in addition to the UART status pin.

When a Bluetooth host pairs with the RN-42 and opens an RFCOMM connection, pin 0.18 will be pulled high and the VI will being streaming vehicle data over UART.

Debug Logging

Logging will be on UART0, which is exposed on the bottom of the board at J3, a 5-pin ISP connector.

LED Lights

The Ford prototype has 2 RGB LEDs. If the LEDs are a dim green and red, then the firmware was not flashed properly and the board is not running.

LED A

  • CAN activity detected - Blue
  • No CAN activity on either bus - Off

LED B

  • USB connected, Bluetooth not connected - Green
  • Bluetooth connected, USB in either state - Blue
  • Neither USB or Bluetooth connected - Off
Digilent chipKIT Max32

To build for the chipKIT-based Vehicle Interface, compile with the flag PLATFORM=CHIPKIT. The chipKIT is also the default platform, so the flag is optional.

The chipKIT VI supports up to 2 of the CAN1, CAN2-1 or CAN2-2 buses simultaneously.

Flashing a Pre-compiled Firmware

These instructions assume your chipKIT is running the stock firmware, the avrdude bootloader.

USB Cable

You need to have the mini-USB port on the chipKIT connected to your computer to upload a new firmware. This is different than the micro-USB port that you use to read vehicle data - see the device connections section of the OpenXC website to make sure you have the correct cable attached.

Uploading Script

Open a terminal run the upload_hex.sh script from the cantranslator directory, passing it the path to the .hex file you downloaded:

$ cd cantranslator
$ script/upload_hex.sh <firmware file you downloaded>.hex

The upload_hex.sh script attempts to install all required dependencies automatically, and it is tested in Cygwin, OS X Mountain Lion, Ubuntu 12.04 and Arch Linux - other operating systems may need to install the dependencies manually.

If you have more than one virtual serial (COM) port active, you may need to explicitly specify which port to use. Pass the port name as the second argument to the script, e.g. in Linux:

$ script/upload_hex.sh <firmware file you downloaded>.hex /dev/ttyUSB2

and in Windows, e.g. if you needed to use com4 instead of the default com3:

$ script/upload_hex.sh <firmware file you downloaded>.hex com4
Windows notes

In Windows, this command will only work in Cygwin, not the standard cmd.exe or Powershell.

If you get errors about $'\r': command not found then your Git configuration added Windows-style CRLF line endings. Run this first to ignore the CR:

$ set -o igncr && export SHELLOPTS
Dependencies

If the flashing script failed, you may need to install the dependencies manually.

FTDI Driver

If you are using Windows or OS X, you need to install the FTDI driver. If you didn’t need to install MPIDE, you can download the driver separately from FTDI.

AVR Programmer

In order to program the CAN translator, you need to install an AVR programmer. There are a number of free options that will work.

With MPIDE

If you have MPIDE installed, that already includes a version of avrdude. You need to set the MPIDE_DIR environment variable in your terminal to point to the folder where you installed MPIDE. Once set, you should be able to use upload_hex.sh.

Without MPIDE

If you do not already have MPIDE installed (and that’s fine, you don’t really need it), you can install a programmer seprately:

  • Linux - Look for avrdude in your distribution’s package manager.

  • OS X - Install avrdude with Homebrew.

  • Windows
    • Install Cygwin and MPIDE, and follow the Installation documentation to configure the MPIDE environment variables.
Bootloader

The PIC32 avrdude bootloader is tested and working and allows flashing over USB with avrdude. All stock chipKITs are programmed with a compatible bootloader at the factory.

Compiling

Once the dependencies are installed, attach the chipKIT to your computer with a mini-USB cable, cd into the src subdirectory, build and upload to the device.

$ make clean
$ make
$ make flash

If the flash command can’t find your chipKIT, you may need to set the SERIAL_PORT variable if the serial emulator doesn’t show up as /dev/ttyUSB* in Linux, /dev/tty.usbserial* in Mac OS X or com3 in Windows. For example, if the chipKIT shows up as /dev/ttyUSB4:

$ SERIAL_PORT=/dev/ttyUSB4 make flash

and if in Windows it appeared as COM4:

$ SERIAL_PORT=com4 make flash

This build process assumes your chipKIT is running the avrdude bootloader - all chipKITs come programmed with a compatible bootloader by default.

IDE Support

It is possible to use an IDE like Eclipse to edit and compile the project.

  • Follow the directions in the above “Installation” section.
  • Install Eclipse with the CDT project
  • In Eclipse, go to File -> Import -> C/C++ -> Existing Code as Makefile Project and then select the cantranslator/src folder.
  • In the project’s properties, under C/C++ General -> Paths and Symbols, add these to the include paths for C and C++:
    • ${MPIDE_DIR}/hardware/pic32/compiler/pic32-tools/pic32mx/include
    • ${MPIDE_DIR}/hardware/pic32/cores/pic32
    • /src/libs/CDL/LPC17xxLib/inc (add as a “workspace path”)
    • /src/libs/chipKITCAN (add as a “workspace path”)
    • /src/libs/chipKITUSBDevice (add as a “workspace path”)
    • /src/libs/chipKITUSBDevice/utility (add as a “workspace path”)
    • /src/libs/chipKITEthernet (add as a “workspace path”)
    • /usr/include (only if you want to use the test suite, which requires the check C library)
  • In the same section under Symbols, if you are building for the chipKIT define a symbol with the name __PIC32__
  • In the project folder listing, select Resource Configurations -> Exclude from   Build for these folders:
    • src/libs
    • build

If you didn’t set up the environment variables from the Installation section (e.g. MPIDE_HOME), you can also do that from within Eclipse in C/C++ project settings.

There will still be some errors in the Eclipse problem detection, e.g. it doesn’t seem to pick up on the GCC __builtin_* functions, and some of the chipKIT libraries are finicky. This won’t have an effect on the actual build process, just the error reporting.

USB

The micro-USB port on the Digilent Network Shield is used to send and receive OpenXC messages. The mini-USB cable on the Max32 itself is only used for re-programming.

UART

On the chipKIT, UART1A is used for OpenXC output at the 230000 baud rate. Hardware flow control (RTS/CTS) is enabled, so CTS must be pulled low by the receiving device before data will be sent. There are a few tricky things to watch out for with UART (i.e. Bluetooth) output on the chipKIT, so make sure to read this entire section.

UART1A is also used by the USB-Serial connection, so in order to flash the PIC32, the Tx/Rx lines must be disconnected. Ideally we could leave that UART interface for debugging, but there are conflicts with all other exposed UART interfaces when using flow control.

  • Pin 0 - U1ARX, connect this to the TX line of the receiver.
  • Pin 1 - U1ATX, connect this to the RX line of the receiver.
  • Pin 18 - U1ARTS, connect this to the CTS line of the receiver.
  • Pin 19 - U1ACTS, connect this to the RTS line of the receiver.

UART data is sent only if pin A1 is pulled low (to ground). If you are using a Bluetooth module like the BlueSMiRF from SparkFun, you need to hard-wire GND into this pin to actually enabling UART. To disable UART, pull A1 high (hard-wire to 5v) or leave it floating.

An additional item to consider when using UART: typically you will want to rig the chipKIT to be self-powered (either from an external power source or the vehicle) if you’re going to use UART for adding Bluetooth support. There’s not much point in being wireless if you still need power from USB.

In that case, move the power jumper from the 5v input on the Network Shield to A0 (analog input 0). Instead of using 5v to power the board, the firmware can use it to detect if USB is actually attached or not. The benefit of this is that if you connect USB, then disconnect it, we can detect that in the firmware and stop wasting time trying to send data over USB. This will dramatically increase the throughput over UART.

Debug Logging

On the chipKIT Max32, logging will be on UART2 (Pin 16 - Tx, Pin 17 - Rx) at 115200 baud (if the firmware was compiled with DEBUG=1).

LED Lights

The chipKIT has 1 user controllable LED. When CAN activity is detected, the LED will be enabled (it’s green).

Pre-built Binary

If you’ve downloaded a pre-built binary for a specific vehicle, see the Flashing a Pre-compiled Binary section for instructions on how to flash your CAN translator. Most users do not need to set up the full development described in these docs.

A Windows driver for the USB interface is available in the conf/windows-driver folder. The driver supports both 32- and 64-bit Windows. The driver is generated using the libusb-win32 project.

CAN Message Definition

CAN Message Definition

The open source repository does not include the implementation of the functions declared in signals.h and these are required to compile and program a CAN transaltor. These functions are dependent on the specific vehicle and message set, which is often proprietary information to the automaker.

Once the libraries are installed and you run make, you’ll notice that it won’t compile - you’ll get a bunch of errors about undefined references to functions from signals.h:

build/pic32/cantranslator.o: In function `updateDataLights()':
cantranslator.cpp:(.text._Z16updateDataLightsv+0x20): undefined reference to `openxc::signals::getCanBusCount()'
cantranslator.cpp:(.text._Z16updateDataLightsv+0x48): undefined reference to `openxc::signals::getCanBusCount()'
cantranslator.cpp:(.text._Z16updateDataLightsv+0xd4): undefined reference to `openxc::signals::getCanBuses()'
build/pic32/cantranslator.o: In function `initializeAllCan()':
cantranslator.cpp:(.text._Z16initializeAllCanv+0x1c): undefined reference to `openxc::signals::getCanBuses()'
cantranslator.cpp:(.text._Z16initializeAllCanv+0x30): undefined reference to `openxc::signals::getCanBusCount()'
build/pic32/cantranslator.o: In function `setup':
cantranslator.cpp:(.text.setup+0x14): undefined reference to `openxc::signals::initialize()'
build/pic32/cantranslator.o: In function `receiveRawWriteRequest(cJSON*, cJSON*)':
cantranslator.cpp:(.text._Z22receiveRawWriteRequestP5cJSONS0_+0x3c): undefined reference to `openxc::signals::getCanBuses()'
build/pic32/cantranslator.o: In function `receiveTranslatedWriteRequest(cJSON*, cJSON*)':
cantranslator.cpp:(.text._Z29receiveTranslatedWriteRequestP5cJSONS0_+0x44): undefined reference to `openxc::signals::getSignals()'
cantranslator.cpp:(.text._Z29receiveTranslatedWriteRequestP5cJSONS0_+0x4c): undefined reference to `openxc::signals::getSignalCount()'
cantranslator.cpp:(.text._Z29receiveTranslatedWriteRequestP5cJSONS0_+0x78): undefined reference to `openxc::signals::getSignals()'
cantranslator.cpp:(.text._Z29receiveTranslatedWriteRequestP5cJSONS0_+0x80): undefined reference to `openxc::signals::getSignalCount()'
cantranslator.cpp:(.text._Z29receiveTranslatedWriteRequestP5cJSONS0_+0xe4): undefined reference to `openxc::signals::getCommands()'
cantranslator.cpp:(.text._Z29receiveTranslatedWriteRequestP5cJSONS0_+0xec): undefined reference to `openxc::signals::getCommandCount()'
cantranslator.cpp:(.text._Z29receiveTranslatedWriteRequestP5cJSONS0_+0x10c): undefined reference to `openxc::signals::getSignals()'
cantranslator.cpp:(.text._Z29receiveTranslatedWriteRequestP5cJSONS0_+0x114): undefined reference to `openxc::signals::getSignalCount()'
build/pic32/cantranslator.o: In function `receiveCan(openxc::pipeline::Pipeline*, CanBus*)':
cantranslator.cpp:(.text._Z10receiveCanPN6openxc8pipeline8PipelineEP6CanBus+0x54): undefined reference to `openxc::signals::decodeCanMessage(openxc::pipeline::Pipeline*, CanBus*, int, unsigned long long)'
build/pic32/cantranslator.o: In function `loop':
cantranslator.cpp:(.text.loop+0x2c): undefined reference to `openxc::signals::getCanBuses()'
cantranslator.cpp:(.text.loop+0x44): undefined reference to `openxc::signals::getCanBusCount()'
cantranslator.cpp:(.text.loop+0x90): undefined reference to `openxc::signals::getCanBuses()'
cantranslator.cpp:(.text.loop+0xa4): undefined reference to `openxc::signals::getCanBusCount()'
cantranslator.cpp:(.text.loop+0xd4): undefined reference to `openxc::signals::loop()'
build/pic32/main.o: In function `main':
main.cpp:(.text.main+0x60): undefined reference to `openxc::signals::getActiveMessageSet()'
build/pic32/main.o: In function `handleControlRequest(unsigned char)':
main.cpp:(.text._Z20handleControlRequesth+0x64): undefined reference to `openxc::signals::getActiveMessageSet()'
main.cpp:(.text._Z20handleControlRequesth+0x8c): undefined reference to `openxc::signals::getActiveMessageSet()'
build/pic32/platform/pic32/canutil.o: In function `openxc::can::initialize(CanBus*)':
canutil.cpp:(.text._ZN6openxc3can10initializeEP6CanBus+0xbc): undefined reference to `openxc::signals::initializeFilters(unsigned long long, int*)'
build/pic32/platform/platform.o: In function `openxc::platform::suspend(openxc::pipeline::Pipeline*)':
platform.cpp:(.text._ZN6openxc8platform7suspendEPNS_8pipeline8PipelineE+0x3c): undefined reference to `openxc::signals::getCanBuses()'
platform.cpp:(.text._ZN6openxc8platform7suspendEPNS_8pipeline8PipelineE+0x50): undefined reference to `openxc::signals::getCanBusCount()'
collect2: ld returned 1 exit status
make: *** [build/pic32/cantranslator-pic32.elf] Error

You have three options to get a working vehicle interface:

  • Use a pre-built binary firmware from an automaker
  • Create a message set mapping and use the OpenXC Python library to auto-generate an implementation of signals.h. Knowledge of the vehicle’s CAN message is required for this method.
  • Implement the signals.h functions manually

Auto-generated from Mapping

The code generation tools are documented in the code generation input definitions.

Once you’ve defined your message set in a JSON file, install the OpenXC Python library, then run the openxc-generate-firmware-code tool to create an implementation of signals.cpp:

cantranslator/ $ openxc-generate-firmware-code --message-set mycar.json > src/signals.cpp

The firmware should now compile! Don’t modify the signals.cpp file manually, since it’s generated you should expect it to be wiped and recreated at any time; always make changes to the JSON instead.

Manual Implementation

You must implement the functions defined in the signals.h header file. The documentation of those functions describes the expected effect of each. Implement these in a file called signals.cpp and the code should now compile.

You must know the CAN message formats of the vehicle you want to use with the vehicle interface, as you cannot implement these functions without that knowledge.

Output Interfaces & Format

The OpenXC message format is specified and versioned separately from any of the individual OpenXC interfaces or libraries, in the OpenXC Message Format repository.

UART Output

You can optionally receive the output data over a UART connection in addition to USB. The data format is the same as USB - a stream of newline separated JSON objects.

In the same way that you can send OpenXC writes over USB using the OUT direction of the USB endpoint, you can send identically formatted messages in the opposite direction on the serial device - from the host to the CAN translator. They’ll be processed in exactly the same way. These write messages are accepted via serial even if USB is connected. One important difference between reads and writes - write JSON messages must be separated by a NULL character instead of a newline.

For details on your particular platform like the pins and baud rate, see the supported platforms.

USB Device Driver

Most users do not need to know the details of the device driver, but for reference it is documented here.

The CAN translator initializes its USB 2.0 controller as a USB device with three endpoints. The Android tablet or computer you connect to the translator acts as the USB host, and must initiate all transfers.

Endpoint 0

This is the standard USB control transfer endpoint. The CAN transalator has a few control commands:

Version

Version control command: 0x80

The host can retrieve the version of the CAN translator using the 0x80 control request. The data returned is a string containing the software version of the firmware and the configured vehicle platform in the format:

Version: 1.0 (c346)

where 1.0 is the software version and c346 is the configured vehicle.

Reset

Reset control command: 0x81

The CAN transceivers can be re-initialized by sending the 0x81 control request. This command was introduced to work around a bug that caused the CAN translator to periodically stop responding. The bug still exists, but there are now workarounds in the code to automatically re-initialize the transceivers if they stop receiving messages.

Endpoint 1 IN

Endpoint 1 is configured as a bulk transfer endpoint with the IN direction (device to host). OpenXC JSON messages read from the vehicle are sent to the host via IN transactions. When the host is ready to receive, it should issue a request to read data from this endpoint. A larger sized request will allow more messages to be batched together into one USB request and give high overall throughput (with the downside of introducing delay depending on the size of the request).

Endpoint 1 OUT

OpenXC JSON messages created by the host to send to the vehicle (i.e. to write to the CAN bus) are sent via OUT transactions. The CAN translator is prepared to accept writes from the host as soon as it initializes USB, so they can be sent at any time. The messages must be separated by a NULL character.

There is no special demarcation on these messages to indicate they are writes - the fact that they are written in the OUT direction is sufficient. Write messages must be no more than 4 USB packets in size, i.e. 4 * 64 = 256 bytes.

In the same way the CAN translator is pre-configured with a list of CAN signals to read and parse from the CAN bus, it is configured with a whitelist of messages and signals for which to accept writes from the host. If a message is sent with an unlisted ID it is silently ignored.

Contributing

Please see our Contributing Guide.

Mailing list

For discussions about the usage, development, and future of OpenXC, please join the OpenXC mailing list.

Bug tracker

If you have any suggestions, bug reports or annoyances please report them to our issue tracker at http://github.com/openxc/cantranslator/issues/

License

Copyright (c) 2012-2013 Ford Motor Company

Licensed under the BSD license.

This software depends on other open source projects, and a binary distribution may contain code covered by other licenses.