From: Ivan Grokhotkov Date: Thu, 29 Dec 2016 09:33:38 +0000 (+0800) Subject: fatfs: add pluggable diskio layer, sdmmc implementation X-Git-Tag: v2.0-rc1~71^2~3 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9398d1b1cc2e28c8cb16011438c4a823960dcbb8;p=esp-idf fatfs: add pluggable diskio layer, sdmmc implementation --- diff --git a/components/fatfs/src/diskio.c b/components/fatfs/src/diskio.c index 25f5e53bc0..b00e9d2ca5 100644 --- a/components/fatfs/src/diskio.c +++ b/components/fatfs/src/diskio.c @@ -7,219 +7,126 @@ /* storage control modules to the FatFs module with a defined API. */ /*-----------------------------------------------------------------------*/ +#include #include "diskio.h" /* FatFs lower layer API */ - -/* Definitions of physical drive number for each drive */ -#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */ -#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */ -#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */ - - -/*-----------------------------------------------------------------------*/ -/* Get Drive Status */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_status ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ -) +#include "ffconf.h" +#include "ff.h" +#include "sdmmc_cmd.h" +#include "esp_log.h" +#include +#include + +static const char* TAG = "ff_diskio"; +static ff_diskio_impl_t s_impls[_VOLUMES] = { { 0 } }; +static sdmmc_card_t* s_cards[_VOLUMES] = { NULL }; + +PARTITION VolToPart[] = { + {0, 1}, /* Logical drive 0 ==> Physical drive 0, 1st partition */ + {1, 0} /* Logical drive 1 ==> Physical drive 1, auto detection */ +}; + +void ff_diskio_register(BYTE pdrv, const ff_diskio_impl_t* discio_impl) { - DSTATUS stat; - int result; - - switch (pdrv) { - case DEV_RAM : - result = RAM_disk_status(); - - // translate the reslut code here - - return stat; - - case DEV_MMC : - result = MMC_disk_status(); - - // translate the reslut code here - - return stat; - - case DEV_USB : - result = USB_disk_status(); - - // translate the reslut code here - - return stat; - } - return STA_NOINIT; + assert(pdrv < _VOLUMES); + memcpy(&s_impls[pdrv], discio_impl, sizeof(ff_diskio_impl_t)); } - - -/*-----------------------------------------------------------------------*/ -/* Inidialize a Drive */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_initialize ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ -) +DSTATUS ff_disk_initialize (BYTE pdrv) { - DSTATUS stat; - int result; - - switch (pdrv) { - case DEV_RAM : - result = RAM_disk_initialize(); - - // translate the reslut code here - - return stat; - - case DEV_MMC : - result = MMC_disk_initialize(); - - // translate the reslut code here - - return stat; - - case DEV_USB : - result = USB_disk_initialize(); - - // translate the reslut code here - - return stat; - } - return STA_NOINIT; + return s_impls[pdrv].init(pdrv); } - - - -/*-----------------------------------------------------------------------*/ -/* Read Sector(s) */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_read ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - BYTE *buff, /* Data buffer to store read data */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to read */ -) +DSTATUS ff_disk_status (BYTE pdrv) { - DRESULT res; - int result; - - switch (pdrv) { - case DEV_RAM : - // translate the arguments here - - result = RAM_disk_read(buff, sector, count); - - // translate the reslut code here - - return res; - - case DEV_MMC : - // translate the arguments here - - result = MMC_disk_read(buff, sector, count); - - // translate the reslut code here - - return res; - - case DEV_USB : - // translate the arguments here - - result = USB_disk_read(buff, sector, count); - - // translate the reslut code here - - return res; - } - - return RES_PARERR; + return s_impls[pdrv].status(pdrv); } - - - -/*-----------------------------------------------------------------------*/ -/* Write Sector(s) */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_write ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - const BYTE *buff, /* Data to be written */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to write */ -) +DRESULT ff_disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { - DRESULT res; - int result; - - switch (pdrv) { - case DEV_RAM : - // translate the arguments here - - result = RAM_disk_write(buff, sector, count); - - // translate the reslut code here - - return res; - - case DEV_MMC : - // translate the arguments here - - result = MMC_disk_write(buff, sector, count); - - // translate the reslut code here - - return res; - - case DEV_USB : - // translate the arguments here - - result = USB_disk_write(buff, sector, count); - - // translate the reslut code here - - return res; - } - - return RES_PARERR; + return s_impls[pdrv].read(pdrv, buff, sector, count); } - - - -/*-----------------------------------------------------------------------*/ -/* Miscellaneous Functions */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_ioctl ( - BYTE pdrv, /* Physical drive nmuber (0..) */ - BYTE cmd, /* Control code */ - void *buff /* Buffer to send/receive control data */ -) +DRESULT ff_disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { - DRESULT res; - int result; - - switch (pdrv) { - case DEV_RAM : - - // Process of the command for the RAM drive - - return res; + return s_impls[pdrv].write(pdrv, buff, sector, count); +} +DRESULT ff_disk_ioctl (BYTE pdrv, BYTE cmd, void* buff) +{ + return s_impls[pdrv].ioctl(pdrv, cmd, buff); +} - case DEV_MMC : +DWORD get_fattime(void) +{ + time_t t = time(NULL); + struct tm *tmr = gmtime(&t); + return ((DWORD)(tmr->tm_year - 80) << 25) + | ((DWORD)(tmr->tm_mon + 1) << 21) + | ((DWORD)tmr->tm_mday << 16) + | (WORD)(tmr->tm_hour << 11) + | (WORD)(tmr->tm_min << 5) + | (WORD)(tmr->tm_sec >> 1); +} - // Process of the command for the MMC/SD card +DSTATUS ff_sdmmc_initialize (BYTE pdrv) +{ + return 0; +} - return res; +DSTATUS ff_sdmmc_status (BYTE pdrv) +{ + return 0; +} - case DEV_USB : +DRESULT ff_sdmmc_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count) +{ + sdmmc_card_t* card = s_cards[pdrv]; + assert(card); + esp_err_t err = sdmmc_read_blocks(card, buff, sector, count); + if (err != ESP_OK) { + ESP_LOGE(TAG, "sdmmc_read_blocks failed (%d)", err); + return RES_ERROR; + } + return RES_OK; +} - // Process of the command the USB drive +DRESULT ff_sdmmc_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) +{ + sdmmc_card_t* card = s_cards[pdrv]; + assert(card); + esp_err_t err = sdmmc_write_blocks(card, buff, sector, count); + if (err != ESP_OK) { + ESP_LOGE(TAG, "sdmmc_write_blocks failed (%d)", err); + return RES_ERROR; + } + return RES_OK; +} - return res; - } +DRESULT ff_sdmmc_ioctl (BYTE pdrv, BYTE cmd, void* buff) +{ + sdmmc_card_t* card = s_cards[pdrv]; + assert(card); + switch(cmd) { + case CTRL_SYNC: + return RES_OK; + case GET_SECTOR_COUNT: + *((uint32_t*) buff) = card->csd.capacity; + return RES_OK; + case GET_SECTOR_SIZE: + *((uint32_t*) buff) = card->csd.sector_size; + return RES_OK; + case GET_BLOCK_SIZE: + return RES_ERROR; + } + return RES_ERROR; +} - return RES_PARERR; +void ff_diskio_register_sdmmc(BYTE pdrv, sdmmc_card_t* card) +{ + static const ff_diskio_impl_t sdmmc_impl = { + .init = &ff_sdmmc_initialize, + .status = &ff_sdmmc_status, + .read = &ff_sdmmc_read, + .write = &ff_sdmmc_write, + .ioctl = &ff_sdmmc_ioctl + }; + s_cards[pdrv] = card; + ff_diskio_register(pdrv, &sdmmc_impl); } diff --git a/components/fatfs/src/diskio.h b/components/fatfs/src/diskio.h index 03e8b7c560..921ef9836a 100644 --- a/components/fatfs/src/diskio.h +++ b/components/fatfs/src/diskio.h @@ -10,7 +10,8 @@ extern "C" { #endif #include "integer.h" - +#include "sdmmc_cmd.h" +#include "driver/sdmmc_host.h" /* Status of Disk Functions */ typedef BYTE DSTATUS; @@ -29,12 +30,31 @@ typedef enum { /* Prototypes for disk control functions */ +/* Redefine names of disk IO functions to prevent name collisions */ +#define disk_initialize ff_disk_initialize +#define disk_status ff_disk_status +#define disk_read ff_disk_read +#define disk_write ff_disk_write +#define disk_ioctl ff_disk_ioctl + + DSTATUS disk_initialize (BYTE pdrv); DSTATUS disk_status (BYTE pdrv); DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); +typedef struct { + DSTATUS (*init) (BYTE pdrv); + DSTATUS (*status) (BYTE pdrv); + DRESULT (*read) (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); + DRESULT (*write) (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); + DRESULT (*ioctl) (BYTE pdrv, BYTE cmd, void* buff); +} ff_diskio_impl_t; + +void ff_diskio_register(BYTE pdrv, const ff_diskio_impl_t* discio_impl); + +void ff_diskio_register_sdmmc(BYTE pdrv, sdmmc_card_t* card); /* Disk Status Bits (DSTATUS) */ diff --git a/components/fatfs/src/ffconf.h b/components/fatfs/src/ffconf.h index c43321f626..b3a1bf5747 100644 --- a/components/fatfs/src/ffconf.h +++ b/components/fatfs/src/ffconf.h @@ -39,7 +39,7 @@ / f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ -#define _USE_MKFS 0 +#define _USE_MKFS 1 /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ @@ -69,7 +69,7 @@ / Locale and Namespace Configurations /---------------------------------------------------------------------------*/ -#define _CODE_PAGE 932 +#define _CODE_PAGE 1 /* This option specifies the OEM code page to be used on the target system. / Incorrect setting of the code page can cause a file open failure. / @@ -147,7 +147,7 @@ / Drive/Volume Configurations /---------------------------------------------------------------------------*/ -#define _VOLUMES 1 +#define _VOLUMES 2 /* Number of volumes (logical drives) to be used. */ @@ -160,7 +160,7 @@ / the drive ID strings are: A-Z and 0-9. */ -#define _MULTI_PARTITION 0 +#define _MULTI_PARTITION 1 /* This option switches support of multi-partition on a physical drive. / By default (0), each logical drive number is bound to the same physical drive / number and only an FAT volume found on the physical drive will be mounted. diff --git a/components/fatfs/src/option/syscall.c b/components/fatfs/src/option/syscall.c index c9d219b797..14140c5a73 100644 --- a/components/fatfs/src/option/syscall.c +++ b/components/fatfs/src/option/syscall.c @@ -9,7 +9,7 @@ #if _FS_REENTRANT /*------------------------------------------------------------------------*/ -/* Create a Synchronization Object +/* Create a Synchronization Object */ /*------------------------------------------------------------------------*/ /* This function is called in f_mount() function to create a new / synchronization object, such as semaphore and mutex. When a 0 is returned,