All of 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] 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.