Attribute VB_Name = "HARDWARE"
'====================================================================
'                    Hardware control subroutines
'====================================================================
'Copyright information contained on About.Frm

Option Explicit

'Globals (Local)
Const COMM_DELAY = 0.5    '500 ms hardware delay time for comm timeout


'----- WIN API Calls
'GetTickCount returns the number of milliseconds that windows has
'been running
Declare Function GetTickCount Lib "Kernel32" () As Long
'
' Waits for a delay of x milliseconds
' Granularity is about 1 mS
'
Sub Delay_Milli_Seconds(msec&)
Dim start_time&

    'Delay if delay time is not zero, otherwise skip the
    'whole thing
    If msec& <> 0 Then
        'Not zero delay, so wait it out
        start_time& = GetTickCount()
        Do Until GetTickCount() > msec& + start_time&
        Loop
    End If

End Sub
'
'Pops a simple icon stop message
'
Sub Pop_Error(ByVal title$, ByVal message$)
Dim rval%
    
    rval% = MsgBox(message$, vbRetryCancel + vbExclamation, title$)
    
    'If abort selected, then bomb program
    If rval% = vbCancel Then
        End
    End If

End Sub

'Pops an information box

Sub Pop_Message(ByVal title$, ByVal message$)
Dim rval%

    rval% = MsgBox(message$, vbExclamation, title$)
    
End Sub

'Sends the command to the receiver and returns
' what we get back
'
'Inputs: char$ = command to send (sinle char, like "S")
'        response_wait% = True if the routine should wait for a response
'
'Typically returns: nothing or * or values in a * terminated string
'
Function Send_Command$(ByVal char$, ByVal response_wait%)
Dim time_out!
Dim ret$

    'Set to read entire contents of buffer
    frmMain.Comm_Control.InputLen = 0
    
    '----- Clear the input buffer of any trash
    ret$ = frmMain.Comm_Control.Input
    
    'Send the command
    frmMain.Comm_Control.Output = char$
    
    'Wait for data to be sent
    time_out! = Timer + COMM_DELAY

    Do While frmMain.Comm_Control.OutBufferCount > 0
        'This would be a good spot for a doevents
        'but it could cause recursion errors
        
        If Timer > time_out! Then
            'Timeout
            Send_Command$ = ""
            Exit Function
        End If
    Loop
    
    'Wait for the data received signal
    time_out! = Timer + COMM_DELAY

    ret$ = ""
    Do While InStr(ret$, Chr(EOT)) = 0
        
        If frmMain.Comm_Control.InBufferCount > 0 Then
            'Something in buffer, so add it to ret$
            ret$ = ret$ + frmMain.Comm_Control.Input
        End If
        
        If Timer > time_out! Then
            'Timeout
            Send_Command$ = ""
            Exit Function
        End If
    Loop

    'Check if we should return a response
    If response_wait% = False Then
        'No response, just exit
            Send_Command$ = ""
            Exit Function
    End If
    
    '----- Return from function
    Send_Command$ = ret$

End Function

'Reads the RSSI and Battery value from the receiver
'and sets the global variable values

Sub Update_Analog()
Dim ret$
Dim ctr%
    
    'Initilize the counter
    ctr% = 0

update_start:
    
    'Send the command's
    ret$ = Send_Command$("D", True)
        
    'If the response length is less than 3 then an error happened reading
    If Len(ret$) < 3 Then
        'Did not get the desired response back
        'increment the counter and try again
        If ctr% > 3 Then
            'too many times, pop an error and
            'do it again or quit function
            Pop_Error "Update_Analog:Error #1", "The program did not receive the proper response when trying to read the RSSI and Battery value. Press RETRY to try again or CANCEL to quit the program now"
            ctr% = 0
            GoTo update_start
        Else
            'Increment counter and try again
            ctr% = ctr% + 1
            GoTo update_start
        End If
    End If

    'Get the RSSI, Squelch and battery values
    
    'Scale the RSSI to 0-100 also
    'The offset and gain values are set from ini file values
    RSSI% = Asc(Mid$(ret$, 1, 1))
    
    RSSI% = (Asc(Mid$(ret$, 1, 1)) - Rssi_Offset%) * Rssi_Gain!
    If RSSI% > 100 Then
        RSSI% = 100
    End If
    If RSSI% < 0 Then
        RSSI% = 0
    End If
     
    'Scale the battery voltage (2 for the voltage divider, 19.5 mV per bit)
    'Battery_Adjust is the fudge factor to account for the divider (Typ = 1)
    Battery! = Asc(Mid$(ret$, 2, 1)) * 2 * 0.0195 * Battery_Adjust!
    
