CMU Board : notes, eprom, cell re-numbering, CAN messages

Mitsubishi i-MiEV Forum

Help Support Mitsubishi i-MiEV Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.

kiev

Well-known member
Joined
May 3, 2015
Messages
2,238
Location
The Heart o' Dixie
Starting a thread to collect this information.

CMU board with labels,

7s6JTru.jpg
 
reading the eprom using an arduino board:

1lus3yJ.jpg


wqDH5Y0.jpg


oEBPWtF.png


ref: https://www.speakev.com/attachments/data-comparison-png.116112/

[edit: ignore this eeprom data it is incorrect]

The (lower 256-words) memory contents from Rupert's posting on the speakev forum:
4iyGsFd.png



Background: Rupert read out the contents of the lower 256-words of the eprom from 2 different boards. He thought his issue was in CMU08 based upon really high voltages shown in Canion cell data, but he was using an incorrect pack layout diagram of the CMU numbering. So he pulled CMU02 instead of 08, and ordered a replacement board 08 from a dismantler (which was also an 02).

Notes: the differences are highlighted; the replacement shows a value "2" in several rows, which could be the CMU ID number, but the original is blank in those locations.

The eprom holds 512 words of 16-bit data. So the memory addresses would range from 0x000 to 0x1FF. The rows that contain the majority of the data seem to be organized to contain a cell address number in bits 7-9 of the address:
i am adding brackets around the [cell address] bits
Hex binary address
0x010 000[0 00]01 0000 MUT or CAN buss cell A, at the most positive terminal of a module
0x050 000[0 01]01 0000 B
0x090 000[0 10]01 0000 C
0x0D0 000[0 11]01 0000 D, at the most negative terminal of a 4-cell module (CMU06 or 12)

if i extend this bit scheme, then a read of the upper 256-words should have cell data in these rows:
0x110 [1 00]01 0000 MUT or CAN buss cell E
0x150 [1 01]01 0000 F
0x190 [1 10]01 0000 G
0x1D0 [1 11]01 0000 H, at the most negative terminal of an 8-cell modules.
 
updated the photo with additional components.

Found some talk on the www that trying to read the eeprom in-situ can introduce spurious data.

On our board, When the power is applied as was done by Rupert, it powers up everything on the LV side of the board, the LTC chip and the microcontroller, etc, The micro is expecting to see an enable signal coming across the optocoupler at the isolation gap, so it's not clear what it might be doing to the four signal lines of the eeprom chip without the "enable" signal.

Made some good progress on circuit traces, hope to draw it up and post up schematic.
 
Here is a sketch of the power supply section. The EV-ECU controls a relay that sends the +12V to the CMUs.

The HV +5V is used to power up the CAN transceiver and the HV digital isolator; the LV +5V powers the microcontroller, the LTC, and the eeprom.

U5UoqjH.png
 
Thanks a heap, Kenny, please keep 'em coming.

I find it strange that the lower voltage regulator has a voltage divider going to pin 1, and the upper one doesn't. Worth a double check?
 
Thanks to Mário Fernandes in Portugal, we now have a CMU wiring color chart for the daisy chain harness in the pack.

Looking at the color of pin 3 wiring, which is the Input side for the Autonumber, i think CMU07 is the first module in the daisy chain, and pin 7 of CMU06 is the last Output back to the BMU. This is my assumption due to the different wire colors used. Hopefully Mike @Coulomb will find the section in code that sorts out this weird wiring and numbering sequence.

vLXKB6i.png
 
coulomb said:
...
I find it strange that the lower voltage regulator has a voltage divider going to pin 1, and the upper one doesn't. Worth a double check?

i double checked and the threshold adjustment feature for pin 1 is not being used for the HV 5V regulator, it's tied to ground which is done to use the on-board threshold level. No delay cap either, so it's tied to ground.

Thanks for taking on the firmware--let me know if there is something else that you need traced out.

i'm thinking to put together an arduino eeprom reader to see what my 4-cell board contains, then i have a single 8-cell module that i can check.
 
[edit: ignore these values, found out the library code was defective]

i finally got back to writing some arduino code to read the eeprom data from the chip on one of my CMU boards. It was a 4-cell card from Martin's cell replacement adventure and video production. The chip is an S93C76A eeprom, 8k-bits organized as 512 words with 16-bits per word. Here is a picture of the lower 256 words, the upper 256 were exactly identical just add 0x100 to the address in the left column.

