tool78: add RL78/G23 stuff (untested)

This commit is contained in:
Triss 2022-04-07 05:30:14 +02:00
parent e0fedc3e60
commit 26c5bb0d36
3 changed files with 196 additions and 2 deletions

View File

@ -102,6 +102,7 @@ static const struct delayvalues delays[23] = {
#define tCS8 tWT9
#define tSD8 tWT1
#define tCS9 tWT12
#define tG23 (1000*1000) /* RL78/G23 datasheet just says "everything 1ms lol" */
static enum tool78_stat tool78_data_send(struct tool78_hw* hw,
@ -761,6 +762,144 @@ enum tool78_stat tool78_do_security_release(struct tool78_hw* hw) {
return st;
}
// new RL78/G23 stuff
enum tool78_stat tool78_do_g23_security_set(struct tool78_hw* hw,
const struct tool78_security* sec) {
bool isrl78 = (hw->target & tool78_mcu_mask) == tool78_mcu_rl78;
if (!isrl78)
return tool78_stat_bad_mcu_for_cmd;
uint8_t data[2];
data[0] = sec->flg | 0xe9;
data[1] = sec->flg2 | 0xfa;
enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_security_set, 2, data);
if (st != tool78_stat_ack) return st;
st = tool78_wait_status(hw, 1, tWT13 + tWT14);
if (st != tool78_stat_ack) return st;
return st;
}
enum tool78_stat tool78_do_g23_security_get(struct tool78_hw* hw,
struct tool78_security* sec) {
bool isrl78 = (hw->target & tool78_mcu_mask) == tool78_mcu_rl78;
if (!isrl78)
return tool78_stat_bad_mcu_for_cmd;
uint8_t data[2];
enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_security_get, 0, NULL);
if (st != tool78_stat_ack) return st;
st = tool78_wait_status(hw, 1, tCS8);
if (st != tool78_stat_ack) return st;
st = tool78_data_recv(hw, data, 2, tSD8);
if (st != tool78_stat_ack) return st;
sec->flg = data[0];
sec->flg2 = data[1];
return st;
}
enum tool78_stat tool78_do_security_idauth(struct tool78_hw* hw,
const uint8_t passwd[static 10]) {
if ((hw->target & tool78_mcu_mask) != tool78_mcu_rl78)
return tool78_stat_bad_mcu_for_cmd;
enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_security_idauth, 10, passwd);
if (st != tool78_stat_ack) return st;
st = tool78_wait_status(hw, 1, tG23);
if (st != tool78_stat_ack) return st;
return st;
}
enum tool78_stat tool78_do_exopt_set(struct tool78_hw* hw,
const uint8_t exopt[static 14]) {
if ((hw->target & tool78_mcu_mask) != tool78_mcu_rl78)
return tool78_stat_bad_mcu_for_cmd;
enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_exopts_set, 14, exopt);
if (st != tool78_stat_ack) return st;
st = tool78_wait_status(hw, 1, tG23);
if (st != tool78_stat_ack) return st;
return st;
}
enum tool78_stat tool78_do_flash_rdp_set(struct tool78_hw* hw,
uint16_t block_start, uint16_t block_end, bool rdp_rw_allow) {
if ((hw->target & tool78_mcu_mask) != tool78_mcu_rl78)
return tool78_stat_bad_mcu_for_cmd;
uint8_t data[4];
data[0] = block_start & 0xff;
data[1] = (block_start >> 8) | 0xfe;
data[2] = block_end & 0xff;
data[3] = ((block_end >> 8) & 1) | 0x7e | (rdp_rw_allow ? 0x80 : 0);
enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_flash_rdp_set, 4, data);
if (st != tool78_stat_ack) return st;
st = tool78_wait_status(hw, 1, tG23);
if (st != tool78_stat_ack) return st;
return st;
}
enum tool78_stat tool78_do_fsw_set(struct tool78_hw* hw,
const struct tool78_fsw_settings* fswopt) {
if ((hw->target & tool78_mcu_mask) != tool78_mcu_rl78)
return tool78_stat_bad_mcu_for_cmd;
uint8_t data[4];
data[0] = fswopt->block_start & 0xff;
data[1] = ((fswopt->block_start >> 8) & 1) | 0x7e
| (fswopt->fswopt_rw_allow ? 0x80 : 0);
data[2] = fswopt->block_end & 0xff;
data[3] = ((fswopt->block_end >> 8) & 1) | 0x7e
| (fswopt->fsw_area_invert ? 0x80 : 0);
enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_fsw_set, 4, data);
if (st != tool78_stat_ack) return st;
st = tool78_wait_status(hw, 1, tG23);
if (st != tool78_stat_ack) return st;
return st;
}
enum tool78_stat tool78_do_fsw_get(struct tool78_hw* hw,
struct tool78_fsw_settings* fswopt) {
bool isrl78 = (hw->target & tool78_mcu_mask) == tool78_mcu_rl78;
if (!isrl78)
return tool78_stat_bad_mcu_for_cmd;
uint8_t data[4];
enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_fsw_get, 0, NULL);
if (st != tool78_stat_ack) return st;
st = tool78_wait_status(hw, 1, tG23);
if (st != tool78_stat_ack) return st;
st = tool78_data_recv(hw, data, 4, tG23);
if (st != tool78_stat_ack) return st;
fswopt->block_start = data[0] | ((data[1] & 1) << 8);
fswopt->block_end = data[2] | ((data[3] & 1) << 8);
fswopt->fswopt_rw_allow = data[1] & 0x80;
fswopt->fsw_area_invert = data[3] & 0x80;
return st;
}
// ----
int tool78_ocd_version(struct tool78_hw* hw, uint16_t* ver) {

View File

@ -34,10 +34,35 @@ enum tool78_stat tool78_do_silicon_signature(struct tool78_hw* hw,
enum tool78_stat tool78_do_version_get(struct tool78_hw* hw, tool78_version_t* vout);
enum tool78_stat tool78_do_security_set(struct tool78_hw* hw,
const struct tool78_security* sec);
enum tool78_stat tool78_do_security_get(struct tool78_hw* hw,
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);
// new commands from the RL78/G23 (Proto C)
// 0xA0
enum tool78_stat tool78_do_g23_security_set(struct tool78_hw* hw,
const struct tool78_security* sec);
// 0xA1
enum tool78_stat tool78_do_g23_security_get(struct tool78_hw* hw, // RL78 only
struct tool78_security* sec);
// 0x9C: payload = passwd; ack/nak
enum tool78_stat tool78_do_security_idauth(struct tool78_hw* hw,
const uint8_t passwd[static 10]);
// 0xA5: payload = exopt; ack/nak
enum tool78_stat tool78_do_exopt_set(struct tool78_hw* hw,
const uint8_t exopt[static 14]);
// 0xAB: payload = block_start || block_end (little-endian); ack/nak
enum tool78_stat tool78_do_flash_rdp_set(struct tool78_hw* hw,
uint16_t block_start, uint16_t block_end, bool rdp_rw_allow);
// 0xAC
enum tool78_stat tool78_do_fsw_set(struct tool78_hw* hw,
const struct tool78_fsw_settings* fswopt);
// 0xAD
enum tool78_stat tool78_do_fsw_get(struct tool78_hw* hw,
struct tool78_fsw_settings* fswopt);
// TODO: also new secget/secset!
// ----
//int tool78_ocd_reset(struct tool78_hw* hw);

View File

@ -82,12 +82,22 @@ enum tool78_cmd {
tool78_cmd_osc_freq_set = 0x90,
// not on 78k0/Kx2. arguments are different for 78K0R/Kx3-L and RL78!
tool78_cmd_baud_rate_set = 0x9a,
// 78K0R/Kx3-L and RL78: also sets flash shield window
tool78_cmd_security_idauth = 0x9c,
// RL78/G23 only
// 78K0R/Kx3-L and RL78/x1y: also sets flash shield window
tool78_cmd_security_set = 0xa0,
// RL78 only
tool78_cmd_security_get = 0xa1,
// RL78 only
tool78_cmd_security_release = 0xa2,
tool78_cmd_exopts_set = 0xa5,
// RL78/G23 only
tool78_cmd_flash_rdp_set = 0xab,
// RL78/G23 only
tool78_cmd_fsw_set = 0xac,
// RL78/G23 only
tool78_cmd_fsw_get = 0xad,
// RL78/G23 only
tool78_cmd_checksum = 0xb0,
// response format & length differ between all MCU versions!
// length & first few bytes can be used to discern between MCUs
@ -242,6 +252,16 @@ enum tool78_sec_flag { // 78k0/78k0r
tool78_sec_flag_boot_xchg = 1<<0 // rl78 only
};
enum tool78_sec_flag12 { // RL78/G23
tool78_sec_flag1_boot_rw_allow = 1<<1,
tool78_sec_flag1_blk_erase_allow = 1<<2,
tool78_sec_flag1_prog_allow = 1<<4,
tool78_sec_flag2_idauth_disable = 1<<0,
tool78_sec_flag2_debug_enable = 1<<2,
tool78_sec_flag2_rdp_write_allow = 1<<3, // NOTE: must be 1 when writing
tool78_sec_flag2_option_write_allow = 1<<4 // NOTE: must be 1 when writing
};
struct tool78_security {
uint8_t flg;
@ -249,6 +269,16 @@ struct tool78_security {
// ^ only these 2 used for 78k0
uint16_t fsws;
uint16_t fswe;
// ^ these two used for RL78/x1y
uint8_t flg2;
// ^ used in RL78/G23
};
struct tool78_fsw_settings {
uint16_t block_start;
uint16_t block_end;
bool fswopt_rw_allow;
bool fsw_area_invert;
};
#endif