RL78/G10 proto (untested)
This commit is contained in:
parent
26c5bb0d36
commit
d523de69b7
|
@ -104,6 +104,16 @@ static const struct delayvalues delays[23] = {
|
|||
#define tCS9 tWT12
|
||||
#define tG23 (1000*1000) /* RL78/G23 datasheet just says "everything 1ms lol" */
|
||||
|
||||
// G10 proto
|
||||
#define tDTR 1
|
||||
#define tDRT 1
|
||||
#define tCRC 1000
|
||||
#define tPRO 1000
|
||||
#define tVER 20000
|
||||
#define tERA (350*1000)
|
||||
#define tDT 1
|
||||
/*#define tDR 1*/
|
||||
|
||||
|
||||
static enum tool78_stat tool78_data_send(struct tool78_hw* hw,
|
||||
int len, const uint8_t* data, bool final_block) {
|
||||
|
@ -902,6 +912,141 @@ enum tool78_stat tool78_do_fsw_get(struct tool78_hw* hw,
|
|||
|
||||
// ----
|
||||
|
||||
enum tool78_stat tool78_do_g10_get_flash_size(struct tool78_hw* hw,
|
||||
enum tool78_g10_flash_size* fsz) {
|
||||
busy_wait_us_32(tDTR);
|
||||
|
||||
// start crc calc cmd
|
||||
uint8_t data[2];
|
||||
data[0] = tool78_cmd_crc_check;
|
||||
int rr = hw->send(1, data, -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
|
||||
enum tool78_stat st = tool78_data_recv(hw, data, 2, tDT+tDRT);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
if (data[0] != tool78_stat_ack) return data[0];
|
||||
|
||||
*fsz = data[1];
|
||||
|
||||
busy_wait_us_32(tDTR);
|
||||
data[0] = tool78_stat_nak; // should send ack here, but send nak to stop crc calc
|
||||
rr = hw->send(1, data, -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
|
||||
/*st =*/ tool78_data_recv(hw, data, 1, tCRC);
|
||||
// ignore status of this stuff
|
||||
//if (st != tool78_stat_ack) return st;
|
||||
|
||||
return tool78_stat_ack;
|
||||
}
|
||||
enum tool78_stat tool78_do_g10_check_crc(struct tool78_hw* hw,
|
||||
enum tool78_g10_flash_size fsz, uint16_t* crc) {
|
||||
busy_wait_us_32(tDTR);
|
||||
|
||||
uint8_t data[2];
|
||||
data[0] = tool78_cmd_crc_check;
|
||||
int rr = hw->send(1, data, -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
|
||||
enum tool78_stat st = tool78_data_recv(hw, data, 2, tDT+tDRT);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
if (data[0] != tool78_stat_ack) return data[0];
|
||||
|
||||
busy_wait_us_32(tDTR);
|
||||
if (data[1] != fsz) {
|
||||
data[0] = tool78_stat_nak; // should send ack here, but send nak to stop crc calc
|
||||
rr = hw->send(1, data, -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
|
||||
/*st =*/ tool78_data_recv(hw, data, 1, tCRC);
|
||||
// ignore status of this stuff
|
||||
//if (st != tool78_stat_ack) return st;
|
||||
|
||||
return tool78_stat_bad_flash_size;
|
||||
} else {
|
||||
data[0] = tool78_stat_ack;
|
||||
rr = hw->send(1, data, -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
|
||||
st = tool78_data_recv(hw, data, 1, tCRC);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
st = data[0];
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
st = tool78_data_recv(hw, data, 2, tDT*2);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
*crc = data[0] | ((uint16_t)data[1] << 8);
|
||||
|
||||
return tool78_stat_ack;
|
||||
}
|
||||
}
|
||||
enum tool78_stat tool78_do_g10_erase_then_write(struct tool78_hw* hw,
|
||||
enum tool78_g10_flash_size fsz, const uint8_t* data_to_wr) {
|
||||
busy_wait_us_32(tDTR);
|
||||
|
||||
uint8_t data[4];
|
||||
data[0] = tool78_cmd_write_after_erase;
|
||||
int rr = hw->send(1, data, -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
|
||||
enum tool78_stat st = tool78_data_recv(hw, data, 2, tDT+tDRT);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
if (data[0] != tool78_stat_ack) return data[0];
|
||||
|
||||
busy_wait_us_32(tDTR);
|
||||
if (data[1] != fsz) {
|
||||
data[0] = tool78_stat_nak; // should send ack here, but send nak to stop crc calc
|
||||
rr = hw->send(1, data, -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
|
||||
/*st =*/ tool78_data_recv(hw, data, 1, tERA);
|
||||
// ignore status of this stuff
|
||||
//if (st != tool78_stat_ack) return st;
|
||||
|
||||
return tool78_stat_bad_flash_size;
|
||||
} else {
|
||||
data[0] = tool78_stat_ack;
|
||||
rr = hw->send(1, data, -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
|
||||
st = tool78_data_recv(hw, data, 1, tERA);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
st = data[0];
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
size_t flash_sz = (fsz + 1) * 256;
|
||||
for (size_t i = 0; i < flash_sz; i += 4) {
|
||||
busy_wait_us_32(tDTR);
|
||||
rr = hw->send(1, &data_to_wr[i+0], -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
busy_wait_us_32(tDRT);
|
||||
rr = hw->send(1, &data_to_wr[i+1], -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
busy_wait_us_32(tDRT);
|
||||
rr = hw->send(1, &data_to_wr[i+2], -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
busy_wait_us_32(tDRT);
|
||||
rr = hw->send(1, &data_to_wr[i+3], -1);
|
||||
if (rr != 1) return tool78_stat_internal_error;
|
||||
|
||||
st = tool78_data_recv(hw, data, 1, tPRO);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
st = data[0];
|
||||
if (st != tool78_stat_ack) return st;
|
||||
}
|
||||
|
||||
st = tool78_data_recv(hw, data, 1, tVER);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
return tool78_stat_ack;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
|
||||
int tool78_ocd_version(struct tool78_hw* hw, uint16_t* ver) {
|
||||
busy_wait_ms(1);
|
||||
|
||||
|
@ -1052,7 +1197,8 @@ static enum tool78_stat tool78_init_common(struct tool78_hw* hw) {
|
|||
if (!hw->init()) return tool78_stat_fatal_hw_error;
|
||||
//printf("init %zu ok\n", i);
|
||||
|
||||
if ((hw->target & tool78_mcu_mask) != tool78_mcu_rl78) {
|
||||
if ((hw->target & tool78_mcu_mask) != tool78_mcu_rl78
|
||||
&& (hw->target & tool78_mcu_mask) != tool78_mcu_rl78g10) {
|
||||
st = tool78_do_reset(hw);
|
||||
//printf("done reset st=0x%02x\n", st);
|
||||
}
|
||||
|
@ -1065,9 +1211,16 @@ static enum tool78_stat tool78_init_common(struct tool78_hw* hw) {
|
|||
if (st != tool78_stat_ack) return st;
|
||||
//printf("hw inited\n");
|
||||
|
||||
st = tool78_do_generic_baudrate(hw);
|
||||
//printf("baudrate result=0x%02x\n", st);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
if ((hw->target & tool78_mcu_mask) != tool78_mcu_rl78g10) {
|
||||
st = tool78_do_generic_baudrate(hw);
|
||||
//printf("baudrate result=0x%02x\n", st);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
} else {
|
||||
enum tool78_stat st2;
|
||||
st = tool78_data_recv(hw, &st2, 1, 1000);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
st = st2;
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
@ -1078,9 +1231,11 @@ enum tool78_stat tool78_init_sfp(struct tool78_hw* hw, tool78_silicon_sig_t* sig
|
|||
enum tool78_stat st = tool78_init_common(hw);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
||||
st = tool78_do_silicon_signature(hw, sig);
|
||||
//printf("sig result=0x%02x\n", st);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
if ((hw->target & tool78_mcu_mask) != tool78_mcu_rl78g10) {
|
||||
st = tool78_do_silicon_signature(hw, sig);
|
||||
//printf("sig result=0x%02x\n", st);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,16 @@ enum tool78_stat tool78_do_security_get(struct tool78_hw* hw, // RL78 only
|
|||
struct tool78_security* sec);
|
||||
enum tool78_stat tool78_do_security_release(struct tool78_hw* hw);
|
||||
|
||||
// RL78/G10,G1M,G1N commands
|
||||
|
||||
// this one is very hacky
|
||||
enum tool78_stat tool78_do_g10_get_flash_size(struct tool78_hw*,
|
||||
enum tool78_g10_flash_size* fsz);
|
||||
enum tool78_stat tool78_do_g10_check_crc(struct tool78_hw*,
|
||||
enum tool78_g10_flash_size fsz, uint16_t* crc);
|
||||
enum tool78_stat tool78_do_g10_erase_then_write(struct tool78_hw*,
|
||||
enum tool78_g10_flash_size fsz, const uint8_t* data);
|
||||
|
||||
// new commands from the RL78/G23 (Proto C)
|
||||
|
||||
// 0xA0
|
||||
|
@ -61,7 +71,6 @@ enum tool78_stat tool78_do_fsw_set(struct tool78_hw* hw,
|
|||
// 0xAD
|
||||
enum tool78_stat tool78_do_fsw_get(struct tool78_hw* hw,
|
||||
struct tool78_fsw_settings* fswopt);
|
||||
// TODO: also new secget/secset!
|
||||
|
||||
// ----
|
||||
|
||||
|
|
|
@ -31,11 +31,13 @@ enum tool78_target {
|
|||
tool78rl_uart1 = 0x31,
|
||||
tool78rl_uart2 = 0x32,
|
||||
tool78rl_ocd = 0x38, // FIXME: do this in a better way
|
||||
tool78rlg10_uart1 = 0x41,
|
||||
|
||||
tool78_mcu_mask = 0xf0,
|
||||
tool78_mcu_78k0 = 0x10,
|
||||
tool78_mcu_78k0r = 0x20,
|
||||
tool78_mcu_rl78 = 0x30,
|
||||
tool78_mcu_rl78g10 = 0x40,
|
||||
|
||||
tool78_phy_mask = 0x0f,
|
||||
tool78_phy_uart1 = 0x01,
|
||||
|
@ -76,6 +78,10 @@ enum tool78_cmd {
|
|||
tool78_cmd_block_erase = 0x22,
|
||||
tool78_cmd_block_blank_check = 0x32,
|
||||
tool78_cmd_programming = 0x40,
|
||||
// RL78/G10 only
|
||||
tool78_cmd_crc_check = 0x53,
|
||||
// RL78/G10 only
|
||||
tool78_cmd_write_after_erase = 0x60,
|
||||
// 78k0/Kx2 SPI only
|
||||
tool78_cmd_status = 0x70,
|
||||
// 78k0/Kx2 only
|
||||
|
@ -131,11 +137,13 @@ enum tool78_stat {
|
|||
tool78_stat_timeout_error = 0xc3,
|
||||
tool78_stat_fatal_hw_error = 0xc4,
|
||||
tool78_stat_parity_error = 0xc5,
|
||||
tool78_stat_bad_flash_size = 0xc6,
|
||||
|
||||
// TODO: OCD status stuff (for 0x91)
|
||||
};
|
||||
|
||||
// TODO: only known for RL78 from fail0overflow. verify!
|
||||
// these commands use a checksum that is the bitwise complement from the usual
|
||||
// checksum (used in the flash programming protocol)
|
||||
// these commands use a checksum that is the bitwise complement from the usual
|
||||
// checksum (used in the flash programming protocol)
|
||||
enum tool78ocd_cmd {
|
||||
//tool78ocd_cmd_reset = 0x00,
|
||||
tool78ocd_cmd_version = 0x90, // also called "ping"
|
||||
|
@ -281,5 +289,14 @@ struct tool78_fsw_settings {
|
|||
bool fsw_area_invert;
|
||||
};
|
||||
|
||||
enum tool78_g10_flash_size {
|
||||
tool78_g10_flash_16k = 0x3f,
|
||||
tool78_g10_flash_8k = 0x1f,
|
||||
tool78_g10_flash_4k = 0x0f,
|
||||
tool78_g10_flash_2k = 0x07,
|
||||
tool78_g10_flash_1k = 0x03,
|
||||
tool78_g10_flash_512 = 0x01,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -46,7 +46,9 @@ extern struct tool78_hw
|
|||
tool78_hw_78k0r_uart1,
|
||||
|
||||
tool78_hw_rl78_uart1,
|
||||
tool78_hw_rl78_uart2;
|
||||
tool78_hw_rl78_uart2,
|
||||
|
||||
tool78_hw_rl78g10_uart1;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -43,6 +43,34 @@ static bool trl78_uart1_init(void) {
|
|||
|
||||
return true; // all is well!
|
||||
}
|
||||
static bool trl78g10_uart1_init(void) {
|
||||
if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
|
||||
&vars)) return false;
|
||||
|
||||
vars.exclusive = true;
|
||||
vars.bitswap = true;
|
||||
|
||||
enum tool78_entry typ = tool78_entry_rl78_uart1;
|
||||
|
||||
tool78_entryseq_rl78(typ);
|
||||
|
||||
tool78_uart_rx_program_init(PINOUT_TOOL78_PIO, vars.smrx, vars.rxoff,
|
||||
PINOUT_TOOL78_RL78_TOOL0, 115200, true);
|
||||
tool78_uart_tx_program_init(PINOUT_TOOL78_PIO, vars.smtx, vars.txoff,
|
||||
PINOUT_TOOL78_RL78_TOOL0, 115200, true);
|
||||
|
||||
uint8_t byte = (uint8_t)typ;
|
||||
trl78_uart1_send(1, &byte, -1);
|
||||
|
||||
//busy_wait_us_32(70); // tMB
|
||||
busy_wait_ms(4);
|
||||
|
||||
// now a baudrate set command needs to be sent, but we leave that to the
|
||||
// upper (command processing) layer as it has to know about those timings
|
||||
// anyway
|
||||
|
||||
return true; // all is well!
|
||||
}
|
||||
static void trl78_uart1_deinit(void) {
|
||||
tool78_hw_deinit_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
|
||||
&vars);
|
||||
|
@ -63,6 +91,12 @@ static int trl78_uart1_send(int len, const uint8_t* data, int32_t timeout_us) {
|
|||
/*inter-byte delay (us) tDR = 90/8M s */,
|
||||
len, data, timeout_us);
|
||||
}
|
||||
static int trl78g10_uart1_send(int len, const uint8_t* data, int32_t timeout_us) {
|
||||
return tool78_hw_help_send(&vars,
|
||||
(tool78_hw_rl78g10_uart1.flags & tool78_hw_flag_done_reset) ? 0 : 190
|
||||
/*inter-byte delay (us) tDR = 90/8M s */,
|
||||
len, data, timeout_us);
|
||||
}
|
||||
|
||||
static void trl78_uart1_set_baudrate(uint32_t baudrate) {
|
||||
float div = (float)clock_get_hz(clk_sys) / (8*baudrate);
|
||||
|
@ -93,4 +127,18 @@ struct tool78_hw tool78_hw_rl78_uart1 = {
|
|||
|
||||
//.rx_set_stop_bit = trl78_uart1_rx_set_stop_bit
|
||||
};
|
||||
struct tool78_hw tool78_hw_rl78g10_uart1 = {
|
||||
.target = tool78rlg10_uart1,
|
||||
|
||||
.init = trl78_uart1_init,
|
||||
.deinit = trl78_uart1_deinit,
|
||||
|
||||
.set_baudrate = trl78_uart1_set_baudrate,
|
||||
.has_available = trl78_uart1_has_available,
|
||||
|
||||
.recv = trl78_uart1_recv,
|
||||
.send = trl78g10_uart1_send,
|
||||
|
||||
//.rx_set_stop_bit = trl78_uart1_rx_set_stop_bit
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue