Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/roncapat/Ford-Fiesta-MK5-MS-CAN-bus

Reverse engineering of CANbus messages of Fiesta MK5 (restyling) dashboard/radio
https://github.com/roncapat/Ford-Fiesta-MK5-MS-CAN-bus

automotive canbus canbus-messages fiesta-mk5 ford ms-can

Last synced: about 2 months ago
JSON representation

Reverse engineering of CANbus messages of Fiesta MK5 (restyling) dashboard/radio

Awesome Lists containing this project

README

        

# Reverse engineering CANbus messages of Fiesta MK5 dashboard/radio subsystem
This documentation applies to Ford Fiesta MK5 >2006 (MK5 restyling), with 2-DIN, 6000CD radio.

The radio sends messages to the LCD screen in the dashboard, like FM station names, CD track IDs, volume changes.

The idea was to tap into the text-to-LCD mechanism, but I ended up reversing some other interesting CANbus messages.

Tapping in the infotaiment CANbus is quite easy: just connect a CANbus interface over CANH and CANL lines that come into the QuadLock conector of the radio, no 120 Ohm terminal block resistor needed.

![QuadLock connector and CANbus pins](quadlock.png)

Personally, I used a [SeedStudio CANbus Shield](https://wiki.seeedstudio.com/CAN-BUS_Shield_V2.0/) stacked onto an Arduino Uno R3.

## Results
Bus speed is 125 KBPS.

The IDs of either partially or fully decoded messages are:
- 0x080
- 0x1e9
- 0x201
- 0x265
- 0x285
- 0x286
- 0x2d5
- 0x2d8
- 0x2da
- 0x2db
- 0x360
- 0x420
- 0x428
- 0x433
- 0x460
- 0x4c0
- 0x4c8
- 0x4f3

A Kayak [.kcd file](Fiesta.kcd) definition file is included (incomplete).

### Text to LCD screen
The radio sends text to the dashboard LCD using either a short message format or an extended message format.

The short format can only be seen whenever the radio switches to AUX mode.


ID
1
2
3
4
5
6
7
8


0x4C0
0x7
0x34
ASCII text

The extended format is composed by one header message containing the length of the text, and subsequent messages that provide additional text portions.


ID
1
2
3
4
5
6
7
8


0x4C0
0x10
Text length + 2
0x34
ASCII text


0x4C0
0x21
ASCII text

this happens to be the [ISO-TP protocol (ISO 15765-2)](https://en.wikipedia.org/wiki/ISO_15765-2). For the sake of completeness, after the first extended frame message, an ACK message is received (as required by the ISO-TP flow control mechansim):


ID
1
2
3
4
5
6
7
8


0x4C8
0x30
0x00
0x00
0x00
0x00
0x00
0x00
0x00

where:
- byte 1 (0x30) tells that the source is "clear to send" the next portions of the message;
- byte 2 (0x00) tells that frames are to be sent without flow control;
- byte 3 (0x00) tells to send as fast as the source can.

Thanks to [/u/thatguy147 for the ISO-TP suggestion!](https://www.reddit.com/r/CarHacking/comments/j28skt/ford_fiesta_mk5_2006_mscan_hacking/g75hm5e?utm_source=share&utm_medium=web2x&context=3)

### Radio station name

The radio also shares the radio station name with a specific message.


ID
1
2
3
4
5
6
7
8


0x1E9
ASCII text

### Radio OFF
When the radio is OFF this message is broadcasted.


ID
1
2
3
4
5
6
7
8


0x4C0
0x2
0x34
0

### Radio mode / seek buttons
Apparently, only mode and seek buttons near the steering column issue commands over MS-CAN, while unfortunately it seems that volume buttons are not.


ID
1
2
3
4
5
6
7
8


0x2D5
(unspecified)
<buttons>
(unspecified)

buttons is a bitmask: the byte is the algebraic sum of these condition codes, whenever applicable.


Status
Code


Mode button
0x10


Seek up
0x40


Seek down
0x80

### Radio volume

The radio unit broadcasts a message containing the current volume level.


ID
1
2
3


0x2D8
0x00
<volume_raw>
0x00

where the real volume level can be obtained as:

```
volume = volume_raw/8
```

### CD track info

When the unit is not in CD playback mode, the following message is emitted:


ID
1
2
3
4
5
6
7
8


0x2DB
0xFF
0xFF
0xFF
0xFF
0x00
0x00
0x00
0x00

Instead, during CD playback, the message contains the track id and current seek time:


ID
1
2
3
4
5
6
7
8


0x2DB
0xFF
0xFF
<track_time>
0x00
<track_id>
0x00
0x00

where the current track time, in seconds, can be obtained like this:
```
track_seconds = track_time - 64
```

### CD status

The radio unit tells informations about the CD presence.


ID
1
2
3
4
5


0x2DA
(unspecified)
<cd_mode>
0x00
<cd_drive>
0x00


CD Mode
Code


No CD inserted
0x2A


CD inserted - playback
0x4A


CD inserted - no playback
0x6A


CD Drive
Code


No CD inserted
0x23


CD loading
0x21


CD inserted - no playback
0x22


CD inserted - playback
0x26

### Date & Time
The car has an onboard RTC that works independently from the radio clock (it works even if the radio is disconnected at all). The date and time are broadcasted with 1 second resolution.


ID
1
2
3
4
5
6


0x80
year (two digits)
month
day
hours
minutes
seconds

### AirBag status

The AirBag dashboard light is commanded either ON or OFF depending with the 5th byte of this message.


ID
1
2
3
4
5
6
7
8


0x460
0x0
0x0
0x0
0x0
<status>
0x0
0x0
0x0


Status
Code


ON
0xC0


OFF
0x0

### Doors status / Lock / Reverse gear
Doors status is signalled setting or clearing bits in the 1st byte of this message. Full lock of the doors is signalled by the 6th byte. Morover, this packet hold the status of the reverse gear in the 4th byte.


ID
1
2
3
4
5
6
7
8


0x433
<door_status>
(unspecified)
<reverse_gear>
(unspecified)
<lock>
(unspecified)

door_status is a bitmask: the 1st byte is the algebraic sum of these condition codes, whenever applicable.


Status
Code


Front left open
0x80


Front right open
0x40


Trunk open
0x08

reverse_gear can be interpreted as follows:


Status
Code


ON
0x02


OFF
0x00

lock can be interpreted as follows:


Status
Code


LOCKED
0x10


UNLOCKED
0x20

### Arrows status

Arrows status is signalled setting or clearing bits in the 1st byte of this message.


ID
1
2
3
4
5
6
7
8


0x265
<status>
(unspecified)

Status is a bitmask: the 1st byte is the algebraic sum of these condition codes, whenever applicable.


Status
Code


Left ON
0x20


Right ON
0x40

### Vehicle ID
Periodically, the veihcle ID (lower part of VIN, so the serial number plus other codes signalling production date) is broadcasted.


ID
1
2
3
4
5
6
7
8


0x4F3
<vehicle ID>

### Front beams / handbrake status

Front beams status is signalled setting or clearing bits in the 1st byte of this message. Notice that, since this message is just for dashboard LEDs, parking lights cannot be distinguished from low beams, as they share the same LED indicator.


ID
1
2
3
4
5
6
7
8


0x286
<status>
(unspecified)

Status is a bitmask: the 1st byte is the algebraic sum of 0x10 and these condition codes, whenever applicable.


Status
Code


Handbrake
0x10


Parking lights / low beams
0x80


High beams
0x40

### Gas pedal / RPM / Speed

Gas pedal position, engine RPM and speed (Km/h) are contained in the same packet.


ID
1
2
3
4
5
6
7
8


0x201
<rpm>
(unspecified)
<speed>
<0x80+gas>

where the position of the pedal can be translated in percentage with the following formula:
```
gas_percent = gas*100/50944
```
while speed in Km/h can be obtained with:
```
km_h = speed/100
```

### Brake pedal / coolant temperature

Brake pedal status is repeated in two different messages, with different codes.


ID
1
2
3
4
5
6
7
8


0x420
<coolant>
(unspecified)
<brake>
(unspecified)

where brake can be interpreted as follows:


Brake status
Code


Not pressed
0x00


Foot on pedal
0x10


Pressed
0x30

and coolant temperature can be obtained as follows:
```
coolant_degrees = coolant - 40
```

and


ID
1
2
3
4
5
6
7
8


0x360
(unspecified)
<brake>
(unspecified)

where brake can be interpreted as follows:


Brake status
Code


Not pressed
0x60


Foot on pedal
0x68


Pressed
0x78

### Key position

Key can be either in position 1, 2 or 3.


ID
1
2
3


0x285
<key>
(unspecified)

where the position can be obtained reading bits 5 and 6 of the first byte:
```
key_position = (key & 0x30) >> 4
```

### Battery voltage

Battery voltage is expressed in tenths of Volt.


ID
1
2
3
4
5
6
7


0x428
(unspecified)
<battery>
(unspecified)

where battery status, in volts, can be obtained as:
```
battery_v = battery/10
```