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-24 03:56:13 +00:00
|
|
|
|
|
|
|
static const GFILEVMT FsFatFSVMT = {
|
|
|
|
GFILE_CHAINHEAD,
|
2014-06-26 22:38:46 +00:00
|
|
|
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,
|
|
|
|
fatfsUnmount
|
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-25 03:23:57 +00:00
|
|
|
static void _flags2mode(GFILE* f, BYTE* mode)
|
|
|
|
{
|
|
|
|
*mode = 0;
|
|
|
|
|
2014-06-26 22:38:46 +00:00
|
|
|
if (f->flags & GFILEFLG_READ)
|
2014-06-25 03:23:57 +00:00
|
|
|
*mode |= FA_READ;
|
2014-06-26 22:38:46 +00:00
|
|
|
if (f->flags & GFILEFLG_WRITE)
|
2014-06-25 03:23:57 +00:00
|
|
|
*mode |= FA_WRITE;
|
2014-06-26 22:38:46 +00:00
|
|
|
if (f->flags & GFILEFLG_APPEND)
|
|
|
|
*mode |= 0; // ToDo
|
|
|
|
if (f->flags & GFILEFLG_TRUNC)
|
|
|
|
*mode |= FA_CREATE_ALWAYS;
|
2014-06-25 03:23:57 +00:00
|
|
|
|
|
|
|
/* ToDo - Complete */
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
{
|
2014-06-26 22:38:46 +00:00
|
|
|
FRESULT ferr;
|
|
|
|
FILINFO fno;
|
2014-06-25 03:23:57 +00:00
|
|
|
|
2014-06-26 22:38:46 +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)
|
|
|
|
{
|
2014-06-26 22:38:46 +00:00
|
|
|
FIL* fd;
|
2014-06-25 03:23:57 +00:00
|
|
|
BYTE mode;
|
|
|
|
FRESULT ferr;
|
2014-06-27 04:10:18 +00:00
|
|
|
/*
|
|
|
|
if (!fatfs_mounted && !fatfsMount(""))
|
|
|
|
return FALSE;
|
|
|
|
*/
|
2014-06-26 22:38:46 +00:00
|
|
|
if (!(fd = gfxAlloc(sizeof(FIL))))
|
|
|
|
return FALSE;
|
|
|
|
|
2014-06-25 03:23:57 +00:00
|
|
|
_flags2mode(f, &mode);
|
|
|
|
|
|
|
|
ferr = f_open(fd, fname, mode);
|
2014-06-26 22:38:46 +00:00
|
|
|
if (ferr != FR_OK) {
|
2014-06-27 04:10:18 +00:00
|
|
|
gfxFree(fd);
|
2014-06-26 22:38:46 +00:00
|
|
|
f->obj = 0;
|
|
|
|
|
2014-06-25 03:23:57 +00:00
|
|
|
return FALSE;
|
2014-06-26 22:38:46 +00:00
|
|
|
}
|
2014-06-25 03:23:57 +00:00
|
|
|
|
|
|
|
f->obj = (void*)fd;
|
|
|
|
|
|
|
|
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) {
|
2014-06-26 22:38:46 +00:00
|
|
|
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);
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2014-06-26 22:38:46 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|