Flash Mem Soldering Help

Status
Not open for further replies.

Dionysus

Active member
Specs: Teensy 4.0 with Audio shield Rev D and a W25Q126JVSIQ-ND memory chip from digi-key.

I am still struggling to get this working; just about the last piece of my puzzle. I was getting Erase Everything to work, but couldn't get RawHardwareTest's full approval. So I used solder braid to desolder everything, pried off the chip, and cleaned everything up with alcohol.

I put a drop of soldern on each of the six contacts, and then positioned a fresh clean chip (also from digikey) over it and heated down all six legs until the solder melted and it was stuck on.

That didn't do anything—EraseEverything no longer erases anything, it just says "Unable to access SPI Flash chip".

So I added some more solder to the tops of the legs, but that didn't do anything except make it look messier. Nothing looks like it's bridging, but EraseEverything is still refusing to play.

I've ordered a brand new AudioShield, and I have one remaining memory chip. I really want to get this to work! Can you recommend anything I should do differently this time?

I'm just using the standard example EraseEverything, but I'll post it here just in case. Thanks again for all your help with this. It's just frustrating because I don't even really know how to debug what's wrong.

IMG_20200527_170440.jpg


Code:
#include <SerialFlash.h>
#include <SPI.h>

const int FlashChipSelect = 6; // digital pin for flash chip CS pin
//const int FlashChipSelect = 21; // Arduino 101 built-in SPI Flash

SerialFlashFile file;

const unsigned long testIncrement = 4096;

void setup() {
  //uncomment these if using Teensy audio shield
  //SPI.setSCK(14);  // Audio shield has SCK on pin 14
  //SPI.setMOSI(7);  // Audio shield has MOSI on pin 7

  //uncomment these if you have other SPI chips connected
  //to keep them disabled while using only SerialFlash
  //pinMode(4, INPUT_PULLUP);
  //pinMode(10, INPUT_PULLUP);

  Serial.begin(9600);

  // wait up to 10 seconds for Arduino Serial Monitor
  unsigned long startMillis = millis();
  while (!Serial && (millis() - startMillis < 10000)) ;
  delay(100);

  if (!SerialFlash.begin(FlashChipSelect)) {
    while (1) {
      Serial.println("Unable to access SPI Flash chip");
      delay(1000);
    }
  }
  unsigned char id[5];
  SerialFlash.readID(id);
  unsigned long size = SerialFlash.capacity(id);

  if (size > 0) {
    Serial.print("Flash Memory has ");
    Serial.print(size);
    Serial.println(" bytes.");
    Serial.println("Erasing ALL Flash Memory:");
    // Estimate the (lengthy) wait time.
    Serial.print("  estimated wait: ");
    int seconds = (float)size / eraseBytesPerSecond(id) + 0.5;
    Serial.print(seconds);
    Serial.println(" seconds.");
    Serial.println("  Yes, full chip erase is SLOW!");
    SerialFlash.eraseAll();
    unsigned long dotMillis = millis();
    unsigned char dotcount = 0;
    while (SerialFlash.ready() == false) {
      if (millis() - dotMillis > 1000) {
        dotMillis = dotMillis + 1000;
        Serial.print(".");
        dotcount = dotcount + 1;
        if (dotcount >= 60) {
          Serial.println();
          dotcount = 0;
        }
      }
    }
    if (dotcount > 0) Serial.println();
    Serial.println("Erase completed");
    unsigned long elapsed = millis() - startMillis;
    Serial.print("  actual wait: ");
    Serial.print(elapsed / 1000ul);
    Serial.println(" seconds.");
  }
}

float eraseBytesPerSecond(const unsigned char *id) {
  if (id[0] == 0x20) return 152000.0; // Micron
  if (id[0] == 0x01) return 500000.0; // Spansion
  if (id[0] == 0xEF) return 419430.0; // Winbond
  if (id[0] == 0xC2) return 279620.0; // Macronix
  return 320000.0; // guess?
}


void loop() {

}
 
