Attribute VB_Name = "Timer1"
'-------------------------------------------------------------------------------
Option Explicit

Private mRangeSetting As Byte
Private UnitConversion As Single

' Timer/Counter1 overflow flag.
'>>Private Const TOV1 As Byte = bx10000000    ' BX-01
Private Const TOV1 As Byte = bx00000100    ' BX-24, BX-35
'-------------------------------------------------------------------------------
Public Sub InitializeTimer( _
    ByVal RangeSetting As Byte)

' Initializes Timer1.

' Allowable values for Resolution:
'
'              Timer            Tick         Maximum
'            Resolution      Frequency     Time Range
'   Value       (us)            (Hz)          (s)
'
'     1       0.135 633 7    7 372 800      0.008 889
'     2       1.085 069        921 600      0.071 11
'     3       8.680 555        115 200      0.568 9
'     4      34.722 22          28 800      2.276
'     5     138.888 9            7 200      9.102

    ' Processor clock rate (Hz).
    Const CK As Single = 7372800.0

    ' Enforce range constraints.
    If (RangeSetting > 5) Then
        mRangeSetting = 5
    ElseIf (RangeSetting < 1) Then
        mRangeSetting = 1
    Else
        mRangeSetting = RangeSetting
    End If

    ' Find the unit conversion number, which is used to convert from the
    ' timer count to floating point seconds.
    Select Case mRangeSetting
        Case 1
            UnitConversion = CK
        Case 2
            UnitConversion = CK / 8.0
        Case 3
            UnitConversion = CK / 64.0
        Case 4
            UnitConversion = CK / 256.0
        Case 5
            UnitConversion = CK / 1024.0
        Case Else
            UnitConversion = CK / 1024.0
    End Select

    ' Configure the Timer1 control register -- disconnect Timer1 from
    ' output pins OC1A and OC1B, and disable PWM operation of the timer.
    Register.TCCR1A = 0

    Call PutTimerCount(0)

End Sub
'-------------------------------------------------------------------------------
Public Sub StartTimer()

' Starts Timer1 after clearing it. The overflow flag is also cleared.

    Call PutTimerCount(0)

    Call ResumeTimer

End Sub
'-------------------------------------------------------------------------------
Public Sub PauseTimer()

' Stops Timer1 without affecting its current value.

    Register.TCCR1B = 0

End Sub
'-------------------------------------------------------------------------------
Public Sub ResumeTimer()

' Restarts Timer1 without affecting its current value.

    Register.TCCR1B = mRangeSetting

End Sub
'-------------------------------------------------------------------------------
Public Sub PutTimerValue( _
    ByVal NewTime As Single)

' Writes the value of Timer1 in units of seconds. The timer is also paused,
' and the overflow flag is cleared.

    Dim Count As Long

    Count = FixL(NewTime * UnitConversion + 0.5)

    Call PutTimerCount(Count)

End Sub
'-------------------------------------------------------------------------------
Public Sub GetTimerValue( _
    ByRef NewTime As Single)

' Reads the value of Timer1 in units of seconds. This procedure has no effect
' on whether the timer is running or halted. If running, it stays running. If
' halted, it stays halted.

    Dim Count As Long

    Call GetTimerCount(Count)

    NewTime = CSng(Count) / UnitConversion

End Sub
'-------------------------------------------------------------------------------
Public Function TimerHasOverflowed() As Boolean

' Returns the overflow value of Timer1.

    If ((Register.TIFR And TOV1) = TOV1) Then
        TimerHasOverflowed = True
    Else
        TimerHasOverflowed = False
    End If

End Function
'-------------------------------------------------------------------------------
Public Sub PutTimerCount( _
    ByVal Count As Long)

' Writes the Timer1 value in units of counts. The timer is also paused and
' the overflow flag is cleared.
'
' Count range is 0 .. 65535.

    Dim LowByte As Byte, HighByte As Byte

    Call PauseTimer

    HighByte = CByte(Count \ 256)

    LowByte = CByte(CuInt(Count) And &HFF)

    ' The high byte must be written first.
    Register.TCNT1H = HighByte

    Register.TCNT1L = LowByte

    Call ClearOverflowFlag

End Sub
'-------------------------------------------------------------------------------
Public Sub GetTimerCount( _
    ByRef Count As Long)

' Reads the Timer1 value in units of counts. This procedure has no effect on
' whether the timer is halted or running.
'
' Count range is 0 .. 65535.

    Dim LowByte As Byte, HighByte As Byte

    ' The low byte must be read first.
    LowByte = Register.TCNT1L

    HighByte = Register.TCNT1H

    Count = CLng(HighByte) * 256 + CLng(LowByte)

End Sub
'-------------------------------------------------------------------------------
Private Sub ClearOverflowFlag()

    ' Clear the Timer1 overflow flag.
    Register.TIFR = TOV1

End Sub
'-------------------------------------------------------------------------------
