This patch adds several enhancements to liburjtag which are used by the python bindings.

to urj_tap_detect_parts() and urj_tap_detect_register_size() I add an additional argument that overrides what used to be the hardcoded
MAX_REGISTER_LENGTH.  Existing users should pass (0) for the previous
behavior.

Two new routines are added to tap/register.c:

uint64_t urj_tap_register_get_field_value (const urj_tap_register_t *tr, int 
msb, int lsb);
int urj_tap_register_set_field_value (urj_tap_register_t *tr, uint64_t val, int 
msb, int lsb);

These allow getting and setting a subfield of made up of contiguous bits in a tap data register.
From 357e9534f6cf7907d328f8a6b26b8d66c80e1618 Mon Sep 17 00:00:00 2001
From: Steve Tell <[email protected]>
Date: Wed, 17 Aug 2011 23:54:14 -0400
Subject: [PATCH 2/3] Add urj_tap_register_set_field_value and 
urj_tap_register_get_field_value
 Allow MAX_REGISTER_LENGTH used for "detect" to be overidden at runtime.
 Setting a value just larger than the max total instruction register length
 makes detect return failure much faster if the chain is broken.
 Setting a larger value than the old default 1024 would be needed for long
 chains of complex parts.

---
 urjtag/include/urjtag/tap.h          |    8 +++--
 urjtag/include/urjtag/tap_register.h |    2 +
 urjtag/src/cmd/cmd_detect.c          |    2 +-
 urjtag/src/tap/detect.c              |   10 +++---
 urjtag/src/tap/discovery.c           |   14 +++++---
 urjtag/src/tap/register.c            |   56 ++++++++++++++++++++++++++++++++++
 6 files changed, 78 insertions(+), 14 deletions(-)

