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
master
Kolja Waschk 17 years ago
parent ebfeb9ea8c
commit 23394ff11d

@ -5,6 +5,9 @@
2008-02-16 Kolja Waschk <kawk>
* 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,

@ -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 * );

@ -32,11 +32,8 @@
#include <unistd.h>
#include <sys/types.h>
#include <stdint.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#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

@ -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,

@ -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,

@ -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,

@ -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,

@ -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,

@ -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,

@ -27,10 +27,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#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 )
{

@ -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 );

@ -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,

@ -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,

@ -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,

@ -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,

@ -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,

@ -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,

@ -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,

@ -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,

@ -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,

@ -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,

Loading…
Cancel
Save