Login Register

Vida CEM swapping

A mid-size luxury crossover SUV, the Volvo XC90 made its debut in 2002 at the Detroit Motor Show. Recognized for its safety, practicality, and comfort, the XC90 is a popular vehicle around the world. The XC90 proved to be very popular, and very good for Volvo's sales numbers, since its introduction in model year 2003 (North America). P2 platform.
Post Reply
flyovr
Posts: 4
Joined: 26 January 2020
Year and Model: 2011 C30
Location: PNW
Has thanked: 2 times

Re: Vida CEM swapping

Post by flyovr »

konielian wrote: 08 Sep 2022, 04:04 I can help you change the config you want just send me the 320kb flash and i change it for you!
Hey! I really appreciate the offer but I want to learn (or try to first). Also, I am trying to understand how to identify not only the actual bytes but what they translate to. I figure diving into VIDA's db is my next step to identify options.

Thank you! If I can't figure it out soon I will take you up on the offer.
07 XC70 with ABL retrofit in works
11 C30 T5 M66 Hilton Stage 2

flyovr
Posts: 4
Joined: 26 January 2020
Year and Model: 2011 C30
Location: PNW
Has thanked: 2 times

Post by flyovr »

vtl wrote: 08 Sep 2022, 07:04
5ft24 wrote: 07 Sep 2022, 20:39 ODA as M32C, BaseAddr 0xFB0000 and default Endian... Wants to know where to start disassembling... If I tell it to start at the beginning, it comes up with a bunch of "unknown"...
That's ok, as the dump contains both code and data sections. Disassemble the whole file, save to disk. Register at Renesas site, download M32C datasheet, look at the address space map, vectors, start sequence.
Disassembled the file and looking into the datasheets but man that is a lot of information. Appreciate the tips!

Still not seeing how this would be flashed back to the CEM.
07 XC70 with ABL retrofit in works
11 C30 T5 M66 Hilton Stage 2

MiclMacl
Posts: 4
Joined: 13 July 2022
Year and Model: 2008 XC90 Sport V8
Location: Wales, UK
Has thanked: 7 times
Been thanked: 3 times

Post by MiclMacl »

flyovr wrote: 08 Sep 2022, 17:53
konielian wrote: 08 Sep 2022, 04:04 I can help you change the config you want just send me the 320kb flash and i change it for you!
Hey! I really appreciate the offer but I want to learn (or try to first). Also, I am trying to understand how to identify not only the actual bytes but what they translate to. I figure diving into VIDA's db is my next step to identify options.

Thank you! If I can't figure it out soon I will take you up on the offer.
Hi, someone posted a SQL query that drags off all parameters from the VIDA DB, onto GitHub. If you run this with SSMS, then it should give you the results back to export into CSV format.

However, like you, I’m trying to translate the config parameters to the dump but as the export from VIDA is for every single model, I’m finding there’s no logical sequence when matching (particularly with the common 0x1 and 0x2 bytes etc.)

It seems to be the case that VIDA has an algorithm or something within it to determine the exact model type and correlate specific parameters to that vehicle / what bytes are stored in the CEM.

T5Luke
Posts: 142
Joined: 11 November 2020
Year and Model: S60 T5 2001
Location: DE
Has thanked: 11 times
Been thanked: 130 times

Post by T5Luke »

This works on all CEMs to MY 2004, 10th place of VIN Y, 1, 2, 3 or 4. Read cem by arduino once, place it back into car and change how often you like by dice.
screenshot.2 CEM tool.jpg
screenshot.2 CEM tool.jpg (43.82 KiB) Viewed 2492 times
Read CEM by arduino nano or UNO by this:

Code: Select all

#define BKPT 4
#define RESET 5
#define FREEZE 6
#define DSI 7
#define DSO 8

static word CMD_READ = 0x1940;
static word CMD_GO = 0x0C00;
static word CMD_WRITEM = 0x1840;

