mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-22 14:09:16 +01:00
flash erase method change
This commit is contained in:
parent
2ce73c03bf
commit
fa561b4728
@ -236,6 +236,13 @@ module n64_pi (
|
|||||||
end
|
end
|
||||||
|
|
||||||
if (n64_scb.cfg_unlock) begin
|
if (n64_scb.cfg_unlock) begin
|
||||||
|
if (n64_pi_dq_in >= 16'h1FFC && n64_pi_dq_in < 16'h1FFE) begin
|
||||||
|
read_port <= PORT_MEM;
|
||||||
|
write_port <= PORT_NONE;
|
||||||
|
mem_offset <= (-32'h1FFC_0000) + SHADOW_OFFSET;
|
||||||
|
n64_scb.pi_flash_active <= 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
if (n64_pi_dq_in >= 16'h1FFE && n64_pi_dq_in < 16'h1FFF) begin
|
if (n64_pi_dq_in >= 16'h1FFE && n64_pi_dq_in < 16'h1FFF) begin
|
||||||
read_port <= PORT_MEM;
|
read_port <= PORT_MEM;
|
||||||
write_port <= PORT_MEM;
|
write_port <= PORT_MEM;
|
||||||
|
@ -20,6 +20,8 @@ typedef enum {
|
|||||||
SC64_CMD_SD_WRITE = 'S',
|
SC64_CMD_SD_WRITE = 'S',
|
||||||
SC64_CMD_SD_READ = 's',
|
SC64_CMD_SD_READ = 's',
|
||||||
SC64_CMD_DD_SD_DISK_INFO = 'D',
|
SC64_CMD_DD_SD_DISK_INFO = 'D',
|
||||||
|
SC64_CMD_FLASH_ERASE_BLOCK = 'P',
|
||||||
|
SC64_CMD_FLASH_WAIT_BUSY = 'p',
|
||||||
} cmd_id_t;
|
} cmd_id_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -166,13 +168,13 @@ bool sc64_sd_card_deinit (void) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sc64_sd_card_get_status (void) {
|
sd_card_status_t sc64_sd_card_get_status (void) {
|
||||||
uint32_t args[2] = { 0, SD_CARD_OP_GET_STATUS };
|
uint32_t args[2] = { 0, SD_CARD_OP_GET_STATUS };
|
||||||
uint32_t result[2];
|
uint32_t result[2];
|
||||||
if (sc64_execute_cmd(SC64_CMD_SD_CARD_OP, args, result)) {
|
if (sc64_execute_cmd(SC64_CMD_SD_CARD_OP, args, result)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return result[1];
|
return (sd_card_status_t) (result[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sc64_sd_card_get_info (uint32_t *address) {
|
bool sc64_sd_card_get_info (uint32_t *address) {
|
||||||
|
@ -24,13 +24,12 @@ typedef enum {
|
|||||||
CFG_ID_SAVE_TYPE,
|
CFG_ID_SAVE_TYPE,
|
||||||
CFG_ID_CIC_SEED,
|
CFG_ID_CIC_SEED,
|
||||||
CFG_ID_TV_TYPE,
|
CFG_ID_TV_TYPE,
|
||||||
CFG_ID_FLASH_ERASE_BLOCK,
|
CFG_ID_DD_SD_MODE,
|
||||||
CFG_ID_DD_DRIVE_TYPE,
|
CFG_ID_DD_DRIVE_TYPE,
|
||||||
CFG_ID_DD_DISK_STATE,
|
CFG_ID_DD_DISK_STATE,
|
||||||
CFG_ID_BUTTON_STATE,
|
CFG_ID_BUTTON_STATE,
|
||||||
CFG_ID_BUTTON_MODE,
|
CFG_ID_BUTTON_MODE,
|
||||||
CFG_ID_ROM_EXTENDED_ENABLE,
|
CFG_ID_ROM_EXTENDED_ENABLE,
|
||||||
CFG_ID_DD_SD_MODE,
|
|
||||||
} cfg_id_t;
|
} cfg_id_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -74,6 +73,12 @@ typedef enum {
|
|||||||
BUTTON_MODE_DD_DISK_SWAP,
|
BUTTON_MODE_DD_DISK_SWAP,
|
||||||
} button_mode_t;
|
} button_mode_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SD_CARD_STATUS_INITIALIZED = (1 << 0),
|
||||||
|
SD_CARD_STATUS_TYPE_BLOCK = (1 << 1),
|
||||||
|
SD_CARD_STATUS_50MHZ_MODE = (1 << 2),
|
||||||
|
} sd_card_status_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
boot_mode_t boot_mode;
|
boot_mode_t boot_mode;
|
||||||
@ -107,7 +112,7 @@ bool sc64_usb_read_ready (uint8_t *type, uint32_t *length);
|
|||||||
bool sc64_usb_read (uint32_t *address, uint32_t length);
|
bool sc64_usb_read (uint32_t *address, uint32_t length);
|
||||||
bool sc64_sd_card_init (void);
|
bool sc64_sd_card_init (void);
|
||||||
bool sc64_sd_card_deinit (void);
|
bool sc64_sd_card_deinit (void);
|
||||||
bool sc64_sd_card_get_status (void);
|
sd_card_status_t sc64_sd_card_get_status (void);
|
||||||
bool sc64_sd_card_get_info (uint32_t *address);
|
bool sc64_sd_card_get_info (uint32_t *address);
|
||||||
bool sc64_sd_write_sectors (uint32_t *address, uint32_t sector, uint32_t count);
|
bool sc64_sd_write_sectors (uint32_t *address, uint32_t sector, uint32_t count);
|
||||||
bool sc64_sd_read_sectors (uint32_t *address, uint32_t sector, uint32_t count);
|
bool sc64_sd_read_sectors (uint32_t *address, uint32_t sector, uint32_t count);
|
||||||
|
@ -13,6 +13,7 @@ bool test_check (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void test_execute (void) {
|
void test_execute (void) {
|
||||||
|
sd_card_status_t card_status;
|
||||||
uint8_t card_info[32] __attribute__((aligned(8)));
|
uint8_t card_info[32] __attribute__((aligned(8)));
|
||||||
|
|
||||||
display_init(NULL);
|
display_init(NULL);
|
||||||
@ -24,6 +25,18 @@ void test_execute (void) {
|
|||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
card_status = sc64_sd_card_get_status();
|
||||||
|
|
||||||
|
if (card_status & SD_CARD_STATUS_INITIALIZED) {
|
||||||
|
display_printf("SD card initialized\n");
|
||||||
|
}
|
||||||
|
if (card_status & SD_CARD_STATUS_TYPE_BLOCK) {
|
||||||
|
display_printf("SD card type block\n");
|
||||||
|
}
|
||||||
|
if (card_status & SD_CARD_STATUS_50MHZ_MODE) {
|
||||||
|
display_printf("SD card 50 MHz clock mode\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (sc64_sd_card_get_info((uint32_t *) (SC64_BUFFERS->BUFFER))) {
|
if (sc64_sd_card_get_info((uint32_t *) (SC64_BUFFERS->BUFFER))) {
|
||||||
display_printf("SD card get info error!\n");
|
display_printf("SD card get info error!\n");
|
||||||
while (1);
|
while (1);
|
||||||
|
@ -19,13 +19,12 @@ typedef enum {
|
|||||||
CFG_ID_SAVE_TYPE,
|
CFG_ID_SAVE_TYPE,
|
||||||
CFG_ID_CIC_SEED,
|
CFG_ID_CIC_SEED,
|
||||||
CFG_ID_TV_TYPE,
|
CFG_ID_TV_TYPE,
|
||||||
CFG_ID_FLASH_ERASE_BLOCK,
|
CFG_ID_DD_SD_MODE,
|
||||||
CFG_ID_DD_DRIVE_TYPE,
|
CFG_ID_DD_DRIVE_TYPE,
|
||||||
CFG_ID_DD_DISK_STATE,
|
CFG_ID_DD_DISK_STATE,
|
||||||
CFG_ID_BUTTON_STATE,
|
CFG_ID_BUTTON_STATE,
|
||||||
CFG_ID_BUTTON_MODE,
|
CFG_ID_BUTTON_MODE,
|
||||||
CFG_ID_ROM_EXTENDED_ENABLE,
|
CFG_ID_ROM_EXTENDED_ENABLE,
|
||||||
CFG_ID_DD_SD_MODE,
|
|
||||||
} cfg_id_t;
|
} cfg_id_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -72,6 +71,19 @@ typedef enum {
|
|||||||
CFG_ERROR_UNKNOWN_CMD = -1,
|
CFG_ERROR_UNKNOWN_CMD = -1,
|
||||||
} cfg_error_t;
|
} cfg_error_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_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SDRAM = (1 << 0),
|
||||||
|
FLASH = (1 << 1),
|
||||||
|
BRAM = (1 << 2),
|
||||||
|
} translate_type_t;
|
||||||
|
|
||||||
|
|
||||||
struct process {
|
struct process {
|
||||||
boot_mode_t boot_mode;
|
boot_mode_t boot_mode;
|
||||||
@ -90,45 +102,57 @@ static void cfg_set_usb_output_ready (void) {
|
|||||||
p.usb_output_ready = true;
|
p.usb_output_ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cfg_translate_address (uint32_t *address, uint32_t length, bool with_flash) {
|
static bool cfg_translate_address (uint32_t *address, uint32_t length, translate_type_t type) {
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*address &= 0x1FFFFFFF;
|
*address &= 0x1FFFFFFF;
|
||||||
if (*address >= 0x06000000 && *address < 0x06400000) {
|
if (type & SDRAM) {
|
||||||
if ((*address + length) <= 0x06400000) {
|
if (*address >= 0x06000000 && *address < 0x06400000) {
|
||||||
*address = *address - 0x06000000 + 0x03BC0000;
|
if ((*address + length) <= 0x06400000) {
|
||||||
return false;
|
*address = *address - 0x06000000 + 0x03BC0000;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*address >= 0x08000000 && *address < 0x08020000) {
|
||||||
|
if ((*address + length) <= 0x08020000) {
|
||||||
|
*address = *address - 0x08000000 + 0x03FE0000;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*address >= 0x10000000 && *address < 0x14000000) {
|
||||||
|
if ((*address + length) <= 0x14000000) {
|
||||||
|
*address = *address - 0x10000000 + 0x00000000;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*address >= 0x08000000 && *address < 0x08020000) {
|
if (type & FLASH) {
|
||||||
if ((*address + length) <= 0x08020000) {
|
if (*address >= 0x14000000 && *address < 0x14E00000) {
|
||||||
*address = *address - 0x08000000 + 0x03FE0000;
|
if ((*address + length) <= 0x14E00000) {
|
||||||
return false;
|
*address = *address - 0x14000000 + 0x04000000;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*address >= 0x1FFC0000 && *address < 0x1FFE0000) {
|
||||||
|
if ((*address + length) <= 0x1FFE0000) {
|
||||||
|
*address = *address - 0x1FFC0000 + 0x04E00000;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*address >= 0x10000000 && *address < 0x14000000) {
|
if (type & BRAM) {
|
||||||
if ((*address + length) <= 0x14000000) {
|
if (*address >= 0x1FFE0000 && *address < 0x1FFE2000) {
|
||||||
*address = *address - 0x10000000 + 0x00000000;
|
if ((*address + length) <= 0x1FFE2000) {
|
||||||
return false;
|
*address = *address - 0x1FFE0000 + 0x05000000;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (*address >= 0x1FFE2000 && *address < 0x1FFE2800) {
|
||||||
if (with_flash && *address >= 0x14000000 && *address < 0x15000000) {
|
if ((*address + length) <= 0x1FFE2800) {
|
||||||
if ((*address + length) <= 0x15000000) {
|
*address = *address - 0x1FFE2000 + 0x05002000;
|
||||||
*address = *address - 0x14000000 + 0x04000000;
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if (*address >= 0x1FFE0000 && *address < 0x1FFE2000) {
|
|
||||||
if ((*address + length) <= 0x1FFE2000) {
|
|
||||||
*address = *address - 0x1FFE0000 + 0x05000000;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (*address >= 0x1FFE2000 && *address < 0x1FFE2800) {
|
|
||||||
if ((*address + length) <= 0x1FFE2800) {
|
|
||||||
*address = *address - 0x1FFE2000 + 0x05002000;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -227,9 +251,6 @@ bool cfg_query (uint32_t *args) {
|
|||||||
case CFG_ID_TV_TYPE:
|
case CFG_ID_TV_TYPE:
|
||||||
args[1] = p.tv_type;
|
args[1] = p.tv_type;
|
||||||
break;
|
break;
|
||||||
case CFG_ID_FLASH_ERASE_BLOCK:
|
|
||||||
args[1] = FLASH_ERASE_BLOCK_SIZE;
|
|
||||||
break;
|
|
||||||
case CFG_ID_DD_DRIVE_TYPE:
|
case CFG_ID_DD_DRIVE_TYPE:
|
||||||
args[1] = dd_get_drive_type();
|
args[1] = dd_get_drive_type();
|
||||||
break;
|
break;
|
||||||
@ -295,9 +316,6 @@ bool cfg_update (uint32_t *args) {
|
|||||||
case CFG_ID_TV_TYPE:
|
case CFG_ID_TV_TYPE:
|
||||||
p.tv_type = (tv_type_t) (args[1] & 0x03);
|
p.tv_type = (tv_type_t) (args[1] & 0x03);
|
||||||
break;
|
break;
|
||||||
case CFG_ID_FLASH_ERASE_BLOCK:
|
|
||||||
flash_erase_block(args[1]);
|
|
||||||
break;
|
|
||||||
case CFG_ID_DD_DRIVE_TYPE:
|
case CFG_ID_DD_DRIVE_TYPE:
|
||||||
dd_set_drive_type(args[1]);
|
dd_set_drive_type(args[1]);
|
||||||
break;
|
break;
|
||||||
@ -341,7 +359,7 @@ void cfg_set_time (uint32_t *args) {
|
|||||||
rtc_set_time(&t);
|
rtc_set_time(&t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfg_reset (void) {
|
void cfg_reset_state (void) {
|
||||||
uint32_t mask = (
|
uint32_t mask = (
|
||||||
CFG_SCR_BOOTLOADER_SKIP |
|
CFG_SCR_BOOTLOADER_SKIP |
|
||||||
CFG_SCR_ROM_WRITE_ENABLED |
|
CFG_SCR_ROM_WRITE_ENABLED |
|
||||||
@ -364,7 +382,7 @@ void cfg_reset (void) {
|
|||||||
|
|
||||||
void cfg_init (void) {
|
void cfg_init (void) {
|
||||||
fpga_reg_set(REG_CFG_SCR, CFG_SCR_BOOTLOADER_ENABLED);
|
fpga_reg_set(REG_CFG_SCR, CFG_SCR_BOOTLOADER_ENABLED);
|
||||||
cfg_reset();
|
cfg_reset_state();
|
||||||
p.usb_output_ready = true;
|
p.usb_output_ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,7 +430,7 @@ void cfg_process (void) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm':
|
case 'm':
|
||||||
if (cfg_translate_address(&args[0], args[1], false)) {
|
if (cfg_translate_address(&args[0], args[1], (SDRAM | BRAM))) {
|
||||||
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -422,7 +440,7 @@ void cfg_process (void) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
if (cfg_translate_address(&args[0], args[1] & 0xFFFFFF, false)) {
|
if (cfg_translate_address(&args[0], args[1] & 0xFFFFFF, (SDRAM | BRAM))) {
|
||||||
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -449,20 +467,20 @@ void cfg_process (void) {
|
|||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
switch (args[1]) {
|
switch (args[1]) {
|
||||||
case 0:
|
case SD_CARD_OP_DEINIT:
|
||||||
sd_card_deinit();
|
sd_card_deinit();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case SD_CARD_OP_INIT:
|
||||||
if (sd_card_init()) {
|
if (sd_card_init()) {
|
||||||
cfg_set_error(CFG_ERROR_SD_CARD);
|
cfg_set_error(CFG_ERROR_SD_CARD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case SD_CARD_OP_GET_STATUS:
|
||||||
args[1] = sd_card_get_status();
|
args[1] = sd_card_get_status();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case SD_CARD_OP_GET_INFO:
|
||||||
if (cfg_translate_address(&args[0], 32, false)) {
|
if (cfg_translate_address(&args[0], 32, (SDRAM | BRAM))) {
|
||||||
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -486,7 +504,7 @@ void cfg_process (void) {
|
|||||||
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cfg_translate_address(&args[0], args[1] * SD_SECTOR_SIZE, true)) {
|
if (cfg_translate_address(&args[0], args[1] * SD_SECTOR_SIZE, (SDRAM | BRAM | FLASH))) {
|
||||||
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -501,7 +519,7 @@ void cfg_process (void) {
|
|||||||
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cfg_translate_address(&args[0], args[1] * SD_SECTOR_SIZE, true)) {
|
if (cfg_translate_address(&args[0], args[1] * SD_SECTOR_SIZE, (SDRAM | BRAM | FLASH))) {
|
||||||
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -512,13 +530,26 @@ void cfg_process (void) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
if (cfg_translate_address(&args[0], args[1], false)) {
|
if (cfg_translate_address(&args[0], args[1], (SDRAM | BRAM))) {
|
||||||
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dd_set_sd_disk_info(args[0], args[1]);
|
dd_set_sd_disk_info(args[0], args[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
flash_wait_busy();
|
||||||
|
args[0] = FLASH_ERASE_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'P':
|
||||||
|
if (cfg_translate_address(&args[0], FLASH_ERASE_BLOCK_SIZE, FLASH)) {
|
||||||
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flash_erase_block(args[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
args[0] = fpga_reg_get(REG_DEBUG);
|
args[0] = fpga_reg_get(REG_DEBUG);
|
||||||
break;
|
break;
|
||||||
|
@ -11,7 +11,7 @@ bool cfg_query (uint32_t *args);
|
|||||||
bool cfg_update (uint32_t *args);
|
bool cfg_update (uint32_t *args);
|
||||||
void cfg_get_time (uint32_t *args);
|
void cfg_get_time (uint32_t *args);
|
||||||
void cfg_set_time (uint32_t *args);
|
void cfg_set_time (uint32_t *args);
|
||||||
void cfg_reset (void);
|
void cfg_reset_state (void);
|
||||||
void cfg_init (void);
|
void cfg_init (void);
|
||||||
void cfg_process (void);
|
void cfg_process (void);
|
||||||
|
|
||||||
|
@ -2,16 +2,20 @@
|
|||||||
#include "fpga.h"
|
#include "fpga.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define FLASH_ADDRESS (0x04000000UL)
|
||||||
#define ERASE_BLOCK_SIZE (64 * 1024)
|
#define ERASE_BLOCK_SIZE (64 * 1024)
|
||||||
|
|
||||||
|
|
||||||
void flash_erase_block (uint32_t offset) {
|
void flash_wait_busy (void) {
|
||||||
uint8_t dummy[2];
|
uint8_t dummy[2];
|
||||||
|
fpga_mem_read(FLASH_ADDRESS, 2, dummy);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
void flash_erase_block (uint32_t offset) {
|
||||||
while (fpga_reg_get(REG_FLASH_SCR) & FLASH_SCR_BUSY);
|
for (int i = 0; i < (FLASH_ERASE_BLOCK_SIZE / ERASE_BLOCK_SIZE); i++) {
|
||||||
fpga_reg_set(REG_FLASH_SCR, offset);
|
fpga_reg_set(REG_FLASH_SCR, offset);
|
||||||
fpga_mem_read(offset, 2, dummy);
|
while (fpga_reg_get(REG_FLASH_SCR) & FLASH_SCR_BUSY);
|
||||||
offset += ERASE_BLOCK_SIZE;
|
offset += ERASE_BLOCK_SIZE;
|
||||||
}
|
}
|
||||||
|
flash_wait_busy();
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#define FLASH_ERASE_BLOCK_SIZE (128 * 1024)
|
#define FLASH_ERASE_BLOCK_SIZE (128 * 1024)
|
||||||
|
|
||||||
|
|
||||||
|
void flash_wait_busy (void);
|
||||||
void flash_erase_block (uint32_t offset);
|
void flash_erase_block (uint32_t offset);
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,6 +128,8 @@ typedef enum {
|
|||||||
#define SD_SCR_CLOCK_MODE_400KHZ (1 << 0)
|
#define SD_SCR_CLOCK_MODE_400KHZ (1 << 0)
|
||||||
#define SD_SCR_CLOCK_MODE_25MHZ (2 << 0)
|
#define SD_SCR_CLOCK_MODE_25MHZ (2 << 0)
|
||||||
#define SD_SCR_CLOCK_MODE_50MHZ (3 << 0)
|
#define SD_SCR_CLOCK_MODE_50MHZ (3 << 0)
|
||||||
|
#define SD_SCR_CLOCK_MODE_BIT (0)
|
||||||
|
#define SD_SCR_CLOCK_MODE_MASK (0x3 << SD_SCR_CLOCK_MODE_BIT)
|
||||||
#define SD_SCR_CMD_BUSY (1 << 2)
|
#define SD_SCR_CMD_BUSY (1 << 2)
|
||||||
#define SD_SCR_CMD_ERROR (1 << 3)
|
#define SD_SCR_CMD_ERROR (1 << 3)
|
||||||
#define SD_SCR_CARD_BUSY (1 << 4)
|
#define SD_SCR_CARD_BUSY (1 << 4)
|
||||||
|
@ -339,8 +339,16 @@ void sd_card_deinit (void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sd_card_get_status (void) {
|
uint32_t sd_card_get_status (void) {
|
||||||
return p.card_initialized;
|
uint32_t scr = fpga_reg_get(REG_SD_SCR);
|
||||||
|
uint32_t clock_mode_50mhz = ((scr & SD_SCR_CLOCK_MODE_MASK) == SD_SCR_CLOCK_MODE_50MHZ) ? 1 : 0;
|
||||||
|
uint32_t card_type_block = p.card_type_block ? 1 : 0;
|
||||||
|
uint32_t initialized = p.card_initialized ? 1 : 0;
|
||||||
|
return (
|
||||||
|
(clock_mode_50mhz << 2) |
|
||||||
|
(card_type_block << 1) |
|
||||||
|
(initialized << 0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sd_card_get_info (uint32_t address) {
|
bool sd_card_get_info (uint32_t address) {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
bool sd_card_init (void);
|
bool sd_card_init (void);
|
||||||
void sd_card_deinit (void);
|
void sd_card_deinit (void);
|
||||||
bool sd_card_get_status (void);
|
uint32_t sd_card_get_status (void);
|
||||||
bool sd_card_get_info (uint32_t address);
|
bool sd_card_get_info (uint32_t address);
|
||||||
bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count);
|
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_read_sectors (uint32_t address, uint32_t sector, uint32_t count);
|
||||||
|
@ -162,7 +162,7 @@ static void usb_rx_process (void) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'R':
|
case 'R':
|
||||||
cfg_reset();
|
cfg_reset_state();
|
||||||
cic_reset_parameters();
|
cic_reset_parameters();
|
||||||
p.rx_state = RX_STATE_IDLE;
|
p.rx_state = RX_STATE_IDLE;
|
||||||
p.response_pending = true;
|
p.response_pending = true;
|
||||||
@ -275,6 +275,20 @@ static void usb_rx_process (void) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
flash_wait_busy();
|
||||||
|
p.rx_state = RX_STATE_IDLE;
|
||||||
|
p.response_pending = true;
|
||||||
|
p.response_info.data_length = 4;
|
||||||
|
p.response_info.data[0] = FLASH_ERASE_BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'P':
|
||||||
|
flash_erase_block(p.rx_args[0]);
|
||||||
|
p.rx_state = RX_STATE_IDLE;
|
||||||
|
p.response_pending = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
p.rx_state = RX_STATE_IDLE;
|
p.rx_state = RX_STATE_IDLE;
|
||||||
p.response_pending = true;
|
p.response_pending = true;
|
||||||
|
@ -235,13 +235,12 @@ class SC64:
|
|||||||
SAVE_TYPE = 6
|
SAVE_TYPE = 6
|
||||||
CIC_SEED = 7
|
CIC_SEED = 7
|
||||||
TV_TYPE = 8
|
TV_TYPE = 8
|
||||||
FLASH_ERASE_BLOCK = 9
|
DD_SD_MODE = 9
|
||||||
DD_DRIVE_TYPE = 10
|
DD_DRIVE_TYPE = 10
|
||||||
DD_DISK_STATE = 11
|
DD_DISK_STATE = 11
|
||||||
BUTTON_STATE = 12
|
BUTTON_STATE = 12
|
||||||
BUTTON_MODE = 13
|
BUTTON_MODE = 13
|
||||||
ROM_EXTENDED_ENABLE = 14
|
ROM_EXTENDED_ENABLE = 14
|
||||||
DD_SD_MODE = 15
|
|
||||||
|
|
||||||
class __UpdateError(IntEnum):
|
class __UpdateError(IntEnum):
|
||||||
OK = 0
|
OK = 0
|
||||||
@ -343,16 +342,24 @@ class SC64:
|
|||||||
return self.__link.execute_cmd(cmd=b'm', args=[address, length], timeout=20.0)
|
return self.__link.execute_cmd(cmd=b'm', args=[address, length], timeout=20.0)
|
||||||
return bytes([])
|
return bytes([])
|
||||||
|
|
||||||
|
def __flash_wait_busy(self) -> int:
|
||||||
|
data = self.__link.execute_cmd(cmd=b'p')
|
||||||
|
return self.__get_int(data[0:4])
|
||||||
|
|
||||||
|
def __flash_erase_block(self, address: int) -> None:
|
||||||
|
self.__link.execute_cmd(cmd=b'P', args=[address, 0])
|
||||||
|
|
||||||
def __erase_flash_region(self, address: int, length: int) -> None:
|
def __erase_flash_region(self, address: int, length: int) -> None:
|
||||||
if (address < self.__Address.FLASH):
|
if (address < self.__Address.FLASH):
|
||||||
raise ValueError('Flash erase address or length outside of possible range')
|
raise ValueError('Flash erase address or length outside of possible range')
|
||||||
if ((address + length) > (self.__Address.FLASH + self.__Length.FLASH)):
|
if ((address + length) > (self.__Address.FLASH + self.__Length.FLASH)):
|
||||||
raise ValueError('Flash erase address or length outside of possible range')
|
raise ValueError('Flash erase address or length outside of possible range')
|
||||||
erase_block_size = self.__get_config(self.__CfgId.FLASH_ERASE_BLOCK)
|
erase_block_size = self.__flash_wait_busy()
|
||||||
if (address % erase_block_size != 0):
|
if (address % erase_block_size != 0):
|
||||||
raise ValueError('Flash erase address not aligned to block size')
|
raise ValueError('Flash erase address not aligned to block size')
|
||||||
for offset in range(address, address + length, erase_block_size):
|
for offset in range(address, address + length, erase_block_size):
|
||||||
self.__set_config(self.__CfgId.FLASH_ERASE_BLOCK, offset)
|
self.__flash_erase_block(offset)
|
||||||
|
self.__flash_wait_busy()
|
||||||
|
|
||||||
def __program_flash(self, address: int, data: bytes):
|
def __program_flash(self, address: int, data: bytes):
|
||||||
program_chunk_size = (128 * 1024)
|
program_chunk_size = (128 * 1024)
|
||||||
@ -377,13 +384,12 @@ class SC64:
|
|||||||
'save_type': self.SaveType(self.__get_config(self.__CfgId.SAVE_TYPE)),
|
'save_type': self.SaveType(self.__get_config(self.__CfgId.SAVE_TYPE)),
|
||||||
'cic_seed': self.CICSeed(self.__get_config(self.__CfgId.CIC_SEED)),
|
'cic_seed': self.CICSeed(self.__get_config(self.__CfgId.CIC_SEED)),
|
||||||
'tv_type': self.TVType(self.__get_config(self.__CfgId.TV_TYPE)),
|
'tv_type': self.TVType(self.__get_config(self.__CfgId.TV_TYPE)),
|
||||||
'flash_erase_block': self.__get_config(self.__CfgId.FLASH_ERASE_BLOCK),
|
'dd_sd_mode': bool(self.__get_config(self.__CfgId.DD_SD_MODE)),
|
||||||
'dd_drive_type': self.__DDDriveType(self.__get_config(self.__CfgId.DD_DRIVE_TYPE)),
|
'dd_drive_type': self.__DDDriveType(self.__get_config(self.__CfgId.DD_DRIVE_TYPE)),
|
||||||
'dd_disk_state': self.__DDDiskState(self.__get_config(self.__CfgId.DD_DISK_STATE)),
|
'dd_disk_state': self.__DDDiskState(self.__get_config(self.__CfgId.DD_DISK_STATE)),
|
||||||
'button_state': bool(self.__get_config(self.__CfgId.BUTTON_STATE)),
|
'button_state': bool(self.__get_config(self.__CfgId.BUTTON_STATE)),
|
||||||
'button_mode': self.__ButtonMode(self.__get_config(self.__CfgId.BUTTON_MODE)),
|
'button_mode': self.__ButtonMode(self.__get_config(self.__CfgId.BUTTON_MODE)),
|
||||||
'rom_extended_enable': bool(self.__get_config(self.__CfgId.ROM_EXTENDED_ENABLE)),
|
'rom_extended_enable': bool(self.__get_config(self.__CfgId.ROM_EXTENDED_ENABLE)),
|
||||||
'dd_sd_mode': bool(self.__get_config(self.__CfgId.DD_SD_MODE)),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def debug_send(self, datatype: __DebugDatatype, data: bytes) -> None:
|
def debug_send(self, datatype: __DebugDatatype, data: bytes) -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user