[net.micro.amiga] Problems with the MICROHZ timer

darryl@psych.uq.oz (Darryl Godfrey) (08/07/86)

Brief background: (512k, Version 1.1)
	I am attempting to use an Amiga for reaction time studies involving
six inputs which come from various types of switches connected to the mouse
ports.  After realising that here in Australia, the system timer gives only 
20ms resolution (and is "changed every time someone asks what time it is" ),
I attempted to use the MICROHZ timer to give more accurate times.
Although the RKM doesn't mention it, it seems reasonable to be able to issue 
a CMD_READ after adding a time request to get a "count down" value.  Using 
some procedures below, this is what I attempted. 

The problem:
	The code fragment below (no excuses for style etc) will happily print
out what I presume are the timer driver's internal idea of where the timer
has counted down to. The numbers start at 10 seconds and count downwards 
with the occasional repeated numbers which I presume are a result of the loop
being out of sync with the timer interrupts. 

	AddTimeReq(10, 0)
	while(1) {
		GetTime( &t );	/* t is a timeval struct */
		printf("%d %d\n", t.tv_secs, t.tv_micro);
	}

If I add a Delay(1 * 50) (we are in 50hz land, remember), after the printf,
I get repeated values for t.tv_micro while the seconds count seems fine. ie. 
The sequence might be:
	10 0
	9 0
	8 0
	etc
The same problem occurs in the experiment where I call WaitPort() or Wait() 
and want to get the time immediately afterwards - I get repeated values for
the microseconds field.

	Has anyone seen this before or better still, found a way around it?
I admit my methods may not be the best, but they are in keeping with the
idea of a consistent device interface. I would like resolution of the order
of milliseconds and can't see why the MICROHZ timer can't do the job
reasonably well. Am I expecting too much from the Amiga? If I can't figure
out this one, our six Amigas won't be very useful for many psychology 
experiments.

Any help at all on this will be hugely appreciated.

	One further point, I am using the SAME timerequest struct to both
post request a timer event and to read the time in GetTime. This is because,
no matter what I did, using two timerequest structs always gave me returned
values of zero for both seconds and microseconds from GetTime. (The wrong 
result is better then none at all, right?)

The support procedures follow:

/* Local variables for timer manipulation */
struct timerequest U_Req;
struct MsgPort *U_Port = NULL;

int
OpenTimer()
{
   if ( ( U_Port = CreatePort("Micro Port", 0)) == NULL )
      	return(ERROR);
   if ( OpenDevice( TIMERNAME, UNIT_MICROHZ, &U_Req, 0) != NULL )
      	return(ERROR);
   U_Req.tr_node.io_Message.mn_ReplyPort = U_Port;
   return(0);
}

void
GetTime(time)
struct timeval *time;
{
	U_Req.tr_node.io_Command = CMD_READ;
	U_Req.tr_node.io_Flags = 0;
	U_Req.tr_node.io_Error = 0;

  	DoIO( (char *) &U_Req.tr_node );

	time->tv_secs = U_Req.tr_time.tv_secs;
	time->tv_micro = U_Req.tr_time.tv_micro;

}

void
AddTimeReq(sec, ms)
int sec, ms;
{
	U_Req.tr_node.io_Command = TR_ADDREQUEST;
	U_Req.tr_node.io_Flags = 0;
   	U_Req.tr_node.io_Error = 0;
	U_Req.tr_time.tv_secs = sec;
	U_Req.tr_time.tv_micro = ms * 1000;

	SendIO( (char *) &U_Req.tr_node );
}

hamilton@uiucuxc.CSO.UIUC.EDU (08/10/86)

>I attempted to use the MICROHZ timer to give more accurate times.
>Although the RKM doesn't mention it, it seems reasonable to be able to issue 
>a CMD_READ after adding a time request to get a "count down" value.

    reasonable or not, CMD_READ is an unimplemented command in the 1.1
timer device.  check your io_Error value after GetTime() and see if it's
-3 (IOERR_NOCMD).
    if there's any useful info to be gotten from tv_secs and tv_micros
while the time request is still pending, go ahead and read them directly;
the read request doesn't affect those values.

	wayne hamilton
	U of Il and US Army Corps of Engineers CERL
UUCP:	{ihnp4,pur-ee,convex}!uiucdcs!uiucuxc!hamilton
ARPA:	hamilton%uiucuxc@a.cs.uiuc.edu	USMail:	Box 476, Urbana, IL 61801
CSNET:	hamilton%uiucuxc@uiuc.csnet	Phone:	(217)333-8703
CIS:    [73047,544]			PLink: w hamilton

donw@zinfandel.UUCP (Don White) (08/11/86)

> Brief background: (512k, Version 1.1)
> 	I am attempting to use an Amiga for reaction time studies involving
> six inputs which come from various types of switches connected to the mouse
> ports.  After realising that here in Australia, the system timer gives only 
> 20ms resolution (and is "changed every time someone asks what time it is" ),
> I attempted to use the MICROHZ timer to give more accurate times.
> Although the RKM doesn't mention it, it seems reasonable to be able to issue 
> a CMD_READ after adding a time request to get a "count down" value.  Using 
> some procedures below, this is what I attempted. 

   I would think the most accuracy would be acheived by using forbid to stop
all other tasks, then perform assembler timing loops. I would think that this
would be the only way to be sure of accuracy. i.e. I would think it NECESSARY
to temporarily step on multitasking.

   Your assembler loops could time out after a few seconds to give back user
control. 

  This approach would be fast, efficient, and (I would think) fairly painless.  
It would also give you reaction times with a resolution of maybe a quarter of 
processor clock speed. Possibly around a half a micro second.


  Hope this helps.
  I'm posting this to the net in hopes that someone will say so if forbid won't
work like i think it will. - I could be wrong !  ;-)

     Don White
     Box 271177
     Concord CA.
     94527-1177
    
     donw@zehntel.UUCP
donw