Rover Service Communications Protocol (ROSCO)

Protocol

The ECU’s diagnostic port uses a serial protocol, with 8 data bits, no parity, and 1 stop bit, running at 9600 bps.

When a diagnostic tool (or a PC running diagnostic software) is first connected to the ECU, it must send an initialisation sequence to enable further communication. I haven’t looked inside the SPi MEMS firmware and I’ve only run experiments with a single car, so I can’t provide any further insight on the meaning of this sequence. I’d certainly like to hear from anyone who has more information. Note that the first byte returned by the ECU appears to always be an echo of the command byte.

Table 1: Initialisation sequence

Sent by toolResponse from ECU (MNE101170)Response from ECU (MNE101070)
CACACA
757575
D0D0 99 00 03 03D0 99 00 02 03

Once the initialisation sequence is complete, any of several single-byte commands may be sent to the ECU. They are described in Table 3.

Some of the commands appear to increment or decrement settings that have a predefined range. The settings that I’ve found are described in Table 2.

Table 2: Software counters/settings used in the firmware on MNE101170. All values in hex.

SettingDefault valueMinimumMaximumDecremented by command(s)Incremented by command(s)
Fuel trim8A00FE7A and 7C79 and 7B
Idle decay230A3C8A89
Idle speed8078889291
Ignition advance offset80748C9493

Although some of the actuators have pairs of on/off commands to drive them, I’ve found that the system fitted to the Mini SPi will actually turn off the AC relay, PTC relay, and fuel pump relay automatically after a short time (i.e. without requiring the ‘off’ command). The ‘off’ command is acknowledged by the ECU, but apparently has no effect.

Table 3: Protocol command bytes (values in hex)

Command byte (sent to ECU)DescriptionResponse from ECU (MNE101170)
01Open fuel pump relay (stop fuel pump)01 00
02Open PTC relay (inlet manifold heater)02 00
03Open air conditioning relay03 00
08Close purge valve?08 00
09Open O2 heater relay?09 00
11Close fuel pump relay (run fuel pump)11 00
12Close PTC relay (inlet manifold heater)12 00
13Close air conditioning relay13 00
18Open purge valve?18 00
19Close O2 heater relay?19 00
1DClose Fan 1 relay? Together with command 1E, I found through protocol analysis that this has something to do with testing an electric fan, but my ECUs didn’t respond beyond the echo byte.1D
1EClose Fan 2 relay?1E
65?65 00
6D?6D 00
79Increments fuel trim setting and returns the current value.79 xx, where the second byte is the counter value
7ADecrements fuel trim setting and returns the current value.7A xx, where the second byte is the counter value
7BIncrements fuel trim setting and returns the current value.7B xx, where the second byte is the counter value
7CDecrements fuel trim setting and returns the current value.7C xx, where the second byte is the counter value
7DRequest data frame7D, followed by 32-byte data frame; see Table 4
7E?7E 08
7F?7F 05
80Request data frame80, followed by 28-byte data frame; see Table 5
82?82 09 9E 1D 00 00 60 05 FF FF
89Increments idle decay setting and returns the current value89 xx, where the second byte is the counter value
8ADecrements idle decay setting and returns the current value8A xx, where the second byte is the counter value
91Increments idle speed setting and returns the current value91 xx, where the second byte is the counter value
92Decrements idle speed setting and returns the current value92 xx, where the second byte is the counter value
93Increments ignition advance offset and returns the current value93 xx, where the second byte is the counter value
94Decrements ignition advance offset and returns the current value94 xx, where the second byte is the counter value
CB?CB 00
CCClear fault codesCC 00
CD?CD 01
D0?D0 99 00 03 03
D1?D1 41 42 4E 4D 50 30 30 33 99 00 03 03 41 42 4E 4D 50 30 30 33 99 00 03 03 41 42 4E 4D 50 30 30 33 99 00 03 03
D2?D2, followed by 02 01, 00 01, or 01 01
D3?D3, followed by 02 01, 00 02, or 01 01
E7?E7 02
E8?E8 05 26 01 00 01
ED?ED 00
EE?EE 00
EFActuate fuel injectors? (MPi?)EF 03
F0?F0 50
F3?F3 00
F4NOP / heartbeat? Sent continuously by handheld diagnostic tools to verify serial link.F4 00
F5?F5 00
F6Unknown. Disconnect or sleep command? During a bench test, the Mini SPi ECU changed its behavior after being commanded with F6; it would only echo single bytes that it received, but nothing else. For example, sending 80 would cause it to echo 80 but no data frame followed. Re-sending the init sequence of CA, 75, and D0 restored normal behavior.F6 00
F7Actuate fuel injector (SPi?)F7 03
F8Fire ignition coilF8 02
FBRequest current IAC positionFB xx, where the second byte represents the IAC position
FC?FC 00
FDOpen IAC by one step and report current positionFD xx, where the second byte represents the IAC position
FEClose IAC by one step and report current positionFE xx, where the second byte represents the IAC position
FFRequest current IAC position?