The chip looks to be oriented right.

Is Flux paste/fluid handy? A small dab after can reflow better on each pin making sure to heat pin and pad both with a clean tip for true solder connect.
Have you cleaned off the flux? Here a toothbrush wet with 90% Isopropyl on just that chip corner soften and remove flux works. Then brush again with clean Iso. pat/shake dry - hit with a hairdryer to heat and blow out trapped liquid while moving/flipping - heat a minute while still hold-able in hand - check for no fluid - allow to cool and dry before powering. 70% should work as well - but I have 90% there that evaporates and may clean better depending on the flux type.

Using post #1 code - TD 1.52 with IDE 1.8.12 on Windows it worked on a T_4.0 with a Rev Audio board with a winbond chips soldered on. So that is the right software setup:
Code:
Flash Memory has 16777216 bytes.
Erasing ALL Flash Memory:
  estimated wait: 40 seconds.
  Yes, full chip erase is SLOW!
..........................................
Erase completed
  actual wait: 42 seconds.

Then loaded RawHardwareTest - unchanged from install:
Code:
Raw SerialFlash Hardware Test

Read Chip Identification:
  JEDEC ID:     EF 40 18
  Part Nummber: W25Q128FV
  Memory Size:  16777216 bytes
  Block Size:   65536 bytes

Reading Chip...

Writing 8192 signatures

Double Checking All Signatures:
  all 8192 signatures read ok

Checking Signature Pairs
  all 4095 signature pairs read ok

Checking Read-While-Write (Program Suspend)
  write 256 bytes at 256
  write time was 374 microseconds.
  read-while-writing: 00 00 00 00 15 F5 95 4B 
  test passed, good read while writing

Checking Read-While-Erase (Erase Suspend)
  erase time was 177112 microseconds.
  erase correctly erased 65536 bytes
  read-while-erasing: 00 00 00 00 15 F5 95 4B 
  test passed, good read while erasing

All Tests Passed  :-)

Test data was written to your chip.  You must run
EraseEverything before using this chip for files.

Then returned to EraseEverything and all is well.
 
Putting solder on all the pads before hand makes it hard to get good contact. I've done a lot of SMDs by hand and this technique works for me. Use a pair of fine tweezers and a small iron tip.
- flux pen to coat all pads. You don't need a lot.
- dab of solder on one corner pad
- touch the iron next to that pad and slide the IC in place when the solder melts. Position the iron so when the IC lead hits the tip it is in place.
- make sure the IC is properly aligned and remove the iron while holding the IC in place till the solder cools. make sure the IC is flat against the PCB.
- double check alignment - fix if not right.
- solder the rest of the IC leads. You put a blob of solder on the tip of the iron, touch it to each lead and draw outward along the lead. I can get several leads per blob. Don't worry about bridges while doing it.
- solder wick and iron to clean up any bridges.
- inspect with microscope or magnifier. fix any suspect joints.
- clean flux with Isopropyl or similar. Toothbrush is a good tool.
 
@PhilB - looks good. I never tinned the pads for reason mentioned - assuring flat contact for all legs.

Chips can be tricky with tweezers - but that 'slide' works. Last one (pair of smaller PSRAMs on T_4.1) from another suggestion was done clear taping it to the board and it worked about as well - but tended to shift the chip as I secured the tape to PCB - so only good is that can't burn oneself redoing the tape to perfection :) - and then both hands are free to solder exposed half of chip, and can take a shaky tweezer hand doing slide out of the process.

And the final 'cleaning' step can be the critical part for proper function even if all else done well.

I ended up with a small tub of flux paste. Flux pens I got first few times would trigger a flood of too much - then the next time needed it was empty.
 
I have some really nice tweezers - no name but very thin - makes it super easy to mount even SOT-23s and such. I have a home brew vacuum pick/place set up. It works quite well if doing reflow but for manual soldering tweezers are my go to tool.

