Skip to content

Commit e2be069

Browse files
committed
Support cached internal flash on the H743
1 parent 7995bca commit e2be069

File tree

13 files changed

+485
-135
lines changed

13 files changed

+485
-135
lines changed

ports/stm/Makefile

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,7 @@ SRC_STM32 = $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES_LOWER)xx_,\
187187
ll_rcc.c \
188188
ll_utils.c \
189189
ll_exti.c \
190-
)
191-
#removed:
192-
# hal_flash_ramfunc.c \
193-
# ll_fsmc.c \
190+
)
194191

195192
SRC_STM32 += system_stm32$(MCU_SERIES_LOWER)xx.c
196193

ports/stm/boards/stm32h743zi_discovery/mpconfigboard.mk renamed to ports/stm/boards/stm32h743zi2_discovery/mpconfigboard.mk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ USB_VID = 0x239A #REPLACE
22
USB_PID = 0x808A #REPLACE
33
USB_PRODUCT = "STM32H743ZI Discovery Board - CPy"
44
USB_MANUFACTURER = "STMicroelectronics"
5-
USB_DEVICES = "CDC,HID"
5+
USB_DEVICES = "CDC,MSC"
66

7-
DISABLE_FILESYSTEM = 1
7+
INTERNAL_FLASH_FILESYSTEM = 1
88

99
MCU_SERIES = H7
1010
MCU_VARIANT = STM32H743xx

ports/stm/boards/stm32h743zi_discovery/pins.c renamed to ports/stm/boards/stm32h743zi2_discovery/pins.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
8686
{ MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_PA04) },
8787
{ MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_PA05) },
8888
{ MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_PB00) },
89-
{ MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PB07) },
89+
{ MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PE01) },
9090
{ MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_PB14) },
9191
{ MP_ROM_QSTR(MP_QSTR_SW), MP_ROM_PTR(&pin_PC13) },
9292
{ MP_ROM_QSTR(MP_QSTR_I2C1_SDA), MP_ROM_PTR(&pin_PB09) },

ports/stm/peripherals/periph.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@
3333
#include STM32_HAL_H
3434
#include "pins.h"
3535

36-
// PERIPH
36+
// Comm Peripherals
3737

3838
typedef struct {
39-
uint8_t periph_index:4; // Index of the I2C unit (1 to 3)
40-
uint8_t altfn_index:4; //Index of the altfn for this pin (0 to 15)
41-
const mcu_pin_obj_t * pin;
39+
uint8_t periph_index:4; // Index of the peripheral instance
40+
uint8_t altfn_index:4; // Index of the altfn for this pin (0 to 15)
41+
const mcu_pin_obj_t * pin; // Pin Object
4242
} mcu_periph_obj_t;
4343

4444
#define PERIPH(index, alt, p_pin) \
@@ -48,7 +48,8 @@ typedef struct {
4848
.pin = p_pin, \
4949
}
5050

