spi 9bit eeprom address can only see addr 0x00?

greetings all,
im having trouble getting this eeprom to work correctly - x5045 http://www.intersil.com/content/dam/Intersil/documents/fn81/fn8126.pdf - it takes a 9 bit address i think "datasheet - page 8, table 1 instruction set. i was able to write a value to addr 0 and read it, but thats the only address i can see, i used the following sketch because of the 9 bits, but this is the only way it works for that one address, cant see any others, obviously i have no idea what im doing wrong, any advice please?

#include <SPI.h>
#define WRITE 2
#define READ  3
#define WREN  6
#define RDSR  5
#define WRSR  1



unsigned int address = 0x00;
byte outval = 243;
byte invalue;

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


  
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV4); // max clock is 20MHz, so can set high speed
  SPI.begin(); // sets up pin modes etc.
  // Enable writing

  digitalWrite(SS, LOW);
  SPI.transfer(WREN);
  digitalWrite(SS, HIGH);
  
  digitalWrite(SS, LOW); 
  SPI.transfer(READ); // read instruction

  SPI.transfer(address >> 16) ;
  SPI.transfer(address >> 8 );
  SPI.transfer(address );
  invalue = SPI.transfer(0);        // Clock out the data
  digitalWrite(SS, HIGH);
  Serial.print(F("Read Data = "));
  Serial.println(invalue,DEC);

}

void loop(){}

In my interpretation of the datasheet, your write operation should look like this:

digitalWrite(SS,LOW);
SPI.transfer(WRITE | (address & 0x0100) ? 8 : 0);
SPI.transfer(address & 0xFF);
SPI.transfer(outval);
digitalWrite(SS, HIGH);

while the read operation should look like this:

digitalWrite(SS,LOW);
SPI.transfer(READ | (address & 0x0100) ? 8 : 0);
SPI.transfer(address & 0xFF);
inval = SPI.transfer(0x00);
digitalWrite(SS,HIGH);

thank you for your reply pylon, im still not getting anything, any reads/writes still shows up as '0'.

Post the code your using for this.

//4k e2prom and cpu supervisor

#include <SPI.h>
#define WRITE 2
#define READ  3
#define WREN  6
#define RDSR  5
#define WRSR  1

unsigned int address = 0x01;
byte outval = 250;
byte invalue;

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

  // set up to match device datasheet
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2); // max clock is 20MHz, so can set high speed
  SPI.begin(); // sets up pin modes etc.
  // Enable writing

  digitalWrite(SS, LOW);
  SPI.transfer(WREN);
  digitalWrite(SS, HIGH);
  
  digitalWrite(SS, LOW);
  SPI.transfer(WRITE); // write instruction
  SPI.transfer((address >> 16) & 255);
  SPI.transfer(address >> 8 & 255);
  SPI.transfer(address & 255);
  SPI.transfer(outval);
  digitalWrite(SS, HIGH);
  delay(5);
  digitalWrite(SS, LOW); 
  SPI.transfer(READ); // read instruction

  SPI.transfer((address >> 16) & 255);
  SPI.transfer(address >> 8 & 255);
  SPI.transfer(address & 255);
  invalue = SPI.transfer(0);        // Clock out the data
  digitalWrite(SS, HIGH);
  Serial.print("Read Data = "));
  Serial.println(invalue,DEC);

}

void loop(){
 
}

i am able to write to one address, im assuming its 0, no matter what i make it. ive also tried your code.

//4k e2prom and cpu supervisor

#include <SPI.h>
#define WRITE 2
#define READ  3
#define WREN  6
#define RDSR  5
#define WRSR  1

unsigned int address = 0x01;
byte outval = 250;
byte invalue;

void setup(){
  Serial.begin(9600);
Serial.println("RESET");

  // set up to match device datasheet
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2); // max clock is 20MHz, so can set high speed
  SPI.begin(); // sets up pin modes etc.
  // Enable writing

  digitalWrite(SS, LOW);
  SPI.transfer(WREN);
  digitalWrite(SS, HIGH);

