Go Down

Topic: [Solved] Flash Memory Programmer "AM29F040B" (Read 16526 times) previous topic - next topic

BlackSharp

Hello There,

Sorry for the delay for this subject I didn't write something since 2 weeks or more.
However, I would like to tell you that my project works perfect now using "AM29F010" not the "F040B" because they were corrupted but I think they are the same (with little bit changes, see the datasheet for those who want more info).
I'm able to read, write, erase and even get the chip code from autoselect mode. I weep for joy  =( (Kidding).

The trick was that one of my arduino data pin had a floating state (I don't know til now why just one pin ? I have changed just my resistor and that's it) and even if my code was correct the chip didn't receive the correct signal. So, I follow what Pito told me before: Check & double check the circuit also don't forget to check the floating states of arduino pins.

This reply is just for those who wants to build up a flash memory programmer using arduino UNO, You can find also below  the arduino code for more information (This is the first version may be another one later ...).


Code: [Select]

/* @Author: Radouane SAMIR
   @Version: 0.1
   @Chip version: AM29F010 (It will work also for AM29F040B with little bit changes)
   
   For AM29F040B the command sequence are little bit different:
   0x555 rather than 0x5555 see the datasheet. But the timing is the same
*/

#include <avr/io.h>
#include <util/delay.h>

void flash_change_pins_mode(boolean io)
{
  if (io) {
    for (int i = 2; i < 10; i++)
    pinMode(i, INPUT);
  }
  else
  {
    for (int i = 2; i < 10; i++)
    pinMode(i, OUTPUT);
  }
}

void flash_ctrl_deselect()
{
  digitalWrite(10, HIGH); //CE
  digitalWrite(12, HIGH);//WE
  digitalWrite(11, HIGH); //OE
}

void flash_ctrl_rd()
{
  digitalWrite(11, LOW);
  _delay_us(1);
  digitalWrite(10, LOW);
  _delay_us(1);
}

void flash_ctrl_wr()
{
  digitalWrite(10, LOW);
  _delay_us(1);
  digitalWrite(12, LOW);
  _delay_us(1);


void flash_set_highest_addresses(uint16_t addr)
{
  /* Highest addresses */
 
  if (addr&bit(0))
  PORTC |= _BV(PORTC2);
  else
  PORTC &= ~_BV(PORTC2);
 
  if (addr&bit(1))
  PORTC |= _BV(PORTC1);
  else
  PORTC &= ~_BV(PORTC1);
 
  if (addr&bit(2))
  PORTC |= _BV(PORTC0);
  else
  PORTC &= ~_BV(PORTC0);
}

void flash_enable_latch()
{
  /* Shift register Latch */
  digitalWrite(A4, HIGH);
}

void flash_disable_latch()
{
  digitalWrite(A4, LOW);
}

void flash_enable_serial_clock()
{
  /* Shift register Serial clock */
  digitalWrite(A3, HIGH);
}

void flash_disable_serial_clock()
{
  digitalWrite(A3, LOW);
}

void flash_send_serial_data(uint16_t data)
{
  /* Shift register manipulation */
  /* Check your wiring before */
 
  uint16_t addr = 0;
  byte octect1 = 0;
  byte octect2 = 0;
 
  addr = (data<<8);
  octect1 = (addr>>8);
 
  addr = (data>>8);
  octect2 = addr;
 
  flash_disable_latch();
  for (int i=7;i>=0; i--)
  {
    flash_disable_serial_clock();
    if (octect2&(1<<i))
    PORTC |= _BV(PORTC5);
    else
    PORTC &= ~_BV(PORTC5);
    flash_enable_serial_clock();
  }
 
 
  for (int i=7;i>=0; i--)
  {
    flash_disable_serial_clock();
    if (octect1&(1<<i))
    PORTC |= _BV(PORTC5);
    else
    PORTC &= ~_BV(PORTC5);
    flash_enable_serial_clock();
  }
  flash_enable_latch();
}

void flash_addr_set(uint32_t addr)
{
  /* Send address  to the shift register and arduino pins */
 
  uint16_t LSB;
  uint16_t MSB;
 
  LSB = addr;
  MSB = (addr>>16);
 
  flash_send_serial_data(LSB);
  flash_set_highest_addresses(MSB);
}

void flash_data_set(uint8_t data)

  /* Put data on the chip data bus */
  for (int i = 0; i < 8; i++)
  {
    if (!(data&(1<<i)))
    {
      digitalWrite(i+2, LOW);
      pinMode(i+2, INPUT);
    }
    else if (data&(1<<i))
    {
     pinMode(i+2, OUTPUT);
     digitalWrite(i+2, HIGH);
    }
   
  }
}

byte flash_data_get()
{
  /* get data from data bus */
 
  byte data = 0;
  boolean state = LOW;
  boolean state2 = LOW;
 
  for (int i = 2, j = 0; i <= 9; i++, j++)
  {
        state = digitalRead(i); 
        state2 = digitalRead(i);
        if (state == state2)
           if (state == HIGH)
           bitWrite(data, j, HIGH);
           
  }
  return data;
}

void flash_send_command(uint32_t addr, uint8_t data)
{
  /* Send command sequence */
 
  flash_addr_set(addr);
  delay(1);
  flash_ctrl_wr();

  flash_data_set(data);
  delay(1);
}