51-
//Timers
51+
// Timer Peripheral
52+
5253
typedef struct {
5354
uint8_t tim_index:4;
5455
uint8_t altfn_index:4;

ports/stm/supervisor/internal_flash.c

Lines changed: 129 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* The MIT License (MIT)
55
*
66
* Copyright (c) 2013, 2014 Damien P. George
7-
* Copyright (c) 2019 Lucian Copeland for Adafruit Industries
7+
* Copyright (c) 2020 Lucian Copeland for Adafruit Industries
88
*
99
* Permission is hereby granted, free of charge, to any person obtaining a copy
1010
* of this software and associated documentation files (the "Software"), to deal
@@ -35,6 +35,7 @@
3535
#include "py/obj.h"
3636
#include "py/runtime.h"
3737
#include "lib/oofatfs/ff.h"
38+
#include "supervisor/shared/safe_mode.h"
3839

3940
typedef struct {
4041
uint32_t base_address;
@@ -46,7 +47,9 @@ typedef struct {
4647
/* Internal Flash API
4748
*------------------------------------------------------------------*/
4849

49-
static const flash_layout_t flash_layout[] = {
50+
#if defined(STM32F4)
51+
52+
STATIC const flash_layout_t flash_layout[] = {
5053
{ 0x08000000, 0x04000, 4 },
5154
{ 0x08010000, 0x10000, 1 },
5255
{ 0x08020000, 0x20000, 3 },
@@ -59,12 +62,45 @@ static const flash_layout_t flash_layout[] = {
5962
{ 0x08120000, 0x20000, 7 },
6063
#endif
6164
};
65+
STATIC uint8_t _flash_cache[0x4000] __attribute__((aligned(4)));
66+
67+
#elif defined(STM32H7)
68+
69+
STATIC const flash_layout_t flash_layout[] = {
70+
{ 0x08000000, 0x20000, 16 },
71+
};
72+
STATIC uint8_t _flash_cache[0x20000] __attribute__((aligned(4)));
73+
74+
#else
75+
#error Unsupported processor
76+
#endif
6277

6378
#define NO_CACHE 0xffffffff
6479
#define MAX_CACHE 0x4000
6580

66-
static uint8_t _flash_cache[0x4000] __attribute__((aligned(4)));
67-
static uint32_t _cache_flash_addr = NO_CACHE;
81+
82+
STATIC uint32_t _cache_flash_addr = NO_CACHE;
83+
84+
#if defined(STM32H7)
85+
// get the bank of a given flash address
86+
STATIC uint32_t get_bank(uint32_t addr) {
87+
if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_SWAP_BANK) == 0) {
88+
// no bank swap
89+
if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
90+
return FLASH_BANK_1;
91+
} else {
92+
return FLASH_BANK_2;
93+
}
94+
} else {
95+
// bank swap
96+
if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
97+
return FLASH_BANK_2;
98+
} else {
99+
return FLASH_BANK_1;
100+
}
101+
}
102+
}
103+
#endif
68104

69105
//Return the sector of a given flash address.
70106
uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size) {
@@ -105,50 +141,98 @@ uint32_t supervisor_flash_get_block_count(void) {
105141
void supervisor_flash_flush(void) {
106142
if (_cache_flash_addr == NO_CACHE) return;
107143

144+
#if defined(STM32H7)
145+
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK2);
146+
#else
147+
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
148+
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
149+
#endif
150+
151+
// set up for erase
152+
FLASH_EraseInitTypeDef EraseInitStruct;
153+
EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
154+
EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
155+
// get the sector information
156+
uint32_t sector_size;
157+
uint32_t sector_start_addr;
158+
#if defined(STM32H7)
159+
EraseInitStruct.Banks = get_bank(_cache_flash_addr);
160+
#endif
161+
EraseInitStruct.Sector = flash_get_sector_info(_cache_flash_addr, &sector_start_addr, &sector_size);
162+
EraseInitStruct.NbSectors = 1;
163+
if (sector_size > sizeof(_flash_cache)) {
164+
__ASM volatile ("bkpt");
165+
mp_printf(&mp_plat_print, "FLASH ERR: invalid sector\n");
166+
reset_into_safe_mode(FLASH_WRITE_FAIL);
167+
}
168+
108169
// Skip if data is the same
109-
if (memcmp(_flash_cache, (void *)_flash_page_addr, FLASH_PAGE_SIZE) != 0) {
170+
if (memcmp(_flash_cache, (void *)_cache_flash_addr, sector_size) != 0) {
110171
// unlock flash
111172
HAL_FLASH_Unlock();
112173

113-
// set up for erase
114-
FLASH_EraseInitTypeDef EraseInitStruct;
115-
EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
116-
EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
117-
// get the sector information
118-
uint32_t sector_size;
119-
uint32_t sector_start_addr;
120-
EraseInitStruct.Sector = flash_get_sector_info(_cache_flash_addr, &sector_start_addr, &sector_size);
121-
EraseInitStruct.NbSectors = 1;
122-
if (sector_size>0x4000) return false;
123-
124174
// erase the sector
125175
uint32_t SectorError = 0;
126176
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
127177
// error occurred during sector erase
128178
HAL_FLASH_Lock(); // lock the flash
129-
mp_printf(&mp_plat_print, "FLASH SECTOR ERASE ERROR");
130-
return false;
179+
__ASM volatile ("bkpt");
180+
mp_printf(&mp_plat_print, "FLASH ERR: erase failure\n");
181+
reset_into_safe_mode(FLASH_WRITE_FAIL);
131182
}
132183

133-
__HAL_FLASH_DATA_CACHE_DISABLE();
134-
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
135-
136-
__HAL_FLASH_DATA_CACHE_RESET();
137-
__HAL_FLASH_INSTRUCTION_CACHE_RESET();
138-
139-
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
140-
__HAL_FLASH_DATA_CACHE_ENABLE();
184+
// __HAL_FLASH_DATA_CACHE_DISABLE();
185+
// __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
186+
187+
// __HAL_FLASH_DATA_CACHE_RESET();
188+
// __HAL_FLASH_INSTRUCTION_CACHE_RESET();
189+
190+
// __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
191+
// __HAL_FLASH_DATA_CACHE_ENABLE();
192+
193+
// // reprogram the sector
194+
// for (uint32_t i = 0; i < sector_size; i++) {
195+
// if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, sector_start_addr, (uint64_t)_flash_cache[i]) != HAL_OK) {
196+
// // error occurred during flash write
197+
// HAL_FLASH_Lock(); // lock the flash
198+
// mp_printf(&mp_plat_print, "FLASH WRITE ERROR");
199+
// }
200+
// sector_start_addr += 1;
201+
// }
202+
203+
uint32_t * cache_addr = (uint32_t*)_flash_cache;
204+
205+
#if defined(STM32H7)
206+
for (uint32_t i = 0; i < (sector_size / 32); i++) {
207+
// Note that the STM32H7 HAL interface differs by taking an address, not 64 bit data
208+
// This is because ST's code is written by a large room of chimpanzees
209+
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, sector_start_addr,
210+
(uint32_t)cache_addr) != HAL_OK) {
211+
// error occurred during flash write
212+
HAL_FLASH_Lock(); // lock the flash
213+
__ASM volatile ("bkpt");
214+
reset_into_safe_mode(FLASH_WRITE_FAIL);
215+
}
216+
// RAM memory is by word (4 byte), but flash memory is by byte
217+
cache_addr += 8;
218+
sector_start_addr += 32;
219+
}
141220

142-
// reprogram the sector
143-
for (uint32_t i = 0; i < sector_size; i++) {
144-
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, sector_start_addr, (uint64_t)_flash_cache[i]) != HAL_OK) {
221+
#else // STM32F4
222+
// program the flash word by word
223+
for (uint32_t i = 0; i < sector_size / 4; i++) {
224+
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, sector_start_addr,
225+
(uint64_t)*cache_addr) != HAL_OK) {
145226
// error occurred during flash write
146227
HAL_FLASH_Lock(); // lock the flash
147-
mp_printf(&mp_plat_print, "FLASH WRITE ERROR");
148-
return false;
228+
__ASM volatile ("bkpt");
229+
reset_into_safe_mode(FLASH_WRITE_FAIL);
149230
}
150-
sector_start_addr += 1;
231+
// RAM memory is by word (4 byte), but flash memory is by byte
232+
cache_addr += 1;
233+
sector_start_addr += 4;
151234
}
235+
#endif
152236

