From c9f81731bb9b009658f1adc9992e6bef8dd5ad1a Mon Sep 17 00:00:00 2001 From: sys64738 Date: Wed, 10 Nov 2021 10:06:46 +0100 Subject: [PATCH] tool78: code finishedish, now to test this --- src/tool78/tool78_cmds.c | 149 ++++++++++++++++++++++++++++++--------- src/tool78/tool78_cmds.h | 2 +- src/tool78/tool78_defs.h | 1 + 3 files changed, 118 insertions(+), 34 deletions(-) diff --git a/src/tool78/tool78_cmds.c b/src/tool78/tool78_cmds.c index 3f05918..434103e 100644 --- a/src/tool78/tool78_cmds.c +++ b/src/tool78/tool78_cmds.c @@ -17,7 +17,7 @@ static uint8_t databuf[255]; // tSF | 215 X X // tWT0 tCS1 | 172 0 255 // tWT1 (tSD8) |857883+128*44160 (1420100+128*281100) 212 -// tWT2 tCS3 |214714*TODO+128*44160 (3300+271600+128*275000) (248862+299307) +// tWT2 tCS3 |214714*512+128*44160 (3300+271600+128*275000) (248862+299307) // tWT3 tCS5 | 1506 0 1432 // tWT4 tDS5 |893355/2 149900 (309870+488315) // tWT5 tSS5 |100407 1187500 (1732+58+(17403+29293)*128+(184+44)) @@ -41,6 +41,66 @@ static uint8_t databuf[255]; // ~tSD8~ | // ~tCS9~ | +struct delayvalues { int none; int k0; int k0r; int rl78; }; +#define D(a,b,c) ((struct delayvalues){.none=1000, .k0=(a), .k0r=(b), .rl78=(c)}) +static const struct delayvalues delays[23] = { + D(106, 14, 62), // tCOM + D(215, -1, -1), // tSF (78k0 SPI only) + D(172, 0, 255), // tWT0 + D(857883+128*44160, (1420100+128*281100), 212), // tWT1 + D(214714*512+128*44160, (3300+271600+128*275000),(248862+299307)), // tWT2 + D(1506,0,1432), // tWT3 + D(893355/2, 149900, (309870+488315)), // tWT4 + D(100407 , 1187500, (1732+58+(17403+29293)*128+(184+44))), // tWT5 + D(686,0,351), // tWT6 + D(12827, 0, 11981), // tWT7 + D(55044, 1800, (3805+168+(5035+1110)*128+(5827+318))), // tWT8 + D(1238, -1, 154), // tWT9, + D(-1, 380, 4735), // tWT10, + D(1233, 0, 111), // tWT11, + D(252, 0, (146110+534723+(5035+1110)*128+(203+57))), // tWT12 + D(975, 0, 168), // tWT13 + D(66005812/2 ,71, (277095+1075967)), // tWT14 + D(66018156/2 ,1153, -1), // tWT15 + D(583, 0, 219), // tWT16 + D(54368, 0, (72+128*30720)), // tFD1 + D(321, 12, 512), // tFD2 + D(163, 417, 41), // tFD3 + D(163, 986, 32), // tFD4 +}; +// SD5 SS5 SD2 CS4 SD7 CS8 SD8 CS9 +#define tCOM (((&delays[ 0].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tSF (((&delays[ 1].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT0 (((&delays[ 2].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT1 (((&delays[ 3].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT2 (((&delays[ 4].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT3 (((&delays[ 5].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT4 (((&delays[ 6].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT5 (((&delays[ 7].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT6 (((&delays[ 8].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT7 (((&delays[ 9].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT8 (((&delays[10].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT9 (((&delays[11].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT10 (((&delays[12].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT11 (((&delays[13].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT12 (((&delays[14].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT13 (((&delays[15].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT14 (((&delays[16].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT15 (((&delays[17].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tWT16 (((&delays[18].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tFD1 (((&delays[19].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tFD2 (((&delays[20].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tFD3 (((&delays[21].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tFD4 (((&delays[22].none)[(hw->target & tool78_mcu_mask) >> 4])) +#define tSD5 tFD3 +#define tSS5 tWT5 +#define tSD2 tFD3 +#define tCS4 tWT8 +#define tSD7 tFD4 +#define tCS8 tWT9 +#define tSD8 tWT1 +#define tCS9 tWT12 + static enum tool78_stat tool78_data_send(struct tool78_hw* hw, int len, const uint8_t* data, bool final_block) { @@ -80,7 +140,7 @@ static enum tool78_stat tool78_cmd_send(struct tool78_hw* hw, uint8_t cmd, if (len > 0x100) return tool78_stat_internal_error; len &= 0xff; - busy_wait_us_32(tCOM); // TODO // aka tSN6(/tDN6?) (reset?) or tMB (others?) + busy_wait_us_32(tCOM); // aka tSN6(/tDN6?) (reset?) or tMB (others?) uint8_t pre[3], // soh, len, cmd post[2]; // cksum, etx @@ -165,7 +225,7 @@ static enum tool78_stat tool78_wait_status(struct tool78_hw* hw, int l, int time enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_status, 0, NULL); if (st != tool78_stat_ack) return st; - busy_wait_us_32(tSF); // TODO + busy_wait_us_32(tSF); } st = tool78_data_recv(hw, databuf, l, timeout_us); @@ -190,7 +250,7 @@ enum tool78_stat tool78_do_reset(struct tool78_hw* hw) { enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_reset, 0, NULL); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 1, tWT0); // TODO // aka tCS1 + st = tool78_wait_status(hw, 1, tWT0); // aka tCS1 if (st != tool78_stat_ack) return st; return st; @@ -214,7 +274,7 @@ enum tool78_stat tool78_do_baud_rate_set(struct tool78_hw* hw) { st = tool78_cmd_send(hw, tool78_cmd_baud_rate_set, 5, d0x); if (st != tool78_stat_ack) return st; - busy_wait_us_32(tWT10); // TODO + busy_wait_us_32(tWT10); // now at 115.2kbaud, so let the physical layer switch to it hw->set_baudrate(115200); @@ -229,7 +289,7 @@ enum tool78_stat tool78_do_baud_rate_set(struct tool78_hw* hw) { st = tool78_cmd_send(hw, tool78_cmd_baud_rate_set, 2, d0x); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 3, tWT10); // TODO // aka tCS6 + st = tool78_wait_status(hw, 3, tWT10); // aka tCS6 if (st != tool78_stat_ack) return st; // now at 115.2kbaud, so let the physical layer switch to it @@ -269,7 +329,7 @@ enum tool78_stat tool78_do_osc_freq_set(struct tool78_hw* hw) { // now at 115.2kbaud, so let the physical layer switch to it if (hw->target != tool78k0_spi) hw->set_baudrate(115200); - st = tool78_wait_status(hw, 1, tWT9); // TODO + st = tool78_wait_status(hw, 1, tWT9); if (st != tool78_stat_ack) return st; return st; @@ -284,7 +344,7 @@ enum tool78_stat tool78_do_chip_erase(struct tool78_hw* hw) { enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_chip_erase, 0, NULL); if (st != tool78_stat_ack) return st; - return tool78_wait_status(hw, 1, tWT1); // TODO + return tool78_wait_status(hw, 1, tWT1); } enum tool78_stat tool78_do_block_erase(struct tool78_hw* hw, uint32_t start, uint32_t end) { @@ -309,7 +369,7 @@ enum tool78_stat tool78_do_block_erase(struct tool78_hw* hw, uint32_t start, uin isrl78 ? 3 : 6, data); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 1, tWT2); // TODO // aka tCS3 + st = tool78_wait_status(hw, 1, tWT2); // aka tCS3 if (st != tool78_stat_ack) return st; //st = tool78_wait_status(hw, 1, tWTx); // TODO: ? @@ -340,12 +400,12 @@ enum tool78_stat tool78_do_programming(struct tool78_hw* hw, uint32_t start, enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_programming, 6, data); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 1, tWT3); // TODO // aka tCS5 + st = tool78_wait_status(hw, 1, tWT3); // aka tCS5 if (st != tool78_stat_ack) return st; int nblocks = ((end - start + 255) / 256); for (size_t off = 0; off < end - start; off += 256) { - busy_wait_us_32(tSD5); // TODO // aka tFD3 + busy_wait_us_32(tSD5); // aka tFD3 size_t todo = (end - start) - off; if (todo > 256) todo = 256; @@ -353,13 +413,13 @@ enum tool78_stat tool78_do_programming(struct tool78_hw* hw, uint32_t start, st = tool78_data_send(hw, todo, &src[off], finalblk); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 2, tWT4); // TODO // aka tDS5 + st = tool78_wait_status(hw, 2, tWT4); // aka tDS5 if (st != tool78_stat_ack) return st; st = databuf[1]; if (st != tool78_stat_ack) return st; } - st = tool78_wait_status(hw, 1, isrl78 ? tSS5 : (tWT5 * nblocks)); // TODO + st = tool78_wait_status(hw, 1, isrl78 ? tSS5 : (tWT5 * nblocks)); if (st != tool78_stat_ack) return st; return st; @@ -389,12 +449,12 @@ enum tool78_stat tool78_do_verify(struct tool78_hw* hw, uint32_t start, enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_verify, 6, data); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 1, tWT6); // TODO // aka tCS2 + st = tool78_wait_status(hw, 1, tWT6); // aka tCS2 if (st != tool78_stat_ack) return st; //int nblocks = ((end - start + 255) / 256); for (size_t off = 0; off < end - start; off += 256) { - busy_wait_us_32(tSD2); // TODO // aka tFD3 + busy_wait_us_32(tSD2); // aka tFD3 size_t todo = (end - start) - off; if (todo > 256) todo = 256; @@ -402,7 +462,7 @@ enum tool78_stat tool78_do_verify(struct tool78_hw* hw, uint32_t start, st = tool78_data_send(hw, todo, &src[off], finalblk); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 2, tWT7); // TODO // aka tDS2 + st = tool78_wait_status(hw, 2, tWT7); // aka tDS2 if (st != tool78_stat_ack) return st; st = databuf[1]; if (st != tool78_stat_ack) return st; @@ -438,12 +498,20 @@ enum tool78_stat tool78_do_block_blank_check(struct tool78_hw* hw, isrl78 ? 7 : 6, data); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 1, isrl78 ? tCS4 : (tWT8 * nblocks)); // TODO + st = tool78_wait_status(hw, 1, isrl78 ? tCS4 : (tWT8 * nblocks)); if (st != tool78_stat_ack) return st; return st; } +static bool check_parity(uint8_t v) { + uint8_t parity = (v >> 7) & 1; + uint8_t calc = 1; // odd parity + for (size_t i = 0; i < 7; ++i) calc ^= (v >> i) & 1; + + return calc == parity; +} + enum tool78_stat tool78_do_silicon_signature(struct tool78_hw* hw, tool78_silicon_sig_t* sig_dest) { int nbyte = 0; @@ -459,13 +527,22 @@ enum tool78_stat tool78_do_silicon_signature(struct tool78_hw* hw, enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_silicon_signature, 0, NULL); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 1, tWT11); // TODO // aka tCS11 + st = tool78_wait_status(hw, 1, tWT11); // aka tCS11 if (st != tool78_stat_ack) return st; - st = tool78_data_recv(hw, (uint8_t*)sig_dest, nbyte, tFD2); // TODO // aka tSD11 + st = tool78_data_recv(hw, (uint8_t*)sig_dest, nbyte, tFD2); // aka tSD11 if (st != tool78_stat_ack) return st; - // TODO: parity check of data + switch (hw->target & tool78_mcu_mask) { + case tool78_mcu_78k0: nbyte = 18; break; + case tool78_mcu_78k0r: nbyte = 6; break; + case tool78_mcu_rl78: nbyte = 0; break; + } + + for (int i = 0; i < nbyte; ++i) { + if (!check_parity(((const uint8_t*)sig_dest)[i])) + return tool78_stat_parity_error; + } return st; } @@ -477,11 +554,11 @@ enum tool78_stat tool78_do_version_get(struct tool78_hw* hw, tool78_version_t* v enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_version_get, 0, NULL); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 1, tWT12); // TODO + st = tool78_wait_status(hw, 1, tWT12); if (st != tool78_stat_ack) return st; memset(vout, 0, 6); - st = tool78_data_recv(hw, (uint8_t*)vout, 6, tFD2); // TODO + st = tool78_data_recv(hw, (uint8_t*)vout, 6, tFD2); if (st != tool78_stat_ack) return st; return st; @@ -511,11 +588,11 @@ enum tool78_stat tool78_do_checksum(struct tool78_hw* hw, uint32_t start, enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_checksum, 6, data); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 1, tWT16); // TODO // aka tCS10 + st = tool78_wait_status(hw, 1, tWT16); // aka tCS10 if (st != tool78_stat_ack) return st; *ckout = 0; - st = tool78_data_recv(hw, (uint8_t*)ckout, 2, tFD1); // TODO // aka tSD10 + st = tool78_data_recv(hw, (uint8_t*)ckout, 2, tFD1); // aka tSD10 if (st != tool78_stat_ack) return st; return st; @@ -532,10 +609,10 @@ enum tool78_stat tool78_do_security_set(struct tool78_hw* hw, isrl78 ? 0 : 2, data); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 1, tWT13); // TODO // aka tCS7 + st = tool78_wait_status(hw, 1, tWT13); // aka tCS7 if (st != tool78_stat_ack) return st; - busy_wait_us_32(tSD7); // TODO // aka tFD3 + busy_wait_us_32(tSD7); // aka tFD3 switch (hw->target & tool78_mcu_mask) { case tool78_mcu_78k0: data[0] = sec->flg; @@ -565,11 +642,11 @@ enum tool78_stat tool78_do_security_set(struct tool78_hw* hw, } if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 1, tWT14); // TODO // aka tDS7 + st = tool78_wait_status(hw, 1, tWT14); // aka tDS7 if (st != tool78_stat_ack) return st; if (!isrl78) { // yeah... - st = tool78_wait_status(hw, 1, tWT15); // TODO + st = tool78_wait_status(hw, 1, tWT15); if (st != tool78_stat_ack) return st; } @@ -608,7 +685,7 @@ enum tool78_stat tool78_do_security_release(struct tool78_hw* hw) { enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_security_release, 0, NULL); if (st != tool78_stat_ack) return st; - st = tool78_wait_status(hw, 1, tCS9); // TODO + st = tool78_wait_status(hw, 1, tCS9); if (st != tool78_stat_ack) return st; // TODO: needs a modeset/re-entry sequence now? @@ -618,13 +695,14 @@ enum tool78_stat tool78_do_security_release(struct tool78_hw* hw) { // ---- -enum tool78_stat tool78_init(struct tool78_hw* hw) { +enum tool78_stat tool78_init(struct tool78_hw* hw, tool78_silicon_sig_t* sig) { if (!hw) return tool78_stat_internal_error; + enum tool78_stat st; for (size_t i = 0; i < 16; ++i) { if (!hw->init()) return tool78_stat_fatal_hw_error; - enum tool78_stat st = tool78_do_reset(hw); + st = tool78_do_reset(hw); if (st == tool78_stat_timeout_error) { hw->deinit(); continue; @@ -632,7 +710,12 @@ enum tool78_stat tool78_init(struct tool78_hw* hw) { return st; } - // TODO: baudrate set/oscfreq set (if not 78k0 SPI) - // TODO: silicon sig get (not reqd if 78k0 but oh well) + st = tool78_do_generic_baudrate(hw); + if (st != tool78_stat_ack) return st; + + st = tool78_do_silicon_signature(hw, sig); + if (st != tool78_stat_ack) return st; + + return st; } diff --git a/src/tool78/tool78_cmds.h b/src/tool78/tool78_cmds.h index 235ce4b..1225c29 100644 --- a/src/tool78/tool78_cmds.h +++ b/src/tool78/tool78_cmds.h @@ -40,7 +40,7 @@ enum tool78_stat tool78_do_security_release(struct tool78_hw* hw); // ---- -enum tool78_stat tool78_init(struct tool78_hw* hw); +enum tool78_stat tool78_init(struct tool78_hw* hw, tool78_silicon_sig_t* sig); #endif diff --git a/src/tool78/tool78_defs.h b/src/tool78/tool78_defs.h index 388f64f..bfd0e8e 100644 --- a/src/tool78/tool78_defs.h +++ b/src/tool78/tool78_defs.h @@ -118,6 +118,7 @@ enum tool78_stat { tool78_stat_bad_mcu_for_cmd = 0xc2, tool78_stat_timeout_error = 0xc3, tool78_stat_fatal_hw_error = 0xc4, + tool78_stat_parity_error = 0xc5, }; // TODO: only known for RL78 from fail0overflow. verify!