Play RAW from Serial Flash

Status
Not open for further replies.
I thought I did provide all the details. If by providing the code used, no I didnt do that. As I am using the exact example located within the Arduino example code that comes with your libraries. But I will post it here. The files on the SD card are named in the following way.. 01SD.raw , 02SD.raw , etc... They are on a 4GB Kingston HC level 10 SD card. The card has been formatted several times to erase and start fresh. Any other details you need, please let me know. Thank you.

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

const int SDchipSelect = 10; // Audio Shield has SD card CS on pin 10
const int FlashChipSelect = 6;

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);
  Serial.println("Copy all files from SD Card to SPI Flash");

  if (!SD.begin(SDchipSelect)) {
    error("Unable to access SD card");
  }
  if (!SerialFlash.begin()) {
    error("Unable to access SPI Flash chip");
  }

  int count = 0;
  File rootdir = SD.open("/");
  while (1) {
    // open a file from the SD card
    Serial.println();
    File f = rootdir.openNextFile();
    if (!f) break;
    const char *filename = f.name();
    Serial.print(filename);
    Serial.print("    ");
    unsigned long length = f.size();
    Serial.println(length);

    // check if this file is already on the Flash chip
    if (SerialFlash.exists(filename)) {
      Serial.println("  already exists on the Flash chip");
      SerialFlashFile ff = SerialFlash.open(filename);
      if (ff && ff.size() == f.size()) {
        Serial.println("  size is the same, comparing data...");
        if (compareFiles(f, ff) == true) {
          Serial.println("  files are identical :)");
          f.close();
          ff.close();
          continue;  // advance to next file
        } else {
          Serial.println("  files are different");
        }
      } else {
        Serial.print("  size is different, ");
        Serial.print(ff.size());
        Serial.println(" bytes");
      }
      // delete the copy on the Flash chip, if different
      Serial.println("  delete file from Flash chip");
      SerialFlash.remove(filename);
    }

    // create the file on the Flash chip and copy data
    if (SerialFlash.create(filename, length)) {
      SerialFlashFile ff = SerialFlash.open(filename);
      if (ff) {
        Serial.print("  copying");
        // copy data loop
        unsigned long count = 0;
        unsigned char dotcount = 9;
        while (count < length) {
          char buf[256];
          unsigned int n;
          n = f.read(buf, 256);
          ff.write(buf, n);
          count = count + n;
          Serial.print(".");
          if (++dotcount > 100) {
             Serial.println();
             dotcount = 0;
          }
        }
        ff.close();
        if (dotcount > 0) Serial.println();
      } else {
        Serial.println("  error opening freshly created file!");
      }
    } else {
      Serial.println("  unable to create file");
    }
    f.close();
  }
  rootdir.close();
  delay(10);
  Serial.println("Finished All Files");
}


bool compareFiles(File &file, SerialFlashFile &ffile) {
  file.seek(0);
  ffile.seek(0);
  unsigned long count = file.size();
  while (count > 0) {
    char buf1[128], buf2[128];
    unsigned long n = count;
    if (n > 128) n = 128;
    file.read(buf1, n);
    ffile.read(buf2, n);
    if (memcmp(buf1, buf2, n) != 0) return false; // differ
    count = count - n;
  }
  return true;  // all data identical
}


void loop() {
}

void error(const char *message) {
  while (1) {
    Serial.println(message);
    delay(2500);
  }
}
 
What do you believe I can do here to help you?

I can assure you, I've run that example many times here with SD cards containing various files. Afterall, I wrote it. If I run it yet again with the cards, files and chips I have here, I'm sure it'll work. It's always worked.

I thought I did provide all the details.

Looking back over the message, the only info I see is "when trying to write files to the flash chip from SD card, I get failures still". I looked over the last dozen messages, which are all about the hardware test not working (which seems to have been due to your SD card in the socket responding to SPI communication during the test with its CS pin floating low). I see almost nothing about this file copy problem.

I don't even see a copy of the serial monitor output from your run of the file copy. How do you even know it's not working? I can't even tell if you're seeing some indication of error during the test, or if you're concluding the file copy didn't work for some other reason.

