switch to mmc-0.5.4

This commit is contained in:
David Voswinkel 2009-08-09 12:15:06 +02:00
parent a27521b22b
commit 2aee210d13
8 changed files with 625 additions and 582 deletions

View File

@ -9,7 +9,9 @@
struct Fat fat; // wichtige daten/variablen der fat
struct File file; // wichtige dateibezogene daten/variablen
#if (write==1)
#if (WRITE==1)
//***************************************************************************************************************
// schreibt sektor nummer:sec auf die karte (puffer:sector) !!
// setzt bufferFlag=0 da puffer nicht dirty sein kann nach schreiben !
@ -20,25 +22,9 @@ unsigned char fat_writeSector(unsigned long int sec){
return(mmc_write_sector(sec,fat.sector)); // schreiben von sektor puffer
}
//***************************************************************************************************************
// markiert sector komplett mit 0x00 (nur den gepufferten)
// wenn neuer direktory cluster verkettet wird, muss er mit 0x00 initialisiert werden (alle felder)
//***************************************************************************************************************
void fat_markSector00(void){
fat.currentSectorNr=0; // geladener sektor wird hier geändert !
unsigned int i=512;
do{
fat.sector[i]=0x00; //schreibt puffer sector voll mit 0x00==leer
}while(--i);
}
#endif
// ***************************************************************************************************************
// umrechnung cluster auf 1.sektor des clusters (möglicherweise mehrere sektoren/cluster) !
// ***************************************************************************************************************
@ -64,7 +50,7 @@ unsigned long int fat_secToClust(unsigned long int sec){
unsigned char fat_loadSector(unsigned long int sec){
if(sec!=fat.currentSectorNr){ // nachladen nötig
#if (write==1)
#if (WRITE==1)
if(fat.bufferDirty==1) fat_writeSector(fat.currentSectorNr); // puffer diry, also vorher schreiben
#endif
mmc_read_sector(sec,fat.sector); // neuen sektor laden
@ -92,26 +78,25 @@ unsigned char fat_loadSector(unsigned long int sec){
// alle wichgigen daten wie: 1.cluster,länge bei dateien, name des eintrags, reihen nummer (im sektor), attribut use...
//***************************************************************************************************************
unsigned char fat_loadRowOfSector(unsigned int row){
unsigned char i;
unsigned char i;
row=row<<5; // multipliziert mit 32 um immer auf zeilen anfang zu kommen (zeile 0=0,zeile 1=32,zeile 2=62 usw).
void *firstCluster=&file.firstCluster; // void pointer auf file.firstCluster,zum schreiben von einzel bytes auf 4 byte variable.
void *length=&file.length; // void pointer auf datei länge, zum schreiben von einzel bytes auf 4 byte variable.
void *vsector; // void, damit man schoen umbiegen kann :)
for(i=0;i<11;i++) file.name[i]=fat.sector[row+i]; // datei name, ersten 10 bytes vom 32 byte eintrag.
for(i=0;i<11;i++)
file.name[i]=fat.sector[row+i]; // datei name, ersten 10 bytes vom 32 byte eintrag.
file.attrib=fat.sector[row+11]; // datei attribut, byte 11.
*(unsigned char*)firstCluster++=fat.sector[row+26]; // datei erster cluster , byte von klein nach hoch: 26,27,20,21 .
*(unsigned char*)firstCluster++=fat.sector[row+27]; // hier nicht mit bytesOfSec pointer, weil man hin und her springen,
*(unsigned char*)firstCluster++=fat.sector[row+20]; // müsste..
*(unsigned char*)firstCluster++=fat.sector[row+21];
vsector=&fat.sector[row+26]; // low word von fist.cluster
file.firstCluster=*(unsigned short*)vsector;
*(unsigned char*)length++=fat.sector[row+28]; // datei länge, bytes 28,29,30,31.
*(unsigned char*)length++=fat.sector[row+29];
*(unsigned char*)length++=fat.sector[row+30];
*(unsigned char*)length++=fat.sector[row+31];
vsector=&fat.sector[row+20]; // high word von first.cluster
file.firstCluster|=(*(unsigned short*)vsector)<<16;
vsector=&fat.sector[row+28]; // 4 byte von file.length
file.length=*(unsigned long int*)vsector;
return(0);
}
@ -129,16 +114,20 @@ unsigned char fat_loadFileDataFromCluster(unsigned long int sec , char name[]){
do{ // sektoren des clusters prüfen
r=0; // neuer sektor, dann reihen von 0 an.
if(0==fat_loadSector(sec+s)){ // läd den sektor:sec auf den puffer:sector
mmc_read_sector(sec+s,fat.sector); // läd den sektor sec auf den puffer fat.sector
fat.currentSectorNr=sec+s; // setzen des aktuellen sektors
do{ // reihen des sektors prüfen
fat_loadRowOfSector(r); // zeile 0-15 auf struct:file laden
fat_loadRowOfSector(r); // zeile 0-15 auf struct file laden
if(file.name[0]==0){ // wenn man auf erste 0 stößt müsste der rest auch leer sein!
file.row=r; // zeile sichern.
return(1);
}
if(0==strncmp((char*)file.name,name,10)){ // zeile r ist gesuchte
file.row=r; // zeile sichern.
return(0);
}
r++;
}while(r<16); // zählt zeilennummer (16(zeilen) * 32(spalten) == 512 bytes des sektors)
}
s++;
}while(s<fat.secPerClust); // geht durch sektoren des clusters
@ -152,7 +141,9 @@ unsigned char fat_loadFileDataFromCluster(unsigned long int sec , char name[]){
// bei fat16 wird der rootDir berreich durchsucht, bei fat32 die cluster chain des rootDir.
//***************************************************************************************************************
unsigned char fat_loadFileDataFromDir(char name[]){
unsigned int s;
if(fat.dir==0 && fat.fatType==16){ // IM ROOTDIR. fat16
for(s=0;s<(unsigned int)(fat.dataDirSec+2-fat.rootDir);s++){ // zählt durch RootDir sektoren (errechnet anzahl rootDir sektoren).
if(0==fat_loadFileDataFromCluster(fat.rootDir+s,name))return(0);// sucht die datei, wenn da, läd daten (1.cluster usw)
@ -173,7 +164,8 @@ unsigned char fat_loadFileDataFromDir(char name[]){
}
#if (smallFileSys==0)
#if (SMALL_FILE_SYSTEM==0)
//***************************************************************************************************************
// start immer im root Dir. start in root dir (dir==0).
// es MUSS in das direktory gewechselt werden, in dem die datei zum lesen/anhängen ist (außer root, da startet mann)!
@ -192,16 +184,16 @@ unsigned char fat_cd(char name[]){
return(1); // dir nicht gewechselt (nicht da?) !!
}
#endif
#if (write==1)
// datei anlegen funktionen :
#if (WRITE==1)
//fat_getFreeRowOfCluster -> fat_getFreeRowOfDir -> fat_makeRowDataEntry -> fat_makeFileEntry -> fat_writeSector -> eintrag gemacht !!
// datei anlegen funktionen :
// ***************************************************************************************************************
// sucht leeren eintrag (zeile) im cluster mit dem startsektor:secStart.
@ -211,18 +203,19 @@ unsigned char fat_cd(char name[]){
// ****************************************************************************************************************
unsigned char fat_getFreeRowOfCluster(unsigned long secStart){
unsigned int b; // zum durchgenen der sektor bytes
unsigned char s=0; // sektoren des clusters.
unsigned int i;
do{
file.row=0; // neuer sektor(oder 1.sektor), reihen von vorne.
if(0==fat_loadSector(secStart+s)){ // läd sektor auf puffer:buffer.dSector, setzt buffer.currentDatSector.
for(i=0;i<512;i=i+32){ // zählt durch zeilen (0-15).
if(fat.sector[i]==0x00||fat.sector[i]==0xE5)return(0); // prüft auf freihen eintrag (leer oder gelöscht == OK!).
if(0==fat_loadSector(secStart+s)){ // laed sektor auf puffer fat.sector
for(b=0;b<512;b=b+32){ // zaehlt durch zeilen (0-15).
if(fat.sector[b]==0x00||fat.sector[b]==0xE5)return(0); // prueft auf freihen eintrag (leer oder geloescht == OK!).
file.row++; // zählt reihe hoch (nächste reihe im sektor).
}
}
s++; // sektoren des clusters ++ weil einen geprüft.
}while(s<fat.secPerClust); // geht die sektoren des clusters durch (möglicherweise auch nur 1. sektor).
}while(s<fat.secPerClust); // geht die sektoren des clusters durch (moeglicherweise auch nur 1. sektor).
return (1); // nicht gefunden in diesem cluster (== nicht OK!).
}
@ -234,33 +227,40 @@ unsigned char fat_getFreeRowOfCluster(unsigned long secStart){
// 1. sektor des freien clusters geladen. die reihe wird auf den ersten eintrag gesetzt, da frei.
// anhand der reihe kann man nun den direktory eintrag vornehmen, und auf die karte schreiben.
// ****************************************************************************************************************
unsigned char fat_getFreeRowOfDir(unsigned long int dir){
void fat_getFreeRowOfDir(unsigned long int dir){
unsigned long int start=dir;
// solange bis ende cluster chain.
while( !((dir==0xfffffff&&fat.fatType==32)||(dir==0xffff&&fat.fatType==16)) ){
if(0==fat_getFreeRowOfCluster(fat_clustToSec(dir)))return(0); // freien eintrag in clustern, des dir gefunden !!
if(0==fat_getFreeRowOfCluster(fat_clustToSec(dir)))return; // freien eintrag in clustern, des dir gefunden !!
start=dir;
dir=fat_getNextCluster(dir);
} // wenn aus schleife raus, kein freier eintrag da -> neuer cluster nötig.
fat_getClustersInRow(2,0); // sucht freie cluster in einer reihe
dir=fat.startSectors; // muss neuen freien cluster suchen (benutzt puffer:sector).
fat_setCluster(start,dir); // cluster-chain mit neuem verketten (benutzt puffer:sector).
fat_setCluster(dir,0x0fffffff); // cluster-chain ende markieren (benutzt puffer:sector).
fat_loadSector(fat_clustToSec(dir)); // läd neuen cluster (wenn bufferFlag==1 schreibt vorher alten cluster) !!
fat_markSector00(); // löschen des sektors (nur im puffer) (benutzt puffer:sector).
dir=fat_secToClust(fat.startSectors); // dir ist jetzt neuer cluster zum verketten !
fat_setCluster(start,dir); // cluster-chain mit neuem cluster verketten
fat_setCluster(dir,0x0fffffff); // cluster-chain ende markieren
unsigned char i=1;
//es muessen neue gesucht werden, weil der bekannte aus file.c ja grade verkettet wurden. datei eintrag passte nicht mehr ins dir...
fat_getFreeClustersInRow(2); // neue freie cluster suchen, für datei.
file.firstCluster=fat_secToClust(fat.startSectors); // 1. cluster der datei
file.lastCluster=fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei
fat.currentSectorNr=fat_clustToSec(dir); // setzen des richtigen sektors, also auf den 1. der neu verketteten
unsigned int j=511;
do{
fat.sector[j]=0x00; //schreibt puffer fat.sector voll mit 0x00==leer
}while(j--);
unsigned char i=1; // ab 1 weil der 1.sektor des clusters eh noch beschrieben wird...
do{
fat_writeSector(fat.currentSectorNr+i); // löschen des cluster (überschreibt mit 0x00), wichtig bei ffls,
i++;
}while(i<fat.secPerClust);
file.row=0; // erste reihe frei, weil grad neuen cluster verkettet.
return(0); // keinen freien platz in clustern, des dir gefunden, aber neuen cluster verkettet.
file.row=0; // erste reihe frei, weil grad neuen cluster verkettet !
}
@ -269,7 +269,7 @@ unsigned char fat_getFreeRowOfDir(unsigned long int dir){
// erstellt eintrag in reihe:row, mit namen:name usw... !!
// muss noch auf die karte geschrieben werden ! nicht optimiert auf geschwindigkeit.
//***************************************************************************************************************
unsigned char fat_makeRowDataEntry(unsigned int row,char name[],unsigned char attrib,unsigned long int cluster,unsigned long int length){
void fat_makeRowDataEntry(unsigned int row,char name[],unsigned char attrib,unsigned long int cluster,unsigned long int length){
fat.bufferDirty=1; // puffer beschrieben, also neue daten darin(vor lesen muss geschrieben werden)
@ -277,31 +277,27 @@ unsigned char fat_makeRowDataEntry(unsigned int row,char name[],unsigned char at
unsigned char i; // byte zähler in reihe von sektor (32byte eintrag)
unsigned char *bytesOfSec=&fat.sector[row]; // zeiger auf sector bytes
void *vLength=&length; // zeiger auf länge (übergebener 4 byte parameter)
void *vsector;
for(i=0;i<11;i++) *bytesOfSec++=name[i]; // namen schreiben
*bytesOfSec++=attrib; // attrib schreiben
for(i=12;i<20;i++)*bytesOfSec++=0x01; // nicht nötige felder beschreiben
vsector=&fat.sector[row+12];
*(unsigned long int*)vsector++=0x01010101; // unnoetige felder beschreiben
*(unsigned long int*)vsector=0x01010101;
*bytesOfSec++=(cluster&0x00ff0000)>>16; // 1. low von cluster
*bytesOfSec++=(cluster&0xff000000)>>24; // high byte
vsector=&fat.sector[row+20];
*(unsigned short*)vsector=(cluster&0xffff0000)>>16;// low word von cluster
*bytesOfSec++=0x01; // nicht nötige felder beschreiben
*bytesOfSec++=0x01; // nicht nötige felder beschreiben
*bytesOfSec++=0x01; // nicht nötige felder beschreiben
*bytesOfSec++=0x01; // nicht nötige felder beschreiben
vsector=&fat.sector[row+22];
*(unsigned long int*)vsector=0x01010101; // unnoetige felder beschreiben
*bytesOfSec++=(cluster&0x000000ff); // low byte von cluster
*bytesOfSec++=(cluster&0x0000ff00)>>8; // 2. low
vsector=&fat.sector[row+26];
*(unsigned short*)vsector=(cluster&0x0000ffff); // high word von cluster
*bytesOfSec++ =*(unsigned char*)vLength++; // low von länge
*bytesOfSec++ =*(unsigned char*)vLength++; // 1. hi
*bytesOfSec++ =*(unsigned char*)vLength++; // 2. hi
*bytesOfSec++ =*(unsigned char*)vLength; // hi
return (0); // eintrag in puffer gemacht !
vsector=&fat.sector[row+28];
*(unsigned long int*)vsector=length; // laenge
}
@ -311,7 +307,7 @@ unsigned char fat_makeRowDataEntry(unsigned int row,char name[],unsigned char at
// sektor gepuffert. für fat16 im root dir muss andere funktion genutzt werden, als fat_getFreeRowOfDir (durchsucht nur dirs).
// fat.rootDir enthält bei fat32 den start cluster des directory, bei fat16 den 1. sektor des rootDir bereichs!
//***************************************************************************************************************
unsigned char fat_makeFileEntry(char name[],unsigned char attrib,unsigned long int cluster,unsigned long int length){
void fat_makeFileEntry(char name[],unsigned char attrib,unsigned long int length){
unsigned int s; // zähler für root dir sektoren fat16
@ -323,13 +319,10 @@ unsigned char fat_makeFileEntry(char name[],unsigned char attrib,unsigned long i
}
}
else fat_getFreeRowOfDir(fat.dir); // NICHT ROOT DIR
fat_makeRowDataEntry(file.row,name,attrib,cluster,length); // macht file eintrag im puffer
fat_writeSector(fat.currentSectorNr); // schreibt file daten auf karte
return(0);
else fat_getFreeRowOfDir(fat.dir); // NICHT ROOT DIR fat32/fat16
fat_makeRowDataEntry(file.row,name,attrib,file.firstCluster,length); // schreibt file eintrag auf puffer
fat_writeSector(fat.currentSectorNr); // schreibt puffer auf karte
}
#endif
@ -347,20 +340,14 @@ unsigned char fat_makeFileEntry(char name[],unsigned char attrib,unsigned long i
//***************************************************************************************************************
unsigned long int fat_getNextCluster(unsigned long int oneCluster){
unsigned char *bytesOfSec;
// FAT 16**************FAT 16
if(fat.fatType==16){
unsigned long int i=oneCluster>>8;; // (i=oneCluster/256)errechnet den sektor der fat in dem oneCluster ist (rundet immer ab)
unsigned long int j=(oneCluster<<1)-(i<<9); // (j=(oneCluster-256*i)*2 == 2*oneCluster-512*i)errechnet das low byte von oneCluster
if(0==fat_loadSector(i+fat.fatSec)){ // ob neu laden nötig, wird von fat_loadSector geprüft
i=0;
void *vi=&i; // zeiger auf i
bytesOfSec=&fat.sector[j]; // zeiger auf puffer
*(unsigned char*)vi++=*bytesOfSec++; // setzen low byte von i, aus puffer
*(unsigned char*)vi++=*bytesOfSec++; // setzen von höherem byte in i, aus puffer
return i; // gibt neuen cluster zurück (oder 0xffff)
void *bytesOfSec=&fat.sector[j]; // zeiger auf puffer
return *(unsigned short*)bytesOfSec; // da der ram auch little endian ist, kann einfach gecastet werden und gut :)
}
}
@ -370,49 +357,24 @@ unsigned long int fat_getNextCluster(unsigned long int oneCluster){
unsigned long int j=(oneCluster<<2)-(i<<9); // (j=(oneCluster-128*i)*4 == oneCluster*4-512*i)errechnet das low byte von oneCluster
if(0==fat_loadSector(i+fat.fatSec)){ // ob neu laden nötig wird von fat_loadSector geprüft
void *vi=&i;
bytesOfSec=&fat.sector[j];
*(unsigned char*)vi++=*bytesOfSec++;
*(unsigned char*)vi++=*bytesOfSec++;
*(unsigned char*)vi++=*bytesOfSec++;
*(unsigned char*)vi++=*bytesOfSec++;
return i;
void *bytesOfSec=&fat.sector[j]; // zeiger auf puffer
return *(unsigned long int*)bytesOfSec; // da der ram auch little endian ist, kann einfach gecastet werden und gut :)
}
}
return(0); // neuladen des fat sektors, in dem oneCluster ist nötig !!
return(0);
}
//***************************************************************************************************************
// sucht freie sektoren oder verkettete in einer reihe !
// das flag emptyOrFirst sagt ob freie oder verkettete gesucht werden. offsetCluster ist einmal der cluster ab dem
// freie gesucht werden oder der erste cluster der datei. beide male enthält fat.startSectors den ersten sektor der
// reihe und fat.cntSectors die anzahl der sektoren in einer reihe!
// [ fat.startSectors , fat.startSectors+fat.cntSectors ] = anzahl der sektoren !!
// sucht verkettete cluster einer datei, die in einer reihe liegen. worst case: nur ein cluster.
// sieht in der fat ab dem cluster offsetCluster nach. sucht die anzahl von MAX_CLUSTERS_IN_ROW,
// am stück,falls möglich. prüft ob der cluster neben offsetCluster dazu gehört...
// setzt dann fat.endSectors und fat.startSectors. das -1 weil z.b. [95,98] = {95,96,97,98} = 4 sektoren
//***************************************************************************************************************
unsigned char fat_getClustersInRow(unsigned long int offsetCluster,unsigned char emptyOrFirst){
void fat_getFatChainClustersInRow(unsigned long int offsetCluster){
unsigned char i; // variable für anzahl der zu suchenden sektoren
if(0==emptyOrFirst){ /** SUCHEN von freien sektoren (max 255 am stück) **/
i=1;
offsetCluster--; // ernidrigen, da dann inklusive diesem cluster gesucht wird
do{ // suche des 1. freien
offsetCluster++; // cluster nummer
}while(fat_getNextCluster(offsetCluster)); // freier cluster gefunden, returnwert=0 -> abbruch
fat.startSectors=fat_clustToSec(offsetCluster); // setzen des startsektors der freien sektoren (umrechnen von cluster zu sektoren)
fat.endSectors=fat.startSectors;
do{ // suche der nächsten freien
if(0==fat_getNextCluster(offsetCluster+i) ) fat.endSectors+=fat.secPerClust; // zählen der zusammenhängenden sektoren
else break; // cluster daneben ist nicht frei
i++;
}while(i<255);
fat.endSectors+=fat.secPerClust;
}
else{ /** SUCHEN von verketteten sektoren der datei (max 255 am stück) **/
i=0;
unsigned int i=0;
fat.startSectors=fat_clustToSec(offsetCluster); // setzen des 1. sektors der datei
fat.endSectors=fat.startSectors;
do{
@ -421,47 +383,53 @@ unsigned char fat_getClustersInRow(unsigned long int offsetCluster,unsigned char
file.lastCluster=offsetCluster+i; // cluster daneben gehört nicht dazu, somit ist offset+i der letzte bekannte
break;
}
i++;
}while(i<255);
fat.endSectors+=fat.secPerClust;
}
return 0;
}while(i++<MAX_CLUSTERS_IN_ROW);
fat.endSectors+=fat.secPerClust-1;
}
#if (write==1)
#if (WRITE==1)
//***************************************************************************************************************
// bekommt cluster übergeben !!!
// verkettet ab newOffsetCluster, cluster in einer reihe bis length (ist nötig zu berechnen ob schon ein neuer cluster angefangen wurde).
// sucht freie zusammenhängende cluster aus der fat. maximal MAX_CLUSTERS_IN_ROW am stück.
// erst wir der erste frei cluster gesucht, ab offsetCluster(iklusive) und dann wird geschaut, ob der
// daneben auch frei ist. setzt dann fat.endSectors und fat.startSectors. das -1 weil z.b. [95,98] = {95,96,97,98} = 4 sektoren
//***************************************************************************************************************
void fat_getFreeClustersInRow(unsigned long int offsetCluster){
unsigned int i=1; // variable für anzahl der zu suchenden sektoren
while(fat_getNextCluster(offsetCluster)) offsetCluster++; // suche des 1. freien clusters
fat.startSectors=fat_clustToSec(offsetCluster); // setzen des startsektors der freien sektoren (umrechnen von cluster zu sektoren)
fat.endSectors=fat.startSectors;
do{ // suche der nächsten freien
if(0==fat_getNextCluster(offsetCluster+i) ) fat.endSectors+=fat.secPerClust; // zählen der zusammenhängenden sektoren
else break; // cluster daneben ist nicht frei
}while(i++<MAX_CLUSTERS_IN_ROW);
fat.endSectors+=fat.secPerClust-1; // -1 weil der erste sektor schon mit zählt z.b. [95,98] = 4 sektoren
}
//***************************************************************************************************************
// verkettet ab startCluster bis einschließlich endCluster. verkettet auch den letzten bekannten mit den neu übergebenen !
// es ist wegen der fragmentierung der fat nötig, sich den letzten bekannten cluster zu merken,
// damit man bei weiteren cluster in einer reihe die alten cluster noch dazu verketten kann (so sind lücken im verketten möglich).
//***************************************************************************************************************
unsigned char fat_setClusterChain(unsigned long int newOffsetCluster,unsigned int length){
void fat_setClusterChain(unsigned long int startCluster,unsigned int endCluster){
if(length==0){ // nur ein bis zu einem sektor geschrieben ?
fat_setCluster(newOffsetCluster,0xfffffff);
return 1;
fat_setCluster(file.lastCluster,startCluster); // ende der chain setzen, bzw verketten der ketten
while(startCluster!=endCluster){
startCluster++;
fat_setCluster( startCluster-1 ,startCluster ); // verketten der cluster der neuen kette
}
unsigned int i=0;
unsigned int tmp_length=length/fat.secPerClust; // anzahl der cluster zum verketten
if( 0 != length % fat.secPerClust ) tmp_length+=1; // wenn z.b. ein sektor mehr beschrieben wurde muss ein ganzer cluster mehr verkettet werden
fat_setCluster(startCluster,0xfffffff); // ende der chain setzen
file.lastCluster=endCluster; // ende cluster der kette updaten
fat_writeSector(fat.currentSectorNr); // schreiben des fat sektors auf die karte
fat_setCluster(file.lastCluster,newOffsetCluster); // ende der chain setzen
do{
fat_setCluster( newOffsetCluster+i , newOffsetCluster+i+1 ); // verketten der cluster der neuen kette
i++;
}while( i < tmp_length );
i--; // damit ende cluster richtig gesetzt wird
fat_setCluster(newOffsetCluster+i,0xfffffff); // ende der chain setzen
file.lastCluster=newOffsetCluster+i; // ende cluster der kette updaten
fat_writeSector(fat.currentSectorNr);
return 0;
}
@ -471,9 +439,7 @@ unsigned char fat_setClusterChain(unsigned long int newOffsetCluster,unsigned in
// prüft ob buffer dirty (zu setztender cluster nicht in jetzt gepuffertem).
// prüfung erfolgt in fat_loadSector, dann wird alter vorher geschrieben, sonst gehen dort daten verloren !!
//***************************************************************************************************************
unsigned char fat_setCluster(unsigned long int cluster, unsigned long int content){
unsigned char *bytesOfSec;
void fat_setCluster(unsigned long int cluster, unsigned long int content){
// FAT 16**************FAT 16
if(fat.fatType==16){
@ -481,12 +447,9 @@ unsigned char fat_setCluster(unsigned long int cluster, unsigned long int conten
unsigned long int j=(cluster<<1)-(i<<9); // (j=(cluster-256*i)*2 == 2*cluster-512*i)errechnet das low byte von cluster
if(0==fat_loadSector(i+fat.fatSec)){ // neu laden (fat_loadSector prüft ob schon gepuffert)
bytesOfSec=&fat.sector[j]; // init des zeigers auf low byte
void *vc=&content; // init des zeigers auf content
*bytesOfSec++=*(unsigned char*)vc++; // setzen von 2 byte..
*bytesOfSec++=*(unsigned char*)vc++;
void *bytesOfSec=&fat.sector[j]; // init des zeigers auf unterste adresse
*(unsigned short*)bytesOfSec=content;// weil ram auch little endian geht das so :)
fat.bufferDirty=1; // zeigt an, dass im aktuellen sector geschrieben wurde
return (0);
}
}
@ -496,19 +459,11 @@ unsigned char fat_setCluster(unsigned long int cluster, unsigned long int conten
unsigned long int j=(cluster<<2)-(i<<9); //(j=(cluster-128*i)*4 == cluster*4-512*i)errechnet das low byte von cluster
if(0==fat_loadSector(i+fat.fatSec)){ // neu laden (fat_loadSector prüft ob schon gepuffert)
bytesOfSec=&fat.sector[j]; // init des zeigers auf low byte
void *vc=&content; // init des zeigers auf content
*bytesOfSec++=*(unsigned char*)vc++; // setzen von 4 byte....
*bytesOfSec++=*(unsigned char*)vc++;
*bytesOfSec++=*(unsigned char*)vc++;
*bytesOfSec++=*(unsigned char*)vc++;
void *bytesOfSec=&fat.sector[j]; // init des zeigers auf unterste adresse
*(unsigned long int*)bytesOfSec=content; // weil ram auch little endian geht das so :)
fat.bufferDirty=1; // zeigt an, dass im aktuellen sector geschrieben wurde
return (0);
}
}
return(1); // neuladen des fat sektors, in dem oneCluster ist, nötig !!
}
@ -543,38 +498,32 @@ unsigned char fat_loadFatData(unsigned long int sec){
unsigned int fatSz16; // 22,2 sectors occupied by one fat16
unsigned long int fatSz32; // 36,4 sectors occupied by one fat32
void *vsector;
if(0==mmc_read_sector(sec,fat.sector)){ // lesen von fat sector und bestimmen der wichtigen berreiche
fat.bufferDirty = 0; // init wert des flags
fat.secPerClust=fat.sector[13]; // fat.secPerClust, 13 only (power of 2)
fat.fatSec=fat.sector[15]; // resvdSecCnt->1.fat sektor, 15 high nibble 14 low nibble
fat.fatSec=fat.fatSec<<8;
fat.fatSec+=fat.sector[14];
vsector=&fat.sector[14];
fat.fatSec=*(unsigned short*)vsector;
rootEntCnt=fat.sector[18]; // rootEntCnt, 18 high nibble 17 low nibble
rootEntCnt=rootEntCnt<<8;
rootEntCnt+=fat.sector[17];
vsector=&fat.sector[17];
rootEntCnt=*(unsigned short*)vsector;
fatSz16=fat.sector[23]; // fatSz16, 23 high nibble 22 low nibble
fatSz16=fatSz16<<8;
fatSz16+=fat.sector[22];
vsector=&fat.sector[22];
fatSz16=*(unsigned short*)vsector;
fat.rootDir = (((rootEntCnt <<5) + 512) /512)-1; // ist 0 bei fat 32, sonst der root dir sektor
if(fat.rootDir==0){ // FAT32 spezifisch (die prüfung so, ist nicht spezifikation konform !).
void *vFatSz32=&fatSz32; // void pointer auf fatSz32 zum schreiben von 4 bytes
*(unsigned char*)vFatSz32++=fat.sector[36]; // lowest byte
*(unsigned char*)vFatSz32++=fat.sector[37]; // 1. higher byte
*(unsigned char*)vFatSz32++=fat.sector[38]; // 2. higher byte
*(unsigned char*)vFatSz32=fat.sector[39]; // high byte
void *rootDir=&fat.rootDir; // void pointer auf fat.rootDir zum schreiben von 4 bytes.
*(unsigned char*)rootDir++=fat.sector[44]; // lowest byte
*(unsigned char*)rootDir++=fat.sector[45]; // 1. higher byte
*(unsigned char*)rootDir++=fat.sector[46]; // 2. higher byte
*(unsigned char*)rootDir=fat.sector[47]; // high byte
vsector=&fat.sector[36];
fatSz32=*(unsigned long int *)vsector;
vsector=&fat.sector[44];
fat.rootDir=*(unsigned long int *)vsector;
fat.dataDirSec = fat.fatSec + (fatSz32 * fat.sector[16]); // data sector (beginnt mit cluster 2)
fat.fatType=32; // fat typ
@ -601,33 +550,28 @@ unsigned char fat_loadFatData(unsigned long int sec){
//************************************************************************************************<<***************
// int fat sucht den 1. cluster des dateisystems (fat16/32) auch VBR genannt,
// wenn superfloppy==0 wird der MBR ausgelesen um an VBR zu kommen.
//************************************************************************************************<<***************
unsigned char fat_initfat(void){
unsigned long int secOfFirstPartition=0; // ist 1. sektor der 1. partition aus dem MBR
if(superfloppy==0){ // ist partitioniert
if(0==mmc_read_sector(0,fat.sector)){
void *vSecOfFirstPartition=&secOfFirstPartition;
*(unsigned char*)vSecOfFirstPartition++=fat.sector[454];
*(unsigned char*)vSecOfFirstPartition++=fat.sector[455];
*(unsigned char*)vSecOfFirstPartition++=fat.sector[456];
*(unsigned char*)vSecOfFirstPartition++=fat.sector[457];
void *vsector=&fat.sector[454]; //startsektor bestimmen
secOfFirstPartition=*(unsigned long int*)vsector;
return fat_loadFatData(secOfFirstPartition); // läd fat daten aus dem 1. sektor der patition
}
}
//prüfung ob man schon im VBR gelesen hat (0x6964654d = "Medi")
if(secOfFirstPartition==0x6964654d) return fat_loadFatData(0); //ist superfloppy
else {
return fat_loadFatData(secOfFirstPartition); // ist nicht partitioniert, läd fat daten aus sektor 0
else {return fat_loadFatData(secOfFirstPartition);} // ist partitioniert...
}
return (1);
}
#if (smallFileSys==0)
#if (SMALL_FILE_SYSTEM==0)
// *****************************************************************************************************************
// bereitet str so auf, dass man es auf die mmc/sd karte schreiben kann.
// wandelt z.b. "t.txt" -> "T TXT" oder "main.c" in "MAIN C " => also immer 8.3 und upper case letter

View File

@ -3,45 +3,43 @@
#define _FAT_H
//#######################################################################################################################
// **************************************************************************************************************************
// WICHTIGE SCHLATER: -> hier kann die code größe angepasst werden, zu lasten der funktionalität !
#define smallFileSys 0 // wenn 1 dann ist kleines file system, wenn 0 dann komplette file unterstützung !
#define write 1 // wenn 1 dann ist write an, wenn 0 dann read only !
/** ===> hier MUSS eingestellt werden ob die karte partitioniert ist oder nicht ! <====**/
#define superfloppy 0 // wenn 0 ist partitioniert, wenn 1 ist unpartitioniert (superfloppy) !!
#define SMALL_FILE_SYSTEM 0 // wenn 1 dann ist kleines file system, wenn 0 dann komplette file unterstützung !
#define WRITE 1 // wenn 1 dann ist write an, wenn 0 dann read only !
#define OVER_WRITE 1 // wenn 1 dann kann ffwrite dateien überschreiben (nicht performant), wenn 0 dann nur normales schreiben !
#define MAX_CLUSTERS_IN_ROW 256 // gibt an wie viele cluster am stück ohne fat lookup geschrieben bzw gelesen werden können, wenn die fat nicht fragmentiert ist !
// 1. fat_getFreeRowOfCluster -> fat_getFreeRowOfDir -> fat_makeRowDataEntry -> fat_makeFileEntry -> fat_writeSector "eintrag gemacht !!"
// 2. fat_loadSector -> fat_loadRowOfSector -> fat_loadFileDataFromCluster -> fat_loadFileDataFromDir (-> fat_cd) "daten chain"
//#######################################################################################################################
// **************************************************************************************************************************
// funktionen
//extern unsigned long int fat_getFreeCluster(unsigned long int offsetCluster); // sucht leeren fat cluster aus der fat
extern unsigned long int fat_clustToSec(unsigned long int); // rechnet cluster zu 1. sektor des clusters um
extern unsigned long int fat_secToClust(unsigned long int sec); // rechnet sektor zu cluster um!
extern unsigned long int fat_getNextCluster(unsigned long int oneCluster); // fat auf nächsten, verketteten cluster durchsuchen
extern unsigned char fat_initfat(void); // initalisierung (durchsucht MBR oder nicht)
extern unsigned char fat_writeSector(unsigned long int sec); // schreibt sektor auf karte
extern unsigned char fat_setCluster(unsigned long int cluster, unsigned long int content); // setzt cluster inhalt in der fat
extern void fat_setCluster(unsigned long int cluster, unsigned long int content); // setzt cluster inhalt in der fat
extern void fat_delClusterChain(unsigned long int startCluster); // löscht cluster-chain in der fat
extern unsigned char fat_getFreeRowOfDir(unsigned long int dir); // durchsucht directory nach feiem eintrag
extern unsigned char fat_makeFileEntry(char name[],unsigned char attrib,unsigned long int cluster,unsigned long int length);
extern void fat_getFreeRowOfDir(unsigned long int dir); // durchsucht directory nach feiem eintrag
extern void fat_makeFileEntry(char name[],unsigned char attrib,unsigned long int length);
extern unsigned char fat_loadSector(unsigned long int sec); // läd übergebenen absoluten sektor
extern unsigned char fat_loadFileDataFromDir(char name[]); // durchsucht das aktuelle directory
extern unsigned char fat_cd(char *); // wechselt directory (start im rootDir)
extern unsigned char fat_loadFatData(unsigned long int); // läd fat daten
extern unsigned char fat_getFreeRowOfCluster(unsigned long secStart);// durchsucht cluster nach freiem eintrag
extern unsigned char fat_getClustersInRow(unsigned long int offsetCluster,unsigned char emptyOrFirst); // holt zusammenhängende cluster
extern unsigned char fat_makeRowDataEntry(unsigned int row,char name[],unsigned char attrib,unsigned long int cluster,unsigned long int length);
extern void fat_getFreeClustersInRow(unsigned long int offsetCluster); // sucht zusammenhängende freie cluster aus der fat
extern void fat_getFatChainClustersInRow(unsigned long int offsetCluster); // sucht fat-chain cluster die zusammenhängen
extern void fat_makeRowDataEntry(unsigned int row,char name[],unsigned char attrib,unsigned long int cluster,unsigned long int length);
extern unsigned char fat_loadRowOfSector(unsigned int); // läd reihe des geladen sektors auf struct:file
extern unsigned char fat_loadFileDataFromCluster(unsigned long int sec , char name[]); // durchsucht die reihen des geladenen sektors
extern void fat_markSector00(void); // markiert puffer:sector mit 0x00
extern unsigned char fat_setClusterChain(unsigned long int newOffsetCluster,unsigned int length);
extern char * fat_str(char *str);
extern void fat_setClusterChain(unsigned long int newOffsetCluster,unsigned int length);
extern char *fat_str(char *str); // wandelt einen string so, dass er der fat konvention entspricht !
//#######################################################################################################################
// **************************************************************************************************************************
// variablen
extern struct Fat{ // fat daten (1.cluster, root-dir, dir usw.)
@ -56,10 +54,9 @@
unsigned long int endSectors;
unsigned char secPerClust; // anzahl der sektoren pro cluster
unsigned char fatType; // fat16 oder fat32 (16 oder 32)
}fat;
extern struct File{ // datei infos (32 bytes lang- 16 bei 512 bytesPerSec)
extern struct File{ // datei infos
unsigned int cntOfBytes; // -nicht direkt aus dem dateisystem- zäht geschriebene bytes eines sektors
unsigned char name[13]; // 0,10 datei Name.ext (8.3 = max 11)(MUSS unsigned char weil E5)
unsigned char attrib; // 11,1 datei Attribut: 8=value name, 32=datei, 16=Verzeichniss, 15=linux kleingeschrieben eintrag

View File

@ -1,32 +1,42 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "hardware.h"
#include "fat.h"
#include "file.h"
//*******************************************************************************************************************************
// 2 möglichkeiten beim öffnen, datei existiert oder muss angelegt werden
// 2 möglichkeiten beim öffnen, datei existiert(return 1) oder muss angelegt werden(return 2)
// zuerst wird geprüft ob es die datei im verzeichniss gibt. danach wird entschieden, ob die datei geöffnet wird oder angelegt.
// -beim offnen werden die bekannten cluster gesucht maximal MAX_CLUSTERS_IN_ROW in reihe. dann wird der 1. sektor der datei auf
// den puffer fat.sector geladen. jetzt kann man ffread lesen...
// -beim anlegen werden freie cluster gesucht, maximal MAX_CLUSTERS_IN_ROW in reihe. dann wird das struct file gefüllt.
// danach wird der dateieintrag gemacht(auf karte). dort wird auch geprüft ob genügend platz im aktuellen verzeichniss existiert.
// möglicherweise wird der 1. cluster der datei nochmal geändert. jetzt ist der erste frei sektor bekannt und es kann geschrieben werden.
//*******************************************************************************************************************************
unsigned char ffopen(char name[]){
unsigned char file_flag=fat_loadFileDataFromDir(name); //prüfung ob datei vorhanden und evetuelles laden des file struct
if( file_flag==0 ){ /** Datei existiert, anlegen nicht nötig! **/
fat_getClustersInRow( file.firstCluster,1 ); // cluster chain suchen
fat_getFatChainClustersInRow( file.firstCluster ); // verkettete cluster aus der fat-chain suchen.
fat_loadSector( fat_clustToSec(file.firstCluster) ); // lät die ersten 512 bytes der datei auf puffer:sector.
file.lastCluster=file.firstCluster; // setzen des arbeis clusters
file.lastCluster=fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei
return 1;
}
#if (write==1)
#if (WRITE==1) // anlegen ist schreiben !
else{ /** Datei existiert nicht, also anlegen ! (nur wenn schreiben option an ist)**/
fat_getClustersInRow(3,0); // leere cluster suchen
fat_getFreeClustersInRow(2); // leere cluster suchen, ab cluster 2.
strcpy((char*)file.name,(char*)name); // --- füllen des file struct, zum abschließenden schreiben.
file.firstCluster=fat_secToClust(fat.startSectors); // 1. cluster der datei.
file.lastCluster=file.firstCluster; // letzter bekannter cluster der datei
file.firstCluster=fat_secToClust(fat.startSectors); // 1. cluster der datei
file.lastCluster=file.firstCluster;//fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei
file.attrib=32; // --- file.row wird in der funktion fat_getFreeRowOfDir geschrieben !!
fat_makeFileEntry((char *)file.name,file.attrib,file.firstCluster,0); // DATEI ANLEGEN
file.length=0; // damit da nix drin steht ^^
fat_makeFileEntry((char *)file.name,file.attrib,0); // DATEI ANLEGEN auf karte
fat.currentSectorNr=fat_clustToSec(file.firstCluster); // setzen des ersten sektors
return 2;
}
@ -35,82 +45,87 @@ unsigned char ffopen(char name[]){
//*******************************************************************************************************************************
// schließt die datei operation ab. eigentlich nur nötig wenn geschrieben wurde.
// es gibt 2 möglichkeiten :
// 1. die datei wird geschlossen und man war innerhalb der datei größe, dann muss nur der daten sektor geschrieben werden.
// 2. die datei wird geschlossen und es wurde über die alte datei länge hinaus geschrieben.
// der zweite fall ist komplizierter, weil ermittelt werden muss wie viele sektoren neu beschrieben wurden um diese zu verketten
// und die neue datei länge zu ermitteln. abschließend wird entweder (fall 1) nur der daten sektor geschrieben, oder
// der aktuallisierte datei eintrag (von setClusterChain wird ggf der dirty sector puffer geschrieben)
// schließt die datei operation ab. eigentlich nur nötig wenn geschrieben wurde. es gibt 2 möglichkeiten :
// 1. die datei wird geschlossen und es wurde über die alte datei länge hinaus geschrieben.
// 2. die datei wird geschlossen und man war innerhalb der datei größe, dann muss nur der aktuelle sektor geschrieben werden.
// der erste fall ist komplizierter, weil ermittelt werden muss wie viele sektoren neu beschrieben wurden um diese zu verketten
// und die neue datei länge muss ermitt weden. abschließend wird entweder (fall 2) nur der aktuelle sektor geschrieben, oder
// der aktuallisierte datei eintrag und die cluster (diese werden verkettet, siehe fileUpdate() ).
//*******************************************************************************************************************************
unsigned char ffclose(void){
#if (write==1)
/** 2 möglichkeiten beim schließen !! (lesend spielt keine rolle) **/
if( file.length < (file.seek+file.cntOfBytes) ){ /** 1.) es wurde über die alte datei größe hinaus geschrieben **/
#if (WRITE==1) /** 2 möglichkeiten beim schließen !! (lesend spielt keine rolle, nichts muss geupdatet werden) **/
if( file.length < (file.seek+file.cntOfBytes) ) fileUpdate(); /** 1.) es wurde über die alte datei größe hinaus geschrieben **/
else if( fat.bufferDirty==1) fat_writeSector( fat.currentSectorNr ); /** 2.) nicht über alte datei länge hinaus **/
#endif
file.cntOfBytes=0; // init werte der nötigen zähler
file.seek=0;
return(0);
}
// *******************************************************************************************************************************
// updatet datei eintrag auf der karte und verkettet die dazugehörigen fat cluster.
// füllt den aktuell beschriebenen sektor mit 0x00, da sonst die datei nicht richtig angezeigt wird.
// darf nur während schreibe operationen aufgerufen werden !
// *******************************************************************************************************************************
void fileUpdate(void){
unsigned int comp_cntOfBytes=file.cntOfBytes; // sicher nötig wegen schleife...
while( comp_cntOfBytes < 512 ){ // sektor ist beschrieben worden, daher nötigenfalls mit 00 füllen
fat.sector[comp_cntOfBytes]=0x00; // beschreibt ungenutzte bytes mit 0x00
comp_cntOfBytes++;
}
char name[13]; // zum sichern des dateinamens
unsigned long int save_length = file.cntOfBytes + file.seek; // muss gesichert werden, wird sonst von der karte geladen und verändert !
strcpy(name,(char *)file.name); // muss gesichert werden, wird sonst von der karte geladen und verändert !
fat_setClusterChain(fat_secToClust(fat.startSectors),fat.currentSectorNr - fat.startSectors); // verketten der geschriebenen cluster
fat_setClusterChain(fat_secToClust(fat.startSectors),fat_secToClust(fat.currentSectorNr)); // verketten der geschriebenen cluster
fat_loadFileDataFromDir(name); // läd sektor, des datei eintrags, und läd daten von karte auf struct file!
fat_makeRowDataEntry(file.row,name,32,file.firstCluster,save_length); // macht eintrag im puffer
fat_writeSector(fat.currentSectorNr); // abschließendes schreiben !
fat_writeSector(fat.currentSectorNr);
}
else if( fat.bufferDirty==1) fat_writeSector( fat.currentSectorNr ); /** 2.) nicht über alte datei länge hinaus **/
#endif
file.cntOfBytes=0; // init der nötigen zähler
file.seek=0;
return(0);
}
// *******************************************************************************************************************************
// offset byte wird übergeben. es wird durch die sektoren der datei gespult, bis der sektor mit dem offset byte erreicht ist,
// dann wird der sektor geladen und der zähler für die bytes eines sektors gesetzt. wenn das byte nicht in den sektoren ist,
// die vorgeladen wurden, müssen noch weitere sektoren der datei gesucht werden.
// offset byte wird übergeben. es wird durch die sektoren der datei gespult (gerechnet), bis der sektor mit dem offset byte erreicht
// ist, dann wird der sektor geladen und der zähler für die bytes eines sektors gesetzt. wenn das byte nicht in den sektoren ist,
// die "vorgesucht" wurden, müssen noch weitere sektoren der datei gesucht werden (sec > fat.endSectors).
// *******************************************************************************************************************************
void ffseek(unsigned long int offset){
fat_getClustersInRow(file.firstCluster,1); // suchen von anfang der cluster chain aus !
unsigned long int sec=fat.startSectors; // setzen des 1. sektors der neu gesuchten // sektor variable zum durchgehen durch die sektoren
#if (OVER_WRITE==1) // man muss den dateieintrag updaten, um die daten zu retten !!
if( file.seek > file.length ) fileUpdate(); // fat verketten und datei update auf der karte !
#endif
do{ /** 3 möglichkeiten ab hier ! **/
if(offset>=512){ /** 1. offset ist in nächstem sektor **/
fat_getFatChainClustersInRow(file.firstCluster); // suchen von anfang der cluster chain aus !
unsigned long int sec=fat.startSectors; // sektor variable zum durchgehen durch die sektoren
file.seek=0; // weil auch von anfang an der chain gesucht wird mit 0 initialisiert
while(offset>=512){ /** suchen des sektors in dem offset ist **/
sec++; // da byte nicht in diesem sektor ist, muss hochgezählt werden
offset-=512; // ein sektor weniger in dem das byte sein kann
file.seek+=512; // file.seek update, damit bei ffclose() die richtige file.length herauskommt
if ( sec > fat.endSectors ){ // es müssen mehr sektoren der datei gesucht werden
fat_getFatChainClustersInRow(fat_getNextCluster( file.lastCluster ) ); // nachladen von clustern in der chain
sec=fat.startSectors; // setzen des 1. sektors der neu geladenen, zum weitersuchen !
}
else break; /** 2. sektor in dem offset ist, ist gefunden ! **/
if ( sec == fat.endSectors ){ /** 3. es müssen mehr sektoren der datei gesucht werden **/
fat_getClustersInRow(fat_getNextCluster( file.lastCluster ),1 ); // nachladen von clustern in der chain
sec=fat.startSectors; // setzen des 1. sektors der neu gesuchten
}
}while(1);
file.lastCluster=fat_secToClust(sec); // letzter bekannter cluster der datei
file.lastCluster=fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei
fat_loadSector(sec); // sektor mit offset byte laden
file.cntOfBytes = offset % 512; // setzen des lese zählers
file.cntOfBytes = offset; // setzen des lese zählers
}
#if (smallFileSys==0)
#if (SMALL_FILE_SYSTEM==0)
//***************************************************************************************PhysFS****************************************
// *******************************************************************************************************************************
// wechselt verzeichniss. start immer im root Dir.
// MUSS in das direktory gewechselt werden, in dem die datei zum lesen/schreiben ist !
// *******************************************************************************************************************************
@ -129,13 +144,12 @@ void lsRowsOfClust (unsigned long int start_sec){
unsigned char row; // reihen
unsigned char sec=0; // sektoren
do{
fat_loadSector(start_sec + sec); // sektoren des clusters laden
for(row=0;row<16;row++){ // geht durch reihen des sektors
fat_loadRowOfSector(row); // reihe eines sektors (auf dem puffer) laden
if( (file.attrib==0x20||file.attrib==0x10) && (file.name[0]!=0xE5 && file.name[0]!=0x00) ){
printf("%s %li\n",file.name, file.length);
printf("Name:%s Size:%li\n",file.name,file.length );
}
}
}while(++sec<fat.secPerClust);
@ -147,7 +161,7 @@ void lsRowsOfClust (unsigned long int start_sec){
// unterscheidung ob man sich im rootDir befindet nötig, weil bei fat16 im root dir eine bestimmt anzahl sektoren durchsucht
// werden müssen und bei fat32 ab einem start cluster ! ruft lsRowsOfClust auf um cluster/sektoren anzuzeigen.
// *******************************************************************************************************************************
unsigned char ffls(void){
void ffls(void){
unsigned long int clust; // cluster
unsigned int s; // fat16 root dir sektoren
@ -166,7 +180,6 @@ unsigned char ffls(void){
clust=fat_getNextCluster(clust); // liest nächsten cluster des dir-eintrags
}
}
return(0);
}
@ -188,57 +201,61 @@ unsigned char ffcdLower(void){
}
#ifndef __AVR_ATmega8__
// *******************************************************************************************************************************
// erstellt einen dir eintrag im aktuellen verzeichniss (geht nur wenn keine lese/schreib usw. vorgänge).
// prüft ob es den den dir-namen:name schon gibt, dann wird nichts angelegt.
// erstellt einen dir eintrag im aktuellen verzeichniss.
// prüft ob es den den dir-namen schon gibt, dann wird nichts angelegt.
// wenn ok, dann wird ein freier cluster gesucht, als ende markiert, der eintrag ins dir geschrieben.
// dann wird der cluster des dirs aufbereitet. der erste sektor des clusters enthält den "." und ".." eintrag.
// der "." hat den 1. cluster des eigenen dirs. der ".." eintrag ist der 1. cluster des parent dirs.
// ein dir wird immer mit 0x00 initialisiert ! also alle sektoren des clsters ( bis auf . und .. einträge)!
// ein dir wird immer mit 0x00 initialisiert ! also alle einträge der sektoren des clusters ( bis auf . und .. einträge)!
// *******************************************************************************************************************************
unsigned char ffmkdir(char name[]){
#ifndef __AVR_ATmega8__
void ffmkdir(char name[]){
unsigned char i;
if(0==fat_loadFileDataFromDir(name))return (1); // prüft ob dirname im dir schon vorhanden, wenn ja, abbruch !
unsigned int j;
fat_getClustersInRow(2,0); // holt neue freie cluster, ab cluster 2 ...
if(0==fat_loadFileDataFromDir(name))return ; // prüft ob dirname im dir schon vorhanden, wenn ja, abbruch !
// cluster in fat setzen, und ordner eintrg im aktuellen verzeichniss machen.
fat_getFreeClustersInRow(2); // holt neue freie cluster, ab cluster 2 ...
fat_setCluster(fat_secToClust(fat.startSectors),0x0fffffff); // fat16/32 cluster chain ende setzen. (neuer ordner in fat)
file.firstCluster=fat_secToClust(fat.startSectors); // dammit fat_makeFileEntry den cluster richtig setzen kann
fat_makeFileEntry(name,0x10,0); // macht dir eintrag im aktuellen verzeichniss (legt ordner im partent verzeichniss an)
fat_makeFileEntry(name,0x10,fat_secToClust(fat.startSectors),0); // macht dir eintrag im aktuellen verzeichniss (legt ordner im partent verzeichniss an)
// aufbereiten des neuen dir clusters !
fat_markSector00(); // löschen des sektors (nur im puffer)./**/
// fat_makeRowDataEntry(0,(char *)str_p(PSTR(". ")),0x10,fat_secToClust(fat.currentSectorNr),0); // macht "." eintrag des dirs
// fat_makeRowDataEntry(1,(char *)str_p(PSTR(".. ")),0x10,fat.dir,0); // macht ".." eintrag des dirs
fat_makeRowDataEntry(0,". ",0x10,fat_secToClust(fat.currentSectorNr),0); // macht "." eintrag des dirs
fat_makeRowDataEntry(1,".. ",0x10,fat.dir,0); // macht ".." eintrag des dirs
fat_writeSector(fat_clustToSec(fat.startSectors)); // schreibt einträge auf karte !
fat_markSector00(); // löschen des sektors (nur im puffer).
// aufbereiten des puffers
j=511;
do{
fat.sector[j]=0x00; //schreibt puffer fat.sector voll mit 0x00==leer
}while(j--);
// aufbereiten des clusters
for(i=1;i<fat.secPerClust;i++){ // ein dir cluster muss mit 0x00 initialisiert werden !
fat_writeSector(fat.startSectors+i); // löschen des cluster (überschreibt mit 0x00), wichtig bei ffls!
}
#endif
return(0);
// aufbereiten des neuen dir sektors mit "." und ".." eintraegen !
fat_makeRowDataEntry(0,". ",0x10,file.firstCluster,0); // macht "." eintrag des dirs
fat_makeRowDataEntry(1,".. ",0x10,fat.dir,0); // macht ".." eintrag des dirs
fat_writeSector(fat_clustToSec(file.firstCluster)); // schreibt einträge auf karte !
}
#endif // ffmkdir wegen atmega8
#endif
#if (write==1)
#if (WRITE==1)
//*******************************************************************************************************************************
// löscht datei aus aktuellem verzeichniss, wenn es die datei gibt.
// löscht datei/ordner aus aktuellem verzeichniss, wenn es die datei gibt.
// löscht dateien und ordner rekursiv !
//*******************************************************************************************************************************
unsigned char ffrm(char name[]){
if(0==fat_loadFileDataFromDir(name)){ // datei oder ordner ist vorhanden, nur dann lösch operation
if(0==fat_loadFileDataFromDir(name)){ // datei/ordner gibt es
if(file.attrib!=0x10){ // ist datei.
fat.sector[file.row<<5]=0xE5; // datei gelöscht markieren (file.row*32, damit man auf reihen anfang kommt)
if((file.row-1)>=0){ // gibt es einen eintrag davor ?
@ -251,12 +268,12 @@ unsigned char ffrm(char name[]){
}
//TODO noch nicht optimal. zu viele schreib vorgänge beim löschen von datei einträgen. max bis zu 16/sektor !
else{ // ist ordner, rekursiv löschen !!
else{ // ist ordner, dann rekursiv löschen !!
#ifndef __AVR_ATmega8__ // mega8 zu klein für die funktionalität....
unsigned long int parent;
unsigned long int own;
unsigned long int clustsOfDir; // um durch die cluster chain eines dirs zu gehen.
unsigned long int cntSecOfClust=0;
unsigned char cntSecOfClust=0;
unsigned char i=0;
fat.sector[file.row<<5]=0xE5; // löscht dir eintrag
@ -289,7 +306,7 @@ unsigned char ffrm(char name[]){
fat.bufferDirty=1; // puffer eintrag gemacht
}
if(file.attrib==0x10&&file.name[0]!='.'&&file.name[0]!=0xe5&&file.name[0]!=0){ // ordner erkannt !
if(file.attrib==0x10 && file.name[0]!='.' && file.name[0]!=0xE5 && file.name[0]!=0){ // ordner erkannt !
fat.sector[i<<5]=0xE5; // dir eintrag als gelöscht markiert
fat.bufferDirty=1; // puffer eintrag gemacht
fat_loadSector(fat_clustToSec(file.firstCluster)); // sektor des dirs laden
@ -338,6 +355,7 @@ unsigned char ffrm(char name[]){
return(1); // fehler, nicht gefunden?
}
#endif
@ -349,8 +367,8 @@ inline unsigned char ffread(void){
if(file.cntOfBytes==512){ /** EINEN SEKTOR GLESEN (ab hier 2 möglichkeiten !) **/
file.cntOfBytes=0; // byte zähler zurück setzen
if( fat.currentSectorNr == fat.endSectors-1 ){ /** 1.) nötig mehr sektoren der chain zu laden (mit ein bisschen glück nur alle 512*500=256000 bytes)**/
fat_getClustersInRow(fat_getNextCluster(fat_secToClust( fat.endSectors-1) ),1); // nachladen von clustern in der chain
if( fat.currentSectorNr == fat.endSectors ){ /** 1.) nötig mehr sektoren der chain zu laden (mit ein bisschen glück nur alle 512*MAX_CLUSTERS_IN_ROW bytes)**/
fat_getFatChainClustersInRow(fat_getNextCluster(fat_secToClust( fat.endSectors) )); // nachladen von clustern in der chain
fat.currentSectorNr=fat.startSectors-1; // setzen des nächsten sektors um weiter lesen zu können..
}
fat_loadSector(fat.currentSectorNr+1); /** 2.) die bekannten in einer reihe reichen noch.(nur alle 512 bytes)**/
@ -360,37 +378,72 @@ inline unsigned char ffread(void){
}
#if (write==1)
#if (WRITE==1)
#if (OVER_WRITE==0) // nicht überschreibende write funktion
//*******************************************************************************************************************************
// schreibt 512 byte blöcke auf den puffer fat.sector. dann wird dieser auf die karte geschrieben. wenn genügend feie
// sektoren zum beschreiben bekannt sind, muss nicht in der fat nachgeschaut werden. sollten nicht genügend zusammenhängende
// sektoren bekannt sein, werden die alten verkettet und neue gesucht (ist nötig sich den letzten bekannten zu merken -> file.lastCluster).
// es wird geprüft ob eine datei überschrieben wird (dann werden keine neuen sektoren verkettet), oder ob man über das
// dateiende hinaus schreibt. wichtige variabeln: fat.startSectors/fat.endSectors, fat.currentSectorNr und file.cntOfBytes
// sektoren zum beschreiben bekannt sind(datenmenge zu groß), muss nicht in der fat nachgeschaut werden. sollten nicht genügend
// zusammenhängende sektoren bekannt sein, werden die alten verkettet und neue gesucht. es ist nötig sich den letzten bekannten
// einer kette zu merken -> file.lastCluster, um auch nicht zusammenhängende cluster verketten zu können (fat_setClusterChain macht das)!
//*******************************************************************************************************************************
inline void ffwrite(unsigned char c){
fat.sector[file.cntOfBytes++]=c; // schreiben des chars auf den puffer sector und zähler erhöhen (pre-increment)
fat.bufferDirty=1; // puffer dirty weil geschrieben und noch nicht auf karte.
if( file.cntOfBytes==512 ){ /** SEKTOR GESCHRIEBEN ( 2 möglichkeiten ab hier !) **/
if( file.cntOfBytes==512 ){ /** SEKTOR VOLL ( 2 möglichkeiten ab hier !) **/
file.cntOfBytes=0; // rücksetzen des sektor byte zählers
mmc_write_sector(fat.currentSectorNr++,fat.sector); /** 1.) vollen sektor auf karte schreiben und hochzählen von sektoren**/
mmc_write_sector(fat.currentSectorNr,fat.sector); /** 1.) vollen sektor auf karte schreiben **/
fat.bufferDirty=0; // puffer jetzt clear, weil grade alles geschrieben.
file.seek+=512; // position in der datei erhöhen, weil grade 512 bytes geschrieben
if( fat.currentSectorNr==fat.endSectors ){ /** 2.) es ist nötig, neue freie zu suchen und die alten zu verketten (mit ein bischen glück nur alle 512*MAX_CLUSTERS_IN_ROW bytes) **/
fat_setClusterChain( fat_secToClust(fat.startSectors) , fat_secToClust(fat.endSectors) ); // verketten der beschriebenen
fat_getFreeClustersInRow(file.lastCluster); // suchen von leeren sektoren.
fat.currentSectorNr=fat.startSectors-1; // setzen des 1. sektors der neuen reihe zum schreiben.
}
fat.currentSectorNr++; // nächsten sektor zum beschreiben.
}
}
if( fat.currentSectorNr==fat.endSectors ){ /** 2.) es ist nötig, neue freie zu suchen und die alten zu verketten (mit ein bischen glück nur alle 512*500 bytes) **/
unsigned char flag=1;
#endif
#if (OVER_WRITE==1) // überschreibende write funktion, nicht performant, weil immer auch noch ein sektor geladen werden muss
//*******************************************************************************************************************************
// schreibt 512 byte blöcke auf den puffer fat.sector. dann wird dieser auf die karte geschrieben. wenn genügend feie
// sektoren zum beschreiben bekannt sind, muss nicht in der fat nachgeschaut werden. sollten nicht genügend zusammenhängende
// sektoren bekannt sein(datenmenge zu groß), werden die alten verkettet und neue gesucht. es ist nötig sich den letzten bekannten einer
// kette zu merken -> file.lastCluster, um auch nicht zusammenhängende cluster verketten zu können (fat_setClusterChain macht das)!
// es ist beim überschreiben nötig, die schon beschriebenen sektoren der datei zu laden, damit man die richtigen daten
// hat. das ist blöd, weil so ein daten overhead von 50% entsteht. da lesen aber schneller als schreiben geht, verliert man nicht 50% an geschwindigkeit.
//*******************************************************************************************************************************
inline void ffwrite(unsigned char c){
fat.sector[file.cntOfBytes++]=c; // schreiben des chars auf den puffer sector und zähler erhöhen (pre-increment)
fat.bufferDirty=1; // puffer dirty weil geschrieben und noch nicht auf karte.
if( file.cntOfBytes==512 ){ /** SEKTOR VOLL ( 2 möglichkeiten ab hier !) **/
file.cntOfBytes=0; // rücksetzen des sektor byte zählers.
mmc_write_sector(fat.currentSectorNr,fat.sector); /** 1.) vollen sektor auf karte schreiben**/
fat.bufferDirty=0; // puffer jetzt clear, weil grade alles geschrieben.
file.seek+=512; // position in der datei erhöhen, weil grade 512 bytes geschrieben.
if( fat.currentSectorNr==fat.endSectors ){ /** 2.) es ist nötig, neue freie zu suchen und die alten zu verketten (mit ein bischen glück nur alle 512*MAX_CLUSTERS_IN_ROW bytes) **/
if( file.seek > file.length ){ // außerhalb der datei !!
fat_setClusterChain(fat_secToClust(fat.startSectors),fat.endSectors-fat.startSectors); // verketten der beschriebenen
flag=0;
fat_setClusterChain( fat_secToClust(fat.startSectors) , fat_secToClust(fat.endSectors) ); // verketten der beschriebenen.
fat_getFreeClustersInRow( file.lastCluster ); // neue leere sektoren benötigt, also suchen.
}
fat_getClustersInRow(file.lastCluster,flag); // suchen der neuen sektoren.
fat.currentSectorNr=fat.startSectors; // setzen des 1. sektors der neuen reihe zum schreiben.
else {
fat_getFatChainClustersInRow( fat_getNextCluster(file.lastCluster) ); // noch innerhalb der datei, deshlab verkettete suchen.
}
fat.currentSectorNr=fat.startSectors-1; // setzen des 1. sektors der neuen reihe zum schreiben.
}
fat.currentSectorNr++; // nächsten sektor zum beschreiben.
mmc_read_sector(fat.currentSectorNr,fat.sector); // wegen überschreiben, muss der zu beschreibende sektor geladen werden...
}
}
#endif
// *******************************************************************************************************************************
// schreibt string auf karte, siehe ffwrite()
@ -398,6 +451,7 @@ inline void ffwrite(unsigned char c){
inline void ffwrites(const char *s ){
while (*s) ffwrite(*s++);
}
#endif

View File

@ -5,7 +5,7 @@
#define _FILE_H
//#######################################################################################################################
// **************************************************************************************************************************
// funktionen
extern inline unsigned char ffread(void); // liest byte-weise aus der datei (puffert immer 512 bytes zwischen)
@ -17,13 +17,14 @@
extern void ffseek(unsigned long int offset); // setzt zeiger:bytesOfSec auf position in der geöffneten datei.
extern unsigned char ffcd(char name[]); // wechselt direktory
extern unsigned char ffls(void); // zeigt direktory inhalt an
extern void ffls(void); // zeigt direktory inhalt an
extern unsigned char ffcdLower(void); // geht ein direktory zurück, also cd.. (parent direktory)
extern unsigned char ffrm(char name[]); // löscht datei aus aktuellem verzeichniss.
extern unsigned char ffmkdir(char name[]); // legt ordner in aktuellem verzeichniss an.
extern void ffmkdir(char name[]); // legt ordner in aktuellem verzeichniss an.
void lsRowsOfClust (unsigned long int start_sec); // zeigt reihen eines clusters an, ab start_sec
void fileUpdate(void); // updatet datei eintrag auf karte
//#######################################################################################################################
// **************************************************************************************************************************// #######################################################################################################################

View File

@ -1,6 +1,6 @@
/*
File: main.smc
Time: Thu, 06 Aug 2009 20:01:38
Time: Sun, 09 Aug 2009 11:41:19
*/
#include <avr/pgmspace.h>
#include <loader.h>

View File

@ -26,16 +26,18 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#######################################################################################*/
#include <avr/io.h>
#include <stdio.h>
#include "mmc.h"
#include <util/delay.h>
//############################################################################
//Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE)
unsigned char mmc_init (){
unsigned int Timeout = 0;
unsigned char mmc_init (void){
unsigned char a;
unsigned char b;
unsigned int Timeout = 0;
//Konfiguration des Ports an der die MMC/SD-Karte angeschlossen wurde
MMC_Direction_REG &=~(1<<SPI_DI); //Setzen von Pin MMC_DI auf Input
MMC_Direction_REG |= (1<<SPI_Clock); //Setzen von Pin MMC_Clock auf Output
@ -45,25 +47,29 @@ unsigned char mmc_init (){
MMC_Write |= (1<<MMC_Chip_Select); //Setzt den Pin MMC_Chip_Select auf High Pegel
for(a=0;a<200;a++){
nop();
nop();
nop();
}; //Wartet eine kurze Zeit
//Aktiviren des SPI - Bus, Clock = Idel LOW
//SPI Clock teilen durch 128
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); //Enable SPI, SPI in Master Mode
//SPSR = (0<<SPI2X);
_delay_ms(10);
//Initialisiere MMC/SD-Karte in den SPI-Mode
for (b = 0;b<0x0f;b++){ //Sendet min 74+ Clocks an die MMC/SD-Karte
for (a = 0;a<0x0f;a++){ //Sendet min 74+ Clocks an die MMC/SD-Karte
mmc_write_byte(0xff);
_delay_us(100);
}
//Sendet Commando CMD0 an MMC/SD-Karte
unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
while(mmc_write_command (CMD) !=1){
_delay_us(100);
if (Timeout++ > 200){
MMC_Disable();
printf("fail1\n");
return(1); //Abbruch bei Commando1 (Return Code1)
}
}
@ -74,7 +80,6 @@ unsigned char mmc_init (){
while( mmc_write_command (CMD) !=0){
if (Timeout++ > 400){
MMC_Disable();
printf("fail2\n");
return(2); //Abbruch bei Commando2 (Return Code2)
}
}
@ -92,9 +97,10 @@ unsigned char mmc_init (){
//############################################################################
//Sendet ein Commando an die MMC/SD-Karte
unsigned char mmc_write_command (unsigned char *cmd){
unsigned char a;
unsigned char tmp = 0xff;
unsigned int Timeout = 0;
unsigned char a;
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable();
@ -122,22 +128,16 @@ unsigned char mmc_write_command (unsigned char *cmd){
//############################################################################
//Routine zum Empfangen eines Bytes von der MMC-Karte
unsigned char mmc_read_byte (void){
//unsigned char Byte = 0;
SPDR = 0xff;
while(!(SPSR & (1<<SPIF))){};
//Byte = SPDR;
return (SPDR);
}
//############################################################################
//Routine zum Senden eines Bytes zur MMC-Karte
void mmc_write_byte (unsigned char Byte){
SPDR = Byte; //Sendet ein Byte
while(!(SPSR & (1<<SPIF))){ //Wartet bis Byte gesendet wurde
while(!(SPSR & (1<<SPIF))){ ; //Wartet bis Byte gesendet wurde
}
}
@ -146,13 +146,15 @@ void mmc_write_byte (unsigned char Byte){
//Routine zum schreiben eines Blocks(512Byte) auf die MMC/SD-Karte
unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer){
unsigned char tmp;
unsigned int a;
unsigned char b;
//Commando 24 zum schreiben eines Blocks auf die MMC/SD - Karte
unsigned char cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
unsigned char a;
unsigned int i;
/*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
addr wird von Blocks zu Bytes umgerechnet danach werden
diese in das Commando eingef<EFBFBD>gt*/
diese in das Commando eingefuegt*/
addr = addr << 9; //addr = addr * 512
@ -162,13 +164,11 @@ unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer){
//Sendet Commando cmd24 an MMC/SD-Karte (Write 1 Block/512 Bytes)
tmp = mmc_write_command (cmd);
if (tmp != 0)
{
return(tmp);
}
if (tmp != 0) return(tmp);
//Wartet einen Moment und sendet einen Clock an die MMC/SD-Karte
for (a=0;a<100;a++)
for (b=0;b<100;b++)
{
mmc_read_byte();
}
@ -177,10 +177,13 @@ unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer){
mmc_write_byte(0xFE);
//Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte
for (i=0;i<512;i++)
{
mmc_write_byte(*Buffer++);
}
a=511; // do while konstrukt weils schneller geht
tmp=*Buffer++; // holt neues byte aus ram in register
do{
SPDR = tmp; //Sendet ein Byte
tmp=*Buffer++; // holt schonmal neues aus ram in register
while( !(SPSR & (1<<SPIF)) ){ ;}//Wartet bis Byte gesendet wurde
}while(a--);
//CRC-Byte schreiben
mmc_write_byte(0xFF); //Schreibt Dummy CRC
@ -201,8 +204,10 @@ return(0);
//############################################################################
//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
void mmc_read_block(unsigned char *cmd,unsigned char *Buffer,unsigned int Bytes){
//Sendet Commando cmd an MMC/SD-Karte
unsigned int a;
//Sendet Commando cmd an MMC/SD-Karte
if (mmc_write_command (cmd) != 0)
{
return;
@ -249,3 +254,26 @@ unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer){
}
/*
//############################################################################
//Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
unsigned char mmc_read_cid (unsigned char *Buffer){
//Commando zum lesen des CID Registers
unsigned char cmd[] = {0x4A,0x00,0x00,0x00,0x00,0xFF};
mmc_read_block(cmd,Buffer,16);
return(0);
}
//############################################################################
//Routine zum lesen des CSD Registers von der MMC/SD-Karte (16Bytes)
unsigned char mmc_read_csd (unsigned char *Buffer){
//Commando zum lesen des CSD Registers
unsigned char cmd[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
mmc_read_block(cmd,Buffer,16);
return(0);
}
*/

View File

@ -13,13 +13,16 @@ Copyright (C) 2004 Ulrich Radig
#define MMC_Direction_REG DDRB
#if defined (__AVR_ATmega644__)
#define SPI_DI 6 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist
#define SPI_DO 5 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist
#define SPI_Clock 7 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk)
#define MMC_Chip_Select 4 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist
//#define SPI_SS 4 //Nicht Benutz mu<6D> aber definiert werden
#endif
//Prototypes
extern unsigned char mmc_read_byte(void);
extern void mmc_write_byte(unsigned char);
extern void mmc_read_block(unsigned char *,unsigned char *,unsigned in);
@ -27,10 +30,15 @@ Copyright (C) 2004 Ulrich Radig
extern unsigned char mmc_read_sector (unsigned long,unsigned char *);
extern unsigned char mmc_write_sector (unsigned long,unsigned char *);
extern unsigned char mmc_write_command (unsigned char *);
//extern unsigned char mmc_read_csd (unsigned char *);
//extern unsigned char mmc_read_cid (unsigned char *);
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
#define MMC_Disable() MMC_Write|= (1<<MMC_Chip_Select);
//set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
#define MMC_Enable() MMC_Write&=~(1<<MMC_Chip_Select);
#define nop() __asm__ __volatile__ ("nop" ::)
#endif

View File

@ -128,37 +128,48 @@ void test_sdcard(void){
printf("fatinit failed\n");
return;
}
ffls();
char datei[12]="test.txt"; // hier muss platz für 11 zeichen sein (8.3), da fat_str diesen string benutzt !!
fat_str(datei); // wandelt "test.txt" in das fat format 8.3 der form: "TEST TXT" muss immer dieses Format haben, auch ordner !!
printf("rmove %s\n",datei);
// 0.) ______________löschen von dateien/ordnern (ordner rekursiv)____________________________________________
ffrm( datei ); // löschen der datei/ordner falls vorhanden
// 1.) ______________anlegen und schreiben____________________________________________________________________
/* öffnet datei, wenn nicht vorhanden, legt ffopen datei an (rückgabewert = 1 datei existiert, also nur öffnen, 2 = angelegt). */
printf("open %s\n",datei);
ffopen( datei );
printf("write %s\n",datei);
/* schreibt string */
ffwrites((char*)"Hallo Datei :)");
// neue zeile in der datei
ffwrite(0x0D);
ffwrite(0x0A);
printf("close %s\n",datei);
/* schließt datei */
ffclose();
printf("open %s\n",datei);
// 2.)________________ändern von vorhandenen daten in dateien__________________________________________________
ffopen( datei ); // siehe oben...
printf("seek %s\n",datei);
ffseek(12); // spult in datei auf position 12 vor (fängt immer bei 0 an zu zählen !)
printf("write %s\n",datei);
ffwrite(';'); // schreibt dann ab position 12 (überschreibt daten der datei, hier nur 1 zeichen)
printf("close %s\n",datei);
ffclose(); // schließt datei
// 3.)________________lesen von dateien_________________________________________________________________________
ffopen( datei ); // siehe oben...
ffopen( datei );
ffls();
// siehe oben...
printf("open %s\n",datei);
unsigned long int seek=file.length; // eine variable setzen und runterzählen bis 0 geht am schnellsten !
do{
printf(ffread()); // liest ein zeichen und gibt es über uart aus !
printf("%c",ffread()); // liest ein zeichen und gibt es über uart aus !
}while(--seek); // liest solange bytes da sind (von datei länge bis 0)
ffclose(); // schließt datei