From 170bf2855319319c961b1d0e213f11015b26f132 Mon Sep 17 00:00:00 2001 From: Mateusz Faderewski Date: Wed, 4 Jan 2023 23:18:55 +0100 Subject: [PATCH] [SC64][SW] Save writeback SD card optimizations --- sw/controller/src/cfg.c | 13 +++------ sw/controller/src/cfg.h | 11 +++++++ sw/controller/src/dd.c | 40 +++++-------------------- sw/controller/src/sd.c | 29 ++++++++++++++++++ sw/controller/src/sd.h | 4 +++ sw/controller/src/writeback.c | 55 +++++++++++++++++++++++++---------- 6 files changed, 95 insertions(+), 57 deletions(-) diff --git a/sw/controller/src/cfg.c b/sw/controller/src/cfg.c index 1044bfc..e8f5004 100644 --- a/sw/controller/src/cfg.c +++ b/sw/controller/src/cfg.c @@ -42,15 +42,6 @@ typedef enum { BOOT_MODE_DIRECT = 3 } boot_mode_t; -typedef enum { - SAVE_TYPE_NONE = 0, - SAVE_TYPE_EEPROM_4K = 1, - SAVE_TYPE_EEPROM_16K = 2, - SAVE_TYPE_SRAM = 3, - SAVE_TYPE_FLASHRAM = 4, - SAVE_TYPE_SRAM_BANKED = 5 -} save_type_t; - typedef enum { CIC_SEED_UNKNOWN = 0xFFFF } cic_seed_t; @@ -359,6 +350,10 @@ bool cfg_update (uint32_t *args) { return false; } +save_type_t cfg_get_save_type (void) { + return p.save_type; +} + void cfg_get_time (uint32_t *args) { rtc_time_t t; rtc_get_time(&t); diff --git a/sw/controller/src/cfg.h b/sw/controller/src/cfg.h index 8ca463b..ffac1c1 100644 --- a/sw/controller/src/cfg.h +++ b/sw/controller/src/cfg.h @@ -6,9 +6,20 @@ #include +typedef enum { + SAVE_TYPE_NONE = 0, + SAVE_TYPE_EEPROM_4K = 1, + SAVE_TYPE_EEPROM_16K = 2, + SAVE_TYPE_SRAM = 3, + SAVE_TYPE_FLASHRAM = 4, + SAVE_TYPE_SRAM_BANKED = 5 +} save_type_t; + + uint32_t cfg_get_version (void); bool cfg_query (uint32_t *args); bool cfg_update (uint32_t *args); +save_type_t cfg_get_save_type (void); void cfg_get_time (uint32_t *args); void cfg_set_time (uint32_t *args); void cfg_reset_state (void); diff --git a/sw/controller/src/dd.c b/sw/controller/src/dd.c index b3dee08..82d4e74 100644 --- a/sw/controller/src/dd.c +++ b/sw/controller/src/dd.c @@ -125,41 +125,14 @@ static uint32_t dd_fill_sd_sector_table (uint32_t index, uint32_t *sector_table) return sectors; } -static void dd_process_sd_request (uint16_t index, uint32_t buffer_address, bool write) { - uint32_t sector_table[DD_SD_SECTOR_TABLE_SIZE]; - uint32_t sectors = dd_fill_sd_sector_table(index, sector_table); - dd_set_block_ready(false); - if (sectors == 0) { - return; - } - uint32_t starting_sector = 0; - uint32_t sectors_to_process = 0; - for (uint32_t i = 0; i < sectors; i++) { - sectors_to_process += 1; - if ((i < (sectors - 1)) && ((sector_table[i] + 1) == sector_table[i + 1])) { - continue; - } - if (write) { - if (sd_write_sectors(buffer_address, sector_table[starting_sector], sectors_to_process)) { - return; - } - } else { - if (sd_read_sectors(buffer_address, sector_table[starting_sector], sectors_to_process)) { - return; - } - } - buffer_address += (sectors_to_process * SD_SECTOR_SIZE); - starting_sector += sectors_to_process; - sectors_to_process = 0; - } - dd_set_block_ready(true); -} - static bool dd_block_read_request (void) { uint16_t index = dd_track_head_block(); uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS; if (p.sd_mode) { - dd_process_sd_request(index, buffer_address, false); + uint32_t sector_table[DD_SD_SECTOR_TABLE_SIZE]; + uint32_t sectors = dd_fill_sd_sector_table(index, sector_table); + bool error = sd_optimize_sectors(buffer_address, sector_table, sectors, sd_read_sectors); + dd_set_block_ready(!error); } else { usb_tx_info_t packet_info; usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST); @@ -178,7 +151,10 @@ static bool dd_block_write_request (void) { uint32_t index = dd_track_head_block(); uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS; if (p.sd_mode) { - dd_process_sd_request(index, buffer_address, true); + uint32_t sector_table[DD_SD_SECTOR_TABLE_SIZE]; + uint32_t sectors = dd_fill_sd_sector_table(index, sector_table); + bool error = sd_optimize_sectors(buffer_address, sector_table, sectors, sd_write_sectors); + dd_set_block_ready(!error); } else { usb_tx_info_t packet_info; usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST); diff --git a/sw/controller/src/sd.c b/sw/controller/src/sd.c index 5202da5..e6740bf 100644 --- a/sw/controller/src/sd.c +++ b/sw/controller/src/sd.c @@ -197,6 +197,7 @@ static bool sd_dat_wait (uint16_t timeout) { do { uint32_t sd_dat = fpga_reg_get(REG_SD_DAT); uint32_t sd_dma_scr = fpga_reg_get(REG_SD_DMA_SCR); + led_blink_act(); if ((!(sd_dat & SD_DAT_BUSY)) && (!(sd_dma_scr & DMA_SCR_BUSY))) { sd_clear_timeout(); return (sd_dat & SD_DAT_ERROR); @@ -430,6 +431,34 @@ bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count) { return false; } +bool sd_optimize_sectors (uint32_t address, uint32_t *sector_table, uint32_t count, sd_process_sectors_t sd_process_sectors) { + uint32_t starting_sector = 0; + uint32_t sectors_to_process = 0; + + if (count == 0) { + return true; + } + + for (uint32_t i = 0; i < count; i++) { + if (sector_table[i] == 0) { + return true; + } + sectors_to_process += 1; + if ((i < (count - 1)) && ((sector_table[i] + 1) == sector_table[i + 1])) { + continue; + } + bool error = sd_process_sectors(address, sector_table[starting_sector], sectors_to_process); + if (error) { + return true; + } + address += (sectors_to_process * SD_SECTOR_SIZE); + starting_sector += sectors_to_process; + sectors_to_process = 0; + } + + return false; +} + void sd_init (void) { p.card_initialized = false; sd_set_clock(CLOCK_STOP); diff --git a/sw/controller/src/sd.h b/sw/controller/src/sd.h index 40445a5..3df2434 100644 --- a/sw/controller/src/sd.h +++ b/sw/controller/src/sd.h @@ -8,12 +8,16 @@ #define SD_SECTOR_SIZE (512) +typedef bool sd_process_sectors_t (uint32_t address, uint32_t sector, uint32_t count); + + bool sd_card_init (void); void sd_card_deinit (void); uint32_t sd_card_get_status (void); bool sd_card_get_info (uint32_t address); bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count); bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count); +bool sd_optimize_sectors (uint32_t address, uint32_t *sector_table, uint32_t count, sd_process_sectors_t sd_process_sectors); void sd_init (void); void sd_process (void); diff --git a/sw/controller/src/writeback.c b/sw/controller/src/writeback.c index 40f0351..5ea80b5 100644 --- a/sw/controller/src/writeback.c +++ b/sw/controller/src/writeback.c @@ -1,13 +1,19 @@ +#include "cfg.h" #include "fpga.h" #include "sd.h" #include "timer.h" #include "writeback.h" -#define SAVE_MAX_SECTOR_COUNT (256) -#define SRAM_FLASHRAM_ADDRESS (0x03FE0000) -#define EEPROM_ADDRESS (0x05002000) -#define WRITEBACK_DELAY_TICKS (100) +#define SAVE_MAX_SECTOR_COUNT (256) +#define SRAM_FLASHRAM_ADDRESS (0x03FE0000) +#define EEPROM_ADDRESS (0x05002000) +#define EEPROM_4K_SECTOR_COUNT (1) +#define EEPROM_16K_SECTOR_COUNT (4) +#define SRAM_SECTOR_COUNT (64) +#define FLASHRAM_SECTOR_COUNT (256) +#define SRAM_BANKED_SECTOR_COUNT (192) +#define WRITEBACK_DELAY_TICKS (100) struct process { @@ -22,20 +28,37 @@ static struct process p; static void writeback_save_to_sd (void) { - uint32_t save_address = SRAM_FLASHRAM_ADDRESS; - if (fpga_reg_get(REG_CFG_SCR) & CFG_SCR_EEPROM_ENABLED) { - save_address = EEPROM_ADDRESS; - } - for (int i = 0; i < SAVE_MAX_SECTOR_COUNT; i++) { - uint32_t sector = p.sectors[i]; - if (sector == 0) { + uint32_t address; + uint32_t count; + + switch (cfg_get_save_type()) { + case SAVE_TYPE_EEPROM_4K: + address = EEPROM_ADDRESS; + count = EEPROM_4K_SECTOR_COUNT; break; - } - if (sd_write_sectors(save_address, sector, 1)) { + case SAVE_TYPE_EEPROM_16K: + address = EEPROM_ADDRESS; + count = EEPROM_16K_SECTOR_COUNT; + break; + case SAVE_TYPE_SRAM: + address = SRAM_FLASHRAM_ADDRESS; + count = SRAM_SECTOR_COUNT; + break; + case SAVE_TYPE_FLASHRAM: + address = SRAM_FLASHRAM_ADDRESS; + count = FLASHRAM_SECTOR_COUNT; + break; + case SAVE_TYPE_SRAM_BANKED: + address = SRAM_FLASHRAM_ADDRESS; + count = SRAM_BANKED_SECTOR_COUNT; + break; + default: p.enabled = false; - break; - } - save_address += SD_SECTOR_SIZE; + return; + } + + if(sd_optimize_sectors(address, p.sectors, count, sd_write_sectors)) { + p.enabled = false; } }