tool78: code finishedish, now to test this
This commit is contained in:
parent
e77699c9cc
commit
c9f81731bb
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
|
Loading…
Reference in New Issue