initial implementation - untested

ugfx_release_2.6
Joel Bodenmann 2014-06-25 05:23:57 +02:00
parent d7129e6058
commit b054a7220f
7 changed files with 420 additions and 8 deletions

View File

@ -0,0 +1,6 @@
GFXSRC += $(GFXLIB)/src/gfile/fatfs/src/ff.c \
$(GFXLIB)/src/gfile/fatfs/src/chibios_fatfs_diskio.c \
$(GFXLIB)/src/gfile/fatfs/src/chibios_fatfs_syscall.c
GFXINC += $(GFXLIB)/src/gfile/fatfs/src

View File

@ -1,4 +0,0 @@
The contents of this directory are not part of the Works of the
uGFX library. All the contents in this directory are 3rdparty and come with
their own licenses.

View File

@ -0,0 +1,254 @@
/*-----------------------------------------------------------------------*/
/* 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 "ffconf.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 (blkGetDriverState(&MMCD1) != BLK_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 (blkGetDriverState(&SDCD1) != BLK_READY)
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 (blkGetDriverState(&MMCD1) != BLK_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 (blkGetDriverState(&SDCD1) != BLK_READY)
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) */
UINT count /* Number of sectors to read (1..255) */
)
{
switch (drv) {
#if HAL_USE_MMC_SPI
case MMC:
if (blkGetDriverState(&MMCD1) != BLK_READY)
return RES_NOTRDY;
if (mmcStartSequentialRead(&MMCD1, sector))
return RES_ERROR;
while (count > 0) {
if (mmcSequentialRead(&MMCD1, buff))
return RES_ERROR;
buff += MMCSD_BLOCK_SIZE;
count--;
}
if (mmcStopSequentialRead(&MMCD1))
return RES_ERROR;
return RES_OK;
#else
case SDC:
if (blkGetDriverState(&SDCD1) != BLK_READY)
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) */
UINT count /* Number of sectors to write (1..255) */
)
{
switch (drv) {
#if HAL_USE_MMC_SPI
case MMC:
if (blkGetDriverState(&MMCD1) != BLK_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 += MMCSD_BLOCK_SIZE;
count--;
}
if (mmcStopSequentialWrite(&MMCD1))
return RES_ERROR;
return RES_OK;
#else
case SDC:
if (blkGetDriverState(&SDCD1) != BLK_READY)
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) = MMCSD_BLOCK_SIZE;
return RES_OK;
#if _USE_ERASE
case CTRL_ERASE_SECTOR:
mmcErase(&MMCD1, *((DWORD *)buff), *((DWORD *)buff + 1));
return RES_OK;
#endif
default:
return RES_PARERR;
}
#else
case SDC:
switch (ctrl) {
case CTRL_SYNC:
return RES_OK;
case GET_SECTOR_COUNT:
*((DWORD *)buff) = mmcsdGetCardCapacity(&SDCD1);
return RES_OK;
case GET_SECTOR_SIZE:
*((WORD *)buff) = MMCSD_BLOCK_SIZE;
return RES_OK;
case GET_BLOCK_SIZE:
*((DWORD *)buff) = 256; /* 512b blocks in one erase block */
return RES_OK;
#if _USE_ERASE
case CTRL_ERASE_SECTOR:
sdcErase(&SDCD1, *((DWORD *)buff), *((DWORD *)buff + 1));
return RES_OK;
#endif
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
}

View File