diff --git a/urjtag/include/urjtag/tap.h b/urjtag/include/urjtag/tap.h
index 0957e1d..6fd7e89 100644
--- a/urjtag/include/urjtag/tap.h
+++ b/urjtag/include/urjtag/tap.h
@@ -44,11 +44,11 @@ void urj_tap_shift_register (urj_chain_t *chain,
 
 /** API functions */
 /** @return number of detected parts on success; -1 on error */
-int urj_tap_detect_parts (urj_chain_t *chain, const char *db_path);
+int urj_tap_detect_parts (urj_chain_t *chain, const char *db_path, int 
maxirlen);
 /** @return chain length on success; -1 on error */
 int urj_tap_manual_add (urj_chain_t *chain, int instr_len);
 /** @return register size on success; -1 on error */
-int urj_tap_detect_register_size (urj_chain_t *chain);
+int urj_tap_detect_register_size (urj_chain_t *chain, int maxlen);
 /** @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on error */
 int urj_tap_discovery (urj_chain_t *chain);
 /** @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on error */
@@ -56,9 +56,11 @@ int urj_tap_idcode (urj_chain_t *chain, unsigned int bytes);
 /**
  * Convenience function that detects the parts, initialises them to BYPASS,
  * and initialises the bus drivers.
+ * maxirlen is the maximum expected length of all concatenated instruction 
+ * registers on the chain.  If set to 0, a default is assumed.
  *
  * @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on error
  */
-int urj_tap_detect (urj_chain_t *chain);
+int urj_tap_detect (urj_chain_t *chain, int maxirlen);
 
 #endif /* URJ_TAP_H */
diff --git a/urjtag/include/urjtag/tap_register.h 
b/urjtag/include/urjtag/tap_register.h
index 6d46631..d70b012 100644
--- a/urjtag/include/urjtag/tap_register.h
+++ b/urjtag/include/urjtag/tap_register.h
@@ -42,8 +42,10 @@ void urj_tap_register_free (urj_tap_register_t *tr);
 urj_tap_register_t *urj_tap_register_fill (urj_tap_register_t *tr, int val);
 int urj_tap_register_set_string (urj_tap_register_t *tr, const char *str);
 int urj_tap_register_set_value (urj_tap_register_t *tr, uint64_t val);
+int urj_tap_register_set_field_value (urj_tap_register_t *tr, uint64_t val, 
int msb, int lsb);
 const char *urj_tap_register_get_string (const urj_tap_register_t *tr);
 uint64_t urj_tap_register_get_value (const urj_tap_register_t *tr);
+uint64_t urj_tap_register_get_field_value (const urj_tap_register_t *tr, int 
msb, int lsb);
 /** @return 0 or 1 on success; -1 on error */
 int urj_tap_register_all_bits_same_value (const urj_tap_register_t *tr);
 urj_tap_register_t *urj_tap_register_init (urj_tap_register_t *tr,
diff --git a/urjtag/src/cmd/cmd_detect.c b/urjtag/src/cmd/cmd_detect.c
index 7b5ddc3..3c56995 100644
--- a/urjtag/src/cmd/cmd_detect.c
+++ b/urjtag/src/cmd/cmd_detect.c
@@ -49,7 +49,7 @@ cmd_detect_run (urj_chain_t *chain, char *params[])
     if (urj_cmd_test_cable (chain) != URJ_STATUS_OK)
         return URJ_STATUS_FAIL;
 
-    if (urj_tap_detect (chain) != URJ_STATUS_OK)
+    if (urj_tap_detect (chain, 0) != URJ_STATUS_OK)
         return URJ_STATUS_FAIL;
 
     return URJ_STATUS_OK;
diff --git a/urjtag/src/tap/detect.c b/urjtag/src/tap/detect.c
index ca85402..1cf18fd 100644
--- a/urjtag/src/tap/detect.c
+++ b/urjtag/src/tap/detect.c
@@ -175,7 +175,7 @@ find_record (char *filename, urj_tap_register_t *key, 
struct id_record *idr)
 #define strncat_const(dst, src) strncat(dst, src, sizeof(dst) - strlen(dst) - 
1)
 
 int
-urj_tap_detect_parts (urj_chain_t *chain, const char *db_path)
+urj_tap_detect_parts (urj_chain_t *chain, const char *db_path, int maxirlen)
 {
     int irlen;
     urj_tap_register_t *ir;
@@ -197,7 +197,7 @@ urj_tap_detect_parts (urj_chain_t *chain, const char 
*db_path)
     /* Detect IR length */
     urj_tap_reset (chain);
     urj_tap_capture_ir (chain);
-    irlen = urj_tap_detect_register_size (chain);
+    irlen = urj_tap_detect_register_size (chain, maxirlen);
     if (irlen < 1)
         // retain error state
         return -1;
@@ -215,7 +215,7 @@ urj_tap_detect_parts (urj_chain_t *chain, const char 
*db_path)
 
     /* Detect chain length */
     urj_tap_capture_dr (chain);
-    chlen = urj_tap_detect_register_size (chain);
+    chlen = urj_tap_detect_register_size (chain, 0);
     if (chlen < 1)
     {
         // retain error state
@@ -540,7 +540,7 @@ urj_tap_manual_add (urj_chain_t *chain, int instr_len)
 }
 
 int
-urj_tap_detect (urj_chain_t *chain)
+urj_tap_detect (urj_chain_t *chain, int maxirlen)
 {
     int i;
     urj_bus_t *abus;
@@ -548,7 +548,7 @@ urj_tap_detect (urj_chain_t *chain)
     urj_bus_buses_free ();
     urj_part_parts_free (chain->parts);
     chain->parts = NULL;
-    if (urj_tap_detect_parts (chain, urj_get_data_dir ()) == -1)
+    if (urj_tap_detect_parts (chain, urj_get_data_dir (), maxirlen) == -1)
         // retain error state
         return URJ_STATUS_FAIL;
     if (!chain->parts)
diff --git a/urjtag/src/tap/discovery.c b/urjtag/src/tap/discovery.c
index a0479c6..92149cf 100644
--- a/urjtag/src/tap/discovery.c
+++ b/urjtag/src/tap/discovery.c
@@ -33,24 +33,28 @@
 
 
 #define DETECT_PATTERN_SIZE     8
-#define MAX_REGISTER_LENGTH     1024
+#define MIN_REGISTER_LENGTH     2       /* anything less is silly */
+#define DEFAULT_MAX_REGISTER_LENGTH 1024
 #define TEST_COUNT              1
 #define TEST_THRESHOLD          100     /* in % */
 
 #undef VERY_LOW_LEVEL_DEBUG
 
 int
-urj_tap_detect_register_size (urj_chain_t *chain)
+urj_tap_detect_register_size (urj_chain_t *chain, int maxlen)
 {
     int len;
     urj_tap_register_t *rz;
     urj_tap_register_t *rout;
     urj_tap_register_t *rpat;
 
+    if(maxlen < MIN_REGISTER_LENGTH)
+        maxlen = DEFAULT_MAX_REGISTER_LENGTH;
+
     /* This seems to be a good place to check if TDO changes at all */
     int tdo, tdo_stuck = -2;
 
-    for (len = 1; len <= MAX_REGISTER_LENGTH; len++)
+    for (len = 1; len <= maxlen; len++)
     {
         int p;
         int ok = 0;
@@ -143,7 +147,7 @@ urj_tap_discovery (urj_chain_t *chain)
     fflush (stdout);
 
     urj_tap_capture_ir (chain);
-    irlen = urj_tap_detect_register_size (chain);
+    irlen = urj_tap_detect_register_size (chain, 0);
 
     urj_log (URJ_LOG_LEVEL_NORMAL, _("%d\n"), irlen);
 
@@ -179,7 +183,7 @@ urj_tap_discovery (urj_chain_t *chain)
         fflush (stdout);
 
         urj_tap_capture_dr (chain);
-        rs = urj_tap_detect_register_size (chain);
+        rs = urj_tap_detect_register_size (chain, 0);
 
         urj_log (URJ_LOG_LEVEL_NORMAL, _("%d\n"), rs);
 
diff --git a/urjtag/src/tap/register.c b/urjtag/src/tap/register.c
index 33bdd46..7423d77 100644
--- a/urjtag/src/tap/register.c
+++ b/urjtag/src/tap/register.c
@@ -203,6 +203,33 @@ urj_tap_register_set_value (urj_tap_register_t *tr, 
uint64_t val)
     return URJ_STATUS_OK;
 }
 
+int
+urj_tap_register_set_field_value (urj_tap_register_t *tr, uint64_t val, int 
msb, int lsb)
+{
+    unsigned int bit;
+
+    if (msb > tr->len-1 || lsb > tr->len-1 || msb < 0 || lsb < 0)
+    {
+        urj_error_set (URJ_ERROR_OUT_OF_BOUNDS,
+                       _("register %d:%d will not fit in %d bits"),
+                       msb, lsb, tr->len);
+        return URJ_STATUS_FAIL;
+    }
+
+    if(msb >= lsb) {
+        for (bit = lsb; bit <= msb; ++bit) {
+            tr->data[bit] = !!(val & 1);
+           val >>= 1;
+        }
+    } else {
+        for (bit = lsb; bit >= msb; --bit) {
+           tr->data[bit] = !!(val & 1);
+           val >>= 1;
+        }
+    }
+    return URJ_STATUS_OK;
+}
+
 const char *
 urj_tap_register_get_string (const urj_tap_register_t *tr)
 {
@@ -238,6 +265,35 @@ urj_tap_register_get_value (const urj_tap_register_t *tr)
     return l;
 }
 
+uint64_t
+urj_tap_register_get_field_value (const urj_tap_register_t *tr, int msb, int 
lsb)
+{
+    int bit;
+    uint64_t l, b;
+
+    if (!tr)
+        return 0;
+
+    l = 0;
+    b = 1;
+
+    if(msb >= lsb) {
+        for (bit = lsb; bit <= msb; ++bit) {
+            if (tr->data[bit] & 1)
+                l |= b;
+            b <<= 1;
+        }
+    } else {
+        for (bit = lsb; bit >= msb; --bit) {
+            if (tr->data[bit] & 1)
+                l |= b;
+            b <<= 1;
+        }
+    }
+    return l;
+}
+
+
 int
 urj_tap_register_all_bits_same_value (const urj_tap_register_t *tr)
 {
-- 
1.7.4

------------------------------------------------------------------------------
Get a FREE DOWNLOAD! and learn more about uberSVN rich system, 
user administration capabilities and model configuration. Take 
the hassle out of deploying and managing Subversion and the 
tools developers use with it. http://p.sf.net/sfu/wandisco-d2d-2
_______________________________________________
UrJTAG-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/urjtag-development

Reply via email to