fat.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /*#######################################################################################
  2. FAT for AVR (MMC/SD)
  3. Copyright (C) 2004 Ulrich Radig
  4. Bei Fragen und Verbesserungen wendet euch per EMail an
  5. mail@ulrichradig.de
  6. oder im Forum meiner Web Page : www.ulrichradig.de
  7. Dieses Programm ist freie Software. Sie können es unter den Bedingungen der
  8. GNU General Public License, wie von der Free Software Foundation veröffentlicht,
  9. weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder
  10. (nach Ihrer Option) jeder späteren Version.
  11. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung,
  12. daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE,
  13. sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT
  14. FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.
  15. Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
  16. Programm erhalten haben.
  17. Falls nicht, schreiben Sie an die Free Software Foundation,
  18. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  19. #######################################################################################*/
  20. #include "fat.h"
  21. unsigned char cluster_size;
  22. unsigned int fat_offset;
  23. unsigned int cluster_offset;
  24. unsigned int volume_boot_record_addr;
  25. //############################################################################
  26. //Auslesen Cluster Size der MMC/SD Karte und Speichern der größe ins EEprom
  27. //Auslesen Cluster Offset der MMC/SD Karte und Speichern der größe ins EEprom
  28. void fat_init (uint8_t *Buffer)
  29. //############################################################################
  30. {
  31. struct BootSec *bootp; //Zeiger auf Bootsektor Struktur
  32. // unsigned char Buffer[BlockSize];
  33. //volume_boot_record_addr = fat_addr (Buffer);
  34. mmc_read_sector (MASTER_BOOT_RECORD,Buffer); //Read Master Boot Record
  35. if (Buffer[510] == 0x55 && Buffer[511] == 0xAA)
  36. {
  37. FAT_DEBUG("MBR Signatur found!\r\n");
  38. }
  39. else
  40. {
  41. FAT_DEBUG("MBR Signatur not found!\r\n");
  42. while(1);
  43. }
  44. volume_boot_record_addr = Buffer[VBR_ADDR] + (Buffer[VBR_ADDR+1] << 8);
  45. mmc_read_sector (volume_boot_record_addr,Buffer);
  46. if (Buffer[510] == 0x55 && Buffer[511] == 0xAA)
  47. {
  48. FAT_DEBUG("VBR Signatur found!\r\n");
  49. }
  50. else
  51. {
  52. FAT_DEBUG("VBR Signatur not found!\r\n");
  53. volume_boot_record_addr = MASTER_BOOT_RECORD;//<- added by Hennie
  54. mmc_read_sector (MASTER_BOOT_RECORD,Buffer); //Read Master Boot Record
  55. }
  56. bootp=(struct BootSec *)Buffer;
  57. cluster_size = bootp->BPB_SecPerClus;
  58. fat_offset = bootp->BPB_RsvdSecCnt;
  59. cluster_offset = ((bootp->BPB_BytesPerSec * 32)/BlockSize);
  60. cluster_offset += fat_root_dir_addr(Buffer);
  61. }
  62. //############################################################################
  63. //Auslesen der Adresse des First Root Directory von Volume Boot Record
  64. unsigned int fat_root_dir_addr (unsigned char *Buffer)
  65. //############################################################################
  66. {
  67. struct BootSec *bootp; //Zeiger auf Bootsektor Struktur
  68. unsigned int FirstRootDirSecNum;
  69. //auslesen des Volume Boot Record von der MMC/SD Karte
  70. mmc_read_sector (volume_boot_record_addr,Buffer);
  71. bootp=(struct BootSec *)Buffer;
  72. //berechnet den ersten Sector des Root Directory
  73. FirstRootDirSecNum = ( bootp->BPB_RsvdSecCnt +
  74. (bootp->BPB_NumFATs * bootp->BPB_FATSz16));
  75. FirstRootDirSecNum+= volume_boot_record_addr;
  76. return(FirstRootDirSecNum);
  77. }
  78. //############################################################################
  79. // Ausgabe des angegebenen Directory Eintrag in Entry_Count
  80. // ist kein Eintrag vorhanden, ist der Eintrag im
  81. // Rückgabe Cluster 0xFFFF. Es wird immer nur ein Eintrag ausgegeben
  82. // um Speicherplatz zu sparen um es auch für kleine Atmels zu benutzen
  83. unsigned int fat_read_dir_ent (unsigned int dir_cluster, //Angabe Dir Cluster
  84. unsigned char Entry_Count, //Angabe welcher Direintrag
  85. unsigned long *Size, //Rückgabe der File Größe
  86. unsigned char *Dir_Attrib, //Rückgabe des Dir Attributs
  87. unsigned char *Buffer) //Working Buffer
  88. //############################################################################
  89. {
  90. unsigned char *pointer;
  91. unsigned int TMP_Entry_Count = 0;
  92. unsigned long Block = 0;
  93. struct DirEntry *dir; //Zeiger auf einen Verzeichniseintrag
  94. pointer = Buffer;
  95. if (dir_cluster == 0)
  96. {
  97. Block = fat_root_dir_addr(Buffer);
  98. }
  99. else
  100. {
  101. //Berechnung des Blocks aus BlockCount und Cluster aus FATTabelle
  102. //Berechnung welcher Cluster zu laden ist
  103. //Auslesen der FAT - Tabelle
  104. fat_load (dir_cluster,&Block,Buffer);
  105. Block = ((Block-2) * cluster_size) + cluster_offset;
  106. }
  107. //auslesen des gesamten Root Directory
  108. for (unsigned int blk = Block;;blk++)
  109. {
  110. mmc_read_sector (blk,Buffer); //Lesen eines Blocks des Root Directory
  111. for (unsigned int a=0;a<BlockSize; a = a + 32)
  112. {
  113. dir=(struct DirEntry *)&Buffer[a]; //Zeiger auf aktuellen Verzeichniseintrag holen
  114. if (dir->DIR_Name[0] == 0) //Kein weiterer Eintrag wenn erstes Zeichen des Namens 0 ist
  115. {
  116. return (0xFFFF);
  117. }
  118. //Prüfen ob es ein 8.3 Eintrag ist
  119. //Das ist der Fall wenn es sich nicht um einen Eintrag für lange Dateinamen
  120. //oder um einen als gelöscht markierten Eintrag handelt.
  121. if ((dir->DIR_Attr != ATTR_LONG_NAME) &&
  122. (dir->DIR_Name[0] != DIR_ENTRY_IS_FREE))
  123. {
  124. //Ist es der gewünschte Verzeichniseintrag
  125. if (TMP_Entry_Count == Entry_Count)
  126. {
  127. //Speichern des Verzeichnis Eintrages in den Rückgabe Buffer
  128. for(unsigned char b=0;b<11;b++)
  129. {
  130. if (dir->DIR_Name[b] != SPACE)
  131. {
  132. if (b == 8)
  133. {
  134. *pointer++= '.';
  135. }
  136. *pointer++=dir->DIR_Name[b];
  137. }
  138. }
  139. *pointer++='\0';
  140. *Dir_Attrib = dir->DIR_Attr;
  141. //Speichern der Filegröße
  142. *Size=dir->DIR_FileSize;
  143. //Speichern des Clusters des Verzeichniseintrages
  144. dir_cluster = dir->DIR_FstClusLO;
  145. //Eintrag gefunden Rücksprung mit Cluster File Start
  146. return(dir_cluster);
  147. }
  148. TMP_Entry_Count++;
  149. }
  150. }
  151. }
  152. return (0xFFFF); //Kein Eintrag mehr gefunden Rücksprung mit 0xFFFF
  153. }
  154. //############################################################################
  155. // Auslesen der Cluster für ein File aus der FAT
  156. // in den Buffer(512Byte). Bei einer 128MB MMC/SD
  157. // Karte ist die Cluster größe normalerweise 16KB groß
  158. // das bedeutet das File kann max. 4MByte groß sein.
  159. // Bei größeren Files muß der Buffer größer definiert
  160. // werden! (Ready)
  161. // Cluster = Start Clusterangabe aus dem Directory
  162. void fat_load ( unsigned int Cluster, //Angabe Startcluster
  163. unsigned long *Block,
  164. unsigned char *TMP_Buffer) //Workingbuffer
  165. //############################################################################
  166. {
  167. //Zum Überprüfen ob der FAT Block schon geladen wurde
  168. unsigned int FAT_Block_Store = 0;
  169. //Byte Adresse innerhalb des Fat Blocks
  170. unsigned int FAT_Byte_Addresse;
  171. //FAT Block Adresse
  172. unsigned int FAT_Block_Addresse;
  173. //Berechnung für den ersten FAT Block (FAT Start Addresse)
  174. for (unsigned int a = 0;;a++)
  175. {
  176. if (a == *Block)
  177. {
  178. *Block = (0x0000FFFF & Cluster);
  179. return;
  180. }
  181. if (Cluster == 0xFFFF)
  182. {
  183. break; //Ist das Ende des Files erreicht Schleife beenden
  184. }
  185. //Berechnung des Bytes innerhalb des FAT Block´s
  186. FAT_Byte_Addresse = (Cluster*2) % BlockSize;
  187. //Berechnung des Blocks der gelesen werden muß
  188. FAT_Block_Addresse = ((Cluster*2) / BlockSize) +
  189. volume_boot_record_addr + fat_offset;
  190. //Lesen des FAT Blocks
  191. //Überprüfung ob dieser Block schon gelesen wurde
  192. if (FAT_Block_Addresse != FAT_Block_Store)
  193. {
  194. FAT_Block_Store = FAT_Block_Addresse;
  195. //Lesen des FAT Blocks
  196. mmc_read_sector (FAT_Block_Addresse,TMP_Buffer);
  197. }
  198. //Lesen der nächsten Clusternummer
  199. Cluster = (TMP_Buffer[FAT_Byte_Addresse + 1] << 8) +
  200. TMP_Buffer[FAT_Byte_Addresse];
  201. }
  202. return;
  203. }
  204. //############################################################################
  205. //Lesen eines 512Bytes Blocks von einem File
  206. void fat_read_file (unsigned int Cluster,//Angabe des Startclusters vom File
  207. unsigned char *Buffer, //Workingbuffer
  208. unsigned long BlockCount) //Angabe welcher Bock vom File geladen
  209. //werden soll a 512 Bytes
  210. //############################################################################
  211. {
  212. //Berechnung des Blocks aus BlockCount und Cluster aus FATTabelle
  213. //Berechnung welcher Cluster zu laden ist
  214. unsigned long Block = (BlockCount/cluster_size);
  215. //Auslesen der FAT - Tabelle
  216. fat_load (Cluster,&Block,Buffer);
  217. Block = ((Block-2) * cluster_size) + cluster_offset;
  218. //Berechnung des Blocks innerhalb des Cluster
  219. Block += (BlockCount % cluster_size);
  220. //Read Data Block from Device
  221. mmc_read_sector (Block,Buffer);
  222. return;
  223. }
  224. //############################################################################
  225. //Lesen eines 512Bytes Blocks von einem File
  226. void fat_write_file (unsigned int cluster,//Angabe des Startclusters vom File
  227. unsigned char *buffer, //Workingbuffer
  228. unsigned long blockCount) //Angabe welcher Bock vom File gespeichert
  229. //werden soll a 512 Bytes
  230. //############################################################################
  231. {
  232. //Berechnung des Blocks aus BlockCount und Cluster aus FATTabelle
  233. //Berechnung welcher Cluster zu speichern ist
  234. unsigned char tmp_buffer[513];
  235. unsigned long block = (blockCount/cluster_size);
  236. //Auslesen der FAT - Tabelle
  237. fat_load (cluster,&block,tmp_buffer);
  238. block = ((block-2) * cluster_size) + cluster_offset;
  239. //Berechnung des Blocks innerhalb des Cluster
  240. block += (blockCount % cluster_size);
  241. //Write Data Block to Device
  242. mmc_write_sector (block,buffer);
  243. return;
  244. }
  245. //####################################################################################
  246. //Sucht ein File im Directory
  247. unsigned char fat_search_file (unsigned char *File_Name, //Name des zu suchenden Files
  248. unsigned int *Cluster, //Angabe Dir Cluster welches
  249. //durchsucht werden soll
  250. //und Rückgabe des clusters
  251. //vom File welches gefunden
  252. //wurde
  253. unsigned long *Size, //Rückgabe der File Größe
  254. unsigned char *Dir_Attrib,//Rückgabe des Dir Attributs
  255. unsigned char *Buffer) //Working Buffer
  256. //####################################################################################
  257. {
  258. unsigned int Dir_Cluster_Store = *Cluster;
  259. for (unsigned char a = 0;a < 100;a++)
  260. {
  261. *Cluster = fat_read_dir_ent(Dir_Cluster_Store,a,Size,Dir_Attrib,Buffer);
  262. if (*Cluster == 0xffff)
  263. {
  264. return(0); //File not Found
  265. }
  266. if(strcasecmp((char *)File_Name,(char *)Buffer) == 0)
  267. {
  268. return(1); //File Found
  269. }
  270. }
  271. return(2); //Error
  272. }