'-------------------------------------------------------------------------------
Option Explicit

'-------------------------------------------------------------------------------
Public Sub Main()

' This program waits for edge captures on the input capture pin. An edge
' capture occurs when a falling edge is detected on the pin.
'
' The time delay to the edge capture is compared with the time delay as
' measured by the Real Time Clock. Both values are sent to the Com1 serial
' port so you can compare the values.
'
' If no transition is detected on the pin, the edge capture overflows and
' a message is displayed to that effect. Overflow occurs about 2.3 seconds
' after EdgeCapture is called.
'
' Warning -- the Com2 or Com3 serial ports should not be used in this program
' because of conflicts with Timer1.
'
' Input capture pin number:
'
'    BX-01 => 31
'    BX-24 => 12
'    BX-35 => 20

    Dim RisingEdgeSelected As Boolean
    Dim TimeInterval As Single
    Dim HasOverflowed As Boolean
    Dim T1 As Single
    Dim T2 As Single

    RisingEdgeSelected = False   ' Wait for falling edge.

    Do
        Debug.Print "Waiting"

        T1 = Timer  ' Real time clock.

        Call EdgeCapture(RisingEdgeSelected, TimeInterval, HasOverflowed)

        T2 = Timer

        Debug.Print " Edge:  ";

        If (HasOverflowed) Then
            Debug.Print "Overflow"
        Else
            Debug.Print CStr(TimeInterval)  ' Edge capture time.
        End If

       ' Real time clock results for comparison.
        Debug.Print "  RTC:  "; CStr(T2 - T1)
        Debug.Print

        Call Delay(1.0)
    Loop

End Sub
'-------------------------------------------------------------------------------
Public Sub EdgeCapture( _
    ByVal RisingEdgeSelected As Boolean, _
    ByRef TimeInterval As Single, _
    ByRef HasOverflowed As Boolean)

' Measures the time delay until a pin transition on the Input Capture pin.
' RisingEdgeSelected determines whether to wait for a rising or falling edge.
' TimeInterval is returned, along with an overflow flag.
'
' The procedure returns when the desired edge occurs or the overflow flag
' is set -- whichever comes first. If an overflow occurs, TimeInterval is set
' to its largest allowable value, which depends on the Timer1 frequency.

    ' Timer/Counter1 Overflow Flag.
    '>>Const TOV1 As Byte = bx1000_0000     ' BX-01
    Const TOV1 As Byte = bx0000_0100     ' BX-24, BX-35

    ' Input Capture Flag 1.
    '>>Const ICF1 As Byte = bx0000_1000     ' BX-01
    Const ICF1 As Byte = bx0010_0000     ' BX-24, BX-35

    ' Input Capture1 Edge Select.   
    Const ICES1 As Byte = bx0100_0000

    Const UnitConversion As Single = 3.47222222E-5  ' 1 / 28 800

    Const OverflowValue As Long = 65535

    Dim Count As New UnsignedInteger, TIFRcopy As Byte
    Dim LowByte As Byte, HighByte As Byte

    ' Disconnect Timer/Counter1 from output pins OC1A and OC1B. Also, disable
    ' PWM operation.
    Register.TCCR1A = 0

    ' Stop Timer1.
    Register.TCCR1B = 0

    ' Clear the Timer1 value. The high byte must be written first.
    Register.TCNT1H = 0
    Register.TCNT1L = 0

    ' Clear Input Capture Flag 1. This is done by writing a logic one to
    ' the bit position.
    Register.TIFR = ICF1

    ' Clear the Timer/Counter1 Overflow Flag. This is done by writing a logic
    ' one to the bit position.
    Register.TIFR = TOV1

    ' Set the edge select bit if we're looking for a rising edge. Otherwise
    ' look for falling edge.
    If (RisingEdgeSelected) Then
        Register.TCCR1B = ICES1
    End If

    ' Start Timer1 using frequency (CK / 256), which is 28 800 Hz.
    Register.TCCR1B = Register.TCCR1B + 4

    HasOverflowed = False

    Do
        TIFRcopy = Register.TIFR

        ' Bail out if timer overflows.
        If ((TIFRcopy And TOV1) = TOV1) Then
            HasOverflowed = True
            Exit Do
        End If
    Loop Until ((TIFRcopy And ICF1) = ICF1) ' Stop if edge is detected.

    If (HasOverflowed) Then

        Count = CuInt(OverflowValue)
    Else
        ' As soon an edge is detected, the value of Timer1 is copied to
        ' registers ICR1H and ICR1L. Note that the low byte must be
        ' read first.
        LowByte = Register.ICR1L
        HighByte = Register.ICR1H

        Count = CuInt(HighByte) * 256 + CuInt(LowByte)
    End If

    TimeInterval = CSng(Count) * UnitConversion

End Sub
'-------------------------------------------------------------------------------
