#include #include #include #include #include #include #include #include #include static void translate(size_t fs_block, size_t fs_block_count, size_t fs_block_size, size_t device_sector_size, size_t* out_phys_sector, size_t* out_sector_count) { size_t ratio = fs_block_size / device_sector_size; if (out_phys_sector != NULL) *out_phys_sector = fs_block * ratio; if (out_sector_count != NULL) *out_sector_count = fs_block_count * ratio; } static int fat_diskio_read(struct fatfs_ctx* ctx, uint32_t sector, uint8_t* buffer, uint32_t sector_count) { (void)ctx; int ret; size_t sector_size; size_t phys_sector, phys_sector_count; if (sector_count == 0) return 0; if ((ret = device_do(ctx->device_name, XDRV_GET_SECTOR_SIZE, §or_size, NULL, NULL, NULL)) < 0) return 0; translate(sector, sector_count, FAT_SECTOR_SIZE, sector_size, &phys_sector, &phys_sector_count); if ((ret = device_do(ctx->device_name, XDRV_READ, &phys_sector, &phys_sector_count, buffer, NULL)) < 0) return 0; if (ctx->update_cb != NULL) ctx->update_cb(phys_sector, phys_sector_count); return 1; } static int fat_diskio_write(struct fatfs_ctx* ctx, uint32_t sector, uint8_t* buffer, uint32_t sector_count) { (void)ctx; int ret; size_t sector_size; size_t phys_sector, phys_sector_count; if (sector_count == 0) return 0; if ((ret = device_do(ctx->device_name, XDRV_GET_SECTOR_SIZE, §or_size, NULL, NULL, NULL)) < 0) return 0; translate(sector, sector_count, FAT_SECTOR_SIZE, sector_size, &phys_sector, &phys_sector_count); if ((ret = device_do(ctx->device_name, XDRV_WRITE, &phys_sector, &phys_sector_count, buffer, NULL)) < 0) return 0; if (ctx->update_cb != NULL) ctx->update_cb(phys_sector, phys_sector_count); return 1; } int fat_format_drive(struct fatfs_ctx* ctx, const char* device_key, int fs_type) { memcpy(ctx->device_name, device_key, strlen(device_key)); int r = -1; size_t total_size = 0; if ((r = device_do(device_key, XDRV_GET_SIZE, &total_size, NULL, NULL, NULL)) < 0) return r; size_t sectors = ((total_size + FAT_SECTOR_SIZE) / FAT_SECTOR_SIZE); fl_init(ctx); ctx->_fs.disk_io.read_media = &fat_diskio_read; ctx->_fs.disk_io.write_media = &fat_diskio_write; r = -1; switch (fs_type) { case FS_FAT16: r = fatfs_format_fat16(ctx, &ctx->_fs, sectors, "mop3 fat16"); break; case FS_FAT32: r = fatfs_format_fat32(ctx, &ctx->_fs, sectors, "mop3 fat32"); break; default: break; } if (r < 0) return -ST_FORMAT_ERROR; return ST_OK; }