[ 1194130 ] busy-loop waiting (breaks compilation of svf.c... wait for next two patches)

git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@704 b68d4a1b-bc3d-0410-92ed-d4ac073336b7
master
Kolja Waschk 17 years ago
parent a9b63dafe9
commit 0fc13035ad

@ -39,4 +39,5 @@ noinst_HEADERS = \
bssignal.h \
state.h \
jtag.h \
tap.h
tap.h \
fclock.h

@ -64,7 +64,8 @@ int cable_get_tdo( cable_t *cable );
int cable_set_trst( cable_t *cable, int trst );
int cable_get_trst( cable_t *cable );
extern uint32_t frequency;
void cable_set_frequency( cable_t *cable, uint32_t frequency );
uint32_t cable_get_frequency( cable_t *cable );
void cable_wait( void );
extern cable_driver_t *cable_drivers[];

@ -0,0 +1,47 @@
/*
* fclock.h
*
* Copyright (C) 2005 Hein Roehrig
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
*/
#ifndef FCLOCK_H
#define FCLOCK_H
#ifdef __cplusplus
extern "C" {
#endif
/* return real time in seconds starting at some arbitrary point in
time*/
long double frealtime();
/* return the CPU time used by this process (seconds) */
long double fcputime();
#ifdef __cplusplus
}
#endif
#endif

@ -63,6 +63,7 @@ jtag_LDADD = \
-L../libbrux -lbrux \
-Lbus -lbus \
-Lsvf -lsvf \
-lrt \
-lm \
@LIBINTL@

@ -27,6 +27,7 @@
#include <stdio.h>
#include "cable.h"
#include "jtag.h"
#include "cmd.h"
@ -36,7 +37,7 @@ cmd_frequency_run( char *params[] )
unsigned int freq;
if (cmd_params( params ) == 1) {
printf( _("Current TCK frequency is %u Hz\n"), frequency );
printf( _("Current TCK frequency is %u Hz\n"), cable_get_frequency(chain->cable) );
return 1;
}
@ -47,7 +48,7 @@ cmd_frequency_run( char *params[] )
return -1;
printf( _("Setting TCK frequency to %u Hz\n"), freq );
frequency = freq;
cable_set_frequency(chain->cable, freq);
return 1;
}

@ -27,4 +27,5 @@ noinst_LIBRARIES = libjtaglib.a
libjtaglib_a_SOURCES = \
getdelim.c \
getline.c
getline.c \
fclock.c

@ -0,0 +1,86 @@
/*
* fclock.c
*
* Copyright (C) 2005 Hein Roehrig
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
*/
#define _ISOC99_SOURCE
#define _POSIX_C_SOURCE 199309L
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sys/times.h>
#include <math.h>
#include <assert.h>
#ifndef CLK_TCK
static clock_t CLK_TCK = 0;
static void set_clk_tck(void) __attribute__ ((constructor));
static void set_clk_tck(void)
{
long v = sysconf(_SC_CLK_TCK);
if (v == -1) {
perror("sysconf(_SC_CLK_TCK)");
exit(EXIT_FAILURE);
}
CLK_TCK = v;
}
#endif
long double
frealtime()
{
long double result;
#ifdef _POSIX_TIMERS
struct timespec t;
if (clock_gettime(CLOCK_REALTIME, &t)==-1) {
perror("frealtime (clock_gettime)");
exit(EXIT_FAILURE);
}
result = (long double)t.tv_sec + (long double)t.tv_nsec*(long double)1e-9;
#else
struct tms t;
clock_t c=times(&t);
if (c==(clock_t)-1) {
perror("frealtime (times)");
exit(EXIT_FAILURE);
}
result = (long double)c/CLK_TCK;
#endif
assert(isnormal(result));
assert(result > 0);
return result;
}
long double
fcputime()
{
struct tms t;
clock_t c=times(&t);
if (c==(clock_t)-1) {
perror("fcputime (times)");
exit(EXIT_FAILURE);
}
return ((long double)t.tms_utime+t.tms_stime)/CLK_TCK;
}

@ -28,7 +28,11 @@
#include <unistd.h>
#include <sys/types.h>
#include <stdint.h>
#include <assert.h>
#include <math.h>
#include "fclock.h"
#include "jtag.h"
#include "cable.h"
extern cable_driver_t arcom_cable_driver;
@ -43,8 +47,6 @@ extern cable_driver_t triton_cable_driver;
extern cable_driver_t wiggler_cable_driver;
extern cable_driver_t wiggler2_cable_driver;
uint32_t frequency = 0;
cable_driver_t *cable_drivers[] = {
&arcom_cable_driver,
&byteblaster_cable_driver,
@ -102,17 +104,88 @@ cable_get_trst( cable_t *cable )
return cable->driver->get_trst( cable );
}
static uint32_t delay = 0;
static uint32_t frequency = 0;
void
cable_set_frequency( cable_t *cable, uint32_t new_frequency )
{
if (new_frequency == 0) {
delay = 0;
frequency = 0;
} else {
const double tolerance = 0.1;
uint32_t loops;
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);
}
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;
}
}
}
frequency = new_frequency;
}
}
uint32_t
cable_get_frequency( cable_t *cable )
{
return frequency;
}
void
cable_wait( void )
{
useconds_t s;
int i;
volatile int j;
if (!frequency)
if (delay == 0)
return;
s = 1000000 / frequency / 2;
if (s == 0)
s = 1;
usleep( s );
for (i = 0; i < delay; ++i) {
j = i;
}
}

Loading…
Cancel
Save