jtag: driver-neutral JTAG_TCK_FREQ_KHZ clock (phase A)
One clock knob across probes instead of per-driver names: - jtag_open mirrors JTAG_TCK_FREQ_KHZ into PROBE_FTDI_TCK_FREQ_KHZ for the Viveris FTDI driver (read-only at init); unset leaves the existing value untouched - the Digilent driver reads JTAG_TCK_FREQ_KHZ directly instead of hardcoding 4 MHz (falls back to 4 MHz when unset) - documented in probes.yaml; CLAUDE.md design note marks phase A done FTDI path validated on the IGLOO2/FlashPro (250 kHz, mirror confirmed); Digilent path not hardware-tested. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -183,8 +183,11 @@ fact bounded by both the probe and the board/device.
|
|||||||
|
|
||||||
### Phasing
|
### Phasing
|
||||||
|
|
||||||
- **A** — one canonical `tck_khz` honoured by FTDI (shim) + Digilent
|
- **A (done)** — one canonical `JTAG_TCK_FREQ_KHZ` (kHz): mirrored to
|
||||||
(read it): kills the immediate smell, one knob for the two real probes.
|
`PROBE_FTDI_TCK_FREQ_KHZ` at `jtag_open` for the Viveris FTDI driver,
|
||||||
|
read directly by our Digilent driver; unset → each driver's own default
|
||||||
|
(FTDI 1000, Digilent 4000). Set it via `set`, a `probes.yaml` profile,
|
||||||
|
or `defaults:`. (FTDI path hardware-validated; Digilent path untested.)
|
||||||
- **B** — device `max_tck_khz` + resolution after `jtag_autoinit`.
|
- **B** — device `max_tck_khz` + resolution after `jtag_autoinit`.
|
||||||
- **C** — generalise the other link settings (reset/RTCK) and wire the
|
- **C** — generalise the other link settings (reset/RTCK) and wire the
|
||||||
`prog` method tag into backend dispatch (ties into the SVF player).
|
`prog` method tag into backend dispatch (ties into the SVF player).
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "jtag_core/jtag_core.h"
|
#include "jtag_core/jtag_core.h"
|
||||||
#include "jtag_core/dbg_logs.h"
|
#include "jtag_core/dbg_logs.h"
|
||||||
#include "config/bs_defines.h"
|
#include "config/bs_defines.h"
|
||||||
|
#include "script/env.h"
|
||||||
|
|
||||||
#include "drivers/drv_loader.h"
|
#include "drivers/drv_loader.h"
|
||||||
|
|
||||||
@@ -209,11 +210,17 @@ static int drv_Digilent_Detect(jtag_core *jc)
|
|||||||
|
|
||||||
static int drv_Digilent_Init(jtag_core *jc, int sub_drv, char *params)
|
static int drv_Digilent_Init(jtag_core *jc, int sub_drv, char *params)
|
||||||
{
|
{
|
||||||
DJ_DWORD frq_req = 4000000; /* 4 MHz — safe and fast enough for IDCODE/IR */
|
DJ_DWORD frq_req;
|
||||||
DJ_DWORD frq_set = 0;
|
DJ_DWORD frq_set = 0;
|
||||||
|
int tck_khz;
|
||||||
|
|
||||||
(void)params;
|
(void)params;
|
||||||
|
|
||||||
|
/* Driver-neutral JTAG clock (JTAG_TCK_FREQ_KHZ, kHz). Unset/<=0 keeps
|
||||||
|
* the 4 MHz default — safe and fast enough for IDCODE/IR. */
|
||||||
|
tck_khz = jtagcore_getEnvVarValue(jc, "JTAG_TCK_FREQ_KHZ");
|
||||||
|
frq_req = (tck_khz > 0) ? (DJ_DWORD)tck_khz * 1000u : 4000000u;
|
||||||
|
|
||||||
/* Lazy enumeration: jtag_open can be called without going
|
/* Lazy enumeration: jtag_open can be called without going
|
||||||
* through jtag_probes first, so make sure Detect ran. */
|
* through jtag_probes first, so make sure Detect ran. */
|
||||||
if (g_dj_num_probes == 0) {
|
if (g_dj_num_probes == 0) {
|
||||||
|
|||||||
@@ -1863,6 +1863,20 @@ static int cmd_open_probe(script_ctx *ctx, char *line)
|
|||||||
ctx->script_printf(ctx, MSG_INFO_0, "Applied probe profile '%s'.\n", profile);
|
ctx->script_printf(ctx, MSG_INFO_0, "Applied probe profile '%s'.\n", profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Driver-neutral JTAG clock: if JTAG_TCK_FREQ_KHZ is set, feed it to
|
||||||
|
// the Viveris FTDI driver's own variable (it reads only PROBE_FTDI_*;
|
||||||
|
// our Digilent driver reads the neutral name directly). Harmless for
|
||||||
|
// the other drivers, which keep their defaults.
|
||||||
|
{
|
||||||
|
int tck_khz = jtagcore_getEnvVarValue(jc, "JTAG_TCK_FREQ_KHZ");
|
||||||
|
if (tck_khz > 0)
|
||||||
|
{
|
||||||
|
char tck_str[24];
|
||||||
|
snprintf(tck_str, sizeof(tck_str), "%d", tck_khz);
|
||||||
|
setEnvVarDat((envvar_entry *)ctx->env, "PROBE_FTDI_TCK_FREQ_KHZ", tck_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = jtagcore_select_and_open_probe(jc, id);
|
ret = jtagcore_select_and_open_probe(jc, id);
|
||||||
if (ret != JTAG_CORE_NO_ERROR)
|
if (ret != JTAG_CORE_NO_ERROR)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ defaults:
|
|||||||
# Baseline for a standalone FT2232H JTAG probe: drive ADBUS4 as the
|
# Baseline for a standalone FT2232H JTAG probe: drive ADBUS4 as the
|
||||||
# "JTAG buffer enable" output (matches the built-in default).
|
# "JTAG buffer enable" output (matches the built-in default).
|
||||||
PROBE_FTDI_SET_PIN_DIR_ADBUS4: 1
|
PROBE_FTDI_SET_PIN_DIR_ADBUS4: 1
|
||||||
|
# Driver-neutral JTAG clock in kHz. Honoured by the FTDI driver (mapped
|
||||||
|
# to PROBE_FTDI_TCK_FREQ_KHZ at open) and our Digilent driver. Leave it
|
||||||
|
# out to keep each driver's own default (FTDI 1000, Digilent 4000).
|
||||||
|
# JTAG_TCK_FREQ_KHZ: 1000
|
||||||
|
|
||||||
profiles:
|
profiles:
|
||||||
# Embedded FlashPro on Microsemi eval kits (FT4232H, JTAG on channel A
|
# Embedded FlashPro on Microsemi eval kits (FT4232H, JTAG on channel A
|
||||||
|
|||||||
Reference in New Issue
Block a user