summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHierophect <hierophect@gmail.com>2019-08-09 19:58:54 -0400
committerHierophect <hierophect@gmail.com>2019-08-09 19:58:54 -0400
commit294d6dc8673d3c288033ac226ff1d695b8df1073 (patch)
tree860c1c2240e95f14d63e33a957a99d929fa08fd8
parentc375a5d37f8fa3016b0a328b3efaa165094e6387 (diff)
Add flash functions and setup, fix msc descriptor bug
-rw-r--r--ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.h12
-rw-r--r--ports/stm32f4/boards/stm32f411ve_discovery/mpconfigboard.mk3
-rw-r--r--ports/stm32f4/supervisor/internal_flash.c114
-rw-r--r--ports/stm32f4/supervisor/internal_flash.h19
-rw-r--r--tools/gen_usb_descriptor.py4
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 1b1410aea..1bb5849af 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 7c4e3be3a..747d34ebe 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 e05236948..fab067818 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 <stdint.h>
#include <string.h>
@@ -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 8c015a3e4..4d720913f 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 db17c9766..a5667dd46 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)