ts-7000
[Top] [All Lists]

Re: [ts-7000] Re: 983.04 Khz timer

To:
Subject: Re: [ts-7000] Re: 983.04 Khz timer
From: Lennert Buytenhek <>
Date: Wed, 19 Apr 2006 18:44:26 +0200
On Mon, Apr 17, 2006 at 05:09:02PM -0000, Jesse Off wrote:

> > I have been testing this timer using the example code, and find the
> > speed, at least on the 7260 I have to be close to  983.285 Khz. 
> 
> The speed is 983040, exactly.  It is the external 14.7456Mhz crystal 
> input divided by 15.  All you should have is the 50PPM error in the 
> 14 Mhz crystal.  The Linux system tick (and gettimeofday()), 
> however, is much less accurate.  Linux wants a precise 100.0Hz 
> system tick which cannot be arrived at perfectly from the ep93xx 
> timing hardware.  All we can get is something like 100.09Hz (I can't 
> recall exactly what it is) 

This is how the ep93xx timer interrupt is currently implemented in
linux 2.6:

static unsigned int last_jiffy_time;

#define TIMER4_TICKS_PER_JIFFY          ((CLOCK_TICK_RATE + (HZ/2)) / HZ)

static int ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
        write_seqlock(&xtime_lock);

        __raw_writel(1, EP93XX_TIMER1_CLEAR);
        while (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time
                                                >= TIMER4_TICKS_PER_JIFFY) {
                last_jiffy_time += TIMER4_TICKS_PER_JIFFY;
                timer_tick(regs);
        }

        write_sequnlock(&xtime_lock);

        return IRQ_HANDLED;
}

Coding it this way, it doesn't matter all that much whether the 100Hz
timer is 100.000Hz, 101Hz, or even 200Hz -- in the 200Hz case it'll
only call timer_tick() on every second timer interrupt.

I was being lazy when I implemented this, and so the 983040/HZ division
error will still cause some drift, but this should be easy enough to
compensate for -- just do the TIMER4_TICKS_PER_JIFFY division as a round-
to-zero instead of round-nearest division, and increment a separate
accumulator by 983040 % HZ on every timer tick, and when that accumulator
goes >= HZ, increment next_jiffy_time by one.  I'll just code that up
right now and see if it works.

For reference, gettimeoffset is implemented as follows:

static unsigned long ep93xx_gettimeoffset(void)
{
        int offset;

        offset = __raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time;

        /* Calculate (1000000 / 983040) * offset.  */
        return offset + (53 * offset / 3072);
}


cheers,
Lennert


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/ts-7000/

<*> To unsubscribe from this group, send an email to:
    

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 


<Prev in Thread] Current Thread [Next in Thread>
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU