aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Negreanu <adrian.negreanu@nxp.com>2020-09-07 22:36:10 +0300
committerAntonio Borneo <borneo.antonio@gmail.com>2020-09-27 17:40:12 +0100
commit051e80812b1b3bb4deabef272c12bb95f10748da (patch)
tree59d3261f22b6998a5be30cd10d9a41202e2c3c0d
parent35e580373a77438f2832974b1f0dc36863dc3f03 (diff)
downloadriscv-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.c12
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;