From 8656beb76945bb53a9e4d8010be4b6a0af153286 Mon Sep 17 00:00:00 2001 From: David Voswinkel Date: Mon, 10 Aug 2009 19:26:01 +0200 Subject: [PATCH] code cleanup --- avr/usbload/fat.c | 797 ++++++++++++++++++++++-------------------- avr/usbload/fat.h | 121 +++---- avr/usbload/file.c | 617 ++++++++++++++++---------------- avr/usbload/file.h | 45 ++- avr/usbload/mmc.c | 128 ++++--- avr/usbload/mmc.h | 42 +-- avr/usbload/testing.c | 24 +- quickdev16.tmproj | 344 +++++++++++++++++- 8 files changed, 1262 insertions(+), 856 deletions(-) diff --git a/avr/usbload/fat.c b/avr/usbload/fat.c index cc0fa2c..f19207e 100644 --- a/avr/usbload/fat.c +++ b/avr/usbload/fat.c @@ -6,20 +6,21 @@ #include "file.h" #include "hardware.h" -struct Fat fat; // wichtige daten/variablen der fat -struct File file; // wichtige dateibezogene daten/variablen +struct Fat fat; // wichtige daten/variablen der fat +struct File file; // wichtige dateibezogene daten/variablen #if (WRITE==1) -//*************************************************************************************************************** +// *************************************************************************************************************** // schreibt sektor nummer:sec auf die karte (puffer:sector) !! // setzt bufferFlag=0 da puffer nicht dirty sein kann nach schreiben ! -//*************************************************************************************************************** -unsigned char fat_writeSector(unsigned long int sec){ - - fat.bufferDirty=0; // buffer kann nicht dirty sein weil wird geschrieben - return(mmc_write_sector(sec,fat.sector)); // schreiben von sektor puffer +// *************************************************************************************************************** +unsigned char fat_writeSector(unsigned long int sec) +{ + + fat.bufferDirty = 0; // buffer kann nicht dirty sein weil wird geschrieben + return (mmc_write_sector(sec, fat.sector)); // schreiben von sektor puffer } #endif @@ -28,39 +29,44 @@ unsigned char fat_writeSector(unsigned long int sec){ // *************************************************************************************************************** // umrechnung cluster auf 1.sektor des clusters (möglicherweise mehrere sektoren/cluster) ! // *************************************************************************************************************** -unsigned long int fat_clustToSec(unsigned long int clust){ +unsigned long int fat_clustToSec(unsigned long int clust) +{ - return (fat.dataDirSec+2+((clust-2) * fat.secPerClust)); // errechnet den 1. sektor der sektoren des clusters + return (fat.dataDirSec + 2 + ((clust - 2) * fat.secPerClust)); // errechnet den 1. sektor der sektoren des clusters } // *************************************************************************************************************** // umrechnung sektor auf cluster (nicht die position im cluster selber!!) // *************************************************************************************************************** -unsigned long int fat_secToClust(unsigned long int sec){ - - return ((sec-fat.dataDirSec-2+2*fat.secPerClust)/fat.secPerClust); // umkerhrfunktion von fat_clustToSec +unsigned long int fat_secToClust(unsigned long int sec) +{ + + return ((sec - fat.dataDirSec - 2 + 2 * fat.secPerClust) / fat.secPerClust); // umkerhrfunktion von fat_clustToSec } -//*************************************************************************************************************** +// *************************************************************************************************************** // läd sektor:sec auf puffer:sector zum bearbeiten im ram ! // setzt currentSectorNr auf richtigen wert (also den sektor der gepuffert ist). es wird geprüft // ob der gepufferte sektor geändert wurde, wenn ja muss erst geschrieben werden, um diese daten nicht zu verlieren ! -//*************************************************************************************************************** -unsigned char fat_loadSector(unsigned long int sec){ - - if(sec!=fat.currentSectorNr){ // nachladen nötig - #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 - fat.currentSectorNr=sec; // aktualisiert sektor nummer (nummer des gepufferten sektors) - return(0); - } - - else return(0); // alles ok, daten sind schon da (sec==fat.currentSectorNr) +// *************************************************************************************************************** +unsigned char fat_loadSector(unsigned long int sec) +{ - return(1); // fehler + if (sec != fat.currentSectorNr) { // nachladen nötig +#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 + fat.currentSectorNr = sec; // aktualisiert sektor nummer (nummer des gepufferten sektors) + return (0); + } + + else + return (0); // alles ok, daten sind schon da (sec==fat.currentSectorNr) + + return (1); // fehler } @@ -71,118 +77,129 @@ unsigned char fat_loadSector(unsigned long int sec){ // datei lesen funktionen: -// fat_loadSector -> fat_loadRowOfSector -> fat_loadFileDataFromCluster -> fat_loadFileDataFromDir -> fat_loadFileDataFromDir -> fat_cd "daten chain" +// fat_loadSector -> fat_loadRowOfSector -> fat_loadFileDataFromCluster -> fat_loadFileDataFromDir -> fat_loadFileDataFromDir -> fat_cd +// "daten chain" -//*************************************************************************************************************** +// *************************************************************************************************************** // läd die reihe:row des gepufferten sektors auf das struct:file. dort stehen dann // 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 fat_loadRowOfSector(unsigned int row) +{ - 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). + 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 *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. + void *vsector; // void, damit man schoen umbiegen kann :) - file.attrib=fat.sector[row+11]; // datei attribut, byte 11. + for (i = 0; i < 11; i++) + file.name[i] = fat.sector[row + i]; // datei name, ersten 10 bytes vom 32 byte eintrag. - vsector=&fat.sector[row+26]; // low word von fist.cluster - file.firstCluster=*(unsigned short*)vsector; - - vsector=&fat.sector[row+20]; // high word von first.cluster - file.firstCluster|=(*(unsigned short*)vsector)<<16; + file.attrib = fat.sector[row + 11]; // datei attribut, byte 11. - vsector=&fat.sector[row+28]; // 4 byte von file.length - file.length=*(unsigned long int*)vsector; + vsector = &fat.sector[row + 26]; // low word von fist.cluster + file.firstCluster = *(unsigned short *) vsector; - return(0); + 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); } -//*************************************************************************************************************** +// *************************************************************************************************************** // geht reihen weise durch sektoren des clusters mit dem startsektor:sec, und sucht nach der datei mit dem // namen:name. es werden die einzelnen sektoren nachgeladen auf puffer:sector vor dem bearbeiten. // wird die datei in dem cluster gefunden ist return 0 , sonst return1. -//*************************************************************************************************************** -unsigned char fat_loadFileDataFromCluster(unsigned long int sec , char name[]){ - - unsigned char r; - unsigned char s=0; +// *************************************************************************************************************** +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. - 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 - 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 neuer cluster nötig. +void fat_getFreeRowOfDir(unsigned long int dir) +{ - 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 long int start = dir; - //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 + // solange bis ende cluster chain. + while (! + ((dir == 0xfffffff && fat.fatType == 32) + || (dir == 0xffff && fat.fatType == 16))) { + 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.currentSectorNr=fat_clustToSec(dir); // setzen des richtigen sektors, also auf den 1. der neu verketteten + 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 int j=511; - do{ - fat.sector[j]=0x00; //schreibt puffer fat.sector voll mit 0x00==leer - }while(j--); + // 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 - 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>16;// low word von cluster - - vsector=&fat.sector[row+22]; - *(unsigned long int*)vsector=0x01010101; // unnoetige felder beschreiben - - vsector=&fat.sector[row+26]; - *(unsigned short*)vsector=(cluster&0x0000ffff); // high word von cluster - - vsector=&fat.sector[row+28]; - *(unsigned long int*)vsector=length; // laenge + vsector = &fat.sector[row + 12]; + *(unsigned long int *) vsector++ = 0x01010101; // unnoetige felder beschreiben + *(unsigned long int *) vsector = 0x01010101; + + vsector = &fat.sector[row + 20]; + *(unsigned short *) vsector = (cluster & 0xffff0000) >> 16; // low word von cluster + + vsector = &fat.sector[row + 22]; + *(unsigned long int *) vsector = 0x01010101; // unnoetige felder beschreiben + + vsector = &fat.sector[row + 26]; + *(unsigned short *) vsector = (cluster & 0x0000ffff); // high word von cluster + + vsector = &fat.sector[row + 28]; + *(unsigned long int *) vsector = length; // laenge } -//*************************************************************************************************************** +// *************************************************************************************************************** // macht den datei eintrag im jetzigen verzeichniss (fat.dir). // file.row enthält die reihen nummer des leeren eintrags, der vorher gesucht wurde, auf puffer:sector ist der gewünschte // 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! -//*************************************************************************************************************** -void fat_makeFileEntry(char name[],unsigned char attrib,unsigned long int length){ - - unsigned int s; // zähler für root dir sektoren fat16 - - if(fat.dir==0&&fat.fatType==32)fat_getFreeRowOfDir(fat.rootDir); // IM ROOT DIR (fat32) +// *************************************************************************************************************** +void fat_makeFileEntry(char name[], unsigned char attrib, + unsigned long int length) +{ - else if(fat.dir==0 && fat.fatType==16){ // IM ROOT DIR (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_getFreeRowOfCluster(fat.rootDir+s))break; // geht durch sektoren des root dir. - } - } + unsigned int s; // zähler für root dir sektoren fat16 - 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 + if (fat.dir == 0 && fat.fatType == 32) + fat_getFreeRowOfDir(fat.rootDir); // IM ROOT DIR (fat32) + + else if (fat.dir == 0 && fat.fatType == 16) { // IM ROOT DIR (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_getFreeRowOfCluster(fat.rootDir + s)) + break; // geht durch sektoren des root dir. + } + } + + 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 @@ -333,240 +366,260 @@ void fat_makeFileEntry(char name[],unsigned char attrib,unsigned long int length // fat funktionen: -//*************************************************************************************************************** +// *************************************************************************************************************** // sucht nötige folge Cluster aus der fat ! // erster daten cluster = 2, ende einer cluster chain 0xFFFF (fat16) oder 0xFFFFFFF, 0xFFFFFF8 (fat32), // stelle des clusters in der fat, hat als wert, den nächsten cluster. (1:1 gemapt)! -//*************************************************************************************************************** -unsigned long int fat_getNextCluster(unsigned long int oneCluster){ - - // 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 - 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 :) - } - } +// *************************************************************************************************************** +unsigned long int fat_getNextCluster(unsigned long int oneCluster) +{ - // FAT 32**************FAT 32 - else{ - unsigned long int i=oneCluster>>7; // (i=oneCluster/128)errechnet den sektor der fat in dem oneCluster ist (rundet immer ab) - 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 *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 :) - } - } + // 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 - return(0); + if (0 == fat_loadSector(i + fat.fatSec)) { // ob neu laden nötig, wird von fat_loadSector geprüft + 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 :) + } + } + // FAT 32**************FAT 32 + else { + unsigned long int i = oneCluster >> 7; // (i=oneCluster/128)errechnet den sektor der fat in dem oneCluster ist (rundet immer ab) + 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 *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); } -//*************************************************************************************************************** +// *************************************************************************************************************** // 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 -//*************************************************************************************************************** -void fat_getFatChainClustersInRow(unsigned long int offsetCluster){ +// *************************************************************************************************************** +void fat_getFatChainClustersInRow(unsigned long int offsetCluster) +{ - unsigned int i=0; - fat.startSectors=fat_clustToSec(offsetCluster); // setzen des 1. sektors der datei - fat.endSectors=fat.startSectors; - do{ - if( (offsetCluster+1+i)==fat_getNextCluster(offsetCluster+i) ) fat.endSectors+=fat.secPerClust; // zählen der zusammenhängenden sektoren - else { - file.lastCluster=offsetCluster+i; // cluster daneben gehört nicht dazu, somit ist offset+i der letzte bekannte - break; - } - }while(i++>8; // (i=cluster/256)errechnet den sektor der fat in dem cluster ist (rundet immer ab) - 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) - 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 - } - } + // FAT 16**************FAT 16 + if (fat.fatType == 16) { + unsigned long int i = cluster >> 8; // (i=cluster/256)errechnet den sektor der fat in dem cluster ist (rundet immer ab) + unsigned long int j = (cluster << 1) - (i << 9); // (j=(cluster-256*i)*2 == 2*cluster-512*i)errechnet das low byte von + // cluster - // FAT 32**************FAT 32 - else{ - unsigned long int i=cluster>>7; // (i=cluster/128)errechnet den sektor der fat in dem cluster ist (rundet immer ab) - 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) - 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 - } - } + if (0 == fat_loadSector(i + fat.fatSec)) { // neu laden (fat_loadSector prüft ob schon gepuffert) + 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 + } + } + // FAT 32**************FAT 32 + else { + unsigned long int i = cluster >> 7; // (i=cluster/128)errechnet den sektor der fat in dem cluster ist (rundet immer ab) + 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) + 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 + } + } } -//*************************************************************************************************************** +// *************************************************************************************************************** // löscht cluster chain, beginnend ab dem startCluster. // sucht cluster, setzt inhalt usw.. abschließend noch den cluster-chain ende markierten cluster löschen. -//*************************************************************************************************************** -void fat_delClusterChain(unsigned long int startCluster){ +// *************************************************************************************************************** +void fat_delClusterChain(unsigned long int startCluster) +{ - unsigned long int nextCluster=startCluster; // tmp variable, wegen verketteter cluster.. - - do{ - startCluster=nextCluster; - nextCluster=fat_getNextCluster(startCluster); - fat_setCluster(startCluster,0x00000000); - }while(!((nextCluster==0xfffffff&&fat.fatType==32)||(nextCluster==0xffff&&fat.fatType==16))); - fat_writeSector(fat.currentSectorNr); + unsigned long int nextCluster = startCluster; // tmp variable, wegen verketteter cluster.. + + do { + startCluster = nextCluster; + nextCluster = fat_getNextCluster(startCluster); + fat_setCluster(startCluster, 0x00000000); + } while (! + ((nextCluster == 0xfffffff && fat.fatType == 32) + || (nextCluster == 0xffff && fat.fatType == 16))); + fat_writeSector(fat.currentSectorNr); } - + #endif -//*************************************************************************************************************** +// *************************************************************************************************************** // Initialisiert die Fat(16/32) daten, wie: root directory sektor, daten sektor, fat sektor... // siehe auch Fatgen103.pdf. ist NICHT auf performance optimiert! // byte/sector, byte/cluster, anzahl der fats, sector/fat ... (halt alle wichtigen daten zum lesen ders datei systems!) -//*****************************************************************<********************************************** -unsigned char fat_loadFatData(unsigned long int sec){ +// *****************************************************************<********************************************** +unsigned char fat_loadFatData(unsigned long int sec) +{ - // offset,size - unsigned int rootEntCnt; // 17,2 größe die eine fat belegt - unsigned int fatSz16; // 22,2 sectors occupied by one fat16 - unsigned long int fatSz32; // 36,4 sectors occupied by one fat32 + // offset,size + unsigned int rootEntCnt; // 17,2 größe die eine fat belegt + unsigned int fatSz16; // 22,2 sectors occupied by one fat16 + unsigned long int fatSz32; // 36,4 sectors occupied by one fat32 - void *vsector; + void *vsector; - if(0==mmc_read_sector(sec,fat.sector)){ // lesen von fat sector und bestimmen der wichtigen berreiche + 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.bufferDirty = 0; // init wert des flags - vsector=&fat.sector[14]; - fat.fatSec=*(unsigned short*)vsector; + fat.secPerClust = fat.sector[13]; // fat.secPerClust, 13 only (power of 2) - vsector=&fat.sector[17]; - rootEntCnt=*(unsigned short*)vsector; + vsector = &fat.sector[14]; + fat.fatSec = *(unsigned short *) vsector; - vsector=&fat.sector[22]; - fatSz16=*(unsigned short*)vsector; + vsector = &fat.sector[17]; + rootEntCnt = *(unsigned short *) vsector; - fat.rootDir = (((rootEntCnt <<5) + 512) /512)-1; // ist 0 bei fat 32, sonst der root dir sektor + vsector = &fat.sector[22]; + fatSz16 = *(unsigned short *) vsector; - if(fat.rootDir==0){ // FAT32 spezifisch (die prüfung so, ist nicht spezifikation konform !). + fat.rootDir = (((rootEntCnt << 5) + 512) / 512) - 1; // ist 0 bei fat 32, sonst der root dir sektor - vsector=&fat.sector[36]; - fatSz32=*(unsigned long int *)vsector; + if (fat.rootDir == 0) { // FAT32 spezifisch (die prüfung so, ist nicht spezifikation konform !). - vsector=&fat.sector[44]; - fat.rootDir=*(unsigned long int *)vsector; + vsector = &fat.sector[36]; + fatSz32 = *(unsigned long int *) vsector; - fat.dataDirSec = fat.fatSec + (fatSz32 * fat.sector[16]); // data sector (beginnt mit cluster 2) - fat.fatType=32; // fat typ - } + vsector = &fat.sector[44]; + fat.rootDir = *(unsigned long int *) vsector; - else{ // FAT16 spezifisch - fat.dataDirSec = fat.fatSec + (fatSz16 * fat.sector[16]) + fat.rootDir; // data sektor (beginnt mit cluster 2) - fat.rootDir=fat.dataDirSec-fat.rootDir; // root dir sektor, da nicht im datenbereich (cluster) - fat.rootDir+=sec; // addiert den startsektor auf " - fat.fatType=16; // fat typ - } + fat.dataDirSec = fat.fatSec + (fatSz32 * fat.sector[16]); // data sector (beginnt mit cluster 2) + fat.fatType = 32; // fat typ + } - fat.fatSec+=sec; // addiert den startsektor auf - fat.dataDirSec+=sec; // addiert den startsektor auf (umrechnung von absolut auf real) - fat.dataDirSec-=2; // zeigt auf 1. cluster - fat.dir=0; // dir auf '0'==root dir, sonst 1.Cluster des dir - return (0); - } + else { // FAT16 spezifisch + fat.dataDirSec = fat.fatSec + (fatSz16 * fat.sector[16]) + fat.rootDir; // data sektor (beginnt mit cluster 2) + fat.rootDir = fat.dataDirSec - fat.rootDir; // root dir sektor, da nicht im datenbereich (cluster) + fat.rootDir += sec; // addiert den startsektor auf " + fat.fatType = 16; // fat typ + } + + fat.fatSec += sec; // addiert den startsektor auf + fat.dataDirSec += sec; // addiert den startsektor auf (umrechnung von absolut auf real) + fat.dataDirSec -= 2; // zeigt auf 1. cluster + fat.dir = 0; // dir auf '0'==root dir, sonst 1.Cluster des dir + return (0); + } - return (1); // sector nicht gelesen, fat nicht initialisiert!! + return (1); // sector nicht gelesen, fat nicht initialisiert!! } -//************************************************************************************************<<*************** -// int fat sucht den 1. cluster des dateisystems (fat16/32) auch VBR genannt, -//************************************************************************************************<<*************** -unsigned char fat_initfat(void){ - - unsigned long int secOfFirstPartition=0; // ist 1. sektor der 1. partition aus dem MBR - - if(0==mmc_read_sector(0,fat.sector)){ +// ************************************************************************************************<<*************** +// int fat sucht den 1. cluster des dateisystems (fat16/32) auch VBR genannt, +// ************************************************************************************************<<*************** +unsigned char fat_initfat(void) +{ - void *vsector=&fat.sector[454]; //startsektor bestimmen - secOfFirstPartition=*(unsigned long int*)vsector; + unsigned long int secOfFirstPartition = 0; // ist 1. sektor der 1. partition aus dem MBR - //prüfung ob man schon im VBR gelesen hat (0x6964654d = "Medi") - if(secOfFirstPartition==0x6964654d) return fat_loadFatData(0); //ist superfloppy + if (0 == mmc_read_sector(0, fat.sector)) { - else {return fat_loadFatData(secOfFirstPartition);} // ist partitioniert... - } + void *vsector = &fat.sector[454]; // startsektor bestimmen + secOfFirstPartition = *(unsigned long int *) vsector; - return (1); + // 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 partitioniert... + } + + return (1); } @@ -574,35 +627,39 @@ unsigned char fat_initfat(void){ // ***************************************************************************************************************** // 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 +// wandelt z.b. "t.txt" -> "T TXT" oder "main.c" in "MAIN C " => also immer 8.3 und upper case letter // VORSICHT es werden keine Prüfungen gemacht ! // ***************************************************************************************************************** -char * fat_str(char *str){ +char *fat_str(char *str) +{ - unsigned char i; - unsigned char j=0; - unsigned char c; - char tmp[12]; // tmp string zum einfacheren umwandeln - - strcpy(tmp,str); + unsigned char i; + unsigned char j = 0; + unsigned char c; + char tmp[12]; // tmp string zum einfacheren umwandeln - for(i=0;i<11;i++)str[i]=' '; // als vorbereitung alles mit leerzeichen füllen - str[11]='\0'; + strcpy(tmp, str); - i=0; + for (i = 0; i < 11; i++) + str[i] = ' '; // als vorbereitung alles mit leerzeichen füllen + str[11] = '\0'; - do{ - c=toupper(tmp[j]); - if(c=='\0')return str; - if(c!='.')str[i]=c; - else i=7; - i++; - j++; - }while(i<12); + i = 0; + + do { + c = toupper(tmp[j]); + if (c == '\0') + return str; + if (c != '.') + str[i] = c; + else + i = 7; + i++; + j++; + } while (i < 12); + + return str; - return str; - } #endif - diff --git a/avr/usbload/fat.h b/avr/usbload/fat.h index d05aa3b..9767227 100644 --- a/avr/usbload/fat.h +++ b/avr/usbload/fat.h @@ -1,76 +1,77 @@ #ifndef _FAT_H - #define _FAT_H +#define _FAT_H // ************************************************************************************************************************** // WICHTIGE SCHLATER: -> hier kann die code größe angepasst werden, zu lasten der funktionalität ! - #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" +#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_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 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 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 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_setClusterChain(unsigned long int newOffsetCluster,unsigned int length); - extern char *fat_str(char *str); // wandelt einen string so, dass er der fat konvention entspricht ! - +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 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 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 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_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.) - unsigned char sector[512]; // der puffer für sektoren ! - unsigned char bufferDirty; // puffer wurde beschrieben, sector muss geschrieben werden bevor er neu geladen wird - unsigned long int currentSectorNr;// aktuell geladener Sektor (in sector) //beschleunigt wenn z.b 2* 512 byte puffer vorhanden, oder bei fat operationen im gleichen sektor - unsigned long int dir; // Direktory zeiger rootDir=='0' sonst(1.Cluster des dir; start auf root) - unsigned long int rootDir; // Sektor(f16)/Cluster(f32) nr root directory - unsigned long int dataDirSec; // Sektor nr data area - unsigned long int fatSec; // Sektor nr fat area - unsigned long int startSectors; // der erste sektor in einer reihe (freie oder verkettete) - unsigned long int endSectors; - unsigned char secPerClust; // anzahl der sektoren pro cluster - unsigned char fatType; // fat16 oder fat32 (16 oder 32) - }fat; +extern struct Fat { // fat daten (1.cluster, root-dir, dir usw.) + unsigned char sector[512]; // der puffer für sektoren ! + unsigned char bufferDirty; // puffer wurde beschrieben, sector muss geschrieben werden bevor er neu geladen wird + unsigned long int currentSectorNr; // aktuell geladener Sektor (in sector) //beschleunigt wenn z.b 2* 512 byte puffer vorhanden, oder + // bei fat operationen im gleichen sektor + unsigned long int dir; // Direktory zeiger rootDir=='0' sonst(1.Cluster des dir; start auf root) + unsigned long int rootDir; // Sektor(f16)/Cluster(f32) nr root directory + unsigned long int dataDirSec; // Sektor nr data area + unsigned long int fatSec; // Sektor nr fat area + unsigned long int startSectors; // der erste sektor in einer reihe (freie oder verkettete) + 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 - 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 - unsigned char row; // reihe im sektor in der die datei infos stehen (reihe 0-15) - unsigned long int firstCluster; // 20,2 /26,2 datei 1.cluster hi,low(möglicherweise der einzige) (4-byte) - unsigned long int length; // 28,4 datei Länge (4-byte) - unsigned long int lastCluster; // -nicht direkt aus dem dateisystem- letzter cluster der ersten kette - unsigned long int seek; // schreib position in der datei - }file; +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 + unsigned char row; // reihe im sektor in der die datei infos stehen (reihe 0-15) + unsigned long int firstCluster; // 20,2 /26,2 datei 1.cluster hi,low(möglicherweise der einzige) (4-byte) + unsigned long int length; // 28,4 datei Länge (4-byte) + unsigned long int lastCluster; // -nicht direkt aus dem dateisystem- letzter cluster der ersten kette + unsigned long int seek; // schreib position in der datei +} file; #endif - - - - - - diff --git a/avr/usbload/file.c b/avr/usbload/file.c index 4f56c04..376cbd7 100644 --- a/avr/usbload/file.c +++ b/avr/usbload/file.c @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -8,7 +8,7 @@ -//******************************************************************************************************************************* +// ******************************************************************************************************************************* // 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 @@ -16,55 +16,58 @@ // -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 ffopen(char name[]) +{ - unsigned char file_flag=fat_loadFileDataFromDir(name); //prüfung ob datei vorhanden und evetuelles laden des file struct + 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_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=fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei - return 1; - } - - #if (WRITE==1) // anlegen ist schreiben ! - else{ /** Datei existiert nicht, also anlegen ! (nur wenn schreiben option an ist)**/ - 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;//fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei - file.attrib=32; // --- file.row wird in der funktion fat_getFreeRowOfDir geschrieben !! - 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; - } - #endif + if (file_flag == 0) { /** Datei existiert, anlegen nicht nötig! **/ + 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 = fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei + return 1; + } +#if (WRITE==1) // anlegen ist schreiben ! + else { /** Datei existiert nicht, also anlegen ! (nur wenn schreiben option an ist)**/ + 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; // fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei + file.attrib = 32; // --- file.row wird in der funktion fat_getFreeRowOfDir geschrieben !! + 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; + } +#endif } -//******************************************************************************************************************************* +// ******************************************************************************************************************************* // 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){ +// ******************************************************************************************************************************* +unsigned char ffclose(void) +{ - #if (WRITE==1) /** 2 möglichkeiten beim schließen !! (lesend spielt keine rolle, nichts muss geupdatet werden) **/ +#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 **/ + 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 **/ + 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); +#endif + + file.cntOfBytes = 0; // init werte der nötigen zähler + file.seek = 0; + return (0); } // ******************************************************************************************************************************* @@ -72,22 +75,24 @@ unsigned char ffclose(void){ // 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){ +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_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 + 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_writeSector(fat.currentSectorNr); + 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); } @@ -96,28 +101,30 @@ void fileUpdate(void){ // 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){ - - #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 +void ffseek(unsigned long int offset) +{ - 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 +#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 - 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 ! - } - } - file.lastCluster=fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei - fat_loadSector(sec); // sektor mit offset byte laden - file.cntOfBytes = offset; // setzen des lese zählers + 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 ! + } + } + file.lastCluster = fat_secToClust(fat.endSectors); // letzter bekannter cluster der datei + fat_loadSector(sec); // sektor mit offset byte laden + file.cntOfBytes = offset; // setzen des lese zählers } @@ -129,8 +136,9 @@ void ffseek(unsigned long int offset){ // wechselt verzeichniss. start immer im root Dir. // MUSS in das direktory gewechselt werden, in dem die datei zum lesen/schreiben ist ! // ******************************************************************************************************************************* -unsigned char ffcd(char name[]){ - return(fat_cd(name)); +unsigned char ffcd(char name[]) +{ + return (fat_cd(name)); } @@ -140,19 +148,21 @@ unsigned char ffcd(char name[]){ // eintrag in der reihe ist (nicht gelöscht, nicht frei usw). die sektoren des clusters werden nachgeladen. // die dateien werden mit namen und datei größe angezeigt. // ******************************************************************************************************************************* -void lsRowsOfClust (unsigned long int start_sec){ +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("Name:%s Size:%li\n",file.name,file.length ); - } - } - }while(++sec=0){ // gibt es einen eintrag davor ? - if(fat.sector[(file.row<<5)-21]==0x0f)fat.sector[(file.row<<5)-32]=0xE5; // langer datei eintag auch gelöscht. - } - fat.bufferDirty=1; // eintrag in puffer gemacht. - if(0==fat_getNextCluster(file.firstCluster)) return(0); // 1.cluster ist leer ?!? - fat_delClusterChain(file.firstCluster); // löscht die zu der datei gehörige cluster-chain aus der fat. - return(0); - } - - //TODO noch nicht optimal. zu viele schreib vorgänge beim löschen von datei einträgen. max bis zu 16/sektor ! - 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 char cntSecOfClust=0; - unsigned char i=0; + 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 ? + if (fat.sector[(file.row << 5) - 21] == 0x0f) + fat.sector[(file.row << 5) - 32] = 0xE5; // langer datei eintag auch gelöscht. + } + fat.bufferDirty = 1; // eintrag in puffer gemacht. + if (0 == fat_getNextCluster(file.firstCluster)) + return (0); // 1.cluster ist leer ?!? + fat_delClusterChain(file.firstCluster); // löscht die zu der datei gehörige cluster-chain aus der fat. + return (0); + } + // TODO noch nicht optimal. zu viele schreib vorgänge beim löschen von datei einträgen. max bis zu 16/sektor ! + 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 char cntSecOfClust = 0; + unsigned char i = 0; - fat.sector[file.row<<5]=0xE5; // löscht dir eintrag - if((file.row-1)>=0){ // gibt es einen eintrag davor (langer datei eintrag)? - if(fat.sector[(file.row<<5)-21]==0x0f)fat.sector[(file.row<<5)-32]=0xE5; // langer datei eintag auch gelöscht - } - fat.bufferDirty=1; // puffer eintrag gemacht + fat.sector[file.row << 5] = 0xE5; // löscht dir eintrag + if ((file.row - 1) >= 0) { // gibt es einen eintrag davor (langer datei eintrag)? + if (fat.sector[(file.row << 5) - 21] == 0x0f) + fat.sector[(file.row << 5) - 32] = 0xE5; // langer datei eintag auch gelöscht + } + fat.bufferDirty = 1; // puffer eintrag gemacht - parent=fat.dir; // der ordner in dem der zu löschende ordner ist. - own=file.firstCluster; // der 1. cluster des ordners der zu löschen ist. - clustsOfDir=file.firstCluster; // die "cluster" des zu löschenden ordners + parent = fat.dir; // der ordner in dem der zu löschende ordner ist. + own = file.firstCluster; // der 1. cluster des ordners der zu löschen ist. + clustsOfDir = file.firstCluster; // die "cluster" des zu löschenden ordners - do{ // geht durch cluster des dirs - fat_loadSector(fat_clustToSec(clustsOfDir)); // sektor des dirs laden - do{ // geht durch sektoren des clusters - do{ // geht durch reihen des sektors - fat_loadRowOfSector(i); + do { // geht durch cluster des dirs + fat_loadSector(fat_clustToSec(clustsOfDir)); // sektor des dirs laden + do { // geht durch sektoren des clusters + do { // geht durch reihen des sektors + fat_loadRowOfSector(i); - if(file.attrib!=0x10 && file.attrib!=0x00 && file.name[0]!=0xE5){ // ist kein ordner,noch nicht gelöscht, kein freier eintrag - fat.sector[i<<5]=0xE5; // erster eintrag der reihe als gelöscht markiert - fat.bufferDirty=1; // puffer eintrag gemacht - if(file.attrib==0x20){ // ist datei! - fat_delClusterChain(file.firstCluster); // ist datei, dann cluster-chain der datei löschen - fat_loadSector(fat_clustToSec(clustsOfDir)+cntSecOfClust); // sektor neu laden, weil löschen der chain, den puffer nutzt. - } - } + if (file.attrib != 0x10 && file.attrib != 0x00 && file.name[0] != 0xE5) { // ist kein ordner,noch nicht + // gelöscht, kein freier eintrag + fat.sector[i << 5] = 0xE5; // erster eintrag der reihe als gelöscht markiert + fat.bufferDirty = 1; // puffer eintrag gemacht + if (file.attrib == 0x20) { // ist datei! + fat_delClusterChain(file.firstCluster); // ist datei, dann cluster-chain der datei löschen + fat_loadSector(fat_clustToSec(clustsOfDir) + cntSecOfClust); // sektor neu laden, weil löschen der + // chain, den puffer nutzt. + } + } - if(file.attrib==0x10 && file.name[0]=='.'){ // "." oder ".." eintrag erkannt, löschen ! - fat.sector[i<<5]=0xE5; // eintrag als gelöscht markiert - fat.bufferDirty=1; // puffer eintrag gemacht - } + if (file.attrib == 0x10 && file.name[0] == '.') { // "." oder ".." eintrag erkannt, löschen ! + fat.sector[i << 5] = 0xE5; // eintrag als gelöscht markiert + fat.bufferDirty = 1; // puffer eintrag gemacht + } - 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 - clustsOfDir=file.firstCluster; // eigenes dir ist file.firstCluster - own=file.firstCluster; // eigener start cluster/dir - fat_loadRowOfSector(1); // ".." laden um parent zu bestimmen - parent=file.firstCluster; // parent sichern. - cntSecOfClust=0; // init von gelesenen sektoren und reihen ! - i=0; - continue; - } + 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 + clustsOfDir = file.firstCluster; // eigenes dir ist file.firstCluster + own = file.firstCluster; // eigener start cluster/dir + fat_loadRowOfSector(1); // ".." laden um parent zu bestimmen + parent = file.firstCluster; // parent sichern. + cntSecOfClust = 0; // init von gelesenen sektoren und reihen ! + i = 0; + continue; + } - if(file.name[0]==0x00){ // ende des dirs erreicht, wenn nicht voll !! - if(parent==fat.dir){ // erfolgreich alles gelöscht - fat_delClusterChain(own); // cluster chain des ordners löschen - return(0); - } - fat_delClusterChain(own); // cluster chain des ordners löschen - clustsOfDir=parent; // parent ist jetzt wieder arbeisverzeichniss. - own=parent; // arbeitsverzeichniss setzten - fat_loadSector(fat_clustToSec(own)); // sektor des dirs laden - fat_loadRowOfSector(1); // ".." laden um parent zu bestimmen - parent=file.firstCluster; // parent sichern. - cntSecOfClust=0; // init von gelesenen sektoren und reihen ! - i=0; - continue; - } + if (file.name[0] == 0x00) { // ende des dirs erreicht, wenn nicht voll !! + if (parent == fat.dir) { // erfolgreich alles gelöscht + fat_delClusterChain(own); // cluster chain des ordners löschen + return (0); + } + fat_delClusterChain(own); // cluster chain des ordners löschen + clustsOfDir = parent; // parent ist jetzt wieder arbeisverzeichniss. + own = parent; // arbeitsverzeichniss setzten + fat_loadSector(fat_clustToSec(own)); // sektor des dirs laden + fat_loadRowOfSector(1); // ".." laden um parent zu bestimmen + parent = file.firstCluster; // parent sichern. + cntSecOfClust = 0; // init von gelesenen sektoren und reihen ! + i = 0; + continue; + } - i++; - }while(i<16); // geht durch reihen des sektors. - - i=0; // neuer sektor -> reihen von vorne. - cntSecOfClust++; - fat_loadSector(fat_clustToSec(clustsOfDir)+cntSecOfClust); // läd sektoren des clusters nach - }while(cntSecOfClust sektoren von vorne. - clustsOfDir=fat_getNextCluster(clustsOfDir); // sucht neuen cluster der cluster-chain. - }while( !((clustsOfDir==0xfffffff && fat.fatType==32) || (clustsOfDir==0xffff && fat.fatType==16)) ); // geht durch cluster des dirs. - fat_delClusterChain(own); // hier landet man, wenn der ordner voll war (auf cluster "ebene")!! - #endif - } - - } - + i++; + } while (i < 16); // geht durch reihen des sektors. - return(1); // fehler, nicht gefunden? + i = 0; // neuer sektor -> reihen von vorne. + cntSecOfClust++; + fat_loadSector(fat_clustToSec(clustsOfDir) + cntSecOfClust); // läd sektoren des clusters nach + } while (cntSecOfClust < fat.secPerClust); // geht durch sektoren des clusters. + + cntSecOfClust = 0; // neuer cluster -> sektoren von vorne. + clustsOfDir = fat_getNextCluster(clustsOfDir); // sucht neuen cluster der cluster-chain. + } while (!((clustsOfDir == 0xfffffff && fat.fatType == 32) || (clustsOfDir == 0xffff && fat.fatType == 16))); // geht + // durch + // cluster + // des + // dirs. + fat_delClusterChain(own); // hier landet man, wenn der ordner voll war (auf cluster "ebene")!! +#endif + } + + } + + + return (1); // fehler, nicht gefunden? } #endif -//******************************************************************************************************************************* +// ******************************************************************************************************************************* // liest 512 bytes aus dem puffer fat.sector. dann werden neue 512 bytes der datei geladen, sind nicht genügend verkettete // sektoren in einer reihe bekannt, wird in der fat nachgeschaut. dann werden weiter bekannte nachgeladen... -//******************************************************************************************************************************* -inline unsigned char ffread(void){ +// ******************************************************************************************************************************* +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.) 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)**/ - } - - return fat.sector[file.cntOfBytes++]; // rückgabe, byte des sektors (NACH rückgabe erhöhen von zähler ! ) + 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.) 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)**/ + } + + return fat.sector[file.cntOfBytes++]; // rückgabe, byte des sektors (NACH rückgabe erhöhen von zähler ! ) } #if (WRITE==1) -#if (OVER_WRITE==0) // nicht überschreibende write funktion +#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(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. +// ******************************************************************************************************************************* +inline void ffwrite(unsigned char c) +{ - 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) **/ - 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. - } + 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) **/ + 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. + } } #endif -#if (OVER_WRITE==1) // überschreibende write funktion, nicht performant, weil immer auch noch ein sektor geladen werden muss +#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. +// 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) +{ - 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_secToClust(fat.endSectors) ); // verketten der beschriebenen. - fat_getFreeClustersInRow( file.lastCluster ); // neue leere sektoren benötigt, also suchen. - } - 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... - } + 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_secToClust(fat.endSectors)); // verketten der beschriebenen. + fat_getFreeClustersInRow(file.lastCluster); // neue leere sektoren benötigt, also suchen. + } 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 @@ -448,16 +481,10 @@ inline void ffwrite(unsigned char c){ // ******************************************************************************************************************************* // schreibt string auf karte, siehe ffwrite() // ******************************************************************************************************************************* -inline void ffwrites(const char *s ){ - while (*s) ffwrite(*s++); - } +inline void ffwrites(const char *s) +{ + while (*s) + ffwrite(*s++); +} #endif - - - - - - - - diff --git a/avr/usbload/file.h b/avr/usbload/file.h index c8388f2..3cd682e 100644 --- a/avr/usbload/file.h +++ b/avr/usbload/file.h @@ -3,33 +3,30 @@ #ifndef _FILE_H - #define _FILE_H - +#define _FILE_H + // ************************************************************************************************************************** // funktionen - extern inline unsigned char ffread(void); // liest byte-weise aus der datei (puffert immer 512 bytes zwischen) - extern inline void ffwrite(unsigned char c); // schreibt ein byte in die geöffnete datei - extern inline void ffwrites(const char *s ); // schreibt string auf karte +extern inline unsigned char ffread(void); // liest byte-weise aus der datei (puffert immer 512 bytes zwischen) +extern inline void ffwrite(unsigned char c); // schreibt ein byte in die geöffnete datei +extern inline void ffwrites(const char *s); // schreibt string auf karte + +extern unsigned char ffopen(char name[]); // kann immer nur 1 datei bearbeiten. +extern unsigned char ffclose(void); // muss aufgerufen werden bevor neue datei bearbeitet wird. + +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 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 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 + + // **************************************************************************************************************************// + // ####################################################################################################################### + - extern unsigned char ffopen(char name[]); // kann immer nur 1 datei bearbeiten. - extern unsigned char ffclose(void); // muss aufgerufen werden bevor neue datei bearbeitet wird. - 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 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 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 - - // **************************************************************************************************************************// ####################################################################################################################### - - - #endif - - - - diff --git a/avr/usbload/mmc.c b/avr/usbload/mmc.c index f10e614..c943bbf 100644 --- a/avr/usbload/mmc.c +++ b/avr/usbload/mmc.c @@ -1,32 +1,29 @@ -/*####################################################################################### -Connect AVR to MMC/SD - -Copyright (C) 2004 Ulrich Radig - -Bei Fragen und Verbesserungen wendet euch per EMail an - -mail@ulrichradig.de - -oder im Forum meiner Web Page : www.ulrichradig.de - -Dieses Programm ist freie Software. Sie können es unter den Bedingungen der -GNU General Public License, wie von der Free Software Foundation veröffentlicht, -weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder -(nach Ihrer Option) jeder späteren Version. - -Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, -daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, -sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT -FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. - -Sie sollten eine Kopie der GNU General Public License zusammen mit diesem -Programm erhalten haben. -Falls nicht, schreiben Sie an die Free Software Foundation, -Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -#######################################################################################*/ +/* + * ####################################################################################### Connect AVR to MMC/SD + * + * Copyright (C) 2004 Ulrich Radig + * + * Bei Fragen und Verbesserungen wendet euch per EMail an + * + * mail@ulrichradig.de + * + * oder im Forum meiner Web Page : www.ulrichradig.de + * + * Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software + * Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder + * späteren Version. + * + * Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, + * sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU + * General Public License. + * + * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * ####################################################################################### + */ #include -#include +#include #include "mmc.h" @@ -46,7 +43,7 @@ uint8_t mmc_init() _delay_us(10); MMC_WRITE &= ~(1 << MMC_CS); _delay_us(3); - + uint8_t CMD[] = { 0x40, 0x00, 0x00, 0x00, 0x00, 0x95 }; while (mmc_write_command(CMD) != 1) { if (Timeout++ > 20) { @@ -54,7 +51,7 @@ uint8_t mmc_init() return (1); } } - + Timeout = 0; CMD[0] = 0x41; CMD[5] = 0xFF; @@ -71,11 +68,11 @@ uint8_t mmc_write_command(uint8_t * cmd) uint8_t tmp = 0xff; uint16_t Timeout = 0; uint8_t a; - + for (a = 0; a < 0x06; a++) { mmc_write_byte(*cmd++); } - + while (tmp == 0xff) { tmp = mmc_read_byte(); if (Timeout++ > 50) { @@ -84,8 +81,8 @@ uint8_t mmc_write_command(uint8_t * cmd) } return (tmp); } - - + + uint8_t mmc_read_byte(void) { uint8_t Byte = 0, j; @@ -96,7 +93,7 @@ uint8_t mmc_read_byte(void) if (PINB & (1 << MMC_DI)) { Byte |= 1; } - + else { Byte &= ~1; } @@ -105,8 +102,8 @@ uint8_t mmc_read_byte(void) } return (Byte); } - - + + void mmc_write_byte(uint8_t Byte) { uint8_t i; @@ -114,7 +111,7 @@ void mmc_write_byte(uint8_t Byte) if (Byte & 0x80) { MMC_WRITE |= (1 << MMC_DO); } - + else { MMC_WRITE &= ~(1 << MMC_DO); } @@ -130,72 +127,72 @@ void mmc_write_byte(uint8_t Byte) uint8_t mmc_write_sector(uint32_t addr, uint8_t * Buffer) { uint8_t tmp; - - + + uint8_t cmd[] = { 0x58, 0x00, 0x00, 0x00, 0x00, 0xFF }; uint8_t a; uint16_t i; - + addr = addr << 9; cmd[1] = ((addr & 0xFF000000) >> 24); cmd[2] = ((addr & 0x00FF0000) >> 16); cmd[3] = ((addr & 0x0000FF00) >> 8); - - + + tmp = mmc_write_command(cmd); if (tmp != 0) { return (tmp); } - + for (a = 0; a < 100; a++) { mmc_read_byte(); } - + mmc_write_byte(0xFE); - + for (a = 0; i < 512; i++) { mmc_write_byte(*Buffer++); } - + mmc_write_byte(0xFF); mmc_write_byte(0xFF); - + if ((mmc_read_byte() & 0x1F) != 0x05) return (1); - + while (mmc_read_byte() != 0xff) { }; return (0); } - - + + void mmc_read_block(uint8_t * cmd, uint8_t * Buffer, uint16_t Bytes) { uint16_t a; - + if (mmc_write_command(cmd) != 0) { return; } - + while (mmc_read_byte() != 0xfe) { }; - - + + for (a = 0; a < Bytes; a++) { *Buffer++ = mmc_read_byte(); } - + mmc_read_byte(); mmc_read_byte(); return; } - + uint8_t mmc_read_sector(uint32_t addr, uint8_t * Buffer) { - - + + uint8_t cmd[] = { 0x51, 0x00, 0x00, 0x00, 0x00, 0xFF }; - + addr = addr << 9; cmd[1] = ((addr & 0xFF000000) >> 24); cmd[2] = ((addr & 0x00FF0000) >> 16); @@ -203,22 +200,21 @@ uint8_t mmc_read_sector(uint32_t addr, uint8_t * Buffer) mmc_read_block(cmd, Buffer, 512); return (0); } - - + + uint8_t mmc_read_cid(uint8_t * Buffer) { - + uint8_t cmd[] = { 0x4A, 0x00, 0x00, 0x00, 0x00, 0xFF }; mmc_read_block(cmd, Buffer, 16); return (0); } - - + + uint8_t mmc_read_csd(uint8_t * Buffer) { - + uint8_t cmd[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0xFF }; mmc_read_block(cmd, Buffer, 16); return (0); } - diff --git a/avr/usbload/mmc.h b/avr/usbload/mmc.h index c4ef8df..8417033 100644 --- a/avr/usbload/mmc.h +++ b/avr/usbload/mmc.h @@ -1,44 +1,44 @@ -/*####################################################################################### -Connect ARM to MMC/SD - -Copyright (C) 2004 Ulrich Radig -#######################################################################################*/ +/* + * ####################################################################################### Connect ARM to MMC/SD + * + * Copyright (C) 2004 Ulrich Radig ####################################################################################### + */ #ifndef _MMC_H - #define _MMC_H +#define _MMC_H -#define SPI_Mode 0 //1 = Hardware SPI | 0 = Software SPI +#define SPI_Mode 0 // 1 = Hardware SPI | 0 = Software SPI #define MMC_WRITE PORTB #define MMC_READ PINB #define MMC_REG DDRB - + #define MMC_CS PB4 #define MMC_DO PB6 #define MMC_DI PB5 #define MMC_CLK PB7 -#define MMC_WRITE PORTB //Port an der die MMC/SD-Karte angeschlossen ist also des SPI +#define MMC_WRITE PORTB // Port an der die MMC/SD-Karte angeschlossen ist also des SPI #define MMC_READ PINB -#define MMC_REG DDRB +#define MMC_REG DDRB - 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); - extern unsigned char mmc_init(void); - 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 *); - - #define mmc_disable() MMC_WRITE|= (1< + currentDocument + poc/avr_usbload/sram.c documents @@ -19,7 +21,125 @@ 271 metaData + avr/bootloader/bootloader.c + + caret + + column + 11 + line + 231 + + columnSelection + + firstVisibleColumn + 0 + firstVisibleLine + 189 + selectFrom + + column + 8 + line + 231 + + selectTo + + column + 14 + line + 231 + + + avr/bootloader/config.h + + caret + + column + 0 + line + 22 + + firstVisibleColumn + 0 + firstVisibleLine + 0 + + avr/usbload/fat.c + + caret + + column + 0 + line + 207 + + firstVisibleColumn + 0 + firstVisibleLine + 613 + avr/usbload/fat.h + + caret + + column + 28 + line + 21 + + columnSelection + + firstVisibleColumn + 0 + firstVisibleLine + 0 + selectFrom + + column + 23 + line + 21 + + selectTo + + column + 34 + line + 21 + + + avr/usbload/file.c + + caret + + column + 45 + line + 135 + + columnSelection + + firstVisibleColumn + 0 + firstVisibleLine + 109 + selectFrom + + column + 41 + line + 135 + + selectTo + + column + 45 + line + 135 + + + avr/usbload/file.h caret @@ -33,6 +153,208 @@ firstVisibleLine 0 + avr/usbload/main.c + + caret + + column + 0 + line + 25 + + columnSelection + + firstVisibleColumn + 0 + firstVisibleLine + 293 + selectFrom + + column + 0 + line + 24 + + selectTo + + column + 0 + line + 25 + + + avr/usbload/mmc.c + + caret + + column + 0 + line + 224 + + firstVisibleColumn + 0 + firstVisibleLine + 173 + + avr/usbload/mmc.h + + caret + + column + 0 + line + 39 + + firstVisibleColumn + 0 + firstVisibleLine + 0 + + avr/usbload/shared_memory.h + + caret + + column + 0 + line + 0 + + firstVisibleColumn + 0 + firstVisibleLine + 0 + + avr/usbload/testing.c + + caret + + column + 17 + line + 130 + + firstVisibleColumn + 0 + firstVisibleLine + 31 + + avr/usbload/testing.h + + caret + + column + 0 + line + 0 + + firstVisibleColumn + 0 + firstVisibleLine + 0 + + poc/avr_sdcard/fat.c + + caret + + column + 0 + line + 38 + + firstVisibleColumn + 0 + firstVisibleLine + 0 + + poc/avr_sdcard/fat.h + + caret + + column + 4 + line + 63 + + columnSelection + + firstVisibleColumn + 0 + firstVisibleLine + 23 + selectFrom + + column + 1 + line + 63 + + selectTo + + column + 9 + line + 63 + + + poc/avr_sdcard/main.c + + caret + + column + 12 + line + 170 + + columnSelection + + firstVisibleColumn + 0 + firstVisibleLine + 137 + selectFrom + + column + 1 + line + 170 + + selectTo + + column + 20 + line + 170 + + + poc/avr_sdcard/main.lst + + caret + + column + 0 + line + 0 + + firstVisibleColumn + 0 + firstVisibleLine + 0 + + poc/avr_usbload/sram.c + + caret + + column + 0 + line + 22 + + firstVisibleColumn + 0 + firstVisibleLine + 0 + snes/banktest/LoadGraphics.asm caret @@ -62,6 +384,26 @@ 211 + openDocuments + + avr/usbload/mmc.c + avr/usbload/testing.h + avr/usbload/testing.c + poc/avr_sdcard/fat.c + poc/avr_sdcard/fat.h + poc/avr_sdcard/main.lst + avr/bootloader/config.h + avr/bootloader/bootloader.c + poc/avr_sdcard/main.c + poc/avr_usbload/sram.c + avr/usbload/file.c + avr/usbload/file.h + avr/usbload/mmc.h + avr/usbload/shared_memory.h + avr/usbload/fat.c + avr/usbload/fat.h + avr/usbload/main.c + showFileHierarchyDrawer showFileHierarchyPanel @@ -80,7 +422,7 @@ subItems - usbload + bootloader isExpanded