MO1K6DH.png
 
kiev said:
Here is a picture of the lower 256 words, the upper 256 were exactly identical just add 0x100 to the address in the left column.
If the two 256 word banks are mirrored doesn't that suggest a problem with the most significant address bit of your reader not addressing the whole chip properly ? Remember Rupert had problems with his read attempts as well...

I can't imagine why they would purposefully duplicate the data in this way. And if the most significant bit was not used in the CMU board (left grounded for example) because they only needed 256 words, you would not expect to find duplicated data in the top 256 words, they should be empty or random.

Seems a little fishy to me.
 
[edit: ignore this, the github library code is defective]

The code will let you read any memory address and i tried it with settings to read just the lower 256 and then read the entire block. The data seems to be contained in 0x040 blocks (64 words) on my card, which came from a 4-cell module. The CMU ID data repeats 2 times in each 256 block for a total of 4 times in a 4-cell module.

Rupert's second board reading in which it identified the CMU number in the first word was from an 8-cell module. His lower 256 block repeats the ID data 4 times using the 0x040 blocks which would be a total of 8 times in an 8-cell module.

Don't yet know what the values mean, maybe it is calibration and scale factors?

Listings of the Arduino source code for library, header and sketch files.

Code:
/*
  MicrowireEEPROM Arduino Library Source File to
 Read and write a Microwire EEPROM.
 Written by Timo S <[email protected]> 
 Mods by MarkGen (MG).
 notes by kiev, 10/23/2019
 This code was found on github in the public domain.
*/

#include "Arduino.h"
#include "MicrowireEEPROM.h"

// class :: member
MicrowireEEPROM::MicrowireEEPROM(int cs_pin, int clk_pin, int di_pin,
                                 int do_pin, int pg_size, int addr_width,
								 int clock_period)
{
//use the "this" pointer for current class member reference 
  this->CS = cs_pin;
  this->CLK = clk_pin;
  this->DI = di_pin;
  this->DO = do_pin;

  this->ADDRWIDTH = addr_width;
  this->PAGESIZE = pg_size;
  this->HALF_CLOCK_PERIOD = clock_period / 2; 

  // make CS, CLK, DI outputs
  pinMode(CS, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DI, OUTPUT);
  
  // make DO an input
  pinMode(DO, INPUT);
}

// member function used to either send or read some data value
long MicrowireEEPROM::transmit(int data, int bits)
{
        int dout = 0; //create loop to shift bits
        for (int i=(bits-1); i>=0; i--) {
                dout |= ((int) digitalRead(DO)) << i;//read bit, typecast it,
		//then bitshift left and compound OR to get new dout integer 

                if ((1 << i) & data) { 
			digitalWrite(DI, HIGH);//send data
		    }
                else {
			digitalWrite(DI, LOW);
		    }

                delayMicroseconds(HALF_CLOCK_PERIOD);
                digitalWrite(CLK, HIGH);
                delayMicroseconds(HALF_CLOCK_PERIOD);
                digitalWrite(CLK, LOW);
        }
        digitalWrite(DI, LOW);
        return dout;
}

void MicrowireEEPROM::send_opcode(char op)
{
	   //------
	   //MG added to ensure CS & DI are low before
	   //making them HIGH.
	   digitalWrite(CS, LOW);
	   digitalWrite(DI, LOW);
         
	   //----------
	  //MG - Commented out
        //digitalWrite(CLK, HIGH);
        //delayMicroseconds(HALF_CLOCK_PERIOD);
	  //----------
        digitalWrite(CLK, LOW);
	   delayMicroseconds(HALF_CLOCK_PERIOD); //MG added to
		//ensure adequate time for CLK to go LOW 
		//93LC86 Must have CS  & DI High on positive
		//edge of the clock bit   
								
        digitalWrite(CS, HIGH);
        digitalWrite(DI, HIGH);
        // transmit start bit and two bit opcode
        transmit((1 << 2) | op, 3);
}

//class member function to read a memory address
int MicrowireEEPROM::read(int addr)
{
        send_opcode(2); //the opcode for read is 02
        transmit(addr, ADDRWIDTH); //sends the desired address
		//a leading dummy zero is returned, add extra bit holder
        long data = transmit(0, PAGESIZE+1); //return with the value
        digitalWrite(CS, LOW);
        return data;
}

