Files
TencentOS-tiny/components/fs/fatfs/wrapper/tos_fatfs_drv.c
daishengdong 7f4b0b2582 add fatfs through vfs for EVB plus
1. see board\TencentOS_tiny_EVB_MX_Plus\KEIL\fatfs_through_vfs
2020-06-02 21:31:11 +08:00

139 lines
3.0 KiB
C

#include "tos_vfs.h"
#include "tos_hal.h"
#include "tos_ff.h"
#include "tos_diskio.h"
DWORD tos_get_fattime(void)
{
return 0;
}
static hal_sd_t sd;
static hal_sd_info_t sd_info;
static int sd_open(vfs_inode_t *dev)
{
if (tos_hal_sd_init(&sd) != 0) {
return -1;
}
return tos_hal_sd_info_get(&sd, &sd_info);
}
static int sd_close(vfs_inode_t *dev)
{
return tos_hal_sd_deinit(&sd);
}
static uint8_t sdio_aligned_buffer[512] __ALIGNED__(4);
static ssize_t sd_read(vfs_inode_t *dev, void *buf, size_t start_sector, unsigned int nsectors)
{
TOS_CPU_CPSR_ALLOC();
int rc = 0;
uint32_t i;
uint8_t *buff = (uint8_t *)buf;
uint64_t sector_addr = start_sector << 9;
TOS_CPU_INT_DISABLE();
if ((cpu_addr_t)buff % 4 != 0) {
for (i = 0; i < nsectors; ++i) {
rc = tos_hal_sd_read(&sd, sdio_aligned_buffer, sector_addr + 512 * i, 1, 2000);
memcpy(buff, sdio_aligned_buffer, 512);
buff += 512;
}
} else {
rc = tos_hal_sd_read(&sd, buff, sector_addr, nsectors, 2000);
}
TOS_CPU_INT_ENABLE();
return rc;
}
static ssize_t sd_write(vfs_inode_t *dev, const unsigned char *buf, size_t start_sector, unsigned int nsectors)
{
TOS_CPU_CPSR_ALLOC();
int rc = 0;
uint32_t i;
uint8_t *buff = (uint8_t *)buf;
uint64_t sector_addr = start_sector << 9;
TOS_CPU_INT_DISABLE();
if ((cpu_addr_t)buff % 4 != 0) {
for (i = 0; i < nsectors; ++i) {
memcpy(sdio_aligned_buffer, buff, 512);
rc = tos_hal_sd_write(&sd, sdio_aligned_buffer, sector_addr + 512 * i, 1, 2000);
buff += 512;
}
} else {
rc = tos_hal_sd_write(&sd, buff, sector_addr, nsectors, 2000);
}
TOS_CPU_INT_ENABLE();
return rc;
}
static int sd_ioctl(vfs_inode_t *dev, int cmd, unsigned long arg)
{
int rc = 0;
void *buff = (void *)arg;
if (cmd != CTRL_SYNC && !buff) {
return -1;
}
switch (cmd) {
case CTRL_SYNC:
break;
case GET_SECTOR_SIZE:
*(DWORD *)buff = sd_info.blk_size;
break;
case GET_BLOCK_SIZE:
*(WORD *)buff = sd_info.blk_size;
break;
case GET_SECTOR_COUNT:
*(DWORD *)buff = sd_info.blk_num;
break;
default:
rc = -1;
break;
}
return rc;
}
static int sd_geometry(vfs_inode_t *dev, vfs_blkdev_geo_t *geo)
{
hal_sd_info_t sd_info;
hal_sd_state_t sd_state;
if (!dev || !geo) {
return -1;
}
if (tos_hal_sd_info_get(&sd, &sd_info) != 0) {
return -1;
}
if (tos_hal_sd_state_get(&sd, &sd_state) != 0) {
return -1;
}
geo->is_available = (sd_state != HAL_SD_STAT_ERROR);
geo->sector_size = sd_info.blk_size;
geo->nsectors = sd_info.blk_num;
return 0;
}
vfs_blkdev_ops_t sd_dev = {
.open = sd_open,
.close = sd_close,
.read = sd_read,
.write = sd_write,
.ioctl = sd_ioctl,
.geometry = sd_geometry,
};