Announcement

Collapse
No announcement yet.

CSL '0401' Program Binary Disassembly Notes

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

  • karter16
    replied
    I posted the below in the a quick and easy way to street tune your csl conversion for drivability thread, and thought I'd also put here for reference:


    For what it's worth I've just been working through this in my disassembly project and thought it would be worth noting here. Below is a summary of how it comes together:

    AQ_ABS (absolute cross-sectional opening) = AQ_ABS_LLS (absolute cross-sectional opening of idle control valve) + AQ_ABS_WDK (absolute cross-sectional opening of throttle plates)

    AQ_REL (relative cross-sectional opening (%)) = (AQ_ABS - K_AQ_ABS_MIN (minimum possible cross-sectional opening)) / (K_QA_ABS_MAX (maximum possible cross-sectional opening) - K_AQ_ABS_MIN)

    This AQ_REL value is what's used in the standard M3 software, a commonly referenced example of this is the VANOS maps - AQ_REL is the y-axis in those tables.


    The important thing to know is that AQ_REL isn't used directly in the CSL AlphaN maps. It's actually a modified version of AQ_REL that is used.

    For the purposes of this explanation I will call this modified value AQ_REL_ALPHA_N it is calculated thusly:

    AQ_REL_ALPHA_N = AQ_REL / AQ_REL_ALPHA_N_FAKT

    So what's AQ_REL_ALPHA_N_FAKT? It's just my name for the output of the lookup curve at: 0xE056


    Click image for larger version  Name:	Screenshot 2025-06-02 at 8.25.50 PM.png Views:	0 Size:	22.7 KB ID:	307058

    x axis is N (rpm) and the output is a scaling factor.

    Essentially what this means is that AQ_REL_ALPHA_N will be a smaller value (between 0-30% smaller dependent on RPM) than actual AQ_REL beneath 2400 RPM.

    Additionally there is another value that is also calculated in the same routine, let's call it AQ_REL_ALPHA_N_PT_KORR which is additionally scaled based on P_UMG (Ambient air pressure) and TAN (Intake air temperature).

    Click image for larger version  Name:	Screenshot 2025-06-02 at 8.31.34 PM.png Views:	0 Size:	26.9 KB ID:	307059

    This value isn't used in the CSL AlphaN maps (or in other operational code), but it is used in two routines which seem to be involved in the sending/export of data (I haven't figured out yet if these are the DS2 routines or something else). Crucially AQ_REL_ALPHA_N is NOT referenced in any sending/export routines. Which raises the possibility that the "Relative Opening" datapoint that we are logging in TestO isn't even the same data point that is actually used as an input to the VE table (indeed it could even be the standard AQ_REL variable)​. Looking at the two tables above they are normalized around 20 degrees C intake temp and ambient air pressure of 962mbar, so it's not going to be too far off either way, but for example today in Auckland was 1016mbar at 20C, so PRESUMING THIS IS THE CASE I'd be looking at a 4% variance.

    I will spend more time looking at this to see if I can establish with certainty which of the two variables "Relative Opening" represents.


    Also worth mentioning that the MAP sensor does not have any part in the calculation of AQ_REL. The MAP sensor is used in the calculation of air mass, which in turn is used in the calculation of final Relative Fill (an adjustment to the value obtained from the VE table).


    I realize this post is more focused on the "academic" side but hopefully of use to the collective understanding.​
    Last edited by karter16; 06-02-2025, 12:50 AM.

    Leave a comment:


  • karter16
    replied
    Well being sick has given me the excuse to spend some more time working on the disassembly. I've been focused on the calculation of rg_m which is the mass of residual gas in the cylinder and is one of three components which results in the final calculation of mass of gas in the cylinder (which is key to the calculation of final RF).

    I'm very pleased to have completely figured out the EVAN (intake cam) component of the calculation of rg_m. The position of the intake camshaft influences the amount of residual gas left in the cylinder. I've *almost* figured out the exhaust cam component of it as well, but am not quite there yet. I haven't yet figured out the units of the curves at 0xe6d6 and 0xe708 ( ppm008 if you're around I'd love a hint on these :-)).

    Anyway - here's the intake component of the function. Once I've got the entire function figured out I'll do a write up and add it to the wiki page

    I'm really pleased to have figured this out as MPowerE36's analysis hadn't gone in to this aspect of the mass calculation, and as far as I know no one has (publicly) figured this out.

    Click image for larger version

