jtaglib: fix register reading on MSP430G2452 and similar chips

This commit is contained in:
Triss 2021-10-09 23:19:23 +02:00
parent cba3cd4f33
commit a5252e13f6
3 changed files with 95 additions and 20 deletions

View File

@ -1015,17 +1015,25 @@ address_t jtag_read_reg(struct jtdev *p, int reg)
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); /* older code did an extra clock cycle -- don't do this! will put the
jtag_tclk_set(p); * current instruction word on the data bus instead of the register value
* on the G2452, making it useless. the clock cycles are still required to
* move to the next instruction, but those should be done later. */
/*jtag_tclk_clr(p);
jtag_tclk_set(p);*/
/* Read databus which contains the registers value */ /* Read databus which contains the registers value */
jtag_ir_shift(p, IR_DATA_CAPTURE); jtag_ir_shift(p, IR_DATA_CAPTURE);
value = jtag_dr_shift_16(p, 0x0000); value = jtag_dr_shift_16(p, 0x0000);
jtag_tclk_clr(p);
/* JTAG controls RW & BYTE */ /* JTAG controls RW & BYTE */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift_16(p, 0x2401); jtag_dr_shift_16(p, 0x2401);
jtag_tclk_set(p);
/* Return value read from register */ /* Return value read from register */
return value; return value;
} }

View File

