M-Drive and MDM in non M cars

carabuser

Lieutenant
Oct 2, 2019
960
1
957
0
UK
Ride
Z4 35i & 335i
let me try to explain this... i am not good at explaining stuff thought so forgive me if i get this wrong
i used ghidra to decompile this and it doesnt do it cleanly

View attachment 48190

take this as an example
800f2062 puts together the address of the can message buffer to a12 as a pointer
800f206a stores the address into d15

View attachment 48192

800f206c directly writes 0xffff to the can message buffer (d15)
800f2074 shifts another 0xffff into the can message buffer (d15)
800f2078 buffer pointer + 4 (byte5) = d15

View attachment 48193
everything in the middle is done similarly with bit shifting. checksum is calculated then the buffer is sent out to COM_MM_EV_SendMsg at 800f21c8

the gearbox canbus stuff is put together in c_can_GETRIEBEDATEN, c_can_GETRIEBEDATEN_2, c_can_GETRIEBEDATEN_3
So to active that M_ACT signal that is currently marked as "unused" in the documentation we could change the logic to store CTR_DISP_MDRV in Bit0 of Byte1 rather than Bit4 of Byte4. It would be a rough hack and you'd lose the KOMBI light but that should be a proof of concept.
 

RSL

Lieutenant
Aug 11, 2017
937
501
0
I searched for 0x3CA but no results for a CAN packet.
There may be one in M3 @amg6975. Since 1M does not have the selectable levels in CIC, there would be no need to pass/store external temp/change values from CIC. As far as MSD81 goes, seems they are defined permanently in the DME and passed on wheel button.

So to active that M_ACT signal that is currently marked as "unused" in the documentation we could change the logic to store CTR_DISP_MDRV in Bit0 of Byte1 rather than Bit4 of Byte4. It would be a rough hack and you'd lose the KOMBI light but that should be a proof of concept.
Maybe not instead of, but in addition to. For proof of concept, just just be a hard coded 1 or 2 should do it if it's easier.
 

carabuser

Lieutenant
Oct 2, 2019
960
1
957
0
UK
Ride
Z4 35i & 335i
There may be one in M3 @amg6975. Since 1M does not have the selectable levels in CIC, there would be no need to pass/store external temp/change values from CIC. As far as MSD81 goes, seems they are defined permanently in the DME and passed on wheel button.


Maybe not instead of, but in addition to. For proof of concept, just just be a hard coded 1 or 2 should do it if it's easier.
Problem is with assembly level modifications is that inserting new code is almost impossible, you have to make space by deleting unused logic paths or repurpose existing code which is the only choice here as there's no unused logic nearby. If I put a another 4 bytes in it'll shift all the code that comes after and it'll probably brick the DME.

This is my rough comments on the packet construction:
1610898867293.png


I've circled the bits that would be modified, I'd just change the first circled value to a 1 instead of a 4 and the second from a 4 to a 0. That would work from a logic standpoint as it would set the enable status of MDRV to 1 at exactly the right time.

EDIT: CTR_DISP_MDRV only gets set to 1. It's the other tag St_mdrv_anz that gets set to 2. I'd need to force CTR_DISP_MDRV to 2 instead of 1 so requires changes elsewhere.
 
Last edited:

aus335iguy

Colonel
Nov 18, 2017
2,256
806
0
Down under
Ride
335i DCT 2009
Could we just add the code to Superwoofy’s arduino sketch as a proof of concept ?

edit Or we could delete the code from the DME and manipulate the CIC to do it instead. The clever chaps in the other thread can play doom on the thing I’m sure this would be a doddle :)
 
Last edited:

RSL

Lieutenant
Aug 11, 2017
937
501
0
Problem is with assembly level modifications is that inserting new code is almost impossible, you have to make space by deleting unused logic paths or repurpose existing code which is the only choice here as there's no unused logic nearby. If I put a another 4 bytes in it'll shift all the code that comes after and it'll probably brick the DME.

This is my rough comments on the packet construction:
View attachment 48198

I've circled the bits that would be modified, I'd just change the first circled value to a 1 instead of a 4 and the second from a 4 to a 0. That would work from a logic standpoint as it would set the enable status of MDRV to 1 at exactly the right time.

