mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-29 08:44:15 +01:00
ff69030643
* isv support + usb/dd improvements
* make room for saves
* update offset
* fixed debug address
* idk
* exception
* ironed out all broken stuff
* cleanup
* return epc fix
* better
* more cleanup
* even more cleanup
* mooore cleanup
* fixed printf
* no assert
* improved docker build, pyft232 instead of pyserial
* fixed displaying long message strings
description test
* just straight cleanup
* smallest cleanup
* PAL
* cpu buffer
* n64 bootloader done
* super slow usb storage reading implemented
* reduced buffer size
* usb gets fast
* little cleanup
* double buffered reads
* removed separate event id
* ISV in hardware finally
* small exception changes
* mac testing
* py spacing
* fsd write, rtc, isv and reset fixes
* fixxx
* good stopping point
* usb fixed?
* pretend we have 128 MB sdram
* backup
* chmod
* test
* test done
* more tests
* user rm
* help
* final fix
* updated component values
* nice asset names
* cic 64dd support
* ddipl enable separation
* pre DMA rewrite, created dedicated buffer memory space, simplified code
* dma rewrite, needs testing
* moved xml
* dd basics
* timing
* 64dd working yet again, isv brought back, dma fixes, usb path rewrite, pc code rewrite
* added usb read functionality, general cleanup
* changed mem addressing
* added fpga flash update access
* added mcu update
* chmod
* little cleanup
* update format and stuff
* fixes
* uninitialized fix
* small fixes
* update fixes
* update stuff done
* fpga update tested
* build time fix
* boot fix
* test timing
* readme test
* test 2
* reports
* testseet
* final
* build test
* forgot
* button and naming
* General cleanup
And multiline commit message test
* Exception screen UI touch ups
* display separation and tests beginning
* pc software update
* pc software done
* timing test
* delete launch.json
* sw fixes
* fixed button hole diameter in shell
* small cleanup, rpi testing
* shell fillet fix, pc rtc printing
* added cfg lock mechanism
* moved lock to cfg address space
* extended ROM and ISV fixes
* preliminary sd card support
* little sd card cleanup
* sd menu fixes
* 5 second limit
* reduced shell thickness
* basic led act blinking
* faster sd menu loading
* inst cache invalidate
* sd card writing is working
* SD card CSD and CID registers
* wait for previous command
* led error codes
* fixed cfg_translate_address use
* 64dd from sd card working
* 64dd speedup and button handling
* delayed address latching cycle - might break other builds, needs testing
* bootloader improvements
* small fixes
* return previous cfg when setting new
* cache stuff
* unfloader debug protocol support
* UNFLoader style debug command line support
* requirements.txt
* shell groove fillet
* reset state inside controller
* fixed fast PI read, added PI R/W fifo debug info
* PI access prioritize
* SD clock stop when RX FIFO is more than half full
* flash erase method change
* CFG error handling, TLOZ MM debug ISV support
* CIC5167 support
* general fixes
* USB unplugged cable handling
* turn off led when changing between error/act modes
* rtc 2 bit clock stop support
* line endings
* Revert "line endings"
This reverts commit d0ddfe5ec7
.
* PI address debug
* readme test
* diagram update
* diagram background
* diagram background
* diagram background
* updated readme
586 lines
18 KiB
C
586 lines
18 KiB
C
#include "button.h"
|
|
#include "cfg.h"
|
|
#include "dd.h"
|
|
#include "flash.h"
|
|
#include "fpga.h"
|
|
#include "isv.h"
|
|
#include "rtc.h"
|
|
#include "sd.h"
|
|
#include "usb.h"
|
|
|
|
|
|
typedef enum {
|
|
CFG_ID_BOOTLOADER_SWITCH,
|
|
CFG_ID_ROM_WRITE_ENABLE,
|
|
CFG_ID_ROM_SHADOW_ENABLE,
|
|
CFG_ID_DD_MODE,
|
|
CFG_ID_ISV_ADDRESS,
|
|
CFG_ID_BOOT_MODE,
|
|
CFG_ID_SAVE_TYPE,
|
|
CFG_ID_CIC_SEED,
|
|
CFG_ID_TV_TYPE,
|
|
CFG_ID_DD_SD_ENABLE,
|
|
CFG_ID_DD_DRIVE_TYPE,
|
|
CFG_ID_DD_DISK_STATE,
|
|
CFG_ID_BUTTON_STATE,
|
|
CFG_ID_BUTTON_MODE,
|
|
CFG_ID_ROM_EXTENDED_ENABLE,
|
|
} cfg_id_t;
|
|
|
|
typedef enum {
|
|
DD_MODE_DISABLED = 0,
|
|
DD_MODE_REGS = 1,
|
|
DD_MODE_IPL = 2,
|
|
DD_MODE_FULL = 3
|
|
} dd_mode_t;
|
|
|
|
typedef enum {
|
|
BOOT_MODE_MENU = 0,
|
|
BOOT_MODE_ROM = 1,
|
|
BOOT_MODE_DD = 2,
|
|
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;
|
|
|
|
typedef enum {
|
|
TV_TYPE_PAL = 0,
|
|
TV_TYPE_NTSC = 1,
|
|
TV_TYPE_MPAL = 2,
|
|
TV_TYPE_UNKNOWN = 3
|
|
} tv_type_t;
|
|
|
|
typedef enum {
|
|
CFG_ERROR_OK = 0,
|
|
CFG_ERROR_BAD_ARGUMENT = 1,
|
|
CFG_ERROR_BAD_ADDRESS = 2,
|
|
CFG_ERROR_BAD_CONFIG_ID = 3,
|
|
CFG_ERROR_TIMEOUT = 4,
|
|
CFG_ERROR_SD_CARD = 5,
|
|
CFG_ERROR_UNKNOWN_CMD = -1,
|
|
} 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 {
|
|
boot_mode_t boot_mode;
|
|
save_type_t save_type;
|
|
cic_seed_t cic_seed;
|
|
tv_type_t tv_type;
|
|
bool usb_output_ready;
|
|
uint32_t sd_card_sector;
|
|
};
|
|
|
|
|
|
static struct process p;
|
|
|
|
|
|
static void cfg_set_usb_output_ready (void) {
|
|
p.usb_output_ready = true;
|
|
}
|
|
|
|
static bool cfg_translate_address (uint32_t *address, uint32_t length, translate_type_t type) {
|
|
if (length == 0) {
|
|
return true;
|
|
}
|
|
*address &= 0x1FFFFFFF;
|
|
if (type & SDRAM) {
|
|
if (*address >= 0x06000000 && *address < 0x06400000) {
|
|
if ((*address + length) <= 0x06400000) {
|
|
*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 (type & FLASH) {
|
|
if (*address >= 0x14000000 && *address < 0x14E00000) {
|
|
if ((*address + length) <= 0x14E00000) {
|
|
*address = *address - 0x14000000 + 0x04000000;
|
|
return false;
|
|
}
|
|
}
|
|
if (*address >= 0x1FFC0000 && *address < 0x1FFE0000) {
|
|
if ((*address + length) <= 0x1FFE0000) {
|
|
*address = *address - 0x1FFC0000 + 0x04E00000;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
if (type & BRAM) {
|
|
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;
|
|
}
|
|
|
|
static void cfg_set_error (cfg_error_t error) {
|
|
fpga_reg_set(REG_CFG_DATA_0, error);
|
|
fpga_reg_set(REG_CFG_DATA_1, 0);
|
|
fpga_reg_set(REG_CFG_CMD, CFG_CMD_ERROR | CFG_CMD_DONE);
|
|
}
|
|
|
|
static void cfg_change_scr_bits (uint32_t mask, bool value) {
|
|
if (value) {
|
|
fpga_reg_set(REG_CFG_SCR, fpga_reg_get(REG_CFG_SCR) | mask);
|
|
} else {
|
|
fpga_reg_set(REG_CFG_SCR, fpga_reg_get(REG_CFG_SCR) & (~mask));
|
|
}
|
|
}
|
|
|
|
static bool cfg_set_save_type (save_type_t save_type) {
|
|
if (save_type > SAVE_TYPE_SRAM_BANKED) {
|
|
return true;
|
|
}
|
|
|
|
uint32_t save_reset_mask = (
|
|
CFG_SCR_EEPROM_16K |
|
|
CFG_SCR_EEPROM_ENABLED |
|
|
CFG_SCR_FLASHRAM_ENABLED |
|
|
CFG_SCR_SRAM_BANKED |
|
|
CFG_SCR_SRAM_ENABLED
|
|
);
|
|
|
|
cfg_change_scr_bits(save_reset_mask, false);
|
|
|
|
switch (save_type) {
|
|
case SAVE_TYPE_NONE:
|
|
break;
|
|
case SAVE_TYPE_EEPROM_4K:
|
|
cfg_change_scr_bits(CFG_SCR_EEPROM_ENABLED, true);
|
|
break;
|
|
case SAVE_TYPE_EEPROM_16K:
|
|
cfg_change_scr_bits(CFG_SCR_EEPROM_16K | CFG_SCR_EEPROM_ENABLED, true);
|
|
break;
|
|
case SAVE_TYPE_SRAM:
|
|
cfg_change_scr_bits(CFG_SCR_SRAM_ENABLED, true);
|
|
break;
|
|
case SAVE_TYPE_FLASHRAM:
|
|
cfg_change_scr_bits(CFG_SCR_FLASHRAM_ENABLED, true);
|
|
break;
|
|
case SAVE_TYPE_SRAM_BANKED:
|
|
cfg_change_scr_bits(CFG_SCR_SRAM_BANKED | CFG_SCR_SRAM_ENABLED, true);
|
|
break;
|
|
default:
|
|
save_type = SAVE_TYPE_NONE;
|
|
break;
|
|
}
|
|
|
|
p.save_type = save_type;
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
uint32_t cfg_get_version (void) {
|
|
return fpga_reg_get(REG_CFG_VERSION);
|
|
}
|
|
|
|
bool cfg_query (uint32_t *args) {
|
|
uint32_t scr = fpga_reg_get(REG_CFG_SCR);
|
|
|
|
switch (args[0]) {
|
|
case CFG_ID_BOOTLOADER_SWITCH:
|
|
args[1] = (scr & CFG_SCR_BOOTLOADER_ENABLED);
|
|
break;
|
|
case CFG_ID_ROM_WRITE_ENABLE:
|
|
args[1] = (scr & CFG_SCR_ROM_WRITE_ENABLED);
|
|
break;
|
|
case CFG_ID_ROM_SHADOW_ENABLE:
|
|
args[1] = (scr & CFG_SCR_ROM_SHADOW_ENABLED);
|
|
break;
|
|
case CFG_ID_DD_MODE:
|
|
args[1] = DD_MODE_DISABLED;
|
|
if (scr & CFG_SCR_DDIPL_ENABLED) {
|
|
args[1] |= DD_MODE_IPL;
|
|
}
|
|
if (scr & CFG_SCR_DD_ENABLED) {
|
|
args[1] |= DD_MODE_REGS;
|
|
}
|
|
break;
|
|
case CFG_ID_ISV_ADDRESS:
|
|
args[1] = isv_get_address();
|
|
break;
|
|
case CFG_ID_BOOT_MODE:
|
|
args[1] = p.boot_mode;
|
|
break;
|
|
case CFG_ID_SAVE_TYPE:
|
|
args[1] = p.save_type;
|
|
break;
|
|
case CFG_ID_CIC_SEED:
|
|
args[1] = p.cic_seed;
|
|
break;
|
|
case CFG_ID_TV_TYPE:
|
|
args[1] = p.tv_type;
|
|
break;
|
|
case CFG_ID_DD_SD_ENABLE:
|
|
args[1] = dd_get_sd_mode();
|
|
break;
|
|
case CFG_ID_DD_DRIVE_TYPE:
|
|
args[1] = dd_get_drive_type();
|
|
break;
|
|
case CFG_ID_DD_DISK_STATE:
|
|
args[1] = dd_get_disk_state();
|
|
break;
|
|
case CFG_ID_BUTTON_STATE:
|
|
args[1] = button_get_state();
|
|
break;
|
|
case CFG_ID_BUTTON_MODE:
|
|
args[1] = button_get_mode();
|
|
break;
|
|
case CFG_ID_ROM_EXTENDED_ENABLE:
|
|
args[1] = (scr & CFG_SCR_ROM_EXTENDED_ENABLED);
|
|
break;
|
|
default:
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool cfg_update (uint32_t *args) {
|
|
switch (args[0]) {
|
|
case CFG_ID_BOOTLOADER_SWITCH:
|
|
cfg_change_scr_bits(CFG_SCR_BOOTLOADER_ENABLED, args[1]);
|
|
break;
|
|
case CFG_ID_ROM_WRITE_ENABLE:
|
|
cfg_change_scr_bits(CFG_SCR_ROM_WRITE_ENABLED, args[1]);
|
|
break;
|
|
case CFG_ID_ROM_SHADOW_ENABLE:
|
|
cfg_change_scr_bits(CFG_SCR_ROM_SHADOW_ENABLED, args[1]);
|
|
break;
|
|
case CFG_ID_DD_MODE:
|
|
if (args[1] == DD_MODE_DISABLED) {
|
|
cfg_change_scr_bits(CFG_SCR_DD_ENABLED | CFG_SCR_DDIPL_ENABLED, false);
|
|
} else if (args[1] == DD_MODE_REGS) {
|
|
cfg_change_scr_bits(CFG_SCR_DD_ENABLED, true);
|
|
cfg_change_scr_bits(CFG_SCR_DDIPL_ENABLED, false);
|
|
} else if (args[1] == DD_MODE_IPL) {
|
|
cfg_change_scr_bits(CFG_SCR_DD_ENABLED, false);
|
|
cfg_change_scr_bits(CFG_SCR_DDIPL_ENABLED, true);
|
|
} else if (args[1] == DD_MODE_FULL) {
|
|
cfg_change_scr_bits(CFG_SCR_DD_ENABLED | CFG_SCR_DDIPL_ENABLED, true);
|
|
} else {
|
|
return true;
|
|
}
|
|
break;
|
|
case CFG_ID_ISV_ADDRESS:
|
|
return isv_set_address(args[1]);
|
|
break;
|
|
case CFG_ID_BOOT_MODE:
|
|
if (args[1] > BOOT_MODE_DIRECT) {
|
|
return true;
|
|
}
|
|
p.boot_mode = args[1];
|
|
cfg_change_scr_bits(CFG_SCR_BOOTLOADER_SKIP, (args[1] == BOOT_MODE_DIRECT));
|
|
break;
|
|
case CFG_ID_SAVE_TYPE:
|
|
return cfg_set_save_type((save_type_t) (args[1]));
|
|
break;
|
|
case CFG_ID_CIC_SEED:
|
|
if ((args[1] != 0xFFFF) && (args[1] > 0x1FF)) {
|
|
return true;
|
|
}
|
|
p.cic_seed = (cic_seed_t) (args[1] & 0xFFFF);
|
|
break;
|
|
case CFG_ID_TV_TYPE:
|
|
if (args[1] > TV_TYPE_UNKNOWN) {
|
|
return true;
|
|
}
|
|
p.tv_type = (tv_type_t) (args[1] & 0x03);
|
|
break;
|
|
case CFG_ID_DD_SD_ENABLE:
|
|
dd_set_sd_mode(args[1]);
|
|
break;
|
|
case CFG_ID_DD_DRIVE_TYPE:
|
|
return dd_set_drive_type(args[1]);
|
|
break;
|
|
case CFG_ID_DD_DISK_STATE:
|
|
return dd_set_disk_state(args[1]);
|
|
break;
|
|
case CFG_ID_BUTTON_STATE:
|
|
return true;
|
|
break;
|
|
case CFG_ID_BUTTON_MODE:
|
|
return button_set_mode(args[1]);
|
|
break;
|
|
case CFG_ID_ROM_EXTENDED_ENABLE:
|
|
cfg_change_scr_bits(CFG_SCR_ROM_EXTENDED_ENABLED, args[1]);
|
|
break;
|
|
default:
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void cfg_get_time (uint32_t *args) {
|
|
rtc_time_t t;
|
|
rtc_get_time(&t);
|
|
args[0] = ((t.hour << 16) | (t.minute << 8) | t.second);
|
|
args[1] = ((t.weekday << 24) | (t.year << 16) | (t.month << 8) | t.day);
|
|
}
|
|
|
|
void cfg_set_time (uint32_t *args) {
|
|
rtc_time_t t;
|
|
t.second = (args[0] & 0xFF);
|
|
t.minute = ((args[0] >> 8) & 0xFF);
|
|
t.hour = ((args[0] >> 16) & 0xFF);
|
|
t.weekday = ((args[0] >> 24) & 0xFF);
|
|
t.day = (args[1] & 0xFF);
|
|
t.month = ((args[1] >> 8) & 0xFF);
|
|
t.year = ((args[1] >> 16) & 0xFF);
|
|
rtc_set_time(&t);
|
|
}
|
|
|
|
void cfg_reset_state (void) {
|
|
uint32_t mask = (
|
|
CFG_SCR_BOOTLOADER_SKIP |
|
|
CFG_SCR_ROM_WRITE_ENABLED |
|
|
CFG_SCR_ROM_SHADOW_ENABLED |
|
|
CFG_SCR_DD_ENABLED |
|
|
CFG_SCR_DDIPL_ENABLED |
|
|
CFG_SCR_ROM_EXTENDED_ENABLED
|
|
);
|
|
cfg_change_scr_bits(mask, false);
|
|
cfg_set_save_type(SAVE_TYPE_NONE);
|
|
button_set_mode(BUTTON_MODE_NONE);
|
|
dd_set_drive_type(DD_DRIVE_TYPE_RETAIL);
|
|
dd_set_disk_state(DD_DISK_STATE_EJECTED);
|
|
dd_set_sd_mode(false);
|
|
isv_set_address(0);
|
|
p.cic_seed = CIC_SEED_UNKNOWN;
|
|
p.tv_type = TV_TYPE_UNKNOWN;
|
|
p.boot_mode = BOOT_MODE_MENU;
|
|
}
|
|
|
|
void cfg_init (void) {
|
|
fpga_reg_set(REG_CFG_SCR, CFG_SCR_BOOTLOADER_ENABLED);
|
|
cfg_reset_state();
|
|
p.usb_output_ready = true;
|
|
}
|
|
|
|
void cfg_process (void) {
|
|
uint32_t reg;
|
|
uint32_t args[2];
|
|
uint32_t prev_cfg[2];
|
|
usb_tx_info_t packet_info;
|
|
|
|
reg = fpga_reg_get(REG_CFG_CMD);
|
|
|
|
if (reg & CFG_CMD_PENDING) {
|
|
args[0] = fpga_reg_get(REG_CFG_DATA_0);
|
|
args[1] = fpga_reg_get(REG_CFG_DATA_1);
|
|
char cmd = (char) ((reg & CFG_CMD_MASK) >> CFG_CMD_BIT);
|
|
|
|
switch (cmd) {
|
|
case 'v':
|
|
args[0] = cfg_get_version();
|
|
break;
|
|
|
|
case 'c':
|
|
if (cfg_query(args)) {
|
|
cfg_set_error(CFG_ERROR_BAD_CONFIG_ID);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 'C':
|
|
prev_cfg[0] = args[0];
|
|
cfg_query(prev_cfg);
|
|
if (cfg_update(args)) {
|
|
cfg_set_error(CFG_ERROR_BAD_CONFIG_ID);
|
|
return;
|
|
}
|
|
args[1] = prev_cfg[1];
|
|
break;
|
|
|
|
case 't':
|
|
cfg_get_time(args);
|
|
break;
|
|
|
|
case 'T':
|
|
cfg_set_time(args);
|
|
break;
|
|
|
|
case 'm':
|
|
if (cfg_translate_address(&args[0], args[1], (SDRAM | BRAM))) {
|
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
|
return;
|
|
}
|
|
if (!usb_prepare_read(args)) {
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 'M':
|
|
if (cfg_translate_address(&args[0], args[1] & 0xFFFFFF, (SDRAM | BRAM))) {
|
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
|
return;
|
|
}
|
|
usb_create_packet(&packet_info, PACKET_CMD_DEBUG_OUTPUT);
|
|
packet_info.data_length = 4;
|
|
packet_info.data[0] = args[1];
|
|
packet_info.dma_length = (args[1] & 0xFFFFFF);
|
|
packet_info.dma_address = args[0];
|
|
packet_info.done_callback = cfg_set_usb_output_ready;
|
|
if (usb_enqueue_packet(&packet_info)) {
|
|
p.usb_output_ready = false;
|
|
} else {
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 'u':
|
|
usb_get_read_info(args);
|
|
break;
|
|
|
|
case 'U':
|
|
args[0] = p.usb_output_ready ? 0 : (1 << 31);
|
|
break;
|
|
|
|
case 'i':
|
|
switch (args[1]) {
|
|
case SD_CARD_OP_DEINIT:
|
|
sd_card_deinit();
|
|
break;
|
|
case SD_CARD_OP_INIT:
|
|
if (sd_card_init()) {
|
|
cfg_set_error(CFG_ERROR_SD_CARD);
|
|
return;
|
|
}
|
|
break;
|
|
case SD_CARD_OP_GET_STATUS:
|
|
args[1] = sd_card_get_status();
|
|
break;
|
|
case SD_CARD_OP_GET_INFO:
|
|
if (cfg_translate_address(&args[0], 32, (SDRAM | BRAM))) {
|
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
|
return;
|
|
}
|
|
if (sd_card_get_info(args[0])) {
|
|
cfg_set_error(CFG_ERROR_SD_CARD);
|
|
return;
|
|
}
|
|
break;
|
|
default:
|
|
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 'I':
|
|
p.sd_card_sector = args[0];
|
|
break;
|
|
|
|
case 's':
|
|
if (args[1] >= 0x800000) {
|
|
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
|
return;
|
|
}
|
|
if (cfg_translate_address(&args[0], args[1] * SD_SECTOR_SIZE, (SDRAM | BRAM | FLASH))) {
|
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
|
return;
|
|
}
|
|
if (sd_read_sectors(args[0], p.sd_card_sector, args[1])) {
|
|
cfg_set_error(CFG_ERROR_SD_CARD);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 'S':
|
|
if (args[1] >= 0x800000) {
|
|
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
|
return;
|
|
}
|
|
if (cfg_translate_address(&args[0], args[1] * SD_SECTOR_SIZE, (SDRAM | BRAM | FLASH))) {
|
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
|
return;
|
|
}
|
|
if (sd_write_sectors(args[0], p.sd_card_sector, args[1])) {
|
|
cfg_set_error(CFG_ERROR_SD_CARD);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 'D':
|
|
if (cfg_translate_address(&args[0], args[1], (SDRAM | BRAM))) {
|
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
|
return;
|
|
}
|
|
dd_set_sd_disk_info(args[0], args[1]);
|
|
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 '?':
|
|
args[0] = fpga_reg_get(REG_DEBUG_0);
|
|
args[1] = fpga_reg_get(REG_DEBUG_1);
|
|
break;
|
|
|
|
default:
|
|
cfg_set_error(CFG_ERROR_UNKNOWN_CMD);
|
|
return;
|
|
}
|
|
|
|
fpga_reg_set(REG_CFG_DATA_0, args[0]);
|
|
fpga_reg_set(REG_CFG_DATA_1, args[1]);
|
|
fpga_reg_set(REG_CFG_CMD, CFG_CMD_DONE);
|
|
}
|
|
}
|