tool78: code finishedish, now to test this

This commit is contained in:
Triss 2021-11-10 10:06:46 +01:00
parent e77699c9cc
commit c9f81731bb
3 changed files with 118 additions and 34 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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!