@ -219,6 +219,10 @@ static const struct jtdev_func jtdev_func_mehfet = {
static int read_words(device_t dev_base, const struct chipinfo_memory *m, static int read_words(device_t dev_base, const struct chipinfo_memory *m,
address_t addr, address_t len, uint8_t *data) address_t addr, address_t len, uint8_t *data)
{ {
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: read_words: addr=0x%04x, len=0x%x\n", addr, len);
#endif
struct mehfet_device* dev = (struct mehfet_device*)dev_base; struct mehfet_device* dev = (struct mehfet_device*)dev_base;
struct jtdev *p = &dev->jtag; struct jtdev *p = &dev->jtag;
@ -268,9 +272,20 @@ static int write_words(device_t dev_base, const struct chipinfo_memory *m,
int r; int r;
if (m->type != CHIPINFO_MEMTYPE_FLASH) { if (m->type != CHIPINFO_MEMTYPE_FLASH) {
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: write_words: addr=0x%04x, len=0x%x data=0x%04x\n",
addr, len, r16le(data));
if (len != 2) {
printc_dbg("mehfet: WARN: write_words: len != 2! but 0x%04x\n", len);
__builtin_trap();
}
#endif
len = 2; len = 2;
r = write_ram_word(p, addr, r16le(data)); r = write_ram_word(p, addr, r16le(data));
} else { } else {
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: write_flash_block: addr=0x%04x, len=0x%x\n", addr, len);
#endif
r = write_flash_block(p, addr, len, data); r = write_flash_block(p, addr, len, data);
} }
@ -306,7 +321,13 @@ static int mehfet_setregs(device_t dev_base, const address_t *regs)
dev->jtag.failed = 0; dev->jtag.failed = 0;
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: set regs\n");
#endif
for (int i = 0; i < DEVICE_NUM_REGS; i++) { for (int i = 0; i < DEVICE_NUM_REGS; i++) {
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: [%d] = 0x%04x\n", i, regs[i]);
#endif
jtag_write_reg(&dev->jtag, i, regs[i]); jtag_write_reg(&dev->jtag, i, regs[i]);
} }
return dev->jtag.failed ? -1 : 0; return dev->jtag.failed ? -1 : 0;
@ -318,8 +339,15 @@ static int mehfet_getregs(device_t dev_base, address_t *regs)
dev->jtag.failed = 0; dev->jtag.failed = 0;
for (int i = 0; i < DEVICE_NUM_REGS; i++) #ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: get regs\n");
#endif
for (int i = 0; i < DEVICE_NUM_REGS; i++) {
regs[i] = jtag_read_reg(&dev->jtag, i); regs[i] = jtag_read_reg(&dev->jtag, i);
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: [%d] = 0x%04x\n", i, regs[i]);
#endif
}
return dev->jtag.failed ? -1 : 0; return dev->jtag.failed ? -1 : 0;
} }
@ -333,29 +361,44 @@ static int mehfet_ctl(device_t dev_base, device_ctl_t type)
switch (type) { switch (type) {
case DEVICE_CTL_RESET: case DEVICE_CTL_RESET:
/* perform soft reset */ /* perform soft reset */
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: soft reset (PUC)\n");
#endif
jtag_execute_puc(&dev->jtag); jtag_execute_puc(&dev->jtag);
break; break;
case DEVICE_CTL_RUN: case DEVICE_CTL_RUN:
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: set breakpoints\n");
#endif
/* transfer changed breakpoints to device */ /* transfer changed breakpoints to device */
if (jtag_refresh_bps("mehfet", &dev->base, &dev->jtag) < 0) return -1; if (jtag_refresh_bps("mehfet", &dev->base, &dev->jtag) < 0) return -1;
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: run @ current PC\n");
#endif
/* start program execution at current PC */ /* start program execution at current PC */
jtag_release_device(&dev->jtag, 0xffff); jtag_release_device(&dev->jtag, 0xffff);
break; break;
case DEVICE_CTL_HALT: case DEVICE_CTL_HALT:
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: halt\n");
#endif
/* take device under JTAG control */ /* take device under JTAG control */
jtag_get_device(&dev->jtag); jtag_get_device(&dev->jtag);
break; break;
case DEVICE_CTL_STEP: case DEVICE_CTL_STEP:
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: single-step\n");
#endif
/* execute next instruction at current PC */ /* execute next instruction at current PC */
jtag_single_step(&dev->jtag); jtag_single_step(&dev->jtag);
break; break;
default: default:
printc_err("mehfet: unsupported operation\n"); printc_err("mehfet: unsupported operation %d\n", type);
return -1; return -1;
} }
@ -369,7 +412,13 @@ static device_status_t mehfet_poll(device_t dev_base)
if (delay_ms(100) < 0 || ctrlc_check()) if (delay_ms(100) < 0 || ctrlc_check())
return DEVICE_STATUS_INTR; return DEVICE_STATUS_INTR;
if (jtag_cpu_state(&dev->jtag) == 1) return DEVICE_STATUS_HALTED; int r = jtag_cpu_state(&dev->jtag);
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: cpu state: %d\n", r);
#endif
if (r == 1) return DEVICE_STATUS_HALTED;
return DEVICE_STATUS_RUNNING; return DEVICE_STATUS_RUNNING;
} }
@ -394,6 +443,10 @@ static int mehfet_erase(device_t dev_base, device_erase_type_t type,
default: return -1; default: return -1;
} }
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: erase flash %d at %04x: %s\n", type, addr, dev->jtag.failed ? "failed" : "succeeded");
#endif
return dev->jtag.failed ? -1 : 0; return dev->jtag.failed ? -1 : 0;
} }
@ -401,7 +454,13 @@ static int mehfet_getconfigfuses(device_t dev_base)
{ {
struct mehfet_device* dev = (struct mehfet_device*)dev_base; struct mehfet_device* dev = (struct mehfet_device*)dev_base;
return jtag_get_config_fuses(&dev->jtag); int r = jtag_get_config_fuses(&dev->jtag);
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: get_config_fuses: %d\n", r);
#endif
return r;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -490,6 +549,10 @@ static void mehfet_destroy(device_t dev_base) {
if (!dev) return; if (!dev) return;
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: releasing device & disconnecting\n");
#endif
jtag_release_device(&dev->jtag, 0xfffe); // 0xfffe=reset address : POR jtag_release_device(&dev->jtag, 0xfffe); // 0xfffe=reset address : POR
mehfet_cmd_disconnect(dev->trans); mehfet_cmd_disconnect(dev->trans);
@ -548,6 +611,10 @@ static device_t mehfet_open(const struct device_args* args) {
r = init_device(dev); r = init_device(dev);
if (r < 0) goto FAIL; if (r < 0) goto FAIL;
#ifdef DEBUG_MEHFET_DRIVER
printc_dbg("mehfet: device opened\n");
#endif
return (device_t)dev; return (device_t)dev;
FAIL: FAIL:

View File

@ -64,7 +64,7 @@ int mehfet_cmd_info(transport_t t, struct mehfet_info* info) {
info->devicename = str; info->devicename = str;
} }
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: Info(): '%s' caps=0x%x, protover=0x%04x, pktsize=0x%x\n", printc_dbg("mehfet: Info(): '%s' caps=0x%x, protover=0x%04x, pktsize=0x%x\n",
info->devicename ? info->devicename : "<none>", info->devicename ? info->devicename : "<none>",
info->caps, info->proto_version, info->packet_buf_size); info->caps, info->proto_version, info->packet_buf_size);
@ -95,7 +95,7 @@ int mehfet_cmd_status(transport_t t, enum mehfet_conn* ret) {
*ret = buf[0]; *ret = buf[0];
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: Status(): %hhu\n", *ret); printc_dbg("mehfet: Status(): %hhu\n", *ret);
#endif #endif
@ -121,7 +121,7 @@ int mehfet_cmd_connect(transport_t t, enum mehfet_conn conn) {
return -1; return -1;
} }
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: Connect(0x%x)\n", conn); printc_dbg("mehfet: Connect(0x%x)\n", conn);
#endif #endif
@ -146,7 +146,7 @@ int mehfet_cmd_disconnect(transport_t t) {
return -1; return -1;
} }
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: Disconnect()\n"); printc_dbg("mehfet: Disconnect()\n");
#endif #endif
@ -177,7 +177,7 @@ int mehfet_cmd_delay(transport_t t, bool us, bool exact, uint32_t time) {
return -1; return -1;
} }
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: Delay(us=%c exact=%c time=%u)\n", printc_dbg("mehfet: Delay(us=%c exact=%c time=%u)\n",
us?'t':'f', exact?'t':'f', time); us?'t':'f', exact?'t':'f', time);
#endif #endif
@ -204,7 +204,7 @@ int mehfet_cmd_set_clkspeed(transport_t t, bool fast) {
return -1; return -1;
} }
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: SetClkSpeed(%s)\n", fast?"fast":"slow"); printc_dbg("mehfet: SetClkSpeed(%s)\n", fast?"fast":"slow");
#endif #endif
@ -233,7 +233,7 @@ int mehfet_cmd_get_old_lines(transport_t t, enum mehfet_lines* lines) {
*lines = buf[0]; *lines = buf[0];
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: GetOldLines(): 0x%x\n", *lines); printc_dbg("mehfet: GetOldLines(): 0x%x\n", *lines);
#endif #endif
@ -269,7 +269,7 @@ int mehfet_cmd_tdio_seq(transport_t t, uint32_t nbits, bool tms, const uint8_t*
memcpy(tdo, buf, nbytes); memcpy(tdo, buf, nbytes);
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: TdioSequence(%u, TMS=%c):\n", nbits, tms?'1':'0'); printc_dbg("mehfet: TdioSequence(%u, TMS=%c):\n", nbits, tms?'1':'0');
debug_hexdump("\tTDI", tdi, nbytes); debug_hexdump("\tTDI", tdi, nbytes);
debug_hexdump("\tTDO", tdo, nbytes); debug_hexdump("\tTDO", tdo, nbytes);
@ -303,7 +303,7 @@ int mehfet_cmd_tms_seq(transport_t t, uint32_t nbits, bool tdi, const uint8_t* t
return -1; return -1;
} }
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: TmsSequence(%u, TDI=%c):\n", nbits, tdi?'1':'0'); printc_dbg("mehfet: TmsSequence(%u, TDI=%c):\n", nbits, tdi?'1':'0');
debug_hexdump("\tTMS", tms, nbytes); debug_hexdump("\tTMS", tms, nbytes);
#endif #endif
@ -330,7 +330,7 @@ int mehfet_cmd_tclk_edge(transport_t t, bool newtclk) {
return -1; return -1;
} }
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: TclkEdge(TCLK=%c)\n", newtclk?'H':'L'); printc_dbg("mehfet: TclkEdge(TCLK=%c)\n", newtclk?'H':'L');
#endif #endif
@ -356,7 +356,7 @@ int mehfet_cmd_tclk_burst(transport_t t, uint32_t ncyc) {
return -1; return -1;
} }
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: TclkBurst(ncyc=%u)\n", ncyc); printc_dbg("mehfet: TclkBurst(ncyc=%u)\n", ncyc);
#endif #endif
@ -388,7 +388,7 @@ int mehfet_cmd_reset_tap(transport_t t, enum mehfet_resettap_flags flags,
*tstat = buf[0]; *tstat = buf[0];
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: ResetTAP(flags=0x%x) = 0x%x\n", flags, *tstat); printc_dbg("mehfet: ResetTAP(flags=0x%x) = 0x%x\n", flags, *tstat);
#endif #endif
@ -430,7 +430,7 @@ int mehfet_cmd_irshift(transport_t t, uint8_t newir, uint8_t* oldir) {
*oldir = buf[0]; *oldir = buf[0];
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: IRshift(new=0x%02x) = 0x%02x\n", newir, *oldir); printc_dbg("mehfet: IRshift(new=0x%02x) = 0x%02x\n", newir, *oldir);
#endif #endif
@ -462,7 +462,7 @@ int mehfet_cmd_drshift(transport_t t, uint32_t nbits, const uint8_t* newdr, uint
memcpy(olddr, buf, nbytes); memcpy(olddr, buf, nbytes);
#ifdef DEBUG_MEHFET_DRIVER #ifdef DEBUG_MEHFET_PROTO_DRIVER
printc_dbg("mehfet: DRshift(nbits=%u):\n", nbits); printc_dbg("mehfet: DRshift(nbits=%u):\n", nbits);
debug_hexdump("\tin ", newdr, nbytes); debug_hexdump("\tin ", newdr, nbytes);
debug_hexdump("\tout", olddr, nbytes); debug_hexdump("\tout", olddr, nbytes);