|
|
|
|
|
|
|
|
uint32_t sig[2]; |
|
|
uint32_t sig[2]; |
|
|
|
|
|
|
|
|
SerialFlash.read(0, sig, 8); |
|
|
SerialFlash.read(0, sig, 8); |
|
|
|
|
|
//Serial.printf("sig: %08X %08X\n", sig[0], sig[1]); |
|
|
if (sig[0] == 0xFA96554C) return sig[1]; |
|
|
if (sig[0] == 0xFA96554C) return sig[1]; |
|
|
if (sig[0] == 0xFFFFFFFF) { |
|
|
if (sig[0] == 0xFFFFFFFF) { |
|
|
sig[0] = 0xFA96554C; |
|
|
sig[0] = 0xFA96554C; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void pbuf(const void *buf, uint32_t len) |
|
|
|
|
|
{ |
|
|
|
|
|
const uint8_t *p = (const uint8_t *)buf; |
|
|
|
|
|
do { |
|
|
|
|
|
//Serial.printf("%02X ", *p++); |
|
|
|
|
|
} while (--len > 0); |
|
|
|
|
|
//Serial.println(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
SerialFlashFile SerialFlashChip::open(const char *filename) |
|
|
SerialFlashFile SerialFlashChip::open(const char *filename) |
|
|
{ |
|
|
{ |
|
|
uint32_t maxfiles, straddr; |
|
|
uint32_t maxfiles, straddr; |
|
|
|
|
|
|
|
|
SerialFlashFile file; |
|
|
SerialFlashFile file; |
|
|
|
|
|
|
|
|
maxfiles = check_signature(); |
|
|
maxfiles = check_signature(); |
|
|
|
|
|
//Serial.printf("sig: %08X\n", maxfiles); |
|
|
if (!maxfiles) return file; |
|
|
if (!maxfiles) return file; |
|
|
maxfiles &= 0xFFFF; |
|
|
maxfiles &= 0xFFFF; |
|
|
hash = filename_hash(filename); |
|
|
hash = filename_hash(filename); |
|
|
|
|
|
|
|
|
n = 8; |
|
|
n = 8; |
|
|
if (n > maxfiles - index) n = maxfiles - index; |
|
|
if (n > maxfiles - index) n = maxfiles - index; |
|
|
SerialFlash.read(8 + index * 2, hashtable, n * 2); |
|
|
SerialFlash.read(8 + index * 2, hashtable, n * 2); |
|
|
|
|
|
//Serial.printf(" read %u: ", 8 + index * 2); |
|
|
|
|
|
//pbuf(hashtable, n * 2); |
|
|
for (i=0; i < n; i++) { |
|
|
for (i=0; i < n; i++) { |
|
|
if (hashtable[i] == hash) { |
|
|
if (hashtable[i] == hash) { |
|
|
|
|
|
//Serial.printf(" hash match at index %u\n", index+i); |
|
|
buf[2] = 0; |
|
|
buf[2] = 0; |
|
|
SerialFlash.read(8 + maxfiles * 2 + (index+i) * 10, buf, 10); |
|
|
SerialFlash.read(8 + maxfiles * 2 + (index+i) * 10, buf, 10); |
|
|
|
|
|
|
|
|
|
|
|
//Serial.printf(" maxf=%d, index=%d, i=%d\n", maxfiles, index, i); |
|
|
|
|
|
//Serial.printf(" read %u: ", 8 + maxfiles * 2 + (index+i) * 10); |
|
|
|
|
|
//pbuf(buf, 10); |
|
|
straddr = 8 + maxfiles * 12 + buf[2] * 4; |
|
|
straddr = 8 + maxfiles * 12 + buf[2] * 4; |
|
|
|
|
|
//Serial.printf(" straddr = %u\n", straddr); |
|
|
if (filename_compare(filename, straddr)) { |
|
|
if (filename_compare(filename, straddr)) { |
|
|
|
|
|
//Serial.printf(" match!\n"); |
|
|
|
|
|
//Serial.printf(" addr = %u\n", buf[0]); |
|
|
|
|
|
//Serial.printf(" len = %u\n", buf[1]); |
|
|
file.address = buf[0]; |
|
|
file.address = buf[0]; |
|
|
file.length = buf[1]; |
|
|
file.length = buf[1]; |
|
|
file.offset = 0; |
|
|
file.offset = 0; |
|
|
|
|
|
|
|
|
stringsize = (maxfiles & 0xFFFF0000) >> 14; |
|
|
stringsize = (maxfiles & 0xFFFF0000) >> 14; |
|
|
maxfiles &= 0xFFFF; |
|
|
maxfiles &= 0xFFFF; |
|
|
// TODO: should we check if the file already exists? Then what? |
|
|
// TODO: should we check if the file already exists? Then what? |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// find the first unused slot for this file |
|
|
// find the first unused slot for this file |
|
|
index = find_first_unallocated_file_index(maxfiles); |
|
|
index = find_first_unallocated_file_index(maxfiles); |
|
|
if (index >= maxfiles) return false; |
|
|
if (index >= maxfiles) return false; |
|
|
|
|
|
//Serial.printf("index = %u\n", index); |
|
|
// compute where to store the filename and actual data |
|
|
// compute where to store the filename and actual data |
|
|
straddr = 8 + maxfiles * 12; |
|
|
straddr = 8 + maxfiles * 12; |
|
|
if (index == 0) { |
|
|
if (index == 0) { |
|
|
|
|
|
|
|
|
straddr += string_length(straddr); |
|
|
straddr += string_length(straddr); |
|
|
straddr = (straddr + 3) & 0x0003FFFC; |
|
|
straddr = (straddr + 3) & 0x0003FFFC; |
|
|
} |
|
|
} |
|
|
|
|
|
//Serial.printf("straddr = %u\n", straddr); |
|
|
|
|
|
//Serial.printf("address = %u\n", address); |
|
|
|
|
|
//Serial.printf("length = %u\n", length); |
|
|
if (align > 0) { |
|
|
if (align > 0) { |
|
|
// for files aligned to sectors, adjust addr & len |
|
|
// for files aligned to sectors, adjust addr & len |
|
|
address += align - 1; |
|
|
address += align - 1; |
|
|
address /= align; |
|
|
address /= align; |
|
|
address *= align; |
|
|
address *= align; |
|
|
|
|
|
//Serial.printf("align address = %u\n", address); |
|
|
length += align - 1; |
|
|
length += align - 1; |
|
|
length /= align; |
|
|
length /= align; |
|
|
length *= align; |
|
|
length *= align; |
|
|
|
|
|
//Serial.printf("align length = %u\n", length); |
|
|
} else { |
|
|
} else { |
|
|
// always align every file to a page boundary |
|
|
// always align every file to a page boundary |
|
|
// for predictable write latency and to guarantee |
|
|
// for predictable write latency and to guarantee |
|
|
|
|
|
|
|
|
// a write page). |
|
|
// a write page). |
|
|
address = (address + 255) & 0xFFFFFF00; |
|
|
address = (address + 255) & 0xFFFFFF00; |
|
|
} |
|
|
} |
|
|
|
|
|
//Serial.printf("address = %u\n", address); |
|
|
// last check, if enough space exists... |
|
|
// last check, if enough space exists... |
|
|
len = strlen(filename); |
|
|
len = strlen(filename); |
|
|
// TODO: check for enough string space for filename |
|
|
// TODO: check for enough string space for filename |
|
|
|
|
|
|
|
|
buf[1] = length; |
|
|
buf[1] = length; |
|
|
buf[2] = (straddr - (8 + maxfiles * 12)) / 4; |
|
|
buf[2] = (straddr - (8 + maxfiles * 12)) / 4; |
|
|
SerialFlash.write(8 + maxfiles * 2 + index * 10, buf, 10); |
|
|
SerialFlash.write(8 + maxfiles * 2 + index * 10, buf, 10); |
|
|
|
|
|
//Serial.printf(" write %u: ", 8 + maxfiles * 2 + index * 10); |
|
|
|
|
|
//pbuf(buf, 10); |
|
|
|
|
|
while (!SerialFlash.ready()) ; // TODO: timeout |
|
|
|
|
|
|
|
|
buf[0] = filename_hash(filename); |
|
|
buf[0] = filename_hash(filename); |
|
|
|
|
|
//Serial.printf("hash = %04X\n", buf[0]); |
|
|
SerialFlash.write(8 + index * 2, buf, 2); |
|
|
SerialFlash.write(8 + index * 2, buf, 2); |
|
|
while (!SerialFlash.ready()) ; // TODO: timeout |
|
|
while (!SerialFlash.ready()) ; // TODO: timeout |
|
|
return true; |
|
|
return true; |
|
|
|
|
|
|
|
|
index = dirindex; |
|
|
index = dirindex; |
|
|
if (index >= maxfiles) return false; |
|
|
if (index >= maxfiles) return false; |
|
|
dirindex = index + 1; |
|
|
dirindex = index + 1; |
|
|
|
|
|
//Serial.printf("readdir, index = %u\n", index); |
|
|
|
|
|
|
|
|
buf[1] = 0; |
|
|
buf[1] = 0; |
|
|
SerialFlash.read(8 + 4 + maxfiles * 2 + index * 10, buf, 6); |
|
|
SerialFlash.read(8 + 4 + maxfiles * 2 + index * 10, buf, 6); |
|
|
if (buf[0] == 0xFFFFFFFF) return false; |
|
|
if (buf[0] == 0xFFFFFFFF) return false; |
|
|
filesize = buf[0]; |
|
|
filesize = buf[0]; |
|
|
straddr = 8 + maxfiles * 12 + buf[1] * 4; |
|
|
straddr = 8 + maxfiles * 12 + buf[1] * 4; |
|
|
|
|
|
//Serial.printf(" length = %u\n", buf[0]); |
|
|
|
|
|
//Serial.printf(" straddr = %u\n", straddr); |
|
|
|
|
|
|
|
|
while (strsize) { |
|
|
while (strsize) { |
|
|
n = strsize; |
|
|
n = strsize; |
|
|
|
|
|
|
|
|
for (i=0; i < n; i++) { |
|
|
for (i=0; i < n; i++) { |
|
|
*p++ = str[i]; |
|
|
*p++ = str[i]; |
|
|
if (str[i] == 0) { |
|
|
if (str[i] == 0) { |
|
|
|
|
|
//Serial.printf(" name = %s\n", filename); |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
strsize -= n; |
|
|
strsize -= n; |
|
|
} |
|
|
} |
|
|
*(p - 1) = 0; |
|
|
*(p - 1) = 0; |
|
|
|
|
|
//Serial.printf(" name(overflow) = %s\n", filename); |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|