can get siliconsig & secinfo from RL78/G11

This commit is contained in:
Triss 2021-11-14 01:10:30 +01:00
parent 3c1b4d88aa
commit a5a3a99fa4
5 changed files with 90 additions and 30 deletions

View File

@ -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() {

View File

@ -4,6 +4,7 @@
#include <pico/time.h>
#include <pico/timeout_helper.h>
#include <hardware/gpio.h>
#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;

View File

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

View File

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

View File

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