Go Down

Topic: I2C EEPROM Emulator - arduino. (Read 2 times) previous topic - next topic

rbz

May 27, 2010, 11:54 pm Last Edit: May 27, 2010, 11:58 pm by rbz Reason: 1
Hello!

I'm currently working to try and repair an XBOX. The thing is, the EEPROM chip is missing. It had the I2C address of 0x54.

Now, while the chip is bieng posted i thought i'd have a go at trying to emulate an EEPROM using an arduino.

so far what i've done.

  • Connected to device to the I2C bus using address 0x54.
  • Created an eeprom lookup table in a byte array.
  • Recieved data from the XBOX.
  • Sent corrospoding bytes to what I _THINK_ are eeprom offsets.

    Now the xbox does boot, not fully though (E.g GREEN light, hard drive spinning, CD Drive eject working etc, before it was an orangle light then isntant power off), I think this is because i'm sending the wrong thing at the wrong time.

    heres the code:

    Code: [Select]
    #include <Wire.h>

    void setup()
    {
     Wire.begin(0x54);
     Wire.onReceive(receiveEvent);
     Serial.begin(9600);
    }

    void loop()
    {
    }

    void receiveEvent(int hurr)
    {
      byte XEEPROM[] = { 0x5d, 0x26, 0x31, 0x91, 0x3e, 0x12, 0x8e, 0x70, 0xa5, 0x57, 0x3d, 0xed, 0x91, 0x99, 0xb4, 0x11, 0x38, 0xde, 0x1b, 0xd6, 0x4c, 0xd9, 0xf5, 0x13, 0x23, 0x94, 0xb8, 0x3d, 0x9c, 0xb0, 0xc4, 0x54, 0xf0, 0x69, 0xca, 0xb3, 0x28, 0x84, 0xa5, 0xc1, 0x80, 0x53, 0x69, 0x0c, 0x38, 0x4f, 0x0c, 0x74, 0xa1, 0x5b, 0x8c, 0x71, 0x34, 0x30, 0x38, 0x30, 0x30, 0x38, 0x31, 0x35, 0x33, 0x31, 0x30, 0x35, 0x00, 0x12, 0x5a, 0x1e, 0xbd, 0x9e, 0x00, 0x00, 0x02, 0x82, 0x30, 0xaa, 0x10, 0xb7, 0x7f, 0x8d, 0x0a, 0xcb, 0x2e, 0xc1, 0xeb, 0x52, 0x20, 0xdc, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x55, 0x57, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x47, 0x4d, 0x54, 0x00, 0x42, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x02, 0x03, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x68, 0xaa, 0xdd, 0x02, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x01, 0x04, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x01, 0x04, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x12, 0x03, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x02, 0x02, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x12, 0x02, 0x84, 0x79, 0x80, 0x00, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00 };
      while (Wire.available()){
          byte WR = Wire.receive();
          Wire.send(XEEPROM[WR]);
          Serial.print("\nRECEIVE: 0x");
          Serial.print(WR, HEX);
          Serial.print("\nSENT: 0x");
          Serial.print(XEEPROM[WR], HEX);
       };
    }


    Heres the output from when the console is on, to when it stops requesting bytes from the arduino.

    Code: [Select]
    RECEIVE: 0xC3
    SENT: 0x2
    RECEIVE: 0xC2
    SENT: 0xDD
    RECEIVE: 0xC1
    SENT: 0xAA
    RECEIVE: 0xC0
    SENT: 0x68
    RECEIVE: 0xC3
    SENT: 0x2
    RECEIVE: 0xC2
    SENT: 0xDD
    RECEIVE: 0xC1
    SENT: 0xAA
    RECEIVE: 0xC0
    SENT: 0x68
    RECEIVE: 0xC4
    SENT: 0x46
    RECEIVE: 0xC6
    SENT: 0x8F
    RECEIVE: 0xC8
    SENT: 0x78
    RECEIVE: 0xCA
    SENT: 0xBB
    RECEIVE: 0xCC
    SENT: 0x1
    RECEIVE: 0xCE
    SENT: 0x46
    RECEIVE: 0xD0
    SENT: 0x8F
    RECEIVE: 0xD2
    SENT: 0x78
    RECEIVE: 0xD4
    SENT: 0xBB
    RECEIVE: 0xD6
    SENT: 0x1
    RECEIVE: 0xD8
    SENT: 0x46
    RECEIVE: 0xDA
    SENT: 0x8F
    RECEIVE: 0xDC
    SENT: 0x78
    RECEIVE: 0xDE
    SENT: 0xBB
    RECEIVE: 0xE0
    SENT: 0x12
    RECEIVE: 0xE2
    SENT: 0x46
    RECEIVE: 0xE4
    SENT: 0x8F
    RECEIVE: 0xE6
    SENT: 0x78
    RECEIVE: 0xE8
    SENT: 0xBB
    RECEIVE: 0xEA
    SENT: 0x2
    RECEIVE: 0xEC
    SENT: 0x46
    RECEIVE: 0xEE
    SENT: 0x8F
    RECEIVE: 0xF0
    SENT: 0x78
    RECEIVE: 0xF2
    SENT: 0xBB
    RECEIVE: 0xF4
    SENT: 0x12


    Any help would be cool, thanks a lot.

