Skip to content

Commit b67c53e

Browse files
committed
Factor out of external flash as well.
Plus some cleanup. Fixes adafruit#1324
1 parent 87ddd64 commit b67c53e

File tree

3 files changed

+66
-137
lines changed

3 files changed

+66
-137
lines changed

ports/nrf/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_C
7878
#Debugging/Optimization
7979
ifeq ($(DEBUG), 1)
8080
#ASMFLAGS += -g -gtabs+
81-
CFLAGS += -Os -ggdb
82-
LDFLAGS += -Os
81+
CFLAGS += -O1 -ggdb
82+
LDFLAGS += -O1
8383
else
8484
CFLAGS += -Os -DNDEBUG
8585
LDFLAGS += -Os

supervisor/shared/external_flash/external_flash.c

Lines changed: 63 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
#include "supervisor/memory.h"
4141
#include "supervisor/shared/rgb_led_status.h"
4242

43-
#define SPI_FLASH_PART1_START_BLOCK (0x1)
44-
4543
#define NO_SECTOR_LOADED 0xFFFFFFFF
4644

4745
// The currently cached sector in the cache, ram or flash based.
@@ -268,7 +266,7 @@ uint32_t supervisor_flash_get_block_size(void) {
268266
uint32_t supervisor_flash_get_block_count(void) {
269267
// We subtract one erase sector size because we may use it as a staging area
270268
// for writes.
271-
return SPI_FLASH_PART1_START_BLOCK + (flash_device->total_size - SPI_FLASH_ERASE_SIZE) / FILESYSTEM_BLOCK_SIZE;
269+
return (flash_device->total_size - SPI_FLASH_ERASE_SIZE) / FILESYSTEM_BLOCK_SIZE;
272270
}
273271

274272
// Flush the cache that was written to the scratch portion of flash. Only used
@@ -444,155 +442,88 @@ void supervisor_flash_flush(void) {
444442
spi_flash_flush_keep_cache(false);
445443
}
446444

447-
// Builds a partition entry for the MBR.
448-
static void build_partition(uint8_t *buf, int boot, int type,
449-
uint32_t start_block, uint32_t num_blocks) {
450-
buf[0] = boot;
451-
452-
if (num_blocks == 0) {
453-
buf[1] = 0;
454-
buf[2] = 0;
455-
buf[3] = 0;
456-
} else {
457-
buf[1] = 0xff;
458-
buf[2] = 0xff;
459-
buf[3] = 0xff;
460-
}
461-
462-
buf[4] = type;
463-
464-
if (num_blocks == 0) {
465-
buf[5] = 0;
466-
buf[6] = 0;
467-
buf[7] = 0;
468-
} else {
469-
buf[5] = 0xff;
470-
buf[6] = 0xff;
471-
buf[7] = 0xff;
472-
}
473-
474-
buf[8] = start_block;
475-
buf[9] = start_block >> 8;
476-
buf[10] = start_block >> 16;
477-
buf[11] = start_block >> 24;
478-
479-
buf[12] = num_blocks;
480-
buf[13] = num_blocks >> 8;
481-
buf[14] = num_blocks >> 16;
482-
buf[15] = num_blocks >> 24;
483-
}
484-
485445
static int32_t convert_block_to_flash_addr(uint32_t block) {
486-
if (SPI_FLASH_PART1_START_BLOCK <= block && block < supervisor_flash_get_block_count()) {
446+
if (0 <= block && block < supervisor_flash_get_block_count()) {
487447
// a block in partition 1
488-
block -= SPI_FLASH_PART1_START_BLOCK;
489448
return block * FILESYSTEM_BLOCK_SIZE;
490449
}
491450
// bad block
492451
return -1;
493452
}
494453

495454
bool external_flash_read_block(uint8_t *dest, uint32_t block) {
496-
if (block == 0) {
497-
// Fake the MBR so we can decide on our own partition table
498-
for (int i = 0; i < 446; i++) {
499-
dest[i] = 0;
500-
}
501-
502-
build_partition(dest + 446, 0, 0x01 /* FAT12 */,
503-
SPI_FLASH_PART1_START_BLOCK,
504-
supervisor_flash_get_block_count() - SPI_FLASH_PART1_START_BLOCK);
505-
build_partition(dest + 462, 0, 0, 0, 0);
506-
build_partition(dest + 478, 0, 0, 0, 0);
507-
build_partition(dest + 494, 0, 0, 0, 0);
508-
509-
dest[510] = 0x55;
510-
dest[511] = 0xaa;
511-
512-
return true;
513-
} else if (block < SPI_FLASH_PART1_START_BLOCK) {
514-
memset(dest, 0, FILESYSTEM_BLOCK_SIZE);
515-
return true;
516-
} else {
517-
// Non-MBR block, get data from flash memory.
518-
int32_t address = convert_block_to_flash_addr(block);
519-
if (address == -1) {
520-
// bad block number
521-
return false;
522-
}
523-
524-
// Mask out the lower bits that designate the address within the sector.
525-
uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1));
526-
uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE);
527-
uint8_t mask = 1 << (block_index);
528-
// We're reading from the currently cached sector.
529-
if (current_sector == this_sector && (mask & dirty_mask) > 0) {
530-
if (MP_STATE_VM(flash_ram_cache) != NULL) {
531-
uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE;
532-
for (int i = 0; i < pages_per_block; i++) {
533-
memcpy(dest + i * SPI_FLASH_PAGE_SIZE,
534-
MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i],
535-
SPI_FLASH_PAGE_SIZE);
536-
}
537-
return true;
538-
} else {
539-
uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE;
540-
return read_flash(scratch_address, dest, FILESYSTEM_BLOCK_SIZE);
541-
}
542-
}
543-
return read_flash(address, dest, FILESYSTEM_BLOCK_SIZE);
455+
int32_t address = convert_block_to_flash_addr(block);
456+
if (address == -1) {
457+
// bad block number
458+
return false;
544459
}
545-
}
546460

