application: improve SWD scan

This commit is contained in:
King Kévin 2021-03-22 11:56:48 +01:00
parent 7ef3e2494b
commit 6910f024f0
1 changed files with 49 additions and 29 deletions

View File

@ -263,39 +263,59 @@ static void command_swd_scan(void* argument)
putc('!'); putc('!');
continue; continue;
} }
// try enabling SWD // switch from JTAG to SWD (see ARM IHI 0074A B5.2.2)
uint32_t data; // data to read/write over SWD
enum swd_ack_e ack; // SWD acknowledge response
swd_line_reset(); // put target in reset state swd_line_reset(); // put target in reset state
swd_jtag_to_swd(); // put target SWJ in SWD mode swd_jtag_to_swd(); // put target SWJ in SWD mode
swd_line_reset(); // put target in reset state // read DPIDR (see ARM IHI 0074A)
swd_idle_cycles(2); // idle before packet request // connection, e.g. reading the DPIDR, is the only allowed action after line reset
swd_packet_request(false, SWD_A_DP_DPIDR, true); // request DPIDR uint8_t retry = 2; // number of times to retry reading DPIDR
swd_turnaround(1); // switch from writing to reading while (retry) {
ack = swd_acknowledge_response(); // get ack swd_line_reset(); // put target in reset state
if (SWD_ACK_OK != ack) { // no SWD on this combination swd_idle_cycles(2); // idle before packet request
putc('.'); swd_packet_request(false, SWD_A_DP_DPIDR, true); // request DPIDR
continue; swd_turnaround(1); // switch from writing to reading
} const enum swd_ack_e ack = swd_acknowledge_response(); // get ack
printf("\nSWD found: SWCLK=CH%02u SWDIO=CH%02u, ", swclk, swdio); uint32_t data; // data to read/write over SWD
printf("SWD target DPIDR: "); const bool parity = swd_read(&data); // read data no matter what
if (!swd_read(&data)) { swd_turnaround(1); // switch from reading to writing
printf("parity error\n"); switch (ack) {
return; case SWD_ACK_OK: // expected answer
} if (parity) { // parity is ok
swd_turnaround(1); // switch from reading to writing printf("\nSWD found: SWCLK=CH%02u SWDIO=CH%02u, DPIDR=0x%08x", swclk, swdio, data);
printf("0x%08x ", data); found++; // remember we found an SWD combination
if (data & 0x1) { if (data & 0x1) {
puts("("); puts(" (");
print_idcode(data); // decode DPIDR print_idcode(data); // decode DPIDR
puts(")\n"); puts(")");
} else { } else {
printf("(invalid: RAO != 1)\n"); 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 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 gpio_set(GPIO_PORT(TARGET_EN), GPIO_PIN(TARGET_EN)); // disable level shifters
printf("\n%u SWD interface(s) found\n", found); printf("\n%u SWD interface(s) found\n", found);