|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 |
-
-
- #include "SerialFlash.h"
- #include "util/crc16.h"
-
-
-
- #define DEFAULT_MAXFILES 600
- #define DEFAULT_STRINGS_SIZE 25560
-
-
- static uint32_t check_signature(void)
- {
- uint32_t sig[2];
-
- SerialFlash.read(0, sig, 8);
-
- if (sig[0] == 0xFA96554C) return sig[1];
- if (sig[0] == 0xFFFFFFFF) {
- sig[0] = 0xFA96554C;
- sig[1] = ((uint32_t)(DEFAULT_STRINGS_SIZE/4) << 16) | DEFAULT_MAXFILES;
- SerialFlash.write(0, sig, 8);
- while (!SerialFlash.ready()) ;
- SerialFlash.read(0, sig, 8);
- if (sig[0] == 0xFA96554C) return sig[1];
- }
- return 0;
- }
-
- static uint16_t filename_hash(const char *filename)
- {
-
- uint32_t hash = 2166136261;
- const char *p;
-
- for (p=filename; *p; p++) {
- hash ^= *p;
- hash *= 16777619;
- }
- hash = (hash % (uint32_t)0xFFFE) + 1;
- return hash;
- }
-
- static bool filename_compare(const char *filename, uint32_t straddr)
- {
- unsigned int i;
- const char *p;
- char buf[16];
-
- p = filename;
- while (1) {
- SerialFlash.read(straddr, buf, sizeof(buf));
- straddr += sizeof(buf);
- for (i=0; i < sizeof(buf); i++) {
- if (*p++ != buf[i]) return false;
- if (buf[i] == 0) return true;
- }
- }
- }
-
- #if 0
- 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();
- }
- #endif
-
- SerialFlashFile SerialFlashChip::open(const char *filename)
- {
- uint32_t maxfiles, straddr;
- uint16_t hash, hashtable[8];
- uint32_t i, n, index=0;
- uint32_t buf[3];
- SerialFlashFile file;
-
- maxfiles = check_signature();
-
- if (!maxfiles) return file;
- maxfiles &= 0xFFFF;
- hash = filename_hash(filename);
-
- while (index < maxfiles) {
- n = 8;
- if (n > maxfiles - index) n = maxfiles - index;
- SerialFlash.read(8 + index * 2, hashtable, n * 2);
-
-
- for (i=0; i < n; i++) {
- if (hashtable[i] == hash) {
-
- buf[2] = 0;
- SerialFlash.read(8 + maxfiles * 2 + (index+i) * 10, buf, 10);
-
-
-
-
- straddr = 8 + maxfiles * 12 + buf[2] * 4;
-
- if (filename_compare(filename, straddr)) {
-
-
-
- file.address = buf[0];
- file.length = buf[1];
- file.offset = 0;
- file.dirindex = index + i;
- return file;
- }
- } else if (hashtable[i] == 0xFFFF) {
- return file;
- }
- }
- index += n;
- }
- 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)
- {
-
-
-
- if (!file) return false;
- uint16_t hash;
- SerialFlash.read(8 + file.dirindex * 2, &hash, 2);
-
- hash ^= 0xFFFF;
- SerialFlash.write(8 + file.dirindex * 2, &hash, 2);
- while (!SerialFlash.ready()) ;
- SerialFlash.read(8 + file.dirindex * 2, &hash, 2);
- if (hash != 0) {
-
- 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];
- uint32_t i, n, index=0;
-
- do {
- n = 8;
- if (index + n > maxfiles) n = maxfiles - index;
- SerialFlash.read(8 + index * 2, hashtable, n * 2);
- for (i=0; i < n; i++) {
- if (hashtable[i] == 0xFFFF) return index + i;
- }
- index += n;
- } while (index < maxfiles);
- return 0xFFFFFFFF;
- }
-
- static uint32_t string_length(uint32_t addr)
- {
- char buf[16];
- const char *p;
- uint32_t len=0;
-
- while (1) {
- SerialFlash.read(addr, buf, sizeof(buf));
- for (p=buf; p < buf + sizeof(buf); p++) {
- len++;
- if (*p == 0) return len;
- }
- addr += sizeof(buf);
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
- bool SerialFlashChip::create(const char *filename, uint32_t length, uint32_t align)
- {
- uint32_t maxfiles, stringsize;
- uint32_t index, buf[3];
- uint32_t address, straddr, len;
- SerialFlashFile file;
-
-
- if (exists(filename)) return false;
-
-
- maxfiles = check_signature();
- if (!maxfiles) return false;
- stringsize = (maxfiles & 0xFFFF0000) >> 14;
- maxfiles &= 0xFFFF;
-
-
- index = find_first_unallocated_file_index(maxfiles);
- if (index >= maxfiles) return false;
-
-
- straddr = 8 + maxfiles * 12;
- if (index == 0) {
- address = straddr + stringsize;
- } else {
- buf[2] = 0;
- SerialFlash.read(8 + maxfiles * 2 + (index-1) * 10, buf, 10);
- address = buf[0] + buf[1];
- straddr += buf[2] * 4;
- straddr += string_length(straddr);
- straddr = (straddr + 3) & 0x0003FFFC;
- }
-
-
-
- if (align > 0) {
-
- address += align - 1;
- address /= align;
- address *= align;
-
- length += align - 1;
- length /= align;
- length *= align;
-
- } else {
-
-
-
-
-
- address = (address + 255) & 0xFFFFFF00;
- }
-
-
- len = strlen(filename);
-
- uint8_t id[3];
- SerialFlash.readID(id);
- if (address + length > SerialFlash.capacity(id)) return false;
-
- SerialFlash.write(straddr, filename, len+1);
- buf[0] = address;
- buf[1] = length;
- buf[2] = (straddr - (8 + maxfiles * 12)) / 4;
- SerialFlash.write(8 + maxfiles * 2 + index * 10, buf, 10);
-
-
- while (!SerialFlash.ready()) ;
-
- buf[0] = filename_hash(filename);
-
- SerialFlash.write(8 + index * 2, buf, 2);
- while (!SerialFlash.ready()) ;
- return true;
- }
-
- bool SerialFlashChip::readdir(char *filename, uint32_t strsize, uint32_t &filesize)
- {
- uint32_t maxfiles, index, straddr;
- uint32_t i, n;
- uint32_t buf[2];
- uint16_t hash;
- char str[16], *p=filename;
-
- filename[0] = 0;
- maxfiles = check_signature();
- if (!maxfiles) return false;
- maxfiles &= 0xFFFF;
- index = dirindex;
- while (1) {
- if (index >= maxfiles) return false;
-
- SerialFlash.read(8 + index * 2, &hash, 2);
- if (hash != 0) break;
- index++;
- }
- dirindex = index + 1;
- buf[1] = 0;
- SerialFlash.read(8 + 4 + maxfiles * 2 + index * 10, buf, 6);
- if (buf[0] == 0xFFFFFFFF) return false;
- filesize = buf[0];
- straddr = 8 + maxfiles * 12 + buf[1] * 4;
-
-
-
- while (strsize) {
- n = strsize;
- if (n > sizeof(str)) n = sizeof(str);
- SerialFlash.read(straddr, str, n);
- for (i=0; i < n; i++) {
- *p++ = str[i];
- if (str[i] == 0) {
-
- return true;
- }
- }
- strsize -= n;
- straddr += n;
- }
- *(p - 1) = 0;
-
- return true;
- }
-
-
- void SerialFlashFile::erase()
- {
- uint32_t i, blocksize;
-
- blocksize = SerialFlash.blockSize();
- if (address & (blocksize - 1)) return;
- if (length & (blocksize - 1)) return;
- for (i=0; i < length; i += blocksize) {
- SerialFlash.eraseBlock(address + i);
- }
- }
-
|