X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Ffs%2Ffat.c;fp=bertos%2Ffs%2Ffat.c;h=aca2fa30d4a9078e504a4cb2a724b0d382fe10fc;hb=b65e60edaa04a0d0bec335198d7cf2279f3a22ae;hp=0000000000000000000000000000000000000000;hpb=0774f0adbb7c85ab48bc4ba83e3c0473f68bd73b;p=bertos.git diff --git a/bertos/fs/fat.c b/bertos/fs/fat.c new file mode 100644 index 00000000..aca2fa30 --- /dev/null +++ b/bertos/fs/fat.c @@ -0,0 +1,150 @@ +/** + * \file + * + * + * \brief FatFS: kfile interface for FatFS module by ChaN. + * + * \version $Id$ + * + * \author Luca Ottaviano + * + */ + +#include "fat.h" + +static size_t fatfile_read(struct KFile *_fd, void *buf, size_t size) +{ + FatFile *fd = FATFILE_CAST(_fd); + UINT count; + fd->error_code = f_read(&fd->fat_file, buf, size, &count); + return count; +} + +static size_t fatfile_write(struct KFile *_fd, const void *buf, size_t size) +{ + FatFile *fd = FATFILE_CAST(_fd); + UINT count; + fd->error_code = f_write(&fd->fat_file, buf, size, &count); + return count; +} + +static int fatfile_close(struct KFile *_fd) +{ + FatFile *fd = FATFILE_CAST(_fd); + fd->error_code = f_close(&fd->fat_file); + if (fd->error_code) + return EOF; + else + return 0; +} + +static kfile_off_t fatfile_seek(struct KFile *_fd, kfile_off_t offset, KSeekMode whence) +{ + /* clip at start-of-file + * don't clip at end-of-file when in write mode + */ + FatFile *fd = FATFILE_CAST(_fd); + DWORD lseek_offset; + switch (whence) + { + case KSM_SEEK_SET: + if (offset > 0) + lseek_offset = (DWORD) offset; + else + lseek_offset = 0; + break; + case KSM_SEEK_CUR: + if (offset > 0) + lseek_offset = fd->fat_file.fptr + (DWORD) offset; + else + { + if (fd->fat_file.fptr > (DWORD) (-offset)) + lseek_offset = fd->fat_file.fptr - (DWORD)(-offset); + else + lseek_offset = 0; + } + break; + case KSM_SEEK_END: + if (offset > 0) + lseek_offset = fd->fat_file.fsize + (DWORD) offset; + else + { + if (fd->fat_file.fsize > (DWORD) (-offset)) + lseek_offset = fd->fat_file.fsize + (DWORD) offset; + else + lseek_offset = 0; + } + break; + } + fd->error_code = f_lseek(&fd->fat_file, lseek_offset); + if ((fd->error_code) || (fd->fat_file.fptr != lseek_offset)) + return EOF; + else + /* TODO: this conversion may overflow */ + return (kfile_off_t)fd->fat_file.fptr; +} + +static int fatfile_flush(struct KFile *_fd) +{ + FatFile *fd = FATFILE_CAST(_fd); + fd->error_code = f_sync(&fd->fat_file); + if (fd->error_code) + return EOF; + else + return 0; +} + +static int fatfile_error(struct KFile *_fd) +{ + FatFile *fd = FATFILE_CAST(_fd); + return (int)fd->error_code; +} + +static void fatfile_clearerr(struct KFile *_fd) +{ + FatFile *fd = FATFILE_CAST(_fd); + fd->error_code = FR_OK; +} + +FRESULT fatfile_open(FatFile *file, const char *file_path, BYTE mode) +{ + file->fd._type = KFT_FATFILE; + file->fd.read = fatfile_read; + file->fd.write = fatfile_write; + file->fd.reopen = 0; + file->fd.close = fatfile_close; + file->fd.seek = fatfile_seek; + file->fd.flush = fatfile_flush; + file->fd.error = fatfile_error; + file->fd.clearerr = fatfile_clearerr; + return f_open(&file->fat_file, file_path, mode); +} +