diff options
author | Adrian Negreanu <adrian.negreanu@nxp.com> | 2020-09-07 22:36:10 +0300 |
---|---|---|
committer | Antonio Borneo <borneo.antonio@gmail.com> | 2020-09-27 17:40:12 +0100 |
commit | 051e80812b1b3bb4deabef272c12bb95f10748da (patch) | |
tree | 59d3261f22b6998a5be30cd10d9a41202e2c3c0d | |
parent | 35e580373a77438f2832974b1f0dc36863dc3f03 (diff) | |
download | riscv-openocd-051e80812b1b3bb4deabef272c12bb95f10748da.zip riscv-openocd-051e80812b1b3bb4deabef272c12bb95f10748da.tar.gz riscv-openocd-051e80812b1b3bb4deabef272c12bb95f10748da.tar.bz2 |
drivers/jlink: fix calculate_swo_prescaler formula
a) TPIU_ACPR is defined as:
SWO_baudrate = TRACECLKIN/(TPIU_ACPR +1)
b) TPIU_ACPR is set by armv7m_trace_tpiu_config()
target_write_u32(target, TPIU_ACPR, Prescaler-1), so
TPIU_ACPR = Prescaler-1
Replacing TPIU_ACPR in a), we get:
SWO_baudrate = TRACECLKIN/Prescaler, so
c) Prescaler = TRACECLKIN/SWO_baudrate
The Prescaler calculated by calculate_swo_prescaler() is greater by 1:
Prescaler = TRACECLKIN/SWO_baudrate + 1
The second problem is that even in situations when
an exact baudrate match is possible,
the resulting TRACECLKIN/Prescaler already has a 3% deviation.
For example, TRACECLKIN=88000000, SWO_baudrate=500000,
calculate_swo_prescaler will return Prescaler=171.
The correct value should be Prescaler=176 (TPIU_ACPR=175).
Might be related to https://sourceforge.net/p/openocd/tickets/263/
Change-Id: Ib4d6df6e34685a9be4c2995cb500b2411c76e39b
Signed-off-by: Adrian Negreanu <adrian.negreanu@nxp.com>
Reviewed-on: http://openocd.zylin.com/5807
Tested-by: jenkins
Reviewed-by: Marc Schink <dev@zapb.de>
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
-rw-r--r-- | src/jtag/drivers/jlink.c | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 57e357b..910799c 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -1270,16 +1270,14 @@ static bool calculate_swo_prescaler(unsigned int traceclkin_freq, uint32_t trace_freq, uint16_t *prescaler) { unsigned int presc; - double deviation; - - presc = ((1.0 - SWO_MAX_FREQ_DEV) * traceclkin_freq) / trace_freq + 1; - + presc = DIV_ROUND_UP(traceclkin_freq, trace_freq); if (presc > TPIU_ACPR_MAX_SWOSCALER) return false; - deviation = fabs(1.0 - ((double)trace_freq * presc / traceclkin_freq)); - - if (deviation > SWO_MAX_FREQ_DEV) + /* Probe's UART speed must be within 3% of the TPIU's SWO baud rate. */ + unsigned int max_deviation = (traceclkin_freq * 3) / 100; + if (presc * trace_freq < traceclkin_freq - max_deviation || + presc * trace_freq > traceclkin_freq + max_deviation) return false; *prescaler = presc; |