digitalWrite(SS,LOW);
SPI.transfer(WRITE | (address & 0x0100) ? 8 : 0);
SPI.transfer(address & 0xFF);
SPI.transfer(outval);
digitalWrite(SS, HIGH);


digitalWrite(SS,LOW);
SPI.transfer(READ | (address & 0x0100) ? 8 : 0);
SPI.transfer(address & 0xFF);
invalue = SPI.transfer(0x00);
digitalWrite(SS,HIGH);

this is what interil told me to look at, i cannot however translate this to arduino, any help appreciated.

http://www.intersil.com/content/dam/Intersil/documents/an21/an21.pdf

this is what interil told me to look at, i cannot however translate this to arduino

Looks like the chip has to be initialized a bit further before being ready:

//4k e2prom and cpu supervisor

#include <SPI.h>
#define WRITE 2
#define READ  3
#define WREN  6
#define RDSR  5
#define WRSR  1

unsigned int address = 0x01;
byte outval = 250;
byte invalue;

void setup(){
  Serial.begin(9600);
  Serial.println("RESET");

  // set up to match device datasheet
  SPI.begin(); // sets up pin modes etc.
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2); // max clock is 20MHz, so can set high speed

  // Enable writing
  digitalWrite(SS, LOW);
  SPI.transfer(WREN);
  digitalWrite(SS, HIGH);

  // Initialize status register
  digitalWrite(SS, LOW);
  SPI.transfer(WRSR);
  SPI.transfer(0x00);
  digitalWrite(SS, HIGH);

  // Latch enable write again (don't know why this is necessary)
  digitalWrite(SS, LOW);
  SPI.transfer(WREN);
  digitalWrite(SS, HIGH);

  // write a value to address 0x01
  digitalWrite(SS,LOW);
  SPI.transfer(WRITE | (address & 0x0100) ? 8 : 0);
  SPI.transfer(address & 0xFF);
  SPI.transfer(outval);
  digitalWrite(SS, HIGH);

  // read a value from address 0x01
  digitalWrite(SS,LOW);
  SPI.transfer(READ | (address & 0x0100) ? 8 : 0);
  SPI.transfer(address & 0xFF);
  invalue = SPI.transfer(0x00);
  digitalWrite(SS,HIGH);
  Serial.print("Read Data = ");
  Serial.println(invalue,DEC);
}

void loop() {
}

What’s the output of this sketch?

hi pylon,
heres results

im also working on this, i would have just thrown the chip aside by now usually, but i soldered it (soic8) on an adapter board (5 for $5.95 adafruit) so its kind of a challenge, ill never be able to figure this out on my own though, but im trying :smiley:

Just to be sure we don’t get problems from operator priority, please try this version too:

//4k e2prom and cpu supervisor

#include <SPI.h>
#define WRITE 2
#define READ  3
#define WREN  6
#define RDSR  5
#define WRSR  1

unsigned int address = 0x01;
byte outval = 250;
byte invalue;

void setup(){
  Serial.begin(9600);
  Serial.println("RESET");

  // set up to match device datasheet
  SPI.begin(); // sets up pin modes etc.
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2); // max clock is 20MHz, so can set high speed

  // Enable writing
  digitalWrite(SS, LOW);
  SPI.transfer(WREN);
  digitalWrite(SS, HIGH);

  // Initialize status register
  digitalWrite(SS, LOW);
  SPI.transfer(WRSR);
  SPI.transfer(0x00);
  digitalWrite(SS, HIGH);

  // Latch enable write again (don't know why this is necessary)
  digitalWrite(SS, LOW);
  SPI.transfer(WREN);
  digitalWrite(SS, HIGH);

  // write a value to address 0x01
  digitalWrite(SS,LOW);
  SPI.transfer(WRITE | ((address & 0x0100) ? 8 : 0));
  SPI.transfer(address & 0xFF);
  SPI.transfer(outval);
  digitalWrite(SS, HIGH);

  // read a value from address 0x01
  digitalWrite(SS,LOW);
  SPI.transfer(READ | ((address & 0x0100) ? 8 : 0));
  SPI.transfer(address & 0xFF);
  invalue = SPI.transfer(0x00);
  digitalWrite(SS,HIGH);
  Serial.print("Read Data = ");
  Serial.println(invalue,DEC);
}

