From aa230f0d45c46240c9cbced8e3fffb0844fbf553 Mon Sep 17 00:00:00 2001 From: ALTracer <11005378+ALTracer@users.noreply.github.com> Date: Thu, 29 Jan 2026 20:40:30 +0300 Subject: [PATCH 1/3] hosted/jlink: Use jtagtap_cycle to switch from SWD to JTAG --- src/platforms/hosted/jlink_jtag.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/platforms/hosted/jlink_jtag.c b/src/platforms/hosted/jlink_jtag.c index 781e2686da3..bcae97b3837 100644 --- a/src/platforms/hosted/jlink_jtag.c +++ b/src/platforms/hosted/jlink_jtag.c @@ -42,8 +42,6 @@ static void jlink_jtag_tdi_seq(bool final_tms, const uint8_t *data_in, size_t cl static bool jlink_jtag_next(bool tms, bool tdi); static void jlink_jtag_cycle(bool tms, bool tdi, size_t clock_cycles); -static const uint8_t jlink_switch_to_jtag_seq[9U] = {0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0x3cU, 0xe7U}; - bool jlink_jtag_init(void) { DEBUG_PROBE("-> jlink_jtag_init\n"); @@ -56,7 +54,10 @@ bool jlink_jtag_init(void) /* Ensure we're in JTAG mode */ DEBUG_PROBE("%s: Switch to JTAG\n", __func__); - if (!jlink_transfer(sizeof(jlink_switch_to_jtag_seq) * 8U, jlink_switch_to_jtag_seq, NULL, NULL)) { + jlink_jtag_cycle(true, false, 56U - 5U); + uint8_t tms_swd_to_jtag_seq[2] = {0x3cU, 0xe7U}; + bool res = jlink_transfer(16U, tms_swd_to_jtag_seq, NULL, NULL); + if (!res) { DEBUG_ERROR("Switch to JTAG failed\n"); return false; } From 774a1b90772ddca315157f7a8c483edde418d7a7 Mon Sep 17 00:00:00 2001 From: ALTracer <11005378+ALTracer@users.noreply.github.com> Date: Thu, 29 Jan 2026 20:54:21 +0300 Subject: [PATCH 2/3] hosted/jlink: Implement jtagtap_cycle via jlink_transfer --- src/platforms/hosted/jlink_jtag.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/platforms/hosted/jlink_jtag.c b/src/platforms/hosted/jlink_jtag.c index bcae97b3837..018463f2004 100644 --- a/src/platforms/hosted/jlink_jtag.c +++ b/src/platforms/hosted/jlink_jtag.c @@ -123,6 +123,17 @@ static bool jlink_jtag_next(bool tms, bool tdi) static void jlink_jtag_cycle(const bool tms, const bool tdi, const size_t clock_cycles) { - for (size_t i = 0; i < clock_cycles; i++) - jlink_jtag_next(tms, tdi); + uint8_t tms_buf[8] = {0}; + uint8_t tdi_buf[8] = {0}; + if (clock_cycles > 64U) + return; + const uint64_t all_ones = clock_cycles == 64U ? UINT64_MAX : (UINT64_C(1) << clock_cycles) - 1U; + const uint64_t tms_pattern = tms ? all_ones : 0U; + const uint64_t tdi_pattern = tdi ? all_ones : 0U; + memcpy(tms_buf, &tms_pattern, 8); + memcpy(tdi_buf, &tdi_pattern, 8); + DEBUG_PROBE("jtagtap_cycle tms=%u tdi=%u, clock cycles: %zu\n", tms, tdi, clock_cycles); + const bool result = jlink_transfer(clock_cycles, tms_buf, tdi_buf, NULL); + if (!result) + raise_exception(EXCEPTION_ERROR, "jtagtap_cycle failed"); } From 82a05810b44ab3e0459226d39f9043c84c918135 Mon Sep 17 00:00:00 2001 From: ALTracer <11005378+ALTracer@users.noreply.github.com> Date: Wed, 4 Feb 2026 19:18:17 +0300 Subject: [PATCH 3/3] hosted/jlink: Rewrite jtagtap_cycles using plain for-loops and bitmasking --- src/platforms/hosted/jlink_jtag.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/platforms/hosted/jlink_jtag.c b/src/platforms/hosted/jlink_jtag.c index 018463f2004..a173b3964a8 100644 --- a/src/platforms/hosted/jlink_jtag.c +++ b/src/platforms/hosted/jlink_jtag.c @@ -123,15 +123,19 @@ static bool jlink_jtag_next(bool tms, bool tdi) static void jlink_jtag_cycle(const bool tms, const bool tdi, const size_t clock_cycles) { - uint8_t tms_buf[8] = {0}; - uint8_t tdi_buf[8] = {0}; - if (clock_cycles > 64U) + uint8_t tms_buf[512] = {0}; + uint8_t tdi_buf[512] = {0}; + if (clock_cycles > 4096U) return; - const uint64_t all_ones = clock_cycles == 64U ? UINT64_MAX : (UINT64_C(1) << clock_cycles) - 1U; - const uint64_t tms_pattern = tms ? all_ones : 0U; - const uint64_t tdi_pattern = tdi ? all_ones : 0U; - memcpy(tms_buf, &tms_pattern, 8); - memcpy(tdi_buf, &tdi_pattern, 8); + const size_t clock_bytes = clock_cycles >> 3U; + memset(tms_buf, tms ? 0xffU : 0U, clock_bytes); + memset(tdi_buf, tdi ? 0xffU : 0U, clock_bytes); + const size_t clock_bits = clock_cycles & 7U; + if (clock_bits) { + const uint8_t ones = (1U << clock_bits) - 1U; + tms_buf[clock_bytes] = tms ? ones : 0U; + tdi_buf[clock_bytes] = tdi ? ones : 0U; + } DEBUG_PROBE("jtagtap_cycle tms=%u tdi=%u, clock cycles: %zu\n", tms, tdi, clock_cycles); const bool result = jlink_transfer(clock_cycles, tms_buf, tdi_buf, NULL); if (!result)