I used to use flux with an applicator but always got too much no matter how light a touch I tried. Don't know what to say, my pens have always been stingy - to point I will dribble a little isopropyl in it. A spare coating is all it takes and makes clean up a lot easier. My current one is from MG Chemicals.

Here's an example of one I did by hand with the iron/tweezers technique. Even the tssops came out ok.
PCB V100.jpg
 
Ok, reflowing and cleaning worked wonders! If I've learned nothing else from this, "the final 'cleaning' step can be the critical part for proper function even if all else done well" is a great takeaway, thank you!

So now it works unless I put in an SD card. Without the card, I get an "All tests passed" from RawHardwareTest (see below). But if there is an SD card in the audio shield drive, even though EraseEverything and CopyFromSDCard both work, it fails the RawHardwareTest (see below, as well).

Also, when I plug in the touchscreen , EraseEverything and CopyFromSDCard no longer work. Surely this must mean something, right?! :)


Here's the results with no SD card in the drive:

Code:
Raw SerialFlash Hardware Test



Read Chip Identification:

  JEDEC ID:     EF 40 18

  Part Nummber: W25Q128FV

  Memory Size:  16777216 bytes

  Block Size:   65536 bytes



Reading Chip...



Writing 8192 signatures



Double Checking All Signatures:

  all 8192 signatures read ok



Checking Signature Pairs

  all 4095 signature pairs read ok



Checking Read-While-Write (Program Suspend)

  write 256 bytes at 256

  write time was 377 microseconds.

  read-while-writing: 00 00 00 00 15 F5 95 4B 

  test passed, good read while writing



Checking Read-While-Erase (Erase Suspend)

  erase time was 147290 microseconds.

  erase correctly erased 65536 bytes

  read-while-erasing: 00 00 00 00 15 F5 95 4B 

  test passed, good read while erasing



All Tests Passed  :-)



Test data was written to your chip.  You must run

EraseEverything before using this chip for files.

Then I put an SD card in and ran EraseEverything. It took 22 seconds (both with and without an SD card), and then RawHardwareTest gave me this:
Code:
Raw SerialFlash Hardware Test



Read Chip Identification:

  JEDEC ID:     EF 40 18

  Part Nummber: W25Q128FV

  Memory Size:  16777216 bytes

  Block Size:   65536 bytes



Reading Chip...



Writing 8192 signatures

  error writing signature at 3395576

  Read this: 00 00 00 00 00 00 00 00 

  Expected:  00 33 CF F8 8B FA FB 5F 



