From 294d6dc8673d3c288033ac226ff1d695b8df1073 Mon Sep 17 00:00:00 2001 From: Hierophect Date: Fri, 9 Aug 2019 19:58:54 -0400 Subject: [PATCH] Add flash functions and setup, fix msc descriptor bug --- .../stm32f411ve_discovery/mpconfigboard.h | 12 +- .../stm32f411ve_discovery/mpconfigboard.mk | 3 + ports/stm32f4/supervisor/internal_flash.c | 114 +++++++++++++++++- ports/stm32f4/supervisor/internal_flash.h | 19 ++- tools/gen_usb_descriptor.py | 4 +- 5 files changed, 139 insertions(+), 13 deletions(-) diff --git a/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h index 1b1410aea2..1bb5849afa 100644 --- a/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h +++ b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h @@ -30,11 +30,13 @@ #define MICROPY_HW_BOARD_NAME "STM32F411E_DISCO" #define MICROPY_HW_MCU_NAME "STM32F411xE" -#define FLASH_SIZE (0x7D000) -#define FLASH_PAGE_SIZE (0x4000) +// #define FLASH_SIZE (0x7D000) +// #define FLASH_PAGE_SIZE (0x4000) #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 -#define CIRCUITPY_INTERNAL_NVM_SIZE (4096) -#define AUTORESET_DELAY_MS 500 -#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) \ No newline at end of file +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x8080000 - 0x2000 - 0x019000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define AUTORESET_DELAY_MS 500 \ No newline at end of file diff --git a/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk index 7c4e3be3a3..747d34ebe4 100644 --- a/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk +++ b/ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk @@ -3,6 +3,9 @@ USB_PID = 0x802A USB_PRODUCT = "STM32F411VE Discovery Board - CPy" USB_MANUFACTURER = "Adafruit Industries LLC" +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + MCU_SERIES = m4 MCU_VARIANT = stm32f4 MCU_SUB_VARIANT = stm32f411xe diff --git a/ports/stm32f4/supervisor/internal_flash.c b/ports/stm32f4/supervisor/internal_flash.c index e052369481..fab0678182 100644 --- a/ports/stm32f4/supervisor/internal_flash.c +++ b/ports/stm32f4/supervisor/internal_flash.c @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "supervisor/flash.h" +#include "supervisor/internal_flash.h" #include #include @@ -35,11 +35,56 @@ #include "py/runtime.h" #include "lib/oofatfs/ff.h" +#include "stm32f4xx_hal.h" + +typedef struct { + uint32_t base_address; + uint32_t sector_size; + uint32_t sector_count; +} flash_layout_t; /*------------------------------------------------------------------*/ /* Internal Flash API *------------------------------------------------------------------*/ +static const flash_layout_t flash_layout[] = { + { 0x08000000, 0x04000, 4 }, + { 0x08010000, 0x10000, 1 }, + { 0x08020000, 0x20000, 3 }, + #if defined(FLASH_SECTOR_8) + { 0x08080000, 0x20000, 4 }, + #endif + #if defined(FLASH_SECTOR_12) + { 0x08100000, 0x04000, 4 }, + { 0x08110000, 0x10000, 1 }, + { 0x08120000, 0x20000, 7 }, + #endif +}; + +uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size) { + if (addr >= flash_layout[0].base_address) { + uint32_t sector_index = 0; + for (int i = 0; i < MP_ARRAY_SIZE(flash_layout); ++i) { + for (int j = 0; j < flash_layout[i].sector_count; ++j) { + uint32_t sector_start_next = flash_layout[i].base_address + + (j + 1) * flash_layout[i].sector_size; + if (addr < sector_start_next) { + if (start_addr != NULL) { + *start_addr = flash_layout[i].base_address + + j * flash_layout[i].sector_size; + } + if (size != NULL) { + *size = flash_layout[i].sector_size; + } + return sector_index; + } + ++sector_index; + } + } + } + return 0; +} + void supervisor_flash_init(void) { } @@ -48,21 +93,82 @@ uint32_t supervisor_flash_get_block_size(void) { } uint32_t supervisor_flash_get_block_count(void) { - return false; + return INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS; } void supervisor_flash_flush(void) { +} +static int32_t convert_block_to_flash_addr(uint32_t block) { + if (0 <= block && block < INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS) { + // a block in partition 1 + return INTERNAL_FLASH_FILESYSTEM_START_ADDR + block * FILESYSTEM_BLOCK_SIZE; + } + // bad block + return -1; } mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { - + uint32_t src = convert_block_to_flash_addr(block); + if (src == -1) { + // bad block number + return false; + } + memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE*num_blocks); return 0; // success } -mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) { +bool supervisor_flash_write_block(const uint8_t *src, uint32_t block) { + int32_t dest = convert_block_to_flash_addr(block); + if (dest == -1) { + // bad block number + return false; + } + // unlock + HAL_FLASH_Unlock(); + FLASH_EraseInitTypeDef EraseInitStruct; + + // erase the sector(s) + EraseInitStruct.TypeErase = TYPEERASE_SECTORS; + EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V + //get the sector number + EraseInitStruct.Sector = flash_get_sector_info(dest, NULL, NULL); + //find end address, subtract for number of sectors + EraseInitStruct.NbSectors = flash_get_sector_info(dest + FILESYSTEM_BLOCK_SIZE - 1, NULL, NULL) - EraseInitStruct.Sector + 1; + + uint32_t SectorError = 0; + if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) { + // error occurred during sector erase + HAL_FLASH_Lock(); // lock the flash + return false; + } + + // program the flash word by word + for (int i = 0; i < (FILESYSTEM_BLOCK_SIZE / 4); i++) { + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, dest, *src) != HAL_OK) { + // error occurred during flash write + HAL_FLASH_Lock(); // lock the flash + return false; + } + dest += 4; + src += 1; //src += 4; + } + + // lock the flash + HAL_FLASH_Lock(); + + return true; +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { + + for (size_t i = 0; i < num_blocks; i++) { + if (!supervisor_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { + return 1; // error + } + } return 0; // success } diff --git a/ports/stm32f4/supervisor/internal_flash.h b/ports/stm32f4/supervisor/internal_flash.h index 8c015a3e46..4d720913fd 100644 --- a/ports/stm32f4/supervisor/internal_flash.h +++ b/ports/stm32f4/supervisor/internal_flash.h @@ -31,7 +31,22 @@ #include "py/mpconfig.h" -#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms -#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) +#ifdef STM32F411xE +#define STM32_FLASH_SIZE 0x80000 //512KiB +#define INTERNAL_FLASH_FILESYSTEM_SIZE 0x19000 //100KiB +#endif + +#ifdef STM32F412Zx +#define STM32_FLASH_SIZE 0x100000 //512KiB +#define INTERNAL_FLASH_FILESYSTEM_SIZE 0x19000 //100KiB +#endif + +#define STM32_FLASH_OFFSET 0x8000000 //All STM32 chips map to this flash location + +#define INTERNAL_FLASH_FILESYSTEM_START_ADDR ((STM32_FLASH_SIZE + STM32_FLASH_OFFSET) - INTERNAL_FLASH_FILESYSTEM_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE) +#define INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS (INTERNAL_FLASH_FILESYSTEM_SIZE / FILESYSTEM_BLOCK_SIZE) + +// #define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms +// #define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) #endif // MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_H diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py index db17c97666..a5667dd46e 100644 --- a/tools/gen_usb_descriptor.py +++ b/tools/gen_usb_descriptor.py @@ -131,7 +131,7 @@ msc_interfaces = [ bInterval=0), standard.EndpointDescriptor( description="MSC out", - bEndpointAddress=0x1 | standard.EndpointDescriptor.DIRECTION_OUT, + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT, bmAttributes=standard.EndpointDescriptor.TYPE_BULK, bInterval=0) ] @@ -273,7 +273,7 @@ cdc_iad = standard.InterfaceAssociationDescriptor( descriptor_list = [] descriptor_list.append(cdc_iad) descriptor_list.extend(cdc_interfaces) -# descriptor_list.extend(msc_interfaces) +descriptor_list.extend(msc_interfaces) # Only add the control interface because other audio interfaces are managed by it to ensure the # correct ordering. # descriptor_list.append(audio_control_interface)