18 KiB
USB-CAN-GPIO Adapter Command Protocol
Based on USB-CAN.
Unlike original (only USB-CAN) adapter, in spite of it have GPIO contacts on board, this firmware allows to use both USB-CAN and GPIO.
The old USB-CAN is available as earlier by /dev/USB-CANx, also you can see new device: /dev/USB-GPIOx. New interface allows you to configure GPIO and use it's base functions.
GPIO Interface Protocol for /dev/USB-CANx
Overview
This firmware implements a versatile USB device with two CDC ACM interfaces:
- ICAN (interface 0) — for CAN bus communication
- IGPIO (interface 1) — for GPIO, USART, I2C, SPI, PWM control and monitoring
The device can be configured dynamically via text commands sent over the USB virtual COM ports. All settings can be saved to internal flash and restored on startup.
General Command Format
- Commands are case-sensitive, up to 15 characters long.
- Parameters are separated by spaces or commas.
- Numeric values can be decimal, hexadecimal (
0x...), octal (0...), or binary (b...). - For
USART=...command the part after=is interpreted according to the currenthexinputmode (seehexinputcommand). Specific numeric values (as inSPIandI2Csend) are hex-only without0xprefix.
Global Commands
| Command | Description |
|---|---|
canspeed [=value] |
Get or set CAN bus speed (kBaud, 10─1000). |
curcanspeed |
Show the actual CAN speed currently used by the interface. |
curpinconf |
Dump the current (working) pin configuration ─ may differ from saved config. |
dumpconf |
Dump the global configuration stored in RAM (including CAN speed, interface names, pin settings, USART/I2C/SPI parameters). |
eraseflash |
Erase the entire user configuration storage area. |
help |
Show help message. |
hexinput [=0/1] |
Set input mode: 0 ─ plain text, 1 ─ hex bytes + quoted text. Affects commands like USART and sendcan. |
iic=addr data... |
Write data over I2C. Address and data bytes are given in hex. Example: iic=50 01 02 |
iicread=addr nbytes |
Read nbytes from I2C device at addr and display as hex. Both addr and nbytes are hex numbers. |
iicreadreg=addr reg nbytes |
Read nbytes from I2C device register reg. Also hex. |
iicscan |
Start scanning I2C bus; found addresses are printed asynchronously. |
mcutemp |
Show MCU internal temperature in ℃*10. |
mcureset |
Reset the microcontroller. |
PAx [= ...] |
Configure or read GPIOA pin x (0-15). See Pin Configuration below. |
PBx [= ...] |
Configure or read GPIOB pin x. |
pinout [=function1,function2,...] |
List all pins and their available alternate functions. If a space- or comma-separated list of functions is given, only pins supporting any of them are shown. |
pwmmap |
Show pins capable of PWM and indicate collisions (pins sharing the same timer channel). |
readconf |
Re-read configuration from flash into RAM. |
reinit |
Apply the current pin configuration to hardware. Must be issued after any pin changes. |
saveconf |
Save current RAM configuration to flash. |
sendcan=... |
Send data over the CAN USB interface. If hexinput=1, the argument is parsed as hex bytes with plain text in quotes; otherwise as plain text (a newline is appended). |
setiface=N [=name] |
Set or get the name of interface N (0 = CAN, 1 = GPIO). |
SPI=data... |
Perform SPI transfer: send hex bytes, receive and display the received bytes. |
time |
Show system time in milliseconds since start. |
USART[=...] |
If =... is given, send data over USART (text or hex depending on hexinput). Without argument, read and display any received USART data (as text or hex, according to USART's TEXT/HEX setting). |
vdd |
Show approximate supply voltage (Vdd, V*100). |
Pin Configuration (Commands PAx, PBx)
Pins are configured with the syntax:
PAx = MODE PULL OTYPE FUNC MISC ...
or for a simple digital output:
PAx = 0 # set pin low
PAx = 1 # set pin high
or for PWM output:
PAx = value # set PWM duty cycle (0-255)
Available Keywords (in any order)
| Group | Keyword | Meaning |
|---|---|---|
| MODE | AIN |
Analog input (ADC) |
IN |
Digital input | |
OUT |
Digital output | |
AF |
Alternate function ─ automatically set when a function like USART, SPI, I2C, PWM is selected. |
|
| PULL | PU |
Pull-up enabled (GPIO-only group, don't affect on functions) |
PD |
Pull-down enabled | |
FL |
Floating (no pull) | |
| OTYPE | PP |
Push-pull output |
OD |
Open-drain output | |
| FUNC | USART |
Enable USART alternate function |
SPI |
Enable SPI alternate function | |
I2C |
Enable I2C alternate function | |
PWM |
Enable PWM alternate function | |
| MISC | MONITOR |
Enable asynchronous monitoring of pin changes (for GPIO input or ADC) or USART incoming message. When the pin changes, its new value is sent over USB automatically. |
THRESHOLD n |
Set ADC threshold (0-4095). Only meaningful with AIN. A change larger than this triggers an async report (if MONITOR enabled on this pin). |
|
SPEED n |
Set interface speed/frequency (baud for USART, Hz for SPI, speed index for I2C). | |
TEXT |
USART operates in text mode (lines terminated by \n). |
|
HEX |
USART operates in binary mode (data output as hex dump, data input by IDLE-separated portions if MONITOR enabled). |
Notes
AFis automatically set when anyFUNCis selected; you do not need to type it explicitly.- For
PWM, the duty cycle can be set by assigning a number (0-255) directly, e.g.PA1=128. - For
OUT, assigning0or1sets/clears the pin. - For
ADC(AIN),MONITORuses theTHRESHOLDvalue; if not given, any change triggers a report. - Conflicting configurations (e.g., two different USARTs on the same pins, or missing SCL/SDA for I2C) are detected and rejected with an error message.
After changing pin settings, you must issue the reinit command for the changes to take effect.
USART
Pin Assignment
USART1 can be used on:
- PA9 (TX), PA10 (RX)
- PB6 (TX), PB7 (RX)
USART2 on:
- PA2 (TX), PA3 (RX)
Both USARTs share the same DMA channels, so only one USART can be active at a time.
Configuration via Pin Commands
When you set a pin to FUNC_USART, you can also specify:
SPEED n─ baud rate (default 9600)TEXT─ enable line-oriented mode (data is buffered until\n)HEX─ binary mode (data is sent/received as raw bytes; asynchronous output appears as hex dump)MONITOR─ enable asynchronous reception; received data will be sent over USB automatically (as text lines or hex dump depending on mode)
Example:
PA9 = USART SPEED 115200 TEXT MONITOR
PA10 = USART
reinit
Now USART1 is active at 115200 baud, text mode, with monitoring. Any incoming line will be printed as USART = ....
Sending Data
USART=Hello, world! # if hexinput=0, sends plain text
USART=48 65 6c 6c 6f # if hexinput=1, sends 5 bytes
If TEXT mode is enabled, a newline is automatically appended to the transmitted string.
Receiving Data
Without =, the command reads and displays any data waiting in the ring buffer, like:
USART = 48 65 6c 6c 6f
If in TEXT mode, only complete lines are returned. In HEX mode, all received bytes are shown as a hex dump.
If MONITOR disabled, but incoming data flow is too large for buffering between consequent USART calls,
some "old" data would be printed asynchroneously.
I2C
Pin Assignment
I2C1 is available on any mix of:
- PB6 (SCL), PB7 (SDA)
- PB10 (SCL), PB11 (SDA)
You must configure both SCL and SDA pins for I2C.
Configuration via Pin Commands
I2C─ selects I2C alternate functionSPEED n─ speed index: 0=10kHz, 1=100kHz, 2=400kHz, 3=1MHz (default 100kHz if omitted)MONITORis not used for I2C.
Example:
PB6 = I2C SPEED 2
PB7 = I2C
reinit
This sets up I2C at 400 kHz.
Commands
iic=addr data...─ write bytes to device at 7-bit addressaddr. Address and data are given in hex, e.g.iic=50 01 02 03.iicread=addr nbytes─ readnbytes(both numbers are hex) from device and display as hex dump.iicreadreg=addr reg nbytes─ readnbytesfrom registerreg(all numbers are hex).iicscan─ start scanning all possible 7-bit addresses (1─127). As devices respond, messages likefoundaddr = 0x50are printed asynchronously.
SPI
Pin Assignment
SPI1 can be used on any mix of:
- PA5 (SCK), PA6 (MISO), PA7 (MOSI)
- PB3 (SCK), PB4 (MISO), PB5 (MOSI)
All three pins are not strictly required; you may configure only SCK+MOSI (TX only) or SCK+MISO (RX only). The SPI peripheral will be set to the appropriate mode automatically.
Configuration via Pin Commands
SPI─ selects SPI alternate functionSPEED n─ desired frequency in Hz (actual nearest prescaler will be chosen automatically)CPOL─ clock polarity (1 = idle high)CPHA─ clock phase (1 = second edge)LSBFIRST─ LSB first transmission.
If CPOL/CPHA are not given, they default to 0 (mode 0). LSBFIRST defaults to MSB first.
Example:
PA5 = SPI SPEED 2000000 CPOL CPHA
PA6 = SPI
PA7 = SPI
reinit
Configures SPI at ~2 MHz, mode 3 (CPOL=1, CPHA=1), full duplex.
Commands
-
SPI=data...─ send the given hex bytes, and display the received bytes. Works in full-duplex or write-only modes. Example:SPI=01 02 03will send three bytes and output the three bytes received simultaneously.
-
SPI=n— readsnbytest of data (n should be decimal, binary or hex with prefixes0bor0x).
PWM
Pin Assignment
PWM is available on many pins; see the output of pwmmap (or pinout=PWM) for a complete list with possible conflicts (pins sharing the same timer channel).
Conflicts are automatically detected ─ if you try to use two conflicting pins, one will be reset to default.
Configuration via Pin Commands
PWM─ selects PWM alternate function- No additional parameters are needed; the duty cycle is set by writing a number directly to the pin.
Example:
PA1 = PWM
reinit
PA1=128 # set 50% duty cycle
Reading PWM Value
PA1
returns the current duty cycle (0─255).
Monitoring and Asynchronous Messages
When a pin is configured with MONITOR and is not in AF mode (i.e., GPIO input or ADC), any change in its state triggers an automatic USB message. The format is the same as the pin getter: PAx = value. For ADC, the value is the ADC reading; the message is sent only when the change exceeds the programmed THRESHOLD (if any).
USART monitoring (if enabled with MONITOR) sends received data asynchronously, using the same output format as the USART command.
I2C scan results are also printed asynchronously while scan mode is active.
Saving Configuration
The entire configuration (interface names, CAN speed, pin settings, USART/I2C/SPI parameters) can be saved to flash with saveconf.
On startup, the last saved configuration is automatically loaded. The flash storage uses a simple rotating scheme, so many previous configurations are preserved until the storage area is erased with eraseflash.
Error Codes
Most commands return one of the following status strings (if not silent):
| Code | Meaning |
|---|---|
OK |
Command executed successfully. |
BADCMD |
Unknown command. |
BADPAR |
Invalid parameter. |
BADVAL |
Value out of range or unacceptable. |
WRONGLEN |
Message length incorrect. |
CANTRUN |
Cannot execute due to current state (e.g., peripheral not configured). |
BUSY |
Resource busy (e.g., USART TX busy). |
OVERFLOW |
Input string too long. |
Commands that produce no direct output (e.g., getters) return nothing (silent) and only print the requested value.
CAN Interface Protocol for /dev/USB-CANx
This part describes the simple text‑based protocol used to communicate with the CAN interface of the USB‑CAN‑GPIO adapter.
The interface appears as a standard CDC ACM virtual COM port (e.g. /dev/ttyACM0 or /dev/USB-CANx).
All commands are terminated by a newline character (\n). Numeric parameters can be entered in decimal, hexadecimal (prefix 0x), octal (prefix 0), or binary (prefix b).
Received CAN Message Format
When a CAN message is received (and display is not paused), it is printed as:
<timestamp_ms> #<ID> <data0> <data1> ... <dataN-1>
<timestamp_ms>– system time in milliseconds since start.<ID>– 11‑bit CAN identifier in hexadecimal (e.g.0x123).<dataX>– data bytes in hexadecimal, separated by spaces. If the message has no data, only the timestamp and ID are printed.
Example:
12345 #0x123 0xDE 0xAD 0xBE 0xEF
Commands
General
| Command | Description | Example |
|---|---|---|
? |
Show a brief help message. | ? |
CAN Configuration & Control
| Command | Description | Example |
|---|---|---|
b [speed] |
Set CAN bus speed in kBaud (10–1000). Without argument, display the current speed. | b 250 |
I |
Re‑initialise the CAN controller with the last set speed. | I |
c |
Show CAN status registers (MSR, TSR, RF0R, RF1R). | c |
e |
Show the CAN error register (ESR) with a human‑readable description. | e |
Sending Messages
| Command | Description | Example |
|---|---|---|
s ID [byte0 ... byte7] |
Send a CAN message with the given ID and up to 8 data bytes. Returns immediately after queuing. | s 0x123 0xAA 0xBB |
S ID [byte0 ... byte7] |
Same as s. |
S 0x100 0x01 |
Flood (Periodic Transmission)
| Command | Description | Example |
|---|---|---|
F ID [byte0 ... byte7] |
Set a message to be transmitted repeatedly. The message is stored and sent every t milliseconds. |
F 0x200 0x55 0xAA |
i |
Enable incremental flood mode. Sends a 4‑byte counter (increasing by 1 each time) using the ID from the last F command. |
i |
t <ms> |
Set the flood period in milliseconds (default 5 ms). | t 10 |
Filtering
| Command | Description | Example |
|---|---|---|
f bank fifo mode num0 [num1 [num2 [num3]]] |
Configure a hardware filter. bank — filter bank number (0–27). fifo — FIFO assignment (0 or 1). mode — I for ID list mode, M for mask mode. numX — IDs or ID/mask pairs (for mask mode). |
f 0 1 I 0x123 0x456 – two IDs in list mode. f 1 0 M 0x123 0x7FF – ID 0x123 with mask 0x7FF (accept all). |
l |
List all active filters with their configuration. | l |
a <ID> |
Add an ID to the software ignore list (up to 10 IDs). Messages with this ID will not be printed. | a 0x321 |
p |
Print the current ignore list. | p |
d |
Clear the entire ignore list. | d |
P |
Pause/resume printing of incoming CAN messages. Toggles between paused and running. | P |
LEDs & Misc
| Command | Description | Example |
|---|---|---|
o |
Turn both LEDs off. | o |
O |
Turn both LEDs on. | O |
T |
Show the system time in milliseconds since start. | T |
R |
Perform a software reset of the microcontroller. | R |
Error Reporting
When an error occurs, the device may print one of the following messages:
| Message | Meaning |
|---|---|
ERROR: ... |
General error with a descriptive text. |
NAK |
A transmitted message was not acknowledged (e.g., no receiver on the bus). |
FIFO overrun |
A CAN FIFO overrun occurred – messages were lost. |
CAN bus is off |
The controller entered the bus‑off state; try to restart it with I. |
Additionally, the e command gives a detailed breakdown of the error register.
Notes
- All settings (baud rate, filters, ignore list, flood message) are stored in RAM only and are lost after a reset or power‑off.
To make changes (only speed available) permanent, use the GPIO interface commands
saveconf/storeconfafter configuring CAN. - The device can only handle one active USART at a time, but the CAN interface operates independently.
- The command parser is case‑sensitive for the single‑letter commands (they are expected in lower case, except where noted).
How to distinguish between identical device
In the GPIO interface you can setup custom interface name (setiface=...) for both USB-CAN and USB-GPIO interfaces.
After storing them in flash, reconnect and lsusb -v for given device will show your saved names on iInterface fields.
These fields could be used to create human-readable symlinks in /dev.
To see symlink in /dev to your /dev/ttyACMx device based on iInterface field, add this udev-script to /etc/udev/rules.d/usbids.rules
ACTION=="add", DRIVERS=="usb", ENV{USB_IDS}="%s{idVendor}:%s{idProduct}"
ACTION=="add", ENV{USB_IDS}=="067b:2303", ATTRS{interface}=="?*", PROGRAM="/bin/bash -c \"ls /dev | grep $attr{interface} | wc -l \"", SYMLINK+="$attr{interface}%c", MODE="0666", GROUP="tty"
ACTION=="add", ENV{USB_IDS}=="0483:5740", ATTRS{interface}=="?*", PROGRAM="/bin/bash -c \"ls /dev | grep $attr{interface} | wc -l \"", SYMLINK+="$attr{interface}%c", MODE="0666", GROUP="tty"