瀏覽代碼

Handle files that already exist & add ListFiles example

main
PaulStoffregen 9 年之前
父節點
當前提交
4dc26020d9
共有 5 個文件被更改,包括 148 次插入105 次删除
  1. +5
    -1
      SerialFlash.h
  2. +44
    -5
      SerialFlashDirectory.cpp
  3. +45
    -2
      examples/CopyFromSD/CopyFromSD.ino
  4. +54
    -0
      examples/ListFiles/ListFiles.ino
  5. +0
    -97
      examples/TestHardware/TestHardware.ino

+ 5
- 1
SerialFlash.h 查看文件

@@ -52,6 +52,9 @@ public:
static bool createErasable(const char *filename, uint32_t length) {
return create(filename, length, blockSize());
}
static bool exists(const char *filename);
static bool remove(const char *filename);
static bool remove(SerialFlashFile &file);
static void opendir() { dirindex = 0; }
static bool readdir(char *filename, uint32_t strsize, uint32_t &filesize);
private:
@@ -75,7 +78,7 @@ public:
if (address > 0) return true;
return false;
}
uint32_t read(uint8_t *buf, uint32_t rdlen) {
uint32_t read(void *buf, uint32_t rdlen) {
if (offset + rdlen > length) {
if (offset >= length) return 0;
rdlen = length - offset;
@@ -119,6 +122,7 @@ protected:
uint32_t address; // where this file's data begins in the Flash, or zero
uint32_t length; // total length of the data in the Flash chip
uint32_t offset; // current read/write offset in the file
uint16_t dirindex;
};



+ 44
- 5
SerialFlashDirectory.cpp 查看文件

@@ -94,7 +94,7 @@ static uint16_t filename_hash(const char *filename)
hash ^= *p;
hash *= 16777619;
}
hash %= (uint32_t)0xFFFF;
hash = (hash % (uint32_t)0xFFFE) + 1; // all values except 0000 & FFFF
return hash;
}

@@ -115,14 +115,16 @@ static bool filename_compare(const char *filename, uint32_t straddr)
}
}

#if 0
void pbuf(const void *buf, uint32_t len)
{
const uint8_t *p = (const uint8_t *)buf;
do {
//Serial.printf("%02X ", *p++);
Serial.printf("%02X ", *p++);
} while (--len > 0);
//Serial.println();
Serial.println();
}
#endif

SerialFlashFile SerialFlashChip::open(const char *filename)
{
@@ -137,6 +139,7 @@ SerialFlashFile SerialFlashChip::open(const char *filename)
if (!maxfiles) return file;
maxfiles &= 0xFFFF;
hash = filename_hash(filename);
//Serial.printf("hash %04X for \"%s\"\n", hash, filename);
while (index < maxfiles) {
n = 8;
if (n > maxfiles - index) n = maxfiles - index;
@@ -161,6 +164,7 @@ SerialFlashFile SerialFlashChip::open(const char *filename)
file.address = buf[0];
file.length = buf[1];
file.offset = 0;
file.dirindex = index + i;
return file;
}
} else if (hashtable[i] == 0xFFFF) {
@@ -172,6 +176,40 @@ SerialFlashFile SerialFlashChip::open(const char *filename)
return file;
}

bool SerialFlashChip::exists(const char *filename)
{
SerialFlashFile file = open(filename);
return (bool)file;
}

bool SerialFlashChip::remove(const char *filename)
{
SerialFlashFile file = open(filename);
return remove(file);
}

bool SerialFlashChip::remove(SerialFlashFile &file)
{
// To "remove" a file, we simply zero its hash in the lookup
// table, so it can't be found by open(). The space on the
// flash memory is not freed.
if (!file) return false;
uint16_t hash;
SerialFlash.read(8 + file.dirindex * 2, &hash, 2);
//Serial.printf("remove hash %04X at %d index\n", hash, file.dirindex);
hash ^= 0xFFFF; // write zeros to all ones
SerialFlash.write(8 + file.dirindex * 2, &hash, 2);
while (!SerialFlash.ready()) ; // wait... TODO: timeout
SerialFlash.read(8 + file.dirindex * 2, &hash, 2);
if (hash != 0) {
//Serial.printf("remove failed, hash %04X\n", hash);
return false;
}
file.address = 0;
file.length = 0;
return true;
}

