?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 6

Line No. Rev Author Line
1 6 kaklik <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
3 <title>Procyon AVRlib: fat.c Source File</title>
4 <link href="dox.css" rel="stylesheet" type="text/css">
5 </head><body>
6 <!-- Generated by Doxygen 1.4.2 -->
7 <div class="qindex"><a class="qindex" href="main.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
8 <h1>fat.c</h1><a href="fat_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment">00001 <span class="comment">/*! \file fat.c \brief FAT16/32 file system driver. */</span>
9 00002 <span class="comment">//*****************************************************************************</span>
10 00003 <span class="comment">//</span>
11 00004 <span class="comment">// File Name : 'fat.c'</span>
12 00005 <span class="comment">// Title : FAT16/32 file system driver</span>
13 00006 <span class="comment">// Author : Pascal Stang</span>
14 00007 <span class="comment">// Date : 11/07/2000</span>
15 00008 <span class="comment">// Revised : 12/12/2000</span>
16 00009 <span class="comment">// Version : 0.3</span>
17 00010 <span class="comment">// Target MCU : ATmega103 (should work for Atmel AVR Series)</span>
18 00011 <span class="comment">// Editor Tabs : 4</span>
19 00012 <span class="comment">//</span>
20 00013 <span class="comment">// This code is based in part on work done by Jesper Hansen for his</span>
21 00014 <span class="comment">// YAMPP MP3 player project.</span>
22 00015 <span class="comment">//</span>
23 00016 <span class="comment">// NOTE: This code is currently below version 1.0, and therefore is considered</span>
24 00017 <span class="comment">// to be lacking in some functionality or documentation, or may not be fully</span>
25 00018 <span class="comment">// tested. Nonetheless, you can expect most functions to work.</span>
26 00019 <span class="comment">//</span>
27 00020 <span class="comment">// This code is distributed under the GNU Public License</span>
28 00021 <span class="comment">// which can be found at http://www.gnu.org/licenses/gpl.txt</span>
29 00022 <span class="comment">//</span>
30 00023 <span class="comment">//*****************************************************************************</span>
31 00024
32 00025
33 00026 <span class="preprocessor">#include &lt;avr/io.h&gt;</span>
34 00027 <span class="preprocessor">#include &lt;avr/pgmspace.h&gt;</span>
35 00028 <span class="preprocessor">#include &lt;string.h&gt;</span>
36 00029
37 00030 <span class="preprocessor">#include "<a class="code" href="ata_8h.html">ata.h</a>"</span>
38 00031 <span class="preprocessor">#include "<a class="code" href="rprintf_8h.html">rprintf.h</a>"</span>
39 00032 <span class="preprocessor">#include "<a class="code" href="debug_8h.html">debug.h</a>"</span>
40 00033
41 00034 <span class="preprocessor">#include "<a class="code" href="fat_8h.html">fat.h</a>"</span>
42 00035 <span class="preprocessor">#include "<a class="code" href="fatconf_8h.html">fatconf.h</a>"</span>
43 00036
44 00037 <span class="comment">// globals</span>
45 00038 <span class="comment">// buffers</span>
46 00039 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *SectorBuffer = (<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *) FAT_SECTOR_BUFFER_ADDR;
47 00040 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *FileNameBuffer = (<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *) FAT_FILENAME_BUFFER_ADDR;
48 00041 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *PathNameBuffer = (<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *) FAT_PATHNAME_BUFFER_ADDR;
49 00042
50 00043 <span class="comment">// filesystem constants/metrics</span>
51 00044 <span class="keyword">struct </span>partrecord PartInfo;
52 00045 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Fat32Enabled;
53 00046 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> FirstDataSector;
54 00047 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> BytesPerSector;
55 00048 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> SectorsPerCluster;
56 00049 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> FirstFATSector;
57 00050 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> RootDirStartCluster;
58 00051
59 00052 <span class="comment">// operating variables</span>
60 00053 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> CurrentDirStartCluster; <span class="comment">//&lt; current directory starting cluster</span>
61 00054 <span class="keyword">struct </span>FileInfoStruct FileInfo; <span class="comment">//&lt; file information for last file accessed</span>
62 00055 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> FatInCache = 0;
63 00056
64 00057
65 00058 <span class="comment">/*************************************************************************/</span>
66 00059 <span class="comment">/*************************************************************************/</span>
67 00060
68 00061
69 00062 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> fatClustToSect(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> clust)
70 00063 {
71 00064 <span class="keywordflow">return</span> ((clust-2) * SectorsPerCluster) + FirstDataSector;
72 00065 }
73 00066
74 00067 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> fatClusterSize(<span class="keywordtype">void</span>)
75 00068 {
76 00069 <span class="comment">// return the number of sectors in a disk cluster</span>
77 00070 <span class="keywordflow">return</span> SectorsPerCluster;
78 00071 }
79 00072
80 00073 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> fatInit( <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> device)
81 00074 {
82 00075 <span class="comment">//struct partrecord *pr;</span>
83 00076 <span class="keyword">struct </span>bpb710 *bpb;
84 00077
85 00078 <span class="comment">// read partition table</span>
86 00079 <span class="comment">// TODO.... error checking</span>
87 00080 ataReadSectors(DRIVE0, 0, 1, SectorBuffer);
88 00081 <span class="comment">// map first partition record </span>
89 00082 <span class="comment">// save partition information to global PartInfo</span>
90 00083 PartInfo = *((<span class="keyword">struct </span>partrecord *) ((<span class="keyword">struct </span>partsector *) SectorBuffer)-&gt;psPart);
91 00084 <span class="comment">// PartInfo = *pr;</span>
92 00085
93 00086 <span class="comment">// Read the Partition BootSector</span>
94 00087 <span class="comment">// **first sector of partition in PartInfo.prStartLBA</span>
95 00088 ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer );
96 00089 bpb = (<span class="keyword">struct </span>bpb710 *) ((<span class="keyword">struct </span>bootsector710 *) SectorBuffer)-&gt;bsBPB;
97 00090
98 00091 <span class="comment">// setup global disk constants</span>
99 00092 FirstDataSector = PartInfo.prStartLBA;
100 00093 <span class="keywordflow">if</span>(bpb-&gt;bpbFATsecs)
101 00094 {
102 00095 <span class="comment">// bpbFATsecs is non-zero and is therefore valid</span>
103 00096 FirstDataSector += bpb-&gt;bpbResSectors + bpb-&gt;bpbFATs * bpb-&gt;bpbFATsecs;
104 00097 }
105 00098 <span class="keywordflow">else</span>
106 00099 {
107 00100 <span class="comment">// bpbFATsecs is zero, real value is in bpbBigFATsecs</span>
108 00101 FirstDataSector += bpb-&gt;bpbResSectors + bpb-&gt;bpbFATs * bpb-&gt;bpbBigFATsecs;
109 00102 }
110 00103 SectorsPerCluster = bpb-&gt;bpbSecPerClust;
111 00104 BytesPerSector = bpb-&gt;bpbBytesPerSec;
112 00105 FirstFATSector = bpb-&gt;bpbResSectors + PartInfo.prStartLBA;
113 00106
114 00107 <span class="keywordflow">switch</span> (PartInfo.prPartType)
115 00108 {
116 00109 <span class="keywordflow">case</span> PART_TYPE_DOSFAT16:
117 00110 <span class="keywordflow">case</span> PART_TYPE_FAT16:
118 00111 <span class="keywordflow">case</span> PART_TYPE_FAT16LBA:
119 00112 <span class="comment">// first directory cluster is 2 by default (clusters range 2-&gt;big)</span>
120 00113 RootDirStartCluster = CLUST_FIRST;
121 00114 <span class="comment">// push data sector pointer to end of root directory area</span>
122 00115 <span class="comment">//FirstDataSector += (bpb-&gt;bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;</span>
123 00116 Fat32Enabled = FALSE;
124 00117 <span class="keywordflow">break</span>;
125 00118 <span class="keywordflow">case</span> PART_TYPE_FAT32LBA:
126 00119 <span class="keywordflow">case</span> PART_TYPE_FAT32:
127 00120 <span class="comment">// bpbRootClust field exists in FAT32 bpb710, but not in lesser bpb's</span>
128 00121 RootDirStartCluster = bpb-&gt;bpbRootClust;
129 00122 <span class="comment">// push data sector pointer to end of root directory area</span>
130 00123 <span class="comment">// need this? FirstDataSector += (bpb-&gt;bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;</span>
131 00124 Fat32Enabled = TRUE;
132 00125 <span class="keywordflow">break</span>;
133 00126 <span class="keywordflow">default</span>:
134 00127 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"Found: No Partition!\r\n"</span>);
135 00128 <span class="comment">//return 1;</span>
136 00129 <span class="keywordflow">break</span>;
137 00130 }
138 00131
139 00132 <span class="comment">// set current directory to root (\)</span>
140 00133 CurrentDirStartCluster = RootDirStartCluster;
141 00134 PathNameBuffer[0] = <span class="charliteral">'\\'</span>;
142 00135 PathNameBuffer[1] = 0;
143 00136
144 00137
145 00138 <span class="comment">// do debug</span>
146 00139 <span class="preprocessor">#ifdef DEBUG_FAT</span>
147 00140 <span class="preprocessor"></span> <span class="keywordflow">switch</span> (PartInfo.prPartType)
148 00141 {
149 00142 <span class="keywordflow">case</span> PART_TYPE_DOSFAT16:
150 00143 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"Found: DOSFAT 16\r\n"</span>);
151 00144 <span class="keywordflow">break</span>;
152 00145 <span class="keywordflow">case</span> PART_TYPE_FAT16:
153 00146 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"Found: FAT16\r\n"</span>);
154 00147 <span class="keywordflow">break</span>;
155 00148 <span class="keywordflow">case</span> PART_TYPE_FAT16LBA:
156 00149 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"Found: FAT16 LBA\r\n"</span>);
157 00150 <span class="keywordflow">break</span>;
158 00151 <span class="keywordflow">case</span> PART_TYPE_FAT32LBA:
159 00152 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"Found: FAT32 LBA\r\n"</span>);
160 00153 <span class="keywordflow">break</span>;
161 00154 <span class="keywordflow">case</span> PART_TYPE_FAT32:
162 00155 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"Found: FAT32\r\n"</span>);
163 00156 <span class="comment">//return 1; </span>
164 00157 <span class="keywordflow">break</span>;
165 00158 <span class="keywordflow">default</span>:
166 00159 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"Found: No Partition!\r\n"</span>);
167 00160 <span class="comment">//return 1;</span>
168 00161 <span class="keywordflow">break</span>;
169 00162 }
170 00163
171 00164 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"First sector : "</span>); <a class="code" href="group__rprintf.html#ga9">rprintfu32</a>(PartInfo.prStartLBA); <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
172 00165 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"Size : "</span>); <a class="code" href="group__rprintf.html#ga9">rprintfu32</a>(PartInfo.prSize); <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
173 00166 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"bytes/sector : "</span>); <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(bpb-&gt;bpbBytesPerSec); <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
174 00167 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"sectors/cluster : "</span>); <a class="code" href="group__rprintf.html#ga7">rprintfu08</a>(bpb-&gt;bpbSecPerClust); <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
175 00168 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"reserved sectors: "</span>); <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(bpb-&gt;bpbResSectors); <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
176 00169 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"FatSectors : "</span>); <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(bpb-&gt;bpbFATsecs); <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
177 00170 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"BigFatSectors : "</span>); <a class="code" href="group__rprintf.html#ga9">rprintfu32</a>(bpb-&gt;bpbBigFATsecs); <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
178 00171 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"Number of Fats : "</span>); <a class="code" href="group__rprintf.html#ga7">rprintfu08</a>(bpb-&gt;bpbFATs); <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
179 00172 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"First Fat Sector: "</span>); <a class="code" href="group__rprintf.html#ga9">rprintfu32</a>(FirstFATSector); <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
180 00173 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"First Data Sect : "</span>); <a class="code" href="group__rprintf.html#ga9">rprintfu32</a>(FirstDataSector); <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
181 00174 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"RootDirStartClus: "</span>); <a class="code" href="group__rprintf.html#ga9">rprintfu32</a>(RootDirStartCluster); <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
182 00175 <span class="preprocessor">#endif</span>
183 00176 <span class="preprocessor"></span>
184 00177 <span class="keywordflow">return</span> 0;
185 00178 }
186 00179 <span class="comment"></span>
187 00180 <span class="comment">//////////////////////////////////////////////////////////////</span>
188 00181 <span class="comment"></span>
189 00182 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> fatGetDirEntry(<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> entry)
190 00183 {
191 00184 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> sector;
192 00185 <span class="keyword">struct </span>direntry *de = 0; <span class="comment">// avoid compiler warning by initializing</span>
193 00186 <span class="keyword">struct </span>winentry *we;
194 00187 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> haveLongNameEntry;
195 00188 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> gotEntry;
196 00189 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> b;
197 00190 <span class="keywordtype">int</span> i,index;
198 00191 <span class="keywordtype">char</span> *fnbPtr;
199 00192 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> entrycount = 0;
200 00193
201 00194 <span class="comment">// read dir data</span>
202 00195 sector = fatClustToSect(CurrentDirStartCluster);
203 00196
204 00197 haveLongNameEntry = 0;
205 00198 gotEntry = 0;
206 00199
207 00200 index = 16; <span class="comment">// crank it up</span>
208 00201
209 00202 <span class="comment">//while(entrycount &lt; entry) </span>
210 00203 <span class="keywordflow">while</span>(1)
211 00204 {
212 00205 <span class="keywordflow">if</span>(index == 16) <span class="comment">// time for next sector ?</span>
213 00206 {
214 00207 ataReadSectors( DRIVE0, sector++, 1, SectorBuffer);
215 00208 de = (<span class="keyword">struct </span>direntry *) SectorBuffer;
216 00209 index = 0;
217 00210 }
218 00211
219 00212 <span class="comment">// check the status of this directory entry slot</span>
220 00213 <span class="keywordflow">if</span>(de-&gt;deName[0] == 0x00)
221 00214 {
222 00215 <span class="comment">// slot is empty and this is the end of directory</span>
223 00216 gotEntry = 0;
224 00217 <span class="keywordflow">break</span>;
225 00218 }
226 00219 <span class="keywordflow">else</span> <span class="keywordflow">if</span>(de-&gt;deName[0] == 0xE5)
227 00220 {
228 00221 <span class="comment">// this is an empty slot</span>
229 00222 <span class="comment">// do nothing and move to the next one</span>
230 00223 }
231 00224 <span class="keywordflow">else</span>
232 00225 {
233 00226 <span class="comment">// this is a valid and occupied entry</span>
234 00227 <span class="comment">// is it a part of a long file/dir name?</span>
235 00228 <span class="keywordflow">if</span>(de-&gt;deAttributes == ATTR_LONG_FILENAME)
236 00229 {
237 00230 <span class="comment">// we have a long name entry</span>
238 00231 <span class="comment">// cast this directory entry as a "windows" (LFN: LongFileName) entry</span>
239 00232 we = (<span class="keyword">struct </span>winentry *) de;
240 00233
241 00234 b = WIN_ENTRY_CHARS*( (we-&gt;weCnt-1) &amp; 0x0f); <span class="comment">// index into string</span>
242 00235 fnbPtr = &amp;FileNameBuffer[b];
243 00236 <span class="keywordflow">for</span> (i=0;i&lt;5;i++) *fnbPtr++ = we-&gt;wePart1[i*2]; <span class="comment">// copy first part</span>
244 00237 <span class="keywordflow">for</span> (i=0;i&lt;6;i++) *fnbPtr++ = we-&gt;wePart2[i*2]; <span class="comment">// second part</span>
245 00238 <span class="keywordflow">for</span> (i=0;i&lt;2;i++) *fnbPtr++ = we-&gt;wePart3[i*2]; <span class="comment">// and third part</span>
246 00239 <span class="keywordflow">if</span> (we-&gt;weCnt &amp; WIN_LAST) *fnbPtr = 0; <span class="comment">// in case dirnamelength is multiple of 13, add termination</span>
247 00240 if ((we-&gt;weCnt &amp; 0x0f) == 1) haveLongNameEntry = 1; <span class="comment">// flag that we have a complete long name entry set</span>
248 00241 }
249 00242 <span class="keywordflow">else</span>
250 00243 {
251 00244 <span class="comment">// we have a short name entry</span>
252 00245
253 00246 <span class="comment">// check if this is the short name entry corresponding</span>
254 00247 <span class="comment">// to the end of a multi-part long name entry</span>
255 00248 <span class="keywordflow">if</span>(haveLongNameEntry)
256 00249 {
257 00250 <span class="comment">// a long entry name has been collected</span>
258 00251 <span class="keywordflow">if</span>(entrycount == entry)
259 00252 {
260 00253 <span class="comment">// desired entry has been found, break out</span>
261 00254 gotEntry = 1;
262 00255 <span class="keywordflow">break</span>;
263 00256 }
264 00257 <span class="comment">// otherwise</span>
265 00258 haveLongNameEntry = 0; <span class="comment">// clear long name flag</span>
266 00259 entrycount++; <span class="comment">// increment entry counter </span>
267 00260 }
268 00261 <span class="keywordflow">else</span>
269 00262 {
270 00263 <span class="comment">// entry is a short name (8.3 format) without a</span>
271 00264 <span class="comment">// corresponding multi-part long name entry</span>
272 00265 fnbPtr = FileNameBuffer;
273 00266 <span class="keywordflow">for</span> (i=0;i&lt;8;i++) *fnbPtr++ = de-&gt;deName[i]; <span class="comment">// copy name</span>
274 00267 *fnbPtr++ = <span class="charliteral">'.'</span>; <span class="comment">// insert '.'</span>
275 00268 <span class="keywordflow">for</span> (i=0;i&lt;3;i++) *fnbPtr++ = de-&gt;deExtension[i]; <span class="comment">// copy extension</span>
276 00269 *fnbPtr = 0; <span class="comment">// null-terminate</span>
277 00270
278 00271 <span class="keywordflow">if</span>(entrycount == entry)
279 00272 {
280 00273 <span class="comment">// desired entry has been found, break out</span>
281 00274 gotEntry = 1;
282 00275 <span class="keywordflow">break</span>;
283 00276 }
284 00277 <span class="comment">// otherwise</span>
285 00278 entrycount++; <span class="comment">// increment entry counter </span>
286 00279 }
287 00280 }
288 00281 }
289 00282 <span class="comment">// next directory entry</span>
290 00283 de++;
291 00284 <span class="comment">// next index</span>
292 00285 index++;
293 00286 }
294 00287
295 00288 <span class="comment">// we have a file/dir to return</span>
296 00289 <span class="comment">// store file/dir starting cluster (start of data)</span>
297 00290 FileInfo.StartCluster = (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>) ((<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)de-&gt;deHighClust &lt;&lt; 16) + de-&gt;deStartCluster;
298 00291 <span class="comment">// store file/dir size</span>
299 00292 <span class="comment">// (note: size field for subdirectory entries is always zero)</span>
300 00293 FileInfo.Size = de-&gt;deFileSize;
301 00294 <span class="comment">// store file/dir attributes</span>
302 00295 FileInfo.Attr = de-&gt;deAttributes;
303 00296 <span class="comment">// store file/dir creation time</span>
304 00297 FileInfo.CreateTime = de-&gt;deCTime[0] | de-&gt;deCTime[1]&lt;&lt;8;
305 00298 <span class="comment">// store file/dir creation date</span>
306 00299 FileInfo.CreateTime = de-&gt;deCDate[0] | de-&gt;deCDate[1]&lt;&lt;8;
307 00300
308 00301 <span class="keywordflow">return</span> gotEntry;
309 00302 }
310 00303
311 00304 <span class="comment">// change directory into </span>
312 00305 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> fatChangeDirectory(<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> entry)
313 00306 {
314 00307 <span class="comment">// get the requested directory entry</span>
315 00308 <span class="keywordflow">if</span>( fatGetDirEntry(entry) )
316 00309 {
317 00310 <span class="comment">// make sure the entry is a directory</span>
318 00311 <span class="keywordflow">if</span>(FileInfo.Attr &amp; ATTR_DIRECTORY)
319 00312 {
320 00313 <span class="comment">// change directories into this directory</span>
321 00314 <span class="comment">// check to see if we are changing back to root directory</span>
322 00315 <span class="keywordflow">if</span>(FileInfo.StartCluster)
323 00316 {
324 00317 <span class="comment">// standard change directory</span>
325 00318 CurrentDirStartCluster = FileInfo.StartCluster;
326 00319 }
327 00320 <span class="keywordflow">else</span>
328 00321 {
329 00322 <span class="comment">// if startCluster pointer is zero,</span>
330 00323 <span class="comment">// a change to the root directory is intended</span>
331 00324 <span class="comment">// change directory to root</span>
332 00325 CurrentDirStartCluster = RootDirStartCluster;
333 00326 }
334 00327 <span class="comment">// TODO: handle pathname properly for going up a directory</span>
335 00328 <span class="comment">// set path string</span>
336 00329 strcat(PathNameBuffer, FileNameBuffer);
337 00330 strcat(PathNameBuffer, <span class="stringliteral">"\\"</span>);
338 00331 <span class="comment">// return success</span>
339 00332 <span class="keywordflow">return</span> TRUE;
340 00333 }
341 00334 <span class="keywordflow">else</span>
342 00335 {
343 00336 <span class="comment">// not a directory, cannot CD into a file!</span>
344 00337 <span class="keywordflow">return</span> FALSE;
345 00338 }
346 00339 }
347 00340 <span class="keywordflow">else</span>
348 00341 {
349 00342 <span class="comment">// not a valid entry, cannot CD!</span>
350 00343 <span class="keywordflow">return</span> FALSE;
351 00344 }
352 00345 }
353 00346
354 00347 <span class="keywordtype">void</span> fatPrintDirEntry(<span class="keywordtype">void</span>)
355 00348 {
356 00349 <span class="comment">// print a formatted dir-style output for most recent file</span>
357 00350 <span class="comment">// print date</span>
358 00351 <a class="code" href="group__rprintf.html#ga10">rprintfNum</a>(10, 2, FALSE, <span class="charliteral">'0'</span>, (FileInfo.CreateDate&amp;DD_MONTH_MASK)&gt;&gt;DD_MONTH_SHIFT ); <span class="comment">// month</span>
359 00352 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'/'</span>);
360 00353 <a class="code" href="group__rprintf.html#ga10">rprintfNum</a>(10, 2, FALSE, <span class="charliteral">'0'</span>, (FileInfo.CreateDate&amp;DD_DAY_MASK)&gt;&gt;DD_DAY_SHIFT ); <span class="comment">// day</span>
361 00354 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'/'</span>);
362 00355 <a class="code" href="group__rprintf.html#ga10">rprintfNum</a>(10, 4, FALSE, <span class="charliteral">'0'</span>, (FileInfo.CreateDate&amp;DD_YEAR_MASK)&gt;&gt;DD_YEAR_SHIFT ); <span class="comment">// year</span>
363 00356 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">' '</span>);
364 00357
365 00358 <span class="comment">// print time</span>
366 00359 <a class="code" href="group__rprintf.html#ga10">rprintfNum</a>(10, 2, FALSE, <span class="charliteral">'0'</span>, (FileInfo.CreateTime&amp;DT_HOURS_MASK)&gt;&gt;DT_HOURS_SHIFT ); <span class="comment">// month</span>
367 00360 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">':'</span>);
368 00361 <a class="code" href="group__rprintf.html#ga10">rprintfNum</a>(10, 2, FALSE, <span class="charliteral">'0'</span>, (FileInfo.CreateTime&amp;DT_MINUTES_MASK)&gt;&gt;DT_MINUTES_SHIFT ); <span class="comment">// day</span>
369 00362 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">':'</span>);
370 00363 <a class="code" href="group__rprintf.html#ga10">rprintfNum</a>(10, 2, FALSE, <span class="charliteral">'0'</span>, 2*(FileInfo.CreateTime&amp;DT_2SECONDS_MASK)&gt;&gt;DT_2SECONDS_SHIFT ); <span class="comment">// seconds</span>
371 00364 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">' '</span>);
372 00365
373 00366 <span class="comment">// print attributes</span>
374 00367 <span class="keywordflow">if</span>(FileInfo.Attr &amp; ATTR_VOLUME) <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'V'</span>); <span class="keywordflow">else</span> <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'-'</span>);
375 00368 <span class="keywordflow">if</span>(FileInfo.Attr &amp; ATTR_DIRECTORY) <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'D'</span>); <span class="keywordflow">else</span> <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'-'</span>);
376 00369 <span class="keywordflow">if</span>(FileInfo.Attr &amp; ATTR_READONLY) <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'R'</span>); <span class="keywordflow">else</span> <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'-'</span>);
377 00370 <span class="keywordflow">if</span>(FileInfo.Attr &amp; ATTR_HIDDEN) <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'H'</span>); <span class="keywordflow">else</span> <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'-'</span>);
378 00371 <span class="keywordflow">if</span>(FileInfo.Attr &amp; ATTR_SYSTEM) <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'S'</span>); <span class="keywordflow">else</span> <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'-'</span>);
379 00372 <span class="keywordflow">if</span>(FileInfo.Attr &amp; ATTR_ARCHIVE) <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'A'</span>); <span class="keywordflow">else</span> <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'-'</span>);
380 00373 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">' '</span>);
381 00374
382 00375 <span class="comment">// print filesize</span>
383 00376 <a class="code" href="group__rprintf.html#ga10">rprintfNum</a>(10, 8, FALSE, <span class="charliteral">' '</span>, FileInfo.Size); <span class="comment">// filesize</span>
384 00377 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">' '</span>);
385 00378
386 00379 <span class="comment">// print filename</span>
387 00380 <a class="code" href="group__rprintf.html#ga2">rprintfStr</a>(FileNameBuffer);
388 00381 }
389 00382
390 00383 <span class="keywordtype">void</span> fatDumpDirSlot(<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> slot)
391 00384 {
392 00385 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> sector;
393 00386 <span class="comment">// load correct sector</span>
394 00387 sector = fatClustToSect(CurrentDirStartCluster);
395 00388 sector += slot/DIRENTRIES_PER_SECTOR;
396 00389 <span class="comment">// print the entry as a hex table</span>
397 00390 <a class="code" href="debug_8c.html#a0">debugPrintHexTable</a>(32, SectorBuffer+(slot&lt;&lt;5) );
398 00391 }
399 00392
400 00393 <span class="keyword">struct </span>FileInfoStruct* fatGetFileInfo(<span class="keywordtype">void</span>)
401 00394 {
402 00395 <span class="keywordflow">return</span> &amp;FileInfo;
403 00396 }
404 00397
405 00398 <span class="comment">// return the size of the last directory entry</span>
406 00399 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> fatGetFilesize(<span class="keywordtype">void</span>)
407 00400 {
408 00401 <span class="keywordflow">return</span> FileInfo.Size;
409 00402 }
410 00403
411 00404 <span class="comment">// return the long name of the last directory entry</span>
412 00405 <span class="keywordtype">char</span>* fatGetFilename(<span class="keywordtype">void</span>)
413 00406 {
414 00407 <span class="keywordflow">return</span> FileNameBuffer;
415 00408 }
416 00409
417 00410 <span class="comment">// return the directory of the last directory entry</span>
418 00411 <span class="keywordtype">char</span>* fatGetDirname(<span class="keywordtype">void</span>)
419 00412 {
420 00413 <span class="keywordflow">return</span> PathNameBuffer;
421 00414 }
422 00415
423 00416 <span class="comment">// load a clusterfull of data</span>
424 00417 <span class="keywordtype">void</span> fatLoadCluster(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> cluster, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *buffer)
425 00418 {
426 00419 <span class="keyword">register</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> i;
427 00420 <span class="comment">// read cluster</span>
428 00421 <span class="comment">//while ( ataReadSectors( DRIVE0, clust2sect(cluster), SectorsPerCluster, buffer) != 0);</span>
429 00422 <span class="keywordflow">for</span>(i=0; i&lt;SectorsPerCluster; i++)
430 00423 {
431 00424 ataReadSectors( DRIVE0, fatClustToSect(cluster)+i, 1, buffer+(i&lt;&lt;9) );
432 00425 <span class="comment">// temporary fix for wierd misaligned cluster problem</span>
433 00426 <span class="comment">// (only when using FAT16?)</span>
434 00427 <span class="comment">// ataReadSectors( DRIVE0, fatClustToSect(cluster+8)+i, 1, buffer+(i&lt;&lt;9) );</span>
435 00428 }
436 00429 }
437 00430
438 00431
439 00432 <span class="comment">// find next cluster in the FAT chain</span>
440 00433 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> fatNextCluster(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> cluster)
441 00434 {
442 00435 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> nextCluster;
443 00436 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> fatMask;
444 00437 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> fatOffset;
445 00438 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> sector;
446 00439 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> offset;
447 00440
448 00441 <span class="comment">// get fat offset in bytes</span>
449 00442 <span class="keywordflow">if</span>(Fat32Enabled)
450 00443 {
451 00444 <span class="comment">// four FAT bytes (32 bits) for every cluster</span>
452 00445 fatOffset = cluster &lt;&lt; 2;
453 00446 <span class="comment">// set the FAT bit mask</span>
454 00447 fatMask = FAT32_MASK;
455 00448 }
456 00449 <span class="keywordflow">else</span>
457 00450 {
458 00451 <span class="comment">// two FAT bytes (16 bits) for every cluster</span>
459 00452 fatOffset = cluster &lt;&lt; 1;
460 00453 <span class="comment">// set the FAT bit mask</span>
461 00454 fatMask = FAT16_MASK;
462 00455 }
463 00456
464 00457 <span class="comment">// calculate the FAT sector that we're interested in</span>
465 00458 sector = FirstFATSector + (fatOffset / BytesPerSector);
466 00459 <span class="comment">// calculate offset of the our entry within that FAT sector</span>
467 00460 offset = fatOffset % BytesPerSector;
468 00461
469 00462 <span class="comment">// if we don't already have this FAT chunk loaded, go get it</span>
470 00463 <span class="keywordflow">if</span> (sector != FatInCache)
471 00464 {
472 00465 <span class="comment">// read sector of FAT table</span>
473 00466 <span class="keywordflow">while</span> (ataReadSectors( DRIVE0, sector, 1, (<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>*)FAT_CACHE_ADDR) != 0);
474 00467 FatInCache = sector;
475 00468 }
476 00469
477 00470 <span class="comment">// read the nextCluster value</span>
478 00471 nextCluster = (*((<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>*) &amp;((<span class="keywordtype">char</span>*)FAT_CACHE_ADDR)[offset])) &amp; fatMask;
479 00472
480 00473 <span class="comment">// check to see if we're at the end of the chain</span>
481 00474 <span class="keywordflow">if</span> (nextCluster == (CLUST_EOFE &amp; fatMask))
482 00475 nextCluster = 0;
483 00476
484 00477 <span class="preprocessor">#ifdef DEBUG_FAT</span>
485 00478 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"&gt;"</span>);
486 00479 <a class="code" href="group__rprintf.html#ga9">rprintfu32</a>(nextCluster);
487 00480 <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
488 00481 <span class="preprocessor">#endif</span>
489 00482 <span class="preprocessor"></span>
490 00483 <span class="keywordflow">return</span> nextCluster;
491 00484 }
492 </pre></div><hr size="1"><address style="align: right;"><small>Generated on Sun Oct 29 03:41:06 2006 for Procyon AVRlib by&nbsp;
493 <a href="http://www.doxygen.org/index.html">
494 <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.2 </small></address>
495 </body>
496 </html>
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3