BenF

Quote
Now, while the chip is bieng posted i thought i'd have a go at trying to emulate an EEPROM using an arduino.

That's a clever idea!

"onReceive" is a receive only event and I think you should limit yourself to save the received data (the EEPROM address) in a global variable.

You should register for the "onRequest" event with a handler and use this to return data. Address of the data will then be in the global variable you saved when processing the onReceive event.


rbz

#2
May 28, 2010, 12:25 am Last Edit: May 28, 2010, 12:30 am by rbz Reason: 1
Got to say, I updated the code and its now running much more like normal, apart from no display, also no serial output :\?. However it appears to be functioning 100%, much more alive than before (fan noise, hard drive activity, reading data off a game disk etc)

I'll keep tweaking, Thanks so far BenF!

Code: [Select]
#include <Wire.h>

byte XEEPROM[] = { 0x5d, 0x26, 0x31, 0x91, 0x3e, 0x12, 0x8e, 0x70, 0xa5, 0x57, 0x3d, 0xed, 0x91, 0x99, 0xb4, 0x11, 0x38, 0xde, 0x1b, 0xd6, 0x4c, 0xd9, 0xf5, 0x13, 0x23, 0x94, 0xb8, 0x3d, 0x9c, 0xb0, 0xc4, 0x54, 0xf0, 0x69, 0xca, 0xb3, 0x28, 0x84, 0xa5, 0xc1, 0x80, 0x53, 0x69, 0x0c, 0x38, 0x4f, 0x0c, 0x74, 0xa1, 0x5b, 0x8c, 0x71, 0x34, 0x30, 0x38, 0x30, 0x30, 0x38, 0x31, 0x35, 0x33, 0x31, 0x30, 0x35, 0x00, 0x12, 0x5a, 0x1e, 0xbd, 0x9e, 0x00, 0x00, 0x02, 0x82, 0x30, 0xaa, 0x10, 0xb7, 0x7f, 0x8d, 0x0a, 0xcb, 0x2e, 0xc1, 0xeb, 0x52, 0x20, 0xdc, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x55, 0x57, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x47, 0x4d, 0x54, 0x00, 0x42, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x02, 0x03, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x68, 0xaa, 0xdd, 0x02, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x01, 0x04, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x01, 0x04, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x12, 0x03, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x02, 0x02, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x12, 0x02, 0x84, 0x79, 0x80, 0x00, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00 };
byte WR = Wire.receive();

void setup()
{
 Wire.begin(0x54);
 Wire.onRequest(requestEvent);
 Serial.begin(9600);
}

void loop()
{
}

void requestEvent()
{
     while (Wire.available()){
      Wire.send(XEEPROM[WR]);
      Serial.print("\nRECEIVE: 0x");
      Serial.print(WR, HEX);
      Serial.print("\nSENT: 0x");
      Serial.print(XEEPROM[WR], HEX);
   };
}

BenF

I would write handlers for both the onReceive and onRequest events.  