547-
bool external_flash_write_block(const uint8_t *data, uint32_t block) {
548-
if (block < SPI_FLASH_PART1_START_BLOCK) {
549-
// Fake writing below the flash partition.
550-
return true;
551-
} else {
552-
// Non-MBR block, copy to cache
553-
int32_t address = convert_block_to_flash_addr(block);
554-
if (address == -1) {
555-
// bad block number
556-
return false;
557-
}
558-
// Wait for any previous writes to finish.
559-
wait_for_flash_ready();
560-
// Mask out the lower bits that designate the address within the sector.
561-
uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1));
562-
uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE);
563-
uint8_t mask = 1 << (block_index);
564-
// Flush the cache if we're moving onto a sector or we're writing the
565-
// same block again.
566-
if (current_sector != this_sector || (mask & dirty_mask) > 0) {
567-
// Check to see if we'd write to an erased page. In that case we
568-
// can write directly.
569-
if (page_erased(address)) {
570-
return write_flash(address, data, FILESYSTEM_BLOCK_SIZE);
571-
}
572-
if (current_sector != NO_SECTOR_LOADED) {
573-
spi_flash_flush_keep_cache(true);
574-
}
575-
if (MP_STATE_VM(flash_ram_cache) == NULL && !allocate_ram_cache()) {
576-
erase_sector(flash_device->total_size - SPI_FLASH_ERASE_SIZE);
577-
wait_for_flash_ready();
578-
}
579-
current_sector = this_sector;
580-
dirty_mask = 0;
581-
}
582-
dirty_mask |= mask;
583-
// Copy the block to the appropriate cache.
461+
// Mask out the lower bits that designate the address within the sector.
462+
uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1));
463+
uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE);
464+
uint8_t mask = 1 << (block_index);
465+
// We're reading from the currently cached sector.
466+
if (current_sector == this_sector && (mask & dirty_mask) > 0) {
584467
if (MP_STATE_VM(flash_ram_cache) != NULL) {
585468
uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE;
586469
for (int i = 0; i < pages_per_block; i++) {
587-
memcpy(MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i],
588-
data + i * SPI_FLASH_PAGE_SIZE,
470+
memcpy(dest + i * SPI_FLASH_PAGE_SIZE,
471+
MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i],
589472
SPI_FLASH_PAGE_SIZE);
590473
}
591474
return true;
592475
} else {
593476
uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE;
594-
return write_flash(scratch_address, data, FILESYSTEM_BLOCK_SIZE);
477+
return read_flash(scratch_address, dest, FILESYSTEM_BLOCK_SIZE);
478+
}
479+
}
480+
return read_flash(address, dest, FILESYSTEM_BLOCK_SIZE);
481+
}
482+
483+
bool external_flash_write_block(const uint8_t *data, uint32_t block) {
484+
// Non-MBR block, copy to cache
485+
int32_t address = convert_block_to_flash_addr(block);
486+
if (address == -1) {
487+
// bad block number
488+
return false;
489+
}
490+
// Wait for any previous writes to finish.
491+
wait_for_flash_ready();
492+
// Mask out the lower bits that designate the address within the sector.
493+
uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1));
494+
uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE);
495+
uint8_t mask = 1 << (block_index);
496+
// Flush the cache if we're moving onto a sector or we're writing the
497+
// same block again.
498+
if (current_sector != this_sector || (mask & dirty_mask) > 0) {
499+
// Check to see if we'd write to an erased page. In that case we
500+
// can write directly.
501+
if (page_erased(address)) {
502+
return write_flash(address, data, FILESYSTEM_BLOCK_SIZE);
503+
}
504+
if (current_sector != NO_SECTOR_LOADED) {
505+
spi_flash_flush_keep_cache(true);
506+
}
507+
if (MP_STATE_VM(flash_ram_cache) == NULL && !allocate_ram_cache()) {
508+
erase_sector(flash_device->total_size - SPI_FLASH_ERASE_SIZE);
509+
wait_for_flash_ready();
595510
}
511+
current_sector = this_sector;
512+
dirty_mask = 0;
513+
}
514+
dirty_mask |= mask;
515+
// Copy the block to the appropriate cache.
516+
if (MP_STATE_VM(flash_ram_cache) != NULL) {
517+
uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE;
518+
for (int i = 0; i < pages_per_block; i++) {
519+
memcpy(MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i],
520+
data + i * SPI_FLASH_PAGE_SIZE,
521+
SPI_FLASH_PAGE_SIZE);
522+
}
523+
return true;
524+
} else {
525+
uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE;
526+
return write_flash(scratch_address, data, FILESYSTEM_BLOCK_SIZE);
596527
}
597528
}
598529

supervisor/shared/filesystem.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ void filesystem_init(bool create_allowed, bool force_create) {
5050
supervisor_flash_init_vfs(vfs_fat);
5151

5252
// try to mount the flash
53-
volatile FRESULT res = f_mount(&vfs_fat->fatfs);
53+
FRESULT res = f_mount(&vfs_fat->fatfs);
5454

5555
if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) {
5656
// No filesystem so create a fresh one, or reformat has been requested.
@@ -59,7 +59,6 @@ void filesystem_init(bool create_allowed, bool force_create) {
5959
// Flush the new file system to make sure it's repaired immediately.
6060
supervisor_flash_flush();
6161
if (res != FR_OK) {
62-
//asm("bkpt");
6362
return;
6463
}
6564

@@ -75,7 +74,6 @@ void filesystem_init(bool create_allowed, bool force_create) {
7574
// and ensure everything is flushed
7675
supervisor_flash_flush();
7776
} else if (res != FR_OK) {
78-
//asm("bkpt");
7977
return;
8078
}
8179
mp_vfs_mount_t *vfs = &_mp_vfs;

0 commit comments

Comments
 (0)