This is an automated email from Gerrit.

Andreas Fritiofson ([email protected]) just uploaded a new patch set 
to Gerrit, which you can find at http://openocd.zylin.com/453

-- gerrit

commit d034da7b35d8c19c3c5bd4b3e75226a5651c9ac8
Author: Andreas Fritiofson <[email protected]>
Date:   Tue Jan 31 00:02:30 2012 +0100

    mpsse: add rtck support and a frequency setting helper
    
    Change-Id: I6e30c8d4af295a99727dff3003c71670a496c566
    Signed-off-by: Andreas Fritiofson <[email protected]>

diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c
index fdbf9b2..0ed0bc0 100644
--- a/src/jtag/drivers/mpsse.c
+++ b/src/jtag/drivers/mpsse.c
@@ -341,6 +341,11 @@ void mpsse_close(struct mpsse_ctx *ctx)
        free(ctx);
 }
 
+bool mpsse_is_high_speed(struct mpsse_ctx *ctx)
+{
+       return ctx->type != TYPE_FT2232C;
+}
+
 void mpsse_purge(struct mpsse_ctx *ctx)
 {
        int err;
@@ -594,19 +599,25 @@ int mpsse_read_data_bits_high_byte(struct mpsse_ctx *ctx, 
uint8_t *data)
        return retval;
 }
 
-int mpsse_loopback_config(struct mpsse_ctx *ctx, bool enable)
+static int single_byte_boolean_helper(struct mpsse_ctx *ctx, bool var, uint8_t 
val_if_true,
+       uint8_t val_if_false)
 {
-       LOG_DEBUG("%s", enable ? "on" : "off");
        int retval = ERROR_OK;
 
        if (buffer_write_space(ctx) < 1)
                retval = mpsse_flush(ctx);
 
-       buffer_write_byte(ctx, enable ? 0x84 : 0x85);
+       buffer_write_byte(ctx, var ? val_if_true : val_if_false);
 
        return retval;
 }
 
+int mpsse_loopback_config(struct mpsse_ctx *ctx, bool enable)
+{
+       LOG_DEBUG("%s", enable ? "on" : "off");
+       return single_byte_boolean_helper(ctx, enable, 0x84, 0x85);
+}
+
 int mpsse_set_divisor(struct mpsse_ctx *ctx, uint16_t divisor)
 {
        LOG_DEBUG("%d", divisor);
@@ -622,6 +633,62 @@ int mpsse_set_divisor(struct mpsse_ctx *ctx, uint16_t 
divisor)
        return retval;
 }
 
+int mpsse_divide_by_5_config(struct mpsse_ctx *ctx, bool enable)
+{
+       if (!mpsse_is_high_speed(ctx))
+               return ERROR_FAIL;
+
+       LOG_DEBUG("%s", enable ? "on" : "off");
+
+       return single_byte_boolean_helper(ctx, enable, 0x8b, 0x8a);
+}
+
+int mpsse_rtck_config(struct mpsse_ctx *ctx, bool enable)
+{
+       if (!mpsse_is_high_speed(ctx))
+               return ERROR_FAIL;
+
+       LOG_DEBUG("%s", enable ? "on" : "off");
+
+       return single_byte_boolean_helper(ctx, enable, 0x96, 0x97);
+}
+
+int mpsse_set_frequency(struct mpsse_ctx *ctx, int frequency)
+{
+       LOG_DEBUG("target %d Hz", frequency);
+       assert(frequency >= 0);
+       int base_clock;
+
+       if (frequency == 0)
+               return mpsse_rtck_config(ctx, true);
+
+       mpsse_rtck_config(ctx, false); /* just try */
+
+       if (frequency > 60000000 / 2 / 65536 && mpsse_is_high_speed(ctx)) {
+               int retval = mpsse_divide_by_5_config(ctx, false);
+               if (retval != ERROR_OK)
+                       return retval;
+               base_clock = 60000000;
+       } else {
+               mpsse_divide_by_5_config(ctx, true); /* just try */
+               base_clock = 12000000;
+       }
+
+       int divisor = (base_clock / 2 + frequency - 1) / frequency - 1;
+       if (divisor > 65535)
+               divisor = 65535;
+       assert(divisor >= 0);
+
+       int retval = mpsse_set_divisor(ctx, divisor);
+       if (retval != ERROR_OK)
+               return retval;
+
+       frequency = base_clock / 2 / (1 + divisor);
+       LOG_DEBUG("actually %d Hz", frequency);
+
+       return frequency;
+}
+
 /* Context needed by the callbacks */
 struct transfer_result {
        struct mpsse_ctx *ctx;
diff --git a/src/jtag/drivers/mpsse.h b/src/jtag/drivers/mpsse.h
index 77efdef..5d1dc04 100644
--- a/src/jtag/drivers/mpsse.h
+++ b/src/jtag/drivers/mpsse.h
@@ -40,10 +40,11 @@ enum ftdi_chip_type {
 
 struct mpsse_ctx;
 
-/* Device open/close */
+/* Device handling */
 struct mpsse_ctx *mpsse_open(uint16_t vid, uint16_t pid, const char 
*description,
                             const char *serial, int channel, unsigned char 
latency);
 void mpsse_close(struct mpsse_ctx *ctx);
+bool mpsse_is_high_speed(struct mpsse_ctx *ctx);
 
 /* Command queuing. These correspond to the MPSSE commands with the same 
names, but no need to care
  * about bit/byte transfer or data length limitation. Read data is guaranteed 
to be available only
@@ -64,6 +65,12 @@ int mpsse_read_data_bits_low_byte(struct mpsse_ctx *ctx, 
uint8_t *data);
 int mpsse_read_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t *data);
 int mpsse_loopback_config(struct mpsse_ctx *ctx, bool enable);
 int mpsse_set_divisor(struct mpsse_ctx *ctx, uint16_t divisor);
+int mpsse_divide_by_5_config(struct mpsse_ctx *ctx, bool enable);
+int mpsse_rtck_config(struct mpsse_ctx *ctx, bool enable);
+
+/* Helper to set frequency in Hertz. Returns actual realizable frequency or 
negative error.
+ * Frequency 0 means RTCK. */
+int mpsse_set_frequency(struct mpsse_ctx *ctx, int frequency);
 
 /* Queue handling */
 int mpsse_flush(struct mpsse_ctx *ctx);

-- 

------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to