Tests Failed  :{



The flash chip may be left in an improper state.

You might need to power cycle to return to normal.

Also, when I plug in the touchscreen, EraseEverything takes 0 seconds, and RawHardwareTest gives me this:

Code:
Raw SerialFlash Hardware Test



Read Chip Identification:

  JEDEC ID:     6F 40 18

  Part Nummber: (unknown chip)

  Memory Size:  16777216 bytes

  Block Size:   65536 bytes



Reading Chip...

  Previous data found at address 0

  You must fully erase the chip before this test

  found this: 00 00 00 00 00 00 00 00 

     correct: 00 00 00 00 15 F5 95 4B 



Tests Failed  :{



The flash chip may be left in an improper state.

You might need to power cycle to return to normal.

Just to make this post as verbose as I possibly can, here are the pins I'm using for the touchscreen:
Pin 7: Audio DIN
Pin 8: Touch Interface CS
Pin 9: Display D/C
Pin 10: Audio SD CS
Pin 11: Touch Interface DIN and also Display MOSI
Pin 12: Touch Interface DO and also Diaplay MISO
Pin 13: Display SCK and also Touch Interface CLK (and also the Audio SCK, as well, it is ok to use this pin for all of that?)
Pin 14: Display CS


Thank you to everyone for you patience and advice in helping me debug this thing! I feel like I'm right on the edge of getting everything to work, but I'm just missing one thing.
 
Ok, reflowing and cleaning worked wonders! If I've learned nothing else from this, "the final 'cleaning' step can be the critical part for proper function even if all else done well" is a great takeaway, thank you!

So now it works unless I put in an SD card. Without the card, I get an "All tests passed" from RawHardwareTest (see below). But if there is an SD card in the audio shield drive, even though EraseEverything and CopyFromSDCard both work, it fails the RawHardwareTest (see below, as well).
...

Thank you to everyone for you patience and advice in helping me debug this thing! I feel like I'm right on the edge of getting everything to work, but I'm just missing one thing.

Great that worked - glad you didn't break anything pulling the other chip off - and didn't give up.

Not able to confirm SD and FLASH function just now though ...

SPI is a common wire bus for SCK/CLK and MOSI and MISO - and to own the bus each device gets its own CS. Just need to be sure the CS's in use aren't in conflict with other uses.
 
Just need to be sure the CS's in use aren't in conflict with other uses.

So, I've wired Pin 9 to the T_CS pin on the touchscreen, and pin 14 to the display CS pin. I'm sorry if this is a dumb question, but when I run EraseEverything I haven't actually done anything with those pins—they aren't mentioned in the code at all. Do I need to initialize the touchscreen in order to make sure that it knows what its CS is? Or do I need to tell the flash chip that it should relinquish control when the touchscreen needs it?

Same question about the audio shield and its SD card CS. I haven't actually told it to pay attention to pin 10. However, if sounds like you were able to get things to work with the audio shield + sd card and only that same code, so I guess that's not the answer.
 
So, I've wired Pin 9 to the T_CS pin on the touchscreen.... Do I need to initialize the touchscreen in order to make sure that it knows what its CS is? Or do I need to tell the flash chip that it should relinquish control when the touchscreen needs it?

Same question about the audio shield and its SD card CS. I haven't actually told it to pay attention to pin 10. However, if sounds like you were able to get things to work with the audio shield + sd card and only that same code, so I guess that's not the answer.
Sounds like a similar problem I had with a setup used for all sorts of SPI and I2C testing. I would leave everything connected even if I wasn't using it. After occasional issues, especially with Audio and SD card stuff, eventually figured out that each device connected should have the corresponding header files and startup code even if I wasn't using them.

So you need tft.begin(), ts.begin(), sd.begin(), Serial.begin() ect. along with their declarations and any non standard pins. You should be able to get the required code from the individual programs you had working separately in other code. All pins with wires connected to the T4 need to be initialized in some fashion. I don't remember the T3.x being so sensitive to this but the T4 is.
 
Holy cow, such a relief! To sum up for anyone coming here in the future, 1) triple check your soldering, 2) make sure that you also clean it up / re-flow, &c. and 3) also be sure to include the startup code for any potentially conflicting SPI devices. As it happens, I didn't need to include the code for the touchscreen, just including the startup code for the SD drive was enough. Obviously my final code will have it all, anyway.

For a teensy 4.0 with a rev D audio shield and an ILI9341 touchscreen, here's the code that is currently working:

Code:
// RawHardwareTest - Check if a SPI Flash chip is compatible
// with SerialFlash by performing many read and write tests
// to its memory.
//
// The chip should be fully erased before running this test.
// Use the EraseEverything to do a (slow) full chip erase.
//
// Normally you should NOT access the flash memory directly,
// as this test program does.  You should create files and
// read and write the files.  File creation allocates space
// with program & erase boundaries within the chip, to allow
// reading from any other files while a file is busy writing
// or erasing (if created as erasable).
//
// If you discover an incompatible chip, please report it here:
// https://github.com/PaulStoffregen/SerialFlash/issues
// You MUST post the complete output of this program, and
// the exact part number and manufacturer of the chip.


#include <SerialFlash.h>
#include <SPI.h>
#include <SD.h>
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  11
#define SDCARD_SCK_PIN   13
const int SD_CS_Pin = 10;
const int Display_CS_Pin = 14;
const int Touch_CS_Pin = 8;
const int FlashChipSelect = 6; // digital pin for flash chip CS pin
//const int FlashChipSelect = 21; // Arduino 101 built-in SPI Flash

SerialFlashFile file;

