Originally posted by karter16
View Post
Announcement
Collapse
No announcement yet.
CSL '0401' Program Binary Disassembly Notes
Collapse
X
-
Well I hate to think how many hours I've spent on this in the last 9 months but this evening I figured out and named the last of the 138 CSL specific parameters.
The last one was the parameter that defines how long the sport button needs to be held down for to trigger displaying the oil level sensor readout on the dash. The function that does this is schalt_m_st_calc (Master CPU "switches" status byte). The function runs every 10ms therefore a hex value of 0x64 (decimal 100) means that by default the button needs to be held down for 1 second.
I might have names for all 138 parameters but the job doesn't finish here. I'm still in the middle of tidying up, refining and aligning names. Once that's done I then need to add/refine the descriptions of the parameters (Edit: this is the most important bit. Over the last 9 months I've got pretty good at understanding obscure German abbreviations for technical terms, but I need to make sure this ends up being something others can reference and use without the backstory), configure conversion factors, etc.
Nevertheless this is a pretty big milestone and I have to say I've managed to get an awful lot further than I was expecting when I embarked on this.Last edited by karter16; 08-02-2025, 12:02 AM.
- Likes 10
Leave a comment:
-
Originally posted by karter16 View PostI've now figured out 128 of the 138 parameters specific to the CSL. You'll see that my naming conventions aren't entirely consistent, but once I've figured out the last 10 and have a complete view I can then align the naming accordingly.Last edited by ac427; 07-29-2025, 10:52 AM.
Leave a comment:
-
I've now figured out 128 of the 138 parameters specific to the CSL. You'll see that my naming conventions aren't entirely consistent, but once I've figured out the last 10 and have a complete view I can then align the naming accordingly.
Last edited by karter16; 07-25-2025, 02:41 PM.
- Likes 9
Leave a comment:
-
Came across the OBD2 readiness monitor functions today:
This function passes a pointer to obd_check_monitor(). The pointer points to an array of bytes which list the DTCs that are applicable to the monitor in question. The DTCs are evaluated against stored status and the monitor status (ready or not) is returned.
- Likes 3
Leave a comment:
-
Awesome thanks for that - I haven't had a chance to go through the log you sent in detail yet, but what you've posted there makes sense. The frame is exactly the same for either bank, just bank 1 sent on 0x700 and bank 2 on 0x701.
Will be super interesting to see what you get if you can cause some knock. As I mentioned I *think* that byte 1 is the amount of retardation being applied for the cylinder - will be interested to see what you get.
- Likes 1
Leave a comment:
-
So it looks like the 0x03+ message format is the same for both IDs 0x700 and 0x701
For Byte 0
bits 0-2: cylinder ID (0x700 only reports 001, 010, 011 and 0x700 only reports 100, 101, 110 as expected)
bit 3: no function (for MSS54/HP, this is probably used in the V8 M5 though to ID cylinder 8)
bit 4: knock detected (1 for knock detected)
bit 5: no function identified yet. Could be related to bit 4 with a type of knock detection state.
bits 6 and 7: some sort of evaluation state. So far I only see values of 11 and 00, where the transition happens after cranking the engine. Probably ‘engine running’ or something similar.
I have a datalog recorded that I’ll need to parse tonight to evaluate the other Bytes.
I’ve also flashed a new file to my car with some extra ignition advance to see if I can trip some knock.Last edited by Bry5on; 07-17-2025, 12:24 PM.
- Likes 1
Leave a comment:
-
Originally posted by ac427 View Post
Is there likely to be other information that maybe enabled for broadcast on the CAN bus, already in the 0401 code?
- Likes 1
Leave a comment:
-
Originally posted by Chris_de View PostSomeone in the old forum already found the message that could be sent on the smg can bus. But detailed information wasn’t published by the time.
- Likes 1
Leave a comment:
-
Originally posted by karter16 View PostA few weeks ago Bry5on and I briefly discussed that it would be useful, for the purposes of tuning, to be able to broadcast and log knock data over CAN as it requires a per-segment data rate which far surpasses DS2. It turns out that BMW's engineers thought this was a good idea too!
In working through all of the CAN functions, last weekend I uncovered that the purpose of ARBID's 0x700 and 0x701 is to broadcast pre-constructed frames from the Knock Manager module. The messages are turned off by default in the 0401 partial, however various configurations can be enabled by setting K_KA_CAN_AUS.
With nam3forum being down at the time I excitedly fired off an email to Bryson and he was able to quickly check that he could receive messages, along with validating the contents of the messages. My original interpretation based on having quickly looked at it was that ARBID 0x700 was for bank 1 and ARBID 0x701 was for bank 2. What Bryson found from testing was that all cylinders were being broadcast on 0x700. Further investigation of the code reveals that 0x701 appears to only be used in certain configurations (Bryson will test this and confirm back).
Exciting to have uncovered this and very useful to have access to these messages for tuning. Presumably these messages are a leftover from when BMW's engineers were tuning the S54.
Here's what we currently have (will continue to amend and update as we uncover and test more):
Leave a comment:
-
Someone in the old forum already found the message that could be sent on the smg can bus. But detailed information wasn’t published by the time.
Leave a comment:
-
A few weeks ago Bry5on and I briefly discussed that it would be useful, for the purposes of tuning, to be able to broadcast and log knock data over CAN as it requires a per-segment data rate which far surpasses DS2. It turns out that BMW's engineers thought this was a good idea too!
In working through all of the CAN functions, last weekend I uncovered that the purpose of ARBID's 0x700 and 0x701 is to broadcast pre-constructed frames from the Knock Manager module. The messages are turned off by default in the 0401 partial, however various configurations can be enabled by setting K_KA_CAN_AUS.
With nam3forum being down at the time I excitedly fired off an email to Bryson and he was able to quickly check that he could receive messages, along with validating the contents of the messages. My original interpretation based on having quickly looked at it was that ARBID 0x700 was for bank 1 and ARBID 0x701 was for bank 2. What Bryson found from testing was that all cylinders were being broadcast on 0x700. Further investigation of the code reveals that 0x701 appears to only be used in certain configurations (Bryson will test this and confirm back).
Exciting to have uncovered this and very useful to have access to these messages for tuning. Presumably these messages are a leftover from when BMW's engineers were tuning the S54.
Here's what we currently have (will continue to amend and update as we uncover and test more):
- Likes 5
Leave a comment:
-
Originally posted by Bry5on View PostHmm, the idea sounds awesome but personally I’d stick with static settings. A new can of worms sounds a little more scary.Originally posted by heinzboehmer View PostI was thinking about this today and I have to agree with Bryson.
I'll take the opportunity to review this work in a couple of days once it's out of my mind and I can look at it again with fresh eyes to see if I'm missing anything.
#1: Define new parameter space variables k_k16_can_cfg, and 64 bytes to store pointers for the 16 bytes of CAN data across the two messages.
k_k16_can_cfg: bit 0 = 7d0 enabled, bit 1 = 7d1 enabled.
The below are the configurable addresses of the RAM variables to copy into the CAN messages
k_k16_can_7d0_b0: ulong at 0x8ef04
k_k16_can_7d0_b1: ulong at 0x8ef08
k_k16_can_7d0_b2: ulong at 0x8ef0c
k_k16_can_7d0_b3: ulong at 0x8ef10
k_k16_can_7d0_b4: ulong at 0x8ef14
k_k16_can_7d0_b5: ulong at 0x8ef18
k_k16_can_7d0_b6: ulong at 0x8ef1c
k_k16_can_7d0_b7: ulong at 0x8ef20
k_k16_can_7d1_b0: ulong at 0x8ef24
k_k16_can_7d1_b1: ulong at 0x8ef28
k_k16_can_7d1_b2: ulong at 0x8ef2c
k_k16_can_7d1_b3: ulong at 0x8ef30
k_k16_can_7d1_b4: ulong at 0x8ef34
k_k16_can_7d1_b5: ulong at 0x8ef38
k_k16_can_7d1_b6: ulong at 0x8ef3c
k_k16_can_7d1_b7: ulong at 0x8ef40
#2: Define new RAM variable k16_can_st (0x00ffec1e) to store the runtime status of the two messages (e.g. they might be enabled in parameter space but disabled by sanity checks in k16_can_init())
k16_can_st: byte
This is our status byte, it is driven from k_k16_can_cfg, but is then modified based on checks that k_k16_can_cfg doesn't equal 0xff (e.g. k16 tune file is not loaded) and is also modified based on the result of the configuration validation checks.
#3: Modify the can_a_slot_cfg_table (0x3cbe8) to replace 771 and 62F with the correct config for 7D0 and 7D1.
#4: Modify the task_10ms function (0x12e9a) to call k16_can_tx_messages() a new version of can_tx_messages() which has extra logic for optionally sending the new messages.
#5: create the new k16_can_tx_messages() function
This modified function includes the 2x new CAN messages, but only if they are enabled and the configuration has passed validation.
#6: create the new k16_can_tx_7d0() function
The handler for 7D0. It looks up each address in the configuration field, then gets the value of the memory location pointed to (e.g. the RAM variable) and pushes the value to the appropriate byte of the CAN message.
#7: create the new k16_can_tx_7d1() function
The handler for 7D1 - works on the same principle as 7D0.
#8: modify the init_cpu function to call an additional k16_init() function
We need to run our k16_can_init() function once on start up to set k16_can_st, and do the validation of the config, etc. The easiest way to do this is to replace the call to an existing function with a call out to a new function that call's both the original function and the new k16_can_init() function.
#9: create the new k16_init() function at 0x3f8a0
Call the original function call we replaced, plus our new k16_can_init() function.
#10: create the new k16_can_init() function
And here's where k_k16_can_cfg is loaded and the configuration of each memory location is validated to ensure it is within range. Any situation which is not valid results in the entire CAN message being disabled.
As I said I'll come back to this to do more logic checking and bug hunting when I have a fresh mind. Looking forward to getting my gauge.s and getting setup so I can play round with this!Last edited by karter16; 07-11-2025, 03:34 AM.
- Likes 3
Leave a comment:
-
Quick update - I've now identified 42 of the CAN-related functions, there's only a few more to go.
I've got more work to do on this and some more to understand, but should be able to get to the point of documenting this pretty-much in full by the time I'm done.
- Likes 4
Leave a comment:
-
Originally posted by karter16 View PostYes this was by far the biggest issue in my mind when I first thought about this. The fact that the 68k's RAM is byte addressable though vastly simplifies this issue.
If there's nothing in the DPR or the RAM that might make things misbehave (not sure why there would be, but I haven't actually looked at the code), then I agree than validating based on address ranges is a viable option.
Don't get me wrong, I'm all for the generalized solution. I just think it's significantly more work to get right.
- Likes 1
Leave a comment:
Leave a comment: