writing to to an eeprom

I am trying to work with the Arduino spi eeprom tutorial.

I am trying to do a page write to ST95020
Datasheet: https://www.st.com/resource/en/datasheet/cd00001755.pdf

Here is the code I am working with

#define DATAOUT 11//MOSI
#define DATAIN  12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
int address=0;
//data buffer
char buffer [256];

void fill_buffer()
{
  for (int I=0;I<256;I++)
  {
    buffer[I]=I;
  }
}

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

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

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  //fill buffer with data
  fill_buffer();
  //fill eeprom w/ buffer
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WREN); //write enable
  digitalWrite(SLAVESELECT,HIGH);
  delay(10);
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WRITE); //write instruction
  address=0;
  spi_transfer((char)(address>>8));   //send MSByte address first
  spi_transfer((char)(address));      //send LSByte address
  //write 128 bytes
  for (int I=0;I<256;I++)
  {
    spi_transfer(buffer[I]); //write data byte
  }
  digitalWrite(SLAVESELECT,HIGH); //release chip
  //wait for eeprom to finish writing
  delay(3000);
  Serial.print('h');
  Serial.print('i');
  Serial.print('\n');//debug
  delay(1000);
}

byte read_eeprom(int EEPROM_address)
{
  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ); //transmit read opcode
  spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
  spi_transfer((char)(EEPROM_address));      //send LSByte address
  data = spi_transfer(0xFF); //get data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;
}

void loop()
{
  eeprom_output_data = read_eeprom(address);
  Serial.print(eeprom_output_data,DEC);
  Serial.print('\n');
  address++;
  if (address == 256)
    address = 0;
  delay(500); //pause for readability
}

The problem I am having is that the write from buffer is only filling out the first 16 bytes of the eeprom. but according to the datasheet for the ST95020 a page write is done the way the code is written unless I am just confused( I am very confused I have no real experience programming). I want it to fill out the entire eeprom. I am just trying to get the write function of this tutorial to work so I can use it in a project I am working on.

If you would take a moment to look at the data sheet, you will discover that a page is 16 bytes.

but if you pull don't chip select high shouldn't it move to the next page? if not how would you make the for loop do it 16 byte segments? PS. Thank you for your help 2 days in row!

The code you copied writes to only the first page.

You will need to do a bit of math, and increment the write address in such a way to write to successive pages, for as many pages as the device has.

This should not go in loop(), which repeats forever.

I guess I am just confused because that tutorial explains it as if you can send all the data and the eeprom will handle it. Maybe the chip they used handle it like that but this one wont.

Now we pull the SLAVESELECT line low to select the device again after a brief delay. We send a WRITE instruction to tell the EEPROM we will be sending data to record into memory. We send the 16 bit address to begin writing at in two bytes, Most Significant Bit first. Next we send our 128 bytes of data from our buffer array, one byte after another without pause. Finally we set the SLAVESELECT pin high to release the device and pause to allow the EEPROM to write the data:

The tutorial was written for the AT25HP512, which has a 128 byte page.

You cannot simply assume that the code will work, unmodified, with any other EEPROM. You really need to go through the data sheet for each different device.

Frankly, I'm surprised that the ST95020 works properly, despite the fact that you throw 256 bytes at it.

well the OP codes are the same ( at least read/write). I did at least check that I honestly made an assumption that page size is just the size of the EEprom after you said look at the data sheet for page size I saw that on the first page of the datasheet. Then I just assumed I was wrong all together of what a page was. I see what you mean on the datasheet for AT25HP512 about the page size of it.

The wiring may or may not be the same I just made I was I sent CS, MISO and MOSI to the right pins of my eeprom didn't follow the wiring from the tutorial.

You got the wiring right! Out of curiosity, which 16 bytes ended up in the EEPROM page?

I expect either the first or last set of 16 in the 256 byte buffer.

FFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE

The last set then, in complete agreement with the data sheet.

In the case of Figure 12: Byte Write (WRITE) sequence, Chip Select (S) is driven high after the eighth bit of the data byte has been latched in, indicating that the instruction is being used to write a single byte. If, though, Chip Select (S) continues to be driven low, as shown in Figure 13: Page Write (WRITE) sequence, the next byte of input data is shifted in, so that more than a single byte, starting from the given address towards the end of the same page, can be written in a single internal Write cycle. If Chip Select (S) still continues to be driven low, the next byte of input data is shifted in, and used to overwrite the byte at the start of the current page.

OK stupid question why does this not just write 1 byte at a time for the whole thing?

for (int I=0;I<256;I++)
  {
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WREN); //write enable
  digitalWrite(SLAVESELECT,HIGH);
  delay(10);
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WRITE); //write instruction
  address=I;
  spi_transfer((char)(address>>8));   //send MSByte address first
  spi_transfer((char)(address));      //send LSByte address


    spi_transfer(buffer[I]); //write data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip
  }

So if run that it ends up FEFEF1F2F3F4F5F6F7F8F9FAFBFCFDFE I think only the first 2 bytes change but I can erase the eeprom to verify that. If that helps?

Sorry if I’m totally insulting your intelligence I just completely out of my wheel I fix circuit boards as a hobby. I really want to make my own programmer that will write in circuit on a board I enable transmission temperature on a lot. At the moment I have to pull the EEprom off the board because TL866 goes into to over current if I do it in circuit. The arduino is working I just dont know what I am doing.

I really appreciate the help. Edit: each byte has an address right or have gone full special ed?

You need to go through the code, line by line, and make sure you understand what each line does. Otherwise you are just flailing around.

For example: these three lines set the start address in eeprom memory of the first byte to write, and send that address to the chip.

  address=0;
  spi_transfer((char)(address>>8));   //send MSByte address first
  spi_transfer((char)(address));      //send LSByte address

If you don’t want to start writing at address 0, put in a different value. The next page up starts at address 16.

As the quote from the data sheet above explains, you can write between 1 and 16 bytes in one operation.

Shouldn't

 address=I;

Start at 0 and move up 1 per cycle of the For loop?

I mean I am ok with being slower thats only 1,280‬ mil so that not that bad of write time and that last code in post 10 was only sending 1 byte per cycle. but it doesn't seem to be going address to address but I didn't give it a 5 mil delay per cycle. It seems like that addressing system isn't working at all.