void MicrowireEEPROM::writeEnable(void)
{
        send_opcode(0);
	  //---------------------------------
	  //transmit(0xFF, ADDRWIDTH);
 	  //MG - Increased 1's data from 8 bits to 16bit
	  //EEPROM 93LC86 has 11/10 bit Adress width 
	  //0xFF is 0000 0000 1111 1111 results in sending
	  //leading zeros for ADW's > 8
        //0xFFFF fills all 16 bits of the INT with 1's
	  //0xFFFF = 1111 1111 1111 1111
        transmit(0xFFFF, ADDRWIDTH);
        digitalWrite(CS, LOW);
}

void MicrowireEEPROM::writeDisable(void)
{
        send_opcode(0);
        transmit(0x00, ADDRWIDTH);
        digitalWrite(CS, LOW);
}

void MicrowireEEPROM::write(int addr, int data)
{
        send_opcode(1);
        transmit(addr, ADDRWIDTH);
        transmit(data, PAGESIZE);
        digitalWrite(CS, LOW);
}

Code:
/*
  MicrowireEEPROM library header file
  added notes, kiev 10/24/2019
 */

#ifndef MICROWIREEEPROM_H
#define MICROWIREEEPROM_H

#include "Arduino.h"

class MicrowireEEPROM {
  private:
  // Microwire needs four wires (apart from VCC/GND) DO,DI,CS,CLK
  // configure them here, note that DO and DI are the pins of the
  // EEPROM, so DI is an output of the uC, while DO is an input
  int CS;
  int CLK;
  int DI;
  int DO;
  // an EEPROM can have a varying register or word size, usually 8 or 16 bits per memory word

  int PAGESIZE;

  // an EEPROM can have a varying address width (depending on its storage size)

  int ADDRWIDTH;

  // (half of) the clock period in us
  int HALF_CLOCK_PERIOD;

  long transmit(int data, int bits);
  void send_opcode(char op);

  public:
  MicrowireEEPROM(int cs_pin, int clk_pin, int di_pin, int do_pin, int pg_size,
                  int addr_width, int clock_period);
  int read(int addr);
  void writeEnable(void);
  void writeDisable(void);
  void write(int addr, int data);
};

#endif

Code:
/* 
  arduino sketch file
  CMU_ee_reader.ino for reading
  Microwire S93C76A EEPROM
  kwh, 10/23/2019
  This is a bit-banger routine forcing the lines as needed
  to make a brute force read of the chip.
*/

#include <MicrowireEEPROM.h>

// Microwire needs four wires (apart from VCC/GND) DO,DI,CS,CLK
// configure them to pin# here, note that DO and DI are the pins of the
// EEPROM, so DI (chip input) is an output of the arduino uC, while
// DO (chip output) is an arduino input.

int CS=13; int CLK=12; int DI=7; int DO=2;

// Configure the memory word size in bits (16 or 8) called PGS in this // code, and the number of bits for the address bus called
// ADW. The speed at which the clock is run, SPD, is configured in
// microseconds.

int PGS=16; int ADW=9; int SPD=200;

// initialize the library

MicrowireEEPROM ME(CS, CLK, DI, DO, PGS, ADW, SPD); 

//start the program setup and main loop functions
//setup opens serial port and sets the baud rate
//main loop reads the device

void setup() {
  Serial.begin(9600);
}

void loop() {
	//print headers
	Serial.print("Address");
	Serial.print("\t");

	Serial.println("Hex Value");
	Serial.println();  
	delay(200);

	// create a loop to read each address

  for (int addr=0; addr < (1<<ADW); addr++) {
    
    // read the value
    int r = ME.read(addr);
    
    // give some debug output

    Serial.print(addr, HEX);
    Serial.print("\t");
    
    Serial.println(r, HEX);
       
    delay(100); // delay 100 msec
  }
  
}
 
[edit: ignore this, the github library code is defective]

For the 4-cell CMU board, the ID number and most of the data is repeated 4 times. But a few data words are only repeated twice, such as that strange couple of words on the last row shown previously.

A blank chip has all bits set to 1, so reading a register would show 0xFFFF.

