Announcement

Collapse
No announcement yet.

CSL '0401' Program Binary Disassembly Notes

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • karter16
    replied
    In addition to adding another CAN frame I've also been having a think about how to make this feature a bit more generic.

    We have limited frames we can use, and without a major rewrite to dynamically swap frames that is quite frankly beyond my capability and current understanding, that isn't going to change. I can already think of enough things that would be interesting to log (particularly during tuning, etc.) that they won't all fit into the available frames at once. Likewise I'm sure others will encounter similar situations.

    I mentioned previously that I thought it would be possible to create the ability to provide for some degree of configuration which would mean 1 standard program binary with the ability to somewhat configure the messages via the partial binary. Having made 0x7D0 work and having done some more thinking around this I'm pretty sure that the following would be fairly easy - it would look something like this:

    Master Program ROM
    • Custom Program ROM with modified CAN table repurposing unused messages (propose using 0x701 as the current version does as well as 0x62F which is another safe option for the E46)
    • Modify existing handler for 0x7D0 to genericise functionality
    • Create new handler for "0x7D1" with generic functionality
    • Insert call into CAN_Send_DME_ARBIDs_karter16 to send 0x7D1 as well and wrap both in conditional logic based on k_can_karter16_cfg

    Master Tune Binary
    • New parameters defined as follows:
      • k_can_karter16_cfg (bitfield to enable/disable 0x7D0 and 0x7D1)
      • An array of 8 32bit values which hold the addresses of the 8 bytes to be mapped to the 0x7D0 message
      • An array of 8 32bit values which hold the addresses of the 8 bytes to be mapped to the 0x7D1 message

    And I think it's as simple as that. I initially was thinking that there would need to be logic to split up 16/32 bit values where required, but given the 68k is byte addressed it's actually very simple. If you want to send the word (2 bytes) at 0x1000 for example it's just two move byte instructions the first referencing 0x1000 and the second referencing 0x1001.

    With the disassembly work that's been done it will be possible to make available a table of all valid variables in the Master + dual-ported-ram which users can then choose from themselves. Any variables from slave that aren't on the DPR would have to be inserted into the DPR (if there's any space left, I don't actually know yet) as a change to the Slave Program ROM, but again this could be done as a generic program rom change.

    Edit: This approach also means that the tune binary remains backwards compatible with the standard 0401 program ROM. e.g. you could flash back to the original ROM without having to also change your tune binary. Likewise running the custom ROM with a standard 0401 tune would also be supported - 0x7D0 and 0x7D1 would simply be disabled.


    What are the downsides of this
    • It unfortunately doesn't solve the problem of restoring the standard functionality of 0x771 and 0x62F when the cfg parameter is disabled. I want to think more about whether this is possible.
    • While the benefit is the ability to craft your own CAN messages, it means that everyone's definition of what 0x7D0 and 0x7D1 are will be different. I'm not sure whether this is a potential negative when it comes to sharing information, configs, etc.
    • I'm still vaguely bothered that 0x771 might be some sort of required mechanism for some sort of BMW diagnostic process. I admit it seems unlikely, but I'm very wary of screwing up anything for anyone.

    Anyway - keen for feedback on this idea/proposal
    Last edited by karter16; 06-30-2025, 07:11 PM.

    Leave a comment:


  • heinzboehmer
    replied
    Originally posted by karter16 View Post
    I selected this one to repurpose as its handler pointer was to 0x00000000. But I've been thinking about that and I can't completely rule out that it's an intentional mechanism to allow reset of the processor via CAN. It seems a bit crude and would be a crash to a hard reset without any preparation, but maybe...
    Man, that would be a pretty crazy way to reset the DME!

    Now I want to try and crash it over CAN

    Leave a comment:


  • karter16
    replied
    Originally posted by Bry5on View Post
    Datalog shows only these:
    Click image for larger version Name:	IMG_5960.png Views:	0 Size:	27.8 KB ID:	310258
    Thanks very much for this. I've been doing some more investigation. I have more work to do to understand more but have figured out the below points:
    • There is a second set of 15 CAN frames which are mapped to a separate region in memory
    • There is a second set of read/write handlers
    • These read-write handlers are more complex and appear to be built to manage the sending/receipt of a series of messages over CAN
    • I'm not sure yet but it's possible that this is support for ISO 15765-2 (ISO-TP/CAN-TP) or similar for transmission of error codes and diagnostics over CAN
    • This functionality is present for both the Master (main CAN) and Slave (SMG CAN)

    I've also been trying to figure out CAN ID 0x770 as it seems to be paired in some way with CAN ID 0x771 (which is what I've repurposed for 0x7D0) I selected this one to repurpose as its handler pointer was to 0x00000000. But I've been thinking about that and I can't completely rule out that it's an intentional mechanism to allow reset of the processor via CAN. It seems a bit crude and would be a crash to a hard reset without any preparation, but maybe...


    Anyway. In terms of the more immediate question of a second CAN message. I'm pretty comfortable that we can use the slot for 0x62F (read) as this message is only ever received for a chassis configuration that isn't the E46.
    Last edited by karter16; 06-30-2025, 03:05 PM.

    Leave a comment:


  • Bry5on
    replied
    Datalog shows only these:
    Click image for larger version  Name:	IMG_5960.png Views:	0 Size:	27.8 KB ID:	310258
    Attached Files

    Leave a comment:


  • karter16
    replied
    Originally posted by Bry5on View Post
    What are the other IDs? We can log them to see if data exists, although neither of us are SMG.
    That would be great thank you! - I think the most likely ones are:

    0x62F
    0x700
    0x701
    0x770
    0x513

    Leave a comment:


  • Bry5on
    replied
    What are the other IDs? We can log them to see if data exists, although neither of us are SMG.

    Leave a comment:


  • karter16
    replied
    Originally posted by heinzboehmer View Post
    ...which reminds me, karter16 any interest in adding a second CAN message with throttle pedal position? Having a reference of what you're telling the car to do with your foot is really useful. The ITBs and idle air valve on this engine (and some other stuff like DSC) make it hard to interpret the TPS logs. You never really know for certain if the throttles opened as much as they did because that's what you wanted or because the DME decided that that was how much they were gonna open.
    Yes! I've actually already been planning to look at adding a second message. I think it's going to be a bit harder as, unless we can conclusively prove one of the 14 other messages is actually not used then there isn't a spot for it, which would mean additional work. I have been doing more disassembly work this weekend around the wider behavior of the CAN system to understand what options there might be.

    Leave a comment:


  • heinzboehmer
    replied
    Custom DME FW is working great! Just ran through a session of VE tuning on my car and it was so nice to be able to pull all that info over CAN.

    Feel free to peruse: http://datazap.me/u/heinzboehmer/csl...?log=0&data=15

    Everything in that log is from CAN, except for throttle pedal position and the two brake pressures.


    ...which reminds me, karter16 any interest in adding a second CAN message with throttle pedal position? Having a reference of what you're telling the car to do with your foot is really useful. The ITBs and idle air valve on this engine (and some other stuff like DSC) make it hard to interpret the TPS logs. You never really know for certain if the throttles opened as much as they did because that's what you wanted or because the DME decided that that was how much they were gonna open.

    Leave a comment:


  • karter16
    replied
    Okay here's one for those who are concerned about heat-soak and the location of the IAT sensor.

    The CSL software has additional code in the function that calculates TAN (intake air temperature):

    Click image for larger version

