Skip to content

Commit 7995bca

Browse files
committed
Flash additions
1 parent 348df4b commit 7995bca

File tree

1 file changed

+101
-6
lines changed

1 file changed

+101
-6
lines changed

ports/stm/supervisor/internal_flash.c

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636
#include "py/runtime.h"
3737
#include "lib/oofatfs/ff.h"
3838

39-
#include "stm32f4xx_hal.h"
40-
4139
typedef struct {
4240
uint32_t base_address;
4341
uint32_t sector_size;
@@ -62,7 +60,11 @@ static const flash_layout_t flash_layout[] = {
6260
#endif
6361
};
6462

65-
static uint8_t sector_copy[0x4000] __attribute__((aligned(4)));
63+
#define NO_CACHE 0xffffffff
64+
#define MAX_CACHE 0x4000
65+
66+
static uint8_t _flash_cache[0x4000] __attribute__((aligned(4)));
67+
static uint32_t _cache_flash_addr = NO_CACHE;
6668

6769
//Return the sector of a given flash address.
6870
uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size) {
@@ -101,6 +103,56 @@ uint32_t supervisor_flash_get_block_count(void) {
101103
}
102104

103105
void supervisor_flash_flush(void) {
106+
if (_cache_flash_addr == NO_CACHE) return;
107+
108+
// Skip if data is the same
109+
if (memcmp(_flash_cache, (void *)_flash_page_addr, FLASH_PAGE_SIZE) != 0) {
110+
// unlock flash
111+
HAL_FLASH_Unlock();
112+
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+
124+
// erase the sector
125+
uint32_t SectorError = 0;
126+
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
127+
// error occurred during sector erase
128+
HAL_FLASH_Lock(); // lock the flash
129+
mp_printf(&mp_plat_print, "FLASH SECTOR ERASE ERROR");
130+
return false;
131+
}
132+
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();
141+
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) {
145+
// error occurred during flash write
146+
HAL_FLASH_Lock(); // lock the flash
147+
mp_printf(&mp_plat_print, "FLASH WRITE ERROR");
148+
return false;
149+
}
150+
sector_start_addr += 1;
151+
}
152+
153+
// lock the flash
154+
HAL_FLASH_Lock();
155+
}
104156
}
105157

106158
static int32_t convert_block_to_flash_addr(uint32_t block) {
@@ -189,13 +241,56 @@ bool supervisor_flash_write_block(const uint8_t *src, uint32_t block) {
189241
return true;
190242
}
191243

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+
192254
mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
255+
while (num_blocks) {
256+
int32_t dest = convert_block_to_flash_addr(block);
257+
if (dest == -1) {
258+
// bad block number
259+
mp_printf(&mp_plat_print, "BAD FLASH BLOCK ERROR");
260+
return false;
261+
}
262+
263+
// unlock flash
264+
HAL_FLASH_Unlock();
265+
266+
flash_get_sector_info(dest, &sector_start_addr, &sector_size);
193267

194-
for (size_t i = 0; i < num_blocks; i++) {
195-
if (!supervisor_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) {
196-
return 1; // error
268+
// Fail for any sector outside the 16k ones for now
269+
if (sector_size > 0x4000) return false;
270+
271+
// Find how many blocks are left in the sector
272+
uint32_t count = (sector_size - (dest - sector_start_addr))/FILESYSTEM_BLOCK_SIZE;
273+
count = MIN(num_blocks, count); `
274+
275+
if (_cache_flash_addr != sector_start_addr) {
276+
// Write out anything in cache before overwriting it.
277+
supervisor_flash_flush();
278+
279+
_cache_flash_addr = sector_start_addr;
280+
281+
// Copy the current contents of the entire page into the cache.
282+
memcpy(_flash_cache, (void *)sector_start_addr, sector_size);
197283
}
284+
285+
// Overwrite part or all of the sector cache with the src data.
286+
memcpy(_flash_cache + (dest-sector_start_addr), src, count * FILESYSTEM_BLOCK_SIZE);
287+
288+
// adjust for next run
289+
block_num += count;
290+
src += count * FILESYSTEM_BLOCK_SIZE;
291+
num_blocks -= count;
198292
}
293+
199294
return 0; // success
200295
}
201296

0 commit comments

Comments
 (0)