Here is a another view of the Hex address and value, and decimal value for the bulk of the data which starts at 0x020 registers after the CMU ID.

WrVKndR.png
 
DBMandrake said:
I can't imagine why they would purposefully duplicate the data in this way. And if the most significant bit was not used in the CMU board (left grounded for example) because they only needed 256 words, you would not expect to find duplicated data in the top 256 words, they should be empty or random.

Seems a little fishy to me.

So i went out and bought some blank chips to use for testing and to verify the reader, and you were right--this was fishy data.

i had used a microwire eeprom library for arduino found on github, but it turns out to have problems and issues. When reading a blank chip, which comes filled with 0xFFFF in every register, the library code would only display the results as 0x7FFF, or in binary as 0111 1111 1111 1111. That leading zero was due to a left bitshifting routine that was used in the code to read the register contents. The chip was responding with the correct data as seen in this scope trace, but the github code is fubar. i can't waste any more time to troubleshoot that code.

Yellow is the clock signal, Blue is the address request (last register), Green is the memory data
w66CECo.png



So i found another arduino library M93Cx6, https://github.com/TauSolutions/M93Cx6, and found that it did read the blank chip properly. Then i used that code to read the eeprom from the 4-cell CMU board. The first register hex value is 0x00C, which is decimal "12" (which btw agrees with an incomplete left bitshifted "6").

Now i'm thinking that this board was from CMU12. The data repeats in the upper and lower 256 words; i don't know why, or that it is a problem. i will do another test to write and read a blank chip to verify the code reads all the chip correctly, but i have no reason to think it is not.

i noticed some possible ascii text string buried in here. It doesn't look like a VIN, but looks something like a mitsubishi part number, " 9? 94 A9 97 5? Z?".

[For example, the label on BMU has part number 9499B116, and on the 8-cell CMU has 9499A794 with a serial number.]

c05wOgX.png
 
kiev said:
i noticed some possible ascii text string buried in here. It doesn't look like a VIN, but looks something like a mitsubishi part number, " 9? 94 A9 97 5? Z?".

[For example, the label on BMU has part number 9499B116, and on the 8-cell CMU has 9499A794 with a serial number.]
I note that if you byte swap them (i.e. process the double bytes little end first), you get "9499A795 " (two spaces at the end). That's about as close as you can get to the CMU label's number as you can get, without actually equalling it ;)
 
Nice work - testing the ability to read and write and read back a new blank chip seems to be the sensible thing to do to verify the results we're getting, otherwise there are too many unknowns if we're not even sure our diagnostic equipment is working properly...

Regarding CMU numbering I found a little nugget in the official i-Miev service manuals that may not have been spotted before. I think we've all seen and referred to these manuals before:

http://mmc-manuals.ru/manuals/i-miev/online/Service_Manual/2013/index_M1.htm

In 54D-ELECTRIC MOTOR UNIT AND TRACTION BATTERY -> BATTERY MANAGEMENT UNIT (BMU) AND TRACTION BATTERY -> DIAGNOSIS FUNCTION we have the following page describing how to use the MUT-III diagnostic tool with the battery:

http://mmc-manuals.ru/manuals/i-miev/online/Service_Manual/2013/54/html/M154940050007800ENG.HTM

And this caught my eye:

NUMBERING CMU ID PROCEDURE

Because done at the factory, numbering the CMU ID is not necessary.
We know this statement is true as the CMU's are numbered (somehow) at the factory, however why even mention at all that the "numbering CMU ID procedure" is not necessary unless the diagnostic tool provides an option to do this ? :)

This implies to me that there MIGHT be a diagnostic procedure that can be run on a MUT-III to trigger a renumber of the CMU's.

From what I remember of previous discussion on this the speculation was that there is a daisy chain signal between the CMU boards that is wired in a certain order which would allow the CMU's to "self organise" themselves into the correct CanBUS ID order when commanded to do so. This is not something you would want to do all the time so it makes sense that it would be a diagnostic procedure that can be initiated at the factory and also on the MUT-III diagnostic tool.

Perhaps they originally planned for module level swapping at dealers to be possible, and thus built the CMU numbering procedure into the diagnostic tool, but later decided that dealers would only do whole pack replacements (less training required) and thus the advice is now that the numbering CMU ID procedure is not necessary and should not be used by the dealer.