Did you provide an exact copy of the full set of files on your card? (sites like dropbox or pastebin are commonly used for large file sets which can't be uploaded here) I see you posted a description "4GB Kingston HC level 10 SD" for your card. Even if I had that card here, how am I supposed to try to duplicate the results you're getting? Am I supposed to just grab a different set of files and try that? I wrote that example and ran it with several different sets of files!

Maybe I missed all this info somewhere? Please tell me where it is.
 
Understood.

STEP 1 : Plug in Teensy 3.1 / Audioboard with the attached W25Q128FV chip. SD card is removed. Running the EraseEverything sketch from the examples. Code and output below.

CODE:
Code:
#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() {

}

SERIAL OUTPUT:
Code:
Flash Memory has 16777216 bytes.
Erasing ALL Flash Memory:
  estimated wait: 40 seconds.
  Yes, full chip erase is SLOW!
........................................
Erase completed
  actual wait: 41 seconds.


STEP 2: Test the hardware using the example sketch RawHardwareTest. Code and output below:

CODE:
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>

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

  while (!Serial) ;
  delay(100);

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

  if (test()) {
    Serial.println();
    Serial.println("All Tests Passed  :-)");
  } 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] == 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 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();
}

SERIAL OUTPUT:
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 406 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 221622 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  :-)

STEP 3: Flash chip with three different test files. Code and output below:
File names on card: 01TP.raw , 01TP.wav , 01TZ.raw

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

const int SDchipSelect = 10; // Audio Shield has SD card CS on pin 10
const int FlashChipSelect = 6;

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);
  Serial.println("Copy all files from SD Card to SPI Flash");

  if (!SD.begin(SDchipSelect)) {
    error("Unable to access SD card");
  }
  if (!SerialFlash.begin()) {
    error("Unable to access SPI Flash chip");
  }

  int count = 0;
  File rootdir = SD.open("/");
  while (1) {
    // open a file from the SD card
    Serial.println();
    File f = rootdir.openNextFile();
    if (!f) break;
    const char *filename = f.name();
    Serial.print(filename);
    Serial.print("    ");
    unsigned long length = f.size();
    Serial.println(length);

    // check if this file is already on the Flash chip
    if (SerialFlash.exists(filename)) {
      Serial.println("  already exists on the Flash chip");
      SerialFlashFile ff = SerialFlash.open(filename);
      if (ff && ff.size() == f.size()) {
        Serial.println("  size is the same, comparing data...");
        if (compareFiles(f, ff) == true) {
          Serial.println("  files are identical :)");
          f.close();
          ff.close();
          continue;  // advance to next file
        } else {
          Serial.println("  files are different");
        }
      } else {
        Serial.print("  size is different, ");
        Serial.print(ff.size());
        Serial.println(" bytes");
      }
      // delete the copy on the Flash chip, if different
      Serial.println("  delete file from Flash chip");
      SerialFlash.remove(filename);
    }

    // create the file on the Flash chip and copy data
    if (SerialFlash.create(filename, length)) {
      SerialFlashFile ff = SerialFlash.open(filename);
      if (ff) {
        Serial.print("  copying");
        // copy data loop
        unsigned long count = 0;
        unsigned char dotcount = 9;
        while (count < length) {
          char buf[256];
          unsigned int n;
          n = f.read(buf, 256);
          ff.write(buf, n);
          count = count + n;
          Serial.print(".");
          if (++dotcount > 100) {
             Serial.println();
             dotcount = 0;
          }
        }
        ff.close();
        if (dotcount > 0) Serial.println();
      } else {
        Serial.println("  error opening freshly created file!");
      }
    } else {
      Serial.println("  unable to create file");
    }
    f.close();
  }
  rootdir.close();
  delay(10);
  Serial.println("Finished All Files");
}


bool compareFiles(File &file, SerialFlashFile &ffile) {
  file.seek(0);
  ffile.seek(0);
  unsigned long count = file.size();
  while (count > 0) {
    char buf1[128], buf2[128];
    unsigned long n = count;
    if (n > 128) n = 128;
    file.read(buf1, n);
    ffile.read(buf2, n);
    if (memcmp(buf1, buf2, n) != 0) return false; // differ
    count = count - n;
  }
  return true;  // all data identical
}


void loop() {
}

