diff options
Diffstat (limited to 'stmhal/storage.c')
-rw-r--r-- | stmhal/storage.c | 116 |
1 files changed, 107 insertions, 9 deletions
diff --git a/stmhal/storage.c b/stmhal/storage.c index 14b504d716..d0f2782856 100644 --- a/stmhal/storage.c +++ b/stmhal/storage.c @@ -29,8 +29,8 @@ #include "py/obj.h" #include "py/runtime.h" -#include "lib/fatfs/ff.h" -#include "extmod/fsusermount.h" +#include "lib/oofatfs/ff.h" +#include "extmod/vfs_fat.h" #include "systick.h" #include "led.h" @@ -38,6 +38,14 @@ #include "storage.h" #include "irq.h" +#if defined(MICROPY_HW_SPIFLASH_SIZE_BITS) +#define USE_INTERNAL (0) +#else +#define USE_INTERNAL (1) +#endif + +#if USE_INTERNAL + #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) #define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k @@ -141,7 +149,7 @@ static uint8_t *flash_cache_get_addr_for_write(uint32_t flash_addr) { flash_cache_sector_size = flash_sector_size; } flash_flags |= FLASH_FLAG_DIRTY; - led_state(PYB_LED_R1, 1); // indicate a dirty cache with LED on + led_state(PYB_LED_RED, 1); // indicate a dirty cache with LED on flash_tick_counter_last_write = HAL_GetTick(); return (uint8_t*)CACHE_MEM_START_ADDR + flash_addr - flash_sector_start; } @@ -158,19 +166,50 @@ static uint8_t *flash_cache_get_addr_for_read(uint32_t flash_addr) { return (uint8_t*)flash_addr; } +#else + +#include "drivers/memory/spiflash.h" +#include "genhdr/pins.h" + +#define FLASH_PART1_START_BLOCK (0x100) +#define FLASH_PART1_NUM_BLOCKS (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE) + +static bool flash_is_initialised = false; + +STATIC const mp_spiflash_t spiflash = { + .cs = &MICROPY_HW_SPIFLASH_CS, + .spi = { + .base = {&mp_machine_soft_spi_type}, + .delay_half = MICROPY_PY_MACHINE_SPI_MIN_DELAY, + .polarity = 0, + .phase = 0, + .sck = &MICROPY_HW_SPIFLASH_SCK, + .mosi = &MICROPY_HW_SPIFLASH_MOSI, + .miso = &MICROPY_HW_SPIFLASH_MISO, + }, +}; + +#endif + void storage_init(void) { if (!flash_is_initialised) { + #if USE_INTERNAL flash_flags = 0; flash_cache_sector_id = 0; flash_tick_counter_last_write = 0; + #else + mp_spiflash_init((mp_spiflash_t*)&spiflash); + #endif flash_is_initialised = true; } + #if USE_INTERNAL // Enable the flash IRQ, which is used to also call our storage IRQ handler // It needs to go at a higher priority than all those components that rely on // the flash storage (eg higher than USB MSC). HAL_NVIC_SetPriority(FLASH_IRQn, IRQ_PRI_FLASH, IRQ_SUBPRI_FLASH); HAL_NVIC_EnableIRQ(FLASH_IRQn); + #endif } uint32_t storage_get_block_size(void) { @@ -182,6 +221,8 @@ uint32_t storage_get_block_count(void) { } void storage_irq_handler(void) { + #if USE_INTERNAL + if (!(flash_flags & FLASH_FLAG_DIRTY)) { return; } @@ -220,12 +261,16 @@ void storage_irq_handler(void) { // clear the flash flags now that we have a clean cache flash_flags = 0; // indicate a clean cache with LED off - led_state(PYB_LED_R1, 0); + led_state(PYB_LED_RED, 0); } + + #endif } void storage_flush(void) { + #if USE_INTERNAL flash_cache_flush(); + #endif } static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_block, uint32_t num_blocks) { @@ -264,6 +309,8 @@ static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_blo buf[15] = num_blocks >> 24; } +#if USE_INTERNAL + static uint32_t convert_block_to_flash_addr(uint32_t block) { if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) { // a block in partition 1 @@ -279,6 +326,8 @@ static uint32_t convert_block_to_flash_addr(uint32_t block) { return -1; } +#endif + bool storage_read_block(uint8_t *dest, uint32_t block) { //printf("RD %u\n", block); if (block == 0) { @@ -299,6 +348,8 @@ bool storage_read_block(uint8_t *dest, uint32_t block) { return true; } else { + #if USE_INTERNAL + // non-MBR block, get data from flash memory, possibly via cache uint32_t flash_addr = convert_block_to_flash_addr(block); if (flash_addr == -1) { @@ -308,6 +359,27 @@ bool storage_read_block(uint8_t *dest, uint32_t block) { uint8_t *src = flash_cache_get_addr_for_read(flash_addr); memcpy(dest, src, FLASH_BLOCK_SIZE); return true; + + #else + + // non-MBR block, get data from SPI flash + + if (block < FLASH_PART1_START_BLOCK || block >= FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) { + // bad block number + return false; + } + + // we must disable USB irqs to prevent MSC contention with SPI flash + uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS); + + mp_spiflash_read((mp_spiflash_t*)&spiflash, + (block - FLASH_PART1_START_BLOCK) * FLASH_BLOCK_SIZE, FLASH_BLOCK_SIZE, dest); + + restore_irq_pri(basepri); + + return true; + + #endif } } @@ -318,6 +390,8 @@ bool storage_write_block(const uint8_t *src, uint32_t block) { return true; } else { + #if USE_INTERNAL + // non-MBR block, copy to cache uint32_t flash_addr = convert_block_to_flash_addr(block); if (flash_addr == -1) { @@ -327,6 +401,27 @@ bool storage_write_block(const uint8_t *src, uint32_t block) { uint8_t *dest = flash_cache_get_addr_for_write(flash_addr); memcpy(dest, src, FLASH_BLOCK_SIZE); return true; + + #else + + // non-MBR block, write to SPI flash + + if (block < FLASH_PART1_START_BLOCK || block >= FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) { + // bad block number + return false; + } + + // we must disable USB irqs to prevent MSC contention with SPI flash + uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS); + + int ret = mp_spiflash_write((mp_spiflash_t*)&spiflash, + (block - FLASH_PART1_START_BLOCK) * FLASH_BLOCK_SIZE, FLASH_BLOCK_SIZE, src); + + restore_irq_pri(basepri); + + return ret == 0; + + #endif } } @@ -393,10 +488,10 @@ STATIC mp_obj_t pyb_flash_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) } STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_flash_ioctl_obj, pyb_flash_ioctl); -STATIC const mp_map_elem_t pyb_flash_locals_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_readblocks), (mp_obj_t)&pyb_flash_readblocks_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_writeblocks), (mp_obj_t)&pyb_flash_writeblocks_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&pyb_flash_ioctl_obj }, +STATIC const mp_rom_map_elem_t pyb_flash_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&pyb_flash_readblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&pyb_flash_writeblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&pyb_flash_ioctl_obj) }, }; STATIC MP_DEFINE_CONST_DICT(pyb_flash_locals_dict, pyb_flash_locals_dict_table); @@ -405,11 +500,14 @@ const mp_obj_type_t pyb_flash_type = { { &mp_type_type }, .name = MP_QSTR_Flash, .make_new = pyb_flash_make_new, - .locals_dict = (mp_obj_t)&pyb_flash_locals_dict, + .locals_dict = (mp_obj_dict_t*)&pyb_flash_locals_dict, }; void pyb_flash_init_vfs(fs_user_mount_t *vfs) { + vfs->base.type = &mp_fat_vfs_type; vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL; + vfs->fatfs.drv = vfs; + vfs->fatfs.part = 1; // flash filesystem lives on first partition vfs->readblocks[0] = (mp_obj_t)&pyb_flash_readblocks_obj; vfs->readblocks[1] = (mp_obj_t)&pyb_flash_obj; vfs->readblocks[2] = (mp_obj_t)storage_read_blocks; // native version |