static uint32_t find_first_unallocated_file_index(uint32_t maxfiles)
{
uint16_t hashtable[8];
@@ -223,13 +261,14 @@ bool SerialFlashChip::create(const char *filename, uint32_t length, uint32_t ali
uint32_t address, straddr, len;
SerialFlashFile file;

// check if the file already exists
if (exists(filename)) return false;

// first, get the filesystem parameters
maxfiles = check_signature();
if (!maxfiles) return false;
stringsize = (maxfiles & 0xFFFF0000) >> 14;
maxfiles &= 0xFFFF;
// TODO: should we check if the file already exists? Then what?


// find the first unused slot for this file
index = find_first_unallocated_file_index(maxfiles);

+ 45
- 2
examples/CopyFromSD/CopyFromSD.ino 查看文件

@@ -26,6 +26,7 @@ void setup() {
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;
@@ -34,11 +35,37 @@ void setup() {
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.
// copy data loop
unsigned long count = 0;
while (count < length) {
char buf[256];
@@ -56,14 +83,30 @@ void setup() {
} else {
Serial.println(" unable to create file");
}
if (++count > 12) break; // testing, only do first 12 files
f.close();
}
rootdir.close();

}


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


+ 54
- 0
examples/ListFiles/ListFiles.ino 查看文件

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

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 for Arduino Serial Monitor
while (!Serial) ;
delay(100);
Serial.println("All Files on SPI Flash chip:");

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

SerialFlash.opendir();
unsigned int count = 0;
while (1) {
char filename[64];
unsigned long filesize;

if (SerialFlash.readdir(filename, sizeof(filename), filesize)) {
Serial.print(" ");
Serial.print(filename);
spaces(20 - strlen(filename));
Serial.print(" ");
Serial.print(filesize);
Serial.print(" bytes");
Serial.println();
} else {
break; // no more files
}
}
}

void spaces(int num) {
for (int i=0; i < num; i++) {
Serial.print(" ");
}
}

void loop() {
}

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

+ 0
- 97
examples/TestHardware/TestHardware.ino 查看文件

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

SerialFlashFile file;

void setup() {
char filename[40];
uint32_t len;

while (!Serial) ;
delay(10);

//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

Serial.println("Test Hardware");
SerialFlash.begin();
#if 0
Serial.println("erase");
SerialFlash.eraseAll();
while (!SerialFlash.ready()) {
}
Serial.println("erase done");
#endif

Serial.println("Directory:");
while (SerialFlash.readdir(filename, sizeof(filename), len)) {
Serial.print(" file: ");
Serial.print(filename);
Serial.print(" bytes: ");
Serial.print(len);
Serial.println();
}
Serial.println();

Serial.println("simple.txt test");
file = SerialFlash.open("simple.txt");
if (file) {
Serial.println(" file opened");
Serial.print(" length = ");
Serial.println(file.size());
Serial.print(" addr on chip = ");
Serial.println(file.getFlashAddress());
file.close();
} else {
Serial.println(" create file");
SerialFlash.create("simple.txt", 516);
}

Serial.println("soundfile.wav test");
file = SerialFlash.open("soundfile.wav");
if (file) {
Serial.println(" file opened");
Serial.print(" length = ");
Serial.println(file.size());
Serial.print(" addr on chip = ");
Serial.println(file.getFlashAddress());
file.close();
} else {
Serial.println(" create file");
SerialFlash.createErasable("soundfile.wav", 3081000);
}

Serial.println("wavetable1 test");
file = SerialFlash.open("wavetable1");
if (file) {
Serial.println(" file opened");
Serial.print(" length = ");
Serial.println(file.size());
Serial.print(" addr on chip = ");
Serial.println(file.getFlashAddress());
file.close();
} else {
Serial.println(" create file");
SerialFlash.create("wavetable1", 181003);
}

Serial.println("end");
}


void loop() {

}


void printbuf(const void *buf, uint32_t len)
{
const uint8_t *p = (const uint8_t *)buf;
do {
Serial.print(*p++);
Serial.print(" ");
} while (--len > 0);
Serial.println();
}


Loading…
取消
儲存