const unsigned long testIncrement = 4096;

void setup() {
  //uncomment these if using Teensy audio shield
  //SPI.setSCK(14);  // Audio shield has SCK on pin 14
  //SPI.setMOSI(7);  // Audio shield has MOSI on pin 7

  //uncomment these if you have other SPI chips connected
  //to keep them disabled while using only SerialFlash
  //pinMode(4, INPUT_PULLUP);
  //pinMode(10, INPUT_PULLUP);

  Serial.begin(9600);

  while (!Serial) ;
  delay(100);

  pinMode(SD_CS_Pin, OUTPUT);
  digitalWrite(SD_CS_Pin, HIGH);
  
  pinMode(Display_CS_Pin, OUTPUT);  
  digitalWrite(Display_CS_Pin, HIGH);
  
  pinMode(Touch_CS_Pin, OUTPUT);
  digitalWrite(Touch_CS_Pin, HIGH);
  
  delay(1);

  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
  delay(1000);



  Serial.println("Raw SerialFlash Hardware Test");
  SerialFlash.begin(FlashChipSelect); // proceed even if begin() fails

  if (test()) {
    Serial.println();
    Serial.println("All Tests Passed  :-)");
    Serial.println();
    Serial.println("Test data was written to your chip.  You must run");
    Serial.println("EraseEverything before using this chip for files.");
  } else {
    Serial.println();
    Serial.println("Tests Failed  :{");
    Serial.println();
    Serial.println("The flash chip may be left in an improper state.");
    Serial.println("You might need to power cycle to return to normal.");
  }
}