char command;
int n_line;

void setup() {
  // put your setup code here, to run once:
  pinMode(BKPT, OUTPUT);
  digitalWrite(BKPT, HIGH);
  pinMode(RESET, OUTPUT);
  digitalWrite(RESET, LOW);
  pinMode(FREEZE, INPUT);
  pinMode(DSI, OUTPUT);
  digitalWrite(DSI, LOW);
  pinMode(DSO, INPUT);
  Serial.begin(57600);
  while(!Serial){
  }
  Serial.println(F("Arduino CEM Reader, press:"));
  Serial.println();
  Serial.println(F("e: enter BDM Mode"));
  Serial.println(F("l: leave BDM (experimental)"));
  Serial.println(F("r: read complete memory"));
  Serial.println(F("b: read Boot 0-3FFF"));
  Serial.println(F("s: read security block 4000-7FFF"));
  Serial.println(F("d: read car data 8000-1FFFF"));
  Serial.println(F("f: read firmware 20000-7FFFF"));
  Serial.println(F("c: BD32 Command Mode")); 
  
  

}

void loop() {
  // put your main code here, to run repeatedly:
    if (Serial.available()) {
      command = Serial.read();
      switch (command)
      {
        case 'e':
        Serial.println("Enter BDM");
        digitalWrite(BKPT, LOW);
        delay(10);
        digitalWrite(RESET, HIGH);
        delay(100);
        Serial.println(digitalRead(FREEZE));
        break;

        case 'l':
        Serial.println("leave BDM");
        shift_BKPT_up();
        digitalWrite(RESET, LOW);
        delay(10);
        digitalWrite(RESET, HIGH);
        wait_openchannel();
        bdm_command(CMD_GO);
        digitalWrite(DSO, LOW);
        shift_BKPT_up();

        
        Serial.println(digitalRead(FREEZE));
        break;

        case 'r':
        Serial.println("Read FLASH");
       
        for (unsigned long offset = 0x0000; offset<=0x7FFFF; offset = offset + 0x02)
        {
           shiftRWord(offset);
        }
        break;

        case 'b':
        Serial.println(F("Read bootblock"));
       
        for (unsigned long offset = 0x0000; offset<=0x3FFF; offset = offset + 0x02)
        {
           shiftRWord(offset);
        }
        break;

        case 's':
        Serial.println(F("Read securityblock"));
       
        for (unsigned long offset = 0x4000; offset<=0x7FFF; offset = offset + 0x02)
        {
           shiftRWord(offset);
        }
        break;

        case 'd':
        Serial.println(F("Read cardata"));
       
        for (unsigned long offset = 0x8000; offset<=0x1FFFF; offset = offset + 0x02)
        {
           shiftRWord(offset);
        }
        break;

        case 'f':
        Serial.println(F("Read firmware"));
       
        for (unsigned long offset = 0x10000; offset<=0x7FFFF; offset = offset + 0x02)
        {
           shiftRWord(offset);
        }
        break;

        case 'c':
        Serial.println(F("BD32 Command Mode"));

        serialFlush();
        while(!Serial.available());
        {
        }
        break;

        default:
        break;

        case 'i':
        Serial.println("wipe");
        for (int i=0; i<=250; i++)
        {
          digitalWrite(BKPT, LOW);
          delay(1);
          digitalWrite(BKPT, HIGH);
          delay(1);
        }
        break;
      }
    }

}


