diff --git a/src/flashcart/flashcart_utils.c b/src/flashcart/flashcart_utils.c index 765a2408..a89230c3 100644 --- a/src/flashcart/flashcart_utils.c +++ b/src/flashcart/flashcart_utils.c @@ -1,3 +1,5 @@ +#include + #include "flashcart_utils.h" #include "utils/fs.h" #include "utils/utils.h" @@ -9,3 +11,19 @@ void fix_file_size (FIL *fil) { // Sending some extra bytes isn't an issue here. fil->obj.objsize = ALIGN(f_size(fil), FS_SECTOR_SIZE); } + +void pi_dma_read_data (void *src, void *dst, size_t length) { + data_cache_hit_writeback_invalidate(dst, length); + dma_read_async(dst, (uint32_t) (src), length); + dma_wait(); +} + +void pi_dma_write_data (void *src, void *dst, size_t length) { + assert((((uint32_t) (src)) & 0x07) == 0); + assert((((uint32_t) (dst)) & 0x01) == 0); + assert((length & 1) == 0); + + data_cache_hit_writeback(src, length); + dma_write_raw_async(src, (uint32_t) (dst), length); + dma_wait(); +} diff --git a/src/flashcart/flashcart_utils.h b/src/flashcart/flashcart_utils.h index 036e54d9..38d1b589 100644 --- a/src/flashcart/flashcart_utils.h +++ b/src/flashcart/flashcart_utils.h @@ -12,6 +12,8 @@ void fix_file_size (FIL *fil); +void pi_dma_read_data (void *src, void *dst, size_t length); +void pi_dma_write_data (void *src, void *dst, size_t length); #endif diff --git a/src/flashcart/sc64/sc64.c b/src/flashcart/sc64/sc64.c index 65d00917..23d9477c 100644 --- a/src/flashcart/sc64/sc64.c +++ b/src/flashcart/sc64/sc64.c @@ -55,13 +55,9 @@ static flashcart_error_t load_to_flash (FIL *fil, void *address, size_t size, UI static flashcart_error_t sc64_init (void) { uint16_t major; uint16_t minor; + uint32_t revision; - sc64_unlock(); - - if (!sc64_check_presence()) { - return FLASHCART_ERROR_UNSUPPORTED; - } - if (sc64_get_version(&major, &minor) != SC64_OK) { + if (sc64_get_version(&major, &minor, &revision) != SC64_OK) { return FLASHCART_ERROR_OUTDATED; } if (major != SUPPORTED_MAJOR_VERSION) { @@ -192,12 +188,14 @@ static flashcart_error_t sc64_load_rom (char *rom_path) { static flashcart_error_t sc64_load_save (char *save_path) { void *address = NULL; - sc64_save_type_t type; + uint32_t value; - if (sc64_get_config(CFG_SAVE_TYPE, &type) != SC64_OK) { + if (sc64_get_config(CFG_SAVE_TYPE, &value) != SC64_OK) { return FLASHCART_ERROR_INT; } + sc64_save_type_t type = (sc64_save_type_t) (value); + switch (type) { case SAVE_TYPE_EEPROM_4K: case SAVE_TYPE_EEPROM_16K: @@ -275,7 +273,7 @@ static flashcart_error_t sc64_set_save_type (flashcart_save_type_t save_type) { } static flashcart_error_t sc64_set_save_writeback (uint32_t *sectors) { - sc64_write_data(sectors, SC64_BUFFERS->BUFFER, 1024); + pi_dma_write_data(sectors, SC64_BUFFERS->BUFFER, 1024); if (sc64_writeback_enable(SC64_BUFFERS->BUFFER) != SC64_OK) { return FLASHCART_ERROR_INT; diff --git a/src/flashcart/sc64/sc64_internal.c b/src/flashcart/sc64/sc64_internal.c index 4ac69d39..62b9163a 100644 --- a/src/flashcart/sc64/sc64_internal.c +++ b/src/flashcart/sc64/sc64_internal.c @@ -13,15 +13,9 @@ typedef struct { #define SC64_REGS_BASE (0x1FFF0000UL) #define SC64_REGS ((sc64_regs_t *) SC64_REGS_BASE) -#define SC64_SR_IRQ_PENDING (1 << 29) #define SC64_SR_CMD_ERROR (1 << 30) #define SC64_SR_CPU_BUSY (1 << 31) -#define SC64_V2_IDENTIFIER (0x53437632) - -#define SC64_KEY_RESET (0x00000000UL) -#define SC64_KEY_UNLOCK_1 (0x5F554E4CUL) -#define SC64_KEY_UNLOCK_2 (0x4F434B5FUL) #define SC64_KEY_LOCK (0xFFFFFFFFUL) @@ -29,23 +23,12 @@ typedef enum { CMD_ID_VERSION_GET = 'V', CMD_ID_CONFIG_GET = 'c', CMD_ID_CONFIG_SET = 'C', - CMD_ID_SD_CARD_OP = 'i', CMD_ID_WRITEBACK_PENDING = 'w', CMD_ID_WRITEBACK_SD_INFO = 'W', - CMD_ID_FLASH_PROGRAM = 'K', CMD_ID_FLASH_WAIT_BUSY = 'p', CMD_ID_FLASH_ERASE_BLOCK = 'P', } sc64_cmd_id_t; -typedef enum { - SD_CARD_OP_DEINIT = 0, - SD_CARD_OP_INIT = 1, - SD_CARD_OP_GET_STATUS = 2, - SD_CARD_OP_GET_INFO = 3, - SD_CARD_OP_BYTE_SWAP_ON = 4, - SD_CARD_OP_BYTE_SWAP_OFF = 5, -} sc64_sd_card_op_t; - typedef struct { sc64_cmd_id_t id; uint32_t arg[2]; @@ -75,90 +58,78 @@ static sc64_error_t sc64_execute_cmd (sc64_cmd_t *cmd) { } -void sc64_unlock (void) { - io_write((uint32_t) (&SC64_REGS->KEY), SC64_KEY_RESET); - io_write((uint32_t) (&SC64_REGS->KEY), SC64_KEY_UNLOCK_1); - io_write((uint32_t) (&SC64_REGS->KEY), SC64_KEY_UNLOCK_2); -} - void sc64_lock (void) { io_write((uint32_t) (&SC64_REGS->KEY), SC64_KEY_LOCK); } -bool sc64_check_presence (void) { - return (io_read((uint32_t) (&SC64_REGS->IDENTIFIER)) == SC64_V2_IDENTIFIER); -} - -void sc64_read_data (void *src, void *dst, size_t length) { - data_cache_hit_writeback_invalidate(dst, length); - dma_read_raw_async(dst, (uint32_t) (src), length); - dma_wait(); -} - -void sc64_write_data (void *src, void *dst, size_t length) { - data_cache_hit_writeback(src, length); - dma_write_raw_async(src, (uint32_t) (dst), length); - dma_wait(); -} - -sc64_error_t sc64_get_version (uint16_t *major, uint16_t *minor) { - sc64_cmd_t cmd = { .id = CMD_ID_VERSION_GET }; +sc64_error_t sc64_get_version (uint16_t *major, uint16_t *minor, uint32_t *revision) { + sc64_cmd_t cmd = { + .id = CMD_ID_VERSION_GET + }; sc64_error_t error = sc64_execute_cmd(&cmd); *major = ((cmd.rsp[0] >> 16) & 0xFFFF); *minor = (cmd.rsp[0] & 0xFFFF); + *revision = cmd.rsp[1]; return error; } -sc64_error_t sc64_get_config (sc64_cfg_t id, void *value) { - sc64_cmd_t cmd = { .id = CMD_ID_CONFIG_GET, .arg = { id } }; +sc64_error_t sc64_get_config (sc64_cfg_t id, uint32_t *value) { + sc64_cmd_t cmd = { + .id = CMD_ID_CONFIG_GET, + .arg = { id } + }; sc64_error_t error = sc64_execute_cmd(&cmd); - *((uint32_t *) (value)) = cmd.rsp[1]; + *value = cmd.rsp[1]; return error; } sc64_error_t sc64_set_config (sc64_cfg_t id, uint32_t value) { - sc64_cmd_t cmd = { .id = CMD_ID_CONFIG_SET, .arg = { id, value } }; - return sc64_execute_cmd(&cmd); -} - -sc64_error_t sc64_sd_set_byte_swap (bool enabled) { sc64_cmd_t cmd = { - .id = CMD_ID_SD_CARD_OP, - .arg = { 0, enabled ? SD_CARD_OP_BYTE_SWAP_ON : SD_CARD_OP_BYTE_SWAP_OFF } + .id = CMD_ID_CONFIG_SET, + .arg = { id, value } }; return sc64_execute_cmd(&cmd); } sc64_error_t sc64_writeback_pending (bool *pending) { - sc64_cmd_t cmd = { .id = CMD_ID_WRITEBACK_PENDING }; + sc64_cmd_t cmd = { + .id = CMD_ID_WRITEBACK_PENDING + }; sc64_error_t error = sc64_execute_cmd(&cmd); *pending = (cmd.rsp[0] != 0); return error; } sc64_error_t sc64_writeback_enable (void *address) { - sc64_cmd_t cmd = { .id = CMD_ID_WRITEBACK_SD_INFO, .arg = { (uint32_t) (address) } }; - return sc64_execute_cmd(&cmd); -} - -sc64_error_t sc64_flash_program (void *address, size_t length) { - sc64_cmd_t cmd = { .id = CMD_ID_FLASH_PROGRAM, .arg = { (uint32_t) (address), length } }; + sc64_cmd_t cmd = { + .id = CMD_ID_WRITEBACK_SD_INFO, + .arg = { (uint32_t) (address) } + }; return sc64_execute_cmd(&cmd); } sc64_error_t sc64_flash_wait_busy (void) { - sc64_cmd_t cmd = { .id = CMD_ID_FLASH_WAIT_BUSY, .arg = { true } }; + sc64_cmd_t cmd = { + .id = CMD_ID_FLASH_WAIT_BUSY, + .arg = { true } + }; return sc64_execute_cmd(&cmd); } sc64_error_t sc64_flash_get_erase_block_size (size_t *erase_block_size) { - sc64_cmd_t cmd = { .id = CMD_ID_FLASH_WAIT_BUSY, .arg = { false } }; + sc64_cmd_t cmd = { + .id = CMD_ID_FLASH_WAIT_BUSY, + .arg = { false } + }; sc64_error_t error = sc64_execute_cmd(&cmd); *erase_block_size = (size_t) (cmd.rsp[0]); return error; } sc64_error_t sc64_flash_erase_block (void *address) { - sc64_cmd_t cmd = { .id = CMD_ID_FLASH_ERASE_BLOCK, .arg = { (uint32_t) (address) } }; + sc64_cmd_t cmd = { + .id = CMD_ID_FLASH_ERASE_BLOCK, + .arg = { (uint32_t) (address) } + }; return sc64_execute_cmd(&cmd); } diff --git a/src/flashcart/sc64/sc64_internal.h b/src/flashcart/sc64/sc64_internal.h index f48767c6..4300ed9a 100644 --- a/src/flashcart/sc64/sc64_internal.h +++ b/src/flashcart/sc64/sc64_internal.h @@ -110,18 +110,12 @@ typedef enum { } sc64_button_mode_t; -void sc64_unlock (void); void sc64_lock (void); -bool sc64_check_presence (void); -void sc64_read_data (void *src, void *dst, size_t length); -void sc64_write_data (void *src, void *dst, size_t length); -sc64_error_t sc64_get_version (uint16_t *major, uint16_t *minor); -sc64_error_t sc64_get_config (sc64_cfg_t cfg, void *value); +sc64_error_t sc64_get_version (uint16_t *major, uint16_t *minor, uint32_t *revision); +sc64_error_t sc64_get_config (sc64_cfg_t cfg, uint32_t *value); sc64_error_t sc64_set_config (sc64_cfg_t cfg, uint32_t value); -sc64_error_t sc64_sd_set_byte_swap (bool enabled); sc64_error_t sc64_writeback_pending (bool *pending); sc64_error_t sc64_writeback_enable (void *address); -sc64_error_t sc64_flash_program (void *address, size_t length); sc64_error_t sc64_flash_wait_busy (void); sc64_error_t sc64_flash_get_erase_block_size (size_t *erase_block_size); sc64_error_t sc64_flash_erase_block (void *address);