esp32_twai
TWAI (CAN 2.0): the ESP32’s CAN controller, an SJA1000-style core.
This driver covers the self-test loopback path: the controller transmits a frame and receives its own copy, with no second node and no bus.
How the loopback works, without a wire or a transceiver
Section titled “How the loopback works, without a wire or a transceiver”Two mechanisms combine:
- Self-test mode (
MODE.STM) lets a transmission complete with no acknowledgement — normally another node must ACK or the frame is retried forever. A self-reception request (CMD.SRR) transmits and receives the same frame at once. - The transmitted bits still have to reach the RX input. Routed through the GPIO matrix, the controller’s TX output and RX input signals land on the same pad, so what it drives it reads back. Real analog path (pad → pad), no internal register loopback.
So a single ESP32, one pin, tests the whole controller: bit timing, framing, CRC, the TX and RX buffers.
Not covered
Section titled “Not covered”A real bus, arbitration against another node, and acknowledgement by a second controller. Those need a transceiver and a peer (issue #27). This is the on-chip functional test, fixed at 125 kbit/s — the rate is immaterial when a node talks only to itself.
Register facts
Section titled “Register facts”DR_REG_CAN_BASE = 0x3FF6B000, from esp-idf soc/soc.h. The register
layout is soc/twai_struct.h (each 8-bit SJA1000 register in the low byte
of a 32-bit word); the sequences are hal/twai_ll.h.
| Register | Offset | Fields |
|---|---|---|
MODE |
0x00 |
RM 0, LOM 1, STM 2, AFM 3 |
CMD |
0x04 |
TR 0, AT 1, RRB 2, CDO 3, SRR 4 |
STATUS |
0x08 |
RBS 0, DOS 1, TBS 2, TCS 3, RS 4, TS 5, ES 6, BS 7 |
INT_ENA |
0x10 |
interrupt enables, all cleared |
BUS_TIMING_0 |
0x18 |
BRP [5:0], SJW [7:6] |
BUS_TIMING_1 |
0x1C |
TSEG1 [3:0], TSEG2 [6:4], SAM 7 |
DATA[0..13] |
0x40..0x74 |
TX/RX buffer; ACR/AMR in reset mode |
CLOCK_DIVIDER |
0x7C |
CD [2:0], CO 3, CM 7 (PeliCAN) |
Structs
Section titled “Structs”struct Frame { pub id: u16, pub len: u8, pub data: [u8; 8],}A standard (11-bit identifier) CAN frame.
Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
struct Twai { /* private fields */ }The TWAI controller.
enum Mode { Normal, SelfTest, ListenOnly,}Operating mode.
Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
TwaiError
Section titled “TwaiError”enum TwaiError { Timeout,}Why a self-reception failed.
Implements: Clone, Copy, Debug, Eq, From, PartialEq, StructuralPartialEq