Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

LibreCar Control Wiki

Welcome to the LibreCar Control Wiki!

Current trend in automotive world is moving towards a zone architecture that classifies ECUs by their physical location inside the vehicle, leveraging a central gateway to manage communication. This physical proximity reduces cabling between ECUs to save space and reduce vehicle weight, while also improving processor speeds.

ECUs with actuators and sensors are connected by lower bandwidth bus of 1Mb/s with CAN and main connection backbone is higher bandwidth of 10Mb/s or 100Mb/s with Automotive Ethernet.

LibreCar Control is a automotive exploration tool that can emulate connections inside an automotive vehicle talking between different protocols and buses.

It can be used to:

  • Send and Receive CANbus data from any low cost fpga inside a vehicle.

  • Send and Receive Ethernet packets from the Arty onboard PHY (J9) for lab and TFTP use.

  • Act as a CAN-Ethernet Gateway on that lab network, carrying CAN frames over IP with cannelloni. See Milestone 4.

  • Send and Receive Automotive Ethernet (IEEE 802.3cg 10BASE-T1S) from the same FPGA, using the Step 0 LAN8670 PMOD on JB.

  • Act as a CAN–10BASE-T1S zonal gateway, with CAN on JC and the 10 Mb/s mixing segment on JB.

We use LiteX SoC builder framework to provide a RISC-V soft processor core and integrate with it peripherals like CAN and Ethernet used in automotive world.

Hardware on this Arty

The host for these pages is a Digilent Arty A7-100T.

ConnectorRole
J10USB power, console and programming
J9Onboard Ethernet PHY: Linux TFTP and lab IP
JC (PMOD-C)CAN transceiver PMOD
JB (PMOD-B)10BASE-T1S PMOD, revision 0.2

The two PMODs and the onboard PHY can sit on the board together. JB is also used by the VexRiscv SWD debug work; run 10BASE-T1S or SWD on that header, one at a time.

Pin maps, termination and mating notes are on Hardware PMODs. CAN bring-up stays on CAN communication. The automotive Ethernet path is on 10BASE-T1S bringup. Putting both buses on one SoC is Zonal gateway.

The Step 0 LAN8670 module is designed and routed. LiteEth RMII/PLCA integration and a working 10BASE-T1S link remain open, and the module is on an engineering fabrication hold. Catalogue matching and clean DRC are not a working bus.

Roadmap and schematic notes live in Open Single Pair Ethernet.

Litex Bringup

Steps to bringup CAN bus on a 32-bit RISC-V CPU on Xilinx FPGA board Arty A7-100T!

  • Install prerequisite packages
sudo apt update
sudo apt upgrade
sudo apt install openocd fakeroot verilator python3 meson gtkterm gawk texinfo git python3-pip bison device-tree-compiler autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev build-essential flex gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build
git clone https://github.com/disdi/litex
cd litex

  • Install cross-compiler toolchain for RISC-V.
python3 ./litex_setup.py --gcc=riscv

Install openxc7 or Xilinx Vivado.

  • Install Litex pacakges
python3 ./litex_setup.py --dev --init
  • Install litex with CAN support
python3 ./litex_setup.py --init --install --user 

Apart from all litex packages ctucan_migen_wb_wrapper should also be installed.

Checkout Litex Board Repo.

git clone https://github.com/disdi/litex-boards
cd litex-boards
  • Build bitstream for Arty board. (Install riscv toolchain and Vivado if not already present.)
python3 litex_boards/targets/digilent_arty.py --variant=a7-100 --build

It creates a bitstream file at build/digilent_arty/gateware/digilent_arty.bit

  • Connect Arty A7-100T (J10) to PC using a MicroUSB cable (power, console and programming).

Optionally connect Arty A7-100T (J9) to Switch/Router using a LAN cable and PMOD Sdcard (J10). J9 is the onboard lab PHY (TFTP and IP). The CAN transceiver PMOD uses JC. The 10BASE-T1S PMOD uses JB; see Hardware PMODs.

Load the bitstream from PC to Arty with –load option or directly using openocd.

python3 litex_boards/targets/digilent_arty.py --variant=a7-100 --load

  • Open ttyUSB port to read board serial logs.

To connect to the system’s console, use the screen utility (assuming /dev/ttyUSB1 is used, below):

screen /dev/ttyUSB1 115200

Litex should bootup and mem_list should show CAN peripheral.

This should match the value of CSR register address generated by Litex.

grep "#define CSR[A-Z_]*BASE"  build/digilent_arty/software/include/generated/csr.h

Linux Bringup

Steps to bringup Linux on LiteX with a 32-bit RISC-V CPU on Xilinx FPGA board Arty A7-100T and run 32-bit Linux.