@ -0,0 +1,84 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*------------------------------------------------------------------------*/
/* Sample code of OS dependent controls for FatFs R0.08b */
/* (C)ChaN, 2011 */
/*------------------------------------------------------------------------*/
#include "ch.h"
#include "ff.h"
#if _FS_REENTRANT
/*------------------------------------------------------------------------*/
/* Static array of Synchronization Objects */
/*------------------------------------------------------------------------*/
static Semaphore ff_sem[_VOLUMES];
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object */
/*------------------------------------------------------------------------*/
int ff_cre_syncobj(BYTE vol, _SYNC_t *sobj) {
*sobj = &ff_sem[vol];
chSemInit(*sobj, 1);
return TRUE;
}
/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object */
/*------------------------------------------------------------------------*/
int ff_del_syncobj(_SYNC_t sobj) {
chSemReset(sobj, 0);
return TRUE;
}
/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume */
/*------------------------------------------------------------------------*/
int ff_req_grant(_SYNC_t sobj) {
msg_t msg = chSemWaitTimeout(sobj, (systime_t)_FS_TIMEOUT);
return msg == RDY_OK;
}
/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume */
/*------------------------------------------------------------------------*/
void ff_rel_grant(_SYNC_t sobj) {
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 */

View File

@ -97,7 +97,7 @@ GFILE *gfileStdErr;
/********************************************************
* The FAT file-system VMT
********************************************************/
#ifndef GFILE_NEED_FATFS
#if GFILE_NEED_FATFS
#include "src/gfile/inc_fatfs.c"
#endif

View File

@ -9,6 +9,9 @@
* This file is included by src/gfile/gfile.c
*/
#include "ff.h"
#include "ffconf.h"
/********************************************************
* The FAT file-system VMT
********************************************************/
@ -45,58 +48,124 @@ static const GFILEVMT FsFatFSVMT = {
#undef GFILE_CHAINHEAD
#define GFILE_CHAINHEAD &FsFatFSVMT
static void _flags2mode(GFILE* f, BYTE* mode)
{
*mode = 0;
if (f->flags & GFILEFLG_MUSTEXIST)
*mode |= FA_READ;
else if (f->flags & GFILEFLG_APPEND)
*mode |= 0; /* ToDO */
else
*mode |= FA_WRITE;
/* ToDo - Complete */
}
static bool_t fatfsDel(const char* fname)
{
FRESULT ferr;
ferr = f_unlink( (const TCHAR*)fname );
if (ferr != FR_OK)
return FALSE;
return TRUE;
}
static bool_t fatfsExists(const char* fname)
{
(void)fname;
/* ToDo */
return TRUE;
}
static long int fatfsFileSize(const char* fname)
{
FRESULT ferr;
FILINFO fno;
ferr = f_stat( (const TCHAR*)fname, &fno );
if (ferr != FR_OK)
return 0;
return (long int)fno.fsize;
}
static bool_t fatfsRename(const char* oldname, const char* newname)
{
FRESULT ferr;
ferr = f_rename( (const TCHAR*)oldname, (const TCHAR*)newname );
if (ferr != FR_OK)
return FALSE;
return TRUE;
}
static bool_t fatfsOpen(GFILE* f, const char* fname)
{
FIL* fd = 0;
BYTE mode;
FRESULT ferr;
_flags2mode(f, &mode);
ferr = f_open(fd, fname, mode);
if (ferr != FR_OK)
return FALSE;
f->obj = (void*)fd;
return TRUE;
}
static void fatfsClose(GFILE* f)
{
f_close( (FIL*)f->obj );
}
static int fatfsRead(GFILE* f, void* buf, int size)
{
int br;
f_read( (FIL*)f->obj, buf, size, (UINT*)&br);
return br;
}
static int fatfsWrite(GFILE* f, const void* buf, int size)
{
int wr;
f_write( (FIL*)f->obj, buf, size, (UINT*)&wr);
return wr;
}
static bool_t fatfsSetPos(GFILE* f, long int pos)
{
FRESULT ferr;
ferr = f_lseek( (FIL*)f->obj, (DWORD)pos );
if (ferr != FR_OK)
return FALSE;
return TRUE;
}
static long int fatfsGetSize(GFILE* f)
{
return (long int)f_tell( (FIL*)f->obj );
}
static bool_t fatfsEOF(GFILE* f)
{
if ( f_eof( (FIL*)f->obj ) != 0)
return TRUE;
else
return FALSE;
}

View File

@ -1 +1,4 @@
include $(GFXLIB)/src/gfile/fatfs/fatfs.mk
GFXSRC += $(GFXLIB)/src/gfile/gfile.c