FB II Compiler

PG PRO

Debugging

Memory

System

Mathematics

Resources

Disk I/O

Windows

Controls

Menus

Mouse

Keyboard

Text

Fonts

Drawing

Sound

Clipboard

Printing

Communication

ASM

Made with FB

MATHEMATICS

Use the Etended Time Manager


I am using the following two functions in a PG project to time the interval between state changes of the GPi serial input. The time between each change is calculated in microseconds. (Thanks to everyone for the bits of code that made this possible).

'gGPiAvailable% is set to _zTrue at startup if GPi on the modem port isavailable.
'gCurrentGPiState% is used to get the current state of the GPi input, either High or Low.
'gFirstGPiShift% is used to check if this is the first time the Function has run.
'gPreviousGPiState% stores the previous state of the GPi either High or Low.
'gTimedifference& is the difference in microseconds between each change ofthe GPi

LOCAL FN Microseconds(MSecPtr&)
'Call as follows:
'FN Microseconds(@theMSec)
'where theMSec is an 8-byte record
  ` dc.w $A193
  ` move.l ^MSecPtr&,a1
  ` move.l a0,(a1)+
  ` move.l d0,(a1)
END FN

LOCAL FN CalFrequency
'-------------------------------------

  LONG IF gGPiAvailable% = _zTrue
    gCurrentGPiState% = (PEEK([_SCCrd] + 2) AND 8) <> 8

    LONG IF gFirstGPiShift% = _False
      gFirstGPiShift% = _zTrue
      FN Microseconds(@gT1)
      gPreviousPGiState% = gCurrentGPiState%
    END IF

    LONG IF gPreviousGPiState% <> gCurrentGPiState%
      FN Microseconds(@gT2)
      gTimedifference& = [@gT2+4] - [@gT1+4]
      gLastTime& = [@gT2+4]
      POKE LONG @gT1+4, gLastTime&
      gPreviousGPiState% = gCurrentGPiState%
    END IF

  END IF
'---------------------------------------

END FN

I have seen a Developers note from Apple that states that due to various system interrupts, calling the routine etc, the accurracy can be any were between 0 and several hundred microseconds. This is not really tight enough for what I need to do.

How can I make this more accurate. Do I need to turn off other interrupts, can I write this up as an interrupt by it's self ? In general I need to try and get this timing as accurate as possible.

Oh by the way, these functions will be running in a loop while my programme does a few other things.

Sean.


Use the Extended Time Manager. I have no idea whether FB supports these calls or if they have ever been ported for FB, but that's the official Apple-sanctioned way to do it.

You can find documentation on the various permutations of the Time Manager in IM: Processes chapter 3.

It works like this: Create a TMTask record. Fill one field with the address of the ENTERPROC statement you want to have called at a specific time. Call InsXTime(@myTMTask) to install the task in the queue. Then when you're ready to go, call PrimeTime(@myTMTask, myDelayValue) where myDelayValue is the number of milliseconds before the task should be called.

You can use this to create a fixed-frequency timer effect by calling PrimeTime again from your ENTERPROC - thus the timer function keeps itself alive.

Mars


The following code might help you with the time manager stuff...
It allows for very precise timing.

Bill Sanford

LOCAL MODE
LOCAL FN InsXTime(tmTaskPtr&)
  ` MOVE.L ^tmTaskPtr&,-(SP) ;QElemPtr
  ` DC.W $205F,$A458
END FN

'-------------------------------------------------------

LOCAL MODE
LOCAL FN PrimeTime(tmTaskPtr&,count&)
  ` MOVE.L ^tmTaskPtr&,-(SP) ;QElemPtr
  ` MOVE.L ^count&,-(SP) ;LONGINT
  ` DC.W $201F,$205F,$A05A
END FN

'-------------------------------------------------------

LOCAL MODE
LOCAL FN RmvTime(tmTaskPtr&)
  ` MOVE.L ^tmTaskPtr&,-(SP) ;QElemPtr
  ` DC.W $205F,$A059
END FN

'-------------------------------------------------------

CLEAR LOCAL MODE
LOCAL FN DelayMS(msCount&)
  DIM delayTaskRec.24
  _tmUser = 22
  delayTaskRec.tmAddr& = LINE "DelayTask"
  delayTaskRec.tmCount& = 0
  delayTaskRec.tmReserved& = 0
  FN InsXTime(@delayTaskRec)
  FN PrimeTime(@delayTaskRec,msCount&)
  DO
  UNTIL delayTaskRec.tmUser%
  FN RmvTime(@delayTaskRec)
  EXIT FN
"DelayTask"
  ` ADDA.L #tmUser,A1
  ` MOVE.W #1,(A1)
  ` RTS
END FN