| Crates.io | gs_usb |
| lib.rs | gs_usb |
| version | 0.1.1 |
| created_at | 2026-01-13 13:29:58.051149+00 |
| updated_at | 2026-01-15 10:43:03.284129+00 |
| description | GS-USB protocol implementation for CAN adapters |
| homepage | |
| repository | https://github.com/maksimdrachov/gs_usb_rs |
| max_upload_size | |
| id | 2040166 |
| size | 214,599 |
A Rust implementation of the GS-USB protocol for communicating with CAN bus adapters like candleLight, CANable, and other GS-USB compatible devices.
Add this to your Cargo.toml:
[dependencies]
gs_usb = "0.1"
This crate requires libusb to be installed:
Linux (Debian/Ubuntu):
sudo apt-get install libusb-1.0-0-dev
Linux (Fedora):
sudo dnf install libusb1-devel
macOS:
brew install libusb
Windows: Download and install libusb from https://libusb.info/
use gs_usb::{GsUsb, GsUsbFrame, GS_CAN_MODE_NORMAL, GS_CAN_MODE_HW_TIMESTAMP};
use std::time::Duration;
fn main() -> gs_usb::Result<()> {
// Scan for devices
let devices = GsUsb::scan()?;
if devices.is_empty() {
println!("No GS-USB device found");
return Ok(());
}
let mut dev = devices.into_iter().next().unwrap();
// Configure bitrate (250 kbps)
dev.set_bitrate(250000)?;
// Start the device
dev.start(GS_CAN_MODE_NORMAL | GS_CAN_MODE_HW_TIMESTAMP)?;
// Send a frame
let data = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
let frame = GsUsbFrame::with_data(0x7FF, &data);
dev.send(&frame)?;
// Read frames
loop {
match dev.read(Duration::from_millis(100)) {
Ok(frame) => println!("RX {}", frame),
Err(gs_usb::GsUsbError::ReadTimeout) => continue,
Err(e) => return Err(e),
}
}
}
Run the examples with:
# Basic usage example
cargo run --example gs_usb_example
# Device initialization sequence
cargo run --example device_initialization
# CAN FD channel start sequence
cargo run --example channel_start_sequence
# Test all supported bitrates
cargo run --example test_all_bitrates
# Test GET_STATE feature
cargo run --example test_get_state
| Bitrate | 80 MHz | 40 MHz |
|---|---|---|
| 10 kbps | ✓ | ✓ |
| 20 kbps | ✓ | ✓ |
| 50 kbps | ✓ | ✓ |
| 100 kbps | ✓ | ✓ |
| 125 kbps | ✓ | ✓ |
| 250 kbps | ✓ | ✓ |
| 500 kbps | ✓ | ✓ |
| 800 kbps | ✓ | ✓ |
| 1 Mbps | ✓ | ✓ |
| Data Bitrate | 80 MHz | 40 MHz |
|---|---|---|
| 2 Mbps | ✓ | ✓ |
| 4 Mbps | ✓ | ✓ |
| 5 Mbps | ✓ | ✓ |
| 8 Mbps | ✓ | ✓ |
| 10 Mbps | - | ✓ |
// Scan for all GS-USB devices
let devices = GsUsb::scan()?;
// Find a specific device by bus and address
let device = GsUsb::find(1, 5)?;
// Set bitrate (classic CAN)
dev.set_bitrate(500000)?;
// Set CAN FD data bitrate
dev.set_data_bitrate(5000000)?;
// Set raw timing parameters
dev.set_timing(prop_seg, phase_seg1, phase_seg2, sjw, brp)?;
use gs_usb::*;
// Normal mode with hardware timestamps
dev.start(GS_CAN_MODE_NORMAL | GS_CAN_MODE_HW_TIMESTAMP)?;
// Listen-only mode (no ACKs)
dev.start(GS_CAN_MODE_LISTEN_ONLY)?;
// Loopback mode for testing
dev.start(GS_CAN_MODE_LOOP_BACK)?;
// CAN FD mode
dev.start(GS_CAN_MODE_NORMAL | GS_CAN_MODE_FD)?;
use gs_usb::{GsUsbFrame, CAN_EFF_FLAG, CAN_RTR_FLAG};
// Standard frame (11-bit ID)
let frame = GsUsbFrame::with_data(0x123, &[0x01, 0x02, 0x03]);
// Extended frame (29-bit ID)
let frame = GsUsbFrame::with_data(0x12345678 | CAN_EFF_FLAG, &data);
// Remote transmission request
let frame = GsUsbFrame::with_data(0x123 | CAN_RTR_FLAG, &[]);
// CAN FD frame with BRS (bit rate switch)
let frame = GsUsbFrame::with_fd_data(0x123, &data_64_bytes, true);
// Get device info (channels, firmware version)
let info = dev.device_info()?;
println!("Channels: {}", info.channel_count());
println!("FW: {:.1}", info.firmware_version());
// Get device capabilities
let cap = dev.device_capability()?;
println!("Clock: {:.1} MHz", cap.clock_mhz());
println!("Features: 0x{:08x}", cap.feature);
// Check CAN FD support
if dev.supports_fd()? {
println!("CAN FD is supported");
}
// Get bus state and error counters
if dev.supports_get_state()? {
let state = dev.get_state(0)?;
println!("State: {}", state.state_name());
println!("RX errors: {}", state.rxerr);
println!("TX errors: {}", state.txerr);
}
To access USB devices without root on Linux, create a udev rule:
sudo tee /etc/udev/rules.d/99-gs_usb.rules << EOF
# GS-USB devices
SUBSYSTEM=="usb", ATTR{idVendor}=="1d50", ATTR{idProduct}=="606f", MODE="0666"
# candleLight
SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="2323", MODE="0666"
# CES CANext FD
SUBSYSTEM=="usb", ATTR{idVendor}=="1cd2", ATTR{idProduct}=="606f", MODE="0666"
# ABE CANdebugger FD
SUBSYSTEM=="usb", ATTR{idVendor}=="16d0", ATTR{idProduct}=="10b8", MODE="0666"
EOF
sudo udevadm control --reload-rules
sudo udevadm trigger
MIT License
This is a Rust port of the Python gs_usb library.