In the onReceive handler you should capture the incoming data and save it to a global variable (this becomes your eeprom memory index). In the onRequest handler you return the content of the EEPROM referenced by the memory index. Also whenever you return data (in onRequest) you should increment the memory pointer as EEPROM's support auto-increment on read. That is an application reading from EEPROM may initially set the memory index to read from (your onReceive handler gets called) and then read (your onRequest handler gets called) subsequent memory locations without having to specify the eeprom address for every byte.

The onReceive and onRequest handlers are called from within the TWI/I2C  interrupt handler. You should keep execution time within interrupt handlers to a minimum and calling Serial.print (however useful) is an absolute no-no. This will upset the TWI/I2C bus timing and more than likely break communication.

leppie

Quote
byte WR = Wire.receive();


What is that for? That will be called before setup() and your call to Wire.begin().

rbz

#5
May 29, 2010, 01:17 am Last Edit: May 29, 2010, 12:44 pm by rbz Reason: 1
Okay,

I think this is working, however not sure, as the xbox see's the eeprom but claims its either blank/wrong image.

However can't really check it untill the chip arrives, but I can't see any reason for this code to not work.

I had to remove the Wire.available etc. from the handlers because it doesn't send data fast enough with those functions in (could also be a problem, skipping bytes due to slow processing?)

Code: [Select]
#include <Wire.h>

byte XEEPROM[256] = { 0x5D, 0x26, 0x31, 0x91, 0x3e, 0x12, 0x8e, 0x70, 0xa5, 0x57, 0x3d, 0xed, 0x91, 0x99, 0xb4, 0x11, 0x38, 0xde, 0x1b, 0xd6, 0x4c, 0xd9, 0xf5, 0x13, 0x23, 0x94, 0xb8, 0x3d, 0x9c, 0xb0, 0xc4, 0x54, 0xf0, 0x69, 0xca, 0xb3, 0x28, 0x84, 0xa5, 0xc1, 0x80, 0x53, 0x69, 0x0c, 0x38, 0x4f, 0x0c, 0x74, 0xa1, 0x5b, 0x8c, 0x71, 0x34, 0x30, 0x38, 0x30, 0x30, 0x38, 0x31, 0x35, 0x33, 0x31, 0x30, 0x35, 0x00, 0x12, 0x5a, 0x1e, 0xbd, 0x9e, 0x00, 0x00, 0x02, 0x82, 0x30, 0xaa, 0x10, 0xb7, 0x7f, 0x8d, 0x0a, 0xcb, 0x2e, 0xc1, 0xeb, 0x52, 0x20, 0xdc, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x55, 0x57, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x47, 0x4d, 0x54, 0x00, 0x42, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x02, 0x03, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x68, 0xaa, 0xdd, 0x02, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x01, 0x04, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x01, 0x04, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x12, 0x03, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x02, 0x02, 0x46, 0x45, 0x8f, 0x8f, 0x78, 0x56, 0xbb, 0x69, 0x12, 0x02, 0x84, 0x79, 0x80, 0x00, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00, 0x00 };
static byte rQ;

void setup()
{
 Wire.begin(0x54);
 Wire.onReceive(receiveEvent);
 Wire.onRequest(requestEvent);
}

void loop()
{
}

void requestEvent(){
   Wire.receive();
   Wire.send(XEEPROM[rQ]);
   rQ++;
}

void receiveEvent(int iData){
    rQ = Wire.receive();
}


However still curious if I'm even parsing incoming data right. As if you shift some of the received bytes << by 8. you see it holds the device address / read/write bit / and a number (possibly, the offset to read).

will keep trying.

BenF

There are still a couple issues with your code:

Code: [Select]

void requestEvent(){
   Wire.receive();
   Wire.send(XEEPROM[rQ]);
   rQ++;
}


The requestEvent should only return data - so wire.receive() should go. This may also be the reason why you had issues with using wire.available() - that is you should not expect any data when processing request.

Code: [Select]
static byte rQ;

The rQ variable is modified in an interrupt handler so must be defined with the volatile flag (volatile byte rQ;)

Go Up