diff --git a/sw/bootloader/src/io.h b/sw/bootloader/src/io.h index 03d3a18..10980b3 100644 --- a/sw/bootloader/src/io.h +++ b/sw/bootloader/src/io.h @@ -228,37 +228,6 @@ typedef struct { #define PIFRAM ((io8_t *) PIFRAM_BASE) -typedef struct { - io8_t BUFFER[8192]; - io8_t EEPROM[2048]; - io8_t DD_SECTOR[256]; - io8_t FLASHRAM[128]; -} sc64_buffers_t; - -#define SC64_BUFFERS_BASE (0x1FFE0000UL) -#define SC64_BUFFERS ((sc64_buffers_t *) SC64_BUFFERS_BASE) - - -typedef struct { - io32_t SR_CMD; - io32_t DATA[2]; - io32_t VERSION; - io32_t KEY; -} sc64_regs_t; - -#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_KEY_RESET (0x00000000UL) -#define SC64_KEY_UNLOCK_1 (0x5F554E4CUL) -#define SC64_KEY_UNLOCK_2 (0x4F434B5FUL) -#define SC64_KEY_LOCK (0xFFFFFFFFUL) - - typedef struct { uint32_t tv_type; uint32_t device_type; diff --git a/sw/bootloader/src/sc64.c b/sw/bootloader/src/sc64.c index aaf7683..6eb3b8b 100644 --- a/sw/bootloader/src/sc64.c +++ b/sw/bootloader/src/sc64.c @@ -2,27 +2,46 @@ #include "sc64.h" -#define SC64_VERSION_2 (0x53437632) +typedef struct { + io32_t SR_CMD; + io32_t DATA[2]; + io32_t VERSION; + io32_t KEY; +} sc64_regs_t; +#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_VERSION_2 (0x53437632) + +#define SC64_KEY_RESET (0x00000000UL) +#define SC64_KEY_UNLOCK_1 (0x5F554E4CUL) +#define SC64_KEY_UNLOCK_2 (0x4F434B5FUL) +#define SC64_KEY_LOCK (0xFFFFFFFFUL) typedef enum { SC64_CMD_VERSION_GET = 'v', - SC64_CMD_CONFIG_SET = 'C', SC64_CMD_CONFIG_GET = 'c', - SC64_CMD_TIME_SET = 'T', + SC64_CMD_CONFIG_SET = 'C', SC64_CMD_TIME_GET = 't', - SC64_CMD_USB_WRITE_STATUS = 'U', + SC64_CMD_TIME_SET = 'T', + SC64_CMD_USB_READ = 'm', SC64_CMD_USB_WRITE = 'M', SC64_CMD_USB_READ_STATUS = 'u', - SC64_CMD_USB_READ = 'm', + SC64_CMD_USB_WRITE_STATUS = 'U', SC64_CMD_SD_CARD_OP = 'i', SC64_CMD_SD_SECTOR_SET = 'I', - SC64_CMD_SD_WRITE = 'S', SC64_CMD_SD_READ = 's', + SC64_CMD_SD_WRITE = 'S', SC64_CMD_DD_SD_INFO = 'D', SC64_CMD_WRITEBACK_SD_INFO = 'W', - SC64_CMD_FLASH_ERASE_BLOCK = 'P', SC64_CMD_FLASH_WAIT_BUSY = 'p', + SC64_CMD_FLASH_ERASE_BLOCK = 'P', + SC64_CMD_DEBUG_GET = '?', } cmd_id_t; typedef enum { @@ -42,7 +61,6 @@ static bool sc64_wait_cpu_busy (void) { } static bool sc64_execute_cmd (uint8_t cmd, uint32_t *args, uint32_t *result) { - sc64_wait_cpu_busy(); if (args != NULL) { pi_io_write(&SC64_REGS->DATA[0], args[0]); pi_io_write(&SC64_REGS->DATA[1], args[1]); @@ -56,6 +74,14 @@ static bool sc64_execute_cmd (uint8_t cmd, uint32_t *args, uint32_t *result) { return error; } + +sc64_error_t sc64_get_error (void) { + if (pi_io_read(&SC64_REGS->SR_CMD) & SC64_SR_CMD_ERROR) { + return (sc64_error_t) (pi_io_read(&SC64_REGS->DATA[0])); + } + return SC64_OK; +} + void sc64_unlock (void) { pi_io_write(&SC64_REGS->KEY, SC64_KEY_RESET); pi_io_write(&SC64_REGS->KEY, SC64_KEY_UNLOCK_1); @@ -69,19 +95,22 @@ void sc64_lock (void) { bool sc64_check_presence (void) { uint32_t version = pi_io_read(&SC64_REGS->VERSION); - return (version == SC64_VERSION_2); -} - -cmd_error_t sc64_get_error (void) { - if (pi_io_read(&SC64_REGS->SR_CMD) & SC64_SR_CMD_ERROR) { - return (cmd_error_t) pi_io_read(&SC64_REGS->DATA[0]); + if (version == SC64_VERSION_2) { + sc64_wait_cpu_busy(); + return true; } - return CMD_OK; + return false; } -void sc64_set_config (cfg_id_t id, uint32_t value) { - uint32_t args[2] = { id, value }; - sc64_execute_cmd(SC64_CMD_CONFIG_SET, args, NULL); +bool sc64_irq_pending (void) { + if (pi_io_read(&SC64_REGS->SR_CMD) & SC64_SR_IRQ_PENDING) { + return true; + } + return false; +} + +void sc64_irq_clear (void) { + pi_io_write(&SC64_REGS->VERSION, 0); } uint32_t sc64_get_config (cfg_id_t id) { @@ -91,20 +120,17 @@ uint32_t sc64_get_config (cfg_id_t id) { return result[1]; } +void sc64_set_config (cfg_id_t id, uint32_t value) { + uint32_t args[2] = { id, value }; + sc64_execute_cmd(SC64_CMD_CONFIG_SET, args, NULL); +} + void sc64_get_boot_info (sc64_boot_info_t *info) { info->cic_seed = (uint16_t) sc64_get_config(CFG_ID_CIC_SEED); info->tv_type = (tv_type_t) sc64_get_config(CFG_ID_TV_TYPE); info->boot_mode = (boot_mode_t) sc64_get_config(CFG_ID_BOOT_MODE); } -void sc64_set_time (rtc_time_t *t) { - uint32_t args[2] = { - ((t->hour << 16) | (t->minute << 8) | t->second), - ((t->weekday << 24) | (t->year << 16) | (t->month << 8) | t->day), - }; - sc64_execute_cmd(SC64_CMD_TIME_SET, args, NULL); -} - void sc64_get_time (rtc_time_t *t) { uint32_t result[2]; sc64_execute_cmd(SC64_CMD_TIME_GET, NULL, result); @@ -117,16 +143,12 @@ void sc64_get_time (rtc_time_t *t) { t->year = ((result[1] >> 16) & 0xFF); } -bool sc64_usb_write_ready (void) { - uint32_t result[2]; - sc64_execute_cmd(SC64_CMD_USB_WRITE_STATUS, NULL, result); - return (!(result[0] & (1 << 31))); -} - -bool sc64_usb_write (uint32_t *address, uint8_t type, uint32_t length) { - while (!sc64_usb_write_ready()); - uint32_t args[2] = { (uint32_t) (address), ((type << 24) | (length & 0xFFFFFF)) }; - return sc64_execute_cmd(SC64_CMD_USB_WRITE, args, NULL); +void sc64_set_time (rtc_time_t *t) { + uint32_t args[2] = { + ((t->hour << 16) | (t->minute << 8) | t->second), + ((t->weekday << 24) | (t->year << 16) | (t->month << 8) | t->day), + }; + sc64_execute_cmd(SC64_CMD_TIME_SET, args, NULL); } bool sc64_usb_read_ready (uint8_t *type, uint32_t *length) { @@ -141,7 +163,7 @@ bool sc64_usb_read_ready (uint8_t *type, uint32_t *length) { return (result[1] > 0); } -bool sc64_usb_read (uint32_t *address, uint32_t length) { +bool sc64_usb_read (void *address, uint32_t length) { uint32_t args[2] = { (uint32_t) (address), length }; uint32_t result[2]; if (sc64_execute_cmd(SC64_CMD_USB_READ, args, NULL)) { @@ -153,6 +175,18 @@ bool sc64_usb_read (uint32_t *address, uint32_t length) { return false; } +bool sc64_usb_write_ready (void) { + uint32_t result[2]; + sc64_execute_cmd(SC64_CMD_USB_WRITE_STATUS, NULL, result); + return (!(result[0] & (1 << 31))); +} + +bool sc64_usb_write (void *address, uint8_t type, uint32_t length) { + while (!sc64_usb_write_ready()); + uint32_t args[2] = { (uint32_t) (address), ((type << 24) | (length & 0xFFFFFF)) }; + return sc64_execute_cmd(SC64_CMD_USB_WRITE, args, NULL); +} + bool sc64_sd_card_init (void) { uint32_t args[2] = { 0, SD_CARD_OP_INIT }; if (sc64_execute_cmd(SC64_CMD_SD_CARD_OP, args, NULL)) { @@ -178,7 +212,7 @@ sd_card_status_t sc64_sd_card_get_status (void) { return (sd_card_status_t) (result[1]); } -bool sc64_sd_card_get_info (uint32_t *address) { +bool sc64_sd_card_get_info (void *address) { uint32_t args[2] = { (uint32_t) (address), SD_CARD_OP_GET_INFO }; if (sc64_execute_cmd(SC64_CMD_SD_CARD_OP, args, NULL)) { return true; @@ -186,16 +220,7 @@ bool sc64_sd_card_get_info (uint32_t *address) { return false; } -bool sc64_sd_write_sectors (uint32_t *address, uint32_t sector, uint32_t count) { - uint32_t sector_set_args[2] = { sector, 0 }; - uint32_t write_args[2] = { (uint32_t) (address), count }; - if (sc64_execute_cmd(SC64_CMD_SD_SECTOR_SET, sector_set_args, NULL)) { - return true; - } - return sc64_execute_cmd(SC64_CMD_SD_WRITE, write_args, NULL); -} - -bool sc64_sd_read_sectors (uint32_t *address, uint32_t sector, uint32_t count) { +bool sc64_sd_read_sectors (void *address, uint32_t sector, uint32_t count) { uint32_t sector_set_args[2] = { sector, 0 }; uint32_t read_args[2] = { (uint32_t) (address), count }; if (sc64_execute_cmd(SC64_CMD_SD_SECTOR_SET, sector_set_args, NULL)) { @@ -204,7 +229,16 @@ bool sc64_sd_read_sectors (uint32_t *address, uint32_t sector, uint32_t count) { return sc64_execute_cmd(SC64_CMD_SD_READ, read_args, NULL); } -bool sc64_dd_set_sd_info (uint32_t *address, uint32_t length) { +bool sc64_sd_write_sectors (void *address, uint32_t sector, uint32_t count) { + uint32_t sector_set_args[2] = { sector, 0 }; + uint32_t write_args[2] = { (uint32_t) (address), count }; + if (sc64_execute_cmd(SC64_CMD_SD_SECTOR_SET, sector_set_args, NULL)) { + return true; + } + return sc64_execute_cmd(SC64_CMD_SD_WRITE, write_args, NULL); +} + +bool sc64_dd_set_sd_info (void *address, uint32_t length) { uint32_t args[2] = { (uint32_t) (address), length }; if (sc64_execute_cmd(SC64_CMD_DD_SD_INFO, args, NULL)) { return true; @@ -212,10 +246,24 @@ bool sc64_dd_set_sd_info (uint32_t *address, uint32_t length) { return false; } -bool sc64_writeback_set_sd_info (uint32_t *address, bool enabled) { +bool sc64_writeback_set_sd_info (void *address, bool enabled) { uint32_t args[2] = { (uint32_t) (address), (uint32_t) (enabled) }; if (sc64_execute_cmd(SC64_CMD_WRITEBACK_SD_INFO, args, NULL)) { return true; } return false; } + +uint32_t sc64_flash_get_erase_block_size (void) { + uint32_t result[2]; + sc64_execute_cmd(SC64_CMD_FLASH_WAIT_BUSY, NULL, result); + return result[0]; +} + +bool sc64_flash_erase_block (void *address) { + uint32_t args[2] = { (uint32_t) (address), 0 }; + if (sc64_execute_cmd(SC64_CMD_FLASH_ERASE_BLOCK, args, NULL)) { + return true; + } + return sc64_execute_cmd(SC64_CMD_FLASH_WAIT_BUSY, NULL, NULL); +} diff --git a/sw/bootloader/src/sc64.h b/sw/bootloader/src/sc64.h index 4feb948..30b0465 100644 --- a/sw/bootloader/src/sc64.h +++ b/sw/bootloader/src/sc64.h @@ -7,12 +7,14 @@ typedef enum { - CMD_OK = 0, - CMD_ERROR_BAD_ADDRESS = 1, - CMD_ERROR_BAD_CONFIG_ID = 2, - CMD_ERROR_TIMEOUT = 3, - CMD_ERROR_UNKNOWN_CMD = -1, -} cmd_error_t; + SC64_OK, + SC64_ERROR_BAD_ARGUMENT, + SC64_ERROR_BAD_ADDRESS, + SC64_ERROR_BAD_CONFIG_ID, + SC64_ERROR_TIMEOUT, + SC64_ERROR_SD_CARD, + SC64_ERROR_UNKNOWN_CMD = -1 +} sc64_error_t; typedef enum { CFG_ID_BOOTLOADER_SWITCH, @@ -79,7 +81,6 @@ typedef enum { SD_CARD_STATUS_50MHZ_MODE = (1 << 2), } sd_card_status_t; - typedef struct { boot_mode_t boot_mode; uint16_t cic_seed; @@ -97,27 +98,49 @@ typedef struct { } rtc_time_t; +typedef struct { + volatile uint8_t BUFFER[8192]; + volatile uint8_t EEPROM[2048]; + volatile uint8_t DD_SECTOR[256]; + volatile uint8_t FLASHRAM[128]; +} sc64_buffers_t; + +#define SC64_BUFFERS_BASE (0x1FFE0000UL) +#define SC64_BUFFERS ((sc64_buffers_t *) SC64_BUFFERS_BASE) + + +sc64_error_t sc64_get_error (void); + void sc64_unlock (void); void sc64_lock (void); bool sc64_check_presence (void); -cmd_error_t sc64_get_error (void); -void sc64_set_config (cfg_id_t id, uint32_t value); + +bool sc64_irq_pending (void); +void sc64_irq_clear (void); + uint32_t sc64_get_config (cfg_id_t id); +void sc64_set_config (cfg_id_t id, uint32_t value); void sc64_get_boot_info (sc64_boot_info_t *info); -void sc64_set_time (rtc_time_t *t); + void sc64_get_time (rtc_time_t *t); -bool sc64_usb_write_ready (void); -bool sc64_usb_write (uint32_t *address, uint8_t type, uint32_t length); +void sc64_set_time (rtc_time_t *t); + 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 (void *address, uint32_t length); +bool sc64_usb_write_ready (void); +bool sc64_usb_write (void *address, uint8_t type, uint32_t length); + bool sc64_sd_card_init (void); bool sc64_sd_card_deinit (void); sd_card_status_t sc64_sd_card_get_status (void); -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_read_sectors (uint32_t *address, uint32_t sector, uint32_t count); -bool sc64_dd_set_sd_disk_info (uint32_t *address, uint32_t length); -bool sc64_writeback_set_sd_info (uint32_t *address, bool enabled); +bool sc64_sd_card_get_info (void *address); +bool sc64_sd_write_sectors (void *address, uint32_t sector, uint32_t count); +bool sc64_sd_read_sectors (void *address, uint32_t sector, uint32_t count); +bool sc64_dd_set_sd_disk_info (void *address, uint32_t length); +bool sc64_writeback_set_sd_info (void *address, bool enabled); + +uint32_t sc64_flash_get_erase_block_size (void); +bool sc64_flash_erase_block (void *address); #endif diff --git a/sw/bootloader/src/test.c b/sw/bootloader/src/test.c index 5095ccd..508c58a 100644 --- a/sw/bootloader/src/test.c +++ b/sw/bootloader/src/test.c @@ -57,10 +57,5 @@ void test_execute (void) { display_printf("%c ", card_info[i] >= ' ' ? card_info[i] : 0xFF); } - if (sc64_sd_card_deinit()) { - display_printf("SD card deinit error!\n"); - while (1); - } - while (1); } diff --git a/sw/controller/src/app.S b/sw/controller/src/app.S index 2c524e0..0f2b160 100644 --- a/sw/controller/src/app.S +++ b/sw/controller/src/app.S @@ -4,7 +4,7 @@ .thumb .section .loader, "a", %progbits -.type g_pfnVectors, %object +.type loader, %object loader: .incbin "../build/loader/loader.bin" diff --git a/sw/controller/src/isv.c b/sw/controller/src/isv.c index 2f20f6a..4dbcee5 100644 --- a/sw/controller/src/isv.c +++ b/sw/controller/src/isv.c @@ -46,7 +46,7 @@ static void isv_update_read_pointer (void) { bool isv_set_address (uint32_t address) { - if ((address > 0x03FF0000) || (address % 4)) { + if ((address >= 0x04000000) || (address % 4)) { return true; } p.address = address;