void loop() {
}

same results. one thing, the chip speed is 3.3mhz, do i have that set correctly?

SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2); // max clock is 20MHz, so can set high speed

how about this i found this but it was the only file i could grab, that site wanted $$ for me to download the rest

#include "spi.h"   
#include "serial.h"   
#include <intrins.h>   
#define NOP()  // _nop_();_nop_()   
   
//¿´ÃŹ·Ð´Ê¹ÄÜ×Ó³ÌÐò   
  void wren_dog(void)   
  {   
    SPI_SCK=0;   
    SPI_CS=0;   
    in_byte(WREN);   
    SPI_SCK=0;   
    SPI_CS=1;   
  }   
   
//¿´ÃŹ·Ð´½ûÖ¹×Ó³ÌÐò   
  void wrdi_dog(void)   
 {   
    SPI_SCK=0;   
    SPI_CS=0;   
    in_byte(WRDI);   
    SPI_SCK=0;   
    SPI_CS=1;   
  }   
   
   
   
//д״̬¼Ä´æÆ÷   
  void wrsr_dog(unsigned char status_reg)   
 {   
    SPI_SCK=0;   
    SPI_CS=0;   
    in_byte(WRSR);   
    in_byte(status_reg);   
    SPI_SCK=0;   
    SPI_CS=1;   
    wip_poll();   
  }   
   
   
//¶Á״̬¼Ä´æÆ÷   
 unsigned char rdsr_dog(void)   
 {   
    unsigned char reg1;   
    SPI_SCK=0;   
    SPI_CS=0;   
    in_byte(RDSR);   
    reg1=out_byte();   
    SPI_SCK=0;   
    SPI_CS=1;   
    return(reg1);   
 }   
   
//×Ö½Ú¶Á   
//H,µØÖ·¸ß×Ö½Ú£»LµØÖ·µÍ×Ö½Ú£»data_dog¶Á³öµÄÊý¾Ý   
  unsigned char byte_read(unsigned char H,unsigned char L)   
 {   
    unsigned char data_dog,add=0;   
    SPI_SCK=0;   
    SPI_CS=0;   
    add=H<<3;   
    add|=READ;//READ;   
    in_byte(add);   
    add=L;   
    in_byte(add);   
    data_dog=out_byte();   
    SPI_SCK=0;   
    SPI_CS=1;   
    return(data_dog);   
  }   
//×Ö½Úд   
//H,µØÖ·¸ß×Ö½Ú£»LµØÖ·µÍ×Ö½Ú£»DдÈëµÄÊý¾Ý   
  void byte_write(unsigned char H,unsigned char L,unsigned char D)   
 {   
    unsigned char data_dog,add=0;   
    SPI_SCK=0;   
    SPI_CS=0;   
    add=H<<3;   
    add|=WRTE;//WRTE;   
    in_byte(add);   
    add=L;   
    in_byte(add);   
    data_dog=D;   
    in_byte(data_dog);   
    SPI_SCK=0;   
    SPI_CS=1;   
    wip_poll();   
  }   
   
//¸´Î»¿´ÃŹ·×Ó³ÌÐò   
  void rest_dog(void)   
 {   
    SPI_CS=0;   
    SPI_CS=1;   
  }   
   
//¼ìÑéд²Ù×÷ÊÇ·ñ½áÊø¡£   
  unsigned char wip_poll(void)   
 {   
    unsigned char i;   
    unsigned char wip;   
    for(i=0xff;i>=1;i--)    
    {   
        wip=rdsr_dog();   
        wip&=0x01;   
        if(wip==0) break;   
    }   
   return(wip);   
 }   
   
