From a5252e13f6447fa6e9a48c7b2383e77f68530463 Mon Sep 17 00:00:00 2001 From: sys64738 Date: Sat, 9 Oct 2021 23:19:23 +0200 Subject: [PATCH] jtaglib: fix register reading on MSP430G2452 and similar chips --- drivers/jtaglib.c | 12 +++++-- drivers/mehfet.c | 75 +++++++++++++++++++++++++++++++++++++++--- drivers/mehfet_proto.c | 28 ++++++++-------- 3 files changed, 95 insertions(+), 20 deletions(-) diff --git a/drivers/jtaglib.c b/drivers/jtaglib.c index 7215d1c..4e9e6c8 100644 --- a/drivers/jtaglib.c +++ b/drivers/jtaglib.c @@ -1015,17 +1015,25 @@ address_t jtag_read_reg(struct jtdev *p, int reg) jtag_tclk_set(p); jtag_tclk_clr(p); jtag_tclk_set(p); - jtag_tclk_clr(p); - jtag_tclk_set(p); + /* older code did an extra clock cycle -- don't do this! will put the + * 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 */ jtag_ir_shift(p, IR_DATA_CAPTURE); value = jtag_dr_shift_16(p, 0x0000); + jtag_tclk_clr(p); + /* JTAG controls RW & BYTE */ jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_dr_shift_16(p, 0x2401); + jtag_tclk_set(p); + /* Return value read from register */ return value; } diff --git a/drivers/mehfet.c b/drivers/mehfet.c index 58e76c5..4ad2d99 100644 --- a/drivers/mehfet.c +++ b/drivers/mehfet.c @@ -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, 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 jtdev *p = &dev->jtag; @@ -268,9 +272,20 @@ static int write_words(device_t dev_base, const struct chipinfo_memory *m, int r; 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; r = write_ram_word(p, addr, r16le(data)); } 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); } @@ -306,7 +321,13 @@ static int mehfet_setregs(device_t dev_base, const address_t *regs) dev->jtag.failed = 0; +#ifdef DEBUG_MEHFET_DRIVER + printc_dbg("mehfet: set regs\n"); +#endif 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]); } 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; - 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); +#ifdef DEBUG_MEHFET_DRIVER + printc_dbg("mehfet: [%d] = 0x%04x\n", i, regs[i]); +#endif + } return dev->jtag.failed ? -1 : 0; } @@ -333,29 +361,44 @@ static int mehfet_ctl(device_t dev_base, device_ctl_t type) switch (type) { case DEVICE_CTL_RESET: /* perform soft reset */ +#ifdef DEBUG_MEHFET_DRIVER + printc_dbg("mehfet: soft reset (PUC)\n"); +#endif jtag_execute_puc(&dev->jtag); break; case DEVICE_CTL_RUN: +#ifdef DEBUG_MEHFET_DRIVER + printc_dbg("mehfet: set breakpoints\n"); +#endif /* transfer changed breakpoints to device */ 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 */ jtag_release_device(&dev->jtag, 0xffff); break; case DEVICE_CTL_HALT: +#ifdef DEBUG_MEHFET_DRIVER + printc_dbg("mehfet: halt\n"); +#endif /* take device under JTAG control */ jtag_get_device(&dev->jtag); break; case DEVICE_CTL_STEP: +#ifdef DEBUG_MEHFET_DRIVER + printc_dbg("mehfet: single-step\n"); +#endif /* execute next instruction at current PC */ jtag_single_step(&dev->jtag); break; default: - printc_err("mehfet: unsupported operation\n"); + printc_err("mehfet: unsupported operation %d\n", type); return -1; } @@ -369,7 +412,13 @@ static device_status_t mehfet_poll(device_t dev_base) if (delay_ms(100) < 0 || ctrlc_check()) 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; } @@ -394,6 +443,10 @@ static int mehfet_erase(device_t dev_base, device_erase_type_t type, 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; } @@ -401,7 +454,13 @@ static int mehfet_getconfigfuses(device_t 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; +#ifdef DEBUG_MEHFET_DRIVER + printc_dbg("mehfet: releasing device & disconnecting\n"); +#endif + jtag_release_device(&dev->jtag, 0xfffe); // 0xfffe=reset address : POR mehfet_cmd_disconnect(dev->trans); @@ -548,6 +611,10 @@ static device_t mehfet_open(const struct device_args* args) { r = init_device(dev); if (r < 0) goto FAIL; +#ifdef DEBUG_MEHFET_DRIVER + printc_dbg("mehfet: device opened\n"); +#endif + return (device_t)dev; FAIL: diff --git a/drivers/mehfet_proto.c b/drivers/mehfet_proto.c index ff25d80..b820e09 100644 --- a/drivers/mehfet_proto.c +++ b/drivers/mehfet_proto.c @@ -64,7 +64,7 @@ int mehfet_cmd_info(transport_t t, struct mehfet_info* info) { 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", info->devicename ? info->devicename : "", 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]; -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: Status(): %hhu\n", *ret); #endif @@ -121,7 +121,7 @@ int mehfet_cmd_connect(transport_t t, enum mehfet_conn conn) { return -1; } -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: Connect(0x%x)\n", conn); #endif @@ -146,7 +146,7 @@ int mehfet_cmd_disconnect(transport_t t) { return -1; } -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: Disconnect()\n"); #endif @@ -177,7 +177,7 @@ int mehfet_cmd_delay(transport_t t, bool us, bool exact, uint32_t time) { return -1; } -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: Delay(us=%c exact=%c time=%u)\n", us?'t':'f', exact?'t':'f', time); #endif @@ -204,7 +204,7 @@ int mehfet_cmd_set_clkspeed(transport_t t, bool fast) { return -1; } -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: SetClkSpeed(%s)\n", fast?"fast":"slow"); #endif @@ -233,7 +233,7 @@ int mehfet_cmd_get_old_lines(transport_t t, enum mehfet_lines* lines) { *lines = buf[0]; -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: GetOldLines(): 0x%x\n", *lines); #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); -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: TdioSequence(%u, TMS=%c):\n", nbits, tms?'1':'0'); debug_hexdump("\tTDI", tdi, 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; } -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: TmsSequence(%u, TDI=%c):\n", nbits, tdi?'1':'0'); debug_hexdump("\tTMS", tms, nbytes); #endif @@ -330,7 +330,7 @@ int mehfet_cmd_tclk_edge(transport_t t, bool newtclk) { return -1; } -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: TclkEdge(TCLK=%c)\n", newtclk?'H':'L'); #endif @@ -356,7 +356,7 @@ int mehfet_cmd_tclk_burst(transport_t t, uint32_t ncyc) { return -1; } -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: TclkBurst(ncyc=%u)\n", ncyc); #endif @@ -388,7 +388,7 @@ int mehfet_cmd_reset_tap(transport_t t, enum mehfet_resettap_flags flags, *tstat = buf[0]; -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: ResetTAP(flags=0x%x) = 0x%x\n", flags, *tstat); #endif @@ -430,7 +430,7 @@ int mehfet_cmd_irshift(transport_t t, uint8_t newir, uint8_t* oldir) { *oldir = buf[0]; -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: IRshift(new=0x%02x) = 0x%02x\n", newir, *oldir); #endif @@ -462,7 +462,7 @@ int mehfet_cmd_drshift(transport_t t, uint32_t nbits, const uint8_t* newdr, uint memcpy(olddr, buf, nbytes); -#ifdef DEBUG_MEHFET_DRIVER +#ifdef DEBUG_MEHFET_PROTO_DRIVER printc_dbg("mehfet: DRshift(nbits=%u):\n", nbits); debug_hexdump("\tin ", newdr, nbytes); debug_hexdump("\tout", olddr, nbytes);