o add avr sdcard poc

This commit is contained in:
optixx
2009-03-05 22:25:54 +01:00
parent 770c49a5f5
commit 9a40d078dd
12 changed files with 1950 additions and 0 deletions

316
poc/avr_sdcard/fat.c Normal file
View File

@@ -0,0 +1,316 @@
/*#######################################################################################
FAT for AVR (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<65>ffentlicht,
weitergeben und/oder modifizieren, entweder gem<65><6D> Version 2 der Lizenz oder
(nach Ihrer Option) jeder sp<73>teren Version.
Die Ver<65>ffentlichung dieses Programms erfolgt in der Hoffnung,
da<EFBFBD> es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE,
sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT
F<EFBFBD>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 "fat.h"
unsigned char cluster_size;
unsigned int fat_offset;
unsigned int cluster_offset;
unsigned int volume_boot_record_addr;
//############################################################################
//Auslesen Cluster Size der MMC/SD Karte und Speichern der gr<67><72>e ins EEprom
//Auslesen Cluster Offset der MMC/SD Karte und Speichern der gr<67><72>e ins EEprom
void fat_init (uint8_t *Buffer)
//############################################################################
{
struct BootSec *bootp; //Zeiger auf Bootsektor Struktur
// unsigned char Buffer[BlockSize];
//volume_boot_record_addr = fat_addr (Buffer);
mmc_read_sector (MASTER_BOOT_RECORD,Buffer); //Read Master Boot Record
if (Buffer[510] == 0x55 && Buffer[511] == 0xAA)
{
FAT_DEBUG("MBR Signatur found!\r\n");
}
else
{
FAT_DEBUG("MBR Signatur not found!\r\n");
while(1);
}
volume_boot_record_addr = Buffer[VBR_ADDR] + (Buffer[VBR_ADDR+1] << 8);
mmc_read_sector (volume_boot_record_addr,Buffer);
if (Buffer[510] == 0x55 && Buffer[511] == 0xAA)
{
FAT_DEBUG("VBR Signatur found!\r\n");
}
else
{
FAT_DEBUG("VBR Signatur not found!\r\n");
volume_boot_record_addr = MASTER_BOOT_RECORD;//<- added by Hennie
mmc_read_sector (MASTER_BOOT_RECORD,Buffer); //Read Master Boot Record
}
bootp=(struct BootSec *)Buffer;
cluster_size = bootp->BPB_SecPerClus;
fat_offset = bootp->BPB_RsvdSecCnt;
cluster_offset = ((bootp->BPB_BytesPerSec * 32)/BlockSize);
cluster_offset += fat_root_dir_addr(Buffer);
}
//############################################################################
//Auslesen der Adresse des First Root Directory von Volume Boot Record
unsigned int fat_root_dir_addr (unsigned char *Buffer)
//############################################################################
{
struct BootSec *bootp; //Zeiger auf Bootsektor Struktur
unsigned int FirstRootDirSecNum;
//auslesen des Volume Boot Record von der MMC/SD Karte
mmc_read_sector (volume_boot_record_addr,Buffer);
bootp=(struct BootSec *)Buffer;
//berechnet den ersten Sector des Root Directory
FirstRootDirSecNum = ( bootp->BPB_RsvdSecCnt +
(bootp->BPB_NumFATs * bootp->BPB_FATSz16));
FirstRootDirSecNum+= volume_boot_record_addr;
return(FirstRootDirSecNum);
}
//############################################################################
// Ausgabe des angegebenen Directory Eintrag in Entry_Count
// ist kein Eintrag vorhanden, ist der Eintrag im
// R<>ckgabe Cluster 0xFFFF. Es wird immer nur ein Eintrag ausgegeben
// um Speicherplatz zu sparen um es auch f<>r kleine Atmels zu benutzen
unsigned int fat_read_dir_ent (unsigned int dir_cluster, //Angabe Dir Cluster
unsigned char Entry_Count, //Angabe welcher Direintrag
unsigned long *Size, //R<>ckgabe der File Gr<47><72>e
unsigned char *Dir_Attrib, //R<>ckgabe des Dir Attributs
unsigned char *Buffer) //Working Buffer
//############################################################################
{
unsigned char *pointer;
unsigned int TMP_Entry_Count = 0;
unsigned long Block = 0;
struct DirEntry *dir; //Zeiger auf einen Verzeichniseintrag
pointer = Buffer;
if (dir_cluster == 0)
{
Block = fat_root_dir_addr(Buffer);
}
else
{
//Berechnung des Blocks aus BlockCount und Cluster aus FATTabelle
//Berechnung welcher Cluster zu laden ist
//Auslesen der FAT - Tabelle
fat_load (dir_cluster,&Block,Buffer);
Block = ((Block-2) * cluster_size) + cluster_offset;
}
//auslesen des gesamten Root Directory
for (unsigned int blk = Block;;blk++)
{
mmc_read_sector (blk,Buffer); //Lesen eines Blocks des Root Directory
for (unsigned int a=0;a<BlockSize; a = a + 32)
{
dir=(struct DirEntry *)&Buffer[a]; //Zeiger auf aktuellen Verzeichniseintrag holen
if (dir->DIR_Name[0] == 0) //Kein weiterer Eintrag wenn erstes Zeichen des Namens 0 ist
{
return (0xFFFF);
}
//Pr<50>fen ob es ein 8.3 Eintrag ist
//Das ist der Fall wenn es sich nicht um einen Eintrag f<>r lange Dateinamen
//oder um einen als gel<65>scht markierten Eintrag handelt.
if ((dir->DIR_Attr != ATTR_LONG_NAME) &&
(dir->DIR_Name[0] != DIR_ENTRY_IS_FREE))
{
//Ist es der gew<65>nschte Verzeichniseintrag
if (TMP_Entry_Count == Entry_Count)
{
//Speichern des Verzeichnis Eintrages in den R<>ckgabe Buffer
for(unsigned char b=0;b<11;b++)
{
if (dir->DIR_Name[b] != SPACE)
{
if (b == 8)
{
*pointer++= '.';
}
*pointer++=dir->DIR_Name[b];
}
}
*pointer++='\0';
*Dir_Attrib = dir->DIR_Attr;
//Speichern der Filegr<67><72>e
*Size=dir->DIR_FileSize;
//Speichern des Clusters des Verzeichniseintrages
dir_cluster = dir->DIR_FstClusLO;
//Eintrag gefunden R<>cksprung mit Cluster File Start
return(dir_cluster);
}
TMP_Entry_Count++;
}
}
}
return (0xFFFF); //Kein Eintrag mehr gefunden R<>cksprung mit 0xFFFF
}
//############################################################################
// Auslesen der Cluster f<>r ein File aus der FAT
// in den Buffer(512Byte). Bei einer 128MB MMC/SD
// Karte ist die Cluster gr<67><72>e normalerweise 16KB gro<72>
// das bedeutet das File kann max. 4MByte gro<72> sein.
// Bei gr<67><72>eren Files mu<6D> der Buffer gr<67><72>er definiert
// werden! (Ready)
// Cluster = Start Clusterangabe aus dem Directory
void fat_load ( unsigned int Cluster, //Angabe Startcluster
unsigned long *Block,
unsigned char *TMP_Buffer) //Workingbuffer
//############################################################################
{
//Zum <20>berpr<70>fen ob der FAT Block schon geladen wurde
unsigned int FAT_Block_Store = 0;
//Byte Adresse innerhalb des Fat Blocks
unsigned int FAT_Byte_Addresse;
//FAT Block Adresse
unsigned int FAT_Block_Addresse;
//Berechnung f<>r den ersten FAT Block (FAT Start Addresse)
for (unsigned int a = 0;;a++)
{
if (a == *Block)
{
*Block = (0x0000FFFF & Cluster);
return;
}
if (Cluster == 0xFFFF)
{
break; //Ist das Ende des Files erreicht Schleife beenden
}
//Berechnung des Bytes innerhalb des FAT Block<63>s
FAT_Byte_Addresse = (Cluster*2) % BlockSize;
//Berechnung des Blocks der gelesen werden mu<6D>
FAT_Block_Addresse = ((Cluster*2) / BlockSize) +
volume_boot_record_addr + fat_offset;
//Lesen des FAT Blocks
//<2F>berpr<70>fung ob dieser Block schon gelesen wurde
if (FAT_Block_Addresse != FAT_Block_Store)
{
FAT_Block_Store = FAT_Block_Addresse;
//Lesen des FAT Blocks
mmc_read_sector (FAT_Block_Addresse,TMP_Buffer);
}
//Lesen der n<>chsten Clusternummer
Cluster = (TMP_Buffer[FAT_Byte_Addresse + 1] << 8) +
TMP_Buffer[FAT_Byte_Addresse];
}
return;
}
//############################################################################
//Lesen eines 512Bytes Blocks von einem File
void fat_read_file (unsigned int Cluster,//Angabe des Startclusters vom File
unsigned char *Buffer, //Workingbuffer
unsigned long BlockCount) //Angabe welcher Bock vom File geladen
//werden soll a 512 Bytes
//############################################################################
{
//Berechnung des Blocks aus BlockCount und Cluster aus FATTabelle
//Berechnung welcher Cluster zu laden ist
unsigned long Block = (BlockCount/cluster_size);
//Auslesen der FAT - Tabelle
fat_load (Cluster,&Block,Buffer);
Block = ((Block-2) * cluster_size) + cluster_offset;
//Berechnung des Blocks innerhalb des Cluster
Block += (BlockCount % cluster_size);
//Read Data Block from Device
mmc_read_sector (Block,Buffer);
return;
}
//############################################################################
//Lesen eines 512Bytes Blocks von einem File
void fat_write_file (unsigned int cluster,//Angabe des Startclusters vom File
unsigned char *buffer, //Workingbuffer
unsigned long blockCount) //Angabe welcher Bock vom File gespeichert
//werden soll a 512 Bytes
//############################################################################
{
//Berechnung des Blocks aus BlockCount und Cluster aus FATTabelle
//Berechnung welcher Cluster zu speichern ist
unsigned char tmp_buffer[513];
unsigned long block = (blockCount/cluster_size);
//Auslesen der FAT - Tabelle
fat_load (cluster,&block,tmp_buffer);
block = ((block-2) * cluster_size) + cluster_offset;
//Berechnung des Blocks innerhalb des Cluster
block += (blockCount % cluster_size);
//Write Data Block to Device
mmc_write_sector (block,buffer);
return;
}
//####################################################################################
//Sucht ein File im Directory
unsigned char fat_search_file (unsigned char *File_Name, //Name des zu suchenden Files
unsigned int *Cluster, //Angabe Dir Cluster welches
//durchsucht werden soll
//und R<>ckgabe des clusters
//vom File welches gefunden
//wurde
unsigned long *Size, //R<>ckgabe der File Gr<47><72>e
unsigned char *Dir_Attrib,//R<>ckgabe des Dir Attributs
unsigned char *Buffer) //Working Buffer
//####################################################################################
{
unsigned int Dir_Cluster_Store = *Cluster;
for (unsigned char a = 0;a < 100;a++)
{
*Cluster = fat_read_dir_ent(Dir_Cluster_Store,a,Size,Dir_Attrib,Buffer);
if (*Cluster == 0xffff)
{
return(0); //File not Found
}
if(strcasecmp((char *)File_Name,(char *)Buffer) == 0)
{
return(1); //File Found
}
}
return(2); //Error
}