LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
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;
}

  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] " 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 \
    --subject='Re: [PATCH update] ieee1394: cycle timer read extension for	raw1394/libraw1394' \
    /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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).