application: scan all channels for SWD

This commit is contained in:
King Kévin 2021-03-15 14:00:22 +01:00
parent c363460ab2
commit aac9bd0866
1 changed files with 63 additions and 22 deletions

View File

@ -223,31 +223,72 @@ static void mux_select(int8_t channel)
static void command_swd_scan(void* argument)
{
(void)argument; // we won't use the argument
printf("SWD target DPIDR: ");
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_jtag_to_swd(); // put target SWJ in SWD mode
swd_line_reset(); // put target in reset state
swd_idle_cycles(2); // idle before packer 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) {
printf("ack error\n");
float* voltages = measure_voltages(); // measure voltages
if (voltages[1] < 0.5) { // check target voltage connection
puts("connect target voltage to test channel type\n");
return;
}
if (!swd_read(&data)) {
printf("parity error\n");
return;
}
swd_turnaround(1); // switch from reading to writing
printf("0x%08x ", data);
if (data & 0x1) {
printf("(designer: %03x/%s, version: %u, part number: 0x%02x/%s, revision %u)\n", (data >> 1) & 0x3ff, swd_jep106_manufacturer((data >> 8) & 0x0f, (data >> 1) & 0x7f), (data >> 12) & 0x0f, (data >> 20) & 0xff, swd_dpidr_partno((data >> 1) & 0x3ff, (data >> 20) & 0xff), (data >> 28) & 0x0f);
} else {
printf("(invalid: RAO != 1)\n");
mux_select(-1); // disable multiplexer
gpio_set(GPIO_PORT(SIGNAL_PU_PIN), GPIO_PIN(SIGNAL_PU_PIN)); // ensure we are not pulling up the signal
gpio_set(GPIO_PORT(SIGNAL_PD_PIN), GPIO_PIN(SIGNAL_PD_PIN)); // ensure we are not pulling down the signal
gpio_clear(GPIO_PORT(TARGET_EN), GPIO_PIN(TARGET_EN)); // power level shifter
sleep_us(100); // wait a tiny bit for the pull-up to be active
printf("searching SWD on channels (%u combinations): ", (channel_stop - channel_start + 1) * (channel_stop - channel_start));
mux_select(-1); // disable multiplexer
gpio_set(GPIO_PORT(SIGNAL_PU_PIN), GPIO_PIN(SIGNAL_PU_PIN)); // ensure we are not pulling up the signal
gpio_set(GPIO_PORT(SIGNAL_PD_PIN), GPIO_PIN(SIGNAL_PD_PIN)); // ensure we are not pulling down the signal
gpio_clear(GPIO_PORT(TARGET_EN), GPIO_PIN(TARGET_EN)); // power level shifter
uint8_t found = 0;
for (uint8_t swclk = channel_start; swclk <= channel_stop; swclk++) {
for (uint8_t swdio = channel_start; swdio <= channel_stop; swdio++) {
// skip when SWCLK and SWDIO share a same pin
if (swdio == swclk) {
continue;
}
// set SWCLK/SWDIO combination
if (!swd_set_pins(channel_ports[swclk], channel_pins[swclk], channel_ports[swdio], channel_pins[swdio])) {
putc('!');
continue;
}
// try enabling SWD
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_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) {
printf("(designer: %03x/%s, version: %u, part number: 0x%02x/%s, revision %u)\n", (data >> 1) & 0x3ff, swd_jep106_manufacturer((data >> 8) & 0x0f, (data >> 1) & 0x7f), (data >> 12) & 0x0f, (data >> 20) & 0xff, swd_dpidr_partno((data >> 1) & 0x3ff, (data >> 20) & 0xff), (data >> 28) & 0x0f);
} else {
printf("(invalid: RAO != 1)\n");
}
swd_release_pins(); // release pins
found++; // remember we found an SWD combination
}
}
gpio_set(GPIO_PORT(TARGET_EN), GPIO_PIN(TARGET_EN)); // disable level shifters
printf("\n%u SWD interface(s) found\n", found);
}
static void command_voltages(void* argument)