EDIT: CTR_DISP_MDRV only gets set to 1. It's the other tag St_mdrv_anz that gets set to 2. I'd need to force CTR_DISP_MDRV to 2 instead of 1 so requires changes elsewhere.
I thought there might have been something writing the unused/undefined 11 in there that could be swapped. I personally don't care about the dash light if it needs to be hijacked, but others may.

Could we just add the code to Superwoofy’s arduino sketch as a proof of concept ?

edit Or we could delete the code from the DME and manipulate the CIC to do it instead. The clever chaps in the other thread can play doom on the thing I’m sure this would be a doddle :)
Possible. Disable so 0x399 isn't sent and we can send our own. Just need a sketch that handles checksum and send all values with it, including the ones missing on MSD81.
 

carabuser

Lieutenant
Oct 2, 2019
960
1
957
0
UK
Ride
Z4 35i & 335i
There's no logic left over for the unused parts. I'm guessing when this logic was copied from the M3 or whatever dev platform it came from they tidied it up a bit. The whole section is labelled as MD_NEU so I assume this was all added in during the move from MSD80 to MSD81.

This is what I propose as a change:
1610902420662.png


Nice and simple 6 byte change. I can make the mod to any MSD81 binary but as @RSL is the only other person here with a developer status in the MHD app you'd be the only person able to flash it. Let me know if it's something you want to try.

@AzNdevil Feel free to comment if I've made a mistake with it, I don't think it'll mess up the addressing further down but it's quite hard to read.
 

RSL

Lieutenant
Aug 11, 2017
937
501
0
There's no logic left over for the unused parts. I'm guessing when this logic was copied from the M3 or whatever dev platform it came from they tidied it up a bit. The whole section is labelled as MD_NEU so I assume this was all added in during the move from MSD80 to MSD81.

This is what I propose as a change:
View attachment 48200

Nice and simple 6 byte change. I can make the mod to any MSD81 binary but as @RSL is the only other person here with a developer status in the MHD app you'd be the only person able to flash it. Let me know if it's something you want to try.
Let 'er rip if it's easy. If that's INA0S, use the original stock one from before (unpatched). Least invasive may be manual 0x399 test first, but if DME option is easy, I'll test it too/instead of.

For the record, CIC with drive logic stage set to 3 in DME and DSC off set in DME.

When M button pressed, CIC updates to reflect those settings, but the functions don't change. DSC stays off until I hold the DSC button and trans stays in its default drive logic level 2 (which you'd see if I had it in D). Change D/S and drive logic levels, but they obviously don't stick.

 
  • Like
Reactions: Begood69

carabuser

Lieutenant
Oct 2, 2019
960
1
957
0
UK
Ride
Z4 35i & 335i
OK, send me your current BIN and I'll modify that directly.

It's a shame my 335i doesn't have iDrive. The Z4 does but it already has mode selection built in which modifies EPS, EDC and the Drivelogic in the DCT so I imagine these changes would cause all kinds of confusion.
 

RSL

Lieutenant
Aug 11, 2017
937
501
0
OK, send me your current BIN and I'll modify that directly.

It's a shame my 335i doesn't have iDrive. The Z4 does but it already has mode selection built in which modifies EPS, EDC and the Drivelogic in the DCT so I imagine these changes would cause all kinds of confusion.
Thanks, sent.

This was/is my thinking on the Z4 button/setup and actually still is. Z4 comms and everything work for multiple modes and are already setup for DCT+MSD81. With the Z4 and M3 logics so similar, I'd think we'd have easy cross-over and be able to use buttons/CIC for control. Might need stock EGS, but that's fine. I do think the Z4 DSC is wired differently, but that may be related to EPS.

I know we keep asking a lot, but can you see WTF K_SPORT_MDRV_DKG does in the DME?
 

carabuser

Lieutenant
Oct 2, 2019
960
1
957
0
UK
Ride
Z4 35i & 335i
Thanks, sent.

This was/is my thinking on the Z4 button/setup and actually still is. Z4 comms and everything work for multiple modes and are already setup for DCT+MSD81. With the Z4 and M3 logics so similar, I'd think we'd have easy cross-over and be able to use buttons/CIC for control. Might need stock EGS, but that's fine. I do think the Z4 DSC is wired differently, but that may be related to EPS.