bool test() {
  unsigned char buf[256], sig[256], buf2[8];
  unsigned long address, count, chipsize, blocksize;
  unsigned long usec;
  bool first;

  // Read the chip identification
  Serial.println();
  Serial.println("Read Chip Identification:");
  SerialFlash.readID(buf);
  Serial.print("  JEDEC ID:     ");
  Serial.print(buf[0], HEX);
  Serial.print(" ");
  Serial.print(buf[1], HEX);
  Serial.print(" ");
  Serial.println(buf[2], HEX);
  Serial.print("  Part Nummber: ");
  Serial.println(id2chip(buf));
  Serial.print("  Memory Size:  ");
  chipsize = SerialFlash.capacity(buf);
  Serial.print(chipsize);
  Serial.println(" bytes");
  if (chipsize == 0) return false;
  Serial.print("  Block Size:   ");
  blocksize = SerialFlash.blockSize();
  Serial.print(blocksize);
  Serial.println(" bytes");


  // Read the entire chip.  Every test location must be
  // erased, or have a previously tested signature
  Serial.println();
  Serial.println("Reading Chip...");
  memset(buf, 0, sizeof(buf));
  memset(sig, 0, sizeof(sig));
  memset(buf2, 0, sizeof(buf2));
  address = 0;
  count = 0;
  first = true;
  while (address < chipsize) {
    SerialFlash.read(address, buf, 8);
    //Serial.print("  addr = ");
    //Serial.print(address, HEX);
    //Serial.print(", data = ");
    //printbuf(buf, 8);
    create_signature(address, sig);
    if (is_erased(buf, 8) == false) {
      if (equal_signatures(buf, sig) == false) {
        Serial.print("  Previous data found at address ");
        Serial.println(address);
        Serial.println("  You must fully erase the chip before this test");
        Serial.print("  found this: ");
        printbuf(buf, 8);
        Serial.print("     correct: ");
        printbuf(sig, 8);
        return false;
      }
    } else {
      count = count + 1; // number of blank signatures
    }
    if (first) {
      address = address + (testIncrement - 8);
      first = false;
    } else {
      address = address + 8;
      first = true;
    }
  }


  // Write any signatures that were blank on the original check
  if (count > 0) {
    Serial.println();
    Serial.print("Writing ");
    Serial.print(count);
    Serial.println(" signatures");
    memset(buf, 0, sizeof(buf));
    memset(sig, 0, sizeof(sig));
    memset(buf2, 0, sizeof(buf2));
    address = 0;
    first = true;
    while (address < chipsize) {
      SerialFlash.read(address, buf, 8);
      if (is_erased(buf, 8)) {
        create_signature(address, sig);
        //Serial.printf("write %08X: data: ", address);
        //printbuf(sig, 8);
        SerialFlash.write(address, sig, 8);
        while (!SerialFlash.ready()) ; // wait
        SerialFlash.read(address, buf, 8);
        if (equal_signatures(buf, sig) == false) {
          Serial.print("  error writing signature at ");
          Serial.println(address);
          Serial.print("  Read this: ");
          printbuf(buf, 8);
          Serial.print("  Expected:  ");
          printbuf(sig, 8);
          return false;
        }
      }
      if (first) {
        address = address + (testIncrement - 8);
        first = false;
      } else {
        address = address + 8;
        first = true;
      }
    }
  } else {
    Serial.println("  all signatures present from prior tests");
  }


  // Read all the signatures again, just to be sure
  // checks prior writing didn't corrupt any other data
  Serial.println();
  Serial.println("Double Checking All Signatures:");
  memset(buf, 0, sizeof(buf));
  memset(sig, 0, sizeof(sig));
  memset(buf2, 0, sizeof(buf2));
  count = 0;
  address = 0;
  first = true;
  while (address < chipsize) {
    SerialFlash.read(address, buf, 8);
    create_signature(address, sig);
    if (equal_signatures(buf, sig) == false) {
      Serial.print("  error in signature at ");
      Serial.println(address);
      Serial.print("  Read this: ");
      printbuf(buf, 8);
      Serial.print("  Expected:  ");
      printbuf(sig, 8);
      return false;
    }
    count = count + 1;
    if (first) {
      address = address + (testIncrement - 8);
      first = false;
    } else {
      address = address + 8;
      first = true;
    }
  }
  Serial.print("  all ");
  Serial.print(count);
  Serial.println(" signatures read ok");


  // Read pairs of adjacent signatures
  // check read works across boundaries
  Serial.println();
  Serial.println("Checking Signature Pairs");
  memset(buf, 0, sizeof(buf));
  memset(sig, 0, sizeof(sig));
  memset(buf2, 0, sizeof(buf2));
  count = 0;
  address = testIncrement - 8;
  first = true;
  while (address < chipsize - 8) {
    SerialFlash.read(address, buf, 16);
    create_signature(address, sig);
    create_signature(address + 8, sig + 8);
    if (memcmp(buf, sig, 16) != 0) {
      Serial.print("  error in signature pair at ");
      Serial.println(address);
      Serial.print("  Read this: ");
      printbuf(buf, 16);
      Serial.print("  Expected:  ");
      printbuf(sig, 16);
      return false;
    }
    count = count + 1;
    address = address + testIncrement;
  }
  Serial.print("  all ");
  Serial.print(count);
  Serial.println(" signature pairs read ok");


  // Write data and read while write in progress
  Serial.println();
  Serial.println("Checking Read-While-Write (Program Suspend)");
  address = 256;
  while (address < chipsize) { // find a blank space
    SerialFlash.read(address, buf, 256);
    if (is_erased(buf, 256)) break;
    address = address + 256;
  }
  if (address >= chipsize) {
    Serial.println("  error, unable to find any blank space!");
    return false;
  }
  for (int i=0; i < 256; i += 8) {
    create_signature(address + i, sig + i);
  }
  Serial.print("  write 256 bytes at ");
  Serial.println(address);
  Serial.flush();
  SerialFlash.write(address, sig, 256);
  usec = micros();
  if (SerialFlash.ready()) {
    Serial.println("  error, chip did not become busy after write");
    return false;
  }
  SerialFlash.read(0, buf2, 8); // read while busy writing
  while (!SerialFlash.ready()) ; // wait
  usec = micros() - usec;
  Serial.print("  write time was ");
  Serial.print(usec);
  Serial.println(" microseconds.");
  SerialFlash.read(address, buf, 256);
  if (memcmp(buf, sig, 256) != 0) {
    Serial.println("  error writing to flash");
    Serial.print("  Read this: ");
    printbuf(buf, 256);
    Serial.print("  Expected:  ");
    printbuf(sig, 256);
    return false;
  }
  create_signature(0, sig);
  if (memcmp(buf2, sig, 8) != 0) {
    Serial.println("  error, incorrect read while writing");
    Serial.print("  Read this: ");
    printbuf(buf2, 256);
    Serial.print("  Expected:  ");
    printbuf(sig, 256);
    return false;
  }
  Serial.print("  read-while-writing: ");
  printbuf(buf2, 8);
  Serial.println("  test passed, good read while writing");



  // Erase a block and read while erase in progress
  if (chipsize >= 262144 + blocksize + testIncrement) {
    Serial.println();
    Serial.println("Checking Read-While-Erase (Erase Suspend)");
    memset(buf, 0, sizeof(buf));
    memset(sig, 0, sizeof(sig));
    memset(buf2, 0, sizeof(buf2));
    SerialFlash.eraseBlock(262144);
    usec = micros();
    delayMicroseconds(50);
    if (SerialFlash.ready()) {
      Serial.println("  error, chip did not become busy after erase");
      return false;
    }
    SerialFlash.read(0, buf2, 8); // read while busy writing
    while (!SerialFlash.ready()) ; // wait
    usec = micros() - usec;
    Serial.print("  erase time was ");
    Serial.print(usec);
    Serial.println(" microseconds.");
    // read all signatures, check ones in this block got
    // erased, and all the others are still intact
    address = 0;
    first = true;
    while (address < chipsize) {
      SerialFlash.read(address, buf, 8);
      if (address >= 262144 && address < 262144 + blocksize) {
        if (is_erased(buf, 8) == false) {
          Serial.print("  error in erasing at ");
          Serial.println(address);
          Serial.print("  Read this: ");
          printbuf(buf, 8);
          return false;
        }
      } else {
        create_signature(address, sig);
        if (equal_signatures(buf, sig) == false) {
          Serial.print("  error in signature at ");
          Serial.println(address);
          Serial.print("  Read this: ");
          printbuf(buf, 8);
          Serial.print("  Expected:  ");
          printbuf(sig, 8);
          return false;
        }
      }
      if (first) {
        address = address + (testIncrement - 8);
        first = false;
      } else {
        address = address + 8;
        first = true;
      }
    }
    Serial.print("  erase correctly erased ");
    Serial.print(blocksize);
    Serial.println(" bytes");
    // now check if the data we read during erase is good
    create_signature(0, sig);
    if (memcmp(buf2, sig, 8) != 0) {
      Serial.println("  error, incorrect read while erasing");
      Serial.print("  Read this: ");
      printbuf(buf2, 256);
      Serial.print("  Expected:  ");
      printbuf(sig, 256);
      return false;
    }
    Serial.print("  read-while-erasing: ");
    printbuf(buf2, 8);
    Serial.println("  test passed, good read while erasing");

  } else {
    Serial.println("Skip Read-While-Erase, this chip is too small");
  }




  return true;
}