void flash_device_id()
{
  /* This is used to get code identification
   * from the chip in autoselect mode
   * See the datasheet
   ******************************************/
 
  flash_ctrl_deselect();
 
  //digitalWrite(11, HIGH);
 
  delay(1000);
 
  flash_change_pins_mode(0);
 
  flash_send_command(0x5555, 0xAA);
  flash_ctrl_deselect();
 
 
  flash_send_command(0x2AAA, 0x55);
  flash_ctrl_deselect();
 
  flash_send_command(0x5555, 0x90);
  flash_ctrl_deselect();

  delay(1000);
 
  flash_change_pins_mode(1);

  flash_addr_set(0x01);
  delay(1);
  flash_ctrl_rd();

  Serial.print("The device ID is: ");
  Serial.println(flash_data_get(), HEX);
  Serial.print("Get device ID complete, Please wait restarting the chip ... ");
  flash_reset_chip();
  Serial.println("Done.");
  delay(1);
  flash_ctrl_deselect();
}

void flash_get_id()
{
  /* This is used to get code identification
   * from the chip in autoselect mode
   * See the datasheet
   ******************************************/
   
  flash_ctrl_deselect();
 
  //digitalWrite(11, HIGH);
 
  delay(1000);
 
  flash_change_pins_mode(0);
 
  flash_send_command(0x5555, 0xAA);
  flash_ctrl_deselect();
 
  flash_send_command(0x2AAA, 0x55);
  flash_ctrl_deselect();
 
  flash_send_command(0x5555, 0x90);
  flash_ctrl_deselect();

  delay(1000);
 
  flash_change_pins_mode(1);

  flash_addr_set(0x00);
  delay(1);
  flash_ctrl_rd();

  Serial.println(flash_data_get(), HEX);
  delay(1);
  flash_ctrl_deselect();
  Serial.println("Finish");
}

void flash_read_memory(uint32_t addr)
{
  /* Read the chip until the address given */
 
  int c = 0;
  for (uint32_t i = 0; i < addr; i++)
  {
    flash_ctrl_deselect();
    delay(1);
   
    flash_addr_set(i);
    delay(1);
   
    flash_ctrl_rd();
    delay(1);
   
    flash_change_pins_mode(1);
    delay(1);
   
    Serial.print(flash_data_get(), HEX);
    if (c++ == 16)
    {
      c = 0;
      Serial.println("");
    } 
    flash_ctrl_deselect();
  }
}

void flash_program_byte(uint32_t addr, uint8_t data)
{
  flash_ctrl_deselect();
  delay(1000);
 
  flash_change_pins_mode(0);
 
  flash_send_command(0x5555, 0xAA);
  flash_ctrl_deselect();
 
  flash_send_command(0x2AAA, 0x55);
  flash_ctrl_deselect();
 
  flash_send_command(0x5555, 0xA0);
  flash_ctrl_deselect();
 
  //Program Address & Program data
  flash_send_command(addr, data);
  flash_ctrl_deselect();

  delay(1000);
}

void flash_reset_chip()
{
  /* This is reset command for the AM29F010 */
 
  flash_ctrl_deselect();
 
  flash_send_command(0x5555, 0xAA);
  flash_ctrl_deselect();
 
  flash_send_command(0x2AAA, 0x55);
  flash_ctrl_deselect();
 
  flash_send_command(0x5555, 0xF0);
  flash_ctrl_deselect();
 
  delay(1000);
}

void flash_erase_memory()
{
  flash_ctrl_deselect();
  delay(1000);
 
  flash_change_pins_mode(0);
 
  flash_send_command(0x5555, 0xAA);
  flash_ctrl_deselect();
 
  flash_send_command(0x2AAA, 0x55);
  flash_ctrl_deselect();
 
  flash_send_command(0x5555, 0x80);
  flash_ctrl_deselect();
 
  flash_send_command(0x5555, 0xAA);
  flash_ctrl_deselect();
 
  flash_send_command(0x2AAA, 0x55);
  flash_ctrl_deselect();
 
  flash_send_command(0x5555, 0x10);
  flash_ctrl_deselect();
 
  delay(3000);
  Serial.println("Erase finished");
}

void setup()
{
  Serial.begin(9600);
  //ANALOG_CONFIG;
 
  int c = 0;

  //Set the shift register pins
 
  pinMode(A5, OUTPUT);
  pinMode(A4, OUTPUT);
  pinMode(A3, OUTPUT);
 
  //set the highest address pins
 
  pinMode(A2, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A0, OUTPUT);
 
  //Set the chip controller
 
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
 
  //Set data pin mode
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
 
  delay(1000);
  //flash_device_id();
  //flash_erase_memory();
  //flash_read_memory(0xFF);
/* for (int i =0; i < 10; i++) {
  flash_program_byte(i, i);
  }*/
}

void loop()
{
  while(1);
}


I would to thank all of you guys (Pito, kf2qd) for your efforts and getting involved in my project.

See you soon guys later with a new topic (new problem :D).

Thanks.

BlackSharp

Hi to everyone in this forum,

After many requests from other people asking for a final circuit diagram and the final code of the Flash Memory Programmer, I have decided to make a Fritzing diagram quickly hoping that will help  those who are  concerned about.

This is my github: https://github.com/warber0x/FMPUNO.

You are free to download any file there and use the code as you want, just keep my name in the author title please.
You'll find also a python GUI Program which allows you to program the chip easily. I recommand to read the README file at first before any attempt.

You can send me a PM if anyone need more comprehension in any section related to this project. The goal is to learn from other people's experiences.

Hope that I'll help you out with this Git. One thing is sure, this project is more fun than it appears so enjoy!!!

Bye.






Go Up