My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SdBaseFile.h 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * \file
  24. * \brief SdBaseFile class
  25. */
  26. /**
  27. * Arduino SdFat Library
  28. * Copyright (C) 2009 by William Greiman
  29. *
  30. * This file is part of the Arduino Sd2Card Library
  31. */
  32. #ifndef _SDBASEFILE_H_
  33. #define _SDBASEFILE_H_
  34. #include "SdFatConfig.h"
  35. #include "SdVolume.h"
  36. /**
  37. * \struct filepos_t
  38. * \brief internal type for istream
  39. * do not use in user apps
  40. */
  41. struct filepos_t {
  42. uint32_t position; // stream byte position
  43. uint32_t cluster; // cluster of position
  44. filepos_t() : position(0), cluster(0) {}
  45. };
  46. // use the gnu style oflag in open()
  47. uint8_t const O_READ = 0x01, // open() oflag for reading
  48. O_RDONLY = O_READ, // open() oflag - same as O_IN
  49. O_WRITE = 0x02, // open() oflag for write
  50. O_WRONLY = O_WRITE, // open() oflag - same as O_WRITE
  51. O_RDWR = (O_READ | O_WRITE), // open() oflag for reading and writing
  52. O_ACCMODE = (O_READ | O_WRITE), // open() oflag mask for access modes
  53. O_APPEND = 0x04, // The file offset shall be set to the end of the file prior to each write.
  54. O_SYNC = 0x08, // Synchronous writes - call sync() after each write
  55. O_TRUNC = 0x10, // Truncate the file to zero length
  56. O_AT_END = 0x20, // Set the initial position at the end of the file
  57. O_CREAT = 0x40, // Create the file if nonexistent
  58. O_EXCL = 0x80; // If O_CREAT and O_EXCL are set, open() shall fail if the file exists
  59. // SdBaseFile class static and const definitions
  60. // flags for ls()
  61. uint8_t const LS_DATE = 1, // ls() flag to print modify date
  62. LS_SIZE = 2, // ls() flag to print file size
  63. LS_R = 4; // ls() flag for recursive list of subdirectories
  64. // flags for timestamp
  65. uint8_t const T_ACCESS = 1, // Set the file's last access date
  66. T_CREATE = 2, // Set the file's creation date and time
  67. T_WRITE = 4; // Set the file's write date and time
  68. // values for type_
  69. uint8_t const FAT_FILE_TYPE_CLOSED = 0, // This file has not been opened.
  70. FAT_FILE_TYPE_NORMAL = 1, // A normal file
  71. FAT_FILE_TYPE_ROOT_FIXED = 2, // A FAT12 or FAT16 root directory
  72. FAT_FILE_TYPE_ROOT32 = 3, // A FAT32 root directory
  73. FAT_FILE_TYPE_SUBDIR = 4, // A subdirectory file
  74. FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED; // Test value for directory type
  75. /**
  76. * date field for FAT directory entry
  77. * \param[in] year [1980,2107]
  78. * \param[in] month [1,12]
  79. * \param[in] day [1,31]
  80. *
  81. * \return Packed date for dir_t entry.
  82. */
  83. static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { return (year - 1980) << 9 | month << 5 | day; }
  84. /**
  85. * year part of FAT directory date field
  86. * \param[in] fatDate Date in packed dir format.
  87. *
  88. * \return Extracted year [1980,2107]
  89. */
  90. static inline uint16_t FAT_YEAR(uint16_t fatDate) { return 1980 + (fatDate >> 9); }
  91. /**
  92. * month part of FAT directory date field
  93. * \param[in] fatDate Date in packed dir format.
  94. *
  95. * \return Extracted month [1,12]
  96. */
  97. static inline uint8_t FAT_MONTH(uint16_t fatDate) { return (fatDate >> 5) & 0XF; }
  98. /**
  99. * day part of FAT directory date field
  100. * \param[in] fatDate Date in packed dir format.
  101. *
  102. * \return Extracted day [1,31]
  103. */
  104. static inline uint8_t FAT_DAY(uint16_t fatDate) { return fatDate & 0x1F; }
  105. /**
  106. * time field for FAT directory entry
  107. * \param[in] hour [0,23]
  108. * \param[in] minute [0,59]
  109. * \param[in] second [0,59]
  110. *
  111. * \return Packed time for dir_t entry.
  112. */
  113. static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { return hour << 11 | minute << 5 | second >> 1; }
  114. /**
  115. * hour part of FAT directory time field
  116. * \param[in] fatTime Time in packed dir format.
  117. *
  118. * \return Extracted hour [0,23]
  119. */
  120. static inline uint8_t FAT_HOUR(uint16_t fatTime) { return fatTime >> 11; }
  121. /**
  122. * minute part of FAT directory time field
  123. * \param[in] fatTime Time in packed dir format.
  124. *
  125. * \return Extracted minute [0,59]
  126. */
  127. static inline uint8_t FAT_MINUTE(uint16_t fatTime) { return (fatTime >> 5) & 0x3F; }
  128. /**
  129. * second part of FAT directory time field
  130. * Note second/2 is stored in packed time.
  131. *
  132. * \param[in] fatTime Time in packed dir format.
  133. *
  134. * \return Extracted second [0,58]
  135. */
  136. static inline uint8_t FAT_SECOND(uint16_t fatTime) { return 2 * (fatTime & 0x1F); }
  137. // Default date for file timestamps is 1 Jan 2000
  138. uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1;
  139. // Default time for file timestamp is 1 am
  140. uint16_t const FAT_DEFAULT_TIME = (1 << 11);
  141. /**
  142. * \class SdBaseFile
  143. * \brief Base class for SdFile with Print and C++ streams.
  144. */
  145. class SdBaseFile {
  146. public:
  147. SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {}
  148. SdBaseFile(const char* path, uint8_t oflag);
  149. ~SdBaseFile() { if (isOpen()) close(); }
  150. /**
  151. * writeError is set to true if an error occurs during a write().
  152. * Set writeError to false before calling print() and/or write() and check
  153. * for true after calls to print() and/or write().
  154. */
  155. bool writeError;
  156. // helpers for stream classes
  157. /**
  158. * get position for streams
  159. * \param[out] pos struct to receive position
  160. */
  161. void getpos(filepos_t* pos);
  162. /**
  163. * set position for streams
  164. * \param[out] pos struct with value for new position
  165. */
  166. void setpos(filepos_t* pos);
  167. bool close();
  168. bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
  169. bool createContiguous(SdBaseFile* dirFile,
  170. const char* path, uint32_t size);
  171. /**
  172. * \return The current cluster number for a file or directory.
  173. */
  174. uint32_t curCluster() const { return curCluster_; }
  175. /**
  176. * \return The current position for a file or directory.
  177. */
  178. uint32_t curPosition() const { return curPosition_; }
  179. /**
  180. * \return Current working directory
  181. */
  182. static SdBaseFile* cwd() { return cwd_; }
  183. /**
  184. * Set the date/time callback function
  185. *
  186. * \param[in] dateTime The user's call back function. The callback
  187. * function is of the form:
  188. *
  189. * \code
  190. * void dateTime(uint16_t* date, uint16_t* time) {
  191. * uint16_t year;
  192. * uint8_t month, day, hour, minute, second;
  193. *
  194. * // User gets date and time from GPS or real-time clock here
  195. *
  196. * // return date using FAT_DATE macro to format fields
  197. * *date = FAT_DATE(year, month, day);
  198. *
  199. * // return time using FAT_TIME macro to format fields
  200. * *time = FAT_TIME(hour, minute, second);
  201. * }
  202. * \endcode
  203. *
  204. * Sets the function that is called when a file is created or when
  205. * a file's directory entry is modified by sync(). All timestamps,
  206. * access, creation, and modify, are set when a file is created.
  207. * sync() maintains the last access date and last modify date/time.
  208. *
  209. * See the timestamp() function.
  210. */
  211. static void dateTimeCallback(
  212. void (*dateTime)(uint16_t* date, uint16_t* time)) {
  213. dateTime_ = dateTime;
  214. }
  215. /**
  216. * Cancel the date/time callback function.
  217. */
  218. static void dateTimeCallbackCancel() { dateTime_ = 0; }
  219. bool dirEntry(dir_t* dir);
  220. static void dirName(const dir_t& dir, char* name);
  221. bool exists(const char* name);
  222. int16_t fgets(char* str, int16_t num, char* delim = 0);
  223. /**
  224. * \return The total number of bytes in a file or directory.
  225. */
  226. uint32_t fileSize() const { return fileSize_; }
  227. /**
  228. * \return The first cluster number for a file or directory.
  229. */
  230. uint32_t firstCluster() const { return firstCluster_; }
  231. /**
  232. * \return True if this is a directory else false.
  233. */
  234. bool isDir() const { return type_ >= FAT_FILE_TYPE_MIN_DIR; }
  235. /**
  236. * \return True if this is a normal file else false.
  237. */
  238. bool isFile() const { return type_ == FAT_FILE_TYPE_NORMAL; }
  239. /**
  240. * \return True if this is an open file/directory else false.
  241. */
  242. bool isOpen() const { return type_ != FAT_FILE_TYPE_CLOSED; }
  243. /**
  244. * \return True if this is a subdirectory else false.
  245. */
  246. bool isSubDir() const { return type_ == FAT_FILE_TYPE_SUBDIR; }
  247. /**
  248. * \return True if this is the root directory.
  249. */
  250. bool isRoot() const { return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32; }
  251. bool getFilename(char * const name);
  252. void ls(uint8_t flags = 0, uint8_t indent = 0);
  253. bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true);
  254. bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag);
  255. bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag);
  256. bool open(const char* path, uint8_t oflag = O_READ);
  257. bool openNext(SdBaseFile* dirFile, uint8_t oflag);
  258. bool openRoot(SdVolume* vol);
  259. int peek();
  260. static void printFatDate(uint16_t fatDate);
  261. static void printFatTime(uint16_t fatTime);
  262. bool printName();
  263. int16_t read();
  264. int16_t read(void* buf, uint16_t nbyte);
  265. int8_t readDir(dir_t* dir, char* longFilename);
  266. static bool remove(SdBaseFile* dirFile, const char* path);
  267. bool remove();
  268. /**
  269. * Set the file's current position to zero.
  270. */
  271. void rewind() { seekSet(0); }
  272. bool rename(SdBaseFile* dirFile, const char* newPath);
  273. bool rmdir();
  274. bool rmRfStar();
  275. /**
  276. * Set the files position to current position + \a pos. See seekSet().
  277. * \param[in] offset The new position in bytes from the current position.
  278. * \return true for success or false for failure.
  279. */
  280. bool seekCur(const int32_t offset) { return seekSet(curPosition_ + offset); }
  281. /**
  282. * Set the files position to end-of-file + \a offset. See seekSet().
  283. * \param[in] offset The new position in bytes from end-of-file.
  284. * \return true for success or false for failure.
  285. */
  286. bool seekEnd(const int32_t offset = 0) { return seekSet(fileSize_ + offset); }
  287. bool seekSet(const uint32_t pos);
  288. bool sync();
  289. bool timestamp(SdBaseFile* file);
  290. bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day,
  291. uint8_t hour, uint8_t minute, uint8_t second);
  292. /**
  293. * Type of file. Use isFile() or isDir() instead of type() if possible.
  294. *
  295. * \return The file or directory type.
  296. */
  297. uint8_t type() const { return type_; }
  298. bool truncate(uint32_t size);
  299. /**
  300. * \return SdVolume that contains this file.
  301. */
  302. SdVolume* volume() const { return vol_; }
  303. int16_t write(const void* buf, uint16_t nbyte);
  304. private:
  305. friend class SdFat; // allow SdFat to set cwd_
  306. static SdBaseFile* cwd_; // global pointer to cwd dir
  307. // data time callback function
  308. static void (*dateTime_)(uint16_t* date, uint16_t* time);
  309. // bits defined in flags_
  310. static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC), // should be 0x0F
  311. F_FILE_DIR_DIRTY = 0x80; // sync of directory entry required
  312. // private data
  313. uint8_t flags_; // See above for definition of flags_ bits
  314. uint8_t fstate_; // error and eof indicator
  315. uint8_t type_; // type of file see above for values
  316. uint32_t curCluster_; // cluster for current file position
  317. uint32_t curPosition_; // current file position in bytes from beginning
  318. uint32_t dirBlock_; // block for this files directory entry
  319. uint8_t dirIndex_; // index of directory entry in dirBlock
  320. uint32_t fileSize_; // file size in bytes
  321. uint32_t firstCluster_; // first cluster of file
  322. SdVolume* vol_; // volume where file is located
  323. /**
  324. * EXPERIMENTAL - Don't use!
  325. */
  326. //bool openParent(SdBaseFile* dir);
  327. // private functions
  328. bool addCluster();
  329. bool addDirCluster();
  330. dir_t* cacheDirEntry(uint8_t action);
  331. int8_t lsPrintNext(uint8_t flags, uint8_t indent);
  332. static bool make83Name(const char* str, uint8_t* name, const char** ptr);
  333. bool mkdir(SdBaseFile* parent, const uint8_t dname[11]);
  334. bool open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag);
  335. bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags);
  336. dir_t* readDirCache();
  337. // Deprecated functions
  338. #if ALLOW_DEPRECATED_FUNCTIONS
  339. public:
  340. /**
  341. * \deprecated Use:
  342. * bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
  343. * \param[out] bgnBlock the first block address for the file.
  344. * \param[out] endBlock the last block address for the file.
  345. * \return true for success or false for failure.
  346. */
  347. bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) {
  348. return contiguousRange(&bgnBlock, &endBlock);
  349. }
  350. /**
  351. * \deprecated Use:
  352. * bool createContiguous(SdBaseFile* dirFile, const char* path, uint32_t size)
  353. * \param[in] dirFile The directory where the file will be created.
  354. * \param[in] path A path with a valid DOS 8.3 file name.
  355. * \param[in] size The desired file size.
  356. * \return true for success or false for failure.
  357. */
  358. bool createContiguous(SdBaseFile& dirFile, const char* path, uint32_t size) {
  359. return createContiguous(&dirFile, path, size);
  360. }
  361. /**
  362. * \deprecated Use:
  363. * static void dateTimeCallback(
  364. * void (*dateTime)(uint16_t* date, uint16_t* time));
  365. * \param[in] dateTime The user's call back function.
  366. */
  367. static void dateTimeCallback(
  368. void (*dateTime)(uint16_t &date, uint16_t &time)) {
  369. oldDateTime_ = dateTime;
  370. dateTime_ = dateTime ? oldToNew : 0;
  371. }
  372. /**
  373. * \deprecated Use:
  374. * bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag);
  375. * \param[in] dirFile An open SdFat instance for the directory containing the
  376. * file to be opened.
  377. * \param[in] path A path with a valid 8.3 DOS name for the file.
  378. * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
  379. * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC.
  380. * \return true for success or false for failure.
  381. */
  382. bool open(SdBaseFile& dirFile, const char* path, uint8_t oflag) {
  383. return open(&dirFile, path, oflag);
  384. }
  385. /**
  386. * \deprecated Do not use in new apps
  387. * \param[in] dirFile An open SdFat instance for the directory containing the
  388. * file to be opened.
  389. * \param[in] path A path with a valid 8.3 DOS name for a file to be opened.
  390. * \return true for success or false for failure.
  391. */
  392. bool open(SdBaseFile& dirFile, const char* path) {
  393. return open(dirFile, path, O_RDWR);
  394. }
  395. /**
  396. * \deprecated Use:
  397. * bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag);
  398. * \param[in] dirFile An open SdFat instance for the directory.
  399. * \param[in] index The \a index of the directory entry for the file to be
  400. * opened. The value for \a index is (directory file position)/32.
  401. * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
  402. * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC.
  403. * \return true for success or false for failure.
  404. */
  405. bool open(SdBaseFile& dirFile, uint16_t index, uint8_t oflag) {
  406. return open(&dirFile, index, oflag);
  407. }
  408. /**
  409. * \deprecated Use: bool openRoot(SdVolume* vol);
  410. * \param[in] vol The FAT volume containing the root directory to be opened.
  411. * \return true for success or false for failure.
  412. */
  413. bool openRoot(SdVolume& vol) { return openRoot(&vol); }
  414. /**
  415. * \deprecated Use: int8_t readDir(dir_t* dir);
  416. * \param[out] dir The dir_t struct that will receive the data.
  417. * \return bytes read for success zero for eof or -1 for failure.
  418. */
  419. int8_t readDir(dir_t& dir, char* longFilename) {
  420. return readDir(&dir, longFilename);
  421. }
  422. /**
  423. * \deprecated Use:
  424. * static uint8_t remove(SdBaseFile* dirFile, const char* path);
  425. * \param[in] dirFile The directory that contains the file.
  426. * \param[in] path The name of the file to be removed.
  427. * \return true for success or false for failure.
  428. */
  429. static bool remove(SdBaseFile& dirFile, const char* path) { return remove(&dirFile, path); }
  430. private:
  431. static void (*oldDateTime_)(uint16_t &date, uint16_t &time);
  432. static void oldToNew(uint16_t * const date, uint16_t * const time) {
  433. uint16_t d, t;
  434. oldDateTime_(d, t);
  435. *date = d;
  436. *time = t;
  437. }
  438. #endif // ALLOW_DEPRECATED_FUNCTIONS
  439. };
  440. #endif // _SDBASEFILE_H_