2.9 KiB
2.9 KiB
Volvo LIN-to-IR Controller (ATtiny84)
This project implements the production firmware for the ATtiny84 to interface a Volvo V50 Steering Wheel Module (SWM) LIN bus with a Raspberry Pi running LineageOS (Android).
It decodes steering wheel navigation buttons from the vehicle's LIN bus and translates them into bit-banged RC-6 Mode 6A (MCE) remote control commands sent over a direct wire connection.
Pin Configurations (ATtiny84)
| ATtiny84 Pin | Digital Pin (Arduino) | Function | Description |
|---|---|---|---|
| PA0 | 10 |
IR Output | Direct-wired to Raspberry Pi GPIO 24 |
| PA5 | 8 |
LIN RX | SoftwareSerial RX from MCP2004 RXD |
| PA1 | 9 |
LIN FAULT/TXE | MCP2004 Fault Detect / Transmit Enable |
| PA2 | 11 |
LIN CS | MCP2004 Chip Select (Active High) |
| PA6 | 3 |
Debug LED | Flash on command transmission |
Key Mapping
The Steering Wheel Module (SWM) sends frames on LIN ID 0x20 with the navigation key statuses. The firmware decodes these and maps them to the following Microsoft MCE remote scancodes:
| Button | LIN Frame Trigger | Active Button Code | MCE Scancode | Action on LineageOS |
|---|---|---|---|---|
| UP | d0 & 0x01 |
1 |
0x800f041e |
Navigate Up |
| DOWN | d0 & 0x02 |
2 |
0x800f041f |
Navigate Down |
| LEFT | d0 & 0x04 |
3 |
0x800f0420 |
Navigate Left |
| RIGHT | d0 & 0x08 |
4 |
0x800f0421 |
Navigate Right |
| ENTER | d1 & 0x08 |
5 |
0x800f0422 |
Select / OK |
| BACK | d1 & 0x01 |
6 |
0x800f0423 |
Back / Exit |
Note: In previous revisions, ENTER and BACK were reversed. This has been corrected so that pressing ENTER maps to 0x800f0422 and BACK maps to 0x800f0423.
Protocol and Timing
- Protocol: RC-6 Mode 6A (MCE).
- Time Unit (1T):
444us. - Modulation: None. Timing is bit-banged directly since the output pin is wired directly to the Pi's IR receiver GPIO (which expects demodulated active-low signals).
- Idle (Space):
HIGH(3.3V). - Active Pulse (Mark):
LOW(0V). - Toggle Bit: Alternates state on each new button press, but remains constant for repeated holds.
- Repeat Interval: Holds trigger repeat IR commands sent every
250ms.
Software Architecture
- SoftwareSerial Interrupt Isolation:
Since SoftwareSerial RX interrupts consume about 1ms per byte, they will disrupt the precise microsecond-level timing of bit-banged IR frames. To avoid this, interrupts are disabled (
noInterrupts()) during the 37ms window of IR transmission and re-enabled (interrupts()) immediately afterward. - Release detection:
The SWM continuously transmits frames on the LIN bus. If no button frames are detected or a frame with all 0s is received, the current active button resets to idle. A timeout of
200msensures that if the LIN bus goes quiet, button repeats cease immediately.