aboutsummaryrefslogtreecommitdiffstats
path: root/src/gfile
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2014-08-15 02:22:02 +1000
committerinmarket <andrewh@inmarket.com.au>2014-08-15 02:22:02 +1000
commit75e1e7a5e26491e942fb2b25f518d8e2e3112721 (patch)
tree970754edda05d38bce1f85492868eca717820b99 /src/gfile
parent9b570be049bf656489bdce823f6f04beb80f053d (diff)
downloaduGFX-75e1e7a5e26491e942fb2b25f518d8e2e3112721.tar.gz
uGFX-75e1e7a5e26491e942fb2b25f518d8e2e3112721.tar.bz2
uGFX-75e1e7a5e26491e942fb2b25f518d8e2e3112721.zip
Add GFILE support for PetitFS (a very tiny FAT implementation)
Diffstat (limited to 'src/gfile')
-rw-r--r--src/gfile/inc_petitfs.c157
-rw-r--r--src/gfile/petitfs_chibios_diskio.c82
-rw-r--r--src/gfile/petitfs_wrapper.c23
-rw-r--r--src/gfile/petitfs_wrapper.h26
-rw-r--r--src/gfile/sys_make.mk7
-rw-r--r--src/gfile/sys_options.h22
-rw-r--r--src/gfile/sys_rules.h3
7 files changed, 317 insertions, 3 deletions
diff --git a/src/gfile/inc_petitfs.c b/src/gfile/inc_petitfs.c
new file mode 100644
index 00000000..9b3b510b
--- /dev/null
+++ b/src/gfile/inc_petitfs.c
@@ -0,0 +1,157 @@
+/*
+ * 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
+ */
+
+/********************************************************
+ * The PETITFS file-system
+ ********************************************************/
+
+#include "gfx.h"
+
+#if GFX_USE_GFILE && GFILE_NEED_PETITFS
+
+#include "gfile_fs.h"
+#include "petitfs_wrapper.h"
+
+static bool_t petitfsExists(const char* fname);
+static bool_t petitfsOpen(GFILE* f, const char* fname);
+static int petitfsRead(GFILE* f, void* buf, int size);
+static bool_t petitfsSetPos(GFILE* f, long int pos);
+#if GFILE_NEED_FILELISTS && _FS_MINIMIZE <= 1
+ static gfileList *petitfsFlOpen(const char *path, bool_t dirs);
+ static const char *petitfsFlRead(gfileList *pfl);
+ static void petitfsFlClose(gfileList *pfl);
+#endif
+
+const GFILEVMT FsPetitFSVMT = {
+ GFSFLG_WRITEABLE | GFSFLG_SEEKABLE,
+ 'F',
+ 0,
+ petitfsExists,
+ 0, // No Filesize
+ 0,
+ petitfsOpen,
+ 0, // No Close
+ petitfsRead,
+ 0, // No Write
+ petitfsSetPos,
+ 0, // No Getsize
+ 0, // No EOF
+ 0, 0, 0, // No Mount, UnMount or Sync
+ #if GFILE_NEED_FILELISTS
+ #if _USE_DIR
+ petitfsFlOpen, petitfsFlRead, petitfsFlClose
+ #else
+ 0, 0, 0
+ #endif
+ #endif
+};
+
+// Our directory list structure
+typedef struct petitfsList {
+ gfileList fl; // This must be the first element.
+ DIR dir;
+ FILINFO fno;
+} petitfsList;
+
+// optimize these later on. Use an array to have multiple
+static bool_t petitfs_mounted = FALSE;
+static FATFS petitfs_fs;
+
+static bool_t petitfsExists(const char* fname)
+{
+ // Mount first
+ if (!petitfs_mounted && pf_mount(&petitfs_fs) != FR_OK)
+ return FALSE;
+
+ // Open
+ if (pf_open(fname) != FR_OK)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bool_t petitfsOpen(GFILE* f, const char* fname)
+{
+ // No writing
+ if ((f->flags & GFILEFLG_WRITE))
+ return FALSE;
+
+ // Mount first
+ if (!petitfs_mounted && pf_mount(&petitfs_fs) != FR_OK)
+ return FALSE;
+
+ // Open
+ if (pf_open(fname) != FR_OK)
+ return FALSE;
+
+ f->obj = &petitfs_fs;
+ return TRUE;
+}
+
+static int petitfsRead(GFILE* f, void* buf, int size)
+{
+ int br;
+ (void) f;
+
+ if (pf_read(buf, size, (UINT*)&br) != FR_OK)
+ return 0;
+
+ return br;
+}
+
+static bool_t petitfsSetPos(GFILE* f, long int pos)
+{
+ (void) f;
+ return pf_lseek((DWORD)pos) == FR_OK;
+}
+
+#if GFILE_NEED_FILELISTS
+ static gfileList *petitfsFlOpen(const char *path, bool_t dirs) {
+ petitfsList *p;
+ (void) dirs;
+
+ if (!(p = gfxAlloc(sizeof(petitfsList))))
+ return 0;
+
+ if (pf_opendir(&p->dir, path) != FR_OK) {
+ gfxFree(p);
+ return 0;
+ }
+ return &p->fl;
+ }
+
+ static const char *petitfsFlRead(gfileList *pfl) {
+ #define ffl ((petitfsList *)pfl)
+
+ while(1) {
+ // Read the next entry
+ if (pf_readdir(&ffl->dir, &ffl->fno) != FR_OK || !ffl->fno.fname[0])
+ return 0;
+
+ /* Ignore dot entries */
+ if (ffl->fno.fname[0] == '.') continue;
+
+ /* Is it a directory */
+ if (ffl->fl.dirs) {
+ if ((ffl->fno.fattrib & AM_DIR))
+ break;
+ } else {
+ if (!(ffl->fno.fattrib & (AM_DIR|AM_HID|AM_SYS)))
+ break;
+ }
+ }
+
+ return ffl->fno.fname;
+ }
+
+ static void petitfsFlClose(gfileList *pfl) {
+ gfxFree(pfl);
+ }
+
+#endif
+
+#endif //GFX_USE_GFILE && GFILE_NEED_PETITFS
diff --git a/src/gfile/petitfs_chibios_diskio.c b/src/gfile/petitfs_chibios_diskio.c
new file mode 100644
index 00000000..dda3f6fc
--- /dev/null
+++ b/src/gfile/petitfs_chibios_diskio.c
@@ -0,0 +1,82 @@
+/*-----------------------------------------------------------------------*/
+/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
+/*-----------------------------------------------------------------------*/
+/* This is a stub disk I/O module that acts as front end of the existing */
+/* disk I/O modules and attach it to FatFs module with common interface. */
+/*-----------------------------------------------------------------------*/
+
+#include "gfx.h"
+
+#if GFX_USE_GFILE && GFILE_NEED_PETITFS && GFX_USE_OS_CHIBIOS
+
+#include "petitfs_wrapper.h"
+
+#include <string.h>
+
+#if HAL_USE_MMC_SPI && HAL_USE_SDC
+#error "cannot specify both MMC_SPI and SDC drivers"
+#endif
+
+#if HAL_USE_MMC_SPI
+extern MMCDriver MMCD1;
+#elif HAL_USE_SDC
+extern SDCDriver SDCD1;
+#else
+#error "MMC_SPI or SDC driver must be specified"
+#endif
+
+/*-----------------------------------------------------------------------*/
+/* Initialize a Drive */
+
+DSTATUS disk_initialize (void) {
+#if HAL_USE_MMC_SPI
+ /* It is initialized externally, just reads the status.*/
+ if (blkGetDriverState(&MMCD1) != BLK_READY)
+ return STA_NOINIT;
+#else
+ /* It is initialized externally, just reads the status.*/
+ if (blkGetDriverState(&SDCD1) != BLK_READY)
+ return STA_NOINIT;
+#endif
+ // All good
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+/* Read Part Sector(s) */
+
+static BYTE sectBuf[512];
+static DWORD sectpos = -1;
+
+DRESULT disk_readp (
+ BYTE* buff, /* [OUT] Pointer to the read buffer */
+ DWORD sector, /* [IN] Sector number */
+ UINT offset, /* [IN] Byte offset in the sector to start to read */
+ UINT count /* [IN] Number of bytes to read */
+ ) {
+
+ if (sector != sectpos) {
+ #if HAL_USE_MMC_SPI
+ if (blkGetDriverState(&MMCD1) != BLK_READY)
+ return RES_NOTRDY;
+ if (mmcStartSequentialRead(&MMCD1, sector))
+ return RES_ERROR;
+ if (mmcSequentialRead(&MMCD1, sectBuf))
+ return RES_ERROR;
+ if (mmcStopSequentialRead(&MMCD1))
+ return RES_ERROR;
+ #else
+ if (blkGetDriverState(&SDCD1) != BLK_READY)
+ return RES_NOTRDY;
+ if (sdcRead(&SDCD1, sector, sectBuf, 1))
+ return RES_ERROR;
+ #endif
+ sectpos = sector;
+ }
+ memcpy(buff, sectBuf + offset, count);
+ return RES_OK;
+}
+
+#endif // GFX_USE_GFILE && GFILE_NEED_PETITFS && GFX_USE_OS_CHIBIOS
+
+
diff --git a/src/gfile/petitfs_wrapper.c b/src/gfile/petitfs_wrapper.c
new file mode 100644
index 00000000..183edb70
--- /dev/null
+++ b/src/gfile/petitfs_wrapper.c
@@ -0,0 +1,23 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gfile/petitfs_wrapper.c
+ * @brief GFILE PETITFS wrapper.
+ *
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GFILE && GFILE_NEED_PETITFS
+
+#include "petitfs_wrapper.h"
+
+// Include the source we want
+#include "3rdparty/petitfs-0.03/src/pff.c"
+
+#endif // GFX_USE_GFILE && GFILE_NEED_PETITFS
diff --git a/src/gfile/petitfs_wrapper.h b/src/gfile/petitfs_wrapper.h
new file mode 100644
index 00000000..4f91bd7f
--- /dev/null
+++ b/src/gfile/petitfs_wrapper.h
@@ -0,0 +1,26 @@
+/*
+ * 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
+ */
+
+/**
+ * @file src/gfile/petitfs_wrapper.h
+ * @brief GFILE PETITFS wrapper.
+ *
+ */
+
+#ifndef _PETITFS_WRAPPER
+#define _PETITFS_WRAPPER
+
+// Include the petitfs configuration from the local directory not the original source folder
+#include "pffconf.h"
+
+// Include the petitfs API
+#include "3rdparty/petitfs-0.03/src/pff.h"
+
+// Include the petitfs diskio API
+#include "3rdparty/petitfs-0.03/src/diskio.h"
+
+#endif //_PETITFS_WRAPPER
diff --git a/src/gfile/sys_make.mk b/src/gfile/sys_make.mk
index ba74a15c..e14527c6 100644
--- a/src/gfile/sys_make.mk
+++ b/src/gfile/sys_make.mk
@@ -3,6 +3,7 @@ GFXSRC += $(GFXLIB)/src/gfile/gfile.c \
$(GFXLIB)/src/gfile/inc_ramfs.c \
$(GFXLIB)/src/gfile/inc_romfs.c \
$(GFXLIB)/src/gfile/inc_fatfs.c \
+ $(GFXLIB)/src/gfile/inc_petitfs.c \
$(GFXLIB)/src/gfile/inc_memfs.c \
$(GFXLIB)/src/gfile/inc_chibiosfs.c \
$(GFXLIB)/src/gfile/inc_strings.c \
@@ -10,4 +11,8 @@ GFXSRC += $(GFXLIB)/src/gfile/gfile.c \
$(GFXLIB)/src/gfile/inc_scang.c \
$(GFXLIB)/src/gfile/inc_stdio.c \
$(GFXLIB)/src/gfile/fatfs_wrapper.c \
- $(GFXLIB)/src/gfile/fatfs_chibios_diskio.c
+ $(GFXLIB)/src/gfile/fatfs_chibios_diskio.c \
+ $(GFXLIB)/src/gfile/petitfs_wrapper.c \
+ $(GFXLIB)/src/gfile/petitfs_chibios_diskio.c \
+
+ \ No newline at end of file
diff --git a/src/gfile/sys_options.h b/src/gfile/sys_options.h
index ff1e5d4c..354d4f2b 100644
--- a/src/gfile/sys_options.h
+++ b/src/gfile/sys_options.h
@@ -101,17 +101,35 @@
#define GFILE_NEED_RAMFS FALSE
#endif
/**
- * @brief Include the FAT file system driver
+ * @brief Include the FAT file system driver based on the FATFS library
* @details Defaults to FALSE
* @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are
* opening a file on the FAT file system by prefixing
* its name with "F|" (the letter 'F', followed by a vertical bar).
- * @note You must separately include the FATFS library and code.
+ * @note FATFS and PETITFS offer the same FAT file system support. They just use
+ * different constraints. PETITFS is smaller but has less features. Only
+ * one can be used at a time. The block interfaces are also different.
*/
#ifndef GFILE_NEED_FATFS
#define GFILE_NEED_FATFS FALSE
#endif
/**
+ * @brief Include the FAT file system driver based on the PETITFS library
+ * @details Defaults to FALSE
+ * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are
+ * opening a file on the FAT file system by prefixing
+ * its name with "F|" (the letter 'F', followed by a vertical bar).
+ * @note FATFS and PETITFS offer the same FAT file system support. They just use
+ * different constraints. PETITFS is smaller but has less features. Only
+ * one can be used at a time. The block interfaces are also different.
+ * @note Due to the restrictions on the PETITFS library on writing, we do not implement
+ * writing.
+ * @note PETITFS can only have one file open at a time.
+ */
+ #ifndef GFILE_NEED_PETITFS
+ #define GFILE_NEED_FATFS FALSE
+ #endif
+ /**
* @brief Include the operating system's native file system
* @details Defaults to FALSE
* @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are
diff --git a/src/gfile/sys_rules.h b/src/gfile/sys_rules.h
index 8d07144d..d13041f2 100644
--- a/src/gfile/sys_rules.h
+++ b/src/gfile/sys_rules.h
@@ -17,6 +17,9 @@
#define _GFILE_RULES_H
#if GFX_USE_GFILE
+ #if GFILE_NEED_PETITFS && GFILE_NEED_FATFS
+ #error "GFILE: Both GFILE_NEED_PETITFS and GFILE_NEED_FATFS cannot both be turned on at the same time."
+ #endif
#endif
#endif /* _GFILE_RULES_H */