From b2304c27084d0fbf98734a0441196b2b48fb5392 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 23 Jun 2010 20:08:35 +0000 Subject: [PATCH] start a quirks field so cables can declare cable-specific quirky behavior git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1799 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 --- urjtag/ChangeLog | 5 ++++ urjtag/include/urjtag/cable.h | 5 ++++ urjtag/src/tap/detect.c | 54 ++++++++++++++++++++++++++++------- urjtag/src/tap/idcode.c | 39 +++++++++++++++++++------ 4 files changed, 84 insertions(+), 19 deletions(-) diff --git a/urjtag/ChangeLog b/urjtag/ChangeLog index 3542d81f..03ac8394 100644 --- a/urjtag/ChangeLog +++ b/urjtag/ChangeLog @@ -7,6 +7,11 @@ * src/tap/cable/generic.c (urj_tap_cable_generic_disconnect): Clear the cable->chain link once we're done with it. + * include/urjtag/cable.h (URJ_CABLE_DRIVER): Add a quirks field, and start + a set of quirks bitfields. + * src/tap/detect.c (urj_tap_detect_parts): Handle new oneshot quirk. + * src/tap/idcode.c (urj_tap_idcode): Likewise. + 2010-06-22 Mike Frysinger * src/tap/usbconn/libftdi.c (usbconn_ftdi_flush): Fix gcc printf warning. diff --git a/urjtag/include/urjtag/cable.h b/urjtag/include/urjtag/cable.h index 9731f4d6..f5f95a7b 100644 --- a/urjtag/include/urjtag/cable.h +++ b/urjtag/include/urjtag/cable.h @@ -62,6 +62,9 @@ typedef enum URJ_CABLE_PARAM_KEY } urj_cable_param_key_t; +/* Random cable-specific quirks; a bitfield */ +#define URJ_CABLE_QUIRK_ONESHOT 0x1 + struct URJ_CABLE_DRIVER { const char *name; @@ -93,6 +96,8 @@ struct URJ_CABLE_DRIVER int (*get_signal) (urj_cable_t *, urj_pod_sigsel_t); void (*flush) (urj_cable_t *, urj_cable_flush_amount_t); void (*help) (urj_log_level_t ll, const char *); + /* A bitfield of quirks */ + uint32_t quirks; }; typedef struct URJ_CABLE_QUEUE urj_cable_queue_t; diff --git a/urjtag/src/tap/detect.c b/urjtag/src/tap/detect.c index 53432b27..39502b2a 100644 --- a/urjtag/src/tap/detect.c +++ b/urjtag/src/tap/detect.c @@ -182,8 +182,10 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) int chlen; urj_tap_register_t *one; urj_tap_register_t *ones; + urj_tap_register_t *all_ones; urj_tap_register_t *br; urj_tap_register_t *id; + urj_tap_register_t *all_ids; urj_parts_t *ps; int i; @@ -224,6 +226,21 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) urj_log (URJ_LOG_LEVEL_NORMAL, _("Chain length: %d\n"), chlen); /* Allocate registers and parts */ + if (chain->cable->driver->quirks & URJ_CABLE_QUIRK_ONESHOT) + { + all_ones = urj_tap_register_fill (urj_tap_register_alloc (32 * chlen), 1); + all_ids = urj_tap_register_alloc (32 * chlen); + if (!all_ones || !all_ids) + { + urj_tap_register_free (all_ones); + urj_tap_register_free (all_ids); + // retain error state + return -1; + } + } + else + all_ones = all_ids = NULL; + one = urj_tap_register_fill (urj_tap_register_alloc (1), 1); ones = urj_tap_register_fill (urj_tap_register_alloc (31), 1); br = urj_tap_register_alloc (1); @@ -233,8 +250,10 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) { urj_tap_register_free (one); urj_tap_register_free (ones); + urj_tap_register_free (all_ones); urj_tap_register_free (br); urj_tap_register_free (id); + urj_tap_register_free (all_ids); urj_part_parts_free (ps); // retain error state return -1; @@ -246,6 +265,9 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) urj_tap_reset (chain); urj_tap_capture_dr (chain); + if (all_ids) + urj_tap_shift_register (chain, all_ones, all_ids, URJ_CHAIN_EXITMODE_SHIFT); + for (i = 0; i < chlen; i++) { urj_part_t *part; @@ -255,12 +277,19 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) char *p; urj_part_init_func_t part_init_func; - urj_tap_shift_register (chain, one, br, URJ_CHAIN_EXITMODE_SHIFT); + if (all_ids) + br->data[0] = all_ids->data[i * 32]; + else + urj_tap_shift_register (chain, one, br, URJ_CHAIN_EXITMODE_SHIFT); + if (urj_tap_register_compare (one, br) == 0) { /* part with id */ - urj_tap_shift_register (chain, ones, id, - URJ_CHAIN_EXITMODE_SHIFT); + if (all_ids) + memcpy (id->data, &all_ids->data[i * 32 + 1], 31 * sizeof (id->data[0])); + else + urj_tap_shift_register (chain, ones, id, + URJ_CHAIN_EXITMODE_SHIFT); urj_tap_register_shift_left (id, 1); id->data[0] = 1; did = id; @@ -417,22 +446,25 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) chain->main_part = ps->len - 1; - for (i = 0; i < 32; i++) - { - urj_tap_shift_register (chain, one, br, URJ_CHAIN_EXITMODE_SHIFT); - if (urj_tap_register_compare (one, br) != 0) + if (!(chain->cable->driver->quirks & URJ_CABLE_QUIRK_ONESHOT)) + for (i = 0; i < 32; i++) { - urj_log (URJ_LOG_LEVEL_NORMAL, - _("Error: Unable to detect JTAG chain end!\n")); - break; + urj_tap_shift_register (chain, one, br, URJ_CHAIN_EXITMODE_SHIFT); + if (urj_tap_register_compare (one, br) != 0) + { + urj_log (URJ_LOG_LEVEL_NORMAL, + _("Error: Unable to detect JTAG chain end!\n")); + break; + } } - } urj_tap_shift_register (chain, one, NULL, URJ_CHAIN_EXITMODE_IDLE); urj_tap_register_free (one); urj_tap_register_free (ones); + urj_tap_register_free (all_ones); urj_tap_register_free (br); urj_tap_register_free (id); + urj_tap_register_free (all_ids); return ps->len; } diff --git a/urjtag/src/tap/idcode.c b/urjtag/src/tap/idcode.c index 917c2fdd..000838a0 100644 --- a/urjtag/src/tap/idcode.c +++ b/urjtag/src/tap/idcode.c @@ -25,10 +25,12 @@ #include #include +#include #include #include #include +#include int @@ -38,31 +40,51 @@ urj_tap_idcode (urj_chain_t *chain, unsigned int bytes) unsigned int i, hit, max_bytes; urj_tap_register_t *rz; urj_tap_register_t *rout; + urj_tap_register_t *all_rout; urj_tap_register_t *rnull; ret = URJ_STATUS_FAIL; max_bytes = bytes ? bytes : 1000; hit = 0; - urj_tap_chain_set_trst (chain, 0); - urj_tap_chain_set_trst (chain, 1); - - urj_tap_reset (chain); - urj_tap_capture_dr (chain); - /* read in chunks of 8 bits */ - rz = urj_tap_register_fill (urj_tap_register_alloc (8), 0); + if (chain->cable->driver->quirks & URJ_CABLE_QUIRK_ONESHOT) + { + all_rout = urj_tap_register_alloc (8 * max_bytes); + if (!all_rout) + return ret; + rz = urj_tap_register_fill (urj_tap_register_alloc (8 * max_bytes), 0); + } + else + { + all_rout = NULL; + rz = urj_tap_register_fill (urj_tap_register_alloc (8), 0); + } rnull = urj_tap_register_fill (urj_tap_register_alloc (8), 0); rout = urj_tap_register_alloc (8); if (!rz || !rout || !rnull) goto done; + urj_tap_chain_set_trst (chain, 0); + urj_tap_chain_set_trst (chain, 1); + + urj_tap_reset (chain); + urj_tap_capture_dr (chain); + + if (all_rout) + urj_tap_shift_register (chain, rz, all_rout, 0); + urj_log (URJ_LOG_LEVEL_NORMAL, _("Read")); for (i = 0; i < max_bytes; ++i) { uint8_t val; - urj_tap_shift_register (chain, rz, rout, 0); + + if (all_rout) + memcpy (rout->data, &all_rout->data[i * 8], 8 * sizeof (rout->data[0])); + else + urj_tap_shift_register (chain, rz, rout, 0); + val = urj_tap_register_get_value (rout); urj_log (URJ_LOG_LEVEL_NORMAL, N_(" %s(0x%x%x)"), urj_tap_register_get_string (rout), @@ -85,6 +107,7 @@ urj_tap_idcode (urj_chain_t *chain, unsigned int bytes) urj_tap_register_free (rz); urj_tap_register_free (rnull); urj_tap_register_free (rout); + urj_tap_register_free (all_rout); return ret; }