1

I am trying to connect a CMOS flash memory Winbond W49F002U-12B to an Arduino Mega, but failing.

Winbond W49F002U-12B

What I did:

  1. Read the Winbond W49F002U-12B datasheet. The key points are: CE - chip enabled; OE - output enabled; WE - write enabled and this table:

Winbond W49F002U-12B Operating Modes

  1. Wrote this code and uploaded to Mega2560:

    int A_pins[18] = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
    int DQ_pins[8] = {40, 41, 42, 43, 44, 45, 46, 47};
    int CE = 50;
    int OE = 49;
    int WE = 48;
    
    char ch;
    char addrs[5];
    unsigned long address;
    unsigned int result;
    void setup() {
      Serial.begin(9600);
      for(int i=0; i<18; ++i)
          pinMode(A_pins[i], INPUT);
      for(int i=0; i<8; ++i)
          pinMode(DQ_pins[i], OUTPUT);
      pinMode(CE, OUTPUT);
      pinMode(OE, OUTPUT);
      pinMode(WE, OUTPUT);
      digitalWrite(WE, HIGH);
      digitalWrite(OE, HIGH);
      digitalWrite(CE, LOW);
    
    }
    
    void func(unsigned long adr)
    {
      for(int i=0; i<18; ++i){
        if(adr & (1ul << i)){
          digitalWrite(A_pins[i], HIGH);
          Serial.print("A_pins[");
          Serial.print(i);
          Serial.println("] = HIGH");}
        else{
          digitalWrite(A_pins[i], LOW);}}
      digitalWrite(OE, LOW);
      delay(100);
      for(int i=0; i<8; ++i){
        if(digitalRead(DQ_pins[i]) == HIGH){
          result|=1<<i;
          Serial.print("DQ_pins[");
          Serial.print(i);
          Serial.println("] = HIGH");}
      }
      Serial.println(result);
      digitalWrite(OE, HIGH);
    }
    
    void loop() {
      if (Serial.available() > 0)
      {
       address = (unsigned long)Serial.parseInt();
       Serial.print("address = ");
       Serial.println(address);
       func(address);
       }
    }
    

What this code is doing is basically after reading serial:

-> takes the value as address

-> changes pins A0-A17 to select particular address cell

-> changes OE to LOW

-> reads DQ0-DQ7

-> coverts those readings into int

-> prints result out.

Example of Arduino IDE Serial Monitor inputs/ouputs stuff:

address = 0
0
address = 1232
A_pins[4] = HIGH
A_pins[6] = HIGH
A_pins[7] = HIGH
A_pins[10] = HIGH
0
address = 131072
A_pins[17] = HIGH
0
address = 245760
A_pins[14] = HIGH
A_pins[15] = HIGH
A_pins[16] = HIGH
A_pins[17] = HIGH
0

Arduino Mega board is 100% functioning. I don't think Winbond w49f002u-12b is not working. Where am I wrong?

UPDATE: Here is fixed code:

int A_pins[18] = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
int DQ_pins[8] = {40, 41, 42, 43, 44, 45, 46, 47};
int CE = 50;
int OE = 49;
int WE = 48;

unsigned long address;
unsigned int result;
void setup() {
  Serial.begin(9600);
  for(int i=0; i<18; ++i)
      pinMode(A_pins[i], OUTPUT);
  for(int i=0; i<8; ++i)
      pinMode(DQ_pins[i], INPUT);
  pinMode(CE, OUTPUT);
  pinMode(OE, OUTPUT);
  pinMode(WE, OUTPUT);
  digitalWrite(WE, HIGH);
  digitalWrite(OE, HIGH);
  digitalWrite(CE, LOW);

}

void func(unsigned long adr)
{
  result = 0;
  for(int i=0; i<18; ++i){
    if(adr & (1ul << i)){
      digitalWrite(A_pins[i], HIGH);
    }
    else{
      digitalWrite(A_pins[i], LOW);}}
  digitalWrite(OE, LOW);
  //delay(100);
  for(int i=0; i<8; ++i){
    if(digitalRead(DQ_pins[i]) == HIGH){
      result|=1<<i;
    }}
  Serial.println(result);
  digitalWrite(OE, HIGH);
}

void loop() {
  if (Serial.available() > 0)
  {
   address = (unsigned long)Serial.parseInt();
   Serial.print(address);
   Serial.print(": ");
   func(address);
   }
}

UPDATE: Changed code using PORTs, Thanks to @MikaelPatel for reminding about PORTs:

unsigned long address;

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

  DDRL = B00000000; //  DQ7-DQ0 42-49
  DDRA = B11111111; //  A7-A0   29-22
  DDRC = B11111111; //  A15-A8  30-37
  DDRG |= B00000011; // A17-A16 40-41
  DDRB |= B00000111; // WE, OE, CE

  PORTB = B00000110; // WE - HIGH, OE - HIGH, CE - LOW
}

void func(unsigned long adr)
{
  PORTA = adr;
  PORTC = (adr>>8L);
  PORTG = (adr>>16L);
  PORTB = B00000100; //OE - LOW
  Serial.println(PINL);
  PORTB = B00000110; //OE - HIGH
}

void loop() {
  if (Serial.available() > 0)
  {
   address = (unsigned long)Serial.parseInt();
   Serial.print(address);
   Serial.print(": ");
   func(address);
   }
}
  • RESET is connected to 5 VCC. Windbond chip's pins are not shorted (checked). Breadboard is good, everything is connected. – Qeeet Feb 20 '16 at 20:27
  • That was a great update and it looks like you did the optimization. There are some small details if you intend to move towards a general device driver library but this is a good starting point! Nice work! – Mikael Patel Feb 21 '16 at 18:34
0

What this code is doing is basically after reading serial: ... -> reads DQ0-DQ7

But all the DQn pins are in OUTPUT mode and the A pins in INPUT mode. Seems to be a mix up. BW: it is the same with all of the pins. The pin mode is from the Arduinos point of view and not the memory chip.

Cheers!

  • Hi. Maybe I'm understanding you incorrectly, but from Arduino board point of view, atmega2560 controls/sets address A, and then reads DQ, therefore A - output, DQ - input – Qeeet Feb 20 '16 at 23:47
  • Your code says the opposite. Check the setup(). – Mikael Patel Feb 21 '16 at 0:18
  • omg, what a dumb. I am ashamed. Such stupid mistake. Thank you for pointing this out. Now it works :D – Qeeet Feb 21 '16 at 10:51
  • You might want to consider using the port directly and assigning the address and read/write data in a single operation. With all the digitalWrite() and digitalRead() this will more less be the same performance as a serial EEPROM on I2C. An SPI EEPROM/Flash would be faster. – Mikael Patel Feb 21 '16 at 11:03
  • I just have this chip. Just wanted to read data, to use it in some way. Don't want to throw it out. But what do you mean saying "using the port directly"? – Qeeet Feb 21 '16 at 11:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.