Allow user to specify JTAG IR lengths.

This allows the use of devices that shift out values other than 0x01
from IR.
This commit is contained in:
Gareth McMullin 2012-06-30 16:47:23 +12:00
parent 01d0390b54
commit 53af978295
6 changed files with 70 additions and 35 deletions

View File

@ -38,7 +38,7 @@
static bool cmd_version(void); static bool cmd_version(void);
static bool cmd_help(target *t); 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_swdp_scan(void);
static bool cmd_targets(target *t); static bool cmd_targets(target *t);
static bool cmd_morse(void); static bool cmd_morse(void);
@ -128,11 +128,22 @@ bool cmd_help(target *t)
return true; 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()); 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) { if(devs < 0) {
gdb_out("JTAG device scan failed!\n"); gdb_out("JTAG device scan failed!\n");

View File

@ -47,7 +47,7 @@ typedef struct jtag_dev_s {
extern struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1]; extern struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1];
extern int jtag_dev_count; 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_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); void jtag_dev_shift_dr(jtag_dev_t *dev, uint8_t *dout, const uint8_t *din, int ticks);

View File

@ -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 * continue to next device. If this is one shift out the remaining 31 bits
* of the IDCODE register. * of the IDCODE register.
*/ */
int jtag_scan(void) int jtag_scan(const uint8_t *irlens)
{ {
int i; int i;
uint32_t j; uint32_t j;
@ -117,35 +117,59 @@ int jtag_scan(void)
jtagtap_init(); jtagtap_init();
jtagtap_reset(); jtagtap_reset();
DEBUG("Change state to Shift-IR\n"); if (irlens) {
jtagtap_shift_ir(); DEBUG("Given list of IR lengths, skipping probe\n");
DEBUG("Change state to Shift-IR\n");
DEBUG("Scanning out IRs\n"); jtagtap_shift_ir();
if(!jtagtap_next(0, 1)) { j = 0;
DEBUG("jtag_scan: Sanity check failed: IR[0] shifted out as 0\n"); while((jtag_dev_count <= JTAG_MAX_DEVS) &&
jtag_dev_count = -1; (jtag_devs[jtag_dev_count].ir_len <= JTAG_MAX_IR_LEN)) {
return -1; /* must be 1 */ uint32_t irout;
} if(*irlens == 0)
jtag_devs[0].ir_len = 1; j = 1; break;
while((jtag_dev_count <= JTAG_MAX_DEVS) && jtagtap_tdi_tdo_seq((uint8_t*)&irout, 0, ones, *irlens);
(jtag_devs[jtag_dev_count].ir_len <= JTAG_MAX_IR_LEN)) { if (!(irout & 1)) {
if(jtagtap_next(0, 1)) { DEBUG("check failed: IR[0] != 1\n");
if(jtag_devs[jtag_dev_count].ir_len == 1) break; return -1;
jtag_devs[++jtag_dev_count].ir_len = 1; }
jtag_devs[jtag_dev_count].ir_len = *irlens;
jtag_devs[jtag_dev_count].ir_prescan = j; jtag_devs[jtag_dev_count].ir_prescan = j;
jtag_devs[jtag_dev_count].dev = jtag_dev_count; jtag_devs[jtag_dev_count].dev = jtag_dev_count;
} else jtag_devs[jtag_dev_count].ir_len++; j += *irlens;
j++; irlens++;
} jtag_dev_count++;
if(jtag_dev_count > JTAG_MAX_DEVS) { }
DEBUG("jtag_scan: Maximum device count exceeded\n"); } else {
jtag_dev_count = -1; DEBUG("Change state to Shift-IR\n");
return -1; jtagtap_shift_ir();
}
if(jtag_devs[jtag_dev_count].ir_len > JTAG_MAX_IR_LEN) { DEBUG("Scanning out IRs\n");
DEBUG("jtag_scan: Maximum IR length exceeded\n"); if(!jtagtap_next(0, 1)) {
jtag_dev_count = -1; DEBUG("jtag_scan: Sanity check failed: IR[0] shifted out as 0\n");
return -1; 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"); DEBUG("Return to Run-Test/Idle\n");

View File

@ -79,7 +79,7 @@ int platform_init(void)
assert(gdb_if_init() == 0); assert(gdb_if_init() == 0);
jtag_scan(); jtag_scan(NULL);
return 0; return 0;
} }

View File

@ -120,7 +120,7 @@ int platform_init(void)
cdcacm_init(); cdcacm_init();
jtag_scan(); jtag_scan(NULL);
return 0; return 0;
} }

View File

@ -68,7 +68,7 @@ int platform_init(void)
cdcacm_init(); cdcacm_init();
jtag_scan(); jtag_scan(NULL);
return 0; return 0;
} }