void loop() {
  // do nothing after the test
}

const char * id2chip(const unsigned char *id)
{
	if (id[0] == 0xEF) {
		// Winbond
		if (id[1] == 0x40) {
			if (id[2] == 0x14) return "W25Q80BV";
			if (id[2] == 0x15) return "W25Q16DV";
			if (id[2] == 0x17) return "W25Q64FV";
			if (id[2] == 0x18) return "W25Q128FV";
			if (id[2] == 0x19) return "W25Q256FV";
		}
	}
	if (id[0] == 0x01) {
		// Spansion
		if (id[1] == 0x02) {
			if (id[2] == 0x16) return "S25FL064A";
			if (id[2] == 0x19) return "S25FL256S";
			if (id[2] == 0x20) return "S25FL512S";
		}
		if (id[1] == 0x20) {
			if (id[2] == 0x18) return "S25FL127S";
		}
	}
	if (id[0] == 0xC2) {
		// Macronix
		if (id[1] == 0x20) {
			if (id[2] == 0x18) return "MX25L12805D";
		}
	}
	if (id[0] == 0x20) {
		// Micron
		if (id[1] == 0xBA) {
			if (id[2] == 0x20) return "N25Q512A";
			if (id[2] == 0x21) return "N25Q00AA";
		}
		if (id[1] == 0xBB) {
			if (id[2] == 0x22) return "MT25QL02GC";
		}
	}
	if (id[0] == 0xBF) {
		// SST
		if (id[1] == 0x25) {
			if (id[2] == 0x02) return "SST25WF010";
			if (id[2] == 0x03) return "SST25WF020";
			if (id[2] == 0x04) return "SST25WF040";
			if (id[2] == 0x41) return "SST25VF016B";
			if (id[2] == 0x4A) return "SST25VF032";
		}
		if (id[1] == 0x25) {
			if (id[2] == 0x01) return "SST26VF016";
			if (id[2] == 0x02) return "SST26VF032";
			if (id[2] == 0x43) return "SST26VF064";
		}
	}
  	if (id[0] == 0x1F) {
    		// Adesto
   		if (id[1] == 0x89) {
      			if (id[2] == 0x01) return "AT25SF128A";
    		}  
  	} 	
	return "(unknown chip)";
}

