#pragma once
#include "main.h"
struct fattime{
word time;
word date;
operator char*() const; // "this" darf in Flash verweisen
void operator() (const char*s=string); // "this" darf nicht in Flash verweisen!
static char string[16];
constexpr static word Time(byte h,byte m, byte s=0) {return h<<11|m<<5|s>>1;}
constexpr static word Date(word y,byte m, byte d) {return (y-1970)<<9|m<<5|d;}
private:
static void out2(char*s, byte v);
static byte in2(const char*s);
};
// Nicht alles wird in myFlash gekapselt!!
// Einiges wird in MTP.cpp direkt angesprochen, um komplizierte Interaktionen einzusparen.
namespace myFlash{
union sec_t{
struct{
union{
word sizeL;
long size;
};
fattime ctime,mtime;
char name[116];
}dirent;
byte data[128];
void empty();
};
// Der Flash-Speicher besteht aus rund 192 Pages à 128 Byte (wie CP/M-Diskette).
// FAT und Verzeichniseinträge werden im EEPROM (erste 256 Byte) geführt:
// Von 1 bis FSTART-1 die Verzeichniseinträge,
// von FSTART bis FEND die Verkettungsliste der Sektoren == Cluster.
// Es handelt sich demnach um eine 8-Bit-FAT.
// Dateien enthalten im ersten Sektor Größe (4 Byte),
// Erstellungsdatum (4 Byte), Modifikationsdatum (4 Byte) und Name (116 Byte).
// Eventuell fehlen Attribute.
const byte FSTART = 0x3C; // Erster Sektor (je nach Programmgröße!)
const byte FEND1 = 0xFC; // Hinter letztem Sektor (Platz für ubaboot)
const byte SEC_SH = 7; // 128-Byte-Sektoren
byte eer(byte a);
void eew(byte a, byte b);
void flashwrite(byte sec, const void*b);
inline word getCapacity() { // Konstant zugewiesener Platz im Flash
return (FEND1-FSTART)<<SEC_SH; // 24 KByte: knapp 8 KByte für's Programm, 512 Byte für ubaboot
}
inline byte getFreeSec() {
byte f=0;
for (byte a=FSTART; a<FEND1; a++) if (eer(a)==0xFF) f++;
return f;
}
inline word getFreeSpace() {return getFreeSec()<<SEC_SH;} // Freie Einträge in der FAT zählen
inline byte getFreeObjects() { // Freie Einträge im Verzeichnis zählen
byte f=0;
for (byte a=1; a<FSTART; a++) if (eer(a)==0xFF) f++;
return f;
}
inline byte GetNumObjects() {
byte b=0;
for (byte a=1; a<FSTART; a++) if (eer(a)!=0xFF) b++; // Einträge im Verzeichnis
return b;
}
inline const sec_t*GetObjectInfo(byte handle) {
if (!handle) return 0; // Fehler
if (handle>=FSTART) return 0; // Fehler
byte start=eer(handle); // Dateizeiger im Wurzelverzeichnis, muss 40..FB sein
return (const sec_t*)FP((char*)(start<<SEC_SH));
}
inline word GetSize(byte handle) {
return pgm_read_word(&GetObjectInfo(handle)->dirent.sizeL);
}
extern byte lastWrittenPage;
extern byte createdDirEnt;
void reserve(byte,byte);
bool Create(const sec_t*);
bool writeNextPage(const sec_t*);
bool DeleteObject(byte handle);
}/*namespace*/
Detected encoding: UTF-8 | 0
|