From: Pieter Palmers <pieterp@joow.be>
To: Stefan Richter <stefanr@s5r6.in-berlin.de>
Cc: Dan Dennedy <dan@dennedy.org>,
linux1394-devel@lists.sourceforge.net,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH update] ieee1394: cycle timer read extension for raw1394/libraw1394
Date: Sun, 04 Feb 2007 13:55:09 +0100 [thread overview]
Message-ID: <45C5D7AD.9080704@joow.be> (raw)
In-Reply-To: <45C4AAFA.3050208@s5r6.in-berlin.de>
[-- Attachment #1: Type: text/plain, Size: 1169 bytes --]
Stefan Richter wrote:
> Pieter Palmers wrote:
>> Stefan Richter wrote:
> ...
>>> - Fix integer overflow.
>> I had to use 1000000ULL instead of USEC_PER_SEC to avoid weird behavior.
>
> OK, I'll change that and will wait for...
>
>> I can't test it right now, but I'll report later.
>
> ...your and Dan's ACK before I commit the patch.
Stefan,
I tested the patches as posted on bugzilla, and it looks like it is
working fine.
I attached a test program I used while writing/debugging the patches.
Might be useful for other people to test if this works correctly.
Compile:
$ gcc -g -o ctr_test -lraw1394 ctr_test.c
Run:
$ ./ctr_test
libraw1394 Cycle Timer API test application
using port 0
init rate=24.5837
Local time: 1170593509294313us, 1170593509294.313ms (approx 38year,
20day since epoch)
CycleTimer: 67s, 2323cy, 1894ticks
rate: 24.583702ticks/usec
Local time: 1170593510294462us, 1170593510294.462ms (approx 38year,
20day since epoch)
CycleTimer: 68s, 2328cy, 2044ticks
rate: 24.587107ticks/usec
The rate should be something around 24.576.
Since epoch is somewhere around 1970, the approx 38 years looks rather
correct.
Greets,
Pieter
[-- Attachment #2: ctr_test.c --]
[-- Type: text/x-csrc, Size: 7530 bytes --]
/* Parts of this are originally from:
*
* FreeBob = Firewire (pro-)audio for linux
*
* http://freebob.sf.net
*
* Copyright (C) 2005,2006,2007 Pieter Palmers <pieterpalmers@users.sourceforge.net>
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
compile:
gcc -g -o ctr_test -lraw1394 ctr_test.c
*/
#include <libraw1394/raw1394.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <inttypes.h>
// Some configuration constants
#define CC_SLEEP_TIME_AFTER_DLL_UPDATE 2000
#define CC_DLL_COEFF (0.0001)
#define CC_INIT_MAX_TRIES 10
#define USECS_BETWEEN_PRINT (1000000LLU)
// Definitions and utility macro's to handle the ISO cycle timer
#define CYCLES_PER_SECOND 8000u
#define TICKS_PER_CYCLE 3072u
#define TICKS_PER_SECOND 24576000u
#define TICKS_PER_USEC (TICKS_PER_SECOND/1000000.0)
#define CYCLE_COUNTER_GET_SECS(x) ((((x) & 0xFE000000) >> 25))
#define CYCLE_COUNTER_GET_CYCLES(x) ((((x) & 0x01FFF000) >> 12))
#define CYCLE_COUNTER_GET_OFFSET(x) ((((x) & 0x00000FFF)))
#define CYCLE_COUNTER_TO_TICKS(x) ((CYCLE_COUNTER_GET_SECS(x) * TICKS_PER_SECOND) +\
(CYCLE_COUNTER_GET_CYCLES(x) * TICKS_PER_CYCLE ) +\
(CYCLE_COUNTER_GET_OFFSET(x) ))
#define CYCLE_COUNTER_UNWRAP_TICKS(x) ((x) \
+ (127 * TICKS_PER_SECOND) \
+ (CYCLES_PER_SECOND * TICKS_PER_CYCLE) \
+ (TICKS_PER_CYCLE) \
)
// globals
uint64_t m_lastmeas_usecs;
unsigned int m_cyclecounter_ticks;
double m_ticks_per_usec;
// signal handler
int keep_running=1;
static void sighandler (int sig)
{
keep_running = 0;
}
// DLL functions
int init_dll(uint64_t usecs1, unsigned int ticks1,
uint64_t usecs2, unsigned int ticks2) {
double rate=0.0;
unsigned int delta_ticks;
if (ticks2 > ticks1) {
delta_ticks=ticks2 - ticks1;
} else { // wraparound
delta_ticks=CYCLE_COUNTER_UNWRAP_TICKS(ticks2) - ticks1;
}
int delta_usecs=usecs2-usecs1;
rate=((double)delta_ticks/(double)delta_usecs);
// update the internal values
m_cyclecounter_ticks=ticks2;
m_lastmeas_usecs=usecs2;
m_ticks_per_usec=rate;
printf("init rate=%6.4f\n", rate);
}
int update_dll(uint64_t new_usecs, unsigned int new_ticks) {
uint64_t prev_usecs=m_lastmeas_usecs;
unsigned int prev_ticks=m_cyclecounter_ticks;
// the difference in system time
int delta_usecs=new_usecs-prev_usecs;
// the measured cycle counter difference
long unsigned int delta_ticks_meas;
if (new_ticks > prev_ticks) {
delta_ticks_meas=new_ticks - prev_ticks;
} else { // wraparound
delta_ticks_meas=CYCLE_COUNTER_UNWRAP_TICKS(new_ticks) - prev_ticks;
}
// the estimated cycle counter difference
unsigned int delta_ticks_est=(unsigned int)(m_ticks_per_usec * ((double)delta_usecs));
// the measured & estimated rate
double rate_meas=((double)delta_ticks_meas/(double)delta_usecs);
double rate_est=((double)m_ticks_per_usec);
int diff=(int)delta_ticks_est;
// calculate the difference in predicted ticks and
// measured ticks
diff -= delta_ticks_meas;
if (diff > 24000 || diff < -24000) { // approx +/-1 msec error
printf("Bad pred: diff=%d, dt_est=%u, dt_meas=%u, d=%dus, err=%fus\n",
diff, delta_ticks_est, delta_ticks_meas, delta_usecs, (((double)diff)/24.576)
);
}
// calculate the error
double err=rate_meas-rate_est;
// first order DLL update to obtain the rate.
m_ticks_per_usec += CC_DLL_COEFF*err;
// update the internal values
m_cyclecounter_ticks += delta_ticks_est;
// if we need to wrap, do it
if (m_cyclecounter_ticks > TICKS_PER_SECOND * 128) {
m_cyclecounter_ticks -= TICKS_PER_SECOND * 128;
}
m_lastmeas_usecs = new_usecs;
return 0;
}
// main
int32_t main(int32_t argc, char **argv)
{
int port=0;
raw1394handle_t handle;
uint64_t last_local_time=0;
struct raw1394_cycle_timer ctr;
struct raw1394_cycle_timer ctr2;
int err;
printf("libraw1394 Cycle Timer API test application\n");
if (argc==2) {
port = atoi(argv[1]);
}
printf("using port %d\n",port);
// get handle
handle = raw1394_new_handle_on_port(port);
if (handle == NULL) {
perror("raw1394_new_handle");
return -1;
}
// register signal handler
signal (SIGINT, sighandler);
signal (SIGPIPE, sighandler);
// init the DLL
err=raw1394_read_cycle_timer(handle, &ctr);
if(err) {
perror("raw1394_read_cycle_timer");
}
usleep(CC_SLEEP_TIME_AFTER_DLL_UPDATE);
err=raw1394_read_cycle_timer(handle, &ctr2);
if(err) {
perror("raw1394_read_cycle_timer");
}
init_dll(ctr.local_time,CYCLE_COUNTER_TO_TICKS(ctr.cycle_timer),
ctr2.local_time,CYCLE_COUNTER_TO_TICKS(ctr2.cycle_timer));
usleep(CC_SLEEP_TIME_AFTER_DLL_UPDATE);
printf("\n");
// start the monitor loop
while (keep_running) {
ctr.local_time=0;
err=raw1394_read_cycle_timer(handle, &ctr);
if(err) {
perror("raw1394_read_cycle_timer");
} else {
uint64_t local_time_usec=ctr.local_time;
double local_time_msec=(double)local_time_usec;
unsigned int offset=CYCLE_COUNTER_GET_OFFSET(ctr.cycle_timer);
unsigned int cycles=CYCLE_COUNTER_GET_CYCLES(ctr.cycle_timer);
unsigned int secs=CYCLE_COUNTER_GET_SECS(ctr.cycle_timer);
local_time_msec /= 1000.0;
update_dll(ctr.local_time,CYCLE_COUNTER_TO_TICKS(ctr.cycle_timer));
if ((ctr.local_time - last_local_time) > USECS_BETWEEN_PRINT) {
const uint64_t usecs_per_day=24LLU*60LLU*60LLU*1000000LLU;
const uint64_t usecs_per_year=356LLU*usecs_per_day;
uint64_t years=local_time_usec/usecs_per_year;
uint64_t days=local_time_usec%usecs_per_year;
days /= usecs_per_day;
printf("Local time: %16lluus, %16.3fms (approx %2lluyear, %3lluday since epoch)\n",
local_time_usec,local_time_msec, years, days);
printf("CycleTimer: %3us, %4ucy, %4uticks\n",secs,cycles,offset);
printf(" rate: %10.6fticks/usec\n\n",m_ticks_per_usec);
last_local_time=ctr.local_time;
}
}
usleep(CC_SLEEP_TIME_AFTER_DLL_UPDATE);
}
return 0;
}
next prev parent reply other threads:[~2007-02-04 12:58 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <45BA5CFD.6070900@joow.be>
2007-01-27 10:21 ` [RFC] cycle timer read extension for raw1394/libraw1394 Stefan Richter
2007-01-27 10:45 ` Pieter Palmers
2007-01-27 12:48 ` Stefan Richter
2007-02-03 12:58 ` [PATCH update] ieee1394: " Stefan Richter
2007-02-03 13:42 ` which header for local_irq_save? (was Re: [PATCH update] ieee1394: cycle timer read extension for raw1394/libraw1394) Stefan Richter
2007-02-03 14:22 ` [PATCH update] ieee1394: cycle timer read extension for raw1394/libraw1394 Pieter Palmers
2007-02-03 15:32 ` Stefan Richter
2007-02-04 12:55 ` Pieter Palmers [this message]
2007-02-03 16:42 ` Stefan Richter
2007-02-03 19:03 ` Stefan Richter
2007-02-03 20:18 ` Pieter Palmers
2007-02-10 14:20 ` compat_ioctl (was [PATCH update] ieee1394: cycle timer read extension for raw1394/libraw1394) Stefan Richter
2007-02-10 15:47 ` Arnd Bergmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=45C5D7AD.9080704@joow.be \
--to=pieterp@joow.be \
--cc=dan@dennedy.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux1394-devel@lists.sourceforge.net \
--cc=stefanr@s5r6.in-berlin.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.