void shiftRWord(unsigned long val)
{
    word i;
    word lowbyte = val;
    word hibyte = val >> 16;

    //Wait for DSO to get 0 => gets ready
   wait_openchannel();

    bdm_command(CMD_READ);
    shift_BKPT_up();
    shift_BKPT_up();
    


     for (i = 0; i < 16; i++)  {  //HighByte


        digitalWrite(DSI, !!(hibyte & (1 << (15 - i))));
        shift_BKPT_up();
    }
        digitalWrite(DSI, LOW);
        delayMicroseconds(1);
        shift_BKPT_up();



     for (i = 0; i < 16; i++)  {  //LowByte


        digitalWrite(DSI, !!(lowbyte & (1 << (15 - i))));
        shift_BKPT_up();
    }
    digitalWrite(DSI, LOW);
    delayMicroseconds(1);


    word W_Read;

    for (i= 0; i < 1; i++)   //Read Status Byte
    {
      //digitalWrite(BKPT, HIGH);
      //delayMicroseconds(1);
      digitalWrite(BKPT, LOW);
      delayMicroseconds(1);
      //Serial.print(digitalRead(DSO));
    }

    for (i= 0; i < 16; i++) //Read back
    {
      digitalWrite(BKPT, HIGH);
      delayMicroseconds(1);
      digitalWrite(BKPT, LOW);
      delayMicroseconds(1);
      //Serial.print(digitalRead(DSO));
       bitWrite(W_Read,(15-i),digitalRead(DSO));
    }

    check_lzero(W_Read);

    if (n_line <=6)
    {        
       Serial.print(W_Read,HEX);
       Serial. print(" ");
       n_line++;
    }else{
      Serial.println(W_Read,HEX);
      n_line = 0;
    }

   
    //return W_Read;
}


 void write_Register(word cmd, unsigned long addr)
 {
    word lowbyte = addr;
    word hibyte = addr >> 16;

    wait_openchannel(); //Wait for DSO to get 0 => gets ready
    bdm_command2(cmd);
    shift_BKPT_up();

    for (int i = 0; i < 16; i++)  {  //HighByte OFFSET
        digitalWrite(DSI, !!(hibyte & (1 << (15 - i))));
        shift_BKPT_up();
    }
    digitalWrite(DSI, LOW);
    delayMicroseconds(1);
    shift_BKPT_up();

    for (int i = 0; i < 16; i++)  {  //LowByte OFFSET
        digitalWrite(DSI, !!(lowbyte & (1 << (15 - i))));
        shift_BKPT_up();
    }
    digitalWrite(DSI, LOW);
    delayMicroseconds(1);
 }
 

 void check_lzero(word W_Read){
      if (W_Read < 0x10)
      {
        Serial.print("000");
        return;
      }
        
      if (W_Read < 0x100)
      {
        Serial.print("00");
        return;
      }
      if (W_Read < 0x1000)
      {
        Serial.print("0");
        return;
      }
     }

 void shift_BKPT_up()
 {
      digitalWrite(BKPT, LOW);
      delayMicroseconds(1);
      digitalWrite(BKPT, HIGH);
      delayMicroseconds(1);
 }

 void wait_openchannel()
 {
      while(digitalRead(DSO)!=0)
    {
      shift_BKPT_up();
    }
     while(digitalRead(DSO)!=1)
    {
      shift_BKPT_up();
    }
 }

 void bdm_command(word command)
 {
  for (int i = 0; i < 15; i++)  {  
        digitalWrite(DSI, !!(command & (1 << (15 - i))));
        shift_BKPT_up();
    }
  digitalWrite(DSI, LOW);
 }

  void bdm_command2(word command)
 {
  for (int i = 0; i < 16; i++)  {  
        digitalWrite(DSI, !!(command & (1 << (15 - i))));
        shift_BKPT_up();
    }
  digitalWrite(DSI, LOW);
 }

 void serialFlush(){
  while(Serial.available() > 0) {
    char t = Serial.read();
  }
}   
BKPT to D4
RESET to D5
FREEZE to D6
DSI to D7
DSO to D8

2 options, connect the 5V line at the capacitor, or connect the 12V at the CEMs main connector. Both connections 5V and +12V are not needed together...

Masse means GND
If you use 12V power supply connect GND from it also to arduios GND, so they should have common GND.