I know we keep asking a lot, but can you see WTF K_SPORT_MDRV_DKG does in the DME?
That is the DriveLogic level that gets sent to the DCT. It does nothing in the DME.
 

RSL

Lieutenant
Aug 11, 2017
937
501
0
Not the stage one, the one that goes to St_mdrv_mod_getr. This is the one I always thought should be sending program mode (sport) to the trans. I'll see if I can find anything in the docs, but for some reason, none of mine even have that sport switch logic layout in them.

Edit: it may, might just need the actual sport button logic in the trans to do it, or a full 0x399.
 
  • Like
Reactions: Begood69

carabuser

Lieutenant
Oct 2, 2019
960
1
957
0
UK
Ride
Z4 35i & 335i
Not the stage one, the one that goes to St_mdrv_mod_getr. This is the one I always thought should be sending program mode (sport) to the trans. I'll see if I can find anything in the docs, but for some reason, none of mine even have that sport switch logic layout in them.

Edit: it may, might just need the actual sport button logic in the trans to do it, or a full 0x399.
The other one controls the gearbox mode. Between automatic when set to 1 or sequential when set to 2.
 
  • Like
Reactions: Begood69

Begood69

Corporal
Nov 13, 2016
234
114
25
Fayetteville, NC
Ride
335i N54 Predator 3.2L stroker
Yeap.. u guys r doing a crazy job. Good job. Im finally coming back out to the streets. Im running 1m bin. Is there anything i can test. Im running m3gts flash with msd81/M3DSC/M3JBBF/M3KOMBI/M3SZL/M3GWS/M3CIC
No errors.
And i have a bin of the tune im using. Let me know
 

amg6975

Sergeant
Oct 27, 2019
278
187
0
Ride
2012 135, 2005 ZHP, 2009 fJCW
I searched for 0x3CA but no results for a CAN packet.

0x3CA comes from changing the M Drive settings in the CIC.

There may be one in M3 @amg6975. Since 1M does not have the selectable levels in CIC, there would be no need to pass/store external temp/change values from CIC. As far as MSD81 goes, seems they are defined permanently in the DME and passed on wheel button.


Maybe not instead of, but in addition to. For proof of concept, just just be a hard coded 1 or 2 should do it if it's easier.

Right. I don't suspect the MSD81 would accept values from 0x3CA anyway. The ideal scenario is to hard code in standard values that would be activated with the M button in non-M cars. Probably Power = Sport, Servotronic = SPort, DSC = MDM, DKG = S5.

Not the stage one, the one that goes to St_mdrv_mod_getr. This is the one I always thought should be sending program mode (sport) to the trans. I'll see if I can find anything in the docs, but for some reason, none of mine even have that sport switch logic layout in them.

Edit: it may, might just need the actual sport button logic in the trans to do it, or a full 0x399.

ST_MDRV_MOD_GRB is the S/D setting for M DCT, not sure if it has an analog in the non M DCT. ST_MDRV_STG_GRB is the 1-6 Drive Logic level.

Yeap.. u guys r doing a crazy job. Good job. Im finally coming back out to the streets. Im running 1m bin. Is there anything i can test. Im running m3gts flash with msd81/M3DSC/M3JBBF/M3KOMBI/M3SZL/M3GWS/M3CIC
No errors.
And i have a bin of the tune im using. Let me know

Yeah, amazing progress already. ^This is definitely ideal set up to test the DME code change. He should instantly be able to see the MDM light up, and feel the Servotronic stiffen up.
 

amg6975

Sergeant
Oct 27, 2019
278
187
0
Ride
2012 135, 2005 ZHP, 2009 fJCW
Also don't forget you need to add 1 to the Byte 1 message before stuffing it into the CAN packet

1610987980114.png
 

amg6975

Sergeant
Oct 27, 2019
278
187
0
Ride
2012 135, 2005 ZHP, 2009 fJCW
When M button pressed, CIC updates to reflect those settings, but the functions don't change. DSC stays off until I hold the DSC button and trans stays in its default drive logic level 2 (which you'd see if I had it in D). Change D/S and drive logic levels, but they obviously don't stick.


That is strange. My M3 didn't change what was in the CIC when M Drive was activated... I don't think.
 

RSL