The tables below describe the known fields in the data frames that are sent by the ECU in response to commands 0x7D and 0x80, respectively. Multi-byte fields are sent in big-endian format.

Table 4: Data frame (Command 0x7D)

Byte positionField
0x00Size of data frame, including this byte
0x01Unknown
0x02Throttle angle?
0x03Unknown
0x04Sometimes documented to be air/fuel ratio, but often observed to never change from 0xFF
0x05Unknown
0x06Lambda sensor voltage, 0.5mv per LSB
0x07Lambda sensor frequency?
0x08Lambda sensor duty cycle?
0x09Lambda sensor status? 0x01 for good, any other value for no good
0x0ALoop indicator, 0 for open loop and nonzero for closed loop
0x0BLong term trim?
0x0CShort term trim, 1% per LSB
0x0DCarbon canister purge valve duty cycle?
0x0EUnknown
0x0FIdle base position
0x10Unknown
0x11Unknown
0x12Unknown
0x13Unknown
0x14Idle error?
0x15Unknown
0x16Unknown
0x17Unknown
0x18Unknown
0x19Unknown
0x1AUnknown
0x1BUnknown
0x1CUnknown
0x1DUnknown
0x1EUnknown
0x1FUnknown

Table 5: Data frame (Command 0x80)

Byte positionField
0x00Size of data frame, including this byte. This should be 0x1C (28 bytes) for the frame described here.
0x01-2Engine speed in RPM (16 bits)
0x03Coolant temperature in degrees C with +55 offset and 8-bit wrap
0x04Computed ambient temperature in degrees C with +55 offset and 8-bit wrap
0x05Intake air temperature in degrees C with +55 offset and 8-bit wrap
0x06Fuel temperature in degrees C with +55 offset and 8-bit wrap. This is not supported on the Mini SPi, and always appears as 0xFF.
0x07MAP sensor value in kilopascals
0x08Battery voltage, 0.1V per LSB (e.g. 0x7B == 12.3V)
0x09Throttle pot voltage, 0.02V per LSB. WOT should probably be close to 0xFA or 5.0V.
0x0AIdle switch. Bit 4 will be set if the throttle is closed, and it will be clear otherwise.
0x0BUnknown. Probably a bitfield. Observed as 0x24 with engine off, and 0x20 with engine running. A single sample during a fifteen minute test drive showed a value of 0x30.
0x0CPark/neutral switch. Zero is closed, nonzero is open.
0x0DFault codes. On the Mini SPi, only two bits in this location are checked:

Bit 0: Coolant temp sensor fault (Code 1)
Bit 1: Inlet air temp sensor fault (Code 2)

On the Mini SPi, only two bits in this location are checked:
Bit 1: Fuel pump circuit fault (Code 10) |
Bit 7: Throttle pot circuit fault (Code 16)

Idle air control motor position. On the Mini SPi’s A-series engine, 0 is closed, and 180 is wide open. Idle speed deviation (16 bits)
Ignition advance, 0.5 degrees per LSB with range of -24 deg (0x00) to 103.5 deg (0xFF)
Coil time, 0.002 milliseconds per LSB (16 bits)