hosted/cmsis_dap: Removed one-bit SWD read while SWIO is undriven + pulled up which can cause issues with certain CMSIS-DAP adaptors

Many thanks to @mubes for finding this and suggesting a fix
This commit is contained in:
dragonmux 2022-07-13 12:49:11 -04:00 committed by Piotr Esden-Tempski
parent dcf9b1fc09
commit 8e8ad7dbd4
3 changed files with 9 additions and 26 deletions

View File

@ -392,9 +392,7 @@ static void dap_mem_read(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
DEBUG_WIRE("memread res last data %08" PRIx32 "\n", ((uint32_t*)dest)[-1]); DEBUG_WIRE("memread res last data %08" PRIx32 "\n", ((uint32_t*)dest)[-1]);
} }
static void dap_mem_write_sized( static void dap_mem_write_sized( ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len, enum align align)
ADIv5_AP_t *ap, uint32_t dest, const void *src,
size_t len, enum align align)
{ {
if (len == 0) if (len == 0)
return; return;
@ -452,15 +450,13 @@ static void cmsis_dap_jtagtap_tms_seq(uint32_t MS, int ticks)
DEBUG_PROBE("tms_seq DI %08x %d\n", MS, ticks); DEBUG_PROBE("tms_seq DI %08x %d\n", MS, ticks);
} }
static void cmsis_dap_jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, static void cmsis_dap_jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks)
const uint8_t *DI, int ticks)
{ {
dap_jtagtap_tdi_tdo_seq(DO, (final_tms), NULL, DI, ticks); dap_jtagtap_tdi_tdo_seq(DO, (final_tms), NULL, DI, ticks);
DEBUG_PROBE("jtagtap_tdi_tdo_seq %d, %02x-> %02x\n", ticks, DI[0], (DO)? DO[0] : 0); DEBUG_PROBE("jtagtap_tdi_tdo_seq %d, %02x-> %02x\n", ticks, DI[0], (DO)? DO[0] : 0);
} }
static void cmsis_dap_jtagtap_tdi_seq(const uint8_t final_tms, static void cmsis_dap_jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks)
const uint8_t *DI, int ticks)
{ {
dap_jtagtap_tdi_tdo_seq(NULL, (final_tms), NULL, DI, ticks); dap_jtagtap_tdi_tdo_seq(NULL, (final_tms), NULL, DI, ticks);
DEBUG_PROBE("jtagtap_tdi_seq %d, %02x\n", ticks, DI[0]); DEBUG_PROBE("jtagtap_tdi_seq %d, %02x\n", ticks, DI[0]);
@ -541,12 +537,11 @@ int dap_swdptap_init(ADIv5_DP_t *dp)
dap_connect(false); dap_connect(false);
dap_led(0, 1); dap_led(0, 1);
dap_reset_link(false); dap_reset_link(false);
if ((has_swd_sequence) && dap_sequence_test()) { if (has_swd_sequence)
/* DAP_SWD_SEQUENCE does not do auto turnaround, use own!*/ /* DAP_SWD_SEQUENCE does not do auto turnaround, use own!*/
dp->dp_low_write = dap_dp_low_write; dp->dp_low_write = dap_dp_low_write;
} else { else
dp->dp_low_write = NULL; dp->dp_low_write = NULL;
}
dp->seq_out = dap_swdptap_seq_out; dp->seq_out = dap_swdptap_seq_out;
dp->dp_read = dap_dp_read_reg; dp->dp_read = dap_dp_read_reg;
/* For error() use the TARGETID switching firmware_swdp_error */ /* For error() use the TARGETID switching firmware_swdp_error */

View File

@ -415,11 +415,12 @@ unsigned int dap_read_block(ADIv5_AP_t *ap, void *dest, uint32_t src,
DEBUG_WARN("dap_read_block @ %08" PRIx32 " fault -> line reset\n", src); DEBUG_WARN("dap_read_block @ %08" PRIx32 " fault -> line reset\n", src);
dap_line_reset(); dap_line_reset();
} }
if (sz != transferred) { if (sz != transferred)
return 1; return 1;
} else if (align > ALIGN_HALFWORD) {
if (align > ALIGN_HALFWORD)
memcpy(dest, &buf[3], len); memcpy(dest, &buf[3], len);
} else { else {
uint32_t *p = (uint32_t *)&buf[3]; uint32_t *p = (uint32_t *)&buf[3];
while(sz) { while(sz) {
dest = extract(dest, src, *p, align); dest = extract(dest, src, *p, align);
@ -796,18 +797,6 @@ void dap_swdptap_seq_out_parity(uint32_t MS, int ticks)
DEBUG_WARN("dap_swdptap_seq_out error\n"); DEBUG_WARN("dap_swdptap_seq_out error\n");
} }
bool dap_sequence_test(void)
{
uint8_t buf[4] = {
ID_DAP_SWD_SEQUENCE,
0x1,
0x81, /* Read one bit */
0 /* one idle cycle */
};
dbg_dap_cmd(buf, sizeof(buf), 3);
return (buf[0] == DAP_OK);
}
#define SWD_SEQUENCE_IN 0x80 #define SWD_SEQUENCE_IN 0x80
uint32_t dap_swdptap_seq_in(int ticks) uint32_t dap_swdptap_seq_in(int ticks)
{ {

View File

@ -85,6 +85,5 @@ void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS, co
int dap_jtag_configure(void); int dap_jtag_configure(void);
void dap_swdptap_seq_out(uint32_t MS, int ticks); void dap_swdptap_seq_out(uint32_t MS, int ticks);
void dap_swdptap_seq_out_parity(uint32_t MS, int ticks); void dap_swdptap_seq_out_parity(uint32_t MS, int ticks);
bool dap_sequence_test(void);
#endif // _DAP_H_ #endif // _DAP_H_