jtaglib: fix register reading on MSP430G2452 and similar chips
This commit is contained in:
parent
cba3cd4f33
commit
a5252e13f6
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue