Skip to content

3. Communication Protocol

Spb2005 edited this page Feb 21, 2026 · 7 revisions

Overview

The Thrustmaster T248 wheel and wheelbase communicate over a UART interface.

Configuration:

  • Baud rate: 115200
  • Format: 8E1 (8 data bits, even parity, 1 stop bit)
  • Master: Wheelbase
  • Slave: Wheel

The wheelbase controls all timing and initiates cyclic exchanges.


Wheel-to-Wheelbase Connection

Compared to other Thrustmaster wheels:

  • Older models (T300, T150, TMX, T500) → SPI
  • Newer models (T818) → CAN-BUS

The T248/T124 uses UART with even parity at 115200 baud.

Wheel connector pins (observed):

Pin Function Notes
TX (PA2) Data to wheelbase Testpad 7, via 27.5Ω series resistor
RX (PA3) Data from wheelbase Testpad 6
RESET (TP9) Reset wheel MCU Used during startup
PA14 (TP8) Mode button / GPIO Likely involved in boot or firmware update

Communication Phases

Communication is divided into three main phases:

  1. Startup Sequence
  2. Normal Operation
  3. Shutdown Sequence

Note: If the wheel is powered on without the wheelbase, communication differs entirely. Pulseview captures are provided for analysis.


1. Startup Sequence

  1. Wheelbase pulls RESET line high for ~400 ms → resets wheel MCU

  2. ~100 ms later, wheelbase starts sending keep-alive frames

    • Wheel does not respond yet
  3. After another ~100 ms, wheel finishes booting and sends a “hello” frame twice:

    F4 02 00 02 AA E1 FF DE

  4. Wheelbase responds to each frame:

    F0 00 00 00

  5. Normal operation begins:

  • 4 Hz button messages
  • Keep-alive frames
  • Screen data (if supported by game)

Startup Sequence

Hello Frame


2. Normal Operation

Keep-Alive Frames

Wheelbase cyclically transmits four 4-byte frames:

D0 00 00 00
D1 00 FF 01
D2 00 00 00
D3 00 00 00

  • Frames rotate every 250 ms (e.g., D0 → D1 → D2 → D3 → next cycle D3 → D0 → …)
  • Wheel must respond to each frame: F0 00 00 00

⚠️ Timing requirement: ~5 ms per keep-alive frame

Keep-Alive

Keep-Alive


Button Frames

  • Sent every 250 ms (B0 and B1 frame) or immediately after a button press (only B0 frame)
  • Alternating frames:
  • B0 xx xx xx → button data
  • B1 00 00 00 → placeholder

Only the B0 frame is evaluated by the wheelbase. The button states are encoded in the B0 frame as follows:

B0 Frame Structure

Byte 0:

  • static 0xB0

Byte 1:

  • DPAD Right
  • Display
  • Mode
  • Encoder Left Up
  • Encoder Left Down
  • Encoder Right Up
  • Encoder Right Down

Byte 2:

  • BTN 9
  • BTN 10
  • BTN 22
  • BTN 23
  • BTN 13
  • DPAD Up
  • DPAD Down
  • DPAD Left

Byte 3:

  • BTN 1–8

Button Data


General Data Frames (F3)

In addition the wheelbase sends a general-purpose data frame used for multiple functions.

Frame length: 18 bytes
Example: F3 0E 00 00 05 45 20 31 20 2B A0 86 01 00 00 00 00 00

Observations:

  • Byte 0–1: static
  • Byte 5: message subtype
    • 0x45 → Encoder-related data
    • 0x20 → Default / idle state
    • maybe additional types

This frame is sent:

  • randomly in idle mode (non-encoder data)
  • immediately after encoder interaction (encoder data)

Encoder Data

  • Byte 7: bits 0–2 encode the current encoder layer
  • Byte 9: identifies the pressed encoder button (EX+, EX-, EXP)
  • Byte 10–11: encode the encoder action:
    • no action / reset
    • layer switch
    • encoder button press

Excel Analysis

Encoder Data


Screen Frames (UART Level)

Display frames are transmitted by the wheelbase when a running game supports the T248 display.

Characteristics:

  • Variable frame length
  • Transmitted asynchronously (not tied to the 250 ms keep-alive cycle)
  • Only active when telemetry data is available

