diff options
Diffstat (limited to 'stmhal/diskio.c')
-rw-r--r-- | stmhal/diskio.c | 322 |
1 files changed, 127 insertions, 195 deletions
diff --git a/stmhal/diskio.c b/stmhal/diskio.c index 9a4efd1a4d..998729a70d 100644 --- a/stmhal/diskio.c +++ b/stmhal/diskio.c @@ -35,17 +35,23 @@ #include "py/runtime.h" #include "lib/fatfs/ff.h" /* FatFs lower layer API */ #include "lib/fatfs/diskio.h" /* FatFs lower layer API */ -#include "storage.h" -#include "sdcard.h" #include "extmod/fsusermount.h" // constants for block protocol ioctl -//#define BP_IOCTL_INIT (1) // unused +#define BP_IOCTL_INIT (1) //#define BP_IOCTL_DEINIT (2) // unused #define BP_IOCTL_SYNC (3) #define BP_IOCTL_SEC_COUNT (4) #define BP_IOCTL_SEC_SIZE (5) +STATIC fs_user_mount_t *disk_get_device(uint id) { + if (id < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) { + return MP_STATE_PORT(fs_user_mount)[id]; + } else { + return NULL; + } +} + /*-----------------------------------------------------------------------*/ /* Initialize a Drive */ /*-----------------------------------------------------------------------*/ @@ -54,33 +60,27 @@ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber (0..) */ ) { - switch (pdrv) { -#if MICROPY_HW_HAS_FLASH - case PD_FLASH: - storage_init(); - return 0; -#endif - -#if MICROPY_HW_HAS_SDCARD - case PD_SDCARD: - if (!sdcard_power_on()) { - return STA_NODISK; - } - // TODO return STA_PROTECT if SD card is read only - return 0; -#endif + fs_user_mount_t *vfs = disk_get_device(pdrv); + if (vfs == NULL) { + return STA_NOINIT; + } - case PD_USER: - if (MP_STATE_PORT(fs_user_mount) == NULL) { - return STA_NODISK; - } - if (MP_STATE_PORT(fs_user_mount)->writeblocks[0] == MP_OBJ_NULL) { - return STA_PROTECT; - } - return 0; + if (vfs->flags & FSUSER_HAVE_IOCTL) { + // new protocol with ioctl; call ioctl(INIT, 0) + vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_INIT); + vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused + mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl); + if (MP_OBJ_SMALL_INT_VALUE(ret) != 0) { + // error initialising + return STA_NOINIT; + } } - return STA_NOINIT; + if (vfs->writeblocks[0] == MP_OBJ_NULL) { + return STA_PROTECT; + } else { + return 0; + } } /*-----------------------------------------------------------------------*/ @@ -91,28 +91,16 @@ DSTATUS disk_status ( BYTE pdrv /* Physical drive nmuber (0..) */ ) { - switch (pdrv) { - case PD_FLASH : - // flash is ready - return 0; - -#if MICROPY_HW_HAS_SDCARD - case PD_SDCARD: - // TODO return STA_PROTECT if SD card is read only - return 0; -#endif - - case PD_USER: - if (MP_STATE_PORT(fs_user_mount) == NULL) { - return STA_NODISK; - } - if (MP_STATE_PORT(fs_user_mount)->writeblocks[0] == MP_OBJ_NULL) { - return STA_PROTECT; - } - return 0; + fs_user_mount_t *vfs = disk_get_device(pdrv); + if (vfs == NULL) { + return STA_NOINIT; } - return STA_NOINIT; + if (vfs->writeblocks[0] == MP_OBJ_NULL) { + return STA_PROTECT; + } else { + return 0; + } } /*-----------------------------------------------------------------------*/ @@ -126,37 +114,24 @@ DRESULT disk_read ( UINT count /* Number of sectors to read (1..128) */ ) { - switch (pdrv) { -#if MICROPY_HW_HAS_FLASH - case PD_FLASH: - for (int i = 0; i < count; i++) { - if (!storage_read_block(buff + i * FLASH_BLOCK_SIZE, sector + i)) { - return RES_ERROR; - } - } - return RES_OK; -#endif - -#if MICROPY_HW_HAS_SDCARD - case PD_SDCARD: - if (sdcard_read_blocks(buff, sector, count) != 0) { - return RES_ERROR; - } - return RES_OK; -#endif + fs_user_mount_t *vfs = disk_get_device(pdrv); + if (vfs == NULL) { + return RES_PARERR; + } - case PD_USER: - if (MP_STATE_PORT(fs_user_mount) == NULL) { - // nothing mounted - return RES_ERROR; - } - MP_STATE_PORT(fs_user_mount)->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector); - MP_STATE_PORT(fs_user_mount)->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff); - mp_call_method_n_kw(2, 0, MP_STATE_PORT(fs_user_mount)->readblocks); - return RES_OK; + if (vfs->flags & FSUSER_NATIVE) { + mp_uint_t (*f)(uint8_t*, uint32_t, uint32_t) = (void*)vfs->readblocks[2]; + if (f(buff, sector, count) != 0) { + return RES_ERROR; + } + } else { + vfs->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector); + vfs->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff); + mp_call_method_n_kw(2, 0, vfs->readblocks); + // TODO handle error return } - return RES_PARERR; + return RES_OK; } /*-----------------------------------------------------------------------*/ @@ -171,41 +146,29 @@ DRESULT disk_write ( UINT count /* Number of sectors to write (1..128) */ ) { - switch (pdrv) { -#if MICROPY_HW_HAS_FLASH - case PD_FLASH: - for (int i = 0; i < count; i++) { - if (!storage_write_block(buff + i * FLASH_BLOCK_SIZE, sector + i)) { - return RES_ERROR; - } - } - return RES_OK; -#endif + fs_user_mount_t *vfs = disk_get_device(pdrv); + if (vfs == NULL) { + return RES_PARERR; + } -#if MICROPY_HW_HAS_SDCARD - case PD_SDCARD: - if (sdcard_write_blocks(buff, sector, count) != 0) { - return RES_ERROR; - } - return RES_OK; -#endif + if (vfs->writeblocks[0] == MP_OBJ_NULL) { + // read-only block device + return RES_WRPRT; + } - case PD_USER: - if (MP_STATE_PORT(fs_user_mount) == NULL) { - // nothing mounted - return RES_ERROR; - } - if (MP_STATE_PORT(fs_user_mount)->writeblocks[0] == MP_OBJ_NULL) { - // read-only block device - return RES_ERROR; - } - MP_STATE_PORT(fs_user_mount)->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector); - MP_STATE_PORT(fs_user_mount)->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void*)buff); - mp_call_method_n_kw(2, 0, MP_STATE_PORT(fs_user_mount)->writeblocks); - return RES_OK; + if (vfs->flags & FSUSER_NATIVE) { + mp_uint_t (*f)(const uint8_t*, uint32_t, uint32_t) = (void*)vfs->writeblocks[2]; + if (f(buff, sector, count) != 0) { + return RES_ERROR; + } + } else { + vfs->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector); + vfs->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void*)buff); + mp_call_method_n_kw(2, 0, vfs->writeblocks); + // TODO handle error return } - return RES_PARERR; + return RES_OK; } #endif @@ -221,100 +184,69 @@ DRESULT disk_ioctl ( void *buff /* Buffer to send/receive control data */ ) { - switch (pdrv) { -#if MICROPY_HW_HAS_FLASH - case PD_FLASH: - switch (cmd) { - case CTRL_SYNC: - storage_flush(); - return RES_OK; - - case GET_BLOCK_SIZE: - *((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) block size - return RES_OK; - } - break; -#endif + fs_user_mount_t *vfs = disk_get_device(pdrv); + if (vfs == NULL) { + return RES_PARERR; + } -#if MICROPY_HW_HAS_SDCARD - case PD_SDCARD: - switch (cmd) { - case CTRL_SYNC: - return RES_OK; + if (vfs->flags & FSUSER_HAVE_IOCTL) { + // new protocol with ioctl + switch (cmd) { + case CTRL_SYNC: + vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SYNC); + vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused + mp_call_method_n_kw(2, 0, vfs->u.ioctl); + return RES_OK; + + case GET_SECTOR_COUNT: { + vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SEC_COUNT); + vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused + mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl); + *((DWORD*)buff) = mp_obj_get_int(ret); + return RES_OK; + } + + case GET_SECTOR_SIZE: { + vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SEC_SIZE); + vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused + mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl); + *((WORD*)buff) = mp_obj_get_int(ret); + return RES_OK; + } + + case GET_BLOCK_SIZE: + *((DWORD*)buff) = 1; // erase block size in units of sector size + return RES_OK; + + default: + return RES_PARERR; + } + } else { + // old protocol with sync and count + switch (cmd) { + case CTRL_SYNC: + if (vfs->u.old.sync[0] != MP_OBJ_NULL) { + mp_call_method_n_kw(0, 0, vfs->u.old.sync); + } + return RES_OK; - case GET_BLOCK_SIZE: - *((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) block size - return RES_OK; + case GET_SECTOR_COUNT: { + mp_obj_t ret = mp_call_method_n_kw(0, 0, vfs->u.old.count); + *((DWORD*)buff) = mp_obj_get_int(ret); + return RES_OK; } - break; -#endif - case PD_USER: { - fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount); - if (vfs == NULL) { - // nothing mounted - return RES_ERROR; - } - if (vfs->u.old.count[1] == MP_OBJ_SENTINEL) { - // new protocol with ioctl - switch (cmd) { - case CTRL_SYNC: - vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SYNC); - vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused - mp_call_method_n_kw(2, 0, vfs->u.ioctl); - vfs->u.ioctl[3] = MP_OBJ_SENTINEL; // indicate new protocol - return RES_OK; - - case GET_SECTOR_COUNT: { - vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SEC_COUNT); - vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused - mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl); - *((DWORD*)buff) = mp_obj_get_int(ret); - vfs->u.ioctl[3] = MP_OBJ_SENTINEL; // indicate new protocol - return RES_OK; - } - - case GET_SECTOR_SIZE: { - vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SEC_SIZE); - vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused - mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl); - *((WORD*)buff) = mp_obj_get_int(ret); - vfs->u.ioctl[3] = MP_OBJ_SENTINEL; // indicate new protocol - return RES_OK; - } - - case GET_BLOCK_SIZE: - *((DWORD*)buff) = 1; // erase block size in units of sector size - return RES_OK; - } - } else { - // old protocol with sync and count - switch (cmd) { - case CTRL_SYNC: - if (vfs->u.old.sync[0] != MP_OBJ_NULL) { - mp_call_method_n_kw(0, 0, vfs->u.old.sync); - } - return RES_OK; - - case GET_SECTOR_COUNT: { - mp_obj_t ret = mp_call_method_n_kw(0, 0, vfs->u.old.count); - *((DWORD*)buff) = mp_obj_get_int(ret); - return RES_OK; - } - - case GET_SECTOR_SIZE: - *((WORD*)buff) = 512; // old protocol had fixed sector size - return RES_OK; - - case GET_BLOCK_SIZE: - *((DWORD*)buff) = 1; // erase block size in units of sector size - return RES_OK; - } - } - break; + case GET_SECTOR_SIZE: + *((WORD*)buff) = 512; // old protocol had fixed sector size + return RES_OK; + + case GET_BLOCK_SIZE: + *((DWORD*)buff) = 1; // erase block size in units of sector size + return RES_OK; + + default: + return RES_PARERR; } } - - return RES_PARERR; } #endif |