Copy content to HXD and save to BIN file.

Open bin file by this tool, make the changes you like and write this data back to cem by DICE-206751.
It would be nice to get paramter file fills up by the community if you need this tool...

As everything by me it is free, also free to analyze and build your own tools out of it...

Self i test this tools tomorrow, if it has bugs i will fix them... Have fun...
Attachments
CEMtool.zip
(1.77 MiB) Downloaded 455 times
cem_b.jpg
cem_b.jpg (154.8 KiB) Viewed 2492 times
CEMCON.jpg
CEMCON.jpg (302.96 KiB) Viewed 2492 times

myname
Posts: 39
Joined: 10 January 2010
Year and Model: 2007 XC70
Location: Montreal Quebec
Has thanked: 1 time
Been thanked: 4 times

Post by myname »

ahh remove the key. didnt realize that one.
is the "error error error" it working?


T5Luke
Posts: 142
Joined: 11 November 2020
Year and Model: S60 T5 2001
Location: DE
Has thanked: 11 times
Been thanked: 130 times

Post by T5Luke »

Error means the DICE didn't get the message it needs.

DICE sends:
0x27 0x01 to request a seed to CEM

CEM responds:
0x67 0x01 SEED1 SEED2 SEED3 (Print ERROR when this is missing)

DICE calculates key
0x27 0x02 KEY1 KEY2 KEY3

CEM responds with
0x67 0x02 if key was right (Print ERROR when this is missing)

When one of this 2 cem replys is missing, Error is printed on terminal.

I would think your dice is not able to catch all the can frames. Do you have the one with all blue LEDs or the metallic box?
We know your CEM will catch all frames and respond to all of them otherwise your car won't work...

vtl
Posts: 4723
Joined: 16 August 2012
Year and Model: 2005 XC70
Location: Boston
Has thanked: 114 times
Been thanked: 603 times

Post by vtl »

T5Luke wrote: 10 Sep 2022, 16:37 When one of this 2 cem replys is missing, Error is printed on terminal.

I would think your dice is not able to catch all the can frames. Do you have the one with all blue LEDs or the metallic box?
We know your CEM will catch all frames and respond to all of them otherwise your car won't work...
As far as I know, earlier P3 CEMs are sort of sluggish, can't keep up with cracking at full speed and fall off the programming mode. In Teensy logic (p3 branch) I have retry loops and (re)forcing into programming mode, which seems to help.

T5Luke
Posts: 142
Joined: 11 November 2020
Year and Model: S60 T5 2001
Location: DE
Has thanked: 11 times
Been thanked: 130 times

Post by T5Luke »

From what I know there are 2 versions on dice on market, The better one original has M32C CPU and runs original firmware. The other one has some other chip and runs something that should emulate some functions, i don't have one self so i can't find out, but i often heard about it has problems about this function:

PassThruStartPeriodicMsg(ChannelID, &Msg, &MsgID, TimeInterval);

This is used to send the modules into prog because the normal send function is not able to send fast enough.
I use this function to turn the cem into prog mode and send the diagnostic session frames to keep the cem in prog mode on both channels. I think the problem is here, but also don't know exactly, maybe a longer video and a better description of used hw could help...

Dudde
Posts: 64
Joined: 22 January 2020
Year and Model: 2005 V70 and more
Location: Finland
Has thanked: 14 times
Been thanked: 17 times

Post by Dudde »

Here is parameter file for T5Lukes config editor, will add more probably tommorow if i have the time.
parameter.txt
(2.62 KiB) Downloaded 316 times

Divxet
Posts: 10
Joined: 4 April 2022
Year and Model: 2003 v70n
Location: Sweden
Has thanked: 15 times
Been thanked: 3 times

Post by Divxet »

Anybody have any idea about what parameter is for add amplifier and the trip computer in the config editor from T5Luke.

Post Reply
  • Similar Topics
    Replies
    Views
    Last post