jtag/drivers/bitbang: avoid mostly harmless glitch on SWDIO
commit148bc7e2151740527b4ca67d0a7c7c9f01725981
authorTomas Vanek <vanekt@fbl.cz>
Fri, 14 Oct 2022 07:19:29 +0000 (14 09:19 +0200)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sat, 28 Jan 2023 15:53:21 +0000 (28 15:53 +0000)
tree5a5ddbdc0ea61b2e14f9bb35436673673969c078
parent20285b91008106c9fa966cea3269c6f6a81e539a
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>
src/jtag/drivers/bitbang.c