void print_signature(const unsigned char *data)
{
	Serial.print("data=");
	for (unsigned char i=0; i < 8; i++) {
		Serial.print(data[i]);
		Serial.print(" ");
	}
	Serial.println();
}

void create_signature(unsigned long address, unsigned char *data)
{
	data[0] = address >> 24;
	data[1] = address >> 16;
	data[2] = address >> 8;
	data[3] = address;
	unsigned long hash = 2166136261ul;
	for (unsigned char i=0; i < 4; i++) {
		hash ^= data[i];
		hash *= 16777619ul;
	}
	data[4] = hash;
	data[5] = hash >> 8;
	data[6] = hash >> 16;
	data[7] = hash >> 24;
}

bool equal_signatures(const unsigned char *data1, const unsigned char *data2)
{
	for (unsigned char i=0; i < 8; i++) {
		if (data1[i] != data2[i]) return false;
	}
	return true;
}

bool is_erased(const unsigned char *data, unsigned int len)
{
	while (len > 0) {
		if (*data++ != 255) return false;
		len = len - 1;
	}
	return true;
}


void printbuf(const void *buf, uint32_t len)
{
  const uint8_t *p = (const uint8_t *)buf;
  do {
    unsigned char b = *p++;
    Serial.print(b >> 4, HEX);
    Serial.print(b & 15, HEX);
    //Serial.printf("%02X", *p++);
    Serial.print(" ");
  } while (--len > 0);
  Serial.println();
}


and here is the result:
Code:
Raw SerialFlash Hardware Test



Read Chip Identification:

  JEDEC ID:     EF 40 18

  Part Nummber: W25Q128FV

  Memory Size:  16777216 bytes

  Block Size:   65536 bytes



Reading Chip...



Writing 8192 signatures



Double Checking All Signatures:

  all 8192 signatures read ok



Checking Signature Pairs

  all 4095 signature pairs read ok



Checking Read-While-Write (Program Suspend)

  write 256 bytes at 256

  write time was 375 microseconds.

  read-while-writing: 00 00 00 00 15 F5 95 4B 

  test passed, good read while writing



Checking Read-While-Erase (Erase Suspend)

  erase time was 155598 microseconds.

  erase correctly erased 65536 bytes

  read-while-erasing: 00 00 00 00 15 F5 95 4B 

  test passed, good read while erasing



All Tests Passed  :-)



Test data was written to your chip.  You must run

EraseEverything before using this chip for files.



Thank you again to everyone!
 
Status
Not open for further replies.
Back
Top