Name:	Screenshot 2025-06-01 at 8.17.13 PM.png
Views:	149
Size:	250.2 KB
ID:	306994
    Attached Files

    Leave a comment:


  • ac427
    replied
    Originally posted by karter16 View Post
    Today I finally got round to trying setting k_rf_cfg to 0x02 (from 0x12) to take the MAP sensor out of the final RF calculation path.

    The result is that the car behaves and drives in the same way as if the MAP sensor is physically disconnected. The car runs in AlphaN + TABG adjustment mode.

    I didn't personally have any doubt that this would be the case (although I know others did), but good to prove this. I think I mentioned previously that it seems like this would be good practice to take the MAP sensor out of the RF calculation path when doing the VE tuning process. I can't think of an objective way to measure this though. If anyone has any ideas I'm all ears!
    Me neither but it would be interesting to compare the VE tuning output from both with and without the MAP sensor tuning results.

    Leave a comment:


  • karter16
    replied
    Originally posted by ac427 View Post

    What difference did you notice with k_rf_cfg to 0x02, poor part throttle performance?
    Yep less responsive part throttle and more jerkiness. Exactly the same effect as disconnecting (electrically) the MAP sensor and going for a drive.

    Leave a comment:


  • ac427
    replied
    Originally posted by karter16 View Post
    Today I finally got round to trying setting k_rf_cfg to 0x02 (from 0x12) to take the MAP sensor out of the final RF calculation path.

    The result is that the car behaves and drives in the same way as if the MAP sensor is physically disconnected. The car runs in AlphaN + TABG adjustment mode.

    I didn't personally have any doubt that this would be the case (although I know others did), but good to prove this. I think I mentioned previously that it seems like this would be good practice to take the MAP sensor out of the RF calculation path when doing the VE tuning process. I can't think of an objective way to measure this though. If anyone has any ideas I'm all ears!
    What difference did you notice with k_rf_cfg to 0x02, poor part throttle performance?

    Leave a comment:


  • karter16
    replied
    Today I finally got round to trying setting k_rf_cfg to 0x02 (from 0x12) to take the MAP sensor out of the final RF calculation path.

    The result is that the car behaves and drives in the same way as if the MAP sensor is physically disconnected. The car runs in AlphaN + TABG adjustment mode.

    I didn't personally have any doubt that this would be the case (although I know others did), but good to prove this. I think I mentioned previously that it seems like this would be good practice to take the MAP sensor out of the RF calculation path when doing the VE tuning process. I can't think of an objective way to measure this though. If anyone has any ideas I'm all ears!

    Leave a comment:


  • karter16
    replied
    Continuing on with the MAP sensor work. I'll write this up properly and put it in the MAP sensor wiki, but for now here's the disassembled code listing. This is the function that takes the raw MAP sensor AD values from the ring buffer and calculates MAP pressure and manifold vacuum pressure.

    It really would be very nice to have the actual parameter/variable names, but you'll have to suffer through my made up names (identified as all lowercase) :-)

    Key things of note:
    - The code loops through the ring buffer every time it runs and pulls and averages a number of valid samples (by default it's actually only 1 valid value that it samples).
    - It then takes the raw value and offsets it and scales it according to the MAP scaler and offset parameters that have been known for some time.
    - Manifold vacuum pressure is calculated as P_UMG (ambient pressure from the on-DME pressure sensor) minus MAP pressure.
    - The function runs in both the segment task and the 10ms task.


    Click image for larger version

Name:	Screenshot 2025-04-04 at 7.48.16 AM.png
Views:	226
Size:	157.7 KB
ID:	300283
    Click image for larger version

Name:	Screenshot 2025-04-04 at 7.48.27 AM.png
Views:	216
Size:	190.6 KB
ID:	300284

    Leave a comment:


  • karter16
    replied
    This one is interesting. This (function at 0x00011e3c) is a debug function that runs in the background task. It tracks the time in milliseconds since the function last run and captures the longest time in DB_TBGND_MAX and the average in DB_TBGND_AV. This would have been useful during development as the BMW engineers were adding to the codebase to monitor the system and make sure that the CPU was getting to the background task regularly enough.

    Click image for larger version

Name:	Screenshot 2025-04-02 at 8.32.58 PM.png
Views:	120
Size:	54.9 KB
ID:	300070

    Leave a comment:


  • karter16
    replied
    0x00ffeb36 is the 32 bit telegram from the MFL to the DME with the cruise control buttons status. This variable in turn is populated from the TPU config RAM (0x00ffff08) which is a shared RAM section between the DME and the TPU to allow transfer of data. The TPU facilitates the one-wire serial interface to the MFL.

    Section 8.3.2 in 3.05 EGAS Safety Concept in the funktionsrahmen describes how this works and it seems that this is pretty much how it's implemented in the code as well. The safety concept code is really interesting to dig into and seems in general to be pretty close to how it's documented in the funktionsrahmen.

    Leave a comment:


  • karter16
    replied
    0x00ffe508 and 0x00ffe50a appear to be "total count of interrupts" and "number of interrupt service routines currently in progress" (note it is possible for this to be greater than 1 as a higher priority interrupt will "interrupt" a lower priority ISR) respectively.

    I've named these "sys_interrupt_counter" and "sys_active_interrupts".

    edit: renamed to sys_isr_count to mirror BMW's naming of CAN_ISR_COUNT
    Last edited by karter16; 03-29-2025, 10:32 PM.

    Leave a comment:


  • karter16
    replied
    If anyone has any info about these 4 curves it would be super useful to know. From the code I I've worked through so far I *think* that 0xe708 and 0xe732 respectively are possibly representing molar mass of the residual gas mix based on camshaft position, but not overly confident about that yet.

    Click image for larger version

Name:	Screenshot 2025-03-23 at 7.54.58 AM.png
Views:	171
Size:	7.4 KB
ID:	298726

    Leave a comment:


  • karter16
    replied
    These are all of the parameters from the master binary which we currently don't have the actual names for. For anyone who's wondering the addresses below are as the prog binary references them, so the actual addresses in the partial would be the value below minus 0x80000. e.g. 00088826 would be 0x8826.
    00088826
    00089840
    00089a4c
    0008a6c5
    0008a97a
    0008a97c
    0008a97e
    0008a9a2
    0008a9a3
    0008a9a4
    0008a9a6
    0008a9a8
    0008a9aa
    0008c354
    0008c35a
    0008c35c
    0008c376
    0008c378
    0008c37a
    0008c37b
    0008c37c
    0008c37e
    0008c380
    0008c382
    0008c384
    0008c3db
    0008c558
    0008c55a
    0008c55c
    0008c56c
    0008c56e
    0008c582
    0008c59e
    0008c5ba
    0008c5e6
    0008c682
    0008d000
    0008d002
    0008d201
    0008d202
    0008d204
    0008d205
    0008d220
    0008d222
    0008d2ee
    0008d2f0
    0008d2f2
    0008d2f4
    0008d2f6
    0008d2f8
    0008d2fa
    0008d2fc
    0008d716
    0008db30
    0008df4a
    0008dfac
    0008e056
    0008e088
    0008e08a
    0008e08c
    0008e08d
    0008e08e
    0008e25c
    0008e5e4
    0008e5e8
    0008e5ea
    0008e5ec
    0008e5ed
    0008e5ee
    0008e5f0
    0008e5f2
    0008e5fa
    0008e5fc
    0008e5fe
    0008e600
    0008e602
    0008e604
    0008e61e
    0008e638
    0008e69a
    0008e69c
    0008e69e
    0008e6a0
    0008e6a2
    0008e6a4
    0008e6c6
    0008e6ce
    0008e6d0
    0008e6d2
    0008e6d4
    0008e6d6
    0008e708
    0008e732
    0008e764
    0008e7ae
    0008e8fe
    0008e918
    0008e91a

    And these are all the parameters from the slave binary which we currently don't have actual names for. I've included all the SMG parameters (0008a8xx to 0008aexx) which are missing actual names as well. Not sure if anyone has those, but thought I'd include them for completeness. To convert the below addresses to the offset in the partial it's what's below minus 0x88000. e.g. 0008808a would be 0x008a.
    0008808a
    0008903f
    0008a1da
    0008a1dc
    0008a1de
    0008a1df
    0008a1e0
    0008a1e2
    0008a1e4
    0008a1fa
    0008a1fc
    0008a1fe
    0008a200
    0008a202
    0008a204
    0008a206
    0008a228
    0008a24a
    0008a24c
    0008a24e
    0008a251
    0008a252
    0008a253
    0008a254
    0008a255
    0008a256
    0008a258
    0008a259
    0008a25a
    0008a25c
    0008a25e
    0008a260
    0008a262
    0008a263
    0008a264
    0008a265
    0008a80e
    0008a811
    0008a814
    0008a816
    0008a817
    0008a818
    0008a819
    0008a81a
    0008a81b
    0008a81c
    0008a81e
    0008a821
    0008a824
    0008a826
    0008a82a
    0008a82c
    0008a830
    0008a832
    0008a838
    0008a83c
    0008a83d
    0008a840
    0008a842
    0008a844
    0008a846
    0008a848
    0008a84a
    0008a84c
    0008a850
    0008a852
    0008a853
    0008a856
    0008a85a
    0008a85e
    0008a860
    0008a862
    0008a865
    0008a866
    0008a867
    0008a883
    0008a88a
    0008a88c
    0008a88d
    0008a896
    0008a898
    0008a89c
    0008a89d
    0008a8a2
    0008a8b8
    0008a8ba
    0008a8c4
    0008a8d4
    0008a8e2
    0008a918
    0008a96e
    0008a9a0
    0008a9aa
    0008a9b4
    0008a9be
    0008a9cc
    0008a9da
    0008aa30
    0008aa44
    0008aa52
    0008aad2
    0008aadc
    0008aae4
    0008aeb4
    0008e706
    0008e707
    Attached Files

    Leave a comment:


  • karter16
    replied
    ppm008 really appreciate your help - any chance I could list out all the parameter addresses I'm working on and see if you've got details for any others? I've come up with names for a bunch but if it's possible to confirm the actual names that would be even more ideal. (don't want to bug you too much though so feel free to say no!)

    Leave a comment:


  • karter16
    replied
    Originally posted by ppm008 View Post
    8a980 KL_TANM_PT1_INIT
    8e5f4 K_RF_DIAG_F_KATH
    8e5f6 K_RF_DIAG_F_VAN
    8e5f8 K_RF_DIAG_SCHWELLE
    8e848 KF_RF_KORR_DRREL
    8e6c8 K_RG_R
    8e6ca K_RG_V_HUB
    8e6cc K_RG_ZYLANZ_BANK
    Amazing - thank you so so much!


    Sent from my iPhone using Tapatalk

    Leave a comment:


  • ppm008
    replied
    8a980 KL_TANM_PT1_INIT
    8e5f4 K_RF_DIAG_F_KATH
    8e5f6 K_RF_DIAG_F_VAN
    8e5f8 K_RF_DIAG_SCHWELLE
    8e848 KF_RF_KORR_DRREL
    8e6c8 K_RG_R
    8e6ca K_RG_V_HUB
    8e6cc K_RG_ZYLANZ_BANK

    Leave a comment:

Working...
X