[comp.sys.amiga.tech] Timer question

m81_claes@tekn01.chalmers.se (12/15/88)

I  have  been  trying  to  write  a  RTTY  encoding  program,  but  have
encountered problems  using the  timer.device. My  problem is  that when
reading the current time  the shortest time  "unit" is 1/50s  (= 20 ms),
ie. if i read current  time, then "wait", then  read it again, the "wait
time" i get is allways a multipel of 20ms!. 

  I have tried using the timer as an "alarm clock" in the ms range, and
it works fine (ok, you sometimes get to sleep 1ms or two to long, but
never 20)

  Is there anybody out there that knows if this is the way it is, or am
i doing something wrong?

  If this does not work i have to use the CIA's to check the time.

                     Claes Walther
                     CLWA@Gamma.Me.Chalmers.Se
                     Chalmers University of Technology
                     G|teborg Sweden

***** We don't do disclaimers in Sweden, we only spell wrong *****

kodiak@amiga.UUCP (Robert R. Burns) (12/22/88)

In article <427@tekn01.chalmers.se> m81_claes@tekn01.chalmers.se writes:
)I  have  been  trying  to  write  a  RTTY  encoding  program,  but  have
)encountered problems  using the  timer.device. My  problem is  that when
)reading the current time  the shortest time  "unit" is 1/50s  (= 20 ms),
)ie. if i read current  time, then "wait", then  read it again, the "wait
)time" i get is allways a multipel of 20ms!. 

The system time maintained by the timer.device is only updated every
vertical blank (in Sweden, 50Hz).  I believe that if more than one
access is made between vertical blanks, the time is bumped by one to
make it monotonically increasing, but you've correctly described it's
accuracy.

)  I have tried using the timer as an "alarm clock" in the ms range, and
)it works fine (ok, you sometimes get to sleep 1ms or two to long, but
)never 20)
)
)  Is there anybody out there that knows if this is the way it is, or am
)i doing something wrong?
)
)  If this does not work i have to use the CIA's to check the time.

