From 53af978295ad1faa982a1af21219eea19d270cd9 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sat, 30 Jun 2012 16:47:23 +1200 Subject: [PATCH] Allow user to specify JTAG IR lengths. This allows the use of devices that shift out values other than 0x01 from IR. --- src/command.c | 17 +++++-- src/include/jtag_scan.h | 2 +- src/jtag_scan.c | 80 +++++++++++++++++++++----------- src/platforms/libftdi/platform.c | 2 +- src/platforms/native/platform.c | 2 +- src/platforms/stlink/platform.c | 2 +- 6 files changed, 70 insertions(+), 35 deletions(-) diff --git a/src/command.c b/src/command.c index 241f8771..74551d3b 100644 --- a/src/command.c +++ b/src/command.c @@ -38,7 +38,7 @@ static bool cmd_version(void); static bool cmd_help(target *t); -static bool cmd_jtag_scan(void); +static bool cmd_jtag_scan(target *t, int argc, char **argv); static bool cmd_swdp_scan(void); static bool cmd_targets(target *t); static bool cmd_morse(void); @@ -128,11 +128,22 @@ bool cmd_help(target *t) return true; } -bool cmd_jtag_scan(void) +static bool cmd_jtag_scan(target *t, int argc, char **argv) { + (void)t; + uint8_t *irlens = NULL; + gdb_outf("Target voltage: %s\n", platform_target_voltage()); - int devs = jtag_scan(); + if (argc > 1) { + /* Accept a list of IR lengths on command line */ + irlens = alloca(argc); + for (int i = 1; i < argc; i++) + irlens[i-1] = atoi(argv[i]); + irlens[argc-1] = 0; + } + + int devs = jtag_scan(irlens); if(devs < 0) { gdb_out("JTAG device scan failed!\n"); diff --git a/src/include/jtag_scan.h b/src/include/jtag_scan.h index 083aea00..b425b959 100644 --- a/src/include/jtag_scan.h +++ b/src/include/jtag_scan.h @@ -47,7 +47,7 @@ typedef struct jtag_dev_s { extern struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1]; extern int jtag_dev_count; -int jtag_scan(void); +int jtag_scan(const uint8_t *lrlens); void jtag_dev_write_ir(jtag_dev_t *dev, uint32_t ir); void jtag_dev_shift_dr(jtag_dev_t *dev, uint8_t *dout, const uint8_t *din, int ticks); diff --git a/src/jtag_scan.c b/src/jtag_scan.c index df0579f1..0084e2e1 100644 --- a/src/jtag_scan.c +++ b/src/jtag_scan.c @@ -97,7 +97,7 @@ static const char ones[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; * continue to next device. If this is one shift out the remaining 31 bits * of the IDCODE register. */ -int jtag_scan(void) +int jtag_scan(const uint8_t *irlens) { int i; uint32_t j; @@ -117,35 +117,59 @@ int jtag_scan(void) jtagtap_init(); jtagtap_reset(); - DEBUG("Change state to Shift-IR\n"); - jtagtap_shift_ir(); - - DEBUG("Scanning out IRs\n"); - if(!jtagtap_next(0, 1)) { - DEBUG("jtag_scan: Sanity check failed: IR[0] shifted out as 0\n"); - jtag_dev_count = -1; - return -1; /* must be 1 */ - } - jtag_devs[0].ir_len = 1; j = 1; - while((jtag_dev_count <= JTAG_MAX_DEVS) && - (jtag_devs[jtag_dev_count].ir_len <= JTAG_MAX_IR_LEN)) { - if(jtagtap_next(0, 1)) { - if(jtag_devs[jtag_dev_count].ir_len == 1) break; - jtag_devs[++jtag_dev_count].ir_len = 1; + if (irlens) { + DEBUG("Given list of IR lengths, skipping probe\n"); + DEBUG("Change state to Shift-IR\n"); + jtagtap_shift_ir(); + j = 0; + while((jtag_dev_count <= JTAG_MAX_DEVS) && + (jtag_devs[jtag_dev_count].ir_len <= JTAG_MAX_IR_LEN)) { + uint32_t irout; + if(*irlens == 0) + break; + jtagtap_tdi_tdo_seq((uint8_t*)&irout, 0, ones, *irlens); + if (!(irout & 1)) { + DEBUG("check failed: IR[0] != 1\n"); + return -1; + } + jtag_devs[jtag_dev_count].ir_len = *irlens; jtag_devs[jtag_dev_count].ir_prescan = j; jtag_devs[jtag_dev_count].dev = jtag_dev_count; - } else jtag_devs[jtag_dev_count].ir_len++; - j++; - } - if(jtag_dev_count > JTAG_MAX_DEVS) { - DEBUG("jtag_scan: Maximum device count exceeded\n"); - jtag_dev_count = -1; - return -1; - } - if(jtag_devs[jtag_dev_count].ir_len > JTAG_MAX_IR_LEN) { - DEBUG("jtag_scan: Maximum IR length exceeded\n"); - jtag_dev_count = -1; - return -1; + j += *irlens; + irlens++; + jtag_dev_count++; + } + } else { + DEBUG("Change state to Shift-IR\n"); + jtagtap_shift_ir(); + + DEBUG("Scanning out IRs\n"); + if(!jtagtap_next(0, 1)) { + DEBUG("jtag_scan: Sanity check failed: IR[0] shifted out as 0\n"); + jtag_dev_count = -1; + return -1; /* must be 1 */ + } + jtag_devs[0].ir_len = 1; j = 1; + while((jtag_dev_count <= JTAG_MAX_DEVS) && + (jtag_devs[jtag_dev_count].ir_len <= JTAG_MAX_IR_LEN)) { + if(jtagtap_next(0, 1)) { + if(jtag_devs[jtag_dev_count].ir_len == 1) break; + jtag_devs[++jtag_dev_count].ir_len = 1; + jtag_devs[jtag_dev_count].ir_prescan = j; + jtag_devs[jtag_dev_count].dev = jtag_dev_count; + } else jtag_devs[jtag_dev_count].ir_len++; + j++; + } + if(jtag_dev_count > JTAG_MAX_DEVS) { + DEBUG("jtag_scan: Maximum device count exceeded\n"); + jtag_dev_count = -1; + return -1; + } + if(jtag_devs[jtag_dev_count].ir_len > JTAG_MAX_IR_LEN) { + DEBUG("jtag_scan: Maximum IR length exceeded\n"); + jtag_dev_count = -1; + return -1; + } } DEBUG("Return to Run-Test/Idle\n"); diff --git a/src/platforms/libftdi/platform.c b/src/platforms/libftdi/platform.c index 9690a92f..a1202280 100644 --- a/src/platforms/libftdi/platform.c +++ b/src/platforms/libftdi/platform.c @@ -79,7 +79,7 @@ int platform_init(void) assert(gdb_if_init() == 0); - jtag_scan(); + jtag_scan(NULL); return 0; } diff --git a/src/platforms/native/platform.c b/src/platforms/native/platform.c index 16ef28fc..8c6bb7ad 100644 --- a/src/platforms/native/platform.c +++ b/src/platforms/native/platform.c @@ -120,7 +120,7 @@ int platform_init(void) cdcacm_init(); - jtag_scan(); + jtag_scan(NULL); return 0; } diff --git a/src/platforms/stlink/platform.c b/src/platforms/stlink/platform.c index 777db959..fbc13374 100644 --- a/src/platforms/stlink/platform.c +++ b/src/platforms/stlink/platform.c @@ -68,7 +68,7 @@ int platform_init(void) cdcacm_init(); - jtag_scan(); + jtag_scan(NULL); return 0; }