[Solved] Flash Memory Programmer "AM29F040B"

First glance:
use only these 3 functions:

void flash_ctrl_deselect()
{
  digitalWrite(OE, HIGH);
  digitalWrite(WE, HIGH);
  digitalWrite(CE, HIGH);
}

void flash_ctrl_rd()
{
  digitalWrite(CE, LOW);
  digitalWrite(OE, LOW);
}

void flash_ctrl_wr()
{
  digitalWrite(CE, LOW);
  digitalWrite(WE, LOW);
}

Mind - for the addresses: the "unsigned int" is 16bit, you need "unsigned long" (or simply uint32).. !! 16+8bit!!

// read a single byte from flash
byte flash_read(unsigned long address)
{
  byte data = 0;  
  flash_ctrl_deselect();
  flash_change_pins_mode(IN);  
  flash_addr_set(address);
  flash_ctrl_rd();  // rd/oe goes LOW
  delayMicroseconds(1);  // 1usec is ok when reading the flash (70ns is min)  
  data = flash_data_get();
  flash_ctrl_deselect();  // rd/oe goes HIGH, cs goes HIGH
  return data;
}

BTW: Polling a bit on the data bus require "while()":

boolean flash_get_DQ7()
{...
while (...) ... ;
..
}

Mind - for the address: the "unsigned int" is 16bit, you need "unsigned long" (or simply uint32).. !! 16+8bit!!

void flash_addr_set(unsigned long address)
{
  digitalWrite(LATCH, LOW);

  // YOU HAVE TO SET THE HIGHEST 8BITS SOMEWHERE !!
  // for example a function:
  set_highest_flash_address(address>>16);

  shiftOut(SERIALDATA, SERIALCLK, MSBFIRST, (address>>8));
  shiftOut(SERIALDATA, SERIALCLK, MSBFIRST, (address&0xFF));
  digitalWrite(LATCH, HIGH);
}
// write flash Command - using min 70ns long write
void flash_write_command(unsigned long address, byte data)
{
    flash_ctrl_deselect();  
    flash_change_pins_mode(OUT);
    flash_addr_set(address);
    flash_data_set(data);
    flash_ctrl_wr();  //wr goes LOW
    delayMicroseconds(1);  // for example 1us delay
    flash_ctrl_deselect();    //wr goes HIGH, cs goes HIGH
}

YOU NEED:

// write flash memory Data byte - with 10ms delay or POLLING the data bit - see the datasheet
void flash_write_data(unsigned long address, byte data)
{
    flash_ctrl_deselect();  
    flash_change_pins_mode(OUT);
    flash_addr_set(address);
    flash_data_set(data);
    flash_ctrl_wr();   //wr goes LOW
    delay(10);  // for example 10ms delay OR POLLING THE DQ7
    flash_ctrl_deselect();    //wr goes HIGH, cs goes HIGH
}
// write single byte into the flash (Commands + Data)
void flash_write(unsigned long address, byte data)
{  
  //Send the command sequence
  flash_write_command(0x555, 0xAA);  //this is with 1usec delay (70ns is enough)
  flash_write_command(0x2AA, 0x55);  //this is with 1usec delay (70ns is enough)
  flash_write_command(0x555, 0xA0);  //this is with 1usec delay (70ns is enough)

//HERE YOU HAVE TO WRITE THE BYTE INTO THE FLASH:
  flash_write_data(address, data);  //this is a write with 10ms delay or with POLLING THE DQ7  
}

The last function in setup() shall be "flash_ctrl_deselect();" that is the default state !

Usually the next step is to check each function, whether it works properly or not (call the single function and check the pins with voltmeter or oscilloscope or logic analyzer). All above functions must work properly.

Be aware of pin direction setting. Double check.

Mind your address is more than 16bit! Try to write a single byte, and read it back. Do it for few addresses, step by step.
Do not expect it will work on the first attempt. It takes time.. There is a lot of signals and wirings you have to clean up.. It takes time..

Do not try to optimize/simplify the code unless it works - it means you flashed/erased your memory successfully at least 20x :slight_smile:

Do not use polling yet - use the 10-20ms delay as described above - 10ms is usually enough flash write time. Do not decrease the time yet. Rather wait few minutes to write the entire flash. When it works rock stable then you may start with code optimization and/or polling the DQx instead of using the fixed delay..
HTH