Name:	Screenshot 2025-06-28 at 7.44.01 AM.png
Views:	295
Size:	127.9 KB
ID:	310119

    Lines 16 to 26 are not found in the standard euro software. These lines are calculating a version of TAN specifically for the purpose of being used in the CSL's calculation of air mass, which in turn is used in the calculation of final RF as we've seen previously.

    k_tan_m_cfg is set to 1 in the 0401 partial:

    Click image for larger version

Name:	Screenshot 2025-06-28 at 7.45.30 AM.png
Views:	322
Size:	4.3 KB
ID:	310120

    which means that tan_m is set from what I've tentatively named tan_m_adj.

    How is tan_m_adj calculated? Like this:

    Click image for larger version

Name:	Screenshot 2025-06-28 at 7.54.17 AM.png
Views:	280
Size:	169.8 KB
ID:	310121
    Click image for larger version

Name:	Screenshot 2025-06-28 at 7.54.49 AM.png
Views:	278
Size:	194.4 KB
ID:	310122
    Click image for larger version

Name:	Screenshot 2025-06-28 at 7.55.12 AM.png
Views:	274
Size:	206.0 KB
ID:	310123

    The key thing to understand about this function is that it is iterative. It runs every 100ms and the previous result is used to calculate the next.

    So what are the key behaviors?

    To simplify it down a lot, the function basically:

    1: Starts with IAT (measured intake temp)
    2: Compares it with TMOT (motor temp) and blends it to some degree based on:
    3: ML - load

    At high load tan_m_adj is pretty just TAN, at low load conditions where the engine is idling the tan_m_adj function is distrustful of what the IAT is telling it and calculates tan_m_adj more and more heavily based on tmot the longer the conditions continue.

    Why is this model needed? It is specifically to deal with heat-soak at idle and at stop conditions. The model prevents situations where the DME trusts the IAT in heat-soak scenarios. This would be bad as it would result in lean running conditions. The tan_m_adj model gives the DME a more realistic understanding of the actual intake temperature to ensure that lean conditions don't occur.

    It's a bit hard to graph, but this kind of shows the response of the model at various levels of load:


    Click image for larger version