void error(const char *message) {
  while (1) {
    Serial.println(message);
    delay(2500);
  }
}

SERIAL OUTPUT:
Code:
Copy all files from SD Card to SPI Flash

01TP.RAW    220500
  unable to create file

01TP.WAV    442608
  unable to create file

01TZ.RAW    110250
  unable to create file

Finished All Files


There are NO errors during compiling.


If you need more details, please let me know. Im happy to provide them.
 
I should also note the following.

I have reformatted several cards of the same type in the following ways.

I have used the format utility on Windows to format the cards as such:

FAT(32) - 4kb allocation size
FAT(32) - 32kb allocation size
FAT - 64kb allocation size

None of which had a successful change on the above outcome.
 
STEP 2: Test the hardware using the example sketch RawHardwareTest
....
STEP 3: Flash chip with three different test files.

You're missing a required step.

You must fully erase after the hardware test. The hardware test leaves the chip filled with test data. No files can be written to the chip while it's still in that state.

Simply add an erase step between step 2 & 3. I'm guessing that will fully resolve the problem you're seeing.


(can you see how I could not have known you were trying to write files to a chip filled with test data, until you posted this more detailed explanation of the exact steps you're using?)
 
Last edited:
That was the issue!

Thank you!

And yes, I can understand how you never as much detail as possible to solve an issue. I often times forget some of the things I think are trivial. My apologies.

I will now see if I can play the files now.
 
Last edited:
I'm interested in playing audio from Serial Flash the "new way" using AudioPlaySerialflashRaw, but unfortunately only get silence. Audio/WavFilePlayer works as expected (using headphones).

I flashed Paul's sample 52082.RAW file without issue and can see it using SerialFlash/ListFiles:

All Files on SPI Flash chip:
52082.RAW 1080012 bytes



I couldn't find any examples for using the new method, so I tried modifying Audio/WavFilePlayer to include AudioPlaySerialflashRaw.

Here's the code I'm using:
Code:
#include <Audio.h>
#include <SerialFlash.h>

AudioPlaySerialflashRaw  player1;
AudioOutputI2S           audioOutput;

AudioConnection          patchCord1( player1, 0, audioOutput, 0 );
AudioConnection          patchCord2( player1, 1, audioOutput, 1 );
AudioControlSGTL5000     sgtl5000;


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

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

  // Audio connections require memory to work
  AudioMemory( 8 );

  if ( !SerialFlash.begin() )
    Serial.println( "Unable to access SPI Flash chip" );

  sgtl5000.enable();
  sgtl5000.volume( 0.5 );
  }


void playFile( const char* filename )
  {
  Serial.print( "Playing file: " );
  Serial.println( filename );

  // Start playing the file.  This sketch continues to
  // run while the file plays.
  player1.play( filename );

  // A brief delay for the library read info
  delay( 5 );

  // Simply wait for the file to finish playing.
  while ( player1.isPlaying() );
  }


void loop() 
  {
  playFile( "52082.RAW" );
  }
 
Last edited:
Also, if you have the rev1 audio board, copy the pinMode line to keep any SD card disabled. The newer rev2 boards have real pullup resistors.
 
Thanks, I'm getting playback now after adding in the SPI.setMOSI and SPI.setSCK stuff. I'm assuming that's you on guitar?

A couple things I noticed:

1) If I try playback with the SD Card removed, it works but the sound is all crackly and popping.
2) Sound plays back mostly on just the left channel (like 90%). WavFilePlayer playing 52082.WAV works as expected.

Also, I couldn't find the pinMode line you were referring to (in case that's related to issue #1).
 
I'm using a Rev B board as well.

Any ideas what could be causing audio playback via Serial Flash to play 90% on the left channel only?
 
I found the change I needed to make to get the sound to play correctly via Serial Flash in both the left and right channels:

Code:
AudioConnection patchCord1( sound0, 0, headphones, 0 );
AudioConnection patchCord2( sound0, 1, headphones, 1 );

changed to

Code:
AudioConnection patchCord1( sound0, 0, headphones, 0 );
AudioConnection patchCord2( sound0, 0, headphones, 1 );

The Audio System Design Tool shows this in the AudioPlaySerialflashRaw details:
http://www.pjrc.com/teensy/gui/?info=AudioPlaySerialflashRaw

