Browse Source

Add examples for erase and raw hardware test

main
PaulStoffregen 9 years ago
parent
commit
d06442224b
2 changed files with 390 additions and 0 deletions
  1. +69
    -0
      examples/EraseEverything/EraseEverything.ino
  2. +321
    -0
      examples/RawHardwareTest/RawHardwareTest.ino

+ 69
- 0
examples/EraseEverything/EraseEverything.ino View File

@@ -0,0 +1,69 @@
#include <SerialFlash.h>
#include <SPI.h>

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

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

SerialFlash.begin();
unsigned char id[3];
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() {

}


+ 321
- 0
examples/RawHardwareTest/RawHardwareTest.ino View File

@@ -0,0 +1,321 @@
#include <SerialFlash.h>
#include <SPI.h>

SerialFlashFile file;

//const unsigned long testIncrement = 4096;
const unsigned long testIncrement = 4194304;

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

while (!Serial) ;
delay(100);

Serial.println("Raw SerialFlash Hardware Test");
SerialFlash.begin();

test();
}

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 test() {
unsigned char buf[16], sig[16], erased[16];
unsigned long address, count, chipsize;
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;

//chipsize = 0x20000;
//Serial.println("erasing a couple small blocks....");
//SerialFlash.eraseBlock(0x00000000);
//SerialFlash.eraseBlock(0x00010000);
//while (!SerialFlash.ready()); // wait

//Serial.println();
//Serial.println("read locations in memory...");
//SerialFlash.read(0x0000000, buf, 12);
//printbuf(buf, 12);
//SerialFlash.read(0x1000000, buf, 12);
//printbuf(buf, 12);
//SerialFlash.read(0x2000000, buf, 12);
//printbuf(buf, 12);
//SerialFlash.read(0x3000000, buf, 12);
//printbuf(buf, 12);


// Read the entire chip. Every test location must be
// erased, or have a previously tested signature
for (unsigned char i=0; i < 8; i++) {
erased[i] = 255;
}
Serial.println();
Serial.println("Reading Chip...");
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 (equal_signatures(buf, erased) == 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);
Serial.print(" erased: ");
printbuf(erased, 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");
address = 0;
first = true;
while (address < chipsize) {
SerialFlash.read(address, buf, 8);
if (equal_signatures(buf, erased)) {
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
Serial.println();
Serial.println("Double Checking All Signatures:");
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
Serial.println();
Serial.println("Checking Signature Pairs");
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");





Serial.println();
Serial.println("All Tests Passed :-)");
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] == 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";
}
}
return "(unknown chip)";
}


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();
}


Loading…
Cancel
Save