If I understand your application, you don't intend to busy wait while
checking the time.  If you *were* going to do that, you should set up
an interval to wait for, using the UNIT_MICROHZ that you know works.
But I think you just need a time *stamp* with higher granularity.  You
will need to allocate another of the available CIA timers for that --
CIA timers are allocated by acquiring the associated interrupt (even
though you're not going to use that in this instance) from the cia.resource
for CIAB (note that the timers on CIAA are hard allocated, only timers
A & B on CIAB are available to allocate).

-- 
Bob Burns, amiga!kodiak                   _
| /_  _|. _ |      Commodore __          |_) _ |_  _ )'
|<(_)(_)|(_\|<      /\ |  ||| _` /\      |_)(_\| )(_\ |
| \ Software    ___/..\|\/|||__|/..\___           Faith

karl@sugar.uu.net (Karl Lehenbauer) (12/22/88)

In article <3210@amiga.UUCP>, kodiak@amiga.UUCP (Robert R. Burns) writes:
> ...If you *were* going to do that, you should set up
> an interval to wait for, using the UNIT_MICROHZ that you know works.
> But I think you just need a time *stamp* with higher granularity.  You
> will need to allocate another of the available CIA timers for that --
> CIA timers are allocated by acquiring the associated interrupt (even
> though you're not going to use that in this instance) from the cia.resource
> for CIAB (note that the timers on CIAA are hard allocated, only timers
> A & B on CIAB are available to allocate).

You mean there is a CIA timer we can grab that isn't used for the serial
port or timer.device?

A problem with timer.device is that there isn't a "periodic schedule"; that is,
I can get a mesage, signal, etc, in a certain number of milliseconds but there
is no auto-reschedule, consequently I have to reschedule and it induces timing
delays, even if I'm quick about it.  Compensation is possible if I were to
count vertical blanks and examine the vertical and horizontal beam position
to see how late I was, and compute an offset, but this is kludge-city.

The application is a MIDI sequencer and I need more accurate and more precise
timing than I can currently get through timer.device, too.  

I am considering timestamping incoming events when recording by reading the 
video beam's vertical and horizontal positions.  It's a pain to pass this
through the midi library, though, so I don't know if I'll do recording as
a "back door" thing or take a certain accuracy hit to gain consistency --
I currently have a midi module that generates midi clock messages as the
sequencer timing source and, by not connecting the clock module to the
sequencer, the sequencer can accept timing clocks from midi in.  blah blah blah
-- 
-- "We've been following your progress with considerable interest, not to say
-- contempt."  -- Zaphod Beeblebrox IV
-- uunet!sugar!karl, Unix BBS (713) 438-5018

higgin@cbmvax.UUCP (Paul Higginbottom MKT) (12/29/88)

In article <3137@sugar.uu.net> karl@sugar.uu.net (Karl Lehenbauer) writes:
$In article <3210@amiga.UUCP>, kodiak@amiga.UUCP (Robert R. Burns) writes:
$> ...for CIAB (note that the timers on CIAA are hard allocated, only timers
$> A & B on CIAB are available to allocate).
$You mean there is a CIA timer we can grab that isn't used for the serial
$port or timer.device?
$
$A problem with timer.device is that there isn't a "periodic schedule"; that is,
$I can get a mesage, signal, etc, in a certain number of milliseconds but there
$is no auto-reschedule, consequently I have to reschedule and it induces timing
$delays, even if I'm quick about it.  Compensation is possible if I were to
$count vertical blanks and examine the vertical and horizontal beam position
$to see how late I was, and compute an offset, but this is kludge-city.

Funny you should ask for this, I wrote some code to do this that's included in
Amigamail (not sure which issue, but it's either just been released or will be
shortly).

$The application is a MIDI sequencer and I need more accurate and more precise
$timing than I can currently get through timer.device, too.  

That's why I wrote the code (MIDI applications), and it's fairly obvious
how to modify for timestamping (I use the "autotimer" value in the serial
input handler to timestamp the data "no matter what's going on".

$I am considering timestamping incoming events when recording by reading the 
$video beam's vertical and horizontal positions.  It's a pain to pass this
$through the midi library, though, so I don't know if I'll do recording as
$a "back door" thing or take a certain accuracy hit to gain consistency --
$I currently have a midi module that generates midi clock messages as the
$sequencer timing source and, by not connecting the clock module to the
$sequencer, the sequencer can accept timing clocks from midi in.  blah blah blah

See above.

$-- "We've been following your progress with considerable interest, not to say
$-- contempt."  -- Zaphod Beeblebrox IV
$-- uunet!sugar!karl, Unix BBS (713) 438-5018

The only thing (I know of) possibly wrong with the code I put in Amigamail is
that it's not doing the allocation of a cia as per Matt's recent excellent
example.

	Regards,
	Paul.

mcp@ziebmef.uucp (Marc Plumb) (01/01/89)

Just to throw in an idea, I'd like to mention that the way the Inmos
transputer handles its on-chip timer is quite elegant:

There is a current time, which I'll call "now".

When you do something like a Delay(), you actually wait for a time.
There are, in fact, two timers, one of which runs at 1 MHz and one
of which runs at 1/64 that rate.  Even the faster one can fit enough range
into 32 bits (4096 seconds is over an hour) for most purposes.

If you wait for a time which is between now-0x7fffffff and now, you don't
wait at all; your time has passed already, and the call returns immediately.

If you wait for a time from now+1 to now+0x80000000, you are put in the
queue of sleeping processes and awoken when your time rolls around.

Combined with a way to get the current time, this provides all the
functionality most people want.  There's no ned to fudge to be woken up
every n microseconds.
-- 
	-Colin

karl@sugar.uu.net (Karl Lehenbauer) (01/04/89)

I have written code based on Paul Higginbottom's code published in Amiga mail
that uses one of the CIA timers to provide a microsecond-resolution realtime
clock.  What it does is install an interrupt handler that counts the number
of clicks, then it loads in a certain number, I think it's about 47000, and
runs the CIA in continuous mode.  This represents 65536 microseconds (counter 
ticks are 1.397 microseconds).  Anyway, you call this routine, currently 
called ElapsedTime and it returns the elapsed seconds and microseconds since the
interrupt handler was started.  How ElapsedTime works is it reads the counter
registers from the CIA, scales the value up to microseconds, factoring in the 
number of ticks counted by the interrupt routine and returns, as I said, seconds
and microseonds.

I use this in my SMUS player to provide a stable clock.  When I start the song,
I read the elapsed realtime in seconds and microseconds.  Then, each time
I calculate how many microseconds until the next event, I add that to my
kept elapsed time.  That value now represents the realtime when I want the
event to go off.  I then read the current realtime and subtract it from the
calculated realtime of the next event, and I now have arguments for a call to
timer.device that have taken into account time losses due to interrupt 
processing, blitter activity, context switching, etc, while I was running.  

It works.

But I think it needs to be a library, see, because I already have a couple
MIDI programs that need to make use of it.  I was thinking "library" because
it provides a way for tasks to locate the address of the long word that's
being incremented by the interrupt routine.

So I'd like a little feedback on this, and any notes on how to make it a 
library if that's the way to go.  

Email and I'll send you what I already have.  It's not very big.  If a lot
of people ask, I'll post.
-- 
-- uunet!sugar!karl  | "We've been following your progress with considerable 
-- karl@sugar.uu.net |  interest, not to say contempt."  -- Zaphod Beeblebrox IV
-- Usenet BBS (713) 438-5018

higgin@cbmvax.UUCP (Paul Higginbottom MKT) (01/06/89)

In article <3209@sugar.uu.net> karl@sugar.uu.net (Karl Lehenbauer) writes:
$I have written code based on Paul Higginbottom's code published in Amiga mail
$that uses one of the CIA timers to provide a microsecond-resolution realtime
$clock.

Someone used it!  I feel good.

$[describes his application... deleted]
$
$It works.

Even better!

$But I think it needs to be a library, see, because I already have a couple
$MIDI programs that need to make use of it.  I was thinking "library" because
$it provides a way for tasks to locate the address of the long word that's
$being incremented by the interrupt routine.

This is true.  When I wrote the code I realized that it really wasn't
"multi-tasking friendly" but my need for the functionality (as it would seem
yours) was overwhelming so I did it the way it was published.

Ideally it could be done as a handler with clients added such that each
client's timer variable can be updated.  Ooh, but how does that work given
each client will want different precision?  Perhaps a "minimum precision"
must be set, and all client precisions are a multiple of this?  This could
mean a LOT of interrupts for the main handler.  Solutions?

$So I'd like a little feedback on this, and any notes on how to make it a 
$library if that's the way to go.  

It's unclear to me how a library would help.

$-- uunet!sugar!karl  | "We've been following your progress with considerable 
$-- karl@sugar.uu.net |  interest, not to say contempt."  -- Zaphod Beeblebrox IV
$-- Usenet BBS (713) 438-5018

	Paul.

bader+@andrew.cmu.edu (Miles Bader) (01/07/89)

higgin@cbmvax.UUCP (Paul Higginbottom MKT) writes:
> Ideally it could be done as a handler with clients added such that each
> client's timer variable can be updated.  Ooh, but how does that work given
> each client will want different precision?  Perhaps a "minimum precision"
> must be set, and all client precisions are a multiple of this?  This could
> mean a LOT of interrupts for the main handler.  Solutions?

How exactly do the hardware timers work?  Can you read the hardware
count directly?

If so, you'd just set the interrupt (at which point I assume the timer
resets) interval relatively large, and when then a client asks the
library for the "current time", return the hardware count adjusted
appropiately, plus the high order bits which get bumped every timer
interrupt.

If not, then I guess you'd have to set the timer interrupt interval to
whatever the most finest granularity some client requests in advance
(but that's not a big deal, as ANY program using the timer has to do it).

So, I don't see how a library keeping track of the time for a bunch of
clients would be any more complicated than a single program hogging it...

[Why they talk of maintaining separate counters for each program?
 Just have each program ask for the time when it needs it!]

-Miles