Frame Structure (UART – Wheelbase → Wheel)

  • Byte 0: Frame identifier (0x2A or 0x42 observed)
  • Byte 1: Frame counter (increments each transmission)
  • Byte 2: Payload length
  • Remaining bytes: Payload data

Wheel Response

After each display frame, the wheel responds with a fixed 12-byte frame:

47 0C 2A 02 01 00 80 00 00 00 00 00

Observations:

  • Byte 0 appears constant (0x47)
  • Byte 1 likely encodes frame length (0x0C = 12 bytes)
  • Exact functional meaning remains unclear

Display Duration Behavior

Display content remains visible for approximately ~2 seconds unless refreshed.

A short frame (observed on both UART and USB levels) appears to function as a display keep-alive / duration extender:

42 06 D0 63 06 00 E6 B8

(On USB level, this frame contains two additional leading header bytes.)

Repeated transmission extends the visible duration without modifying the displayed content.

Data

Answer


3. Shutdown Sequence

  • Triggered when wheelbase is disconnected from PC
  • Wheelbase sends twice:

FD 01 00 00

  • Wheel does not respond

Protocol Observations

  • High frame redundancy
  • Frequent acknowledgments
  • Rotating frame order
  • Unused headroom in certain frames

USB Communication (Wheelbase ↔ PC)

(Contribution by Lolig4 – February 2026)

Additional reverse engineering work was contributed by GitHub user Lolig4, focusing on the USB/HID communication between the PC and the T248 wheelbase.

While this project primarily analyzes the UART communication between wheelbase and wheel, this contribution provides insight into the upstream USB protocol layer.


Capture Methodology

  • USB traffic captured using Wireshark + USBPcap
  • Test environment: Forza Horizon 5 (display-supported title)
  • Relevant packets filtered and exported as JSON
  • Python script used to extract value-changing frames
  • Frame injection performed using:
    • Arduino Pro Mini (3.3 V)
    • USB Host Shield

Structural Similarities: USB vs UART

Key observation:

Display frames seen on the USB side are structurally nearly identical to the UART display frames documented in this project.

Difference:

  • USB frames contain two additional leading header bytes
  • Remaining structure matches UART payload format very closely

This suggests that the wheelbase performs little to no deep reinterpretation of display data and may forward display payloads with minimal transformation.


Required USB Display Reports

Three primary reports must be transmitted together to update display content:

  • rpt1
  • rpt2
  • rpt3

If only these three reports are sent once, the display content remains visible for approximately ~2 seconds.

An additional short report:

  • rpt10

Acts as a display duration extender, increasing visible time by ~2 seconds per transmission without modifying content.


Report Structure Overview

The implementation is based on the function: SendTestChar(uint8_t ch)

Source file: SendTestChar.c

Report 1 (rpt1)

Contains:

  • ASCII character (center display)
  • RPM value
  • Speed value
  • Bargraph intensity value

Notable behavior:

  • ASCII characters A–Z and 0–9 are working
  • Bargraph behaves like a multi-bit intensity value (likely ~10-bit range)
  • High values (~0x03FF) cause all 9 bars to blink
  • Empirically derived values produce visually clean 0–9 bar levels

Report 2 (rpt2)

Contains:

  • Driver position values (0-99, only last 2 digits of certain value)
  • Lap position values
  • Additional numeric display fields

Report 3 (rpt3)

Purpose not yet fully understood. However:

  • It is required for proper display updates
  • Omitting it prevents stable display behavior

Display Capabilities

So far, the following behaviors are possible:

  • Display of ASCII characters
  • Control of bottom bargraph intensity
  • Speed value injection
  • Driver/lap position field control
  • Display persistence control via keep-alive frame

This shows, that the wheelbase sends all the data and the wheel decides, which to display


Shared Files

The following files are archived in this folder:

  • SendTestChar.c
  • USB_Forza5_Trace1.json
  • USB_Forza5_Trace2.json
  • USB_Forza5_Trace3.json
  • hid_data_extractor.py

These contain raw USB captures and helper tooling for HID frame extraction.

For full context, discussion details, and additional technical remarks, see the complete conversation in this GitHub Issue.


Relevance for This Project

This contribution is particularly valuable because:

  • It confirms structural similarities between USB and UART display frames.
  • It provides additional insight into how the wheelbase handles display updates.
  • It supports future research into full display decoding and firmware behavior.

Special thanks to Lolig4 for sharing this research and capture data.

Read Next