Lieutenant
Aug 11, 2017
937
501
0
Also don't forget you need to add 1 to the Byte 1 message before stuffing it into the CAN packet

View attachment 48245
I thought b1 low bit needed to be 2 from prior posts? I do have the DME program update from @carabuser that should move 2 from _anz to 0x399 b1 bits 0-1, but I have not flashed. I'd prefer CAN first as a less risky first test, but if someone more experienced in assembly can double-check and confirm changes in post 86 above, I may just flash that if this sketch takes too long. If it needs to be 1, we'll have to redo and pull from something else though.

I'm still working on counter/checksum bit/byte math for b0 programmatically in arduino since I haven't had to mess with it before and it's taking some time since I'm getting a crash course. If anyone has a basic function to generate the on-the-fly b0 math, the rest is pretty straightforward.

Everything expected (DSC/drive logic) with MSD81 changes on the CIC, except power. It is still problematic on non-M and what I think the Z4 button setup may allow if it gets to that, but it may work with a complete 0x399 too. If your CAN logs/layouts are any indication, it may also be what's needed to enable shiftlights on M3 Kombi in non-Ms.
 

amg6975

Sergeant
Oct 27, 2019
278
187
0
Ride
2012 135, 2005 ZHP, 2009 fJCW
I thought b1 low bit needed to be 2 from prior posts? I do have the DME program update from @carabuser that should move 2 from _anz to 0x399 b1 bits 0-1, but I have not flashed. I'd prefer CAN first as a less risky first test, but if someone more experienced in assembly can double-check and confirm changes in post 86 above, I may just flash that if this sketch takes too long. If it needs to be 1, we'll have to redo and pull from something else though.

I'm still working on counter/checksum bit/byte math for b0 programmatically in arduino since I haven't had to mess with it before and it's taking some time since I'm getting a crash course. If anyone has a basic function to generate the on-the-fly b0 math, the rest is pretty straightforward.

Everything expected (DSC/drive logic) with MSD81 changes on the CIC, except power. It is still problematic on non-M and what I think the Z4 button setup may allow if it gets to that, but it may work with a complete 0x399 too. If your CAN logs/layouts are any indication, it may also be what's needed to enable shiftlights on M3 Kombi in non-Ms.

You're correct, Byte 1 bit 0-1 needs to be value of 2 for on and 1 for off (actually "Revert") but CTR_DISP_MDRV that's in Byte 4 is a value of 1 for on and 0 for off. So, you need to add one to it to get the correct value for Byte 1.

I don't really know arduino but in standard C the checksum calc would be:

Code:
uint8_t can_packet_399[6];
uint16_t checksum;

can_packet_399[0] &= 0xF0; //remove anything that may be in checksum

checksum = 0x399;   //initialize checksum to 0x399

//add up all the bytes of 0x399
for (uint8_t i=0, i<6, i++){
  checksum += can_packet_399[i]
  }

checksum = (checksum & 0x00FF) + (checksum >> 8); //add upper and lower Bytes

checksum &= 0x00FF; //throw away anything in upper Byte

checksum = (checksum & 0b000F) + (checksum >> 4); //add first and second nibble

checksum &= 0x000F; //throw away anything in upper nibble

can_packet_399[0] += checksum;  //add checksum back into Byte0.
 

RSL

Lieutenant
Aug 11, 2017
937
501
0
uint8_t can_packet_399[6]; uint16_t checksum; can_packet_399[0] &= 0xF0; //remove anything that may be in checksum checksum = 0x399; //initialize checksum to 0x399 //add up all the bytes of 0x399 for (uint8_t i=0, i<6, i++){ checksum += can_packet_399 } checksum = (checksum & 0x00FF) + (checksum >> 8); //add upper and lower Bytes checksum &= 0x00FF; //throw away anything in upper Byte checksum = (checksum & 0b000F) + (checksum >> 4); //add first and second nibble checksum &= 0x000F; //throw away anything in upper nibble can_packet_399[0] += checksum; //add checksum back into Byte0.
OK, so DME logic should work if correct.

Thanks for this code. It's similar to C, but I haven't had to really mess with any byte manipulation/math in anything. I managed to get counter 0-E in high byte of b0, but that's about it so far lol
 
  • Like
Reactions: amg6975