153237
// lock the flash
154238
HAL_FLASH_Lock();
@@ -165,6 +249,9 @@ static int32_t convert_block_to_flash_addr(uint32_t block) {
165249
}
166250

167251
mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
252+
// Must write out anything in cache before trying to read.
253+
supervisor_flash_flush();
254+
168255
int32_t src = convert_block_to_flash_addr(block);
169256
if (src == -1) {
170257
// bad block number
@@ -174,103 +261,33 @@ mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t n
174261
return 0; // success
175262
}
176263

177-
bool supervisor_flash_write_block(const uint8_t *src, uint32_t block) {
178-
int32_t dest = convert_block_to_flash_addr(block);
179-
if (dest == -1) {
180-
// bad block number
181-
mp_printf(&mp_plat_print, "BAD FLASH BLOCK ERROR");
182-
return false;
183-
}
184-
185-
// unlock flash
186-
HAL_FLASH_Unlock();
187-
188-
// set up for erase
189-
FLASH_EraseInitTypeDef EraseInitStruct;
190-
EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
191-
EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
192-
// get the sector information
193-
uint32_t sector_size;
194-
uint32_t sector_start_addr;
195-
EraseInitStruct.Sector = flash_get_sector_info(dest, &sector_start_addr, &sector_size);
196-
EraseInitStruct.NbSectors = 1;
197-
if (sector_size>0x4000) return false;
198-
199-
// copy the sector
200-
memcpy(sector_copy,(void *)sector_start_addr,sector_size);
201-
202-
// // overwrite sector data
203-
memcpy(sector_copy+(dest-sector_start_addr),src,FILESYSTEM_BLOCK_SIZE);
204-
205-
// find end address, subtract for number of sectors
206-
// Shouldn't be required since blocks will always fit in a single sector, they should never overlap
207-
//EraseInitStruct.NbSectors = flash_get_sector_info(dest + FILESYSTEM_BLOCK_SIZE - 1, NULL, NULL) - EraseInitStruct.Sector + 1;
208-
209-
// erase the sector
210-
uint32_t SectorError = 0;
211-
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
212-
// error occurred during sector erase
213-
HAL_FLASH_Lock(); // lock the flash
214-
mp_printf(&mp_plat_print, "FLASH SECTOR ERASE ERROR");
215-
return false;
216-
}
217-
218-
__HAL_FLASH_DATA_CACHE_DISABLE();
219-
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
220-
221-
__HAL_FLASH_DATA_CACHE_RESET();
222-
__HAL_FLASH_INSTRUCTION_CACHE_RESET();
223-
224-
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
225-
__HAL_FLASH_DATA_CACHE_ENABLE();
226-
227-
// reprogram the sector
228-
for (uint32_t i = 0; i < sector_size; i++) {
229-
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, sector_start_addr, (uint64_t)sector_copy[i]) != HAL_OK) {
230-
// error occurred during flash write
231-
HAL_FLASH_Lock(); // lock the flash
232-
mp_printf(&mp_plat_print, "FLASH WRITE ERROR");
233-
return false;
234-
}
235-
sector_start_addr += 1;
236-
}
237-
238-
// lock the flash
239-
HAL_FLASH_Lock();
240-
241-
return true;
242-
}
243-
244-
// mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
245-
246-
// for (size_t i = 0; i < num_blocks; i++) {
247-
// if (!supervisor_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) {
248-
// return 1; // error
249-
// }
250-
// }
251-
// return 0; // success
252-
// }
253-
254264
mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
255265
while (num_blocks) {
256-
int32_t dest = convert_block_to_flash_addr(block);
266+
int32_t dest = convert_block_to_flash_addr(block_num);
257267
if (dest == -1) {
258268
// bad block number
269+
__ASM volatile ("bkpt");
259270
mp_printf(&mp_plat_print, "BAD FLASH BLOCK ERROR");
260271
return false;
261272
}
262273

263274
// unlock flash
264275
HAL_FLASH_Unlock();
265276

277+
uint32_t sector_size;
278+
uint32_t sector_start_addr;
266279
flash_get_sector_info(dest, &sector_start_addr, &sector_size);
267280

268281
// Fail for any sector outside the 16k ones for now
269-
if (sector_size > 0x4000) return false;
282+
if (sector_size > sizeof(_flash_cache)) {
283+
__ASM volatile ("bkpt");
284+
mp_printf(&mp_plat_print, "FLASH ERR: invalid sector\n");
285+
reset_into_safe_mode(FLASH_WRITE_FAIL);
286+
}
270287

271288
// Find how many blocks are left in the sector
272289
uint32_t count = (sector_size - (dest - sector_start_addr))/FILESYSTEM_BLOCK_SIZE;
273-
count = MIN(num_blocks, count); `
290+
count = MIN(num_blocks, count);
274291

275292
if (_cache_flash_addr != sector_start_addr) {
276293
// Write out anything in cache before overwriting it.

0 commit comments

Comments
 (0)