jtag/drivers/bitbang: avoid mostly harmless glitch on SWDIO
bitbang_swd_exchange(rnw=true,...) calls bitbang_interface->swd_write()
with swdio clamped to 0.
bitbang_swd_write_reg() reads 1 turnaround bit, 3 ack bits
and 1 turnaround by one call to bitbang_swd_exchange()
and then switches SWDIO to output.
AFAIK all bitbang interfaces switch SWDIO GPIO direction immediately
in bitbang_interface->swdio_drive().
The GPIO now drives SWDIO line to the value stored in the output register
which is always zero from previous bitbang_swd_exchange(rnw=true,...).
In case the following data bit (bit 0) is 1 we can observe a glitch
on SWDIO:
_____ out 1 ____
HiZ/pull-up ----\ /
\ /
\______ out 0 ______/
swdio_drive(true) swd_write(0,1)
The glitch fortunately takes place far enough from SWCLK rising edge
where SWDIO is sampled by the target, so I believe it is harmless
except some corner cases where the reflected wave is delayed on long
line.
Anyway keeping electrical signals glitch free is a good practice.
To keep performance penalty minimal, pre-write the first data
bit to SWDIO GPIO output buffer while clocking the turnaround bit.
Following swdio_drive(true) outputs the pre-written value
and the same value is rewritten by the next swd_write()
instead of glitching SWDIO.
Change-Id: I72ea9c0b2fae57e8ff5aa616859182c67abc924f
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: https://review.openocd.org/c/openocd/+/7260
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
committed by
Antonio Borneo
parent
20285b9100
commit
148bc7e215
@@ -525,7 +525,19 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay
|
|||||||
bitbang_swd_exchange(false, &cmd, 0, 8);
|
bitbang_swd_exchange(false, &cmd, 0, 8);
|
||||||
|
|
||||||
bitbang_interface->swdio_drive(false);
|
bitbang_interface->swdio_drive(false);
|
||||||
bitbang_swd_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 1);
|
bitbang_swd_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3);
|
||||||
|
|
||||||
|
/* Avoid a glitch on SWDIO when changing the direction to output.
|
||||||
|
* To keep performance penalty minimal, pre-write the first data
|
||||||
|
* bit to SWDIO GPIO output buffer while clocking the turnaround bit.
|
||||||
|
* Following swdio_drive(true) outputs the pre-written value
|
||||||
|
* and the same value is rewritten by the next swd_write()
|
||||||
|
* instead of glitching SWDIO
|
||||||
|
* HiZ/pull-up --------------> 0 -------------> 1
|
||||||
|
* swdio_drive(true) swd_write(0,1)
|
||||||
|
* in case of data bit 0 = 1
|
||||||
|
*/
|
||||||
|
bitbang_swd_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 1);
|
||||||
bitbang_interface->swdio_drive(true);
|
bitbang_interface->swdio_drive(true);
|
||||||
bitbang_swd_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1);
|
bitbang_swd_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user