Name:	Screenshot 2025-06-28 at 7.38.46 AM.png
Views:	274
Size:	182.5 KB
ID:	310124
    This isn't completely representative of how it works in reality as it is based on a fixed TAN reading, when in reality TAN will rise quickly due to heat soak, but what this graph does show is that at higher load levels the model heavily favors actual TAN (higher airflow = more accurate reading) at lower load levels it skews towards TMOT over time.

    I can't come up with a good way to graph or visually represent an actual scenario of a car coming to stop at the lights and the behavior of TAN and tan_m_adj, so you have to just work it through in your mind.

    Essentially this a fairly complex model which is tuned to handle IAT heat soak scenarios and give the air mass calculations a more accurate IAT value in those scenarios. The model is iterative and adjusts the tan_m_adj value further towards TMOT the longer the heat soak conditions continue.

    What's the lesson? Don't mess with your IAT sensor - the software is specifically calibrated to deal with heat soak conditions.

    Leave a comment:


  • terra
    replied
    Looks like a lot of work and knowledge developed here since I became less active. Very cool! I guess I know what my reading will be tonight

    Leave a comment:


  • Bry5on
    replied
    Originally posted by karter16 View Post

    Oh sorry! I completely missed that you already had that one - I wasn't meaning to be pedantic about the 7th decimal place lol
    Hahaha no stress. And I’m going to be taking this to 7 decimal places now. Because why not

    Leave a comment:


  • karter16
    replied
    Originally posted by Bry5on View Post

    well, close on relative opening
    Oh sorry! I completely missed that you already had that one - I wasn't meaning to be pedantic about the 7th decimal place lol

    Leave a comment:


  • karter16
    replied
    awesome! let me know tomorrow if there's anything else I can do to help figure those out :-)

    Leave a comment:


  • Bry5on
    replied
    Originally posted by karter16 View Post
    Okay - so all are served as per DS2 with the exception of TABG as you note.

    TAN (Intake Air Temp): correct - subtract 48
    TKA (Radiator Outlet Temp): correct - subtract 48
    TABG (Exhaust Gas Temp): correct - leave as is, DS2 divides by 16 to fit this into a byte instead of a word.
    AQ_REL (Relative Opening): multiply by 0.003051757
    LA_F_REGLER1 (Lambda Integrator 1): multiply by 0.000030517

    Let me know if this works :-)
    Beautiful. Thank you again my friend. Will test lambda integrator in the morning as it looks like I got the others sorted .. well, close on relative opening

    Leave a comment:


  • karter16
    replied
    Okay - so all are served as per DS2 with the exception of TABG as you note.

    TAN (Intake Air Temp): correct - subtract 48
    TKA (Radiator Outlet Temp): correct - subtract 48
    TABG (Exhaust Gas Temp): correct - leave as is, DS2 divides by 16 to fit this into a byte instead of a word.
    AQ_REL (Relative Opening): multiply by 0.003051757
    LA_F_REGLER1 (Lambda Integrator 1): multiply by 0.000030517

    Let me know if this works :-)

    Leave a comment:

Working...
X