diff --git a/src/main.c b/src/main.c index 14cad9b..8e0764d 100644 --- a/src/main.c +++ b/src/main.c @@ -182,9 +182,20 @@ static void tool78_prototest() { memset(&sig, 0, sizeof sig); enum tool78_stat st = tool78_init(&tool78_hw_rl78_uart1, &sig); printf("result: 0x%02x. sig:\n", st); - for (size_t i = 0; i < sizeof(struct tool78_silicon_sig_78k0); ++i) + for (size_t i = 0; i < sizeof(struct tool78_silicon_sig_rl78); ++i) printf("0x%02x ", ((const uint8_t*)&sig)[i]); printf("%c", '\n'); + + // RL78/G11: 0x10 0x00 0x06 0x52 0x35 0x46 0x31 0x30 0x35 0x34 0x41 0x20 0x20 0xff 0x3f 0x00 0xff 0x17 0x0f 0x03 0x00 0x03 + // flg=fe bot=03 fsws=0000 fswe=000f + + // NOTE: RL78 ONLY + struct tool78_security sec; + memset(&sec, 0, sizeof sec); + st = tool78_do_security_get(&tool78_hw_rl78_uart1, &sec); + printf("secget: 0x%02x\n", st); + printf("sec: flg=%02x bot=%02x fsws=%04x fswe=%04x\n", sec.flg, sec.bot, sec.fsws, sec.fswe); + } int main() { diff --git a/src/tool78/tool78_cmds.c b/src/tool78/tool78_cmds.c index d08f23a..fea58a5 100644 --- a/src/tool78/tool78_cmds.c +++ b/src/tool78/tool78_cmds.c @@ -4,6 +4,7 @@ #include #include +#include #include "tool78_defs.h" #include "tool78_hw.h" @@ -137,16 +138,15 @@ static enum tool78_stat tool78_data_send(struct tool78_hw* hw, static enum tool78_stat tool78_cmd_send(struct tool78_hw* hw, uint8_t cmd, int len, const uint8_t* data) { - if (len == 0) return tool78_stat_ack; if (len > 0x100) return tool78_stat_internal_error; - len &= 0xff; + uint8_t lenfield = len &= 0xff; busy_wait_us_32(tCOM); // aka tSN6(/tDN6?) (reset?) or tMB (others?) uint8_t pre[3], // soh, len, cmd post[2]; // cksum, etx pre[0] = tool78_frame_soh; - pre[1] = len + 1; + pre[1] = lenfield + 1; pre[2] = cmd; post[0] = 0; // checksum post[1] = tool78_frame_etx; @@ -172,37 +172,52 @@ static enum tool78_stat tool78_cmd_send(struct tool78_hw* hw, uint8_t cmd, static enum tool78_stat tool78_data_recv(struct tool78_hw* hw, uint8_t* buf, int expected_len, int timeout_us_first) { - uint8_t pre[2]; // stx, len + uint8_t pre[10]; // stx, len uint8_t post[2]; // cksum, etx/etb int rr = hw->recv(1, &pre[0], timeout_us_first); + //printf("data recv rr=%d\n", rr); + if (rr == 0) return tool78_stat_busy; if (rr != 1) return tool78_stat_internal_error; + //printf("pre[0]=0x%02x\n", pre[0]); if (hw->target == tool78k0_spi && pre[0] == tool78_stat_busy) return tool78_stat_busy; - if (pre[0] != tool78_frame_soh) return tool78_stat_protocol_error; + if (pre[0] != tool78_frame_stx) + return (hw->flags & tool78_hw_flag_done_reset) + ? tool78_stat_busy : tool78_stat_protocol_error; rr = hw->recv(1, &pre[1], 100); - if (rr != 1) return tool78_stat_internal_error; + //printf("rr=%d pre[1]=0x%02x\n", rr, pre[1]); + if (rr != 1) { + /*for (int i = 0; i < rr; ++i) + printf("pre[%d]=0x%02x\n", i+1, pre[i+1]); + printf("interr\n");*/ + return tool78_stat_internal_error; + } int len = pre[1]; if (!len) len = 256; if (hw->target == tool78k0_spi && pre[1] == tool78_stat_busy) return tool78_stat_busy; - if (expected_len >= 0 && len != expected_len) + if (expected_len >= 0 && len != expected_len) { return tool78_stat_protocol_error; + } - rr = hw->recv(len, buf, 100*len); + rr = hw->recv(len, buf, 1000*len); if (rr != len) return tool78_stat_internal_error; rr = hw->recv(2, post, 200); if (rr != 2) return tool78_stat_internal_error; - if (post[1] != tool78_frame_etx && post[1] != tool78_frame_etb) + if (post[1] != tool78_frame_etx && post[1] != tool78_frame_etb) { return tool78_stat_protocol_error; + } uint8_t ck = tool78_calc_checksum8(len, buf); - if (ck != post[0]) + ck = tool78_digest_checksum8(ck, 1, &pre[1]); + if (ck != post[0]) { return tool78_stat_protocol_error; + } return tool78_stat_ack; } @@ -230,10 +245,12 @@ static enum tool78_stat tool78_wait_status(struct tool78_hw* hw, int l, int time } st = tool78_data_recv(hw, databuf, l, timeout_us); + //printf("recv: 0x%02x\n", st); if (st == tool78_stat_busy) goto cont; if (st != tool78_stat_ack) return st; st = databuf[0]; + //printf("recvdat: 0x%02x\n", st); if (st == tool78_stat_busy) goto cont; return st; @@ -242,6 +259,7 @@ static enum tool78_stat tool78_wait_status(struct tool78_hw* hw, int l, int time busy_wait_us_32(timeout_us/64); } + //printf("wait t/o\n"); return tool78_stat_timeout_error; } @@ -249,13 +267,13 @@ static enum tool78_stat tool78_wait_status(struct tool78_hw* hw, int l, int time enum tool78_stat tool78_do_reset(struct tool78_hw* hw) { enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_reset, 0, NULL); - printf("send st=%02x\n", st); + //printf("send st=%02x\n", st); if (st != tool78_stat_ack) return st; st = tool78_wait_status(hw, 1, tWT0); // aka tCS1 - printf("wait st=%02x\n", st); + //printf("wait st=%02x\n", st); if (st != tool78_stat_ack) return st; - printf("reset cmd sent\n"); + //printf("reset cmd sent\n"); return st; } @@ -291,13 +309,16 @@ enum tool78_stat tool78_do_baud_rate_set(struct tool78_hw* hw) { d0x[1] = 33; // 3.3V, will switch to full-speed mode st = tool78_cmd_send(hw, tool78_cmd_baud_rate_set, 2, d0x); + //printf("brs send=0x%02x\n", st); if (st != tool78_stat_ack) return st; st = tool78_wait_status(hw, 3, tWT10); // aka tCS6 + //printf("brs stat=0x%02x\n", st); if (st != tool78_stat_ack) return st; // now at 115.2kbaud, so let the physical layer switch to it hw->set_baudrate(115200); + hw->flags |= tool78_hw_flag_done_reset; // let's ignore the two data bytes for now @@ -527,14 +548,27 @@ enum tool78_stat tool78_do_silicon_signature(struct tool78_hw* hw, return tool78_stat_bad_mcu_for_cmd; } + //gpio_set_function(18, GPIO_FUNC_SIO); + //gpio_set_dir(18, true); + //gpio_put(18, true); + memset(sig_dest, 0, 27); enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_silicon_signature, 0, NULL); if (st != tool78_stat_ack) return st; + //gpio_put(18, false); st = tool78_wait_status(hw, 1, tWT11); // aka tCS11 + //gpio_put(18, true); + //printf("silisig: status 0x%02x\n", st); if (st != tool78_stat_ack) return st; - st = tool78_data_recv(hw, (uint8_t*)sig_dest, nbyte, tFD2); // aka tSD11 + //gpio_put(18, false); + // TODO: tool78_data_wait() + //do { + st = tool78_data_recv(hw, (uint8_t*)sig_dest, nbyte, tFD2); // aka tSD11 + //} while (st == tool78_stat_busy); + //gpio_put(18, true); + //printf("silisig: data 0x%02x\n", st); if (st != tool78_stat_ack) return st; switch (hw->target & tool78_mcu_mask) { @@ -701,14 +735,17 @@ enum tool78_stat tool78_do_security_release(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; + hw->flags = 0; - enum tool78_stat st; + enum tool78_stat st = tool78_stat_ack; for (size_t i = 0; i < 16; ++i) { if (!hw->init()) return tool78_stat_fatal_hw_error; printf("init %zu ok\n", i); - st = tool78_do_reset(hw); - printf("done reset st=0x%02x\n", st); + if ((hw->target & tool78_mcu_mask) != tool78_mcu_rl78) { + st = tool78_do_reset(hw); + printf("done reset st=0x%02x\n", st); + } //else printf("no reset to do (rl78)\n"); if (st == tool78_stat_timeout_error) { hw->deinit(); continue; @@ -719,9 +756,11 @@ enum tool78_stat tool78_init(struct tool78_hw* hw, tool78_silicon_sig_t* sig) { printf("hw inited\n"); st = tool78_do_generic_baudrate(hw); + printf("baudrate result=0x%02x\n", st); 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; return st; diff --git a/src/tool78/tool78_hw.h b/src/tool78/tool78_hw.h index 6c7669a..ecc6448 100644 --- a/src/tool78/tool78_hw.h +++ b/src/tool78/tool78_hw.h @@ -8,8 +8,13 @@ #include "tool78_defs.h" +enum tool78_hw_flags { + tool78_hw_flag_done_reset = 1<<0, +}; + struct tool78_hw { const enum tool78_target target; + enum tool78_hw_flags flags; // performs entry sequence + initial handshake (RESET or similar stuff, eg. // UART needs extra null bytes in the beginning) diff --git a/src/tool78/tool78_hw_helpers.c b/src/tool78/tool78_hw_helpers.c index d56ec5e..717aa02 100644 --- a/src/tool78/tool78_hw_helpers.c +++ b/src/tool78/tool78_hw_helpers.c @@ -110,8 +110,8 @@ int tool78_hw_help_recv(const struct tool78_pio_vars* vars, check_timeout_fn ct = NULL; if (!blockinf) ct = init_single_timeout_until(&ts, at); - for (; i < len && (!pio_sm_is_rx_fifo_empty(PINOUT_TOOL78_PIO, vars->smrx) - || blockinf); ++i) { + for (; i < len /*&& ((!pio_sm_is_rx_fifo_empty(PINOUT_TOOL78_PIO, vars->smrx) || !ct(&ts)) + || blockinf)*/; ++i) { while (pio_sm_is_rx_fifo_empty(PINOUT_TOOL78_PIO, vars->smrx)) { if (!blockinf && ct(&ts)) goto end; // whoops, timeout @@ -123,7 +123,7 @@ int tool78_hw_help_recv(const struct tool78_pio_vars* vars, } end: - return overrun ? -i : i; + return overrun ? (!i ? (int)0x08000000 : -i) : i; } int tool78_hw_help_send(const struct tool78_pio_vars* vars, uint32_t sleep_us_between_bytes, @@ -150,16 +150,19 @@ int tool78_hw_help_send(const struct tool78_pio_vars* vars, uint32_t sleep_us_be // FIXME: THIS IS NOT HOW TO WAIT BETWEEN TWO BYTES YOU DOOFUS // (ok maybe it might work because of bad reasons, so let's fix this // once it causes problems) - if (sleep_us_between_bytes) busy_wait_us_32(sleep_us_between_bytes); + if (sleep_us_between_bytes && (i != len-1 || !(tool78_hw_rl78_uart1.flags & tool78_hw_flag_done_reset))) + busy_wait_us_32(sleep_us_between_bytes); } end: if (vars->exclusive) { - // wait until everything is sent before reenabling the RX SM again - while (!pio_sm_is_tx_fifo_empty(PINOUT_TOOL78_PIO, vars->smtx)) - ; // wait until FIFO is clear - while (!(PINOUT_TOOL78_PIO->fdebug & ((1u << vars->smtx) << PIO_FDEBUG_TXSTALL_LSB))) - ; // now wait for the SM to hang on the next 'pull' + if (tool78_hw_rl78_uart1.flags & tool78_hw_flag_done_reset) { + // wait until everything is sent before reenabling the RX SM again + while (!pio_sm_is_tx_fifo_empty(PINOUT_TOOL78_PIO, vars->smtx)) + ; // wait until FIFO is clear + while (!(PINOUT_TOOL78_PIO->fdebug & ((1u << vars->smtx) << PIO_FDEBUG_TXSTALL_LSB))) + ; // now wait for the SM to hang on the next 'pull' + } pio_sm_set_enabled(PINOUT_TOOL78_PIO, vars->smrx, true); } @@ -294,7 +297,7 @@ void tool78_entryseq_rl78(enum tool78_entry typ) { gpio_put(PINOUT_TOOL78_nRESET, true); - busy_wait_us_32(500); // 750us + tHD + busy_wait_us_32(750); // 750us + tHD gpio_put(PINOUT_TOOL78_RL78_TOOL0, true); diff --git a/src/tool78/tool78_hw_rl78_uart1.c b/src/tool78/tool78_hw_rl78_uart1.c index 45159d0..7e779e1 100644 --- a/src/tool78/tool78_hw_rl78_uart1.c +++ b/src/tool78/tool78_hw_rl78_uart1.c @@ -18,6 +18,7 @@ static bool trl78_uart1_init(void) { if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program, &vars)) return false; + tool78_hw_rl78_uart1.flags = 0; // TODO: also in all other hw impls! vars.exclusive = true; vars.bitswap = true; @@ -54,8 +55,9 @@ static int trl78_uart1_recv(int len, uint8_t* data, int32_t timeout_us) { return tool78_hw_help_recv(&vars, len, data, timeout_us); } static int trl78_uart1_send(int len, const uint8_t* data, int32_t timeout_us) { - // TODO: tDR changes after first baudrate set - return tool78_hw_help_send(&vars, 190/*inter-byte delay (us) tDR = 90/8M s */, + return tool78_hw_help_send(&vars, + (tool78_hw_rl78_uart1.flags & tool78_hw_flag_done_reset) ? 0 : 190 + /*inter-byte delay (us) tDR = 90/8M s */, len, data, timeout_us); }