From 23394ff11dbcb079ce34bfb305e3c209fbd22e97 Mon Sep 17 00:00:00 2001 From: Kolja Waschk Date: Sat, 16 Feb 2008 16:25:51 +0000 Subject: [PATCH] Moved set_frequency function from cable.c to cable_drivers git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1030 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 --- jtag/ChangeLog | 3 ++ jtag/include/cable.h | 1 + jtag/src/tap/cable.c | 68 +--------------------------- jtag/src/tap/cable/arcom.c | 1 + jtag/src/tap/cable/byteblaster.c | 1 + jtag/src/tap/cable/dlc5.c | 1 + jtag/src/tap/cable/ea253.c | 1 + jtag/src/tap/cable/ei012.c | 1 + jtag/src/tap/cable/ft2232.c | 11 ++--- jtag/src/tap/cable/generic.c | 73 +++++++++++++++++++++++++++++- jtag/src/tap/cable/generic.h | 1 + jtag/src/tap/cable/jim.c | 1 + jtag/src/tap/cable/keithkoep.c | 1 + jtag/src/tap/cable/lattice.c | 1 + jtag/src/tap/cable/mpcbdm.c | 1 + jtag/src/tap/cable/triton.c | 1 + jtag/src/tap/cable/usbblaster.c | 5 ++ jtag/src/tap/cable/vision_ep9307.c | 1 + jtag/src/tap/cable/wiggler.c | 2 + jtag/src/tap/cable/wiggler2.c | 1 + jtag/src/tap/cable/xpc.c | 11 +++-- 21 files changed, 110 insertions(+), 77 deletions(-) diff --git a/jtag/ChangeLog b/jtag/ChangeLog index ff702faa..a5f92376 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -5,6 +5,9 @@ 2008-02-16 Kolja Waschk * doc/UrJTAG.txt: Updated doc about building with FTD2XX in Cygwin + * src/tap/cable.c, include/cable.h, src/tap/cable/*.c (all drivers): + moved cable_set_frequency functionality from cable.c to the cable + drivers, to fix [ 1836319 ] Delay loop calibration takes ages * src/tap/cable.c: Include ftdi-based cable drivers if either libftdi or FTDI's FTD2XX (CDM) drivers are present (--with-ftd2xx) * src/flash/Makefile.am, src/flash/jedec_exp.c, src/flash/detectflash.c, diff --git a/jtag/include/cable.h b/jtag/include/cable.h index 53d4983e..42704d3f 100644 --- a/jtag/include/cable.h +++ b/jtag/include/cable.h @@ -52,6 +52,7 @@ struct cable_driver_t { void (*cable_free)( cable_t *cable ); int (*init)( cable_t * ); void (*done)( cable_t * ); + void (*set_frequency)( cable_t *, uint32_t freq ); void (*clock)( cable_t *, int, int, int ); int (*get_tdo)( cable_t * ); int (*transfer)( cable_t *, int, char *, char * ); diff --git a/jtag/src/tap/cable.c b/jtag/src/tap/cable.c index f5c920a2..c2388133 100644 --- a/jtag/src/tap/cable.c +++ b/jtag/src/tap/cable.c @@ -32,11 +32,8 @@ #include #include #include -#include -#include #include -#include "fclock.h" #include "jtag.h" #include "cable.h" @@ -529,69 +526,8 @@ cable_defer_transfer( cable_t *cable, int len, char *in, char *out ) void cable_set_frequency( cable_t *cable, uint32_t new_frequency ) { - if (new_frequency == 0) { - cable->delay = 0; - cable-> frequency = 0; - } else { - const double tolerance = 0.1; - uint32_t loops; - uint32_t delay = cable->delay; - uint32_t frequency = cable->frequency; - - printf("requested frequency %u, now calibrating delay loop\n", new_frequency); - - if (delay == 0) { - delay = 1000; - loops = 10000; - } else { - loops = 3 * frequency; - } - - while (1) { - uint32_t i, new_delay; - long double start, end, real_frequency; - - start = frealtime(); - for (i = 0; i < loops; ++i) { - chain_clock(chain, 0, 0, 1); - } - end = frealtime(); - - assert(end > start); - real_frequency = (long double)loops / (end - start); - printf("new real frequency %Lg, delay %u\n", - real_frequency, delay); - - loops = 3 * fmax(real_frequency, new_frequency); - new_delay = (long double)delay * real_frequency / new_frequency; - - if (real_frequency >= (1.0 - tolerance)*new_frequency) { - if (real_frequency <= (1.0 + tolerance)*new_frequency) { - break; - } - if (new_delay > delay) { - delay = new_delay; - } else { - delay++; - } - } else { - if (new_delay < delay) { - delay = new_delay; - } else { - delay--; - } - if (delay == 0) { - printf("operating without delay\n"); - break; - } - } - } - - printf("done\n"); - - cable->delay = delay; - cable->frequency = frequency; - } + cable_flush( cable, COMPLETELY ); + cable->driver->set_frequency( cable, new_frequency ); } uint32_t diff --git a/jtag/src/tap/cable/arcom.c b/jtag/src/tap/cable/arcom.c index 54b82475..aaec0cb4 100644 --- a/jtag/src/tap/cable/arcom.c +++ b/jtag/src/tap/cable/arcom.c @@ -107,6 +107,7 @@ cable_driver_t arcom_cable_driver = { generic_cable_free, arcom_init, generic_done, + generic_set_frequency, arcom_clock, arcom_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/byteblaster.c b/jtag/src/tap/cable/byteblaster.c index 0b6f7dea..d317eeec 100644 --- a/jtag/src/tap/cable/byteblaster.c +++ b/jtag/src/tap/cable/byteblaster.c @@ -133,6 +133,7 @@ cable_driver_t byteblaster_cable_driver = { generic_cable_free, byteblaster_init, generic_done, + generic_set_frequency, byteblaster_clock, byteblaster_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/dlc5.c b/jtag/src/tap/cable/dlc5.c index 6fb224e9..727dcc79 100644 --- a/jtag/src/tap/cable/dlc5.c +++ b/jtag/src/tap/cable/dlc5.c @@ -104,6 +104,7 @@ cable_driver_t dlc5_cable_driver = { generic_cable_free, dlc5_init, generic_done, + generic_set_frequency, dlc5_clock, dlc5_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/ea253.c b/jtag/src/tap/cable/ea253.c index 36552586..e15928b2 100644 --- a/jtag/src/tap/cable/ea253.c +++ b/jtag/src/tap/cable/ea253.c @@ -107,6 +107,7 @@ cable_driver_t ea253_cable_driver = { generic_cable_free, ea253_init, generic_done, + generic_set_frequency, ea253_clock, ea253_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/ei012.c b/jtag/src/tap/cable/ei012.c index cc31b884..b8bc8cc0 100644 --- a/jtag/src/tap/cable/ei012.c +++ b/jtag/src/tap/cable/ei012.c @@ -109,6 +109,7 @@ cable_driver_t ei012_cable_driver = { generic_cable_free, ei012_init, generic_done, + generic_set_frequency, ei012_clock, ei012_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/ft2232.c b/jtag/src/tap/cable/ft2232.c index 1d6fcec3..9ccd3985 100644 --- a/jtag/src/tap/cable/ft2232.c +++ b/jtag/src/tap/cable/ft2232.c @@ -254,9 +254,8 @@ pop_to_recv( params_t *params ) static void -update_frequency( cable_t *cable ) +ft2232_set_frequency( cable_t *cable, uint32_t new_frequency ) { - uint32_t new_frequency = cable_get_frequency( cable ); params_t *params = (params_t *)cable->params; if (!new_frequency || new_frequency > FT2232_MAX_TCK_FREQ) @@ -549,9 +548,6 @@ ft2232_clock_schedule( cable_t *cable, int tms, int tdi, int n ) tms = tms ? 0x7f : 0; tdi = tdi ? 1 << 7 : 0; - /* check for new frequency setting */ - update_frequency( cable ); - while (n > 0) { /* Clock Data to TMS/CS Pin (no Read) */ push_to_send( params, MPSSE_WRITE_TMS | @@ -805,8 +801,6 @@ ft2232_transfer_finish( cable_t *cable, int len, char *out ) static int ft2232_transfer( cable_t *cable, int len, char *in, char *out ) { - /* check for new frequency setting */ - update_frequency( cable ); ft2232_transfer_schedule( cable, len, in, out ); send_and_receive( cable ); return ft2232_transfer_finish( cable, len, out ); @@ -1050,6 +1044,7 @@ cable_driver_t ft2232_cable_driver = { ft2232_cable_free, ft2232_generic_init, ft2232_generic_done, + ft2232_set_frequency, ft2232_clock, ft2232_get_tdo, ft2232_transfer, @@ -1067,6 +1062,7 @@ cable_driver_t ft2232_armusbocd_cable_driver = { ft2232_cable_free, ft2232_armusbocd_init, ft2232_armusbocd_done, + ft2232_set_frequency, ft2232_clock, ft2232_get_tdo, ft2232_transfer, @@ -1084,6 +1080,7 @@ cable_driver_t ft2232_jtagkey_cable_driver = { ft2232_cable_free, ft2232_jtagkey_init, ft2232_jtagkey_done, + ft2232_set_frequency, ft2232_clock, ft2232_get_tdo, ft2232_transfer, diff --git a/jtag/src/tap/cable/generic.c b/jtag/src/tap/cable/generic.c index 453fd09f..0f8e4144 100644 --- a/jtag/src/tap/cable/generic.c +++ b/jtag/src/tap/cable/generic.c @@ -27,10 +27,13 @@ #include #include #include +#include +#include #include "cable.h" #include "parport.h" #include "chain.h" +#include "fclock.h" #include "generic.h" @@ -244,7 +247,7 @@ generic_flush_using_transfer( cable_t *cable, cable_flush_amount_t how_much ) do { - int r, bits = 0, tdo; + int r, bits = 0, tdo = 0; #ifdef VERBOSE printf("flush(%d)\n", cable->todo.num_items); @@ -398,6 +401,74 @@ generic_flush_using_transfer( cable_t *cable, cable_flush_amount_t how_much ) while(cable->todo.num_items > 0); } +void +generic_set_frequency( cable_t *cable, uint32_t new_frequency ) +{ + if (new_frequency == 0) { + cable->delay = 0; + cable-> frequency = 0; + } else { + const double tolerance = 0.1; + uint32_t loops; + uint32_t delay = cable->delay; + uint32_t frequency = cable->frequency; + + printf("requested frequency %u, now calibrating delay loop\n", new_frequency); + + if (delay == 0) { + delay = 1000; + loops = 10000; + } else { + loops = 3 * frequency; + } + + while (1) { + uint32_t i, new_delay; + long double start, end, real_frequency; + + start = frealtime(); + for (i = 0; i < loops; ++i) { + cable->driver->clock(cable, 0, 0, 1); + } + end = frealtime(); + + assert(end > start); + real_frequency = (long double)loops / (end - start); + printf("new real frequency %Lg, delay %u\n", + real_frequency, delay); + + loops = 3 * fmax(real_frequency, new_frequency); + new_delay = (long double)delay * real_frequency / new_frequency; + + if (real_frequency >= (1.0 - tolerance)*new_frequency) { + if (real_frequency <= (1.0 + tolerance)*new_frequency) { + break; + } + if (new_delay > delay) { + delay = new_delay; + } else { + delay++; + } + } else { + if (new_delay < delay) { + delay = new_delay; + } else { + delay--; + } + if (delay == 0) { + printf("operating without delay\n"); + break; + } + } + } + + printf("done\n"); + + cable->delay = delay; + cable->frequency = frequency; + } +} + void generic_lptcable_help( const char *cablename ) { diff --git a/jtag/src/tap/cable/generic.h b/jtag/src/tap/cable/generic.h index 55935299..1d549e7b 100644 --- a/jtag/src/tap/cable/generic.h +++ b/jtag/src/tap/cable/generic.h @@ -40,6 +40,7 @@ int generic_connect( char *params[], cable_t *cable ); void generic_disconnect( cable_t *cable ); void generic_cable_free( cable_t *cable ); void generic_done( cable_t *cable ); +void generic_set_frequency( cable_t *cable, uint32_t new_freq ); int generic_transfer( cable_t *cable, int len, char *in, char *out ); int generic_get_trst( cable_t *cable ); void generic_flush_one_by_one( cable_t *cable, cable_flush_amount_t hm ); diff --git a/jtag/src/tap/cable/jim.c b/jtag/src/tap/cable/jim.c index 76216b51..5a675f9f 100644 --- a/jtag/src/tap/cable/jim.c +++ b/jtag/src/tap/cable/jim.c @@ -166,6 +166,7 @@ cable_driver_t jim_cable_driver = { jim_cable_free, jim_cable_init, jim_cable_done, + generic_set_frequency, jim_cable_clock, jim_cable_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/keithkoep.c b/jtag/src/tap/cable/keithkoep.c index 90028409..3e23222c 100644 --- a/jtag/src/tap/cable/keithkoep.c +++ b/jtag/src/tap/cable/keithkoep.c @@ -116,6 +116,7 @@ cable_driver_t keithkoep_cable_driver = { generic_cable_free, keithkoep_init, generic_done, + generic_set_frequency, keithkoep_clock, keithkoep_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/lattice.c b/jtag/src/tap/cable/lattice.c index e99ed371..a414ea21 100644 --- a/jtag/src/tap/cable/lattice.c +++ b/jtag/src/tap/cable/lattice.c @@ -99,6 +99,7 @@ cable_driver_t lattice_cable_driver = { generic_cable_free, lattice_init, generic_done, + generic_set_frequency, lattice_clock, lattice_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/mpcbdm.c b/jtag/src/tap/cable/mpcbdm.c index e115e78a..95afd4c3 100644 --- a/jtag/src/tap/cable/mpcbdm.c +++ b/jtag/src/tap/cable/mpcbdm.c @@ -113,6 +113,7 @@ cable_driver_t mpcbdm_cable_driver = { generic_cable_free, mpcbdm_init, generic_done, + generic_set_frequency, mpcbdm_clock, mpcbdm_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/triton.c b/jtag/src/tap/cable/triton.c index a197fade..256462f2 100644 --- a/jtag/src/tap/cable/triton.c +++ b/jtag/src/tap/cable/triton.c @@ -118,6 +118,7 @@ cable_driver_t triton_cable_driver = { generic_cable_free, triton_init, generic_done, + generic_set_frequency, triton_clock, triton_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/usbblaster.c b/jtag/src/tap/cable/usbblaster.c index 69cac14c..dfa9ffec 100644 --- a/jtag/src/tap/cable/usbblaster.c +++ b/jtag/src/tap/cable/usbblaster.c @@ -300,6 +300,10 @@ usbblaster_flush( cable_t *cable, cable_flush_amount_t how_much ) } } +void +usbblaster_set_frequency( cable_t *cable, uint32_t new_frequency ) +{ +} void usbblaster_help( const char *cablename ) @@ -321,6 +325,7 @@ cable_driver_t usbblaster_cable_driver = { generic_cable_free, usbblaster_init, generic_done, + usbblaster_set_frequency, usbblaster_clock, usbblaster_get_tdo, usbblaster_transfer, diff --git a/jtag/src/tap/cable/vision_ep9307.c b/jtag/src/tap/cable/vision_ep9307.c index 50d99eeb..3f94dd42 100644 --- a/jtag/src/tap/cable/vision_ep9307.c +++ b/jtag/src/tap/cable/vision_ep9307.c @@ -314,6 +314,7 @@ cable_driver_t ep9307_cable_driver = { ep9307_cable_free, ep9307_init, ep9307_done, + generic_set_frequency, ep9307_clock, ep9307_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/wiggler.c b/jtag/src/tap/cable/wiggler.c index f03bff74..3b5a99bd 100644 --- a/jtag/src/tap/cable/wiggler.c +++ b/jtag/src/tap/cable/wiggler.c @@ -324,6 +324,7 @@ cable_driver_t wiggler_cable_driver = { generic_cable_free, wiggler_init, generic_done, + generic_set_frequency, wiggler_clock, wiggler_get_tdo, generic_transfer, @@ -341,6 +342,7 @@ cable_driver_t igloo_cable_driver = { generic_cable_free, wiggler_init, generic_done, + generic_set_frequency, wiggler_clock, wiggler_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/wiggler2.c b/jtag/src/tap/cable/wiggler2.c index 16d0a81e..9796c2fa 100644 --- a/jtag/src/tap/cable/wiggler2.c +++ b/jtag/src/tap/cable/wiggler2.c @@ -123,6 +123,7 @@ cable_driver_t wiggler2_cable_driver = { generic_cable_free, wiggler2_init, generic_done, + generic_set_frequency, wiggler2_clock, wiggler2_get_tdo, generic_transfer, diff --git a/jtag/src/tap/cable/xpc.c b/jtag/src/tap/cable/xpc.c index 6cef10e9..24dacb82 100644 --- a/jtag/src/tap/cable/xpc.c +++ b/jtag/src/tap/cable/xpc.c @@ -73,12 +73,9 @@ xpc_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; parport_set_data( cable->port, (1 << PROG) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); - cable_wait( cable ); for (i = 0; i < n; i++) { parport_set_data( cable->port, (1 << PROG) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); - cable_wait( cable ); parport_set_data( cable->port, (1 << PROG) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); - cable_wait( cable ); } } @@ -94,6 +91,12 @@ xpc_set_trst( cable_t *cable, int trst ) return 1; } +void +xpc_set_frequency( cable_t *cable, uint32_t new_frequency ) +{ +} + + void xpcu_usbcable_help( const char *cablename ) { @@ -114,6 +117,7 @@ cable_driver_t xpc_int_cable_driver = { generic_cable_free, xpc_int_init, generic_done, + xpc_set_frequency, xpc_clock, xpc_get_tdo, generic_transfer, @@ -131,6 +135,7 @@ cable_driver_t xpc_ext_cable_driver = { generic_cable_free, xpc_ext_init, generic_done, + xpc_set_frequency, xpc_clock, xpc_get_tdo, generic_transfer,