aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/various/fatfs_bindings/fatfs.mk7
-rw-r--r--os/various/fatfs_bindings/fatfs_diskio.c244
-rw-r--r--os/various/fatfs_bindings/fatfs_syscall.c88
-rw-r--r--os/various/fatfs_bindings/readme.txt6
4 files changed, 345 insertions, 0 deletions
diff --git a/os/various/fatfs_bindings/fatfs.mk b/os/various/fatfs_bindings/fatfs.mk
new file mode 100644
index 000000000..9f80da3b6
--- /dev/null
+++ b/os/various/fatfs_bindings/fatfs.mk
@@ -0,0 +1,7 @@
+# FATFS files.
+FATFSSRC = ${CHIBIOS}/various/fatfs_bindings/fatfs_diskio.c \
+ ${CHIBIOS}/various/fatfs_bindings/fatfs_syscall.c \
+ ${CHIBIOS}/ext/fatfs/src/ff.c \
+ ${CHIBIOS}/ext/fatfs/src/option/ccsbcs.c \
+
+FATFSINC = ${CHIBIOS}/ext/fatfs/src
diff --git a/os/various/fatfs_bindings/fatfs_diskio.c b/os/various/fatfs_bindings/fatfs_diskio.c
new file mode 100644
index 000000000..07d44db49
--- /dev/null
+++ b/os/various/fatfs_bindings/fatfs_diskio.c
@@ -0,0 +1,244 @@
+/*-----------------------------------------------------------------------*/
+/* 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 "ch.h"
+#include "hal.h"
+
+#include "diskio.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
+
+#if HAL_USE_RTC
+#include "chrtclib.h"
+extern RTCDriver RTCD1;
+#endif
+
+/*-----------------------------------------------------------------------*/
+/* Correspondence between physical drive number and physical drive. */
+
+#define MMC 0
+#define SDC 0
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Inidialize a Drive */
+
+DSTATUS disk_initialize (
+ BYTE drv /* Physical drive nmuber (0..) */
+)
+{
+ DSTATUS stat;
+
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ stat |= STA_NOINIT;
+ if (mmcIsWriteProtected(&MMCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#else
+ case SDC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ stat |= STA_NOINIT;
+ if (sdcIsWriteProtected(&SDCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#endif
+ }
+ return STA_NODISK;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Return Disk Status */
+
+DSTATUS disk_status (
+ BYTE drv /* Physical drive nmuber (0..) */
+)
+{
+ DSTATUS stat;
+
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ stat |= STA_NOINIT;
+ if (mmcIsWriteProtected(&MMCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#else
+ case SDC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ stat |= STA_NOINIT;
+ if (sdcIsWriteProtected(&SDCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#endif
+ }
+ return STA_NODISK;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Sector(s) */
+
+DRESULT disk_read (
+ BYTE drv, /* Physical drive nmuber (0..) */
+ BYTE *buff, /* Data buffer to store read data */
+ DWORD sector, /* Sector address (LBA) */
+ BYTE count /* Number of sectors to read (1..255) */
+)
+{
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ return RES_NOTRDY;
+ if (mmcStartSequentialRead(&MMCD1, sector))
+ return RES_ERROR;
+ while (count > 0) {
+ if (mmcSequentialRead(&MMCD1, buff))
+ return RES_ERROR;
+ buff += MMC_SECTOR_SIZE;
+ count--;
+ }
+ if (mmcStopSequentialRead(&MMCD1))
+ return RES_ERROR;
+ return RES_OK;
+#else
+ case SDC:
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ return RES_NOTRDY;
+ if (sdcRead(&SDCD1, sector, buff, count))
+ return RES_ERROR;
+ return RES_OK;
+#endif
+ }
+ return RES_PARERR;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Write Sector(s) */
+
+#if _READONLY == 0
+DRESULT disk_write (
+ BYTE drv, /* Physical drive nmuber (0..) */
+ const BYTE *buff, /* Data to be written */
+ DWORD sector, /* Sector address (LBA) */
+ BYTE count /* Number of sectors to write (1..255) */
+)
+{
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ return RES_NOTRDY;
+ if (mmcIsWriteProtected(&MMCD1))
+ return RES_WRPRT;
+ if (mmcStartSequentialWrite(&MMCD1, sector))
+ return RES_ERROR;
+ while (count > 0) {
+ if (mmcSequentialWrite(&MMCD1, buff))
+ return RES_ERROR;
+ buff += MMC_SECTOR_SIZE;
+ count--;
+ }
+ if (mmcStopSequentialWrite(&MMCD1))
+ return RES_ERROR;
+ return RES_OK;
+#else
+ case SDC:
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ return RES_NOTRDY;
+ if (sdcWrite(&SDCD1, sector, buff, count))
+ return RES_ERROR;
+ return RES_OK;
+#endif
+ }
+ return RES_PARERR;
+}
+#endif /* _READONLY */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Miscellaneous Functions */
+
+DRESULT disk_ioctl (
+ BYTE drv, /* Physical drive nmuber (0..) */
+ BYTE ctrl, /* Control code */
+ void *buff /* Buffer to send/receive control data */
+)
+{
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ switch (ctrl) {
+ case CTRL_SYNC:
+ return RES_OK;
+ case GET_SECTOR_SIZE:
+ *((WORD *)buff) = MMC_SECTOR_SIZE;
+ return RES_OK;
+ default:
+ return RES_PARERR;
+ }
+#else
+ case SDC:
+ switch (ctrl) {
+ case CTRL_SYNC:
+ return RES_OK;
+ case GET_SECTOR_COUNT:
+ *((DWORD *)buff) = sdcGetCardCapacity(&SDCD1);
+ return RES_OK;
+ case GET_SECTOR_SIZE:
+ *((WORD *)buff) = SDC_BLOCK_SIZE;
+ return RES_OK;
+ case GET_BLOCK_SIZE:
+ *((DWORD *)buff) = 256; /* 512b blocks in one erase block */
+ return RES_OK;
+ default:
+ return RES_PARERR;
+ }
+#endif
+ }
+ return RES_PARERR;
+}
+
+DWORD get_fattime(void) {
+#if HAL_USE_RTC
+ return rtcGetTimeFat(&RTCD1);
+#else
+ return ((uint32_t)0 | (1 << 16)) | (1 << 21); /* wrong but valid time */
+#endif
+}
+
+
+
diff --git a/os/various/fatfs_bindings/fatfs_syscall.c b/os/various/fatfs_bindings/fatfs_syscall.c
new file mode 100644
index 000000000..dbfb264b6
--- /dev/null
+++ b/os/various/fatfs_bindings/fatfs_syscall.c
@@ -0,0 +1,88 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*------------------------------------------------------------------------*/
+/* Sample code of OS dependent controls for FatFs R0.08b */
+/* (C)ChaN, 2011 */
+/*------------------------------------------------------------------------*/
+
+#include "ch.h"
+#include "ff.h"
+
+MEMORYPOOL_DECL(fs_sem_pool, sizeof(Semaphore), chCoreAlloc);
+
+#if _FS_REENTRANT
+/*------------------------------------------------------------------------*/
+/* Create a Synchronization Object */
+/*------------------------------------------------------------------------*/
+int ff_cre_syncobj(_SYNC_t *sobj) {
+
+ *sobj = chPoolAlloc(&fs_sem_pool);
+ if (*sobj == NULL)
+ return FALSE;
+ chSemInit(*sobj, 1);
+ return TRUE;
+}
+
+/*------------------------------------------------------------------------*/
+/* Delete a Synchronization Object */
+/*------------------------------------------------------------------------*/
+int ff_del_syncobj(_SYNC_t sobj) {
+
+ chSemReset(sobj, 0);
+ chPoolFree(&fs_sem_pool, sobj);
+ return TRUE;
+}
+
+/*------------------------------------------------------------------------*/
+/* Request Grant to Access the Volume */
+/*------------------------------------------------------------------------*/
+int ff_req_grant(_SYNC_t sobj) {
+
+ msg_t msg = chSemWaitTimeout(sobj, (systick_t)_FS_TIMEOUT);
+ return msg == RDY_OK;
+}
+
+/*------------------------------------------------------------------------*/
+/* Release Grant to Access the Volume */
+/*------------------------------------------------------------------------*/
+void ff_rel_grant(_SYNC_t sob) {
+
+ chSemSignal(sobj);
+}
+#endif /* _FS_REENTRANT */
+
+#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
+/*------------------------------------------------------------------------*/
+/* Allocate a memory block */
+/*------------------------------------------------------------------------*/
+void *ff_memalloc(UINT size) {
+
+ return chHeapAlloc(NULL, size);
+}
+
+/*------------------------------------------------------------------------*/
+/* Free a memory block */
+/*------------------------------------------------------------------------*/
+void ff_memfree(void *mblock) {
+
+ chHeapFree(mblock);
+}
+#endif /* _USE_LFN == 3 */
diff --git a/os/various/fatfs_bindings/readme.txt b/os/various/fatfs_bindings/readme.txt
new file mode 100644
index 000000000..8735cce54
--- /dev/null
+++ b/os/various/fatfs_bindings/readme.txt
@@ -0,0 +1,6 @@
+This directory contains the ChibiOS/RT "official" bindings with the FatFS
+library by ChaN: http://elm-chan.org
+
+In order to use FatFS within ChibiOS/RT project, unzip FatFS under
+./ext/fatfs then include $(CHIBIOS)/os/various/fatfs_bindings/fatfs.mk
+in your makefile.