Bendix Jeep 4.0L ECU Datastream

Here is my reverse engineering work on the Bendix 4.0L Electronic Control Unit found in 87-90 Renix Jeeps. This self contained unit is in charge of running the engines Renix Multi-Point Fuel Injection System as well as other engine Sub-Systems. The ECUs data stream output is available which we can use for datalogging and diagnostics.

TX output is found on Pin C12 of the ECU which connects to Pin D2-1 in the 15 pin Renix Diagnostic Adapter found in the engine bay. This is an open collector output circuit to vehicle ground, so the Receiver pulls the line high and the ECU will pull the line low to transmit. This gives us an inverted signal that will need to be flipped to be read with standard UART.

Data Protocol:

This ECU unit uses a standard Bendix Data Protocol which is as follows:
– Protocol: UART, Inverted Logic
– Baud: 62,500
– Frame Length: 33 Bytes
– Frame Start: value 0 is sent
– Frame End: value 255 is sent
– Special Case: data bytes must send duplicate 255 value to differentiate from Frame End. Duplicate value must be discarded to maintain proper framing.

Data Framing

Byte OrderReadingMathDump
Start Byte
Byte 0Program VersionHEX
B0 = old program
B1 = new program
Byte 1Vehicle CalibrationHEX
Bit 2, 7
Byte 2PROM 3HEX63
Byte 3MAP Sensor
# / 51 = [0 – 5V]
# / 9.13 + 3.1 = [3.1 – 31″hg]
Byte 4CTS Sensor# * 1.125 – 40 = [-40 – 247F]110
Byte 5IAT Sensor# * 1.125 – 40 = [-40 – 247F]106
Byte 6Battery Voltage# / 16.24 = [0 to 15.7V]222
Byte 7o2 Sensor# / 51.2 = [0 – 4.98V]255
Byte 8RPM Low Byte20,000,000 / # = [20,000 – 305]90
Byte 9RPM High byte16 bit Number = (#9, #8)92
Byte 10PROM 5HEX253
Byte 11PROM 4
Injector Open Flags
Bits 2 – 7
Byte 12TPS Sensor# / 51.2 = [0 – 4.98V]
# / 2.55 = [0 – 100%]
Byte 13Spark Advance ºBTDCDEC15
Byte 14M1? Bit Values0
Byte 15M2? Offset related to CTS110
Byte 16Baro Pressure

Manifold Vacuum
# / 51.2 = [0 – 4.98V]
# / 9.13 + 3.1 [3.1 – 31″hg]
Baro – Byte 3
Byte 17M3? Engine Bit Values
Engine Run Flag?

Bit 2
Byte 18Loop Status
EGR Solenoid
Exhaust Mixture
Bit 1, 6
Bit 3
Bit 7
Byte 19Injector Pulse Width# * 0.128 [0 – 32.6ms]100
Byte 20M4? Possibly Error Flags
CTS Simulation Mode

Bit 1
Byte 21Throttle Switch
Distributor Sync Signal Copy
Bit 1, 3
Bit 4
Byte 22Spark Adv Knock Mask
Knock Detect
Spark Retard
DEC (Bit 0 – 6 ONLY)
Bit 7
Knock Mask – Byte 13
Byte 23Cold Enrichment Offset# * 0.128 [0 – 32.6ms]39
Byte 24Short Term Fuel TrimDEC128
Byte 25M7? Offset related to IAT116
Byte 26Long Term Fuel TrimDEC160
Byte 27Knock SensorDEC0
Byte 28M8? Possibly Error Flags0
Byte 29Distributor Sync Signal
Starter Signal
A/C Switch
A/C Request
NSS Drive Gear
Bit 2
Bit 4
Bit 5
Bit 6
Bit 7
Byte 30PROM 6
Output Error Flags
Bits 0, 2 – 6
Stop Byte255

– Most of the Math was Reverse Engineered from the MT2500 1099 Cartridge
– Mystery Bytes are marked with an M#?, these are not listed on tested scan tools

Bit Logic Breakdowns

” ? “ = Unknown Values that have been observed to change
“1 or 0” = Unknown Values that have not been observed to change, normal Value shown
– “(Letter/Numbers)” = Values that have been confirmed to corrosponding ECU Pin

Bit 000
Bit 100
Bit 2Old ProgramNew Program
Bit 300
Bit 411
Bit 500
Bit 600
Bit 7Auto Trans ProgramManual Trans Program

These are the only values I have noticed so far but seem to align with other tested units

Byte 11FalseTrue
Bit 000
Bit 111
Bit 2Injector 1 OpenOK
Bit 3Injector 5 OpenOK
Bit 4Injector 3 OpenOK
Bit 5Injector 6 OpenOK
Bit 6Injector 2 OpenOK
Bit 7Injector 4 OpenOK

– These seem to be Power-On Diagnostic Faults that take place when KO-EF
– Have not tested if this resets during cranking, but key cycling after fix will
– If the Power On Diagnostic Tests were not run, this and other extra PROM bytes will read 255
– FF: The Injectors are listed in firing order instead of sequentially

Bit 0Load Idle Comp Off?Load Idle Comp On?NSS based load flag?
Bit 1A/C Idle Comp Off ?A/C Idle Comp On ?true w/ 29 b5 & b6
Bit 2– ?A/C Clutch Turning Off?pulses on B1 falling
Bit 3– ?A/C Clutch Turning On?pulses on B1 rising
Bit 4IAC not MovingIAC Movingsum of 5 & 6
Bit 5IAC not OpeningIAC Opening
Bit 6IAC not ClosingIAC Closing
Bit 700

I consider this Mystery Byte 1 as it is undocumented
– Bit 1 generally follows the NSS switch, but tends to be true sometimes even when in neutral or park. Not entirely sure what it shows beyond just transmission load idle compensation.
– Bit 2 generally follows the A/C Request gauge, but only seems to update state when TPS reads closed. Otherwise it will stick at last state when driving regardless of A/C Select or Request states.
– Bit 4, 5, & 6 show IAC valve operation, stepper motor command and direction
– Bit 4 is sum of 5 and 6

– Number of actual stepper pulses does not align to the amount of trues, generally showing more true frames then actual pulses. Inferred that IAC is only active when true.
– An up/down counter divided by 10 roughly equals actual IAC revolutions, but there is no easy way to track when fast, continuous pulses are sent.

Bit 000
Bit 100
Bit 2Engine Off False?Engine Off True?
Bit 3??
Bit 4??
Bit 5Closed Loop Not Attempted?Closed Loop Attempted?
Bit 6ECU Crank Mode FalseECU Crank Mode True
Bit 700

– I consider this Mystery Byte 3 as it is undocumented
– Seems to be different engine or ECU Mode  flags
– During crank no start, Bit 2 and 3 are steady True

– Bit 4 is similarish to EGR 18 Bit 3, shows true when MAP is maxed on bench
– Bit 6 is true when cranking, but only after data rate picks up. False after 500+ RPM. Maybe Engine Cranking Mode?

Bit 0??
Bit 1Bit 6Decel LP
Bit 2??
Bit 3EGR OffEGR On
Bit 4??
Bit 5??
Bit 6Open LPClosed LP
Bit 7LeanRich

– Decel takes priority over Bit 6
– Bit 2 closely follows Bit 7

Bit 000
Bit 1CTS Not Detected
Bit 200
Bit 300
Bit 400
Bit 500
Bit 600
Bit 700

– Mystery Byte 4, Possible Error Flags
– When bench probing with bare minimum pins, Bit 1 is true.

Bit 0??
Bit 1TPS PartialTPS WOT
Bit 2Sync Signal Duplicate +Sync Signal Duplicate –
Bit 3TPS PartialTPS Closed
Bit 4Starter Off DuplicateStarter On Duplicate
Bit 5??
Bit 6??
Bit 700

– Partial takes priority if Bit 1 and 3 are equal, usually in false state
– Similar to Byte 29 when rpm is detected except Bit 6 is true
– Bit 2 is a duplicate* of Byte 29, Bit 2 when Engine is Running (*See FF)

Bit 000
Bit 100
Bit 200
Bit 300
Bit 400
Bit 500
Bit 600
Bit 7??

– Mystery Byte 8, Possible Error Flags
– When bench probing with bare minimum pins, Bit 7 is true.

Bit 000
Bit 111
Bit 2C5 Sync Signal LowC5 Sync Signal High
Bit 3TPS PartialTPS Closed
Bit 4C3 Starter Signal LowC3 Starter Signal High
Bit 5D2 A/C Select OffD2 A/C Select On
Bit 6C2 A/C Request NoC2 A/C Request Yes
Bit 7C4 NSS ParkC4 NSS Drive

– Bench testing confirms labeled pinouts, will change even with engine off
– Bits 2, 3, and 4 nearly mirror the same bits from Byte 21
– During crank no start, Bit 1 and 2 will alternate in a Sync pattern, but byte 21 does not move
– Bit 3 is active when RPM is detected, has instant pulses while also following Byte 21

Bit 0ICM FaultOK
Bit 111
Bit 2EGR Solenoid FaultOK
Bit 30Fuel Pump Relay?
Bit 4B+ Latch Relay FaultOK
Bit 5o2 Heater Relay FaultOK
Bit 6AC Relay FaultOK
Bit 711

– PROM 6, Output / Relay Error Flags
– When the Fuel Pump Relay is unplugged, ECU doesn’t report voltage and Prom 4,5,6 read FF
– Prom Numbers 4 and greater all read FF on Bench Test. Some sort of Power On Test Failure?

Other Failure Notes

  • MAP Disconnected: MAP reads 0, Baro reads 0
  • CTS Disconnected: CTS copies IAT at start, M2 reads 255, M4 Bit 2 reads true
  • IAT Disconnected: IAT reads 255, M7 reads 255
  • TPS Disconnected: TPS reads 0, o2 reads 0 (See FF)

Fun Facts

  • The data stream is not sent in a single packet, but rather it is sent each byte individually. The byte spacing is closely related to engine rpm so it is possible there are less available loops to send a byte when it’s trying to process data faster?
  • On top of this weird delay, the output stream is also sent “Live.” Instead of the computer taking a snapshot of all readings and loading them into a buffer to be sent out, each byte is sampled right before it is sent for minimum lag time. But this means that longer byte gaps will cause data to be farther “out of sync” with previously read in bytes of the same data frame.
  • If CTS is not detected, it will mirror the IAT reading until start up, then slowly increase based on Engine Revolutions
  • With Engine Off, o2 reading is instead approximately scaled to TPS reading from 0 – 7
  • The RPM reading is actually the amount of time between 2 spark pulses in Microseconds. This can be converted like so: 1,000,000 * 60 / Pulses per Rotation(Cyl/2) / Pulse Gap = RPM. 
  • The reported Battery Voltage is read from Injector Feed C11/D10 which comes from the Fuel Pump Relay. This explains why it shows 0v with engine off.

ECU Pinout Breakdown

Connector CavityECU CircuitData Stream Relation
A1Injector 3
A2Injector 6
A3Injector 2
A4Injector 4
A5Fuel Pump Relay Ground
A7Oxygen Relay Ground
A8Upshift Lamp – Manual
A9B+ Latch Relay Ground
A10EGR Control
A12A/C Clutch Control
Connector CavityECU CircuitData Stream Relation
B1Injector 1
B2Injector 5
B3AIS Motor (A)
B4AIS Motor (D)
B5AIS Motor (C)
B6AIS Motor (B)
B10B+ Latched
Connector CavityECU CircuitData Stream Relation
C1Engine Speed Input
C2A/C RequestByte 29, Bit 6
C3Start Signal (+)Byte 29, Bit 4
C4Start Signal (-)Byte 29, Bit 7
C5Sync SignalByte 29, Bit 2
C6MAP InputByte 3
C7TPS InputByte 12
C8Air Temp InputByte 5
C10Coolant Temp InputByte 4
C11Injector FeedByte 6
C12TX Serial Data Output
C14MAP 5 Volt Supply
C15TPS 5 Volt Supply
C16Sync 7.1 Volt Supply
Connector CavityECU CircuitData Stream Relation
D1Engine Speed Input
D2A/C SelectByte 29, Bit 5
D3Sensor Ground
D8Knock Sensor Ground
D9Oxygen Sensor InputByte 7
D10Injector FeedByte 6
D11RX Serial Data Input
D13Timing OutputBytes 9 , 8
D16Knock Sensor InputByte 27

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.