ftdi/swdptap: Use parity builtin. Fix array width.

This commit is contained in:
Uwe Bonnes 2020-08-04 15:00:20 +02:00 committed by UweBonnes
parent 34d0f8a2a1
commit c41ab1738e
1 changed files with 10 additions and 29 deletions

View File

@ -48,6 +48,7 @@ static void swdptap_turnaround(enum swdio_status dir)
if (dir == olddir) if (dir == olddir)
return; return;
olddir = dir; olddir = dir;
DEBUG_PROBE("Turnaround %s\n", (dir == SWDIO_STATUS_FLOAT) ? "float": "drive");
if (do_mpsse) { if (do_mpsse) {
if (dir == SWDIO_STATUS_FLOAT) /* SWDIO goes to input */ { if (dir == SWDIO_STATUS_FLOAT) /* SWDIO goes to input */ {
active_state.data_low |= active_cable->mpsse_swd_read.set_data_low | MPSSE_DO; active_state.data_low |= active_cable->mpsse_swd_read.set_data_low | MPSSE_DO;
@ -255,9 +256,7 @@ bool swdptap_seq_in_parity(uint32_t *res, int ticks)
uint8_t DO[5]; uint8_t DO[5];
libftdi_jtagtap_tdi_tdo_seq(DO, 0, NULL, ticks + 1); libftdi_jtagtap_tdi_tdo_seq(DO, 0, NULL, ticks + 1);
result = DO[0] + (DO[1] << 8) + (DO[2] << 16) + (DO[3] << 24); result = DO[0] + (DO[1] << 8) + (DO[2] << 16) + (DO[3] << 24);
for (int i = 0; i < 32; i++) { parity = __builtin_parity(result & ((1LL << ticks) - 1)) & 1;
parity ^= (result >> i) & 1;
}
parity ^= DO[4] & 1; parity ^= DO[4] & 1;
} else { } else {
int index = ticks + 1; int index = ticks + 1;
@ -328,14 +327,13 @@ static void swdptap_seq_out(uint32_t MS, int ticks)
swdptap_turnaround(SWDIO_STATUS_DRIVE); swdptap_turnaround(SWDIO_STATUS_DRIVE);
if (do_mpsse) { if (do_mpsse) {
uint8_t DI[4]; uint8_t DI[4];
swdptap_turnaround(0);
DI[0] = (MS >> 0) & 0xff; DI[0] = (MS >> 0) & 0xff;
DI[1] = (MS >> 8) & 0xff; DI[1] = (MS >> 8) & 0xff;
DI[2] = (MS >> 16) & 0xff; DI[2] = (MS >> 16) & 0xff;
DI[3] = (MS >> 24) & 0xff; DI[3] = (MS >> 24) & 0xff;
libftdi_jtagtap_tdi_tdo_seq(NULL, 0, DI, ticks); libftdi_jtagtap_tdi_tdo_seq(NULL, 0, DI, ticks);
} else { } else {
uint8_t cmd[15]; uint8_t cmd[16];
unsigned int index = 0; unsigned int index = 0;
while (ticks) { while (ticks) {
cmd[index++] = MPSSE_TMS_SHIFT; cmd[index++] = MPSSE_TMS_SHIFT;
@ -356,53 +354,36 @@ static void swdptap_seq_out(uint32_t MS, int ticks)
static void swdptap_seq_out_parity(uint32_t MS, int ticks) static void swdptap_seq_out_parity(uint32_t MS, int ticks)
{ {
unsigned int parity = 0; int parity = __builtin_parity(MS & ((1LL << ticks) - 1)) & 1;
uint8_t cmd[18];
unsigned int index = 0; unsigned int index = 0;
swdptap_turnaround(0); swdptap_turnaround(SWDIO_STATUS_DRIVE);
if (do_mpsse) { if (do_mpsse) {
uint8_t DI[5]; uint8_t DI[8];
DI[0] = (MS >> 0) & 0xff; DI[0] = (MS >> 0) & 0xff;
DI[1] = (MS >> 8) & 0xff; DI[1] = (MS >> 8) & 0xff;
DI[2] = (MS >> 16) & 0xff; DI[2] = (MS >> 16) & 0xff;
DI[3] = (MS >> 24) & 0xff; DI[3] = (MS >> 24) & 0xff;
while(MS) {
parity ^= (MS & 1);
MS >>= 1;
}
DI[4] = parity; DI[4] = parity;
libftdi_jtagtap_tdi_tdo_seq(NULL, 0, DI, ticks + 1); libftdi_jtagtap_tdi_tdo_seq(NULL, 0, DI, ticks + 1);
} else { } else {
uint8_t cmd[32];
int steps = ticks; int steps = ticks;
unsigned int data = MS;
while (steps) { while (steps) {
cmd[index++] = MPSSE_TMS_SHIFT; cmd[index++] = MPSSE_TMS_SHIFT;
if (steps >= 7) { if (steps >= 7) {
cmd[index++] = 6; cmd[index++] = 6;
cmd[index++] = data & 0x7f; cmd[index++] = MS & 0x7f;
data >>= 7; MS >>= 7;
steps -= 7; steps -= 7;
} else { } else {
cmd[index++] = steps - 1; cmd[index++] = steps - 1;
cmd[index++] = data & 0x7f; cmd[index++] = MS & 0x7f;
steps = 0; steps = 0;
} }
} }
while (ticks--) {
parity ^= MS;
MS >>= 1;
}
cmd[index++] = MPSSE_TMS_SHIFT; cmd[index++] = MPSSE_TMS_SHIFT;
cmd[index++] = 0; cmd[index++] = 0;
cmd[index++] = parity; cmd[index++] = parity;
libftdi_buffer_write(cmd, index); libftdi_buffer_write(cmd, index);
} }
while (ticks--) {
parity ^= MS;
MS >>= 1;
}
cmd[index++] = MPSSE_TMS_SHIFT;
cmd[index++] = 0;
cmd[index++] = parity;
libftdi_buffer_write(cmd, index);
} }