g10/g1m bullshit
This commit is contained in:
parent
53b6034272
commit
c4bb26ead1
|
@ -35,6 +35,8 @@ void cli_tool78_g10_ocdtest(void);
|
|||
void cli_tool78_glitch_dump(void);
|
||||
void cli_tool78_glitch_paramsearch(void);
|
||||
void cli_tool78_glitch_ocd_dump(void);
|
||||
void cli_tool78_glitch_param_g10(void);
|
||||
void cli_tool78_glitch_ocd_g10(void);
|
||||
|
||||
static void adc_init_stuff() {
|
||||
adc_init();
|
||||
|
@ -80,6 +82,8 @@ static struct cli_cmd cmds[] = {
|
|||
{ "g78dump", cli_tool78_glitch_dump },
|
||||
{ "g78param", cli_tool78_glitch_paramsearch },
|
||||
{ "g78ocd", cli_tool78_glitch_ocd_dump },
|
||||
{ "g10param", cli_tool78_glitch_param_g10 },
|
||||
{ "g10ocd", cli_tool78_glitch_ocd_g10 },
|
||||
|
||||
{ "zap", cli_dragonzap_test },
|
||||
|
||||
|
|
|
@ -10,7 +10,15 @@ void cli_dragonzap_test(void);
|
|||
void cli_dragonzap_test(void) {
|
||||
zap_init_default();
|
||||
zap_dac_set_enable(zap_dac_a | zap_dac_b);
|
||||
#if 1 /* MCP48x2 */
|
||||
zap_dac_set_mulx2(zap_dac_a | zap_dac_b);
|
||||
#else
|
||||
zap_dac_set_mulx2(0);
|
||||
zap_dac_set_shutdown(false);
|
||||
#endif
|
||||
|
||||
zap_max_use_vhi_jp300(true);
|
||||
zap_max_set_inhibit(false);
|
||||
|
||||
sio_hw->gpio_oe_set = ZAP_GPIO_MASK;
|
||||
sio_hw->gpio_clr = ZAP_GPIO_MASK;
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
void cli_tool78_glitch_dump(void);
|
||||
void cli_tool78_glitch_paramsearch(void);
|
||||
void cli_tool78_glitch_ocd_dump(void);
|
||||
void cli_tool78_glitch_param_g10(void);
|
||||
void cli_tool78_glitch_ocd_g10(void);
|
||||
|
||||
#define DUMP_OFFSET 0/*0xef000*/
|
||||
#define DUMP_SIZE 1024/*65536*/
|
||||
|
@ -45,7 +47,7 @@ static uint8_t databuf[DUMP_SIZE];
|
|||
static struct glitch_param_randrange offset;
|
||||
static struct glitch_param_adc length;
|
||||
|
||||
static bool glitch_init_core1_stuff(bool exttrig) {
|
||||
static bool glitch_init_core1_stuff(bool exttrig, uint glitchpin) {
|
||||
offset.min = 10*1000;
|
||||
offset.max = 35433*1000;
|
||||
length.min = 100;
|
||||
|
@ -81,11 +83,12 @@ static bool glitch_init_core1_stuff(bool exttrig) {
|
|||
// * with REGC, 10uF@VDD, long pulses: 0..3mV (strict upper limit)
|
||||
// * 100uF@VDD: too much, even w/o REGC
|
||||
.trigger_in_pin = -2,
|
||||
.glitch_out_pin = GLITCH_OUT_PIN,
|
||||
.glitch_out_pin = -2,//glitchpin,//GLITCH_OUT_PIN,
|
||||
.trigger_in_polarity = glitch_positive,
|
||||
.glitch_out_polarity = glitch_positive,
|
||||
.impl = glitch_impl_pio,//core1,
|
||||
};
|
||||
gparam.glitch_out_pin = glitchpin;
|
||||
gparam.offset_ns = (struct glitch_param){
|
||||
.ud = &offset,
|
||||
.getter = glitch_param_randrange_fn
|
||||
|
@ -206,9 +209,9 @@ deinit_bad:
|
|||
}
|
||||
|
||||
void cli_tool78_glitch_paramsearch(void) {
|
||||
if (!glitch_init_core1_stuff(true)) {
|
||||
if (!glitch_init_core1_stuff(true, GLITCH_OUT_PIN)) {
|
||||
printf("bad glitcher params!\n");
|
||||
while (1) asm volatile("");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
|
@ -361,14 +364,14 @@ do_reset_stuff:
|
|||
}
|
||||
|
||||
void cli_tool78_glitch_ocd_dump(void) {
|
||||
if (!glitch_init_core1_stuff(false)) {
|
||||
if (!glitch_init_core1_stuff(false, GLITCH_OUT_PIN)) {
|
||||
printf("bad glitcher params!\n");
|
||||
while (1) asm volatile("");
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_set_function(2, GPIO_FUNC_SIO);
|
||||
/*gpio_set_function(2, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(2, GPIO_OUT);
|
||||
gpio_put(2, false);
|
||||
gpio_put(2, false);*/
|
||||
|
||||
//gpio_set_function(3, GPIO_FUNC_SIO);
|
||||
//gpio_set_dir(3, GPIO_OUT);
|
||||
|
@ -383,7 +386,7 @@ void cli_tool78_glitch_ocd_dump(void) {
|
|||
restart:
|
||||
//trl78_uart1_set_exclusive(true);
|
||||
//tool78_hw_rl78_uart1.rx_set_stop_bit(false);
|
||||
gpio_put(2, false);
|
||||
//gpio_put(2, false);
|
||||
/*glitch_disarm();
|
||||
busy_wait_ms(40);*/
|
||||
|
||||
|
@ -456,7 +459,7 @@ do_reset_stuff:
|
|||
goto restart;
|
||||
|
||||
success:;
|
||||
gpio_put(2, true);
|
||||
//gpio_put(2, true);
|
||||
//busy_wait_ms(5);
|
||||
// (02): read from above (checkbuf) code
|
||||
// 03 06 18 00 df 03
|
||||
|
@ -534,3 +537,319 @@ deinit_bad:
|
|||
return;
|
||||
}
|
||||
|
||||
static uint8_t DATA_G1M_paramtest[47] = {
|
||||
0xcf, 0x77, 0x00, 0x00, 0xce, 0x00, 0x00, 0xcf, 0x30, 0x00, 0x00, 0xcf, 0x50,
|
||||
0x00, 0x00, 0xcf, 0x60, 0x00, 0x7f, 0xcf, 0x20, 0xff, 0x00, 0xcf, 0xf0, 0x00,
|
||||
0xe5, 0xcf, 0xf3, 0x00, 0x10, 0xce, 0x00, 0xff, 0x51, 0x48, 0xfc, 0xdc, 0xff,
|
||||
0x0e, 0x51, 0x69, 0xfc, 0xdc, 0xff, 0x0e, 0xd7
|
||||
};
|
||||
|
||||
|
||||
void cli_tool78_glitch_param_g10(void) {
|
||||
struct tool78_hw* hw = &tool78_hw_rl78g10_uart1;
|
||||
|
||||
zap_dac_set_enable(zap_dac_a | zap_dac_b);
|
||||
#if 1 /* MCP48x2 */
|
||||
zap_dac_set_mulx2(zap_dac_a | zap_dac_b);
|
||||
#else
|
||||
zap_dac_set_mulx2(0);
|
||||
zap_dac_set_shutdown(false);
|
||||
#endif
|
||||
|
||||
zap_max_use_vhi_jp300(true);
|
||||
zap_max_set_inhibit(false);
|
||||
|
||||
if (!glitch_init_core1_stuff(true, GLITCH_OUT_PIN)) {
|
||||
printf("bad glitcher params!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
enum tool78_stat st;
|
||||
int rr;
|
||||
static uint8_t checkbuf[256];
|
||||
bool first = true;
|
||||
|
||||
restart:
|
||||
/*glitch_disarm();
|
||||
busy_wait_ms(40);*/
|
||||
|
||||
st = tool78_init_ocd(hw, NULL, passwd);
|
||||
if (st == 0xc3) {
|
||||
printf("aa\n");
|
||||
st = 0;
|
||||
rr = tool78_hw_rl78_uart1.recv(1, (uint8_t*)&st, 120*1000);
|
||||
printf("rr=%d\n", rr);
|
||||
if (rr != 1) {
|
||||
printf("aaaa\n");
|
||||
goto do_reset_stuff;
|
||||
}
|
||||
}
|
||||
//printf("result: 0x%02x ver=%04x\n", st, ver);
|
||||
if (st != 0xf2 && st != 0xf0) {
|
||||
printf("init: 0x%02x\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
if (first) printf("result: 0x%02x\n", st);
|
||||
|
||||
// TODO: upload other code!
|
||||
// can't write too much at 0xf07e0 as 0xf0800 and up contains OCD state,
|
||||
// overwrite this and suddenly the OCD system resets itself
|
||||
st = tool78_ocd_write(hw, 0x07e0,
|
||||
sizeof(exec_jmp_to_ram), exec_jmp_to_ram);
|
||||
//printf("write trampoline res 0x%02x\n", st);
|
||||
if (st != 0) {
|
||||
printf("trampoline write failed: %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
st = tool78_ocd_write(hw, 0xf900,
|
||||
sizeof(DATA_test_dbg__paramtest), DATA_test_dbg__paramtest);
|
||||
//printf("write code res 0x%02x\n", st);
|
||||
if (st != 0) {
|
||||
printf("code write failed: %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
|
||||
st = tool78_ocd_exec(hw);
|
||||
//printf("exec res 0x%02x\n", st);
|
||||
if (st != 0) {
|
||||
printf("exec failed: %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
|
||||
// test custom tool_tx call
|
||||
/*rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 1000);
|
||||
printf("rr=%d\n", rr);
|
||||
if (rr == 1) printf("0x%02x %c\n", stuff[0], stuff[0]);*/
|
||||
|
||||
// wait for completion
|
||||
rr = hw->recv(2, checkbuf, 120*1000);
|
||||
if (rr != 2) {
|
||||
printf("exec code: no response :/ (%d)\n", rr);
|
||||
goto deinit_bad;
|
||||
}
|
||||
|
||||
if (checkbuf[0] != 'H' && checkbuf[1] != 'i') {
|
||||
printf("bad response: %02x %02x\n", checkbuf[0], checkbuf[1]);
|
||||
goto deinit_bad;
|
||||
}
|
||||
|
||||
rr = hw->recv(256, checkbuf, 120*1000);
|
||||
if (rr != 256) {
|
||||
printf("exec code: no data sendback (%d)\n", rr);
|
||||
goto deinit_bad;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 256; ++i) {
|
||||
if (checkbuf[i] != (0xff^0xaa)) {
|
||||
printf("bad value at index %zu: %02x\n", i, checkbuf[i]^0xaa);
|
||||
goto deinit_bad;
|
||||
}
|
||||
}
|
||||
if (first) printf("all set, let's go\n");
|
||||
first = false;
|
||||
|
||||
while (true) {
|
||||
glitch_arm();
|
||||
rr = hw->recv(2, checkbuf, 120*1000);
|
||||
glitch_disarm();
|
||||
if (rr == 2 && (checkbuf[0] != 'H' || checkbuf[1] != 'i')) rr = 0;
|
||||
if (rr == 2) {
|
||||
rr = hw->recv(256, checkbuf, 120*1000);
|
||||
}
|
||||
|
||||
if (rr <= 0) {
|
||||
// timeout or something
|
||||
printf("X");
|
||||
hw->deinit();
|
||||
goto do_reset_stuff;
|
||||
} else {
|
||||
int firstbad = -1, lastbad = -1;
|
||||
for (int i = 0; i < rr; ++i) {
|
||||
if (checkbuf[i] != (0xaa^0xff)) {
|
||||
if (firstbad == -1) firstbad = i;
|
||||
lastbad = i;
|
||||
}
|
||||
}
|
||||
if (firstbad >= 0) {
|
||||
volatile uint32_t
|
||||
*off = (volatile uint32_t*)&glitch_param_cur.offset_ns.cur,
|
||||
*len = (volatile uint32_t*)&glitch_param_cur.length_ns.cur;
|
||||
printf("glitch first=%d last=%d off=%lu len=%lu rr=%d v=%02x\n",
|
||||
firstbad, lastbad, *off, *len, rr, checkbuf[firstbad]^0xaa);
|
||||
} else {
|
||||
printf(".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deinit_bad:
|
||||
hw->deinit();
|
||||
return;
|
||||
|
||||
do_reset_stuff:
|
||||
hw->deinit();
|
||||
|
||||
// glitch for way too long to power cycle
|
||||
sio_hw->gpio_set = 1u << GLITCH_OUT_PIN;
|
||||
busy_wait_ms(16);
|
||||
sio_hw->gpio_clr = 1u << GLITCH_OUT_PIN;
|
||||
|
||||
goto restart;
|
||||
}
|
||||
|
||||
void cli_tool78_glitch_ocd_g10(void) {
|
||||
struct tool78_hw* hw = &tool78_hw_rl78g10_uart1;
|
||||
|
||||
zap_dac_set_enable(zap_dac_a | zap_dac_b);
|
||||
#if 1 /* MCP48x2 */
|
||||
zap_dac_set_mulx2(zap_dac_a | zap_dac_b);
|
||||
#else
|
||||
zap_dac_set_mulx2(0);
|
||||
zap_dac_set_shutdown(false);
|
||||
#endif
|
||||
|
||||
zap_max_use_vhi_jp300(true);
|
||||
zap_max_set_inhibit(false);
|
||||
|
||||
if (!glitch_init_core1_stuff(false, ZAP_GLITCH_OUT)) {
|
||||
printf("bad glitcher params!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_set_function(2, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(2, GPIO_OUT);
|
||||
gpio_put(2, false);
|
||||
|
||||
//gpio_set_function(3, GPIO_FUNC_SIO);
|
||||
//gpio_set_dir(3, GPIO_OUT);
|
||||
//gpio_put(3, false);
|
||||
|
||||
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
int st, rr/*, r0, r1, r2*/;
|
||||
static uint8_t checkbuf[256];
|
||||
bool first = true;
|
||||
|
||||
restart:
|
||||
//trl78_uart1_set_exclusive(true);
|
||||
//hw->rx_set_stop_bit(false);
|
||||
gpio_put(2, false);
|
||||
/*glitch_disarm();
|
||||
busy_wait_ms(40);*/
|
||||
|
||||
st = tool78_init_ocd(hw, NULL, passwd);
|
||||
if (st == 0xc3) {
|
||||
printf("aa\n");
|
||||
st = 0;
|
||||
rr = hw->recv(1, (uint8_t*)&st, 120*1000);
|
||||
printf("rr=%d\n", rr);
|
||||
if (rr != 1) {
|
||||
printf("aaaa\n");
|
||||
goto do_reset_stuff;
|
||||
}
|
||||
}
|
||||
if (first) printf("result: 0x%02x\n", st);
|
||||
if (st == 0xc1) goto do_reset_stuff;
|
||||
if (st != tool78_stat_no_ocd_status) {
|
||||
printf("init: expected status timeout error, got %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
busy_wait_ms(16); // leave time to recharge
|
||||
|
||||
// TODO: update description
|
||||
// right now, the RL78 core is stuck in an infinite loop doing nothing in
|
||||
// the debug monitor part of its bootrom. however, the code we need is
|
||||
// right below it, so we can simply try to glitch it without having to meet
|
||||
// the timing
|
||||
// see https://fail0verflow.com/blog/2018/ps4-syscon/ for more info
|
||||
|
||||
// try up to 16 times because we can't discern between a reset and a glitch
|
||||
// that had no effect. after 16 iterations without result, reset the RL78
|
||||
// and try again.
|
||||
// a successful glitch will output a single null byte over the TOOL0 line
|
||||
|
||||
// apparently we have about 95 ms until the infinite loop gets reset into
|
||||
// the MCU flash automatically? somehow?? I suppose it's the WDT
|
||||
if (first) printf("all set, let's go\n");
|
||||
first = false;
|
||||
|
||||
//hw->rx_set_stop_bit(false);
|
||||
glitch_arm();
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
zap_dac_set_b(zap_adc_read(1));
|
||||
zap_dac_latch();
|
||||
//glitch_trigger_sw_core1();
|
||||
glitch_trigger_sw_pio();
|
||||
rr = hw->recv(1, checkbuf, 12*1000);
|
||||
if (rr != 1 || checkbuf[0] == 0xff) {
|
||||
busy_wait_ms(1); // leave time to recharge
|
||||
printf(".");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("checkbuf: %d", checkbuf[0]);
|
||||
printf("\n!!!\n");
|
||||
hw->flags |= tool78_hw_flag_done_reset;
|
||||
|
||||
glitch_disarm();
|
||||
goto success;
|
||||
}
|
||||
glitch_disarm();
|
||||
|
||||
printf(":");
|
||||
do_reset_stuff:
|
||||
hw->deinit();
|
||||
|
||||
// glitch for way too long to power cycle
|
||||
sio_hw->gpio_set = 1u << GLITCH_OUT_PIN;
|
||||
busy_wait_ms(16);
|
||||
sio_hw->gpio_clr = 1u << GLITCH_OUT_PIN;
|
||||
|
||||
goto restart;
|
||||
|
||||
success:;
|
||||
//gpio_put(2, true);
|
||||
//busy_wait_ms(5);
|
||||
// (02): read from above (checkbuf) code
|
||||
// 03 06 18 00 df 03
|
||||
// ^-- baud rate set response
|
||||
// 00
|
||||
// ^-- OCD entry response
|
||||
rr = hw->recv(4, &checkbuf[1], 10000);
|
||||
if (rr != 4) {
|
||||
printf("#");
|
||||
//printf("rr=%d, wut?\n", rr);
|
||||
goto do_reset_stuff;
|
||||
}
|
||||
printf("recv %02x %02x %02x %02x %02x\n", checkbuf[0], checkbuf[1],
|
||||
checkbuf[2], checkbuf[3], checkbuf[4]);
|
||||
|
||||
busy_wait_us_32(500);
|
||||
|
||||
printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur);
|
||||
/*goto do_reset_stuff;*/
|
||||
|
||||
st = tool78_ocd_connect(hw, passwd);
|
||||
if (st != 0xf0 && st != 0xf2) {
|
||||
printf("OCD: connect failed: %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
printf("connect! 0x%02x\n", st);
|
||||
|
||||
for (size_t i = 0; i < DUMP_SIZE; i += 256) {
|
||||
st = tool78_ocd_read(hw, 0x8000+i, (uint8_t)0x100, &databuf[i]);
|
||||
if (st) {
|
||||
printf("no read! st=%d\n", st);
|
||||
}
|
||||
}
|
||||
for (size_t iii = 0; iii < DUMP_SIZE; ++iii) {
|
||||
printf("%02x%s", databuf[iii], ((iii & 0xf) == 0xf) ? "\n" : " ");
|
||||
}
|
||||
|
||||
printf("\ndone!\n");
|
||||
|
||||
deinit_bad:
|
||||
hw->deinit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,17 @@ static uint8_t shellcode_test[] = {
|
|||
0xd7, // ret
|
||||
};
|
||||
|
||||
static uint8_t G1M_test_1[] = {
|
||||
0xcb, 0xf8, 0x00, 0xfe, // movw sp, #0xfe00
|
||||
0xec, 0xba, 0xff, 0x0e, // br !!0xeffba
|
||||
};
|
||||
static uint8_t G1M_test_2[] = {
|
||||
0x51, 0x61, // mov a, #'a'
|
||||
0xfc, 0xdc, 0xff, 0x0e, // call !!tool_tx
|
||||
0xd7, // ret
|
||||
};
|
||||
|
||||
|
||||
//static uint8_t DATA_test_dbg[7/*85*/] = {
|
||||
// /*0xe0, 0x07, 0x52,*/ 0x51, 0x61, 0xfc, 0xa1, 0xff, 0x0e,
|
||||
// 0xd7,
|
||||
|
@ -207,15 +218,52 @@ void cli_tool78_g10_ocdtest(void) {
|
|||
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
struct tool78_hw* hw = &tool78_hw_rl78g10_uart1;
|
||||
|
||||
int st = tool78_init_ocd(hw, NULL, passwd);
|
||||
printf("init: %02x\n", st);
|
||||
int st, rr;
|
||||
uint8_t checkbuf[2];
|
||||
while (true) {
|
||||
st = tool78_init_ocd(hw, NULL, passwd);
|
||||
if (st == 0xc3) {
|
||||
rr = hw->recv(1, &st, 120*1000*1000);
|
||||
if (rr != 1) {
|
||||
printf("aaaa\n");
|
||||
goto deinit_bad;
|
||||
}
|
||||
} else {
|
||||
printf("result: 0x%02x\n", st);
|
||||
if (st != 0xf2 && st != 0xf0) {
|
||||
printf("init: %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t val = 0;
|
||||
st = tool78_ocd_read(hw, 0x0080, 1, &val);
|
||||
printf("read: st=%d val=%02x\n", st, val);
|
||||
|
||||
st = tool78_ocd_write(hw, 0xfed0, sizeof G1M_test_1, G1M_test_1);
|
||||
printf("write1: st=%d\n", st);
|
||||
st = tool78_ocd_exec(hw);
|
||||
printf("exec1: st=%d\n", st);
|
||||
|
||||
st = tool78_ocd_write(hw, 0xfed0, sizeof G1M_test_2, G1M_test_2);
|
||||
printf("write2: st=%d\n", st);
|
||||
st = tool78_ocd_exec(hw);
|
||||
printf("exec2: st=%d\n", st);
|
||||
|
||||
// wait for completion
|
||||
rr = hw->recv(2, checkbuf, 1000*1000);
|
||||
if (rr != 2) {
|
||||
printf("exec code: no response :/ (%d)\n", rr);
|
||||
goto deinit_bad;
|
||||
}
|
||||
printf("result: '%c' (0x%02x)\n", checkbuf[0], checkbuf[0]);
|
||||
|
||||
|
||||
busy_wait_ms(1000);
|
||||
|
||||
deinit_bad:
|
||||
hw->deinit();
|
||||
}
|
||||
|
||||
|
|
|
@ -1167,7 +1167,7 @@ int tool78_ocd_connect(struct tool78_hw* hw, const uint8_t passwd[10]) {
|
|||
}
|
||||
int tool78_ocd_read(struct tool78_hw* hw, uint16_t off, uint8_t len,
|
||||
uint8_t* data) {
|
||||
busy_wait_us(300);//busy_wait_ms(1);
|
||||
busy_wait_ms(1);
|
||||
|
||||
bool is_g10 = (hw->target & tool78_mcu_mask) == tool78_mcu_rl78g10;
|
||||
|
||||
|
@ -1325,6 +1325,8 @@ int tool78_ocd_write(struct tool78_hw* hw, uint16_t addr, uint8_t len,
|
|||
|
||||
// command echoed back
|
||||
rr = hw->recv(4, hdr, 1000);
|
||||
/*printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);*/
|
||||
if (rr != 4) return -2;
|
||||
if (hdr[0] == 0xff) { // frame error bullshit
|
||||
hdr[0] = hdr[1];
|
||||
|
@ -1333,24 +1335,45 @@ int tool78_ocd_write(struct tool78_hw* hw, uint16_t addr, uint8_t len,
|
|||
rr = hw->recv(1, &hdr[3], 1000);
|
||||
if (rr != 1) return -2;
|
||||
}
|
||||
/*printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);*/
|
||||
|
||||
// status
|
||||
rr = hw->recv(1, hdr, 1000);
|
||||
/*printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);*/
|
||||
if (rr != 1) return -1;
|
||||
if (hdr[0] == len) {
|
||||
rr = hw->recv(1, hdr, 1000);
|
||||
/*printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);*/
|
||||
if (rr != 1) return -1;
|
||||
}
|
||||
if (hdr[0] != 0x00) return -3;
|
||||
|
||||
hdr[0] = tool78ocd_cmdg10_write_raw;
|
||||
|
||||
rr = hw->send(1, hdr, -1);
|
||||
if (rr != 1) return -1;
|
||||
rr = hw->recv(1, hdr, 1000); // sigh
|
||||
if (rr != 1) return -1;
|
||||
/*printf("wr p3: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);*/
|
||||
|
||||
rr = hw->send(len, data, -1);
|
||||
if (rr != len) return -1;
|
||||
rr = hw->recv(len, NULL, 1000*len); // sigh
|
||||
if (rr != len) return -1;
|
||||
/*printf("wr p4: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);*/
|
||||
|
||||
rr = hw->recv(2, hdr, 1000*len);
|
||||
if (rr != 2) return -1;
|
||||
rr = hw->recv(1, hdr, 1000);
|
||||
/*printf("wr p5: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);
|
||||
printf("recv %d: %02x %02x\n", rr, hdr[0], hdr[1]);*/
|
||||
if (rr != 1) return -1;
|
||||
|
||||
return (hdr[1] == 0) ? 0 : -2;
|
||||
return (hdr[0] == 0) ? 0 : -2;
|
||||
}
|
||||
} else {
|
||||
hdr[0] = tool78ocd_cmd_write;
|
||||
|
@ -1380,11 +1403,11 @@ int tool78_ocd_exec(struct tool78_hw* hw) {
|
|||
|
||||
int rr = hw->send(1, hdr, -1);
|
||||
|
||||
rr = hw->recv(2, hdr, 1000);
|
||||
rr = hw->recv(1, hdr, 1000);
|
||||
if (rr != 1 && rr != 2) return -1;
|
||||
//printf("h[0]=0x%02x, h[1]=0x%02x\n", hdr[0], hdr[1]);
|
||||
|
||||
return (hdr[0] == cmd) ? 0 : -2;
|
||||
return 0;//(hdr[0] == cmd) ? 0 : -2;
|
||||
}
|
||||
int tool78_ocd_leave(struct tool78_hw* hw, bool exit_to_ram) {
|
||||
busy_wait_ms(1);
|
||||
|
@ -1455,9 +1478,11 @@ static enum tool78_stat tool78_init_common(struct tool78_hw* hw) {
|
|||
//printf("init rr:%d st=%02x\n", rr, st);
|
||||
if (rr != 2) return tool78_stat_timeout_error;
|
||||
|
||||
// should be 5 zero bytes, but let's not check
|
||||
rr = hw->recv(5, data, 1000*1000);
|
||||
if (rr != 5) return tool78_stat_timeout_error;
|
||||
if (st == 0x06) {
|
||||
// should be 5 zero bytes, but let's not check
|
||||
rr = hw->recv(5, data, 5*1000);
|
||||
if (rr != 5) return tool78_stat_no_ocd_status;
|
||||
}
|
||||
}
|
||||
|
||||
return st;
|
||||
|
|
|
@ -122,6 +122,7 @@ enum tool78_stat {
|
|||
tool78_stat_fatal_hw_error = 0xc4,
|
||||
tool78_stat_parity_error = 0xc5,
|
||||
tool78_stat_bad_flash_size = 0xc6,
|
||||
tool78_stat_no_ocd_status = 0xc7,
|
||||
|
||||
// TODO: OCD status stuff (for 0x91)
|
||||
};
|
||||
|
|
|
@ -126,8 +126,13 @@ int tool78_hw_help_recv(const struct tool78_pio_vars* vars,
|
|||
// TODO: sleep a bit? idk
|
||||
}
|
||||
|
||||
data[i] = *(volatile uint8_t*)&PINOUT_TOOL78_PIO->rxf[vars->smrx];
|
||||
if (vars->bitswap) data[i] = bitswap(data[i]);
|
||||
uint8_t v = *(volatile uint8_t*)&PINOUT_TOOL78_PIO->rxf[vars->smrx];
|
||||
if (data) {
|
||||
data[i] = v;
|
||||
if (vars->bitswap) data[i] = bitswap(data[i]);
|
||||
} else {
|
||||
(void)v;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
|
|
|
@ -5,7 +5,7 @@ OBJCOPY := rl78-elf-objcopy
|
|||
|
||||
all: test-rom.srec test-dbg.srec test-rom.bin test-dbg.bin
|
||||
|
||||
test.S.o: test.S
|
||||
test.S.o: test.S hw.S
|
||||
$(AS) -c -o "$@" "$<"
|
||||
romhdr.S.o: romhdr.S
|
||||
$(AS) -c -o "$@" "$<"
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
|
||||
#include "hw.S"
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
/*mov es, #0*/
|
||||
movw sp, #0xfed0
|
||||
|
||||
; IAWCTL = 0 -> none?
|
||||
|
||||
|
||||
call !siniport
|
||||
call !siniclk
|
||||
;call !sinitau
|
||||
;call !siniuart0
|
||||
call !main
|
||||
|
||||
delay_long:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
delay_data:
|
||||
nop
|
||||
ret
|
||||
|
||||
|
||||
tx_byte:
|
||||
; start condition
|
||||
clr1 P0.0
|
||||
call !delay_long ;27 cyc = 4 cyc + 16 cyc + 7 cyc
|
||||
|
||||
; data bits
|
||||
mov c, #8 ; 1 cyc
|
||||
.Lbitloop:
|
||||
|
||||
; set 1 bit
|
||||
bf a.0, $.Lsetlo ; 3 cyc hi // 5 cyc lo
|
||||
.Lsethi:
|
||||
nop ; 1 cyc hi //
|
||||
nop ; 1 cyc hi //
|
||||
set1 P0.0 ; 2 cyc hi //
|
||||
br $.Lafterset ; 3 cyc hi //
|
||||
.Lsetlo:
|
||||
clr1 P0.0 ; // 2 cyc lo
|
||||
nop ; // 1 cyc lo
|
||||
nop ; // 1 cyc lo
|
||||
nop ; // 1 cyc lo
|
||||
.Lafterset:
|
||||
; delay
|
||||
call !delay_data ;12 cyc
|
||||
|
||||
; next bit
|
||||
shr a, 1 ; 1 cyc
|
||||
dec c ; 1 cyc
|
||||
bnz $.Lbitloop ; 4 cyc
|
||||
|
||||
; stop condition
|
||||
set1 P0.0
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
ret
|
||||
|
||||
|
||||
main:
|
||||
set1 P0.0
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
loop:
|
||||
mov es, #0xe
|
||||
|
||||
;movw bc, #0x0200
|
||||
mov c, #0
|
||||
movw hl, #0xfe00
|
||||
innerloop:
|
||||
mov a, es:[hl]
|
||||
push ax
|
||||
push bc
|
||||
call !tx_byte
|
||||
pop bc
|
||||
pop ax
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
incw hl
|
||||
;decw bc
|
||||
;cmpw bc, #0
|
||||
dec c
|
||||
cmp0 c
|
||||
bnz $innerloop
|
||||
|
||||
;movw bc, #0x0200
|
||||
mov c, #0
|
||||
;movw hl, #0xfe00
|
||||
innerloop2:
|
||||
mov a, es:[hl]
|
||||
push ax
|
||||
push bc
|
||||
call !tx_byte
|
||||
pop bc
|
||||
pop ax
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
incw hl
|
||||
;decw bc
|
||||
;cmpw bc, #0
|
||||
dec c
|
||||
cmp0 c
|
||||
bnz $innerloop2
|
||||
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
mov a, #'E'
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
mov a, #'N'
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
mov a, #'D'
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
mov a, #' '
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
br !loop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mov a, #' '
|
||||
call !tx_byte
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
;set1 P0.0
|
||||
|
||||
br !loop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
siniport:
|
||||
; P00 GPIO
|
||||
; P06 TxD0
|
||||
mov !PIOR, #0
|
||||
|
||||
; set P0 as output
|
||||
mov !P0, #0
|
||||
|
||||
; disable pullups
|
||||
mov !PU0, #0
|
||||
|
||||
; push-pull output
|
||||
mov !POM0, #0
|
||||
|
||||
; not analog in
|
||||
mov !PMC0, #0x7f
|
||||
|
||||
; set port modes
|
||||
;mov !PM0, #0x0f ; P00 GPIO ; P06 TxD0
|
||||
mov !PM0, #0
|
||||
|
||||
ret
|
||||
|
||||
|
||||
siniclk:
|
||||
mov !PER0, #0xe5 ; enable many peripherals
|
||||
mov !OSMC, #0x10
|
||||
;mov !HOCODIV, #1
|
||||
ret
|
||||
|
|
@ -18,6 +18,8 @@
|
|||
/*#define PD1 0x0075*/
|
||||
#define PIOR 0xf0077
|
||||
|
||||
#define tool_tx 0xeffdc
|
||||
|
||||
/*#define CMC 0xfffa0
|
||||
#define CSC 0xfffa1
|
||||
#define CKC 0xfffa4*/
|
||||
|
|
|
@ -3,252 +3,64 @@
|
|||
|
||||
.global _start
|
||||
_start:
|
||||
/*mov es, #0*/
|
||||
movw sp, #0xfed0
|
||||
movw sp, #0xfe00
|
||||
;di
|
||||
|
||||
; IAWCTL = 0 -> none?
|
||||
|
||||
|
||||
call !siniport
|
||||
call !siniclk
|
||||
;call !sinitau
|
||||
;call !siniuart0
|
||||
call !main
|
||||
|
||||
delay_long:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
delay_data:
|
||||
nop
|
||||
ret
|
||||
|
||||
|
||||
tx_byte:
|
||||
; start condition
|
||||
clr1 P0.0
|
||||
call !delay_long ;27 cyc = 4 cyc + 16 cyc + 7 cyc
|
||||
|
||||
; data bits
|
||||
mov c, #8 ; 1 cyc
|
||||
.Lbitloop:
|
||||
|
||||
; set 1 bit
|
||||
bf a.0, $.Lsetlo ; 3 cyc hi // 5 cyc lo
|
||||
.Lsethi:
|
||||
nop ; 1 cyc hi //
|
||||
nop ; 1 cyc hi //
|
||||
set1 P0.0 ; 2 cyc hi //
|
||||
br $.Lafterset ; 3 cyc hi //
|
||||
.Lsetlo:
|
||||
clr1 P0.0 ; // 2 cyc lo
|
||||
nop ; // 1 cyc lo
|
||||
nop ; // 1 cyc lo
|
||||
nop ; // 1 cyc lo
|
||||
.Lafterset:
|
||||
; delay
|
||||
call !delay_data ;12 cyc
|
||||
|
||||
; next bit
|
||||
shr a, 1 ; 1 cyc
|
||||
dec c ; 1 cyc
|
||||
bnz $.Lbitloop ; 4 cyc
|
||||
|
||||
; stop condition
|
||||
set1 P0.0
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
ret
|
||||
|
||||
|
||||
main:
|
||||
set1 P0.0
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
loop:
|
||||
mov es, #0xe
|
||||
|
||||
;movw bc, #0x0200
|
||||
mov c, #0
|
||||
movw hl, #0xfe00
|
||||
innerloop:
|
||||
mov a, es:[hl]
|
||||
push ax
|
||||
push bc
|
||||
call !tx_byte
|
||||
pop bc
|
||||
pop ax
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
incw hl
|
||||
;decw bc
|
||||
;cmpw bc, #0
|
||||
dec c
|
||||
cmp0 c
|
||||
bnz $innerloop
|
||||
|
||||
;movw bc, #0x0200
|
||||
mov c, #0
|
||||
;movw hl, #0xfe00
|
||||
innerloop2:
|
||||
mov a, es:[hl]
|
||||
push ax
|
||||
push bc
|
||||
call !tx_byte
|
||||
pop bc
|
||||
pop ax
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
incw hl
|
||||
;decw bc
|
||||
;cmpw bc, #0
|
||||
dec c
|
||||
cmp0 c
|
||||
bnz $innerloop2
|
||||
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
mov a, #'E'
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
mov a, #'N'
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
mov a, #'D'
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
mov a, #' '
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
br !loop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mov a, #' '
|
||||
call !tx_byte
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
call !delay_long
|
||||
;set1 P0.0
|
||||
|
||||
br !loop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
siniport:
|
||||
; P00 GPIO
|
||||
; P06 TxD0
|
||||
mov !PIOR, #0
|
||||
|
||||
; set P0 as output
|
||||
mov !P0, #0
|
||||
|
||||
; disable pullups
|
||||
mov !PU0, #0
|
||||
|
||||
; push-pull output
|
||||
mov !POM0, #0
|
||||
|
||||
; not analog in
|
||||
mov !PMC0, #0x7f
|
||||
|
||||
; set port modes
|
||||
;mov !PM0, #0x0f ; P00 GPIO ; P06 TxD0
|
||||
mov !PM0, #0
|
||||
|
||||
ret
|
||||
|
||||
|
||||
siniclk:
|
||||
mov !PER0, #0xe5 ; enable many peripherals
|
||||
mov !OSMC, #0x10
|
||||
;mov !HOCODIV, #1
|
||||
ret
|
||||
mov a, #'a'
|
||||
call !!tool_tx
|
||||
br !!0xeffba
|
||||
|
||||
; mov !PIOR, #0
|
||||
; mov P0, #0
|
||||
; mov !PU0, #0
|
||||
; mov !POM0, #0
|
||||
; mov !PMC0, #0x7f
|
||||
; mov !PM0, #0
|
||||
;
|
||||
; mov !PER0, #0xe5 ; enable peripherals
|
||||
; mov !OSMC, #0x10
|
||||
;
|
||||
;looper:
|
||||
; mov P0, #0xff
|
||||
; ;movw ax, #0xfae0
|
||||
;
|
||||
;/* mov hl, ax
|
||||
; mov c, #0
|
||||
;
|
||||
;1: mov b, #0xff
|
||||
; mov a, #0xff
|
||||
;
|
||||
;2: inc a
|
||||
; dec b
|
||||
; bnz 2b
|
||||
;
|
||||
; mov [hl+c], a
|
||||
; dec c
|
||||
; bnz 1b
|
||||
;
|
||||
; mov P0, #0
|
||||
;
|
||||
; mov c, #0x18
|
||||
;3: mov b, #0xff
|
||||
;4: dec b
|
||||
; bnz 4b
|
||||
; dec c
|
||||
; bnz 3b*/
|
||||
;
|
||||
; mov a, #0x48
|
||||
; call !!tool_tx
|
||||
; mov a, #0x69
|
||||
; call !!tool_tx
|
||||
;
|
||||
;/* mov x, #0xaa
|
||||
; mov c, #0
|
||||
;
|
||||
;5: dec c
|
||||
; mov a, [hl+c]
|
||||
; xor a, x
|
||||
; call !!tool_tx
|
||||
; cmp0 c
|
||||
; bnz 5b
|
||||
; br $looper*/
|
||||
;
|
||||
; ret
|
||||
|
|
Loading…
Reference in New Issue