40#include "stream/Stream.h"
43#include "fatfs-drivers.h"
46#define FILE_READ FA_READ
47#define FILE_WRITE (FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_APPEND)
60class File :
public Stream {
70 virtual size_t write(uint8_t ch)
override {
71 if (fs ==
nullptr)
return 0;
72 int rc = fs->
f_putc(ch, &file);
73 return rc == EOF ? 0 : 1;
76 virtual size_t write(
const uint8_t *buf,
size_t size)
override {
77 if (fs ==
nullptr)
return 0;
79 FRESULT rc = fs->
f_write(&file, buf, size, &result);
80 return rc == FR_OK ? result : 0;
84 virtual int read()
override {
87 readBytes((uint8_t *)buf, 1);
88 return result == 1 ? buf[0] : -1;
93 uint32_t pos = position();
99 int available()
override {
return info.fsize - position(); }
101 int availableForWrite()
override {
return get_free_space(); }
103 void flush()
override {
104 if (!isDirectory()) fs->
f_sync(&file);
107 virtual size_t readBytes(uint8_t *data,
size_t len) {
108 if (isDirectory())
return 0;
110 auto rc = fs->
f_read(&file, data, len, &result);
111 return rc == FR_OK ? result : 0;
114 int read(
void *buf,
size_t nbyte) {
return readBytes((uint8_t *)buf, nbyte); }
116 bool seek(uint32_t pos) {
117 if (isDirectory())
return 0;
118 return fs->
f_lseek(&file, pos);
121 uint32_t position() {
122 if (isDirectory())
return 0;
123 return fs->f_tell(&file);
126 uint32_t size() {
return fs->f_size(&file); }
134 memset(&dir,0,
sizeof(dir));
135 memset(&file,0,
sizeof(file));
136 memset(&info, 0,
sizeof(info));
140 char *name() {
return info.fname; }
143 void getName(
char *name,
int len) { strncpy(name, info.fname, len); }
145 bool isDirectory(
void) {
return info.fattrib & AM_DIR; }
147 File openNextFile(uint8_t mode = FA_READ) {
149 FRESULT rc = fs->
f_findnext(&dir, &result.info);
151 result.is_open =
true;
152 if (!result.isDirectory()) {
153 fs->
f_open(&result.file, result.name(), mode);
155 fs->
f_opendir(&result.dir, result.name());
160 void rewindDirectory(
void) { fs->f_rewinddir(&dir); }
162 operator bool() {
return is_open && error() == 0; }
165 if (isDirectory())
return false;
166 return fs->f_eof(&file);
169 uint8_t error() {
return fs->f_error(&file); }
172 using Print::println;
176 FIL *
getFIL() {
return isDirectory() ? nullptr : &file; }
178 DIR *
getDIR() {
return isDirectory() ? &dir :
nullptr; }
189 bool is_open =
false;
193 is_open = fs->
f_stat(filepath, &info) == FR_OK;
197 size_t get_free_space() {
198#if FF_FS_MINIMIZE == 0
199 DWORD fre_clust, fre_sect;
203 auto res = fs->
f_getfree(
"", &fre_clust, &fatfs);
206#if FF_MAX_SS != FF_MIN_SS
207 size_t sector_size = fil.ssize;
209 size_t sector_size = FF_MAX_SS;
213 return (fre_clust * fatfs->csize) * sector_size;
215 return Stream::avaiableForWrite();
244 if (
getDriver() ==
nullptr)
return false;
245 return handleError(
getDriver()->mount(fat_fs));
250 bool begin(
int cs, SPIClass &spi = SPI) {
259 delete[] (work_buffer);
260 work_buffer =
nullptr;
266 File open(
const char *filename, uint8_t mode = FILE_READ) {
268 if (mode & FA_WRITE || file.update_stat(fat_fs, filename)) {
270 if (file.isDirectory()) {
271 result = fat_fs.
f_opendir(&file.dir, filename);
273 result = fat_fs.
f_open(&file.file, filename, mode);
275 file.is_open = handleError(result);
280 File open(
const String &filename, uint8_t mode = FILE_READ) {
281 return open(filename.c_str(), mode);
287 FRESULT rc = fat_fs.
f_stat(filepath, &info);
291 bool exists(
const String &filepath) {
return exists(filepath.c_str()); }
295 bool mkdir(
const char *filepath) {
return fat_fs.
f_mkdir(filepath) == FR_OK; }
296 bool mkdir(
const String &filepath) {
return mkdir(filepath.c_str()); }
300 return fat_fs.
f_unlink(filepath) == FR_OK;
302 bool remove(
const String &filepath) {
return remove(filepath.c_str()); }
304 bool rmdir(
const char *filepath) {
305 return fat_fs.
f_unlink(filepath) == FR_OK;
307 bool rmdir(
const String &filepath) {
return rmdir(filepath.c_str()); }
309#if FF_ARDUINO_LEVEL == 1
311 bool chdir(
const char *filepath) {
return fat_fs.
f_chdir(filepath) == FR_OK; }
313 bool chdir(String filepath) {
return chdir(filepath.c_str()); }
317 return fat_fs.
f_getcwd(buff, len) == FR_OK;
322 bool mkfs(
int workBufferSize = FF_MAX_SS) {
323 if (work_buffer ==
nullptr) work_buffer =
new uint8_t[workBufferSize];
324 return handleError(fat_fs.
f_mkfs(
"",
nullptr, work_buffer, workBufferSize));
328#if FF_FS_MINIMIZE == 0
330 size_t free() {
return File(&fat_fs).availableForWrite(); }
349 uint8_t *work_buffer =
nullptr;
351 bool handleError(FRESULT rc) {
353 Serial.print(
"fatfs: error no: ");
354 Serial.println((
int)rc);
360#if FF_ARDUINO_LEVEL == 0
362 void setDriver(
IO &driver) { fat_fs.setDriver(driver); }
375using namespace fatfs;
Accessing a SD card via the Arduino SPI API.
Definition ArduinoSpiIO.h:41
API for FatFS See http://elm-chan.org/fsw/ff/00index_e.html.
Definition ff.h:34
FRESULT f_close(FIL *fp)
Definition ff-inc.h:4071
FRESULT f_getcwd(TCHAR *buff, UINT len)
FRESULT f_findnext(DIR *dp, FILINFO *fno)
FRESULT f_stat(const TCHAR *path, FILINFO *fno)
Definition ff-inc.h:4631
FRESULT f_opendir(DIR *dp, const TCHAR *path)
Definition ff-inc.h:4449
FRESULT f_unlink(const TCHAR *path)
Definition ff-inc.h:4806
FRESULT f_getfree(const TCHAR *path, DWORD *nclst, FATFS **fatfs)
Definition ff-inc.h:4666
FRESULT f_sync(FIL *fp)
Definition ff-inc.h:3990
FRESULT f_mkfs(const TCHAR *path, const MKFS_PARM *opt, void *work, UINT len)
Definition ff-inc.h:5714
FRESULT f_lseek(FIL *fp, FSIZE_t ofs)
Definition ff-inc.h:4286
FRESULT f_write(FIL *fp, const void *buff, UINT btw, UINT *bw)
Definition ff-inc.h:3868
FRESULT f_read(FIL *fp, void *buff, UINT btr, UINT *br)
Definition ff-inc.h:3767
FRESULT f_chdir(const TCHAR *path)
FRESULT f_mkdir(const TCHAR *path)
Definition ff-inc.h:4900
FRESULT f_closedir(DIR *dp)
Definition ff-inc.h:4515
int f_putc(TCHAR c, FIL *fp)
Definition ff-inc.h:6536
FRESULT f_open(FIL *fp, const TCHAR *path, BYTE mode)
Definition ff-inc.h:3575
IO * getDriver()
Definition ff.h:40
File implementation for fatfs.
Definition fatfs.h:60
int peek() override
Rather inefficient: to be avoided.
Definition fatfs.h:92
void getName(char *name, int len)
Provides the name: getName() is supported by the SDFat Library.
Definition fatfs.h:143
FatFs * getFatFs()
Access to low level FatFS api to use functionality not exposed by this API.
Definition fatfs.h:180
FIL * getFIL()
Access to low level FatFS api.
Definition fatfs.h:176
DIR * getDIR()
Access to low level FatFS api.
Definition fatfs.h:178
bool update_stat(FatFs &fat_fs, const char *filepath)
update fs, info and is_open
Definition fatfs.h:192
IO * getDriver()
Access lo low level driver.
Definition fatfs.h:182
virtual int read() override
Rather inefficient: to be avoided.
Definition fatfs.h:84
FatFS interface definition.
Definition IO.h:74
virtual FRESULT un_mount(FatFs &fs)
unmount the file system - implementation at end of header to avoid recursive include
Definition IO.h:101
SDClass: starting driver, access to files.
Definition fatfs.h:225
bool chdir(const char *filepath)
Change directoy: extended functionality not available in Arduino SD API.
Definition fatfs.h:311
void setDriver(IO &driver)
Set the driver.
Definition fatfs.h:337
void end()
Definition fatfs.h:257
bool mkdir(const char *filepath)
Definition fatfs.h:295
bool chdir(String filepath)
Change directoy: extended functionality not available in Arduino SD API.
Definition fatfs.h:313
bool begin(IO &driver)
Initialization of SD card: Use before other methods.
Definition fatfs.h:236
FatFs * getFatFs()
Access to low level FatFS api to use functionality not exposed by this API.
Definition fatfs.h:334
bool mkfs(int workBufferSize=FF_MAX_SS)
format drive
Definition fatfs.h:322
File open(const char *filename, uint8_t mode=FILE_READ)
Definition fatfs.h:266
bool getcwd(char *buff, size_t len)
Definition fatfs.h:316
bool exists(const char *filepath)
Methods to determine if the requested file path exists.
Definition fatfs.h:285
size_t free()
get free space in bytes
Definition fatfs.h:330
bool begin(int cs, SPIClass &spi=SPI)
Compatibility with SD library: we use the Arduino SPI SD driver.
Definition fatfs.h:250
IO * getDriver()
Access lo low level driver.
Definition fatfs.h:340
bool begin()
Initialization of SD card. We use the SPI SD driver if nothing has been defined in the constructor.
Definition fatfs.h:243
bool remove(const char *filepath)
Delete the file.
Definition fatfs.h:299