//µ¥×Ö½ÚÖ¸Áî»òÊý¾ÝдÈëX25045   
//ÔÚSPI_SIÏßÉÏÊäÈëµÄÊý¾ÝÔÚSPI_SCKµÄÉÏÉýÑر»Ëø´æ¡£   
  void in_byte(unsigned char byt)   
  {   
    unsigned char i;   
    for(i=0;i<8;i++)   
    {   
        SPI_SCK=0;    
        SPI_SI=byt&0x80;   
        SPI_SCK=1;   
        byt<<=1;    
    }   
    SPI_SI=0;   
  }   
   
//µ¥×Ö½ÚÊý¾Ý´ÓX25045¶Áµ½µ¥Æ¬»ú   
//Êý¾ÝÓÉSPI_SCKµÄϽµÑØÊä³öµ½SPI_SOÏßÉÏ¡£   
  unsigned char out_byte(void)   
  {   
    unsigned char i;   
    unsigned char byt=0;   
    for(i=0;i<8;i++)   
    {   
        byt=byt<<1;   
        SPI_SCK=1;   
        SPI_SCK=0;   
        byt|=SPI_SO;   
    }   
    return (byt);   
  }     
   
   
/**************************************************/   
void main(void)   
{   
  unsigned char D;    
  unsigned char add_H=0x01,add_L=0x00;   
  unsigned char ucDATA=0x11;   
  init_serial();   
  while(1)   
    {   
        //wren_dog();   
        //wrsr_dog(0);   
        //wren_dog();      
        byte_write(add_H,(add_L++),(ucDATA++));   
        D=byte_read(add_H,add_L);    
        PutChar(D);     
     }   
}

same results. one thing, the chip speed is 3.3mhz, do i have that set correctly?

Where is this comment coming from then?

max clock is 20MHz, so can set high speed

You have to slow down the communication in this case then:

SPI.setClockDivider(SPI_CLOCK_DIV8); // max speed is 3MHz, we choose 2MHz

Does that change anything?

Where is this comment coming from then?

sorry that comment left over from spi tutorial i just copy/paste it for my spi chips.

same results

How did you connect the chip to the Arduino? Describe every connection made or draw a schematics or post a photo show all.

x5045 Arduino Uno
pin 1 pin10 cs/ss
pin2 pin12
pin3 5v
pin4 gnd
pin5 pin11
pin6 pin13 sclk
pin7 no connection
pin8 5v

Pinout looks good - you have decoupling on the chip? You need it. Keep the SPI wiring short and bundled
together with the ground/supply wires for good measure.

Also when talking to a new SPI chip like this the first thing to do is read the any status registers and
see if the bits coming out make sense. Once thats working you have confidence the basic comms
is functioning - one step at a time is how things are made to work... Be methodical and check everything
twice - its surprising how often that fixes things.

Then for a memory chip implement READ - the inital values for EEPROMs are usually all 0xFF, check
its returning what is expected.

Then implement WRITE - if you think you've got write working on address 0, write a 0xAA (or any unique
pattern you will recognise) and read back all the memory - this will tell you for sure what's working.

leads are about 3 inches, tried everything you said, its only writing the first value (using a for loop to write a few different values) and reading that value back no matter how many address' i cycle through. i really appreciate you guys trying to decipher this but maybe ill order some i2c 256kbit eeproms and just nix the cpu supervisor all together, too bad PaulS or Nick Gammon wont comment i bet you they can figure it out in about 10 seconds :wink:

you know if it wasnt for Nick Gammon's website alot of my projects wouldnt be, he answers just about everything ive ever wondered how to do with my arduino. thanks Nick for sharing the knowledge. today im dumping a bootloader on a blank atmega328p using Mr. Gammon's method/sketch. Gammon Forum : Electronics : Microprocessors : Atmega bootloader programmer