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