The question is, who is brave enough to poke around in the MUT-III settings to see if they can find this renumbering procedure ? Does anyone have a scrap car which they can still communicate with the battery pack with ?

I will have a poke around in Diagbox on my car at some point however the Diagbox UI is very different and is not a one for one replication of the options in the MUT-III, so potentially CMU renumbering may not be possible in Diagbox. It is something that could potentially be added to a third party tool like Hobdrive though.

Martin in this Speak EV thread is having to repair/replace a CMU with a faulty LTC chip and has a spare CMU board on hand but doesn't know which number it is, I've suggested the possibility of trying to find and use the CMU renumbering procedure so he might be the first to give it a try if it does exist!

Edit: It also occurs to me that for the renumber procedure to work even in the case that you start with a clash of CanBus ID's between two or more boards, there would have to be an out of band hardware control signal coming from somewhere else to initiate the renumber - didn't we find a non-Canbus control signal going from the BMU to the CMU's in the schematics ? Maybe the diagnostic tool sends a CanBus command to the BMU to initiate the process and the BMU then sends the necessary non-Canbus signal to the CMU's ?

Finding the secret sauce to easily renumber CMU's using a readily available third party diagnostic tool such as Hobdrive / icarsoft etc (no soldering/eeprom swapping) would be a breakthrough for the DIY and aftermarket repair and servicing of these battery packs.
 
Martin probably won't be able to do any testing because he sent me that extra CMU board--that's the board i have been using for this thread and to extract the eeprom data.

The label on this board has the following information, so it looks like Mike is right about the byte order.

p/n: 9499A795
s/n: 02000003391
type: G8D-795M-4
 
I have a sudden interest in the eeprom contents, because I found the CMU firmware code that talks to it. It's associated (sorry, all I know right now) with CAN ids 6Fn (n=1-C for CMU id 1-12) and 6F0.

My problem at present is that the code reads the contents 16 bits at a time, but the ORG (organisation, 8-bit or 16-bit) pin (pin 6) is connected to Vss (ground) on the CMU I have here. The manual says that ORG=0 means x8 organisation.

Is it possible that there are two versions of the CMU boards, one with ORG=0 and one with ORG=1? The firmware could read two bytes and combine them (quite a pain when the chip can do it for you), but nothing seems too much trouble for the CMU firmware.

Anyone have a CMU board handy that they can test for me, please? Pin 5 is Vss (ground), pin 8 Vcc (+5V). I just want to know does pin 6 connect to Vss (pin 5) or Vcc (pin 8). Thanks in advance.

I guess it doesn't matter, the firmware reads the data somehow, it just bothers me not knowing that detail.

Edit: Duh! I had forgotten that Kiev had posted the eeprom pinout earlier. Sigh.
 
coulomb said:
...

Anyone have a CMU board handy that they can test for me, please? Pin 5 is Vss (ground), pin 8 Vcc (+5V). I just want to know does pin 6 connect to Vss (pin 5) or Vcc (pin 8). Thanks in advance.
.

On my 8-cell CMU board marked "G8D-795M-8 PWB(A) ver0.0.2", pin 6 is tied to the same ground as pin 5. The board is green in color, as i understand there are some red boards out there. HTH

In the pinout on page 1 it shows pin 6 as Test and don't care about connection, so not sure about the ORG designation?
 
kiev said:
On my 8-cell CMU board marked "G8D-795M-8 PWB(A) ver0.0.2", pin 6 is tied to the same ground as pin 5. The board is green in color, as i understand there are some red boards out there. HTH
Yes, that's exactly what I wanted, thanks. The board I have here is also green, marked exactly the same.

In the pinout on page 1 it shows pin 6 as Test and don't care about connection, so not sure about the ORG designation?
Ah! That will be the problem. The first manual I found was from Microchip, and it does have the ORG pin. I guess that means we should not use Microchip parts as a replacement, and in fact we should check any manufacturer's part to see that it is suitable for this board. Or of course hack the board to pull that pin high. I just assumed that all the parts with the same part number would be directly compatible. These would hopefully be "mostly compatible", or "compatible with one condition".

What manufacturer is your manual?

Do we know what manufacturer the part on these boards is?

eQi3LUY.png
 
Back
Top