This worked....most of the time. But the audio would sometimes "freak out" and play with some kind of interference or feedback. The Teensy LED would flash super quickly as well when this happened.

So I added in an AudioMixer4 and now it seems to work.

I'm posting the final code here for completeness:

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

AudioPlaySerialflashRaw  sound0;
AudioMixer4        mix;
AudioOutputI2S     headphones;

AudioConnection patchCord1( sound0, 0, mix, 0 );
AudioConnection patchCord2( mix, 0, headphones, 0 );
AudioConnection patchCord3( mix, 0, headphones, 1 );

AudioControlSGTL5000     sgtl5000;


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

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

  // Audio connections require memory to work
  AudioMemory( 8 );

  SPI.setMOSI( 7 );   // MOSI_PIN for audio board
  SPI.setSCK( 14 );   // SCK_PIN for audio board

  if ( !SerialFlash.begin() )
    Serial.println( "Unable to access SPI Flash chip" );

  sgtl5000.enable();
  sgtl5000.volume( 0.5 );
  }


void playFile( const char* filename )
  {
  Serial.print( "Playing file: " );
  Serial.print( filename );

  // Start playing the file.  This sketch continues to
  // run while the file plays.
  sound0.play( filename );

  // A brief delay for the library read info
  delay( 5 );

  // Simply wait for the file to finish playing.
  while ( sound0.isPlaying() );

  Serial.println( "       DONE" );
  }


void loop() 
  {
  playFile( "52082.RAW" );

  delay( 5000 );
  }
 
Last edited:
Hello all,

Did any one tried playing raw audio from serial flash using Teensy LC through DAC ???...

Sorry, that doesn't work yet - there are plans to make it work but that could take a year or more.

You're far better off using a teensy 3.2 for audio projects, if you want quick success.

That being said, it is quite possible and there are plenty of examples of arduino projects playing audio out of a DAC. Perhaps you could port one of those?
 
I am curious how to use the other approved and tested higher capacity flash chips? The 256mbit chips dont come in the 8SOIC package. Instead they come as 16SOIC and 8-WSON.

Wondering if the 8-WSON package could be soldered onto the pads that are on the Audio Board or not?

Would be most interested in using the Winbond W25Q256FV flash chip.

Any insight into how to apply this chip physically to the audio board would be useful.

Thanks!
 
Wondering if the 8-WSON package could be soldered onto the pads that are on the Audio Board or not?

That's risky. The bottom side of the WSON8 package is a big ground pad. The circuit board has traces in that area, so the only thing preventing those copper traces from shorting to the ground pad is a thin layer of green solder mask.
 
Im curious then, how did you test those chips referenced on the GIThub page?

How are we to use these larger and smaller chips that are claimed to work with the Teensy?

Thank you!
 
how did you test those chips referenced on the GIThub page?

https://forum.pjrc.com/threads/3149...-work-with-these?p=92416&viewfull=1#post92416

How are we to use these larger and smaller chips that are claimed to work with the Teensy?

I hope you can understand I develop and contribute a lot of open source software that isn't strictly in support of specific PJRC products. The SerialFlash library began to enable using some of these chips with the audio board. It's scope has grown, even though PJRC isn't making and selling boards with those specific chips.

Onehorse is selling boards with some of the larger chips. If you need a ready-to-use project, perhaps that's your best path?

You could order the test boards I made, since I shared them on OSH Park's site, and solder them yourself. But those boards are really meant for me to test library compatibility with 4 chips per board. I don't want to represent those boards as a general purpose product.
 
Hi,
I am using Spansion-S25FL208K0RMFI041(8M) and I am getting "The flash chip may be left in an improper state";
"You might need to power cycle to return to normal";
error while running the Raw hardware test program.
Kindly let me know what can be possible reason and solution.

Even I tried erasing all chip via erase everything program but I'm just getting just the waiting dots.

Pins used are 11(DOUT),12(DIN),14(SCK),10(CS).
 
- please post *all* messages.
- try - just for a test - with teensy @ 24MHz.

did you use your "long-wires-on-breadboard" technique (from the other thread...) ?
 
Status
Not open for further replies.
Back
Top