root / arduino-1.0 / libraries / SD / utility / SdFat.h @ 58d82c77
History | View | Annotate | Download (21.9 KB)
1 |
/* Arduino SdFat Library
|
---|---|
2 |
* Copyright (C) 2009 by William Greiman
|
3 |
*
|
4 |
* This file is part of the Arduino SdFat Library
|
5 |
*
|
6 |
* This Library is free software: you can redistribute it and/or modify
|
7 |
* it under the terms of the GNU General Public License as published by
|
8 |
* the Free Software Foundation, either version 3 of the License, or
|
9 |
* (at your option) any later version.
|
10 |
*
|
11 |
* This Library is distributed in the hope that it will be useful,
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 |
* GNU General Public License for more details.
|
15 |
*
|
16 |
* You should have received a copy of the GNU General Public License
|
17 |
* along with the Arduino SdFat Library. If not, see
|
18 |
* <http://www.gnu.org/licenses/>.
|
19 |
*/
|
20 |
#ifndef SdFat_h
|
21 |
#define SdFat_h
|
22 |
/**
|
23 |
* \file
|
24 |
* SdFile and SdVolume classes
|
25 |
*/
|
26 |
#include <avr/pgmspace.h> |
27 |
#include "Sd2Card.h" |
28 |
#include "FatStructs.h" |
29 |
#include "Print.h" |
30 |
//------------------------------------------------------------------------------
|
31 |
/**
|
32 |
* Allow use of deprecated functions if non-zero
|
33 |
*/
|
34 |
#define ALLOW_DEPRECATED_FUNCTIONS 1 |
35 |
//------------------------------------------------------------------------------
|
36 |
// forward declaration since SdVolume is used in SdFile
|
37 |
class SdVolume; |
38 |
//==============================================================================
|
39 |
// SdFile class
|
40 |
|
41 |
// flags for ls()
|
42 |
/** ls() flag to print modify date */
|
43 |
uint8_t const LS_DATE = 1; |
44 |
/** ls() flag to print file size */
|
45 |
uint8_t const LS_SIZE = 2; |
46 |
/** ls() flag for recursive list of subdirectories */
|
47 |
uint8_t const LS_R = 4; |
48 |
|
49 |
// use the gnu style oflag in open()
|
50 |
/** open() oflag for reading */
|
51 |
uint8_t const O_READ = 0X01; |
52 |
/** open() oflag - same as O_READ */
|
53 |
uint8_t const O_RDONLY = O_READ;
|
54 |
/** open() oflag for write */
|
55 |
uint8_t const O_WRITE = 0X02; |
56 |
/** open() oflag - same as O_WRITE */
|
57 |
uint8_t const O_WRONLY = O_WRITE;
|
58 |
/** open() oflag for reading and writing */
|
59 |
uint8_t const O_RDWR = (O_READ | O_WRITE);
|
60 |
/** open() oflag mask for access modes */
|
61 |
uint8_t const O_ACCMODE = (O_READ | O_WRITE);
|
62 |
/** The file offset shall be set to the end of the file prior to each write. */
|
63 |
uint8_t const O_APPEND = 0X04; |
64 |
/** synchronous writes - call sync() after each write */
|
65 |
uint8_t const O_SYNC = 0X08; |
66 |
/** create the file if nonexistent */
|
67 |
uint8_t const O_CREAT = 0X10; |
68 |
/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
|
69 |
uint8_t const O_EXCL = 0X20; |
70 |
/** truncate the file to zero length */
|
71 |
uint8_t const O_TRUNC = 0X40; |
72 |
|
73 |
// flags for timestamp
|
74 |
/** set the file's last access date */
|
75 |
uint8_t const T_ACCESS = 1; |
76 |
/** set the file's creation date and time */
|
77 |
uint8_t const T_CREATE = 2; |
78 |
/** Set the file's write date and time */
|
79 |
uint8_t const T_WRITE = 4; |
80 |
// values for type_
|
81 |
/** This SdFile has not been opened. */
|
82 |
uint8_t const FAT_FILE_TYPE_CLOSED = 0; |
83 |
/** SdFile for a file */
|
84 |
uint8_t const FAT_FILE_TYPE_NORMAL = 1; |
85 |
/** SdFile for a FAT16 root directory */
|
86 |
uint8_t const FAT_FILE_TYPE_ROOT16 = 2; |
87 |
/** SdFile for a FAT32 root directory */
|
88 |
uint8_t const FAT_FILE_TYPE_ROOT32 = 3; |
89 |
/** SdFile for a subdirectory */
|
90 |
uint8_t const FAT_FILE_TYPE_SUBDIR = 4; |
91 |
/** Test value for directory type */
|
92 |
uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT16;
|
93 |
|
94 |
/** date field for FAT directory entry */
|
95 |
static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { |
96 |
return (year - 1980) << 9 | month << 5 | day; |
97 |
} |
98 |
/** year part of FAT directory date field */
|
99 |
static inline uint16_t FAT_YEAR(uint16_t fatDate) { |
100 |
return 1980 + (fatDate >> 9); |
101 |
} |
102 |
/** month part of FAT directory date field */
|
103 |
static inline uint8_t FAT_MONTH(uint16_t fatDate) { |
104 |
return (fatDate >> 5) & 0XF; |
105 |
} |
106 |
/** day part of FAT directory date field */
|
107 |
static inline uint8_t FAT_DAY(uint16_t fatDate) { |
108 |
return fatDate & 0X1F; |
109 |
} |
110 |
/** time field for FAT directory entry */
|
111 |
static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { |
112 |
return hour << 11 | minute << 5 | second >> 1; |
113 |
} |
114 |
/** hour part of FAT directory time field */
|
115 |
static inline uint8_t FAT_HOUR(uint16_t fatTime) { |
116 |
return fatTime >> 11; |
117 |
} |
118 |
/** minute part of FAT directory time field */
|
119 |
static inline uint8_t FAT_MINUTE(uint16_t fatTime) { |
120 |
return(fatTime >> 5) & 0X3F; |
121 |
} |
122 |
/** second part of FAT directory time field */
|
123 |
static inline uint8_t FAT_SECOND(uint16_t fatTime) { |
124 |
return 2*(fatTime & 0X1F); |
125 |
} |
126 |
/** Default date for file timestamps is 1 Jan 2000 */
|
127 |
uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; |
128 |
/** Default time for file timestamp is 1 am */
|
129 |
uint16_t const FAT_DEFAULT_TIME = (1 << 11); |
130 |
//------------------------------------------------------------------------------
|
131 |
/**
|
132 |
* \class SdFile
|
133 |
* \brief Access FAT16 and FAT32 files on SD and SDHC cards.
|
134 |
*/
|
135 |
class SdFile : public Print { |
136 |
public:
|
137 |
/** Create an instance of SdFile. */
|
138 |
SdFile(void) : type_(FAT_FILE_TYPE_CLOSED) {}
|
139 |
/**
|
140 |
* writeError is set to true if an error occurs during a write().
|
141 |
* Set writeError to false before calling print() and/or write() and check
|
142 |
* for true after calls to print() and/or write().
|
143 |
*/
|
144 |
//bool writeError;
|
145 |
/**
|
146 |
* Cancel unbuffered reads for this file.
|
147 |
* See setUnbufferedRead()
|
148 |
*/
|
149 |
void clearUnbufferedRead(void) { |
150 |
flags_ &= ~F_FILE_UNBUFFERED_READ; |
151 |
} |
152 |
uint8_t close(void);
|
153 |
uint8_t contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); |
154 |
uint8_t createContiguous(SdFile* dirFile, |
155 |
const char* fileName, uint32_t size); |
156 |
/** \return The current cluster number for a file or directory. */
|
157 |
uint32_t curCluster(void) const {return curCluster_;} |
158 |
/** \return The current position for a file or directory. */
|
159 |
uint32_t curPosition(void) const {return curPosition_;} |
160 |
/**
|
161 |
* Set the date/time callback function
|
162 |
*
|
163 |
* \param[in] dateTime The user's call back function. The callback
|
164 |
* function is of the form:
|
165 |
*
|
166 |
* \code
|
167 |
* void dateTime(uint16_t* date, uint16_t* time) {
|
168 |
* uint16_t year;
|
169 |
* uint8_t month, day, hour, minute, second;
|
170 |
*
|
171 |
* // User gets date and time from GPS or real-time clock here
|
172 |
*
|
173 |
* // return date using FAT_DATE macro to format fields
|
174 |
* *date = FAT_DATE(year, month, day);
|
175 |
*
|
176 |
* // return time using FAT_TIME macro to format fields
|
177 |
* *time = FAT_TIME(hour, minute, second);
|
178 |
* }
|
179 |
* \endcode
|
180 |
*
|
181 |
* Sets the function that is called when a file is created or when
|
182 |
* a file's directory entry is modified by sync(). All timestamps,
|
183 |
* access, creation, and modify, are set when a file is created.
|
184 |
* sync() maintains the last access date and last modify date/time.
|
185 |
*
|
186 |
* See the timestamp() function.
|
187 |
*/
|
188 |
static void dateTimeCallback( |
189 |
void (*dateTime)(uint16_t* date, uint16_t* time)) {
|
190 |
dateTime_ = dateTime; |
191 |
} |
192 |
/**
|
193 |
* Cancel the date/time callback function.
|
194 |
*/
|
195 |
static void dateTimeCallbackCancel(void) { |
196 |
// use explicit zero since NULL is not defined for Sanguino
|
197 |
dateTime_ = 0;
|
198 |
} |
199 |
/** \return Address of the block that contains this file's directory. */
|
200 |
uint32_t dirBlock(void) const {return dirBlock_;} |
201 |
uint8_t dirEntry(dir_t* dir); |
202 |
/** \return Index of this file's directory in the block dirBlock. */
|
203 |
uint8_t dirIndex(void) const {return dirIndex_;} |
204 |
static void dirName(const dir_t& dir, char* name); |
205 |
/** \return The total number of bytes in a file or directory. */
|
206 |
uint32_t fileSize(void) const {return fileSize_;} |
207 |
/** \return The first cluster number for a file or directory. */
|
208 |
uint32_t firstCluster(void) const {return firstCluster_;} |
209 |
/** \return True if this is a SdFile for a directory else false. */
|
210 |
uint8_t isDir(void) const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} |
211 |
/** \return True if this is a SdFile for a file else false. */
|
212 |
uint8_t isFile(void) const {return type_ == FAT_FILE_TYPE_NORMAL;} |
213 |
/** \return True if this is a SdFile for an open file/directory else false. */
|
214 |
uint8_t isOpen(void) const {return type_ != FAT_FILE_TYPE_CLOSED;} |
215 |
/** \return True if this is a SdFile for a subdirectory else false. */
|
216 |
uint8_t isSubDir(void) const {return type_ == FAT_FILE_TYPE_SUBDIR;} |
217 |
/** \return True if this is a SdFile for the root directory. */
|
218 |
uint8_t isRoot(void) const { |
219 |
return type_ == FAT_FILE_TYPE_ROOT16 || type_ == FAT_FILE_TYPE_ROOT32;
|
220 |
} |
221 |
void ls(uint8_t flags = 0, uint8_t indent = 0); |
222 |
uint8_t makeDir(SdFile* dir, const char* dirName); |
223 |
uint8_t open(SdFile* dirFile, uint16_t index, uint8_t oflag); |
224 |
uint8_t open(SdFile* dirFile, const char* fileName, uint8_t oflag); |
225 |
|
226 |
uint8_t openRoot(SdVolume* vol); |
227 |
static void printDirName(const dir_t& dir, uint8_t width); |
228 |
static void printFatDate(uint16_t fatDate); |
229 |
static void printFatTime(uint16_t fatTime); |
230 |
static void printTwoDigits(uint8_t v); |
231 |
/**
|
232 |
* Read the next byte from a file.
|
233 |
*
|
234 |
* \return For success read returns the next byte in the file as an int.
|
235 |
* If an error occurs or end of file is reached -1 is returned.
|
236 |
*/
|
237 |
int16_t read(void) {
|
238 |
uint8_t b; |
239 |
return read(&b, 1) == 1 ? b : -1; |
240 |
} |
241 |
int16_t read(void* buf, uint16_t nbyte);
|
242 |
int8_t readDir(dir_t* dir); |
243 |
static uint8_t remove(SdFile* dirFile, const char* fileName); |
244 |
uint8_t remove(void);
|
245 |
/** Set the file's current position to zero. */
|
246 |
void rewind(void) { |
247 |
curPosition_ = curCluster_ = 0;
|
248 |
} |
249 |
uint8_t rmDir(void);
|
250 |
uint8_t rmRfStar(void);
|
251 |
/** Set the files position to current position + \a pos. See seekSet(). */
|
252 |
uint8_t seekCur(uint32_t pos) { |
253 |
return seekSet(curPosition_ + pos);
|
254 |
} |
255 |
/**
|
256 |
* Set the files current position to end of file. Useful to position
|
257 |
* a file for append. See seekSet().
|
258 |
*/
|
259 |
uint8_t seekEnd(void) {return seekSet(fileSize_);} |
260 |
uint8_t seekSet(uint32_t pos); |
261 |
/**
|
262 |
* Use unbuffered reads to access this file. Used with Wave
|
263 |
* Shield ISR. Used with Sd2Card::partialBlockRead() in WaveRP.
|
264 |
*
|
265 |
* Not recommended for normal applications.
|
266 |
*/
|
267 |
void setUnbufferedRead(void) { |
268 |
if (isFile()) flags_ |= F_FILE_UNBUFFERED_READ;
|
269 |
} |
270 |
uint8_t timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, |
271 |
uint8_t hour, uint8_t minute, uint8_t second); |
272 |
uint8_t sync(void);
|
273 |
/** Type of this SdFile. You should use isFile() or isDir() instead of type()
|
274 |
* if possible.
|
275 |
*
|
276 |
* \return The file or directory type.
|
277 |
*/
|
278 |
uint8_t type(void) const {return type_;} |
279 |
uint8_t truncate(uint32_t size); |
280 |
/** \return Unbuffered read flag. */
|
281 |
uint8_t unbufferedRead(void) const { |
282 |
return flags_ & F_FILE_UNBUFFERED_READ;
|
283 |
} |
284 |
/** \return SdVolume that contains this file. */
|
285 |
SdVolume* volume(void) const {return vol_;} |
286 |
size_t write(uint8_t b); |
287 |
size_t write(const void* buf, uint16_t nbyte); |
288 |
size_t write(const char* str); |
289 |
void write_P(PGM_P str);
|
290 |
void writeln_P(PGM_P str);
|
291 |
//------------------------------------------------------------------------------
|
292 |
#if ALLOW_DEPRECATED_FUNCTIONS
|
293 |
// Deprecated functions - suppress cpplint warnings with NOLINT comment
|
294 |
/** \deprecated Use:
|
295 |
* uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
|
296 |
*/
|
297 |
uint8_t contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT
|
298 |
return contiguousRange(&bgnBlock, &endBlock);
|
299 |
} |
300 |
/** \deprecated Use:
|
301 |
* uint8_t SdFile::createContiguous(SdFile* dirFile,
|
302 |
* const char* fileName, uint32_t size)
|
303 |
*/
|
304 |
uint8_t createContiguous(SdFile& dirFile, // NOLINT
|
305 |
const char* fileName, uint32_t size) { |
306 |
return createContiguous(&dirFile, fileName, size);
|
307 |
} |
308 |
|
309 |
/**
|
310 |
* \deprecated Use:
|
311 |
* static void SdFile::dateTimeCallback(
|
312 |
* void (*dateTime)(uint16_t* date, uint16_t* time));
|
313 |
*/
|
314 |
static void dateTimeCallback( |
315 |
void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT |
316 |
oldDateTime_ = dateTime; |
317 |
dateTime_ = dateTime ? oldToNew : 0;
|
318 |
} |
319 |
/** \deprecated Use: uint8_t SdFile::dirEntry(dir_t* dir); */
|
320 |
uint8_t dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT |
321 |
/** \deprecated Use:
|
322 |
* uint8_t SdFile::makeDir(SdFile* dir, const char* dirName);
|
323 |
*/
|
324 |
uint8_t makeDir(SdFile& dir, const char* dirName) { // NOLINT |
325 |
return makeDir(&dir, dirName);
|
326 |
} |
327 |
/** \deprecated Use:
|
328 |
* uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag);
|
329 |
*/
|
330 |
uint8_t open(SdFile& dirFile, // NOLINT
|
331 |
const char* fileName, uint8_t oflag) { |
332 |
return open(&dirFile, fileName, oflag);
|
333 |
} |
334 |
/** \deprecated Do not use in new apps */
|
335 |
uint8_t open(SdFile& dirFile, const char* fileName) { // NOLINT |
336 |
return open(dirFile, fileName, O_RDWR);
|
337 |
} |
338 |
/** \deprecated Use:
|
339 |
* uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag);
|
340 |
*/
|
341 |
uint8_t open(SdFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT
|
342 |
return open(&dirFile, index, oflag);
|
343 |
} |
344 |
/** \deprecated Use: uint8_t SdFile::openRoot(SdVolume* vol); */
|
345 |
uint8_t openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT |
346 |
|
347 |
/** \deprecated Use: int8_t SdFile::readDir(dir_t* dir); */
|
348 |
int8_t readDir(dir_t& dir) {return readDir(&dir);} // NOLINT |
349 |
/** \deprecated Use:
|
350 |
* static uint8_t SdFile::remove(SdFile* dirFile, const char* fileName);
|
351 |
*/
|
352 |
static uint8_t remove(SdFile& dirFile, const char* fileName) { // NOLINT |
353 |
return remove(&dirFile, fileName);
|
354 |
} |
355 |
//------------------------------------------------------------------------------
|
356 |
// rest are private
|
357 |
private:
|
358 |
static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT |
359 |
static void oldToNew(uint16_t* date, uint16_t* time) { |
360 |
uint16_t d; |
361 |
uint16_t t; |
362 |
oldDateTime_(d, t); |
363 |
*date = d; |
364 |
*time = t; |
365 |
} |
366 |
#endif // ALLOW_DEPRECATED_FUNCTIONS |
367 |
private:
|
368 |
// bits defined in flags_
|
369 |
// should be 0XF
|
370 |
static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); |
371 |
// available bits
|
372 |
static uint8_t const F_UNUSED = 0X30; |
373 |
// use unbuffered SD read
|
374 |
static uint8_t const F_FILE_UNBUFFERED_READ = 0X40; |
375 |
// sync of directory entry required
|
376 |
static uint8_t const F_FILE_DIR_DIRTY = 0X80; |
377 |
|
378 |
// make sure F_OFLAG is ok
|
379 |
#if ((F_UNUSED | F_FILE_UNBUFFERED_READ | F_FILE_DIR_DIRTY) & F_OFLAG)
|
380 |
#error flags_ bits conflict
|
381 |
#endif // flags_ bits |
382 |
|
383 |
// private data
|
384 |
uint8_t flags_; // See above for definition of flags_ bits
|
385 |
uint8_t type_; // type of file see above for values
|
386 |
uint32_t curCluster_; // cluster for current file position
|
387 |
uint32_t curPosition_; // current file position in bytes from beginning
|
388 |
uint32_t dirBlock_; // SD block that contains directory entry for file
|
389 |
uint8_t dirIndex_; // index of entry in dirBlock 0 <= dirIndex_ <= 0XF
|
390 |
uint32_t fileSize_; // file size in bytes
|
391 |
uint32_t firstCluster_; // first cluster of file
|
392 |
SdVolume* vol_; // volume where file is located
|
393 |
|
394 |
// private functions
|
395 |
uint8_t addCluster(void);
|
396 |
uint8_t addDirCluster(void);
|
397 |
dir_t* cacheDirEntry(uint8_t action); |
398 |
static void (*dateTime_)(uint16_t* date, uint16_t* time); |
399 |
static uint8_t make83Name(const char* str, uint8_t* name); |
400 |
uint8_t openCachedEntry(uint8_t cacheIndex, uint8_t oflags); |
401 |
dir_t* readDirCache(void);
|
402 |
}; |
403 |
//==============================================================================
|
404 |
// SdVolume class
|
405 |
/**
|
406 |
* \brief Cache for an SD data block
|
407 |
*/
|
408 |
union cache_t {
|
409 |
/** Used to access cached file data blocks. */
|
410 |
uint8_t data[512];
|
411 |
/** Used to access cached FAT16 entries. */
|
412 |
uint16_t fat16[256];
|
413 |
/** Used to access cached FAT32 entries. */
|
414 |
uint32_t fat32[128];
|
415 |
/** Used to access cached directory entries. */
|
416 |
dir_t dir[16];
|
417 |
/** Used to access a cached MasterBoot Record. */
|
418 |
mbr_t mbr; |
419 |
/** Used to access to a cached FAT boot sector. */
|
420 |
fbs_t fbs; |
421 |
}; |
422 |
//------------------------------------------------------------------------------
|
423 |
/**
|
424 |
* \class SdVolume
|
425 |
* \brief Access FAT16 and FAT32 volumes on SD and SDHC cards.
|
426 |
*/
|
427 |
class SdVolume { |
428 |
public:
|
429 |
/** Create an instance of SdVolume */
|
430 |
SdVolume(void) :allocSearchStart_(2), fatType_(0) {} |
431 |
/** Clear the cache and returns a pointer to the cache. Used by the WaveRP
|
432 |
* recorder to do raw write to the SD card. Not for normal apps.
|
433 |
*/
|
434 |
static uint8_t* cacheClear(void) { |
435 |
cacheFlush(); |
436 |
cacheBlockNumber_ = 0XFFFFFFFF;
|
437 |
return cacheBuffer_.data;
|
438 |
} |
439 |
/**
|
440 |
* Initialize a FAT volume. Try partition one first then try super
|
441 |
* floppy format.
|
442 |
*
|
443 |
* \param[in] dev The Sd2Card where the volume is located.
|
444 |
*
|
445 |
* \return The value one, true, is returned for success and
|
446 |
* the value zero, false, is returned for failure. Reasons for
|
447 |
* failure include not finding a valid partition, not finding a valid
|
448 |
* FAT file system or an I/O error.
|
449 |
*/
|
450 |
uint8_t init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} |
451 |
uint8_t init(Sd2Card* dev, uint8_t part); |
452 |
|
453 |
// inline functions that return volume info
|
454 |
/** \return The volume's cluster size in blocks. */
|
455 |
uint8_t blocksPerCluster(void) const {return blocksPerCluster_;} |
456 |
/** \return The number of blocks in one FAT. */
|
457 |
uint32_t blocksPerFat(void) const {return blocksPerFat_;} |
458 |
/** \return The total number of clusters in the volume. */
|
459 |
uint32_t clusterCount(void) const {return clusterCount_;} |
460 |
/** \return The shift count required to multiply by blocksPerCluster. */
|
461 |
uint8_t clusterSizeShift(void) const {return clusterSizeShift_;} |
462 |
/** \return The logical block number for the start of file data. */
|
463 |
uint32_t dataStartBlock(void) const {return dataStartBlock_;} |
464 |
/** \return The number of FAT structures on the volume. */
|
465 |
uint8_t fatCount(void) const {return fatCount_;} |
466 |
/** \return The logical block number for the start of the first FAT. */
|
467 |
uint32_t fatStartBlock(void) const {return fatStartBlock_;} |
468 |
/** \return The FAT type of the volume. Values are 12, 16 or 32. */
|
469 |
uint8_t fatType(void) const {return fatType_;} |
470 |
/** \return The number of entries in the root directory for FAT16 volumes. */
|
471 |
uint32_t rootDirEntryCount(void) const {return rootDirEntryCount_;} |
472 |
/** \return The logical block number for the start of the root directory
|
473 |
on FAT16 volumes or the first cluster number on FAT32 volumes. */
|
474 |
uint32_t rootDirStart(void) const {return rootDirStart_;} |
475 |
/** return a pointer to the Sd2Card object for this volume */
|
476 |
static Sd2Card* sdCard(void) {return sdCard_;} |
477 |
//------------------------------------------------------------------------------
|
478 |
#if ALLOW_DEPRECATED_FUNCTIONS
|
479 |
// Deprecated functions - suppress cpplint warnings with NOLINT comment
|
480 |
/** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev); */
|
481 |
uint8_t init(Sd2Card& dev) {return init(&dev);} // NOLINT |
482 |
|
483 |
/** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev, uint8_t vol); */
|
484 |
uint8_t init(Sd2Card& dev, uint8_t part) { // NOLINT
|
485 |
return init(&dev, part);
|
486 |
} |
487 |
#endif // ALLOW_DEPRECATED_FUNCTIONS |
488 |
//------------------------------------------------------------------------------
|
489 |
private:
|
490 |
// Allow SdFile access to SdVolume private data.
|
491 |
friend class SdFile; |
492 |
|
493 |
// value for action argument in cacheRawBlock to indicate read from cache
|
494 |
static uint8_t const CACHE_FOR_READ = 0; |
495 |
// value for action argument in cacheRawBlock to indicate cache dirty
|
496 |
static uint8_t const CACHE_FOR_WRITE = 1; |
497 |
|
498 |
static cache_t cacheBuffer_; // 512 byte cache for device blocks |
499 |
static uint32_t cacheBlockNumber_; // Logical number of block in the cache |
500 |
static Sd2Card* sdCard_; // Sd2Card object for cache |
501 |
static uint8_t cacheDirty_; // cacheFlush() will write block if true |
502 |
static uint32_t cacheMirrorBlock_; // block number for mirror FAT |
503 |
//
|
504 |
uint32_t allocSearchStart_; // start cluster for alloc search
|
505 |
uint8_t blocksPerCluster_; // cluster size in blocks
|
506 |
uint32_t blocksPerFat_; // FAT size in blocks
|
507 |
uint32_t clusterCount_; // clusters in one FAT
|
508 |
uint8_t clusterSizeShift_; // shift to convert cluster count to block count
|
509 |
uint32_t dataStartBlock_; // first data block number
|
510 |
uint8_t fatCount_; // number of FATs on volume
|
511 |
uint32_t fatStartBlock_; // start block for first FAT
|
512 |
uint8_t fatType_; // volume type (12, 16, OR 32)
|
513 |
uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir
|
514 |
uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32
|
515 |
//----------------------------------------------------------------------------
|
516 |
uint8_t allocContiguous(uint32_t count, uint32_t* curCluster); |
517 |
uint8_t blockOfCluster(uint32_t position) const {
|
518 |
return (position >> 9) & (blocksPerCluster_ - 1);} |
519 |
uint32_t clusterStartBlock(uint32_t cluster) const {
|
520 |
return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);} |
521 |
uint32_t blockNumber(uint32_t cluster, uint32_t position) const {
|
522 |
return clusterStartBlock(cluster) + blockOfCluster(position);}
|
523 |
static uint8_t cacheFlush(void); |
524 |
static uint8_t cacheRawBlock(uint32_t blockNumber, uint8_t action);
|
525 |
static void cacheSetDirty(void) {cacheDirty_ |= CACHE_FOR_WRITE;} |
526 |
static uint8_t cacheZeroBlock(uint32_t blockNumber);
|
527 |
uint8_t chainSize(uint32_t beginCluster, uint32_t* size) const;
|
528 |
uint8_t fatGet(uint32_t cluster, uint32_t* value) const;
|
529 |
uint8_t fatPut(uint32_t cluster, uint32_t value); |
530 |
uint8_t fatPutEOC(uint32_t cluster) { |
531 |
return fatPut(cluster, 0x0FFFFFFF); |
532 |
} |
533 |
uint8_t freeChain(uint32_t cluster); |
534 |
uint8_t isEOC(uint32_t cluster) const {
|
535 |
return cluster >= (fatType_ == 16 ? FAT16EOC_MIN : FAT32EOC_MIN); |
536 |
} |
537 |
uint8_t readBlock(uint32_t block, uint8_t* dst) { |
538 |
return sdCard_->readBlock(block, dst);}
|
539 |
uint8_t readData(uint32_t block, uint16_t offset, |
540 |
uint16_t count, uint8_t* dst) { |
541 |
return sdCard_->readData(block, offset, count, dst);
|
542 |
} |
543 |
uint8_t writeBlock(uint32_t block, const uint8_t* dst) {
|
544 |
return sdCard_->writeBlock(block, dst);
|
545 |
} |
546 |
}; |
547 |
#endif // SdFat_h |