Pages: [1]
Author Topic: Reversing Fiat ABS CAN protocol  (Read 12572 times)
woj
Hero Member
*****

Karma: +43/-3
Offline Offline

Posts: 500


« on: July 27, 2018, 01:53:22 PM »

A tougher one, I am currently stuck, and now have to take a break for two weeks from experimenting, so I leave it here to get ideas.

I am trying to reverse ABS module's CAN protocol for the sake of emulating it in a ME7.9.10 standalone setup (please don't argue with me about the sense of doing this, this is for a very special project that is not even mine). I already figured out how to bypass the immo so the body computer is not necessary at all. The ECU does work without the ABS module, but I need it for the vehicle speed, which with CAN emulation will be taken from a gearbox sensor.

So, attached are two CAN bus logs, one from ignition on, and one from running at a steady speed for a couple of seconds. The A001 messages are from the engine ECU, A006-s are from the ABS, or so I believe, I did not look into the other ones (yet). The actual wheel speed messages are clear, these are 01CA006 & 014A006, each having two wheels signal with more or less clear semantics - in each 4 bytes (one wheel) the first nibble is the cyclic counter 0..3, first bit in the second nibble is the ready bit, the rest is a leaping "wheel frequency counter" (not sure how to call it properly, but I see what it's doing).

Now, I wrote a small program that essentially replays the complete protocol for all messages A006 the way I see it's done, maintaining the frequency for each one of them (with the precision allowed by the POSIX RT library on Raspberry PI). As it is, this does not make the bench engine ECU happy at all, nothing happens and a DTC is thrown for the ABS module. So I am missing something, and I am not sure what.

Some things that I know might be off:

- identification of some sort, but my bench ECU has the actual ECU's EEPROM cloned, and the log comes from my car,

- handshakes that I do not see and I blindly send the A006 messages instead of reacting to engine ECU's requests,

- the general timing - for now I switch on the ABS emulator by hand on the Raspberry PI while I switch on the ignition on my bench ECU, (my next step will be to fix this - activate after seeing engine ECU's first message),

- I see that the 010A006 message has some variations in its data that I do not understand, and for now I fixed to constants.

I attached a snapshot of my emulation trace, the time tags are only for verifying intervals, nothing to do with actual time (absolute or from start). Maybe here are some mistakes I do not see...

PS. Yes, I know the ECU has the option to take the gearbox signal directly, but I checked, the necessary components to pass the signal from the connector pin to the CPU are not on the board. If they were, I know the KONFZ bit to enable it.
Logged
woj
Hero Member
*****

Karma: +43/-3
Offline Offline

Posts: 500


« Reply #1 on: August 14, 2018, 11:26:33 PM »

I did more experimenting and I looked deep into the ECU code, I just had to understand where the possible fault could be. In the process I finally more or less understood how ECU handles CAN communication on the low level.

The bottom line so far is: all the bits in the ECU seem to be set correctly for reception, channels are set up, ECU sends its internal messages to other components, yet it refuses to accept my emulated frames. (Or the reception code is not executed at all because of some unmet condition that I do not  see yet). They simply do not end up in the application level CAN read buffers for the given channels. On my emulating RaspberryPI I checked all I could that the messages are actually sent and have right ID, but as soon as they get sucked into the CAN interface I have to trust that they are transmitted over the bus, cannot check that they are in fact there (because I use my sniffer for the emulation, though I could probably setup a loop back of some sort, have to check that too).

So my question now is (I am still a CAN noob a bit) - what other secret information (apart from ID+DATA sent at the right baud rate) could there be in the CAN frame that makes it different from what the ECU expects. BTW, I also briefly checked if the ECU uses RTR frames, does not seem to be the case, but I am not entirely sure yet.
Logged
woj
Hero Member
*****

Karma: +43/-3
Offline Offline

Posts: 500


« Reply #2 on: August 15, 2018, 09:09:14 AM »

... I have to trust that they are transmitted over the bus, cannot check that they are in fact there (because I use my sniffer for the emulation, though I could probably setup a loop back of some sort, have to check that too).

There is no face palm picture out there to express how I now feel :/ This would have worked from the first attempt three weeks ago. I forgot to set the extended ID frame flag when sending stuff. Saw that now when dumping the actual frames transmitted to the ECU (and as it turns out no CAN loop back was necessary to log / see this either). All in all, out of this whole list of messages I posted earlier only three are needed: 14A006, 1CA006, and 210A006. The first two have ABS wheel speed data, the third one contains ASR/MSR stuff I presume, sending empty frames with cyclic counter is sufficient (and I am 80% sure this last frame can be skipped too given a proper flag mod in CWKONFZ, have to check that next). No need to sync with ECU boot more precisely than a couple of seconds either. This effectively shows the speed in the ECU and kills Uxxxx DTC code for ABS connectivity:

https://youtu.be/rhtDllVWD34

Now only to kill the Uxxxx DTC for body computer, my immo-off code mod, and I have a standalone ME7.9.10 configuration as initially stated Cheesy
Logged
woj
Hero Member
*****

Karma: +43/-3
Offline Offline

Posts: 500


« Reply #3 on: August 16, 2018, 01:50:52 PM »

Success. I managed to track back all the needed messages from ABS and Body to keep the ECU happy. For Body some of them are not really switchable through configuration bits, only DTC can be killed through class. Emulation works, ECU gets the needed data, and there are no DTCs. I will document the needed massages later, I still need to confirm one of the bits (99% sure it's the handbrake, but need to log on the car to be 100% sure).
Logged
woj
Hero Member
*****

Karma: +43/-3
Offline Offline

Posts: 500


« Reply #4 on: August 19, 2018, 01:59:34 PM »

I thought that I would also be able to include some of the immo communication stuff (request / unlock), but that will take longer and I have to get help in another thread.

But what I can say for now:

The ABS module CAN messages that the ECU expects:

ID=1CA006/14A006 (first 2 wheels and second 2 wheels) sent every 10ms, 8 bytes of data in each message, 2 times 4 bytes for one wheel

The 4 bytes for each wheel: byte0 - bits #7-#4 - cyclic counter 0..3, bit #3 - ready bit (set to 1), the rest of byte0 together with bytes1, 2, 3 is the impulse counter (with yet unclear to me scale, sorry) for the wheel that wraps at 0x04000000. Example messages:

01CA006   [8]  0B 80 92 25 0A F3 81 91
014A006   [8]  0B B5 2D 87 0B 2E 28 C9

01CA006   [8]  1B 81 A9 31 1A F4 98 86
014A006   [8]  1B B6 44 5B 1B 2F 3F B7

The second message that the ECU expects from the ABS module is (I guess) the ASR/MSR info, the samples I got are of this pattern:

210A006   [8]  FF 07 FF 00 00 00 00 00

where the second data byte is a 00..0F cyclic counter. The reception of this message can be switched off by turning off bits #15 and #6 at the same time in CWKONFZ1. If you want to send it nevertheless, do it every 10ms.

Then from the body computer the ECU expects the following:

every 100ms: ID=A18A000 with 8 bytes of data, where only these matter for the ECU:

byte1.1 - status of the power steering mode / sport mode button
byte3 - ambient temperature with conversion (x+16)*2/3 to get the normal ECU temperature variable that converts as all other short range ones (x*3/4 - 48).
byte5 - fuel level in %, values 0..100 decimal
byte6.5 - handbrake status (1 on, 0 off)

On some ECUs with some CWs different and where there are both power steering button and sport mode button things are a bit different, namely byte4-bits3-5 indicate mode number, but I do not know how this translates to practice (dashboard button arrangement). Also byte4.0 is fuel level indicator error flag, leave at 0. The frame has other information, but the ECU does not care. This message cannot be cleanly disabled.

The second body computer message is ID=810A000 with 4 bytes of data, sent every 10ms. byte1 has some flags, all of the time I see this byte it is 0xFF (ECU does read some of these bits). The third byte2 is a 0..3 cyclic counter on bits 2 and 3, and bits 5 and 6 are respectively light brake press and hard brake press (the latter has the former on too). Sample frames:

0810A000   [4]  00 FF 60 00
0810A000   [4]  00 FF 64 00
0810A000   [4]  00 FF 68 00

This message cannot be cleanly disabled either.

The last body computer message is ID=C24A000 sent every 2 seconds, with only the first byte0 indicating wheel circumference (with unknown to me conversion). The reception of this message can be killed by turning of CWKONFZ1.5, in which case a default value from the flash will be used.

All this keeps the ECU happy about ABS and body modules communication, no DTCs.

Then, during the initialisation the ECU exchanges two messages with the body computer to sort out the immo, ECU sends ID=010A001 with 7 bytes (0 - request code, 4 bytes of crypto-like code, 2 bytes of some other stuff (checksum?)), the body replies with ID=010A000 with 7 data bytes, where the first one is the result/status. Don't yet know more. So far I killed the immo brutally, trying to dissect the code for it now.
« Last Edit: August 19, 2018, 02:05:52 PM by woj » Logged
370rx
Jr. Member
**

Karma: +0/-0
Offline Offline

Posts: 39


« Reply #5 on: October 03, 2018, 06:47:51 AM »

Is obtained when the button "CITY" in the ECU to recalibrate to the SPORT button?
Logged
woj
Hero Member
*****

Karma: +43/-3
Offline Offline

Posts: 500


« Reply #6 on: October 04, 2018, 02:29:03 PM »

The sport mode is achieved in two different ways on these ECUs, depending on the some CW configuration bits in the Flash. Either a proper sport button, or if absent, the CITY power steering mode triggers SPORT mode too. But then you also need to tune the overboost maps for it to be effective in any way.
Logged
370rx
Jr. Member
**

Karma: +0/-0
Offline Offline

Posts: 39


« Reply #7 on: October 05, 2018, 01:01:54 AM »

I have a Fiat Bravo and have a city button that you need to activate the button sports to do in the firmware?   what card is responsible for sports button, MDMAXNMOT MDMAXNMOB? Remind me please, I read somewhere, can't remember which cards overboost responsible for the sport mode?
Logged
adamsanta
Newbie
*

Karma: +0/-0
Offline Offline

Posts: 1


« Reply #8 on: May 10, 2024, 08:05:11 AM »

I thought that I would also be able to include some of the immo communication stuff (request / unlock), but that will take longer and I have to get help in another thread.

But what I can say for now:

The ABS module CAN messages that the ECU expects:

ID=1CA006/14A006 (first 2 wheels and second 2 wheels) sent every 10ms, 8 bytes of data in each message, 2 times 4 bytes for one wheel

The 4 bytes for each wheel: byte0 - bits #7-#4 - cyclic counter 0..3, bit #3 - ready bit (set to 1), the rest of byte0 together with bytes1, 2, 3 is the impulse counter (with yet unclear to me scale, sorry) for the wheel that wraps at 0x04000000. Example messages:

01CA006   [8]  0B 80 92 25 0A F3 81 91
014A006   [8]  0B B5 2D 87 0B 2E 28 C9

01CA006   [8]  1B 81 A9 31 1A F4 98 86
014A006   [8]  1B B6 44 5B 1B 2F 3F B7

The second message that the ECU expects from the ABS module is (I guess) the ASR/MSR info, the samples I got are of this pattern:

210A006   [8]  FF 07 FF 00 00 00 00 00

where the second data byte is a 00..0F cyclic counter. The reception of this message can be switched off by turning off bits #15 and #6 at the same time in CWKONFZ1. If you want to send it nevertheless, do it every 10ms.

Then from the body computer the ECU expects the following:

every 100ms: ID=A18A000 with 8 bytes of data, where only these matter for the ECU:

byte1.1 - status of the power steering mode / sport mode button
byte3 - ambient temperature with conversion (x+16)*2/3 to get the normal ECU temperature variable that converts as all other short range ones (x*3/4 - 48).
byte5 - fuel level in %, values 0..100 decimal
byte6.5 - handbrake status (1 on, 0 off)

On some ECUs with some CWs different and where there are both power steering button and sport mode button things are a bit different, namely byte4-bits3-5 indicate mode number, but I do not know how this translates to practice (dashboard button arrangement). Also byte4.0 is fuel level indicator error flag, leave at 0. The frame has other information, but the ECU does not care. This message cannot be cleanly disabled.

The second body computer message is ID=810A000 with 4 bytes of data, sent every 10ms. byte1 has some flags, all of the time I see this byte it is 0xFF (ECU does read some of these bits). The third byte2 is a 0..3 cyclic counter on bits 2 and 3, and bits 5 and 6 are respectively light brake press and hard brake press (the latter has the former on too). Sample frames:

0810A000   [4]  00 FF 60 00
0810A000   [4]  00 FF 64 00
0810A000   [4]  00 FF 68 00

This message cannot be cleanly disabled either.

The last body computer message is ID=C24A000 sent every 2 seconds, with only the first byte0 indicating wheel circumference (with unknown to me conversion). The reception of this message can be killed by turning of CWKONFZ1.5, in which case a default value from the flash will be used.

All this keeps the ECU happy about ABS and body modules communication, no DTCs.

Then, during the initialisation the ECU exchanges two messages with the body computer to sort out the immo, ECU sends ID=010A001 with 7 bytes (0 - request code, 4 bytes of crypto-like code, 2 bytes of some other stuff (checksum?)), the body replies with ID=010A000 with 7 data bytes, where the first one is the result/status. Don't yet know more. So far I killed the immo brutally, trying to dissect the code for it now.

Hi woj,
Did you find more information about the handshake between the ECU and the body computer (0010A001-0010A00) ? I am trying to generate the correct answer from the body computer for the ECU.
Thanks.
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Page created in 0.021 seconds with 17 queries. (Pretty URLs adds 0s, 0q)