ugfx/src/gfile/inc_fatfs.c

246 lines
4.4 KiB
C
Raw Normal View History

2014-01-04 14:02:53 +00:00
/*
* This file is subject to the terms of the GFX License. If a copy of
* the license was not distributed with this file, you can obtain one at:
*
* http://ugfx.org/license.html
*/
/**
* This file is included by src/gfile/gfile.c
*/
2014-06-25 03:23:57 +00:00
#include "ff.h"
#include "ffconf.h"
2014-01-04 14:02:53 +00:00
/********************************************************
* The FAT file-system VMT
********************************************************/
2014-06-24 03:56:13 +00:00
static bool_t fatfsDel(const char* fname);
static bool_t fatfsExists(const char* fname);
static long int fatfsFileSize(const char* fname);
static bool_t fatfsRename(const char* oldname, const char* newname);
static bool_t fatfsOpen(GFILE* f, const char* fname);
static void fatfsClose(GFILE* f);
static int fatfsRead(GFILE* f, void* buf, int size);
static int fatfsWrite(GFILE* f, const void* buf, int size);
static bool_t fatfsSetPos(GFILE* f, long int pos);
static long int fatfsGetSize(GFILE* f);
static bool_t fatfsEOF(GFILE* f);
2014-06-27 04:10:18 +00:00
static bool_t fatfsMount(const char* drive);
static bool_t fatfsUnmount(const char* drive);
2014-06-29 14:15:46 +00:00
static bool_t fatfsSync(GFILE* f);
2014-06-24 03:56:13 +00:00
static const GFILEVMT FsFatFSVMT = {
GFILE_CHAINHEAD,
GFSFLG_WRITEABLE | GFSFLG_SEEKABLE,
2014-06-24 03:56:13 +00:00
'F',
fatfsDel,
fatfsExists,
fatfsFileSize,
fatfsRename,
fatfsOpen,
fatfsClose,
fatfsRead,
fatfsWrite,
fatfsSetPos,
fatfsGetSize,
2014-06-27 04:10:18 +00:00
fatfsEOF,
fatfsMount,
2014-06-29 14:15:46 +00:00
fatfsUnmount,
fatfsSync
2014-06-24 03:56:13 +00:00
};
#undef GFILE_CHAINHEAD
#define GFILE_CHAINHEAD &FsFatFSVMT
2014-06-27 04:10:18 +00:00
// optimize these later on. Use an array to have multiple FatFS
static bool_t fatfs_mounted = FALSE;
static FATFS fatfs_fs;
2014-06-27 13:04:01 +00:00
static BYTE fatfs_flags2mode(GFILE* f)
2014-06-25 03:23:57 +00:00
{
2014-06-27 13:04:01 +00:00
BYTE mode = 0;
2014-06-25 03:23:57 +00:00
if (f->flags & GFILEFLG_READ)
2014-06-27 13:04:01 +00:00
mode |= FA_READ;
if (f->flags & GFILEFLG_WRITE)
2014-06-27 13:04:01 +00:00
mode |= FA_WRITE;
if (f->flags & GFILEFLG_APPEND)
2014-06-27 13:04:01 +00:00
mode |= 0; // ToDo
if (f->flags & GFILEFLG_TRUNC)
2014-06-27 13:04:01 +00:00
mode |= FA_CREATE_ALWAYS;
2014-06-25 03:23:57 +00:00
2014-06-27 13:04:01 +00:00
/* ToDo - Complete */
return mode;
2014-06-25 03:23:57 +00:00
}
2014-06-24 03:56:13 +00:00
static bool_t fatfsDel(const char* fname)
{
2014-06-25 03:23:57 +00:00
FRESULT ferr;
ferr = f_unlink( (const TCHAR*)fname );
if (ferr != FR_OK)
return FALSE;
2014-06-24 03:56:13 +00:00
2014-06-25 03:23:57 +00:00
return TRUE;
2014-06-24 03:56:13 +00:00
}
static bool_t fatfsExists(const char* fname)
{
FRESULT ferr;
FILINFO fno;
2014-06-25 03:23:57 +00:00
ferr = f_stat( (const TCHAR*)fname, &fno);
if (ferr != FR_OK)
return FALSE;
2014-06-24 03:56:13 +00:00
2014-06-25 03:23:57 +00:00
return TRUE;
2014-06-24 03:56:13 +00:00
}
static long int fatfsFileSize(const char* fname)
{
2014-06-25 03:23:57 +00:00
FRESULT ferr;
FILINFO fno;
2014-06-24 03:56:13 +00:00
2014-06-25 03:23:57 +00:00
ferr = f_stat( (const TCHAR*)fname, &fno );
if (ferr != FR_OK)
return 0;
return (long int)fno.fsize;
2014-06-24 03:56:13 +00:00
}
static bool_t fatfsRename(const char* oldname, const char* newname)
{
2014-06-25 03:23:57 +00:00
FRESULT ferr;
ferr = f_rename( (const TCHAR*)oldname, (const TCHAR*)newname );
if (ferr != FR_OK)
return FALSE;
2014-06-24 03:56:13 +00:00
2014-06-25 03:23:57 +00:00
return TRUE;
2014-06-24 03:56:13 +00:00
}
static bool_t fatfsOpen(GFILE* f, const char* fname)
{
FIL* fd;
2014-06-27 13:04:01 +00:00
#if !GFILE_NEED_NOAUTOMOUNT
if (!fatfs_mounted && !fatfsMount(""))
return FALSE;
#endif
if (!(fd = gfxAlloc(sizeof(FIL))))
return FALSE;
2014-06-27 13:04:01 +00:00
if (f_open(fd, fname, fatfs_flags2mode(f)) != FR_OK) {
2014-06-27 04:10:18 +00:00
gfxFree(fd);
f->obj = 0;
2014-06-25 03:23:57 +00:00
return FALSE;
}
2014-06-25 03:23:57 +00:00
f->obj = (void*)fd;
2014-06-29 14:15:46 +00:00
#if !GFILE_NEED_NOAUTOSYNC
// no need to sync when not opening for write
if (f->flags & GFILEFLG_WRITE) {
f_sync( (FIL*)f->obj );
}
#endif
2014-06-25 03:23:57 +00:00
return TRUE;
2014-06-24 03:56:13 +00:00
}
static void fatfsClose(GFILE* f)
{
2014-06-27 04:10:18 +00:00
if ((FIL*)f->obj != 0) {
gfxFree( (FIL*)f->obj );
2014-06-27 04:10:18 +00:00
f_close( (FIL*)f->obj );
}
2014-06-24 03:56:13 +00:00
}
static int fatfsRead(GFILE* f, void* buf, int size)
{
2014-06-25 03:23:57 +00:00
int br;
f_read( (FIL*)f->obj, buf, size, (UINT*)&br);
2014-06-24 03:56:13 +00:00
2014-06-25 03:23:57 +00:00
return br;
2014-06-24 03:56:13 +00:00
}
static int fatfsWrite(GFILE* f, const void* buf, int size)
{
2014-06-25 03:23:57 +00:00
int wr;
2014-06-24 03:56:13 +00:00
2014-06-25 03:23:57 +00:00
f_write( (FIL*)f->obj, buf, size, (UINT*)&wr);
2014-06-29 14:15:46 +00:00
f_sync( (FIL*)f->obj );
2014-06-25 03:23:57 +00:00
return wr;
2014-06-24 03:56:13 +00:00
}
static bool_t fatfsSetPos(GFILE* f, long int pos)
{
2014-06-25 03:23:57 +00:00
FRESULT ferr;
ferr = f_lseek( (FIL*)f->obj, (DWORD)pos );
if (ferr != FR_OK)
return FALSE;
2014-06-24 03:56:13 +00:00
2014-06-25 03:23:57 +00:00
return TRUE;
2014-06-24 03:56:13 +00:00
}
static long int fatfsGetSize(GFILE* f)
{
return (long int)f_size( (FIL*)f->obj );
2014-06-24 03:56:13 +00:00
}
static bool_t fatfsEOF(GFILE* f)
{
2014-06-25 03:23:57 +00:00
if ( f_eof( (FIL*)f->obj ) != 0)
return TRUE;
else
return FALSE;
2014-06-24 03:56:13 +00:00
}
2014-06-27 04:10:18 +00:00
static bool_t fatfsMount(const char* drive)
{
FRESULT ferr;
if (!fatfs_mounted) {
ferr = f_mount(&fatfs_fs, drive, 1);
if (ferr != FR_OK)
return FALSE;
fatfs_mounted = TRUE;
return TRUE;
}
return FALSE;
}
static bool_t fatfsUnmount(const char* drive)
{
(void)drive;
if (fatfs_mounted) {
// FatFS does not provide an unmount routine.
fatfs_mounted = FALSE;
return TRUE;
}
return FALSE;
}
2014-06-29 14:15:46 +00:00
static bool_t fatfsSync(GFILE *f)
{
FRESULT ferr;
ferr = f_sync( (FIL*)f->obj );
if (ferr != FR_OK) {
return FALSE;
}
return TRUE;
}