End Sub
'
' Sends the commands required to set the audio control
'
' Input: audio_setting = of'F', o'N'
' Returns: True if everything is OK, False otherwise
'
Function Set_Audio%(ByVal audio_setting$)
Dim ret$
Dim ctr%
    
    'Initilize the counter
    ctr% = 0

audio_start:
    
    'Send the command's
    ret$ = Send_Command$("A", True)
        
    If ret$ <> Chr(EOT) Then
        'Did not get the desired response back
        'increment the counter and try again
        If ctr% > 3 Then
            'too many times, pop an error and
            'do it again and quit function
            Pop_Error "Set_Audio:Error #1", "The program did not receive the proper response when trying to set the audio setting. Press RETRY to try again or CANCEL to quit the program now."
            ctr% = 0
            GoTo audio_start
        Else
            'Increment counter and try again
            ctr% = ctr% + 1
            GoTo audio_start
        End If
    End If

    'Send the audio setting
    ret$ = Send_Command$(audio_setting$, True)
    
    If ret$ <> Chr(EOT) Then
        'Did not get the desired response back
        'increment the counter and try again
        If ctr% > 3 Then
            'too many times, pop an error and
            'do it again and quit function
            Pop_Error "Set_Audio:Error #2", "The program did not receive the proper response when trying to set the audio mode. Press RETRY to try again or CANCEL to quit the program now."
            ctr% = 0
            GoTo audio_start
        Else
            'Increment counter and try again
            ctr% = ctr% + 1
            GoTo audio_start
        End If
    End If
    
End Function

'
'Sets PLL Frequency
'
Sub Set_Frequency(ByVal Frequency#)
Dim high_byte As Integer
Dim low_byte As Integer
Dim ret$
Dim temp%
Dim ctr%
Dim channel%

    'Reset counter
    ctr% = 0

    'Convert the frequency in MHz to a channel number, where ch#0 = 144 MHz
    'Channel numbers range from 0 to 800
    channel% = CInt((Frequency# - 144#) / 0.005)
    
    'Bound the channel number
    If channel% > 800 Then
        channel% = 800
    End If
    
    If channel% < 0 Then
        channel% = 0
    End If

    'Convert the channel number to high byte and low byte values
    high_byte = channel% \ 256
    temp% = high_byte * 256
    low_byte = channel% - temp%

freq_start:
    
    ret$ = Send_Command("C", True)
    If ret$ <> Chr(EOT) Then
        'Did not get the desired response back
        'increment the counter and try again
        If ctr% > 3 Then
            'too many times, pop an error and
            'do it again and quit function
            Pop_Error "Set_Frequency:Error #1", "The program did not receive the proper response when trying to set the receive frequency. Press RETRY to try again or CANCEL to quit the program now"
            ctr% = 0
            GoTo freq_start
        Else
            'Increment counter and try again
            ctr% = ctr% + 1
            GoTo freq_start
        End If
    End If
    
    'Send the PLL values
    ret$ = Send_Command(Chr$(high_byte), False) 'Nothing returned here
    ret$ = Send_Command(Chr$(low_byte), True)
    
    'check to be sure that the traling '*' was found
    If ret$ <> Chr(EOT) Then
        'Did not get the desired response back
        Pop_Error "Set_Frequency:Error #2", "The program did not receive the proper response when trying to set the channel number. Press RETRY to try again or CANCEL to quit the program now"
        ctr% = 0
        GoTo freq_start
    End If

End Sub