git clone https://github.com/disdi/linux-on-litex-vexriscv
  • Create bitstream with Linux support for Arty A7-100T and flash it.
./make.py --board=arty --variant=a7-100  --build --load
  • Create kernel binaries with CAN support enabled
git clone http://github.com/buildroot/buildroot
cd buildroot
make BR2_EXTERNAL=../linux-on-litex-vexriscv/buildroot/ litex_vexriscv_defconfig

Enable CTUCAN in linux kernel with make menuconfig

Build the kernel binaries

make

The binaries are located in images.

  • Create new devicetree since somehow devicetree created by Litex in not currently configurable.

Compile new devicetree binary with dtc compiler and replace it with one created by Litex.

cd patch
dtc -O dtb -o arty.dtb arty.dts
cp arty.dtb images/rv32.dtb

  • Load the kernel binaries using TFTP server

Connect the board’s Ethernet port (J9, onboard PHY) to a switch/router port that places it into the same LAN as the machine acting as your TFTP server. Leave J9 on the lab LAN even after a 10BASE-T1S module is fitted on JB. TFTP and SSH stay on this PHY.

Ensure that kernel binaries are available in the TFTP directory, and that the TFTP server (or socket, if using systemd) is started:

sudo cp images/* /var/lib/tftpboot/
sudo systemctl start tftp.socket
  • Open ttyUSB port to read board serial logs.

To connect to the system’s console, use the screen utility (assuming /dev/ttyUSB1 is used, below):

screen /dev/ttyUSB1 115200
  • Linux should bootup and bootup logs should show CAN peripheral.

  • Linux socketcan interface should be up.

Socketcan interface should bringup CAN as a networking device.

The onboard eth0 on J9 is the lab interface used above. A future 10BASE-T1S netdev on JB is a second Ethernet; see 10BASE-T1S bringup.

Hardware PMODs

LibreCar uses two 12-pin PMODs on the Arty A7-100T. The CAN module hangs off JC. The 10BASE-T1S module hangs off JB. The onboard RJ45 at J9 stays the lab Ethernet port used for TFTP in Linux Bringup.

Both modules are 3.3 V. The FPGA supplies power on the PMOD 3.3 V pins. The host supplies the protocol controller: CTUCAN for CAN, LiteEth RMII plus MDIO for 10BASE-T1S.

Connector map

                  Arty A7-100T
  JC ── CAN PMOD ── twisted pair ── CAN device
  JB ── Step 0 PMOD ── single pair ── 10BASE-T1S segment
  J9 ── onboard PHY ── RJ45 ── lab LAN / TFTP
  J10 ─ USB ── console and programming

JB is a high-speed PMOD (no 200 Ω series resistors). That is why the 50 MHz RMII clock uses JB. JA and JD have series resistors and are a poor fit for that clock.

The VexRiscv SWD debug path also uses JB. Keep 10BASE-T1S and SWD off the same header in one sitting.

CAN transceiver PMOD (JC)

Project: disdi/canpmod. Active sources are KiCad 9.0.8. The module is an SN65HVD230 plus a 2-pin CAN terminal and a 120 Ω termination jumper. The FPGA implements the CAN controller.

Viewed from the PCB top with the plug pointing left, pins 1–6 run top to bottom in the inboard row and pins 7–12 run top to bottom in the outboard row. Pin 1 is square and marked on silkscreen.

PMOD pinSignalDirection relative to host
1, 2, 3NCUnconnected
4CAN RXInput to host
5GNDGround
63.3 VSupply from host
7, 8, 9NCUnconnected
10CAN TXOutput from host
11GNDGround
123.3 VSupply from host

J1 on the module is the 5.08 mm CAN terminal: pin 1 CAN_L, pin 2 CAN_H. Fit JP1 for an end node. Leave JP1 open for an intermediate node. The removable shunt is a separate accessory.

R1 is 4.7 kΩ slope control. R2 pulls TX high. C1 is 100 nF supply bypass. R3/C2 and R4/C3 are 100 Ω / 560 pF RC branches from each bus line to ground. There is no CAN controller, isolation, extra TVS device or bus reference-ground terminal on the module.

The 3D render on the CAN page is the original drawing. The front plot above is the current corrected board.

10BASE-T1S PMOD (JB)

Project: open-single-pair-ethernet, Step 0. The PHY is a Microchip LAN8670 in RMII mode. The cable side is a 2-pin screw terminal on a 10BASE-T1S mixing segment.

Revision 0.2 is the Arty JB direct-plug order. CLK50 is PMOD pin 1 so it reaches Arty E15 (SRCC). TXD0 is pin 10 (J15). Earlier Katze/LiteX pinouts differ; this revision needs its own LiteX platform constraints.

Module J1 / Arty JBSignalFPGA package pinDirection at FPGA
1CLK50E15, SRCCInput clock
2TXD1E16Output
3TXEND15Output
4CRS_DVC15Input
7RXD0J17Input
8RXD1J18Input
9RST_NK15Output
10TXD0J15Output
5, 11GNDGround—
6, 12+3V33.3 VSupply to module

Package pins are from the Digilent Arty A7-100 Rev D/E master XDC, consulted 2026-10-26. Confirm the physical Arty revision before building a bitstream.

The FPGA receives CLK50 from the module. Keep TXEN inactive during configuration and reset. Release PHY reset after 3.3 V and the 50 MHz oscillator are stable.

MDIO is a separate 3-pin header J3 on the module: pin 1 MDC, pin 2 MDIO, pin 3 GND. Those nets are off J1. Wire MDC and MDIO to two spare 3.3 V FPGA GPIOs and a common ground. IRQ_N stays on the module.

PHY address straps pull down, so the MDIO address is 0. PLCA node ID is a register, written over MDIO after reset.

J2 is the cable connector: pin 1 TRX_P, pin 2 TRX_N. Fit both JP1 and JP2 for an end-node 100 Ω termination. Leave both open for a drop node.

Mating and status

Plug the CAN module into JC and the 10BASE-T1S module into JB with the PMOD keys aligned and both grounds connected. Check connector type, orientation and mechanical clearance before assembly.

The CAN chapter is a working SocketCAN path once the transceiver is fitted. The 10BASE-T1S chapter is the planned LiteEth path; there is no proven Arty bitstream for that PHY in this wiki yet. Step 0 remains on an engineering fabrication hold for clock qualification, host timing, stackup/DFM and assembler acceptance.

Communication with CAN devices

Steps to bringup CAN communication on a 32-bit RISC-V CPU on Xilinx FPGA board Arty A7-100T.

  • We would need to install a handful of very useful CANbus utilities for linux. This is packaged as can-utils for Linux.

Enable BR2_PACKAGE_CAN_UTILS=y in buildroot rootfs.

  • We would also need iproute2 package to bringup CAN on Linux where it is treated as a network device.

Enable BR2_PACKAGE_IPROUTE2=y in buildroot rootfs.

  • Once resulting rootfs is flashed to target, socketcan device can be brought up on Linux with 100 Kbit/s bitrate.
ip link set can0 type can bitrate 100000
ip link set up can0
  • Connect CAN Controller to CAN Transceiver PMOD

CAN Controller output pins are exposed on PMOD-C(JC) of Arty A7-100T board. Connect CAN Transciever PMOD designed in this project, for easy connection to fpga board over PMOD-C(JC). The current board, pin map and termination jumper are on Hardware PMODs.

PMOD pinSignal
4CAN RX (to FPGA)
10CAN TX (from FPGA)
5, 11GND
6, 123.3 V from the Arty
J1 pin 1 / pin 2CAN_L / CAN_H

Fit JP1 on the module for an end node. Leave it open for a drop node.

The original 3D view is kept for reference:

  • Connect a CAN device to other end of CAN Transciever PMOD.

  • Communicate between Arty A7-100T and CAN device usinf cansend from can-utils package.

To carry those frames onto lab Ethernet see Zonal gateway. Automotive Ethernet on JB is a separate PHY: 10BASE-T1S bringup.

10BASE-T1S bringup

Plan to attach IEEE 802.3cg 10BASE-T1S to the same Arty A7-100T LiteX SoC that already runs CAN and lab Ethernet.

Project Page : Open-single-pair-ethernet

10BASE-T1S is a 10 Mb/s half-duplex mixing segment on one twisted pair. Nodes share the pair. PLCA (Physical Layer Collision Avoidance) grants transmit turns so the bus stays deterministic. That is the 10 Mb/s automotive backbone drawn on the Introduction.

The Arty onboard PHY on J9 remains 100/1000BASE-T for TFTP and lab IP. This chapter is the second Ethernet: RMII to a LAN8670 PMOD on JB.

This page is a bring-up plan. A working LiteEth 10BASE-T1S bitstream, MDIO init and a measured link are still open.

Hardware

Fit the Step 0 LAN8670 PMOD on JB. Pin map, clock, reset, MDIO header J3 and termination jumpers are on Hardware PMODs.

FPGA (LiteX)
  ├── LiteEthPHYRMII
  ├── LiteEthPHYMDIO
  └── software that writes PLCA registers
         │
         └── RMII + MDIO → LAN8670 PMOD (JB + J3)
                │
                └── 2-pin screw terminal → 10BASE-T1S pair

MODE1 is pulled up and MODE0 pulled down, so the PHY is in RMII. The 50 MHz oscillator on the module drives the PHY and JB pin 1. PHYAD[4:0] are pulled down (address 0).

LiteX / LiteEth work

LiteEth already has LiteEthPHYRMII and MDIO. The Arty platform file needs a second Ethernet instance on JB:

  1. Map RMII to the JB pins in the table on Hardware PMODs.
  2. Treat CLK50 as an FPGA input clock, with a 20 ns period constraint and RMII input/output delays for the whole Arty plus module path.
  3. Drive RST_N from an FPGA output. Hold TXEN inactive until reset is released.
  4. Add MDC and MDIO on two spare GPIOs to module header J3.
  5. Keep the existing J9 MAC for TFTP. The LAN8670 is a second interface.

Revision 0.2 uses the Arty-specific JB order (CLK50 on pin 1). Copying an older Katze/LiteX RMII pinout will swap the clock and TXD0.

Half-duplex 10BASE-T1S with PLCA is extra work on top of a generic RMII 100 Mb/s PHY. After reset, software writes the PLCA registers over MDIO (node ID, beacon, transmit opportunity). The PHY address is 0; the PLCA node ID is that register, not the PHY address.

Linux later sees this port as a second eth device. SocketCAN stays on can0 from CTUCAN.

Later: digital PHY

Once the external PHY path works, Step 2 moves Clause 147 PCS and Clause 148 PLCA into FPGA RTL and talks to a small analog PMD over the OPEN Alliance TC14 3-pin interface.

That shrinks the cable-side part to a TC14 transceiver such as a TJA1410. It is the same MAC and application wrapper. It is not required for the first JB bring-up.

Open items

  • LiteX platform constraints and a second LiteEth RMII instance on JB
  • MDIO GPIO choice for J3
  • PLCA register init and a half-duplex MAC configuration
  • 50 MHz clock timing closure on the Arty
  • Physical mating, U2 clock qualification and the rest of the Step 0 fabrication hold

Zonal gateway

The Introduction draws a zone controller: CAN toward nearby sensors and actuators, Automotive Ethernet as the 10 Mb/s backbone, and a CPU that bridges the two. On the Arty A7-100T that is three ports on one LiteX Linux SoC.

sensors / actuators ── CAN pair ── CAN PMOD @ JC ── CTUCAN ──┐
                                                              ├─ VexRiscv Linux
zonal backbone ──── 10BASE-T1S pair ── Step 0 @ JB ── LiteEth ┘
lab / TFTP ──────── RJ45 ────── onboard PHY @ J9

CAN bring-up is CAN communication. The T1S PHY and LiteEth plan are 10BASE-T1S bringup. Pin maps are Hardware PMODs.

Lab gateway already on J9

Milestone 4 brought up the Arty onboard Ethernet in LiteX Linux and ran cannelloni. Cannelloni carries CAN frames over UDP/TCP/SCTP between a SocketCAN interface and a remote IP host.

That path is:

can0 (CTUCAN + CAN PMOD) ── cannelloni ── eth0 (J9) ── IP network ── remote CAN

It is a CAN–Ethernet gateway on the lab LAN. It is the right tool for PC tooling, logging and a Raspberry Pi on the bench. J9 is office Ethernet. The zonal diagram’s backbone is 10BASE-T1S.

Milestone 5 and the XCP update add UDS and XCP on that same Linux user-space. Those protocols can ride CAN or IP once the sockets exist.

Automotive gateway on JB

Replace the IP hop with the mixing segment when the LAN8670 PMOD is up:

can0 (JC) ── user-space gateway ── eth1 (JB, 10BASE-T1S)

Same SocketCAN and Ethernet sockets. The cable becomes a single pair with PLCA instead of an RJ45 switch. Fit CAN JP1 and both Step 0 jumpers on end nodes. Leave them open on drop nodes.

Useful first checks, once both interfaces exist:

  1. cansend / candump on can0 as in the CAN chapter.
  2. Ping or a raw Ethernet test toward another 10BASE-T1S node on eth1.
  3. cannelloni or a small user-space bridge between can0 and eth1.
  4. XCP/UDS against an ECU on CAN, with the calibration tool on the T1S side or the other way around.

What is still open

The lab gateway on J9 is documented on librecar.dev. The zonal T1S gateway needs the Step 0 module, LiteEth RMII/PLCA on JB, and a second Linux netdev. Those pieces are designed and not yet a proven link. Keep J9 connected while bringing T1S up so TFTP and SSH stay on the lab PHY.

Funding

This project is funded through the NGI Zero Entrust Fund, a fund established by NLnet with financial support from the European Commission’s Next Generation Internet program.

Learn more on the NLnet project page.

NLnet foundation logo                                                    NGI Zero Logo