mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 23:24:15 +01:00
added cfg lock mechanism
This commit is contained in:
parent
8a8a3b4439
commit
30f0fc002e
Binary file not shown.
@ -42,6 +42,9 @@
|
|||||||
<Source name="../../rtl/n64/n64_flashram.sv" type="Verilog" type_short="Verilog">
|
<Source name="../../rtl/n64/n64_flashram.sv" type="Verilog" type_short="Verilog">
|
||||||
<Options VerilogStandard="System Verilog"/>
|
<Options VerilogStandard="System Verilog"/>
|
||||||
</Source>
|
</Source>
|
||||||
|
<Source name="../../rtl/n64/n64_lock.sv" type="Verilog" type_short="Verilog">
|
||||||
|
<Options VerilogStandard="System Verilog"/>
|
||||||
|
</Source>
|
||||||
<Source name="../../rtl/n64/n64_pi.sv" type="Verilog" type_short="Verilog">
|
<Source name="../../rtl/n64/n64_pi.sv" type="Verilog" type_short="Verilog">
|
||||||
<Options VerilogStandard="System Verilog"/>
|
<Options VerilogStandard="System Verilog"/>
|
||||||
</Source>
|
</Source>
|
||||||
|
@ -607,6 +607,7 @@ module mcu_top (
|
|||||||
sd_dma_scb.stop <= 1'b0;
|
sd_dma_scb.stop <= 1'b0;
|
||||||
|
|
||||||
n64_scb.cfg_done <= 1'b0;
|
n64_scb.cfg_done <= 1'b0;
|
||||||
|
n64_scb.cfg_error <= 1'b0;
|
||||||
n64_scb.cfg_irq <= 1'b0;
|
n64_scb.cfg_irq <= 1'b0;
|
||||||
|
|
||||||
n64_scb.flashram_done <= 1'b0;
|
n64_scb.flashram_done <= 1'b0;
|
||||||
|
@ -20,12 +20,15 @@ module n64_cfg (
|
|||||||
REG_VERSION_L
|
REG_VERSION_L
|
||||||
} e_reg;
|
} e_reg;
|
||||||
|
|
||||||
|
logic cfg_error;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
reg_bus.rdata = 16'd0;
|
reg_bus.rdata = 16'd0;
|
||||||
|
if (reg_bus.address[16] && (reg_bus.address[15:4] == 12'd0)) begin
|
||||||
case (reg_bus.address[3:1])
|
case (reg_bus.address[3:1])
|
||||||
REG_STATUS: reg_bus.rdata = {
|
REG_STATUS: reg_bus.rdata = {
|
||||||
n64_scb.cfg_pending,
|
n64_scb.cfg_pending,
|
||||||
n64_scb.cfg_error,
|
cfg_error,
|
||||||
14'd0
|
14'd0
|
||||||
};
|
};
|
||||||
REG_DATA_0_H: reg_bus.rdata = n64_scb.cfg_wdata[0][31:16];
|
REG_DATA_0_H: reg_bus.rdata = n64_scb.cfg_wdata[0][31:16];
|
||||||
@ -36,15 +39,18 @@ module n64_cfg (
|
|||||||
REG_VERSION_L: reg_bus.rdata = n64_scb.cfg_version[15:0];
|
REG_VERSION_L: reg_bus.rdata = n64_scb.cfg_version[15:0];
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (reset || n64_scb.n64_reset) begin
|
if (reset || n64_scb.n64_reset) begin
|
||||||
n64_scb.cfg_pending <= 1'b0;
|
n64_scb.cfg_pending <= 1'b0;
|
||||||
n64_scb.cfg_cmd <= 8'h00;
|
n64_scb.cfg_cmd <= 8'h00;
|
||||||
irq <= 1'b0;
|
irq <= 1'b0;
|
||||||
|
cfg_error <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
if (n64_scb.cfg_done) begin
|
if (n64_scb.cfg_done) begin
|
||||||
n64_scb.cfg_pending <= 1'b0;
|
n64_scb.cfg_pending <= 1'b0;
|
||||||
|
cfg_error <= n64_scb.cfg_error;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (n64_scb.cfg_irq) begin
|
if (n64_scb.cfg_irq) begin
|
||||||
@ -52,10 +58,12 @@ module n64_cfg (
|
|||||||
end
|
end
|
||||||
|
|
||||||
if (reg_bus.write) begin
|
if (reg_bus.write) begin
|
||||||
|
if (reg_bus.address[16] && (reg_bus.address[15:4] == 12'd0)) begin
|
||||||
case (reg_bus.address[3:1])
|
case (reg_bus.address[3:1])
|
||||||
REG_COMMAND: begin
|
REG_COMMAND: begin
|
||||||
n64_scb.cfg_pending <= 1'b1;
|
n64_scb.cfg_pending <= 1'b1;
|
||||||
n64_scb.cfg_cmd <= reg_bus.wdata[7:0];
|
n64_scb.cfg_cmd <= reg_bus.wdata[7:0];
|
||||||
|
cfg_error <= 1'b0;
|
||||||
end
|
end
|
||||||
REG_DATA_0_H: n64_scb.cfg_rdata[0][31:16] <= reg_bus.wdata;
|
REG_DATA_0_H: n64_scb.cfg_rdata[0][31:16] <= reg_bus.wdata;
|
||||||
REG_DATA_0_L: n64_scb.cfg_rdata[0][15:0] <= reg_bus.wdata;
|
REG_DATA_0_L: n64_scb.cfg_rdata[0][15:0] <= reg_bus.wdata;
|
||||||
@ -66,5 +74,6 @@ module n64_cfg (
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
52
fw/rtl/n64/n64_lock.sv
Normal file
52
fw/rtl/n64/n64_lock.sv
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
module n64_lock (
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
n64_reg_bus.lock reg_bus,
|
||||||
|
|
||||||
|
n64_scb.lock n64_scb,
|
||||||
|
);
|
||||||
|
|
||||||
|
const bit [15:0] UNLOCK_SEQUENCE [4] = {
|
||||||
|
16'h5F55,
|
||||||
|
16'h4E4C,
|
||||||
|
16'h4F43,
|
||||||
|
16'h4B5F
|
||||||
|
};
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
reg_bus.rdata = 16'd0;
|
||||||
|
end
|
||||||
|
|
||||||
|
logic [1:0] sequence_counter;
|
||||||
|
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
if (reset || n64_scb.n64_reset || n64_scb.n64_nmi) begin
|
||||||
|
n64_scb.cfg_unlock <= 1'b0;
|
||||||
|
sequence_counter <= 2'd0;
|
||||||
|
end else begin
|
||||||
|
if (reg_bus.write) begin
|
||||||
|
if (reg_bus.address[16] && (reg_bus.address[15:2] == 14'd0)) begin
|
||||||
|
for (int i = 0; i < $size(UNLOCK_SEQUENCE); i++) begin
|
||||||
|
if (sequence_counter == i) begin
|
||||||
|
if (reg_bus.wdata == UNLOCK_SEQUENCE[i]) begin
|
||||||
|
sequence_counter <= sequence_counter + 1'd1;
|
||||||
|
if (i == ($size(UNLOCK_SEQUENCE) - 1'd1)) begin
|
||||||
|
n64_scb.cfg_unlock <= 1'b1;
|
||||||
|
sequence_counter <= 2'd0;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
n64_scb.cfg_unlock <= 1'b0;
|
||||||
|
sequence_counter <= 2'd0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
n64_scb.cfg_unlock <= 1'b0;
|
||||||
|
sequence_counter <= 2'd0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
@ -139,6 +139,7 @@ module n64_pi (
|
|||||||
write_port <= PORT_NONE;
|
write_port <= PORT_NONE;
|
||||||
reg_bus.dd_select <= 1'b0;
|
reg_bus.dd_select <= 1'b0;
|
||||||
reg_bus.flashram_select <= 1'b0;
|
reg_bus.flashram_select <= 1'b0;
|
||||||
|
reg_bus.lock_select <= 1'b0;
|
||||||
reg_bus.cfg_select <= 1'b0;
|
reg_bus.cfg_select <= 1'b0;
|
||||||
end else if (aleh_op) begin
|
end else if (aleh_op) begin
|
||||||
read_port <= PORT_NONE;
|
read_port <= PORT_NONE;
|
||||||
@ -146,6 +147,7 @@ module n64_pi (
|
|||||||
mem_offset <= 32'd0;
|
mem_offset <= 32'd0;
|
||||||
reg_bus.dd_select <= 1'b0;
|
reg_bus.dd_select <= 1'b0;
|
||||||
reg_bus.flashram_select <= 1'b0;
|
reg_bus.flashram_select <= 1'b0;
|
||||||
|
reg_bus.lock_select <= 1'b0;
|
||||||
reg_bus.cfg_select <= 1'b0;
|
reg_bus.cfg_select <= 1'b0;
|
||||||
|
|
||||||
if (n64_scb.dd_enabled) begin
|
if (n64_scb.dd_enabled) begin
|
||||||
@ -220,6 +222,13 @@ module n64_pi (
|
|||||||
mem_offset <= (-32'h1400_0000) + FLASH_OFFSET;
|
mem_offset <= (-32'h1400_0000) + FLASH_OFFSET;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (n64_pi_dq_in >= 16'h1FFD && n64_pi_dq_in < 16'h1FFE) begin
|
||||||
|
read_port <= PORT_NONE;
|
||||||
|
write_port <= PORT_REG;
|
||||||
|
reg_bus.lock_select <= 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (n64_scb.cfg_unlock) begin
|
||||||
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;
|
||||||
@ -233,6 +242,7 @@ module n64_pi (
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
// Mem bus read FIFO controller
|
// Mem bus read FIFO controller
|
||||||
|
@ -2,6 +2,7 @@ interface n64_reg_bus ();
|
|||||||
|
|
||||||
logic flashram_select;
|
logic flashram_select;
|
||||||
logic dd_select;
|
logic dd_select;
|
||||||
|
logic lock_select;
|
||||||
logic cfg_select;
|
logic cfg_select;
|
||||||
|
|
||||||
logic read;
|
logic read;
|
||||||
@ -12,12 +13,14 @@ interface n64_reg_bus ();
|
|||||||
|
|
||||||
logic [15:0] flashram_rdata;
|
logic [15:0] flashram_rdata;
|
||||||
logic [15:0] dd_rdata;
|
logic [15:0] dd_rdata;
|
||||||
|
logic [15:0] lock_rdata;
|
||||||
logic [15:0] cfg_rdata;
|
logic [15:0] cfg_rdata;
|
||||||
|
|
||||||
modport controller (
|
modport controller (
|
||||||
output flashram_select,
|
output flashram_select,
|
||||||
output dd_select,
|
output dd_select,
|
||||||
output cfg_select,
|
output cfg_select,
|
||||||
|
output lock_select,
|
||||||
|
|
||||||
output read,
|
output read,
|
||||||
output write,
|
output write,
|
||||||
@ -34,6 +37,9 @@ interface n64_reg_bus ();
|
|||||||
if (dd_select) begin
|
if (dd_select) begin
|
||||||
rdata = dd_rdata;
|
rdata = dd_rdata;
|
||||||
end
|
end
|
||||||
|
if (lock_select) begin
|
||||||
|
rdata = lock_rdata;
|
||||||
|
end
|
||||||
if (cfg_select) begin
|
if (cfg_select) begin
|
||||||
rdata = cfg_rdata;
|
rdata = cfg_rdata;
|
||||||
end
|
end
|
||||||
@ -55,6 +61,14 @@ interface n64_reg_bus ();
|
|||||||
input wdata
|
input wdata
|
||||||
);
|
);
|
||||||
|
|
||||||
|
modport lock (
|
||||||
|
input .read(read && lock_select),
|
||||||
|
input .write(write && lock_select),
|
||||||
|
input address,
|
||||||
|
output .rdata(lock_rdata),
|
||||||
|
input wdata
|
||||||
|
);
|
||||||
|
|
||||||
modport cfg (
|
modport cfg (
|
||||||
input .read(read && cfg_select),
|
input .read(read && cfg_select),
|
||||||
input .write(write && cfg_select),
|
input .write(write && cfg_select),
|
||||||
|
@ -40,6 +40,7 @@ interface n64_scb ();
|
|||||||
logic [41:0] rtc_rdata;
|
logic [41:0] rtc_rdata;
|
||||||
logic [41:0] rtc_wdata;
|
logic [41:0] rtc_wdata;
|
||||||
|
|
||||||
|
logic cfg_unlock;
|
||||||
logic cfg_pending;
|
logic cfg_pending;
|
||||||
logic cfg_done;
|
logic cfg_done;
|
||||||
logic cfg_error;
|
logic cfg_error;
|
||||||
@ -99,7 +100,9 @@ interface n64_scb ();
|
|||||||
input dd_enabled,
|
input dd_enabled,
|
||||||
input ddipl_enabled,
|
input ddipl_enabled,
|
||||||
|
|
||||||
input flashram_read_mode
|
input flashram_read_mode,
|
||||||
|
|
||||||
|
input cfg_unlock
|
||||||
);
|
);
|
||||||
|
|
||||||
modport flashram (
|
modport flashram (
|
||||||
@ -158,6 +161,13 @@ interface n64_scb ();
|
|||||||
input dd_wdata
|
input dd_wdata
|
||||||
);
|
);
|
||||||
|
|
||||||
|
modport lock (
|
||||||
|
input n64_reset,
|
||||||
|
input n64_nmi,
|
||||||
|
|
||||||
|
output cfg_unlock
|
||||||
|
);
|
||||||
|
|
||||||
modport cfg (
|
modport cfg (
|
||||||
input n64_reset,
|
input n64_reset,
|
||||||
|
|
||||||
|
@ -67,6 +67,15 @@ module n64_top (
|
|||||||
.n64_scb(n64_scb)
|
.n64_scb(n64_scb)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
n64_lock n64_lock_inst (
|
||||||
|
.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
|
||||||
|
.reg_bus(reg_bus),
|
||||||
|
|
||||||
|
.n64_scb(n64_scb)
|
||||||
|
);
|
||||||
|
|
||||||
n64_cfg n64_cfg_inst (
|
n64_cfg n64_cfg_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
|
@ -11,6 +11,8 @@ void init (void) {
|
|||||||
|
|
||||||
exception_install();
|
exception_install();
|
||||||
|
|
||||||
|
sc64_unlock();
|
||||||
|
|
||||||
if (!sc64_check_presence()) {
|
if (!sc64_check_presence()) {
|
||||||
error_display("SC64 hardware not detected");
|
error_display("SC64 hardware not detected");
|
||||||
}
|
}
|
||||||
@ -29,4 +31,5 @@ void init (void) {
|
|||||||
void deinit (void) {
|
void deinit (void) {
|
||||||
exception_disable_interrupts();
|
exception_disable_interrupts();
|
||||||
exception_disable_watchdog();
|
exception_disable_watchdog();
|
||||||
|
sc64_lock();
|
||||||
}
|
}
|
||||||
|
@ -225,6 +225,14 @@ typedef struct {
|
|||||||
#define PIFRAM ((io8_t *) PIFRAM_BASE)
|
#define PIFRAM ((io8_t *) PIFRAM_BASE)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
io32_t KEY;
|
||||||
|
} sc64_lock_t;
|
||||||
|
|
||||||
|
#define SC64_LOCK_BASE (0x1FFD0000UL)
|
||||||
|
#define SC64_LOCK ((sc64_lock_t *) SC64_LOCK_BASE)
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
io8_t BUFFER[8192];
|
io8_t BUFFER[8192];
|
||||||
io8_t EEPROM[2048];
|
io8_t EEPROM[2048];
|
||||||
|
@ -40,6 +40,16 @@ static bool sc64_execute_cmd (uint8_t cmd, uint32_t *args, uint32_t *result) {
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sc64_unlock (void) {
|
||||||
|
pi_io_write(&SC64_LOCK->KEY, 0x00000000);
|
||||||
|
pi_io_write(&SC64_LOCK->KEY, 0x5F554E4C);
|
||||||
|
pi_io_write(&SC64_LOCK->KEY, 0x4F434B5F);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sc64_lock (void) {
|
||||||
|
pi_io_write(&SC64_LOCK->KEY, 0x00000000);
|
||||||
|
}
|
||||||
|
|
||||||
bool sc64_check_presence (void) {
|
bool sc64_check_presence (void) {
|
||||||
uint32_t version = pi_io_read(&SC64_REGS->VERSION);
|
uint32_t version = pi_io_read(&SC64_REGS->VERSION);
|
||||||
return (version == SC64_VERSION_2);
|
return (version == SC64_VERSION_2);
|
||||||
|
@ -91,6 +91,8 @@ typedef struct {
|
|||||||
} rtc_time_t;
|
} rtc_time_t;
|
||||||
|
|
||||||
|
|
||||||
|
void sc64_unlock (void);
|
||||||
|
void sc64_lock (void);
|
||||||
bool sc64_check_presence (void);
|
bool sc64_check_presence (void);
|
||||||
cmd_error_t sc64_get_error (void);
|
cmd_error_t sc64_get_error (void);
|
||||||
void sc64_set_config (cfg_id_t id, uint32_t value);
|
void sc64_set_config (cfg_id_t id, uint32_t value);
|
||||||
|
@ -54,7 +54,7 @@ void button_process (void) {
|
|||||||
if (p.trigger) {
|
if (p.trigger) {
|
||||||
switch (p.mode) {
|
switch (p.mode) {
|
||||||
case BUTTON_MODE_N64_IRQ:
|
case BUTTON_MODE_N64_IRQ:
|
||||||
fpga_reg_set(REG_CFG_CMD, fpga_reg_get(REG_CFG_CMD) | CFG_CMD_IRQ);
|
fpga_reg_set(REG_CFG_CMD, CFG_CMD_IRQ);
|
||||||
p.trigger = false;
|
p.trigger = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ from dd64 import BadBlockError, DD64Image
|
|||||||
from enum import Enum, IntEnum
|
from enum import Enum, IntEnum
|
||||||
from serial.tools import list_ports
|
from serial.tools import list_ports
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from typing import Optional
|
from typing import Callable, Optional
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -394,8 +394,6 @@ class SC64:
|
|||||||
|
|
||||||
def upload_save(self, data: bytes) -> None:
|
def upload_save(self, data: bytes) -> None:
|
||||||
save_type = self.SaveType(self.__get_config(self.__CfgId.SAVE_TYPE))
|
save_type = self.SaveType(self.__get_config(self.__CfgId.SAVE_TYPE))
|
||||||
if (save_type not in self.SaveType):
|
|
||||||
raise ConnectionError('Unknown save type fetched from SC64 device')
|
|
||||||
if (save_type == self.SaveType.NONE):
|
if (save_type == self.SaveType.NONE):
|
||||||
raise ValueError('No save type set inside SC64 device')
|
raise ValueError('No save type set inside SC64 device')
|
||||||
if (len(data) != self.__SaveLength[save_type.name]):
|
if (len(data) != self.__SaveLength[save_type.name]):
|
||||||
@ -407,8 +405,6 @@ class SC64:
|
|||||||
|
|
||||||
def download_save(self) -> bytes:
|
def download_save(self) -> bytes:
|
||||||
save_type = self.SaveType(self.__get_config(self.__CfgId.SAVE_TYPE))
|
save_type = self.SaveType(self.__get_config(self.__CfgId.SAVE_TYPE))
|
||||||
if (save_type not in self.SaveType):
|
|
||||||
raise ConnectionError('Unknown save type fetched from SC64 device')
|
|
||||||
if (save_type == self.SaveType.NONE):
|
if (save_type == self.SaveType.NONE):
|
||||||
raise ValueError('No save type set inside SC64 device')
|
raise ValueError('No save type set inside SC64 device')
|
||||||
address = self.__Address.SAVE
|
address = self.__Address.SAVE
|
||||||
@ -432,8 +428,6 @@ class SC64:
|
|||||||
self.__link.execute_cmd(cmd=b'T', args=[self.__get_int(data[0:4]), self.__get_int(data[4:8])])
|
self.__link.execute_cmd(cmd=b'T', args=[self.__get_int(data[0:4]), self.__get_int(data[4:8])])
|
||||||
|
|
||||||
def set_boot_mode(self, mode: BootMode) -> None:
|
def set_boot_mode(self, mode: BootMode) -> None:
|
||||||
if (mode not in self.BootMode):
|
|
||||||
raise ValueError('Boot mode outside of allowed values')
|
|
||||||
self.__set_config(self.__CfgId.BOOT_MODE, mode)
|
self.__set_config(self.__CfgId.BOOT_MODE, mode)
|
||||||
|
|
||||||
def set_cic_seed(self, seed: int) -> None:
|
def set_cic_seed(self, seed: int) -> None:
|
||||||
@ -443,13 +437,9 @@ class SC64:
|
|||||||
self.__set_config(self.__CfgId.CIC_SEED, seed)
|
self.__set_config(self.__CfgId.CIC_SEED, seed)
|
||||||
|
|
||||||
def set_tv_type(self, type: TVType) -> None:
|
def set_tv_type(self, type: TVType) -> None:
|
||||||
if (type not in self.TVType):
|
|
||||||
raise ValueError('TV type outside of allowed values')
|
|
||||||
self.__set_config(self.__CfgId.TV_TYPE, type)
|
self.__set_config(self.__CfgId.TV_TYPE, type)
|
||||||
|
|
||||||
def set_save_type(self, type: SaveType) -> None:
|
def set_save_type(self, type: SaveType) -> None:
|
||||||
if (type not in self.SaveType):
|
|
||||||
raise ValueError('Save type outside of allowed values')
|
|
||||||
self.__set_config(self.__CfgId.SAVE_TYPE, type)
|
self.__set_config(self.__CfgId.SAVE_TYPE, type)
|
||||||
|
|
||||||
def set_cic_parameters(self, dd_mode: bool=False, seed: int=0x3F, checksum: bytes=bytes([0xA5, 0x36, 0xC0, 0xF1, 0xD8, 0x59])) -> None:
|
def set_cic_parameters(self, dd_mode: bool=False, seed: int=0x3F, checksum: bytes=bytes([0xA5, 0x36, 0xC0, 0xF1, 0xD8, 0x59])) -> None:
|
||||||
@ -461,7 +451,7 @@ class SC64:
|
|||||||
data = [*data, *checksum]
|
data = [*data, *checksum]
|
||||||
self.__link.execute_cmd(cmd=b'B', args=[self.__get_int(data[0:4]), self.__get_int(data[4:8])])
|
self.__link.execute_cmd(cmd=b'B', args=[self.__get_int(data[0:4]), self.__get_int(data[4:8])])
|
||||||
|
|
||||||
def update_firmware(self, data: bytes) -> None:
|
def update_firmware(self, data: bytes, status_callback: Optional[Callable[[str], None]]=None) -> None:
|
||||||
address = self.__Address.FIRMWARE
|
address = self.__Address.FIRMWARE
|
||||||
self.__write_memory(address, data)
|
self.__write_memory(address, data)
|
||||||
response = self.__link.execute_cmd(cmd=b'F', args=[address, len(data)])
|
response = self.__link.execute_cmd(cmd=b'F', args=[address, len(data)])
|
||||||
@ -477,7 +467,8 @@ class SC64:
|
|||||||
if (cmd != b'F'):
|
if (cmd != b'F'):
|
||||||
raise ConnectionException('Wrong update status packet')
|
raise ConnectionException('Wrong update status packet')
|
||||||
status = self.__UpdateStatus(self.__get_int(data))
|
status = self.__UpdateStatus(self.__get_int(data))
|
||||||
print(f'Update status [{status.name}]')
|
if (status_callback):
|
||||||
|
status_callback(status.name)
|
||||||
if (status == self.__UpdateStatus.ERROR):
|
if (status == self.__UpdateStatus.ERROR):
|
||||||
raise ConnectionException('Update error, device is most likely bricked')
|
raise ConnectionException('Update error, device is most likely bricked')
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
@ -616,8 +607,8 @@ class EnumAction(argparse.Action):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description='SC64 control software')
|
parser = argparse.ArgumentParser(description='SC64 control software')
|
||||||
parser.add_argument('--backup', help='backup SC64 firmware and write it to specified file')
|
parser.add_argument('--backup-firmware', help='backup SC64 firmware and write it to specified file')
|
||||||
parser.add_argument('--update', help='update SC64 firmware from specified file')
|
parser.add_argument('--update-firmware', help='update SC64 firmware from specified file')
|
||||||
parser.add_argument('--reset-state', action='store_true', help='reset SC64 internal state')
|
parser.add_argument('--reset-state', action='store_true', help='reset SC64 internal state')
|
||||||
parser.add_argument('--print-state', action='store_true', help='print SC64 internal state')
|
parser.add_argument('--print-state', action='store_true', help='print SC64 internal state')
|
||||||
parser.add_argument('--boot', type=SC64.BootMode, action=EnumAction, help='set boot mode')
|
parser.add_argument('--boot', type=SC64.BootMode, action=EnumAction, help='set boot mode')
|
||||||
@ -632,7 +623,7 @@ if __name__ == '__main__':
|
|||||||
parser.add_argument('--ddipl', help='upload 64DD IPL from specified file')
|
parser.add_argument('--ddipl', help='upload 64DD IPL from specified file')
|
||||||
parser.add_argument('--disk', action='append', help='path to 64DD disk (.ndd format), can be specified multiple times')
|
parser.add_argument('--disk', action='append', help='path to 64DD disk (.ndd format), can be specified multiple times')
|
||||||
parser.add_argument('--isv', action='store_true', help='enable IS-Viewer64 support')
|
parser.add_argument('--isv', action='store_true', help='enable IS-Viewer64 support')
|
||||||
parser.add_argument('--debug', action='store_true', help='run debug loop (required for IS-Viewer64 and 64DD)')
|
parser.add_argument('--debug', action='store_true', help='run debug loop (required for 64DD and IS-Viewer64)')
|
||||||
|
|
||||||
if (len(sys.argv) <= 1):
|
if (len(sys.argv) <= 1):
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
@ -643,16 +634,17 @@ if __name__ == '__main__':
|
|||||||
try:
|
try:
|
||||||
sc64 = SC64()
|
sc64 = SC64()
|
||||||
|
|
||||||
if (args.backup):
|
if (args.backup_firmware):
|
||||||
with open(args.backup, 'wb+') as f:
|
with open(args.backup_firmware, 'wb+') as f:
|
||||||
print('Generating backup, this might take a while... ', end='', flush=True)
|
print('Generating backup, this might take a while... ', end='', flush=True)
|
||||||
f.write(sc64.backup_firmware())
|
f.write(sc64.backup_firmware())
|
||||||
print('done')
|
print('done')
|
||||||
|
|
||||||
if (args.update):
|
if (args.update_firmware):
|
||||||
with open(args.update, 'rb+') as f:
|
with open(args.update_firmware, 'rb+') as f:
|
||||||
print('Updating firmware, this might take a while... ', end='', flush=True)
|
print('Updating firmware, this might take a while... ', end='', flush=True)
|
||||||
sc64.update_firmware(f.read())
|
status_callback = lambda status: print(f'{status} ', end='', flush=True)
|
||||||
|
sc64.update_firmware(f.read(), status_callback)
|
||||||
print('done')
|
print('done')
|
||||||
|
|
||||||
if (args.reset_state):
|
if (args.reset_state):
|
||||||
|
Loading…
Reference in New Issue
Block a user