diff --git a/docs/02_usb_commands.md b/docs/02_usb_commands.md index 5d6b598..a4c71d9 100644 --- a/docs/02_usb_commands.md +++ b/docs/02_usb_commands.md @@ -6,7 +6,8 @@ | id | name | arg0 | arg1 | data | response | description | | --- | ---------------------- | ------------ | ------------ | ---- | ---------------- | --------------------------------------------------- | -| `v` | **VERSION_GET** | --- | --- | --- | api_version | Get command API version | +| `v` | **HW_VERSION_GET** | --- | --- | --- | hw_version | Get HW version | +| `V` | **API_VERSION_GET** | --- | --- | --- | api_version | Get USB command API version | | `R` | **STATE_RESET** | --- | --- | --- | --- | Reset entire flashcart state | | `B` | **CIC_PARAMS_SET** | cic_params_0 | cic_params_1 | --- | --- | Set CIC disable/mode/seed/checksum | | `c` | **CONFIG_GET** | config_id | --- | --- | current_value | Get config option | diff --git a/docs/03_n64_commands.md b/docs/03_n64_commands.md index d7d7ed6..5417ba8 100644 --- a/docs/03_n64_commands.md +++ b/docs/03_n64_commands.md @@ -6,7 +6,8 @@ | id | name | arg0 | arg1 | rsp0 | rsp1 | description | | --- | --------------------- | ---------- | ------------ | ---------------- | -------------- | -------------------------------------------------- | -| `v` | **VERSION_GET** | --- | --- | api_version | --- | Get command API version | +| `v` | **HW_VERSION_GET** | --- | --- | hw_version | --- | Get HW version | +| `V` | **API_VERSION_GET** | --- | --- | api_version | --- | Get N64 command API version | | `c` | **CONFIG_GET** | config_id | --- | --- | current_value | Get config option | | `C` | **CONFIG_SET** | config_id | new_value | --- | previous_value | Set config option and get previous value | | `c` | **SETTING_GET** | setting_id | --- | --- | current_value | Get persistent setting option | diff --git a/sw/bootloader/src/sc64.c b/sw/bootloader/src/sc64.c index b377465..16104b1 100644 --- a/sw/bootloader/src/sc64.c +++ b/sw/bootloader/src/sc64.c @@ -24,7 +24,8 @@ typedef struct { #define SC64_KEY_LOCK (0xFFFFFFFFUL) typedef enum { - SC64_CMD_VERSION_GET = 'v', + SC64_CMD_HW_VERSION_GET = 'v', + SC64_CMD_API_VERSION_GET = 'V', SC64_CMD_CONFIG_GET = 'c', SC64_CMD_CONFIG_SET = 'C', SC64_CMD_SETTING_GET = 'a', diff --git a/sw/controller/app.mk b/sw/controller/app.mk index e2da4ec..f3ae8b6 100644 --- a/sw/controller/app.mk +++ b/sw/controller/app.mk @@ -25,6 +25,7 @@ SRC_FILES = \ timer.c \ update.c \ usb.c \ + version.c \ writeback.c include common.mk diff --git a/sw/controller/src/cfg.c b/sw/controller/src/cfg.c index e26cd1e..b7e36b2 100644 --- a/sw/controller/src/cfg.c +++ b/sw/controller/src/cfg.c @@ -7,6 +7,7 @@ #include "rtc.h" #include "sd.h" #include "usb.h" +#include "version.h" #include "writeback.h" @@ -464,6 +465,10 @@ void cfg_process (void) { args[0] = cfg_get_version(); break; + case 'V': + args[0] = version_api(API_N64); + break; + case 'c': if (cfg_query(args)) { cfg_set_error(CFG_ERROR_BAD_CONFIG_ID); diff --git a/sw/controller/src/usb.c b/sw/controller/src/usb.c index 43e773f..f10385a 100644 --- a/sw/controller/src/usb.c +++ b/sw/controller/src/usb.c @@ -7,6 +7,7 @@ #include "rtc.h" #include "update.h" #include "usb.h" +#include "version.h" enum rx_state { @@ -162,6 +163,13 @@ static void usb_rx_process (void) { p.response_info.data[0] = cfg_get_version(); break; + case 'V': + p.rx_state = RX_STATE_IDLE; + p.response_pending = true; + p.response_info.data_length = 4; + p.response_info.data[0] = version_api(API_USB); + break; + case 'R': cfg_reset_state(); cic_reset_parameters(); diff --git a/sw/controller/src/version.c b/sw/controller/src/version.c new file mode 100644 index 0000000..a3a6667 --- /dev/null +++ b/sw/controller/src/version.c @@ -0,0 +1,17 @@ +#include "version.h" + + +#define VERSION_API_USB (1) +#define VERSION_API_N64 (1) + + +uint32_t version_api (version_api_type_t type) { + switch (type) { + case API_USB: + return VERSION_API_USB; + case API_N64: + return VERSION_API_N64; + default: + return 0; + } +} diff --git a/sw/controller/src/version.h b/sw/controller/src/version.h new file mode 100644 index 0000000..be0581d --- /dev/null +++ b/sw/controller/src/version.h @@ -0,0 +1,17 @@ +#ifndef VERSION_H__ +#define VERSION_H__ + + +#include + + +typedef enum { + API_USB, + API_N64, +} version_api_type_t; + + +uint32_t version_api (version_api_type_t type); + + +#endif diff --git a/sw/pc/sc64.py b/sw/pc/sc64.py index 3905e0f..67f88c2 100755 --- a/sw/pc/sc64.py +++ b/sw/pc/sc64.py @@ -319,6 +319,8 @@ class SC64: SCREENSHOT = 4 GDB = 0xDB + __MIN_SUPPORTED_API_VERSION = 1 + __isv_line_buffer: bytes = b'' __debug_header: Optional[bytes] = None __gdb_client: Optional[socket.socket] = None @@ -327,11 +329,20 @@ class SC64: self.__link = SC64Serial() version = self.__link.execute_cmd(cmd=b'v') if (version != b'SCv2'): - raise ConnectionException('Unknown SC64 API version') + raise ConnectionException('Unknown SC64 HW version') def __get_int(self, data: bytes) -> int: return int.from_bytes(data[:4], byteorder='big') + def check_api_version(self) -> None: + try: + data = self.__link.execute_cmd(cmd=b'V') + except ConnectionException: + raise ConnectionException('Outdated SC64 API, please update firmware') + version = self.__get_int(data) + if (version < self.__MIN_SUPPORTED_API_VERSION): + raise ConnectionException('Unsupported SC64 API version, please update firmware') + def __set_config(self, config: __CfgId, value: int) -> None: try: self.__link.execute_cmd(cmd=b'C', args=[config, value]) @@ -876,7 +887,9 @@ if __name__ == '__main__': status_callback = lambda status: print(f'{status} ', end='', flush=True) sc64.update_firmware(f.read(), status_callback) print('done') - + + sc64.check_api_version() + if (args.update_bootloader): with open(args.update_bootloader, 'rb') as f: print('Uploading Bootloader... ', end='', flush=True)