application: improve SWD scan
This commit is contained in:
parent
7ef3e2494b
commit
6910f024f0
|
@ -263,39 +263,59 @@ static void command_swd_scan(void* argument)
|
|||
putc('!');
|
||||
continue;
|
||||
}
|
||||
// try enabling SWD
|
||||
uint32_t data; // data to read/write over SWD
|
||||
enum swd_ack_e ack; // SWD acknowledge response
|
||||
// switch from JTAG to SWD (see ARM IHI 0074A B5.2.2)
|
||||
swd_line_reset(); // put target in reset state
|
||||
swd_jtag_to_swd(); // put target SWJ in SWD mode
|
||||
swd_line_reset(); // put target in reset state
|
||||
swd_idle_cycles(2); // idle before packet request
|
||||
swd_packet_request(false, SWD_A_DP_DPIDR, true); // request DPIDR
|
||||
swd_turnaround(1); // switch from writing to reading
|
||||
ack = swd_acknowledge_response(); // get ack
|
||||
if (SWD_ACK_OK != ack) { // no SWD on this combination
|
||||
putc('.');
|
||||
continue;
|
||||
}
|
||||
printf("\nSWD found: SWCLK=CH%02u SWDIO=CH%02u, ", swclk, swdio);
|
||||
printf("SWD target DPIDR: ");
|
||||
if (!swd_read(&data)) {
|
||||
printf("parity error\n");
|
||||
return;
|
||||
}
|
||||
swd_turnaround(1); // switch from reading to writing
|
||||
printf("0x%08x ", data);
|
||||
if (data & 0x1) {
|
||||
puts("(");
|
||||
print_idcode(data); // decode DPIDR
|
||||
puts(")\n");
|
||||
} else {
|
||||
printf("(invalid: RAO != 1)\n");
|
||||
// read DPIDR (see ARM IHI 0074A)
|
||||
// connection, e.g. reading the DPIDR, is the only allowed action after line reset
|
||||
uint8_t retry = 2; // number of times to retry reading DPIDR
|
||||
while (retry) {
|
||||
swd_line_reset(); // put target in reset state
|
||||
swd_idle_cycles(2); // idle before packet request
|
||||
swd_packet_request(false, SWD_A_DP_DPIDR, true); // request DPIDR
|
||||
swd_turnaround(1); // switch from writing to reading
|
||||
const enum swd_ack_e ack = swd_acknowledge_response(); // get ack
|
||||
uint32_t data; // data to read/write over SWD
|
||||
const bool parity = swd_read(&data); // read data no matter what
|
||||
swd_turnaround(1); // switch from reading to writing
|
||||
switch (ack) {
|
||||
case SWD_ACK_OK: // expected answer
|
||||
if (parity) { // parity is ok
|
||||
printf("\nSWD found: SWCLK=CH%02u SWDIO=CH%02u, DPIDR=0x%08x", swclk, swdio, data);
|
||||
found++; // remember we found an SWD combination
|
||||
if (data & 0x1) {
|
||||
puts(" (");
|
||||
print_idcode(data); // decode DPIDR
|
||||
puts(")");
|
||||
} else {
|
||||
puts(" (invalid LSb)");
|
||||
}
|
||||
} else {
|
||||
printf("(invalid: RAO != 1)");
|
||||
}
|
||||
break;
|
||||
case SWD_ACK_NOREPLY: // the is no SWD here
|
||||
puts("no reply");
|
||||
retry = 0; // no need to retry
|
||||
break;
|
||||
case SWD_ACK_WAIT: // not allowed for DPIDR
|
||||
case SWD_ACK_FAULT: // not allowed for DPIDR
|
||||
default: // invalid ACK
|
||||
if (!swd_read(&data)) { // read the data
|
||||
puts("parity error ");
|
||||
}
|
||||
printf("garbage data %+08x ", data);
|
||||
swd_turnaround(1); // switch from reading to writing
|
||||
break;
|
||||
}
|
||||
if (retry) {
|
||||
retry--; // decrement retry count
|
||||
}
|
||||
}
|
||||
puts("\n");
|
||||
swd_release_pins(); // release pins
|
||||
found++; // remember we found an SWD combination
|
||||
}
|
||||
}
|
||||
} // end SWDIO
|
||||
} // end SWCLK
|
||||
|
||||
gpio_set(GPIO_PORT(TARGET_EN), GPIO_PIN(TARGET_EN)); // disable level shifters
|
||||
printf("\n%u SWD interface(s) found\n", found);
|
||||
|
|
Loading…
Reference in New Issue