Attribute VB_Name = "mod_LL_USB"
' 3217 Phoenixville Pike
' Malvern, PA  19355
' 800 321-5355 or 610 725-8800
' http://www.lawsonlabs.com
' Uses DLL: LL_USB2k.DLL
' Uses LL_USB.cfg
' Version 2.04.2008
' Last updated: 2-21-2008
' filename: LL_USB.bas

Option Explicit


Public dblScanDigoutWaitStartSRI(32) As Double
Public fScanDigoutWaitBusySRI(32) As Boolean



'12-13-04
Public fUseNewConfig As Boolean
'10-06-04
Public vScanDigIOdup_Timer(32) As Variant
'5-3-04
Public bUseInHouseAutoConfig As Byte

'9-20-05
Public bDigoutShopTest As Byte

'5-3-04 START #####################
'from config.ini
'[301]
Public CC_bScanType As Byte
Public CC_iScanAvg As Integer
Public CC_bScanDoDiginScan  As Byte
Public CC_bScanDoCalScan As Byte
Public CC_bScanNumChans As Byte
Public CC_bScanChanForSingleChanScan  As Byte

Public CC_dblInternalDataRate As Double

Public CC_dblDAC0_Volts As Double
Public CC_dblDAC1_Volts As Double
Public CC_dblDAC2_Volts As Double
'5-3-04 END   #####################




'========================================
'9-17-02 START IN-HOUSE testing =========

'#define SCAN_END_REQUEST           0x01
'#define SCAN_END_REQUEST_ACK       0x02
'#define SCAN_END_REQUEST_SENT      0x04
'#define SCAN_END_REQUEST_PENDING   0x08
'#define SCAN_END_REQUEST_FAILED    0x10
'#define SCAN_END_REQUEST_SUCCEEDED 0x20
'#define SCAN_DRIVER_THREAD_EXITED  0x40
Public Const SCAN_END_REQUEST = &H1
Public Const SCAN_END_REQUEST_ACK = &H2
Public Const SCAN_END_REQUEST_SENT = &H4
Public Const SCAN_END_REQUEST_PENDING = &H8
Public Const SCAN_END_REQUEST_FAILED = &H10
Public Const SCAN_END_REQUEST_SUCCEEDED = &H20
Public Const SCAN_DRIVER_THREAD_EXITED = &H40




Public bReadCfgCalled As Byte
Public bIsJusticeBoard As Byte
'Type CUR_CONFIG
'    CC_usDevID As Integer
'    CC_bScanType As Byte        '1 = single-chan scan, 2 = multi-chan, 3 = multi-chan with offset calibration
'    CC_iScanAvg As Integer
'    CC_bScanDoDiginScan As Byte
'    CC_bScanDoCalScan As Byte
'    CC_bScanNumChans As Byte
'    CC_bScanChanForSingleChanScan As Byte
'
'    CC_dblInternalDataRate As Double
'    CC_bConnectionStatus As Long
'    CC_bDAC0_Volts As Double
'    CC_bDAC1_Volts As Double
'    CC_bDAC2_Volts As Double
'End Type
'
''TIM NOTE: Not sure why following array is so big when there are only 32 devices.
'Public CurConfigArray(40) As CUR_CONFIG


Public fDebugFileExists As Boolean
Public TimerTime As Double
Public L_TimerInterval As Long
Public bDoScanDigoutTesting As Byte
Public bTestDigOutValToSend As Byte
Public fScanDigoutErr(32) As Boolean
Public bScanDigout(32) As Byte
Public bScanDigoutOld(32) As Byte
Public bScanDigoutSameTwoTest_Val(32) As Byte
Public bScanDigoutSameTwoTest_Flag(32) As Byte
Public bScanDigout_AnyTwoSameErr(32) As Boolean
'9-17-02 END IN-HOUSE testing ============
'========================================

Public usProgressBar2Val As Integer

'NOTE: Variable prefixing convention:
'f = Boolean(flag - True/False), b = Byte,
's = 16-bit integer(short), i = 32-bit integer(long)
'Constants are ALL CAPS
Public Const ARG_IGNORED = 0

Public usNewScanBuffWrap(32) As Integer
Public usNewMicroBuffWrap(32) As Integer
Public usNewScanPackErr(32) As Integer

Public Const MAX_DEV_CNT = 32
Public Const MAX_DEV_CNT_MINUS_ONE = 31

Public usStatDevList(MAX_DEV_CNT) As Integer
Public usStatDevFlags(MAX_DEV_CNT) As Long



'============================= CODE BLOCKS =============================
'====    Use with EDIT/FIND to find similiar function and code     =====
'====             groupings within the source code file.           =====
'=======================================================================
'**** External functions from LL_USB2k.DLL ******************************
'**** R E A D / W R I T E   C O N F I G U R A T I O N   F I L E ********
'**** C O N T R O L   V I S I B I L I T Y   H A N D L I N G  ***********
'**** S Y S T E M    C A L I B R A T I O N  ****************************
Public bTotalScanChans As Byte

Public usModelNum As Integer
Public fSkipModelChk As Boolean

Public bNumScanChansRequested As Byte
Public bMultiScanActiveChans(8) As Byte
Public bCurMultiScanChan As Byte
Public sCurMultiOffsetIndex As Integer

Public dblScanChan0_SAVE As Double
Public bDAC As Byte
Public dblDAC_VOLTS As Double
'Set flag below for 1volt input range, leave 0 for 5volt input range
'Public Const FLAG_INPUT_RANGE = 1

'#######################################################
' START Graphics variables
'#######################################################
Public dblDotCol    'HR
Public sLastY As Integer
Public sVFrame As Integer
Public sHFrame As Integer
Public sDotCol As Integer
Public sYPixTotal As Integer
Public sXPixTotal As Integer
Public sDotColorChange As Integer
Public iY As Long
Public dblX As Double
Public dblYFS As Double
Public dblLastX As Double
Public dblYRange As Double
Public dblYIndex As Double
Public dblXRange As Double
Public dblXIndex As Double
Public dblPixsPerS As Double
Public dblPixPerDP As Double
Public dblYIndexPix As Double
Public dblXIndexPix As Double
Public dblPixsPerVolt As Double
Public dblCurScanRate(MAX_DEV_CNT) As Double
Public dblZoomFactor As Double
Public dblPercentFullScale As Double
Public fCenterGraph As Boolean
Public fGraphIsDisplayed As Boolean
Public bCurrentChanForGraph(MAX_DEV_CNT) As Byte
'#######################################################
'END  Graphics variables
'#######################################################


'====================>


'#######################################################
' START Scan Voltage Averaging variables
'#######################################################
Public dblVoltAvgTotal_MULTI(8) As Double
Public dblVoltAvgArray_MULTI(8, 32) As Double
Public sVoltAvgArrayIndex_MULTI(8) As Integer
Public bVoltAvgArrayFirstTimeInFlag_MULTI(8) As Integer
Public bAvgVal As Byte
Public bVoltAvgArrayFirstTimeInFlag As Byte
Public usVoltAvgArrayIndex As Integer
Public dblVoltAvgTotal As Double
Public dblVoltAvgArray() As Double
'#######################################################
'END  Scan Voltage Averaging variables
'#######################################################


'====================>


'#######################################################
' START Scanning variables (non graphic)
'#######################################################
Public bScanBoostVal As Byte
Public bThisScanDevIndex As Byte
Public bStopScanDevIndex As Byte
Public fScanEndInProgress(32) As Boolean
Public fTimerEndScanCallEntered As Boolean
Public fScanEndNeeded() As Boolean
Public fNeedToUpdateCurScanDevIndex As Boolean


Public bSDGroup As Integer
Public bCurScanDevIndex As Byte
Public bDevicesCurrentlyScanning() As Byte
Public bScanDynaDiginBuff() As Byte
Public bScanLastDigin(MAX_DEV_CNT) As Byte

Public iScanNum(MAX_DEV_CNT) As Long
Public iDynaVoltageBuff() As Long


Public fScanEnd As Boolean
Public fAnyScanRunning As Boolean
Public fDoScanDataFile As Boolean
Public fScanDataFileOpened As Boolean

Public dblEffectiveBits As Double
Public dblStandardDeviation() As Double
Public dblStandardDeviationTotal As Double
Public dblScanRate(MAX_DEV_CNT) As Long
Public dblStandardDeviationCount  As Long

Type SCAN_OBJECT
    SO_bScanType As Byte        '1 = single-chan scan, 2 = multi-chan, 3 = multi-chan with offset calibration
    SO_dblInternalDataRate As Double
    SO_iTotalPointsReadByDrvr As Long
    SO_iPointsInBuffer As Long
    SO_iStatus As Long
    SO_iSizeVoltageArray As Long
    SO_iCurHead As Long
    SO_iCurTail As Long
    SO_bDigitalInput As Byte
    SO_bChecksum As Byte
    SO_DeviceDisconnect As Byte     'no longer used - see SCAN_DEVICE_DISCONNECTED flag for SO_iStatus
    SO_iScanStartTime As Long       'clock_t SO_ScanStartTime not used by app;
    SO_iScanEndTime As Long         'clock_t SO_ScanEndTime not used by app;
    SO_bScanArg As Byte             'argument to scan
End Type
Public ScanObjectArray() As SCAN_OBJECT
'#######################################################
'END  Scanning variables (non graphic)
'#######################################################


'====================>


'#######################################################
' START DeviceID Related variables
'#######################################################
'Description of individual devices
Type DEVICE_OBJECT
    DEV_sID As Integer
    DEV_bChan As Byte
    DEV_dblRate As Double
    DEV_bStat As Byte
    DEV_lScanBuffSize As Long
End Type
Public DeviceObject As DEVICE_OBJECT
Public DeviceObjectArray(MAX_DEV_CNT) As DEVICE_OBJECT

Public bNumDevicesLocal As Byte
Public bNumDevicesShared As Byte
Public bCurIndexOfSelectedDev As Byte
Public bDeviceRemovedOrInstalled As Byte

Public sDefDeviceID As Integer
Public sDeviceIDToReinit As Integer
Public sCurrentDevice As Integer
Public sLLABS_DeviceIDList(MAX_DEV_CNT) As Integer
Public sLLABS_DeviceIDList_free() As Integer
Public sLLABS_DeviceIDToRelease(MAX_DEV_CNT) As Integer
Public sCurDevToReset As Integer

Public fOkToChangeComboWhichDevice As Boolean   'Required to allow contents of this  box to only be changed by application but not directly by user.
Public fDevRemovedReloadCfg As Boolean

Public strSetupComboDeviceNum As String
'#######################################################
'END  DeviceID Related variables
'#######################################################


'====================>


'#######################################################
' START chan and digout variables
'#######################################################
Public bCurChan As Byte
Public bChanToSend As Byte
Public bDigOutVal As Byte
Public bChangeDefCfgStat As Byte
Public fDigOutPending As Boolean
Public fChanChangePending As Boolean
Public pbLastDigin As Byte
'#######################################################
'END  chan and digout variables
'#######################################################


'====================>


'#######################################################
' START voltage and rawcount (non scan) variables
'#######################################################
Public iRawCount As Long
Public dVoltage(MAX_DEV_CNT) As Double
Public dVoltageSingConv As Double
'#######################################################
'END   voltage and rawcount (non scan) variables
'#######################################################


'====================>


'#######################################################
' START misc variables
'#######################################################
Public bRetVal As Byte

Public bScreenMode As Byte
Public bCurrentEndpoint As Byte

Public bFuncArgIgnored(MAX_DEV_CNT) As Byte
Public bHostClientDataBuf() As Byte

Public sDLLDebug As Integer
Public sRateCmdLow As Integer
Public sRateCmdHigh As Integer
Public dblCurrentRateToSend As Double

Public iRetVal As Long
Public iNumDbgFiles  As Long
Public iNumBytesToReadWrite As Long

Public fAnySignon As Boolean

Public fSignOn As Boolean
Public fRetVal As Boolean
Public fMsgStat As Boolean
Public fTimerStat As Boolean
Public fRetValMisc As Boolean
Public fDLLReadWrite As Boolean

'Most of the following used by the Configuration Setup code
Public strMsg As String
Public szLogFileName As String
Public strCfgFileSpec As String
Public strHostClientMsgBuf As String

'HANDLES to required DLL's and log file
Public hLibCheck As Long
Public hLibLL_USB As Long
Public hValIgnored As Long
Public hLogFile As Long
'#######################################################
'END  misc variables
'#######################################################


'====================>


'#######################################################
' START CONSTANT Definitions
'#######################################################



Public Const INIT_DEV_NO_ERR = &H0
Public Const INIT_DEV_NOT_FOUND = &H1
Public Const INIT_DEV_FAILED_ENUMERATION = &H2
Public Const INIT_DEV_DLL_INIT_ERR = &H4
Public Const INIT_DEV_OTHER_OWNER = &H8
Public Const INIT_DEV_NO_PWR_ERR = &H10             'Not yet used
Public Const INIT_DEV_NO_PWR_RECOVERED = &H20       'Not yet used
Public Const INIT_DEV_FAILED_READ = &H40            'Not yet used
Public Const INIT_DEV_READ_RECOVERED = &H80         'Not yet used
Public Const INIT_DEV_FAILED_WRITE = &H100          'Not yet used
Public Const INIT_DEV_WRITE_RECOVERED = &H200       'Not yet used
Public Const INIT_DEV_SYS_CAL_ERR = &H400           'Not yet used
Public Const INIT_DEV_SYS_CAL_RECOVERED = &H800     'Not yet used
Public Const INIT_DEV_RESET_IOCTL_TRIED = &H1000    'Not yet used
Public Const INIT_DEV_RESET_IOCTL_SUCCESS = &H2000  'Not yet used
Public Const INIT_DEV_RESET_CMD_TRIED = &H4000      'Not yet used
Public Const INIT_DEV_RESET_CMD_SUCCESS = &H8000    'Not yet used
Public Const INIT_DEV_SIGNON_SUCCESS = &H10000
Public Const INIT_DEV_SIGNING_ON = &H20000
Public Const INIT_DEV_FAILED_SYSCAL = &H40000       'Not yet used
Public Const INIT_DEV_DONE_INIT = &H80000           'Not yet used



Public Const FLAG_INPUT_RANGE = 0

Public Const COMMAND_SIGN_ON = &H0
Public Const COMMAND_DIG_OUT = &H2
Public Const COMMAND_CHAN_CHG = &H4
Public Const COMMAND_ANALOG_OUT = &HA
Public Const COMMAND_GET_CONVERSION = &H81
Public Const COMMAND_SYS_CAL = &H85
Public Const SCAN_BUFFSIZE_MAX = 32768

Public Const SCAN_IDLE = &H0
Public Const SCAN_RUN = &H1

Public Const DO_READ = True
Public Const DO_WRITE = False
Public Const ENDPOINT_0 = 0
Public Const ENDPOINT_1 = 1
Public Const TIMER_DONE = True
Public Const TIMER_START = False
Public Const POLLED_SCREEN = &O0
Public Const SCAN_SCREEN = &O1
Public Const DEF_CFG_SAVE = 1
Public Const DEF_CFG_CANCEL = 2
Public Const NO_DEVICE = 0
Public Const DEVICE_AVAILABLE = 1
Public Const DEVICE_IN_USE = 2
Public Const DEVICE_CONNECT_REMOVED = 1
Public Const DEVICE_CONNECT_NOCHANGE = 0

Public Const FREE_ANY_DEV = True
Public Const FREE_ONLY_APP_OWNED_DEVICES = False

Public Const MSG_BOX_OK = 0  'vbOk is actually ok/cancel

Public Const DO_DISPLAY_LISTS = True
Public Const DONT_DISPLAY_LISTS = False

Public Const SCANFILE_CREATE = 1
Public Const SCANFILE_CLOSE = 3

Public Const REDUCE_THREAD_PRIORITY = 1

'Following are possible values for SO_bScanType (scanning)
Public Const SINGLE_CHAN_SCAN = 1
Public Const MULTI_CHAN_SCAN = 2
Public Const MULTI_CHAN_CAL_SCAN = 3
Public Const SINGLE_CHAN_DIGIN_SCAN = 4
Public Const MULTI_CHAN_DIGIN_SCAN = 5
Public Const MULTI_CHAN_CAL_DIGIN_SCAN = 6

'Following are possible values for SO_iStatus (scanning)
Public Const SCAN_RUNNING = &H1
Public Const SCAN_DATA_REQUEST_SUCCEEDED = &H2
Public Const SCAN_ENDING = &H4
Public Const SCAN_HALTED = &H8
Public Const SCAN_CHECKSUM_ERROR = &H10
Public Const SCAN_VOLTAGE_BUFFER_WRAP = &H20
Public Const SCAN_MICRO_CODE_BUFF_WRAP = &H40
Public Const SCAN_DEVICE_IO_ERROR = &H80
Public Const SCAN_DEVICE_DISCONNECTED = &H100
Public Const SCAN_DEVICE_NOT_FOUND = &H200
Public Const SCAN_DIGIN_CHANGE = &H400      'Applies only with calls to DLL_ReadScanDataWithDigin(). DLL will set this flag when digital input has changed since start of scan. You must call the function (even if you just set iNumPointsToTransfer = 0) for DLL to update this flag.
'12-31-03
Public Const SCAN_DEVICE_POWER_LOSS = &H1000

'==========================================
'10-8-02 START OF ADDED ====================

Public Const SCAN_WRITE_DO_WRITE = &H1
Public Const SCAN_WRITE_PENDING = &H2
Public Const SCAN_WRITE_SUCCESS = &H4
Public Const SCAN_WRITE_FAILED = &H8
Public Const SCAN_WRITE_CANCEL = &H10
Public Const SCAN_WRITE_RET_STATS = &H20
Public Const SCAN_WRITE_DEVICE_UNKNOWN = &H40
Public Const SCAN_WRITE_DEVICE_NOT_SCANNING = &H80
Public Const SCAN_WRITE_MEMORY_ERR = &H100


Public Const FUNC_RET_FAIL = 0
Public Const FUNC_RET_SUCCESS = 1
'10-8-02 END OF ADDED ======================
'==========================================

'#######################################################
'END  CONSTANT Definitions
'#######################################################









'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'**** External functions from LL_USB2k.DLL ******************************
'Shown with C++ DLL function prototypes================================\
'=======================================================================
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
'=======================================================================
'======================================================================/

'======================================
'LL_LABS IN-HOUSE TESTING ONLY - START.
'======================================

'12-2-04
'BOOLEAN SP_GetCalculatedRate(double* dblRate, USHORT usDevID)
Declare Function SP_GetCalculatedRate Lib "LL_USB2k.DLL" (ByRef dblRate As Double, ByVal usDevID As Integer) As Byte


'11-29-04
Declare Function SPx_SendRate Lib "LL_USB2k.DLL" (ByRef pdblRate As Double, ByVal usDeviceID As Integer) As Byte

'7-1-04
'BOOLEAN SP_SendToDebug_AllDevInfoThisApp(void)
Declare Function SP_SendToDebug_AllDevInfoThisApp Lib "LL_USB2k.DLL" () As Byte

'4-30-04
'BOOLEAN SP_GetAppDevListInfo(USHORT usAppDevID, USHORT* usDLLDevID, BYTE* bDisonnected,
'                   BYTE* bFound, BYTE* bDevIndex)
Declare Function SP_GetAppDevListInfo Lib "LL_USB2k.DLL" _
            (ByVal usAppDevID As Integer, ByRef usDLLDevID As Integer, ByRef bDisonnected As Byte, _
            ByRef bFound As Byte, ByRef bDevIndex As Byte) As Byte

'2-26-04
'BOOLEAN SP_InitOneDev(USHORT usDevID, DOUBLE* dblRate)
Declare Function SP_InitOneDev Lib "LL_USB2k.DLL" _
            (ByVal usDevID As Integer, ByRef dblRate As Double, ByVal bChan As Byte) As Byte


'2-19-04
Declare Function SP_SetDebugLevel_ALL Lib "LL_USB2k.DLL" _
            (ByVal bDbgLvl As Byte) As Byte
'2-19-04
Declare Function SP_CreateNewDebug Lib "LL_USB2k.DLL" _
            (ByVal bDbgLvl As Byte, ByVal bUseOld As Byte) As Byte

'BOOLEAN DLL_DoMiscDevIOWrite(USHORT usDevID)
Declare Function DLL_DoMiscDevIOWrite Lib "LL_USB2k.DLL" _
            (ByVal usDevID As Integer) As Byte

Declare Function DLL_ReturnDeviceStringsInfo Lib "LL_USB2k.DLL" _
            (ByVal pDynamicArray As String, ByVal usDevID As Integer) As Byte

'BOOLEAN DLL_ResetPipe(USHORT usDevID, BYTE bReserved, BOOLEAN fRead)
Declare Function DLL_ResetPipe Lib "LL_USB2k.DLL" (ByVal usDeviceID As Integer, _
                    ByVal bReserved As Byte, ByVal fRead As Byte) As Byte

'BOOLEAN DLL_ResetDevice(USHORT usDevID, BYTE bReserved);
Declare Function DLL_GetDrvrTimings Lib "LL_USB2k.DLL" (ByVal usDeviceID As Integer) As Byte
Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Declare Function SetThreadPriority Lib "kernel32" (ByVal hThread As Long, ByVal nPriority As Long) As Long
Declare Function GetThreadPriority Lib "kernel32" (ByVal hThread As Long) As Long
'Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As LARGE_INTEGER) As Long
'===================================
'LL_LABS IN-HOUSE TESTING ONLY - END.
'===================================





'======================================
'NEW STUFF NOT YET CATEGORIZED
'======================================

'2-25-04 NEW
'BOOLEAN SP_SendEndScanToken(USHORT usDevID);
Declare Function SP_SendEndScanToken Lib "LL_USB2k.DLL" _
            (ByVal usDevID As Integer) As Byte

'BOOLEAN SP_GetEndScanStatus(USHORT usDevID, UINT* puiEndScanFlags);
Declare Function SP_GetEndScanStatus Lib "LL_USB2k.DLL" _
            (ByVal usDevID As Integer, ByRef puiEndScanFlags As Long) As Byte

'10-8-02
'BOOLEAN SP_WriteWhileScanning(USHORT usDevID, BYTE bCmnd, BYTE bArg, UINT* uiCurStat);
Declare Function SP_WriteWhileScanning Lib "LL_USB2k.DLL" (ByVal usDevID As Integer, _
    ByVal bCmnd As Byte, ByVal bArg As Byte, ByRef puiCurWriteStat As Long) As Byte

'BOOLEAN DLL_DoNothingFunc(BYTE bVal, USHORT usVal, DOUBLE* dblArray)
Declare Function DLL_DoNothingFunc Lib "LL_USB2k.DLL" (ByVal bVal As Byte, _
    ByVal usVal As Integer, ByRef dblArray As Double) As Byte
'===================================
'LL_LABS IN-HOUSE TESTING ONLY - END.
'===================================



'=======================================================================
'---------------->              INITIALIZATION
'=======================================================================
'1-12-02
'BOOLEAN SP_DrvrDebugOutput(USHORT usDevID, UINT uiDbgFlags, char* pszMsg, USHORT usMsgLngth)
Declare Function SP_DrvrDebugOutput Lib "LL_USB2k.DLL" (ByVal usDevID As Integer, _
    ByVal uiDbgFlags As Long, ByVal pszMsg As String, ByVal usMsgLngth As Integer) As Byte

'Need to use the following to set app's device cnt to that of DLL's since the
' pointer is never passed in SP_InitAllDevices like it once was with older
' DLL_Init function call. It's still safe to use this call with older init call.
'BOOLEAN SP_GetAppDevCnt(BYTE* bDevCnt)
Declare Function SP_GetAppDevCnt Lib "LL_USB2k.DLL" (ByRef pbNumDevices As Byte) As Byte


'12-10-01
'BOOLEAN SP_DisableDialog()
Declare Function SP_DisableDialog Lib "LL_USB2k.DLL" () As Byte


'BOOLEAN SP_InitAllDevices(USHORT* pDevList, BYTE* pbNumDevices_LV, DOUBLE* pdblInternalDataRate, BOOLEAN fShowDevList)
Declare Function SP_InitAllDevices Lib "LL_USB2k.DLL" (ByRef pusaLLABS_DeviceIDList As Integer, _
            ByRef pbNumDevices As Byte, ByRef padblInternalDataRate As Double, ByVal fShowList As Byte) As Byte

'BOOLEAN SP_InitAllDevices_Thread(USHORT* pDevList, DOUBLE* pdblInternalDataRate, BOOLEAN fShowDevList)
Declare Function SP_InitAllDevices_Thread Lib "LL_USB2k.DLL" (ByRef pusaLLABS_DeviceIDList As Integer, _
            ByRef padblInternalDataRate As Double, ByVal fShowList As Byte) As Byte
            
'BOOLEAN SP_GetInitThreadStat (void)
Declare Function SP_GetInitThreadStat Lib "LL_USB2k.DLL" () As Byte
           
'BOOLEAN SP_CancelInitThread (void)
Declare Function SP_CancelInitThread Lib "LL_USB2k.DLL" () As Byte

'BOOLEAN SP_GetLastInitDevAndRates(USHORT* pDevList, double* pdblRates);
Declare Function SP_GetLastInitDevAndRates Lib "LL_USB2k.DLL" (ByRef pusaLLABS_DeviceIDList As Integer, _
            ByRef padblInternalDataRate As Double) As Byte
            
'BOOLEAN SP_GetLastInitStat(USHORT* pDevList, UINT* puiFlags);
Declare Function SP_GetLastInitStat Lib "LL_USB2k.DLL" _
        (ByRef pausDevIDList As Integer, ByRef pausDevStatList As Long) As Byte

'BOOLEAN SP_GetOneConversion(USHORT usDevID, UINT* uiConvRawCount, BYTE bCurChan, BYTE* pbLastDigin);
Declare Function SP_GetOneConversion Lib "LL_USB2k.DLL" (ByVal usDeviceID As Integer, _
            ByRef puiConvRawCount As Long, ByVal bCurChan As Byte, ByRef pbDigInput As Byte) As Byte

'BOOLEAN SP_SendRate(DOUBLE* dblRate, USHORT usDevID);
Declare Function SP_SendRate Lib "LL_USB2k.DLL" (ByRef pdblRate As Double, ByVal usDeviceID As Integer) As Byte


'BOOLEAN SP_SendChan(USHORT usDevID, BYTE bCurChan, BYTE* pbLastDigin)
Declare Function SP_SendChan Lib "LL_USB2k.DLL" _
        (ByVal usDeviceID As Integer, ByVal bCurChan As Byte, ByRef pbDigInput As Byte) As Byte

'BOOLEAN DLL_Init(HANDLE hParentWindow, HANDLE hLibSETUPAPI, HANDLE hLibUSER32,
'           SHORT fDebugLevel, BYTE* bpNumDevices, BYTE *bpDeviceStatusShared,
'           SHORT *sLLABS_DeviceIDList);
Declare Function DLL_Init Lib "LL_USB2k.DLL" (ByVal hMainWin As Long, _
            ByVal hValIgnored As Long, ByVal hValIgnored As Long, _
            ByVal fDebugLevel As Integer, ByRef numDevices As Byte, _
            ByRef bDeviceStatusShared As Byte, _
            ByRef sLLABS_DeviceIDList As Integer) As Byte
            
'BOOLEAN DLL_SetSpecialDebugOptions(USHORT* usDeviceIdsToEnableDisable,
'        BYTE* bPerDevDbgLvl, BYTE _bDefaultDbgLvl, UINT uiFlags)
Declare Function DLL_SetSpecialDebugOptions Lib "LL_USB2k.DLL" ( _
            ByRef sDeviceIDList As Integer, _
            ByRef bDbgLvlPerDev As Byte, _
            ByVal bDbgDefault As Byte, ByVal fFlags As Long) As Byte
'Note bDbgDefault sets the value for non-device specific entries
' within the DLL's debug output file. For example, during enumeration
' or other times when a specific device ID doesn't apply or hasn't
' yet been establised.

            
            
'=======================================================================
'---------------->              DEVICE HANDLING
'=======================================================================
'FACTORY USE ONLY!

'BOOLEAN DLL_ResetDevice(USHORT usDevID, BYTE bReserved);
Declare Function DLL_ResetDevice Lib "LL_USB2k.DLL" (ByVal usDeviceID As Integer, ByVal bReserved As Byte) As Byte

'BOOLEAN DLL_ShowSharedDevArray(void);
Declare Function DLL_ShowSharedDevArray Lib "LL_USB2k.DLL" () As Byte

'BOOLEAN DLL_ZeroSharedDevArray(void);
Declare Function DLL_ZeroSharedDevArray Lib "LL_USB2k.DLL" () As Byte

'BOOLEAN DLL_ShowSharedGUIDStringArray(void);
Declare Function DLL_ShowSharedGUIDStringArray Lib "LL_USB2k.DLL" () As Byte

'BOOLEAN DLL_GetDeviceIDList(void);
Declare Function DLL_GetDeviceIDList Lib "LL_USB2k.DLL" () As Byte

'BOOLEAN DLL_InstanceInitDeviceList(BOOLEAN fDisplayLists);
Declare Function DLL_InstanceInitDeviceList Lib "LL_USB2k.DLL" _
        (ByVal fDisplayLists As Byte) As Byte

'BOOLEAN DLL_ReleaseDeviceFromIDList(USHORT* LLABSDeviceIDList, BOOLEAN fAnyHandle);
Declare Function DLL_ReleaseDeviceFromIDList Lib "LL_USB2k.DLL" _
            (ByRef sLLABS_DeviceIDList As Integer, fAnyHandle As Byte) As Byte
            
'BOOLEAN DLL_ReInitOneDev(USHORT usDevID);
Declare Function DLL_ReInitOneDev Lib "LL_USB2k.DLL" (ByVal usDeviceID As Integer) As Byte

'DLL_MarkOneDevAsInUse(USHORT usDevID);
Declare Function DLL_MarkOneDevAsInUse Lib "LL_USB2k.DLL" (ByVal usDeviceID As Integer) As Byte

           
'=======================================================================
'---------------->              DEVICE READ/WRITE
'=======================================================================
'BOOLEAN DLL_ReadWriteOneDevice(BOOLEAN fReadWrite, BYTE* DynamicDataArray, _
                    USHORT usDevID, UINT* numBytes, BYTE* pbDigIn, UINT uiReserved)
            
Declare Function DLL_ReadWriteOneDevice Lib "LL_USB2k.DLL" _
            (ByVal bReadWrite As Byte, ByRef pDynamicArray As Byte, _
            ByVal usDevID As Integer, ByRef uiNumBytes As Long, _
            ByRef pDigInput As Byte, ByVal iReserved As Long) As Byte
            
'=======================================================================
'---------------->              RATE (special)
'=======================================================================
'BOOLEAN DLL_SetRate(USHORT usDevID, DOUBLE dblRate);
Declare Function DLL_SetRate Lib "LL_USB2k.DLL" _
            (ByVal usDevID As Integer, ByVal dblRate As Double) As Byte
'=======================================================================
'---------------->              SCANNING
'=======================================================================
'BOOLEAN DLL_StartScan_DIO(USHORT usDeviceID, _
                        PSCAN_OBJECT_DIO pScanObj_DIO, BYTE bStartMode)
Declare Function DLL_StartScan_DIO Lib "LL_USB2k.DLL" _
           (ByVal usDeviceID As Integer, ByRef ScanObject As SCAN_OBJECT, _
                        ByVal bStartMode As Byte) As Byte

'BOOLEAN DLL_ReadScanData_DIO(USHORT usDevID, UINT* DynaVoltageBuff, _
                        USHORT numPointsToRead, PSCAN_OBJECT_DIO pScanObj_DIO)
Declare Function DLL_ReadScanData_DIO Lib "LL_USB2k.DLL" _
           (ByVal usDevID As Integer, ByRef iDynaVoltageBuff As Long, _
            ByVal numPointsToRead As Integer, ByRef ScanObject As SCAN_OBJECT) _
            As Byte
            
'BOOLEAN DLL_ReadScanDataWithDigin(USHORT usDevID, UINT* DynaVoltageBuff, BYTE* bDiginBuff, _
                        USHORT numPointsToRead, PSCAN_OBJECT_DIO pScanObj_DIO);
Declare Function DLL_ReadScanDataWithDigin Lib "LL_USB2k.DLL" _
           (ByVal usDevID As Integer, ByRef iDynaVoltageBuff As Long, _
           ByRef bDynaDiginBuff As Byte, ByRef bCurScanChan As Byte, _
           ByVal numPointsToRead As Integer, _
           ByRef ScanObject As SCAN_OBJECT) As Byte
            
'BOOLEAN DLL_EndScan_DIO(USHORT usDevID, BOOLEAN fEmptyBuffer, _
                     UINT uiTimeOut, BYTE bScanPauseOrTerminate)
' currently used. Their values are ignored by the DLL.
Declare Function DLL_EndScan_DIO Lib "LL_USB2k.DLL" _
            (ByVal uiDevId As Integer, ByVal fEmptyBuffer As Byte, _
            ByVal uiTimeOut_NOT_CURRENTLY_USED As Long, _
            ByVal bScanPauseOrTerminate_NOT_CURRENTLY_USED As Byte) As Byte
            
'BOOLEAN DLL_GetEndOfScanBuffSize(USHORT usDevID,UINT* uiNumPoints)
Declare Function DLL_GetEndOfScanBuffSize Lib "LL_USB2k.DLL" _
            (ByVal uiDevId As Integer, ByRef uiNumPoints As Long) As Byte
            
'BOOLEAN DLL_ReadEndOfScanData(USHORT usDevID, UINT* DynaVoltageBuff, USHORT numPointsToRead)
Declare Function DLL_ReadEndOfScanData Lib "LL_USB2k.DLL" _
           (ByVal usDevID As Integer, ByRef iDynaVoltageBuff As Long, _
            ByVal iNumPointsToRead As Integer) As Byte
            
            
'=======================================================================
'---------------->          MESSAGING AND MISC DEVICE INFO
'=======================================================================
'BOOLEAN SP_GetRegDevList(USHORT* usCompleteDevList, UINT uiUnused)
Declare Function SP_GetRegDevList Lib "LL_USB2k.DLL" _
            (ByRef sCurDevList As Integer, ByVal iUnused As Long) As Byte
'2-19-04
'BOOLEAN SP_GetAppDevList(USHORT* usCompleteDevList, UINT uiUnused)
Declare Function SP_GetAppDevList Lib "LL_USB2k.DLL" _
            (ByRef sCurDevList As Integer, ByVal iUnused As Long) As Byte
           
'2-20-04
'BOOLEAN SP_GetDevOwnershipList(USHORT* usCompleteDevList, HANDLE* puiAppHandleList)
Declare Function SP_GetDevOwnershipList Lib "LL_USB2k.DLL" _
            (ByRef sCurDevList As Integer, ByRef puiAppHandleList As Long) As Byte

            
            

'BOOLEAN DLL_ShowDeviceDescriptor(char*  pDynamicDeviceDescArray, USHORT usDevID);
Declare Function DLL_ShowDeviceDescriptor Lib "LL_USB2k.DLL" _
            (ByVal pDynamicArray As String, ByVal usDEV_ID As Integer) As Byte

'BOOLEAN DLL_ShowConfigurationDescriptor(char* pDynamicConfigArray, USHORT usDevID);
Declare Function DLL_ShowConfigurationDescriptor Lib "LL_USB2k.DLL" _
            (ByVal pDynamicArray As String, ByVal usDEV_ID As Integer) As Byte

'BOOLEAN DLL_ShowInterfaceDescriptors(BYTE* pDynamicArray, USHORT usDevID);
Declare Function DLL_ShowInterfaceDescriptors Lib "LL_USB2k.DLL" _
            (ByVal pDynamicArray As String, ByVal usDEV_ID As Integer) As Byte

'BOOLEAN DLL_ShowEndpointDescriptors(BYTE* pDynamicEndpointDescArray,
'                 USHORT usDevID, SHORT usWhichEndpoint);
Declare Function DLL_ShowEndpointDescriptors Lib "LL_USB2k.DLL" _
            (ByVal pDynamicArray As String, ByVal usDEV_ID As Integer, _
            ByVal whichEndpoint As Integer) As Byte
            
'BOOLEAN DLL_GetDevVersion(USHORT usDevID, USHORT* usDevVersion, BOOLEAN fDisplayVersion);
Declare Function DLL_GetDevVersion Lib "LL_USB2k.DLL" _
             (ByVal usDevID As Integer, ByRef usDevVer As Integer, ByVal fDispVer As Boolean) As Byte

'BOOLEAN DLL_GetDevVersion(USHORT usDevID, BOOLEAN fDisplayVersion, USHORT* usDevVersion, char* cpDLLVersion, char* cpDrvrVersion)
Declare Function DLL_GetVersionInfo Lib "LL_USB2k.DLL" _
            (ByVal usDevID As Integer, ByVal fDispVer As Byte, ByRef usDevVer As Integer, _
            ByVal pDLLVersion As String, ByVal pDrvrVersion As String) As Byte
            
'======================================================================\
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
'======================================================================/
                    
                    
'=======================================================================
'---------------->              WINAPI FUNCTIONS
'=======================================================================
Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetPrivateProfileInt Lib "kernel32" Alias "GetPrivateProfileIntA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal nDefault As Long, ByVal lpFileName As String) As Long
Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'===================================================================================================================
'=================================================================================================================
'===============================================================================================================
'=============================================================================================================
'===========================================================================================================
'=========================================================================================================
'=======================================================================
'***********************************************************************
'**** R E A D / W R I T E   C O N F I G U R A T I O N   F I L E ********
'***********************************************************************
'=======================================================================
'=======================================================================
'=======================================================================
'=========================================================================================================
'===========================================================================================================
'=============================================================================================================
'===============================================================================================================
'=================================================================================================================
'===================================================================================================================
'12-8-04 Added this function so that a new config file
' that has only the ID, Rate, and channel can be used
' either in place of the old config file, or along with the old
' if there is an error in the old. This requires that the "=" sign
' be right up against (no spaces) the value being checked. Tom did not
' want to add the additional check that would allow the space.
Public Sub ReadCfgFile_RetryWithNewConfigStyle()

    Dim bCurDevListIndex As Byte
    Dim fCfg As Long
    Dim sStr As String
    Dim sSubStr As String
    Dim bDupIndex As Byte
    
    If fSignOn Then
        Dim bCurIndex As Byte
        For bCurIndex = 0 To MAX_DEV_CNT_MINUS_ONE
            sLLABS_DeviceIDToRelease(bCurIndex) = sLLABS_DeviceIDList(bCurIndex)
        Next bCurIndex
        bRetVal = DLL_ReleaseDeviceFromIDList(sLLABS_DeviceIDToRelease(0), FREE_ONLY_APP_OWNED_DEVICES)
        fSignOn = False
    End If
    
    Dim bArrayIndexTemp As Byte
    For bArrayIndexTemp = 0 To MAX_DEV_CNT_MINUS_ONE
        sLLABS_DeviceIDList(bArrayIndexTemp) = 0
        DeviceObjectArray(bArrayIndexTemp).DEV_sID = 0
        DeviceObjectArray(bArrayIndexTemp).DEV_bChan = 0
        DeviceObjectArray(bArrayIndexTemp).DEV_dblRate = 0
        DeviceObjectArray(bArrayIndexTemp).DEV_bStat = 0
        DeviceObjectArray(bArrayIndexTemp).DEV_lScanBuffSize = 0
    Next bArrayIndexTemp
    
    strCfgFileSpec = "LL_USB.cfg"
    fCfg = FreeFile
    On Error GoTo DONE_WITH_ERR
    Open strCfgFileSpec For Input As #fCfg
    
    Dim SearchString_ID As String: SearchString_ID = "ID="
    Dim SearchString_RATE As String: SearchString_RATE = "RATE="
    Dim SearchString_CHAN As String: SearchString_CHAN = "CHAN="
    Dim ID_String, RATE_String, CHAN_String As String
    usModelNum = 0
    Dim DevID  As Integer
    Dim Chan As Byte
    Dim Rate As Double
    Dim strFoundStartAt As Long
    Dim strFoundNextDevAt As Long
    Dim strFoundNextChanAt As Long
    Dim GenericVal As Double
    Dim miscVar
    Dim FileSize As Long: FileSize = 0
    Dim ptrCurIndex As Long: ptrCurIndex = 1
    Dim fDone As Boolean: fDone = False
    Dim fValidDev As Boolean: fValidDev = False
    Dim fValidRate As Boolean: fValidRate = False
    Dim fValidChan As Boolean: fValidChan = False
    Dim bIndexValidDevice As Byte: bIndexValidDevice = 0
    
    Do While Not EOF(fCfg)
        miscVar = Input(1, #fCfg)
        FileSize = FileSize + 1
    Loop
    Close #fCfg
    
    Open strCfgFileSpec For Input As #fCfg
    Do While Not EOF(fCfg)
        sStr = Input(FileSize, #fCfg)
    Loop
    Close #fCfg
   
    Do While Not fDone
RETRY:
        DevID = 0
        strFoundStartAt = InStr(ptrCurIndex, UCase(sStr), SearchString_ID, vbTextCompare)
        If strFoundStartAt <> 0 Then
            sSubStr = Mid(sStr, strFoundStartAt + Len(SearchString_ID), 6)
            ID_String = Trim(sSubStr)
            
            GenericVal = Val(ID_String)
            GenericVal = Round(GenericVal)
            If GenericVal > 14000 Then GenericVal = 0
            DevID = Int(GenericVal)
            ptrCurIndex = strFoundStartAt + Len(SearchString_ID)
            If DevID = 0 Then GoTo RETRY
        Else
            ptrCurIndex = ptrCurIndex + Len(SearchString_ID)
            If (ptrCurIndex + Len(SearchString_ID)) > Len(sStr) Then
                GoTo DONE_ALL
            Else
                GoTo RETRY
            End If
        End If
        
        
DONE_ID_TEST:
        If usModelNum = 0 Then
            If (DevID > 5000) And (DevID < 14000) Then
                usModelNum = 302
                frmLL_USB.Caption = "Model-302 VB sample": frmLL_USB.Label4.Caption = "Model 302 DEMO"
                frmLL_USB.CheckModel301.Value = vbUnchecked: frmLL_USB.CheckModel302.Value = vbChecked
                frmLL_USB.Text2.Visible = True: frmLL_USB.txtDAC_Volts.Visible = True: frmLL_USB.btnAnalogOut.Visible = True: frmLL_USB.Label18.Visible = True: frmLL_USB.cmboDAC.Visible = True: frmLL_USB.Label25.Visible = True
            Else
                If (DevID > 100) And (DevID < 5000) Then
                    usModelNum = 301
                    frmLL_USB.Caption = "Model-301 VB sample": frmLL_USB.Label4.Caption = "Model 301 DEMO"
                    frmLL_USB.CheckModel301.Value = vbChecked: frmLL_USB.CheckModel302.Value = vbUnchecked
                    frmLL_USB.Text2.Visible = False: frmLL_USB.txtDAC_Volts.Visible = False: frmLL_USB.btnAnalogOut.Visible = False: frmLL_USB.Label18.Visible = False: frmLL_USB.cmboDAC.Visible = False: frmLL_USB.Label25.Visible = False
                Else
                    DevID = 0
                End If
            End If
        End If
        
        
        'Test if valid device. Whichever device type is seen first is the type
        '  that I continue to use. For example if the first device in the file
        '  is a 302 then that's all I store the information for. This application
        '  will only use one or the other.
        fValidDev = False: fValidRate = False: fValidChan = False
        If DevID Then
            If usModelNum = 302 Then
                If ((DevID > 5000) And (DevID < 14000)) Then
                    fValidDev = True
                Else
                    If (ptrCurIndex + Len(SearchString_ID)) > Len(sStr) Then
                        GoTo DONE_ALL
                    Else
                        GoTo RETRY
                    End If
                    'fValidDev remains false
                End If
            Else
                If (DevID > 100) And (DevID < 5000) Then
                    fValidDev = True
                Else
                    If (ptrCurIndex + Len(SearchString_ID)) > Len(sStr) Then
                        GoTo DONE_ALL
                    Else
                        GoTo RETRY
                    End If
                    'fValidDev remains false
                End If
            End If
        End If
        
        If fValidDev Then
            For bDupIndex = 0 To (MAX_DEV_CNT - 1)
                If sLLABS_DeviceIDList(bDupIndex) = DevID Then
                    fValidDev = False
                End If
            Next bDupIndex
            If fValidDev Then
                sLLABS_DeviceIDList(bIndexValidDevice) = DevID
                DeviceObjectArray(bIndexValidDevice).DEV_sID = DevID
            End If
        Else
            GoTo DONE_ALL
        End If
        
        strFoundStartAt = InStr(ptrCurIndex, UCase(sStr), SearchString_RATE, vbTextCompare)
        strFoundNextChanAt = InStr(ptrCurIndex, UCase(sStr), SearchString_CHAN, vbTextCompare)
        
        '=============================
        '=============================
        '12-9-04b
        'check if next rate is after next ID, if so is there a channel before next ID, if not are we at the end of the file?
        strFoundNextDevAt = InStr(ptrCurIndex, UCase(sStr), SearchString_ID, vbTextCompare)
        If ((strFoundStartAt <> 0) And (strFoundStartAt > strFoundNextDevAt) And (strFoundNextChanAt > strFoundNextDevAt) And (strFoundNextDevAt > 0)) Then
            DeviceObjectArray(bIndexValidDevice).DEV_dblRate = 100#
            DeviceObjectArray(bIndexValidDevice).DEV_bChan = 7
            bIndexValidDevice = bIndexValidDevice + 1
            GoTo RETRY
        End If
        '=============================
        '=============================
        
        If ((strFoundStartAt <> 0) And (strFoundStartAt < strFoundNextChanAt)) Then
        
            sSubStr = Mid(sStr, strFoundStartAt + Len(SearchString_RATE), 8)
            RATE_String = Trim(sSubStr)
            
            If fValidDev Then
                Rate = CDbl(Val(RATE_String))
                If (Rate < 1000) And (Rate > 49) Then
                    DeviceObjectArray(bIndexValidDevice).DEV_dblRate = Rate
                Else
                    DeviceObjectArray(bIndexValidDevice).DEV_dblRate = 100#
                End If
            End If
            fValidRate = True
            ptrCurIndex = strFoundStartAt + Len(SearchString_RATE)
            GoTo DONE_RATE_TEST
        Else
            'maybe channel is before rate
            strFoundNextDevAt = InStr(ptrCurIndex, UCase(sStr), SearchString_ID, vbTextCompare)
            strFoundStartAt = InStr(ptrCurIndex, UCase(sStr), SearchString_CHAN, vbTextCompare)
            If ((strFoundStartAt <> 0) And (strFoundStartAt < strFoundNextDevAt)) Then
                sSubStr = Mid(sStr, strFoundStartAt + Len(SearchString_CHAN), 2)
                CHAN_String = Trim(sSubStr)

                If fValidDev Then
                    GenericVal = CDbl(Val(CHAN_String)): GenericVal = Round(GenericVal)
                    If GenericVal > 8 Then GenericVal = 8
                    Chan = CByte(GenericVal)

                    If usModelNum = 301 Then
                        If (Chan = 0) Or (Chan = 1) Or (Chan = 6) Or (Chan = 7) Then
                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = Chan
                        Else
                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = 7
                        End If
                    Else
                        If Chan < 8 Then
                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = Chan
                        Else
                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = 7
                        End If
                    End If
                    fValidChan = True
                    ptrCurIndex = strFoundStartAt + Len(SearchString_CHAN)
                Else
                    DeviceObjectArray(bIndexValidDevice).DEV_bChan = 7
                End If

                strFoundStartAt = InStr(ptrCurIndex, UCase(sStr), SearchString_RATE, vbTextCompare)
                If ((strFoundStartAt <> 0) And (strFoundStartAt < strFoundNextDevAt)) Then
                    sSubStr = Mid(sStr, strFoundStartAt + Len(SearchString_RATE), 8)
                    RATE_String = Trim(sSubStr)
                    If fValidDev Then
                        Rate = CDbl(Val(RATE_String))

                        If (Rate < 1000) And (Rate > 49) Then
                            DeviceObjectArray(bIndexValidDevice).DEV_dblRate = Rate
                        Else
                            DeviceObjectArray(bIndexValidDevice).DEV_dblRate = 100#
                        End If
                    End If
                    fValidRate = True
                    ptrCurIndex = strFoundStartAt + Len(SearchString_RATE)
                    GoTo DONE_RATE_TEST
                Else
                    DeviceObjectArray(bIndexValidDevice).DEV_dblRate = 100#
                End If
            Else
                If fValidDev Then DeviceObjectArray(bIndexValidDevice).DEV_dblRate = 100#
                fValidRate = True
                GoTo DONE_RATE_TEST
            End If
        End If


DONE_RATE_TEST:
        
        If fValidChan = 0 Then
            strFoundStartAt = InStr(ptrCurIndex, UCase(sStr), SearchString_CHAN, vbTextCompare)
            
            '=============================
            '=============================
            '12-9-04b
            'check if next channel is after next ID, if so loop back to top, if not are we at the end?
            strFoundNextDevAt = InStr(ptrCurIndex, UCase(sStr), SearchString_ID, vbTextCompare)
            If ((strFoundStartAt <> 0) And (strFoundStartAt > strFoundNextDevAt) And (strFoundNextDevAt > 0)) Then
                DeviceObjectArray(bIndexValidDevice).DEV_bChan = 7
                bIndexValidDevice = bIndexValidDevice + 1
                GoTo RETRY
            End If
            '=============================
            '=============================
            
            If strFoundStartAt <> 0 Then
                sSubStr = Mid(sStr, strFoundStartAt + Len(SearchString_CHAN), 2)
                CHAN_String = Trim(sSubStr)

                If fValidDev Then
                    GenericVal = CDbl(Val(CHAN_String)): GenericVal = Round(GenericVal)
                    If GenericVal > 8 Then GenericVal = 8
                    Chan = CByte(GenericVal)
                    If usModelNum = 301 Then
                        If (Chan = 0) Or (Chan = 1) Or (Chan = 6) Or (Chan = 7) Then
                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = Chan
                        Else
                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = 7
                        End If
                    Else
                        If Chan < 8 Then
                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = Chan
                        Else
                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = 7
                        End If
                    End If
                    fValidChan = True
                    ptrCurIndex = strFoundStartAt + Len(SearchString_CHAN) '+ Len(CHAN_String)
                End If
                GoTo DONE_CHAN_TEST
            Else
                If fValidDev Then DeviceObjectArray(bIndexValidDevice).DEV_bChan = 7
            End If
        End If
DONE_CHAN_TEST:
        If fValidDev Then
            bIndexValidDevice = bIndexValidDevice + 1
        Else
            'either at end of file, or rest of file is junk
            If ((fValidRate = False) And (fValidChan = False)) Then
                GoTo DONE_ALL
            End If
        End If
        
    Loop
    
DONE_ALL:

    bNumDevicesLocal = 0
    For bArrayIndexTemp = 0 To MAX_DEV_CNT_MINUS_ONE
        If sLLABS_DeviceIDList(bArrayIndexTemp) <> 0 Then
            If DeviceObjectArray(bArrayIndexTemp).DEV_sID = 0 Then DeviceObjectArray(bArrayIndexTemp).DEV_sID = sLLABS_DeviceIDList(bArrayIndexTemp)
            If DeviceObjectArray(bArrayIndexTemp).DEV_dblRate = 0 Then DeviceObjectArray(bArrayIndexTemp).DEV_dblRate = 100#
            bNumDevicesLocal = bNumDevicesLocal + 1
        End If
    Next bArrayIndexTemp
    If bNumDevicesLocal <= 0 Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & "No valid devices listed in configuration file!" & vbCrLf
        fRetValMisc = ScrollText("down")
        bReadCfgCalled = 0
    Else
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Number of devices listed in configuration file: " & bNumDevicesLocal & vbCrLf
        fRetValMisc = ScrollText("down")
        For bCurDevListIndex = 0 To (bNumDevicesLocal - 1)
            frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
                & "Configuration for device index: " & bCurDevListIndex _
                & ",  Device: " & DeviceObjectArray(bCurDevListIndex).DEV_sID & vbCrLf _
                & "Channel:" & DeviceObjectArray(bCurDevListIndex).DEV_bChan _
                & vbTab & "Rate:" & DeviceObjectArray(bCurDevListIndex).DEV_dblRate & "Hz" & vbCrLf & vbCrLf
            fRetValMisc = ScrollText("down")
        Next
        bReadCfgCalled = 1
    End If
    
    fRetVal = True
    
    '12-14-04
    fUseNewConfig = True
    'Close #fCfg
    Exit Sub
    
    
DONE_WITH_ERR:
    MsgBox vbCrLf & "ERROR opening, or incorrect data format in LL_USB.cfg" & vbCrLf & vbCrLf & vbCrLf & "Locate and place configuration file in" & vbCrLf & vbCrLf & "same directory as application and try again." & vbCrLf & vbCrLf & "error", 0
    fRetValMisc = ScrollText("down")
    On Error GoTo 0
    fRetVal = False
    'Close #fCfg
    
End Sub
Public Sub ReadCfgFile()
    Dim bCurDevListIndex As Byte
    Dim fCfg As Long
    Dim sStr As String
    Dim bDupIndex As Byte
    
    If fSignOn Then
        Dim bCurIndex As Byte
        For bCurIndex = 0 To MAX_DEV_CNT_MINUS_ONE
            sLLABS_DeviceIDToRelease(bCurIndex) = sLLABS_DeviceIDList(bCurIndex)
        Next bCurIndex
        bRetVal = DLL_ReleaseDeviceFromIDList(sLLABS_DeviceIDToRelease(0), FREE_ONLY_APP_OWNED_DEVICES)
        fSignOn = False
    End If
    
    Dim bArrayIndexTemp As Byte
    For bArrayIndexTemp = 0 To MAX_DEV_CNT_MINUS_ONE
        sLLABS_DeviceIDList(bArrayIndexTemp) = 0
        DeviceObjectArray(bArrayIndexTemp).DEV_sID = 0
        DeviceObjectArray(bArrayIndexTemp).DEV_bChan = 0
        DeviceObjectArray(bArrayIndexTemp).DEV_dblRate = 0
        DeviceObjectArray(bArrayIndexTemp).DEV_bStat = 0
        DeviceObjectArray(bArrayIndexTemp).DEV_lScanBuffSize = 0
    Next bArrayIndexTemp
    
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
        & "Reading LL_USB.cfg configuration file" & vbCrLf
    fRetValMisc = ScrollText("down")
    
    strCfgFileSpec = "LL_USB.cfg"
    fCfg = FreeFile
    On Error GoTo NO_FILE
    Open strCfgFileSpec For Input As #fCfg
    
    'File notes and date info
    'MsgBox "notes and date info: " & sStr
    Line Input #fCfg, sStr
    
    'Get blank line
    Line Input #fCfg, sStr
    
    'model number - for example 301 or 302
    Line Input #fCfg, sStr
    If fSkipModelChk = False Then usModelNum = Val(sStr)
    
    If usModelNum <> 301 And usModelNum <> 302 Then
        '12-7-04 MsgBox vbCrLf & "----- INVALID MODEL NUMBER IN CONFIG FILE ! !" _
        '12-7-04 & vbCrLf & vbCrLf & vbCrLf & "Model number is 3rd line in LL_USB.cfg (counting blank lines)" & vbCrLf & vbCrLf & "The number should be 301 or 302" & vbCrLf & vbCrLf & "Correct the error and try again" & vbCrLf & vbCrLf, 0
        '12-7-04 On Error GoTo 0:  End
        
        '12-7-04
        GoTo NO_FILE
    End If
    
    '2-25-04
    If usModelNum = 301 Then frmLL_USB.CheckIsJusticeBoard.Visible = False
    
    If usModelNum = 301 Then
        frmLL_USB.Caption = "Model-301 VB sample": frmLL_USB.Label4.Caption = "Model 301 DEMO"
        frmLL_USB.CheckModel301.Value = vbChecked: frmLL_USB.CheckModel302.Value = vbUnchecked
        frmLL_USB.Text2.Visible = False: frmLL_USB.txtDAC_Volts.Visible = False: frmLL_USB.btnAnalogOut.Visible = False: frmLL_USB.Label18.Visible = False: frmLL_USB.cmboDAC.Visible = False: frmLL_USB.Label25.Visible = False
    Else
        frmLL_USB.Caption = "Model-302 VB sample": frmLL_USB.Label4.Caption = "Model 302 DEMO"
        frmLL_USB.CheckModel301.Value = vbUnchecked: frmLL_USB.CheckModel302.Value = vbChecked
        frmLL_USB.Text2.Visible = True: frmLL_USB.txtDAC_Volts.Visible = True: frmLL_USB.btnAnalogOut.Visible = True: frmLL_USB.Label18.Visible = True: frmLL_USB.cmboDAC.Visible = True: frmLL_USB.Label25.Visible = True
    End If
    
    Line Input #fCfg, sStr

    'Get Debug Level (not used anymore, but still in file
    Line Input #fCfg, sStr

    'Get Number of devices
    Line Input #fCfg, sStr
    bNumDevicesLocal = Val(sStr)
    If bNumDevicesLocal <= 0 Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & "No devices listed in configuration file!" & vbCrLf
        fRetValMisc = ScrollText("down")
        GoTo NO_FILE
    End If
    
    Dim iTempDevID As Integer
    
    For bCurDevListIndex = 0 To (bNumDevicesLocal - 1)
        'Get blank line
        Line Input #fCfg, sStr

        'Get line description   (Device number)
        Line Input #fCfg, sStr

        'Get Device ID for each device
        Line Input #fCfg, sStr
        
        iTempDevID = Val(sStr)
        
        'Don't act on duplicate IDs
        For bDupIndex = 0 To (bNumDevicesLocal - 1)
            If DeviceObjectArray(bDupIndex).DEV_sID = iTempDevID Then
                Line Input #fCfg, sStr  'chan line
                Line Input #fCfg, sStr  'rate line
                GoTo DO_NEXT
            End If
        Next bDupIndex
        
        If usModelNum = 301 Then
            If iTempDevID > 4990 Then
                If bNumDevicesLocal Then bNumDevicesLocal = bNumDevicesLocal - 1
                
                Line Input #fCfg, sStr  'chan line
                Line Input #fCfg, sStr  'rate line
                GoTo DO_NEXT
            End If
        Else
            If iTempDevID < 4990 Then
                If bNumDevicesLocal Then bNumDevicesLocal = bNumDevicesLocal - 1
                
                Line Input #fCfg, sStr  'chan line
                Line Input #fCfg, sStr  'rate line
                GoTo DO_NEXT
            End If
        End If
        
        DeviceObjectArray(bCurDevListIndex).DEV_sID = Val(sStr)
    
        'Get default channel for each device
        Line Input #fCfg, sStr
        DeviceObjectArray(bCurDevListIndex).DEV_bChan = Val(sStr)
        If DeviceObjectArray(bCurDevListIndex).DEV_bChan = 0 Then GoTo CHAN_OKAY
        If DeviceObjectArray(bCurDevListIndex).DEV_bChan = 1 Then GoTo CHAN_OKAY
        If DeviceObjectArray(bCurDevListIndex).DEV_bChan = 6 Then GoTo CHAN_OKAY
        If DeviceObjectArray(bCurDevListIndex).DEV_bChan = 7 Then GoTo CHAN_OKAY
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
            & "Invalid channel value listed in configuration file!" & vbCrLf
        fRetValMisc = ScrollText("down")
        GoTo NO_FILE
        
CHAN_OKAY:

        'Get default rate for each device
        Line Input #fCfg, sStr
        DeviceObjectArray(bCurDevListIndex).DEV_dblRate = Val(sStr)

        If DeviceObjectArray(bCurDevListIndex).DEV_dblRate >= 50 And _
            DeviceObjectArray(bCurDevListIndex).DEV_dblRate <= 1000 Then GoTo RATE_OKAY
                
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
            & "Invalid rate value listed in configuration file!" & vbCrLf
        fRetValMisc = ScrollText("down")
        GoTo NO_FILE
RATE_OKAY:
        
        'Calculate Scan buffer size based on rate
        DeviceObjectArray(bCurDevListIndex).DEV_lScanBuffSize = &H1000       'minimum
        If DeviceObjectArray(bCurDevListIndex).DEV_dblRate >= 200 Then
            DeviceObjectArray(bCurDevListIndex).DEV_lScanBuffSize = &H4000
        ElseIf DeviceObjectArray(bCurDevListIndex).DEV_dblRate >= 400 Then
            DeviceObjectArray(bCurDevListIndex).DEV_lScanBuffSize = &H7FFF   'signed, so don't use &h8000 making it negative
        End If
DO_NEXT:
    Next bCurDevListIndex
    
    Close #fCfg
    
    'Show configuration information
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Number of devices listed in configuration file: " & bNumDevicesLocal & vbCrLf
    fRetValMisc = ScrollText("down")
    
    frmLL_USB.ComboScanArg.Clear
    If usModelNum = 301 Then
        For bCurDevListIndex = 0 To 2
            frmLL_USB.ComboScanArg.List(bCurDevListIndex) = bCurDevListIndex + 1
        Next bCurDevListIndex
        frmLL_USB.ComboScanArg.List(3) = 4: frmLL_USB.ComboScanArg.Text = "4"
    Else
        For bCurDevListIndex = 0 To 7
            frmLL_USB.ComboScanArg.List(bCurDevListIndex) = bCurDevListIndex + 1
        Next bCurDevListIndex
        frmLL_USB.ComboScanArg.Text = "8"
    End If
    
    Dim bCurDevIndexTemp: Dim fFeatureNotSupported As Boolean: fFeatureNotSupported = False
    If usModelNum = 301 Then
        For bCurDevIndexTemp = 0 To (bNumDevicesLocal - 1)
            If (sLLABS_DeviceIDList(bCurDevIndexTemp) < 155) Then
                'following "IF" is for in-house testing (we use IDs less than #100)
                If sLLABS_DeviceIDList(bCurDevIndexTemp) > 100 Then fFeatureNotSupported = True
            End If
        Next bCurDevIndexTemp
    End If
    If fFeatureNotSupported Then
        frmLL_USB.ComboScanArg.Clear: frmLL_USB.ComboScanArg.Text = "2": frmLL_USB.ComboScanArg.Enabled = False
    End If
    
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf
    fRetValMisc = ScrollText("down")
    For bCurDevListIndex = 0 To (bNumDevicesLocal - 1)
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
            & "Configuration for device index: " & bCurDevListIndex _
            & ",  Device: " & DeviceObjectArray(bCurDevListIndex).DEV_sID & vbCrLf _
            & "Channel:" & DeviceObjectArray(bCurDevListIndex).DEV_bChan _
            & vbTab & "Rate:" & DeviceObjectArray(bCurDevListIndex).DEV_dblRate & "Hz" & vbCrLf & vbCrLf
        fRetValMisc = ScrollText("down")
    Next
    
    bReadCfgCalled = 1
    
    fRetVal = True
    GoTo EXIT_READ_CFG
    
NO_FILE:
    '12-7-04 MsgBox vbCrLf & "ERROR opening, or incorrect data format in LL_USB.cfg" & vbCrLf & vbCrLf & vbCrLf & "Locate and place configuration file in" & vbCrLf & vbCrLf & "same directory as application and try again." & vbCrLf & vbCrLf & "error", 0
    
        
        
    ReadCfgFile_RetryWithNewConfigStyle
    fRetVal = True
    
    On Error GoTo 0
    '12-7-04    fRetVal = False
    GoTo EXIT1
    
EXIT_READ_CFG:
    On Error GoTo 0
    fRetVal = True
    
EXIT1:
    '12-7-04 fRetValMisc = ScrollText("down")
    Close #fCfg

End Sub
Public Sub WriteCfgFile_WithNewConfigStyle()
    Dim bCurDevListIndex As Byte: Dim pCfgFile As Long: Dim sStr As String
    Dim bMsgBoxRetTypeYES As Long: bMsgBoxRetTypeYES = 6: Dim bFileLen As Long: bFileLen = 0
    On Error GoTo FILE_NOT_PRESENT
    bFileLen = FileLen("LL_USB.cfg")
    On Error GoTo 0
    
    Dim usMsgBoxType As Integer            'used in messge box
    usMsgBoxType = &H1124       'MB_YESNO | MB_ICONQUESTION | MB_SYSTEMMODAL | MB_SETFOREGROUND | MB_ICONQUESTION
    iRetVal = MessageBox(frmLL_USB.hwnd, vbCrLf & vbCrLf & "Are you sure you want to overwrite existing configuration file?" & vbCrLf & vbCrLf, " N O T I C E --------", usMsgBoxType)
    If iRetVal <> bMsgBoxRetTypeYES Then
        fRetVal = False
        GoTo EXIT1
    End If
    
FILE_NOT_PRESENT:
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & "Writing LL_USB.cfg configuration file." & vbCrLf
    fRetValMisc = ScrollText("down")
    
    strCfgFileSpec = "LL_USB.cfg"
    pCfgFile = FreeFile(2)
    On Error GoTo NO_FILE
    Open strCfgFileSpec For Output As #pCfgFile
    
    Print #pCfgFile, _
"To use this file use the format shown below. First enter the device ID number (replace" & vbCrLf & _
"the one shown below with your own), followed by the rate you'd like to run, followed by" & vbCrLf & _
"the channel. All that is really required is the device ID which if entered with nothing" & vbCrLf & _
"else, will have default values of 100Hz and Channel 7 set by the application. Note that" & vbCrLf & _
"the  ' = '  sign follows each of the values with no space separation. If you have a" & vbCrLf & _
"combination of 301's and 302's connected and have the ID 's for them all listed below," & vbCrLf & _
"then the app will use the first type that it finds and ignore the rest - for example if" & vbCrLf & _
"the application finds an ID for a model 302 followed by a 301 and then another 302, it" & vbCrLf & _
"will use both 302's but not the 301. Invalid entries will be either ignored or replaced" & vbCrLf & _
"by default values."

    Print #pCfgFile, vbCrLf & vbCrLf
    
    For bCurDevListIndex = 0 To (bNumDevicesLocal - 1)
        Print #pCfgFile, "ID=" & DeviceObjectArray(bCurDevListIndex).DEV_sID
        Print #pCfgFile, "RATE=" & DeviceObjectArray(bCurDevListIndex).DEV_dblRate
        Print #pCfgFile, "CHAN=" & DeviceObjectArray(bCurDevListIndex).DEV_bChan
        Print #pCfgFile, vbCrLf
    Next bCurDevListIndex
    
    GoTo EXIT_WRITE_CFG
    
NO_FILE:
    fRetVal = MsgDisplay( _
          Chr(10) _
        & Chr(10) _
        & "ERROR writing LL_USB.cfg!!" _
        & Chr(10) _
        & Chr(10) _
        & "File of same name may be in use." _
        & Chr(10) _
        & Chr(10), _
        "E R R O R ----")
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
        & "FAILED Writing LL_USB.cfg configuration file." & vbCrLf
    fRetValMisc = ScrollText("down")
    On Error GoTo 0
    fRetVal = False
    End
    
EXIT_WRITE_CFG:
    On Error GoTo 0
    fRetVal = True
EXIT1:
End Sub

Public Sub WriteCfgFile()
    If fUseNewConfig Then
        WriteCfgFile_WithNewConfigStyle
        Exit Sub
    End If

    Dim bCurDevListIndex As Byte: Dim pCfgFile As Long: Dim sStr As String
    Dim bMsgBoxRetTypeYES As Long: bMsgBoxRetTypeYES = 6: Dim bFileLen As Long: bFileLen = 0
    On Error GoTo FILE_NOT_PRESENT
    bFileLen = FileLen("LL_USB.cfg")
    On Error GoTo 0
    
    Dim usMsgBoxType As Integer            'used in messge box
    usMsgBoxType = &H1124       'MB_YESNO | MB_ICONQUESTION | MB_SYSTEMMODAL | MB_SETFOREGROUND | MB_ICONQUESTION
    iRetVal = MessageBox(frmLL_USB.hwnd, vbCrLf & vbCrLf & "Are you sure you want to overwrite existing configuration file?" & vbCrLf & vbCrLf, " N O T I C E --------", usMsgBoxType)
    If iRetVal <> bMsgBoxRetTypeYES Then
        fRetVal = False
        GoTo EXIT1
    End If
    
FILE_NOT_PRESENT:
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & "Writing LL_USB.cfg configuration file." & vbCrLf
    fRetValMisc = ScrollText("down")
    
    strCfgFileSpec = "LL_USB.cfg"
    pCfgFile = FreeFile(2)
    On Error GoTo NO_FILE
    Open strCfgFileSpec For Output As #pCfgFile
    
    Print #pCfgFile, "NOTE: Important information at end of this file. " & " Please keep a copy of this file for future reference.   File created " & Date$ & "  " & Time$
    Print #pCfgFile, ""
    
    If frmLL_USB.CheckModel301.Value = vbUnchecked Then
        Print #pCfgFile, "301"
    Else
        Print #pCfgFile, "302"
    End If
    Print #pCfgFile, ""
    
    Print #pCfgFile, sDLLDebug
    Print #pCfgFile, bNumDevicesLocal
    
    For bCurDevListIndex = 0 To (bNumDevicesLocal - 1)
        Print #pCfgFile, ""
        Print #pCfgFile, "--------->  DEVICE" & bCurDevListIndex + 1 & " (add a device here - increase device-count above if you do) See notes at end of file."
        Print #pCfgFile, DeviceObjectArray(bCurDevListIndex).DEV_sID
        Print #pCfgFile, DeviceObjectArray(bCurDevListIndex).DEV_bChan
        Print #pCfgFile, DeviceObjectArray(bCurDevListIndex).DEV_dblRate
    Next bCurDevListIndex
    
    Print #pCfgFile, ""
    Print #pCfgFile, ""
    Print #pCfgFile, ""
    Print #pCfgFile, ""
    Print #pCfgFile, ""
    Print #pCfgFile, ""
    
    Print #pCfgFile, "==  Line descriptions ============"
    Print #pCfgFile, "*****************************************"
    Print #pCfgFile, "First line:" & vbTab & vbTab & "Misc notes, and file date. Put anything in this line"
    Print #pCfgFile, "Second line:" & vbTab & "Leave blank or put anything in this line"
    Print #pCfgFile, "Third line:" & vbTab & "Model number (301 Or 302)"
    Print #pCfgFile, "Fourth line:" & vbTab & "Leave blank or put anything in this line"
    Print #pCfgFile, "Fifth line:" & vbTab & "Debug  level  used by  DLL  to  write  debug  info  to  file (0  =  no debug,  6 = maximum debug)"
    Print #pCfgFile, "Sixth line:" & vbTab & "Debug  level  used by  DLL  to  write  debug  info  to  file (0  =  no debug,  6 = maximum debug)"
    Print #pCfgFile, "Seventh line:" & vbTab & "Number of devices"
    Print #pCfgFile, "Eighth line:" & vbTab & vbTab & "Leave blank or put anything in this line"
    Print #pCfgFile, "Ninth line:" & vbTab & "Leave blank or put anything in this line. I use it to mark start of new device configuration"
    Print #pCfgFile, "Tenth line:" & vbTab & "Starts entries for first device."
    Print #pCfgFile, ""
    Print #pCfgFile, "Fields for each DEVICE:"
    Print #pCfgFile, vbTab & "First entry:    Device ID"
    Print #pCfgFile, vbTab & "Second entry:   current channel"
    Print #pCfgFile, vbTab & "Third entry: Rate "
    Print #pCfgFile, "First line after each device entry must be blank or whatever you want to put there, but it must be present"
    Print #pCfgFile, "After that repeat for another device for the device count listed in fourth line. After listing all devices anything"
    Print #pCfgFile, "can be inserted into the file (such as I've done with these notes)"

    Print #pCfgFile, "NOTES:"
    Print #pCfgFile, "There  MUST  be a Device ID and other parameters for the number of devices listed in second field"
    Print #pCfgFile, "  Application only reads number of fields indicated by  ""number of devices (Second entry)."""
    Print #pCfgFile, ""
    Print #pCfgFile, "The data in  ""--------->  DEVICE x"" lines and single blank line that precedes them are ignored. However"
    Print #pCfgFile, "  they must be present in this file for each  ""Number of devices""  count."
    
    Close #pCfgFile
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
        & "SUCCESS Writing LL_USB.cfg configuration file." & vbCrLf
    fRetValMisc = ScrollText("down")
    GoTo EXIT_WRITE_CFG
    
NO_FILE:
    fRetVal = MsgDisplay( _
          Chr(10) _
        & Chr(10) _
        & "ERROR writing LL_USB.cfg!!" _
        & Chr(10) _
        & Chr(10) _
        & "File of same name may be in use." _
        & Chr(10) _
        & Chr(10), _
        "E R R O R ----")
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
        & "FAILED Writing LL_USB.cfg configuration file." & vbCrLf
    fRetValMisc = ScrollText("down")
    On Error GoTo 0
    fRetVal = False
    End
    
EXIT_WRITE_CFG:
    On Error GoTo 0
    fRetVal = True
EXIT1:
End Sub
Public Sub LoadDefaultCfg()
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
        & "Creating a default configuration" & vbCrLf
    fRetValMisc = ScrollText("down")
    
    sDefDeviceID = 0
    bChangeDefCfgStat = 0
    frmLL_USB.TextDevID = ""
    frmLL_USB.FrameDefaultCgf.Top = 3060
    frmLL_USB.FrameDefaultCgf.Left = 90

    frmLL_USB.FrameDefaultCgf.Visible = True
    
    While bChangeDefCfgStat = 0
        DoEvents
    Wend

    'DEF_CFG_SAVE = O1
    'DEF_CFG_CANCEL = O2
    If bChangeDefCfgStat = DEF_CFG_CANCEL Then
        sDefDeviceID = 0
        GoTo EXIT1
    End If
    
    If sDefDeviceID = 0 Then GoTo EXIT1
    
    usModelNum = 301
    
    sDLLDebug = 0
    bNumDevicesLocal = 1
    DeviceObjectArray(0).DEV_sID = sDefDeviceID
    DeviceObjectArray(0).DEV_bChan = 0
    DeviceObjectArray(0).DEV_dblRate = 100
    DeviceObjectArray(0).DEV_lScanBuffSize = 4096
    
EXIT1:
End Sub
Public Sub LoadLibraries()
    hLibLL_USB = LoadLibrary("LL_USB2k.DLL")
    If hLibLL_USB = 0 Then GoTo NO_LL_USBLib
    fRetVal = True
    GoTo EXIT1
NO_LL_USBLib:
    fRetVal = MsgDisplay("ERROR finding LL_USB2k.DLL" _
        & Chr(10) _
        & Chr(10) _
        & Chr(10) _
        & "Locate and place file in Windows directory, or" _
        & Chr(10) _
        & Chr(10) _
        & "same directory as application and try again." _
        & Chr(10) _
        & Chr(10), _
         "error")
    fRetVal = False
EXIT1:
    On Error GoTo 0
End Sub
Public Sub UnLoadLibraries()
    On Error GoTo EXIT1
    fRetVal = FreeLibrary(hLibLL_USB)
    hLibLL_USB = 0
EXIT1:
    On Error GoTo 0
End Sub
Public Sub CheckLibFuncs()
'PURPOSE: Checks for presence of required functions in LL_USB2k.DLL

'=====================================================================\
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
'=====================================================================/
'---------------->              INITIALIZATION
'* DLL_Init
'---------------->              DEVICE HANDLING
'* DLL_ResetDevice
'* DLL_GetDeviceIDList
'* DLL_ZeroSharedDevArray
'* DLL_ShowSharedDevArray
'* DLL_InstanceInitDeviceList
'* DLL_ReleaseDeviceFromIDList
'---------------->              DEVICE READ/WRITE
'* DLL_ReadWriteOneDevice
'---------------->              RATE (special)
'* DLL_SetRate
'---------------->              SCANNING
'* DLL_StartScan_DIO
'* DLL_ReadScanData_DIO
'* DLL_ReadScanDataWithDigin
'* DLL_EndScan_DIO
'---------------->              DEVICE INFO
'* DLL_ShowDeviceDescriptor
'* DLL_ShowConfigurationDescriptor
'* DLL_ShowInterfaceDescriptors
'* DLL_ShowEndpointDescriptors
'* DLL_GetDevVersion
'=====================================================================\
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
'=====================================================================/
'On Error GoTo MISSING_DLL_FUNC
'=======================================================================
'---------------->              INITIALIZATION
'=======================================================================
'DLL_Init
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_Init")
    If hLibCheck = 0 Then
        MsgBox "DLL_Init not found"
        GoTo MISSING_DLL_FUNC
    End If

'=======================================================================
'---------------->              DEVICE HANDLING
'=======================================================================
'DLL_ResetDevice(USHORT usDevID, BYTE bReserved);
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ResetDevice")
    If hLibCheck = 0 Then
        MsgBox "DLL_ResetDevice not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_ShowSharedDevArray
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ShowSharedDevArray")
    If hLibCheck = 0 Then
        MsgBox "DLL_ShowSharedDevArray not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_ZeroSharedDevArray
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ZeroSharedDevArray")
    If hLibCheck = 0 Then
        MsgBox "DLL_ZeroSharedDevArray not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_GetDeviceIDList
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_GetDeviceIDList")
    If hLibCheck = 0 Then
        MsgBox "DLL_GetDeviceIDList not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_InstanceInitDeviceList
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_InstanceInitDeviceList")
    If hLibCheck = 0 Then
        MsgBox "DLL_InstanceInitDeviceList not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_ReleaseDeviceFromIDList
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ReleaseDeviceFromIDList")
    If hLibCheck = 0 Then
        MsgBox "DLL_ReleaseDeviceFromIDList not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_ReInitOneDev
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ReInitOneDev")
    If hLibCheck = 0 Then
        MsgBox "DLL_ReInitOneDev not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_MarkOneDevAsInUse
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_MarkOneDevAsInUse")
    If hLibCheck = 0 Then
        MsgBox "DLL_MarkOneDevAsInUse not found"
        GoTo MISSING_DLL_FUNC
    End If
    
'=======================================================================
'---------------->              DEVICE READ/WRITE
'=======================================================================
'DLL_ReadWriteOneDevice
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ReadWriteOneDevice")
    If hLibCheck = 0 Then
        MsgBox "DLL_ReadWriteOneDevice not found"
        GoTo MISSING_DLL_FUNC
    End If
'=======================================================================
'---------------->              RATE (special)
'=======================================================================
'DLL_SetRate
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_SetRate")
    If hLibCheck = 0 Then
        MsgBox "DLL_SetRate not found"
        GoTo MISSING_DLL_FUNC
    End If
'=======================================================================
'---------------->              SCANNING
'=======================================================================
'DLL_StartScan_DIO
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_StartScan_DIO")
    If hLibCheck = 0 Then
        MsgBox "DLL_StartScan_DIO not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_ReadScanData_DIO
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ReadScanData_DIO")
    If hLibCheck = 0 Then
        MsgBox "DLL_ReadScanData_DIO not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_ReadScanDataWithDigin
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ReadScanDataWithDigin")
    If hLibCheck = 0 Then
        MsgBox "DLL_ReadScanDataWithDigin not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_EndScan_DIO
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_EndScan_DIO")
    If hLibCheck = 0 Then
        MsgBox "DLL_EndScan_DIO not found"
        GoTo MISSING_DLL_FUNC
    End If
    
'=======================================================================
'---------------->    DLL MESSAGING AND MISC DEVICE INFO
'=======================================================================
'DLL_ShowDeviceDescriptor
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ShowDeviceDescriptor")
    If hLibCheck = 0 Then
        MsgBox "DLL_ShowDeviceDescriptor not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_ShowConfigurationDescriptor
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ShowConfigurationDescriptor")
    If hLibCheck = 0 Then
        MsgBox "DLL_ShowConfigurationDescriptor not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_ShowInterfaceDescriptors
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ShowInterfaceDescriptors")
    If hLibCheck = 0 Then
        MsgBox "DLL_ShowInterfaceDescriptors not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_ShowEndpointDescriptors
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_ShowEndpointDescriptors")
    If hLibCheck = 0 Then
        MsgBox "DLL_ShowEndpointDescriptors not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_GetDevVersion
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_GetDevVersion")
    If hLibCheck = 0 Then
        MsgBox "DLL_GetDevVersion not found"
        GoTo MISSING_DLL_FUNC
    End If
'DLL_GetVersionInfo
    hLibCheck = GetProcAddress(hLibLL_USB, "DLL_GetVersionInfo")
    If hLibCheck = 0 Then
        MsgBox "DLL_GetVersionInfo not found"
        GoTo MISSING_DLL_FUNC
    End If
    
    GoTo EXIT1
    
MISSING_DLL_FUNC:
    On Error GoTo 0
    UnLoadLibraries
    fRetVal = MsgDisplay("CRITICAL ERROR" _
        & Chr(10) _
        & Chr(10) _
        & Chr(10) _
        & "Could not locate one or more of the required" _
        & Chr(10) _
        & "functions the LL_USBLib.DLL module." _
        & Chr(10) _
        & Chr(10) _
        & Chr(10) _
        & "Please contact Lawson Labs, Inc. For more trouble suggestions" _
        & Chr(10) _
        & Chr(10), _
         "error")
    End
    On Error GoTo 0
    fRetVal = False
    Return
EXIT1:
    fRetVal = True
End Sub
Public Sub Wait(dWaitTime)
    Dim dblEndTime As Double
    dblEndTime = Timer + dWaitTime
    Do While dblEndTime > Timer
        DoEvents
    Loop
End Sub
Public Function MsgDisplay(strMsg As String, mLabel As String)
    Const MB_OK = 0
    'MsgBox strMsg, vbOK       'this box has no title control
    iRetVal = MessageBox(frmLL_USB.hwnd, strMsg, mLabel, MB_OK)
End Function
Public Function ScrollText(Direction As String)
    If Direction = "down" Then
        frmLL_USB.txtMsgDisplay.SelStart = Len(frmLL_USB.txtMsgDisplay) & vbCrLf
    ElseIf Direction = "end" Then
        frmLL_USB.txtMsgDisplay.SelStart = Len(frmLL_USB.txtMsgDisplay)
    End If
End Function
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'===================================================================================================================
'=================================================================================================================
'===============================================================================================================
'=============================================================================================================
'===========================================================================================================
'=========================================================================================================
'=======================================================================
'***********************************************************************
'**** C O N T R O L   V I S I B I L I T Y   H A N D L I N G  ***********
'***********************************************************************
'=======================================================================
'=======================================================================
'=======================================================================
'=========================================================================================================
'===========================================================================================================
'=============================================================================================================
'===============================================================================================================
'=================================================================================================================
'===================================================================================================================
Public Sub MainPnlCtrlEnable()
        frmLL_USB.BtnSendChan.Enabled = True
        frmLL_USB.BtnScreenTypeSelect.Enabled = True
        frmLL_USB.ComboWhichDevice.Enabled = True
        
        frmLL_USB.btnDbgOptions.Enabled = True
        
        frmLL_USB.lblRate.Enabled = True
        frmLL_USB.LabelRate2.Enabled = True
        
        frmLL_USB.lblChan.Enabled = True
        frmLL_USB.lblDigIn.Enabled = True
        frmLL_USB.lblDigOut.Enabled = True
        
        frmLL_USB.EditChan.Enabled = True
        frmLL_USB.ComboRate.Enabled = True
    If bScreenMode = SCAN_SCREEN Then
        frmLL_USB.BtnScreenTypeSelect.Caption = "Change to Polled &Mode"
        frmLL_USB.lblCurMode.Caption = "Scan Mode"
        frmLL_USB.BtnScan.Enabled = True
        frmLL_USB.BtnGetConv.Visible = False
        frmLL_USB.BtnMoreFunctions.Enabled = False
        frmLL_USB.BtnSysCal.Enabled = False
        
        frmLL_USB.lblScanNum.Visible = True
        frmLL_USB.lblLogScansToFile.Visible = True
        frmLL_USB.lblBytesInScanBuff.Visible = True
        frmLL_USB.LblAvg.Visible = True
        
        frmLL_USB.lblScanBoost.Visible = True
        frmLL_USB.ShapeScanBoost.Visible = True
        frmLL_USB.txtScanBoost.Visible = True
        
        frmLL_USB.txtScansCompleted.Visible = True
        frmLL_USB.txtScansInScanBuff.Visible = True
        
        frmLL_USB.ShapeScanNum.Visible = True
        frmLL_USB.ShapeScanLog.Visible = True
        frmLL_USB.ShapeBytesInScanBuff.Visible = True
        frmLL_USB.ShapeAvg.Visible = True
        
        If frmLL_USB.ChkMultiChan.Value = vbChecked Then
            frmLL_USB.ShapeCalScan.Visible = True
            frmLL_USB.CheckCalScan.Visible = True
            frmLL_USB.lblCalScan.Visible = True
            
            frmLL_USB.LabelScanArg.Visible = True
            frmLL_USB.ShapeScanArg.Visible = True
            frmLL_USB.ComboScanArg.Visible = True
            
            frmLL_USB.lblDiginScan.Visible = True
            frmLL_USB.CheckDiginScan.Visible = True
            frmLL_USB.ShapeDiginScan.Visible = True
        Else
            frmLL_USB.ShapeCalScan.Visible = False
            frmLL_USB.CheckCalScan.Visible = False
            frmLL_USB.lblCalScan.Visible = False
            frmLL_USB.LabelScanArg.Visible = False
            frmLL_USB.ShapeScanArg.Visible = False
            frmLL_USB.ComboScanArg.Visible = False
        End If
        
        frmLL_USB.lblMultChan.Visible = True
        frmLL_USB.ChkMultiChan.Visible = True
        frmLL_USB.ShapeMultChan.Visible = True
        
        frmLL_USB.lblDiginScan.Visible = True
        frmLL_USB.CheckDiginScan.Visible = True
        frmLL_USB.ShapeDiginScan.Visible = True
        
        frmLL_USB.CheckDoLogFile.Visible = True
        frmLL_USB.ComboAvg.Visible = True
    Else
        frmLL_USB.BtnScreenTypeSelect.Caption = "Change to Scan &Mode"
        frmLL_USB.lblCurMode.Caption = "Polled Mode"
        frmLL_USB.BtnGetConv.Visible = True
        frmLL_USB.BtnGetConv.Enabled = True
        frmLL_USB.btnAnalogOut.Enabled = True

        frmLL_USB.BtnMoreFunctions.Enabled = True
        frmLL_USB.BtnSysCal.Enabled = True
        
        frmLL_USB.lblScanNum.Visible = False
        frmLL_USB.lblWhichDevice.Enabled = True
        frmLL_USB.lblLogScansToFile.Visible = False
        frmLL_USB.lblBytesInScanBuff.Visible = False
        frmLL_USB.LblAvg.Visible = False
        
        frmLL_USB.lblScanBoost.Visible = False
        frmLL_USB.ShapeScanBoost.Visible = False
        frmLL_USB.txtScanBoost.Visible = False
        
        frmLL_USB.txtScansCompleted.Visible = False
        frmLL_USB.txtScansInScanBuff.Visible = False
        
        frmLL_USB.txtAnyScanErr.Visible = False
        frmLL_USB.btnShowScanErrors.Visible = False
        
        frmLL_USB.ShapeScanNum.Visible = False
        frmLL_USB.ShapeScanLog.Visible = False
        frmLL_USB.ShapeBytesInScanBuff.Visible = False
        frmLL_USB.ShapeAvg.Visible = False
        
        frmLL_USB.ShapeCalScan.Visible = False
        frmLL_USB.CheckCalScan.Visible = False
        frmLL_USB.lblCalScan.Visible = False
        
        frmLL_USB.CheckDoLogFile.Visible = False
        frmLL_USB.ChkMultiChan.Visible = False
        frmLL_USB.lblMultChan.Visible = False
        frmLL_USB.ShapeMultChan.Visible = False
        frmLL_USB.ComboAvg.Visible = False
        
        frmLL_USB.LabelScanArg.Visible = False
        frmLL_USB.ShapeScanArg.Visible = False
        frmLL_USB.ComboScanArg.Visible = False
        
        frmLL_USB.lblDiginScan.Visible = False
        frmLL_USB.CheckDiginScan.Visible = False
        frmLL_USB.ShapeDiginScan.Visible = False
        frmLL_USB.lblCalScan.Visible = False
        frmLL_USB.CheckCalScan.Visible = False
        frmLL_USB.ShapeCalScan.Visible = False
    End If
End Sub
Public Sub MainPnlCtrlDisable()
        frmLL_USB.lblCurMode.Caption = "Polled Mode"
        frmLL_USB.BtnScan.Enabled = False
        frmLL_USB.BtnGetConv.Enabled = False
        
        frmLL_USB.BtnSendChan.Enabled = False
        frmLL_USB.BtnSendDigout.Enabled = False
        
        frmLL_USB.btnDbgOptions.Enabled = False
        
        frmLL_USB.BtnMoreFunctions.Enabled = False
        frmLL_USB.BtnScreenTypeSelect.Enabled = False
        frmLL_USB.BtnSysCal.Enabled = False
        
        frmLL_USB.lblRate.Enabled = False
        frmLL_USB.LabelRate2.Enabled = False
        frmLL_USB.lblChan.Enabled = False
        frmLL_USB.lblDigIn.Enabled = False
        frmLL_USB.lblDigOut.Enabled = False
        frmLL_USB.lblWhichDevice.Enabled = False
        
        frmLL_USB.EditDigout.Text = ""
        frmLL_USB.EditChan.Enabled = False
        frmLL_USB.ComboRate.Enabled = False
        frmLL_USB.ComboWhichDevice.Enabled = False
End Sub
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'===================================================================================================================
'=================================================================================================================
'===============================================================================================================
'=============================================================================================================
'===========================================================================================================
'=========================================================================================================
'=======================================================================
'***********************************************************************
'**** S Y S T E M    C A L I B R A T I O N  ****************************
'***********************************************************************
'=======================================================================
'=======================================================================
'=======================================================================
'=========================================================================================================
'===========================================================================================================
'=============================================================================================================
'===============================================================================================================
'=================================================================================================================
'===================================================================================================================
Public Sub DoSysCal()
    Dim bSysCalChecksum As Byte
    bSysCalChecksum = (COMMAND_SYS_CAL)
    
    Const SYSCAL_RETRY_MAX = 2
    Dim bRetries As Byte: bRetries = 0
    
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
        & vbCrLf & "Calibrating device: " & sLLABS_DeviceIDList(bCurIndexOfSelectedDev)
    fRetValMisc = ScrollText("down")
    
SYSCAL_START:
    
    
    iNumBytesToReadWrite = 8
    ReDim bHostClientDataBuf(iNumBytesToReadWrite)
    bHostClientDataBuf(0) = COMMAND_SYS_CAL
    bHostClientDataBuf(1) = 0
    bHostClientDataBuf(2) = bSysCalChecksum 'Checksum
    bHostClientDataBuf(3) = 0
    bHostClientDataBuf(4) = 0
    
    frmLL_USB.FrameWaitMsg.Visible = True
    DoEvents
    
    bRetVal = DLL_ReadWriteOneDevice(DO_WRITE, bHostClientDataBuf(0), sLLABS_DeviceIDList(bCurIndexOfSelectedDev), iNumBytesToReadWrite, pbLastDigin, 0)
    
    If bRetVal = 0 Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "System Calibration FAILED" & vbCrLf & "Check all cable connections and try again." & vbCrLf
        fRetValMisc = ScrollText("down")
        GoTo EXIT_ERROR
    End If
    
'=======================================================================
'=== Wait settling time for calibration ================================
'=======================================================================
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & vbCrLf & "Waiting settling time ...."
    fRetValMisc = ScrollText("down")
    frmLL_USB.Timer1.Enabled = False
    frmLL_USB.Timer1.Interval = 2000
    fTimerStat = TIMER_START
    frmLL_USB.Timer1.Enabled = True
    While fTimerStat = TIMER_START
        DoEvents
    Wend
    frmLL_USB.Timer1.Enabled = False
    
'=======================================================================
'=== Get results from system calibration ===============================
'=======================================================================
    iNumBytesToReadWrite = 32
    ReDim bHostClientDataBuf(iNumBytesToReadWrite)
    
    bRetVal = DLL_ReadWriteOneDevice(DO_READ, bHostClientDataBuf(0), sLLABS_DeviceIDList(bCurIndexOfSelectedDev), iNumBytesToReadWrite, pbLastDigin, 0)
    If bRetVal = 0 Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Failed READ of mode registers " & "for device: " & sLLABS_DeviceIDList(bCurIndexOfSelectedDev) & vbCrLf & "Check all cable connections and try again." & vbCrLf
        fRetValMisc = ScrollText("down")
        GoTo EXIT_ERROR
    End If
    
    '6-26-02 frmLL_USB.EditDigin.Text = pbLastDigIn
    If usModelNum = 301 Then
        frmLL_USB.EditDigin.Text = pbLastDigin Xor 255
    Else
        frmLL_USB.EditDigin.Text = pbLastDigin And &HF
    End If
    
'=======================================================================
'=== View values returned by board after sending syscal ================
'=======================================================================
    Dim datastring
    datastring = ""
    Dim bArrayIndex As Byte
    For bArrayIndex = 0 To 2
        datastring = datastring & " 0x" & Hex(bHostClientDataBuf(bArrayIndex))
    Next bArrayIndex
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Values read after sending syscal: " & datastring & vbCrLf
    fRetValMisc = ScrollText("down")
    
    Dim bSyscalEchoStat As Byte: bSyscalEchoStat = 0
    If bHostClientDataBuf(0) = 1 _
        And bHostClientDataBuf(1) = 2 _
        And bHostClientDataBuf(2) = 3 Then
        bSyscalEchoStat = 1
    End If
    'bSysCalEchoStat = 1 'override for testing only.
    If bSyscalEchoStat < 1 Then
        bRetries = bRetries + 1
        If bRetries > SYSCAL_RETRY_MAX Then
            frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Could not READ correct bytes from device: " & sLLABS_DeviceIDList(bCurIndexOfSelectedDev) & vbCrLf & "Check all cable connections and try again." & vbCrLf
            fRetValMisc = ScrollText("down")
            GoTo EXIT_ERROR
        Else
            frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Syscal returned incorrect byte sequence. Trying again." & vbCrLf
            fRetValMisc = ScrollText("down")
            GoTo SYSCAL_START
        End If
    End If
    
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "System calibration SUCCESS" & vbCrLf
    fRetValMisc = ScrollText("down")
    
    GoTo EXIT_DONE
    
EXIT_ERROR:
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "System calibration ERROR" & vbCrLf
    fRetValMisc = ScrollText("down")

EXIT_DONE:

    frmLL_USB.FrameWaitMsg.Visible = False

End Sub
Public Sub GetModeReg(usDevID As Integer)
    ' THIS IS FOR IN-HOUSE TROUBLESHOOTING ONLY
    ' Call this after sending a SignOn command, or writing new rate codes to
    '  inspect the bytes returned. Note that both calls echo the rate codes.
    '  A signon always signs on at 100Hz, so it will echo 1,2,3,<mode registers>.
    ' Note that this is more/less a utility function. Not usually required
    '  except for trouble-shooting.
    
    Dim bCurIndex As Byte
    For bCurIndex = 0 To MAX_DEV_CNT_MINUS_ONE
        If sLLABS_DeviceIDList(bCurIndex) = usDevID Then GoTo DONE
    Next bCurIndex
DONE:

    Dim loopcnt As Byte: loopcnt = 0
    iNumBytesToReadWrite = 32
    ReDim bHostClientDataBuf(iNumBytesToReadWrite)
    Dim datastring As String
    Dim bArrayIndex As Byte
    Dim bModeRegEchoStat As Byte

    frmLL_USB.Timer1.Enabled = False
    frmLL_USB.Timer1.Interval = 10000 / DeviceObjectArray(bCurIndex).DEV_dblRate
    fTimerStat = TIMER_START
    frmLL_USB.Timer1.Enabled = True
    While fTimerStat = TIMER_START
        DoEvents
    Wend
    frmLL_USB.Timer1.Enabled = False

    bRetVal = DLL_ReadWriteOneDevice(DO_READ, bHostClientDataBuf(0), usDevID, iNumBytesToReadWrite, pbLastDigin, 0)
    If bRetVal = 0 Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Read failed for for device: " & usDevID & ". Could not read mode registers" & vbCrLf
        fRetValMisc = ScrollText("down")
        fRetVal = False
        GoTo EXIT1
    End If
    
    'For trouble-shooting only
    'dataString = String(255, "*")
    'For bArrayIndex = 0 To 7
    '    dataString = dataString & bArrayIndex & ": " _
    '    & Hex(bHostClientDataBuf(bArrayIndex)) & "h, " & vbCrLf
    'Next bArrayIndex
    'frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
    '    & vbCrLf & "Values read after sending rate change token: " & dataString & vbCrLf & vbCrLf
    'fRetValMisc = ScrollText("down")
    
'=======================================================================
'== Check mode register values returned by board after sending signon ==
'=======================================================================
    ' Board echoes Mode Registers for 100Hz (default signon rate) 35, 0, 140
    '  after sending signon token (0). If this sequence of bytes isn't echoed
    '  then proper first phase of signon did not occur.
    
    bModeRegEchoStat = 0
    bHostClientDataBuf(3) = bHostClientDataBuf(3) And &HFE
    If bHostClientDataBuf(3) = 34 _
        And bHostClientDataBuf(4) = 0 _
        And bHostClientDataBuf(5) = 140 _
        And bHostClientDataBuf(6) = 0 Then
        bModeRegEchoStat = 1
    End If
    
    If bModeRegEchoStat < 1 Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Incorrect mode register bytes " & "after system calibration for device: " & usDevID & vbCrLf
        fRetValMisc = ScrollText("down")
        fRetVal = False
        GoTo EXIT1
    Else
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Read the expected Mode Register values " & "for device: " & usDevID & vbCrLf
        fRetValMisc = ScrollText("down")
    End If
    fRetVal = True
    
EXIT1:
End Sub

'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'##############################################################################################################
'===================================================================================================================
'=================================================================================================================
'===============================================================================================================
'=============================================================================================================
'===========================================================================================================
'=========================================================================================================
'=======================================================================
'***********************************************************************
'**** C H A N N E L   C H A N G E  *************************************
'***********************************************************************
'=======================================================================
'=======================================================================
'=======================================================================
'=========================================================================================================
'===========================================================================================================
'=============================================================================================================
'===============================================================================================================
'=================================================================================================================
'===================================================================================================================
'12-10-01 The following replaces the old function shown below
Public Function DoChanChange() As Boolean
    Dim bChanToSendLocal As Byte
    bChanToSendLocal = DeviceObjectArray(bCurIndexOfSelectedDev).DEV_bChan
    bRetVal = SP_SendChan(sLLABS_DeviceIDList(bCurIndexOfSelectedDev), bChanToSendLocal, pbLastDigin)
    If bRetVal = 0 Then
        '8-2-04 frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Channel change FAILED for DevID: " & sLLABS_DeviceIDList(bCurIndexOfSelectedDev) & vbCrLf & "Check all cable connections and try again." & vbCrLf: fRetValMisc = ScrollText("down")
        
        '8-2-04  ######################
        Dim usDevList_LOCAL(32) As Integer
        Dim uiUnused As Long
        Dim bDevListIndex_LOCAL As Byte
        Dim bThisRetVal As Byte
        Dim fDevFoundInList As Boolean: fDevFoundInList = False
        For bDevListIndex_LOCAL = 0 To 31
            usDevList_LOCAL(bDevListIndex_LOCAL) = 0
        Next bDevListIndex_LOCAL

        bThisRetVal = SP_GetAppDevList(usDevList_LOCAL(0), uiUnused)
        If bThisRetVal Then
            For bDevListIndex_LOCAL = 0 To 31
                If (usDevList_LOCAL(bDevListIndex_LOCAL) <> 0) And usDevList_LOCAL(bDevListIndex_LOCAL) = sLLABS_DeviceIDList(bCurIndexOfSelectedDev) Then
                    fDevFoundInList = True
                    Exit For
                End If
            Next bDevListIndex_LOCAL
        End If
        If fDevFoundInList = False Then
            frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Device: " & sLLABS_DeviceIDList(bCurIndexOfSelectedDev) & " no longer owned by this app" & vbCrLf
            fRetValMisc = ScrollText("down")
        Else
            frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Channel change FAILED" & vbCrLf & "Check all cable connections and try again." & vbCrLf
            fRetValMisc = ScrollText("down")
        End If
        '8-2-04  ######################
        
        
        DoChanChange = False: Exit Function
    Else
        DoChanChange = True: fChanChangePending = False
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Channel: " & bChanToSendLocal & " sent for DevID: " & sLLABS_DeviceIDList(bCurIndexOfSelectedDev): fRetValMisc = ScrollText("down")
        frmLL_USB.BtnSendChan.BackColor = vbButtonFace
    End If
End Function
'12-10-01 The following has been replaced with the new function
' shown above.
Public Function DoChanChange_OLD() As Boolean
    Dim bChanToSendLocal As Byte
    bChanToSendLocal = DeviceObjectArray(bCurIndexOfSelectedDev).DEV_bChan
    
    iNumBytesToReadWrite = 8
    ReDim bHostClientDataBuf(iNumBytesToReadWrite)
    bHostClientDataBuf(0) = COMMAND_CHAN_CHG
    bHostClientDataBuf(1) = bChanToSendLocal
    bHostClientDataBuf(2) = (COMMAND_CHAN_CHG + bChanToSendLocal) Mod 256
    
    bHostClientDataBuf(3) = 0
    bHostClientDataBuf(4) = 0
    
    bRetVal = DLL_ReadWriteOneDevice(DO_WRITE, bHostClientDataBuf(0), sLLABS_DeviceIDList(bCurIndexOfSelectedDev), iNumBytesToReadWrite, pbLastDigin, 0)
    If bRetVal = 0 Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Channel change FAILED for DevID: " & sLLABS_DeviceIDList(bCurIndexOfSelectedDev) & vbCrLf & "Check all cable connections and try again." & vbCrLf
        fRetValMisc = ScrollText("down")
        DoChanChange_OLD = False
        GoTo EXIT1
    End If
    
    DoChanChange_OLD = True
        
    fChanChangePending = False
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Channel: " & bChanToSendLocal & " sent for DevID: " & sLLABS_DeviceIDList(bCurIndexOfSelectedDev)
    fRetValMisc = ScrollText("down")
    frmLL_USB.BtnSendChan.BackColor = vbButtonFace
    
EXIT1:
End Function
'10-28-05 function removed
Public Sub CalcAndLoadRateCodes()
'
End Sub
Public Sub UpdateLocalDevice()
'=======================================================================
'=== Check actual installed devices against the ones listed       ======
'===  by the application, from a config file for example. When    ======
'===  this function returns, sLLABS_DeviceIDList() will contain   ======
'===  a listing of the available devices as found by the DLL.     ======
'===  For example, if the following is true before the call:      ======
'===  sLLABS_DeviceIDList(0) = 33                                 ======
'===  sLLABS_DeviceIDList(1) = 85                                 ======
'===  sLLABS_DeviceIDList(3) = 12                                 ======
'===  sLLABS_DeviceIDList(4) = 129                                ======
'===  sLLABS_DeviceIDList(5) = 65                                 ======
'===  and only device ID #85 and #65 exists, then afterwards      ======
'===  the array will look like:                                   ======
'===  sLLABS_DeviceIDList(0) = 0                                  ======
'===  sLLABS_DeviceIDList(1) = 85                                 ======
'===  sLLABS_DeviceIDList(3) = 0                                  ======
'===  sLLABS_DeviceIDList(4) = 0                                  ======
'===  sLLABS_DeviceIDList(5) = 65                                 ======
'===  The bNumDevicesShared variable (passed in DLL_Init() above  ======
'===   will equal the number devices found by the DLL that match  ======
'===   the ID's of devies requested by the application. Hereafter ======
'===   when interracting with the DLL with a device number such   ======
'===   as referenced by  "bCurDevListIndex"  throughout this code ======
'===   if bCurDevListIndex = 0 then the device being referenced   ======
'===   will be device ID #85. Also the var bNumDevicesShared will ======
'===   equal the number of devices found by the DLL that equal the =====
'===   requested devices. In this case that would be "2".         ======
'=======================================================================
    
    'Initialize this array to zeroes before the call. Only do this
    ' during this sign-on process. The following array is used to
    ' communicate between the DLL and application the current usage
    ' of the desired Device ID by this or another application. If the
    ' device is currently being used by this or another application,
    ' then it's position in this array that corresponds to it's
    ' position in the sLLABS_DeviceIDList array will have it's value
    ' set to 2. If the device exists, but isn't in use, then the value
    ' well be set to 1.
    Dim bArrayIndex As Byte
    For bArrayIndex = 0 To MAX_DEV_CNT_MINUS_ONE
        bFuncArgIgnored(bArrayIndex) = 0
    Next bArrayIndex
   
    'Save a temporary list of the DeviceID's loaded from configuration
    ' file or setup. The DLL will remove unavailable devices from the
    ' main sLLABS_DeviceIDList array.
    Dim DeviceIDListOriginal(MAX_DEV_CNT) As Integer
    For bArrayIndex = 0 To MAX_DEV_CNT_MINUS_ONE
        DeviceIDListOriginal(bArrayIndex) = sLLABS_DeviceIDList(bArrayIndex)
    Next bArrayIndex
    
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "BEFORE DLL_InstanceInitDeviceList()" & vbCrLf
       
    If bNumDevicesLocal > 0 Then
        For bArrayIndex = 0 To MAX_DEV_CNT_MINUS_ONE
            If sLLABS_DeviceIDList(bArrayIndex) > 0 Then
                frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & "    sLLABS_DeviceIDList(" & bArrayIndex & "): " & sLLABS_DeviceIDList(bArrayIndex) & vbCrLf
                fRetValMisc = ScrollText("down")
            End If
        Next bArrayIndex
    End If
    
    Dim bShowDeviceLists As Byte
    bShowDeviceLists = 0
    bRetVal = DLL_InstanceInitDeviceList(bShowDeviceLists)
    
    '1-4-02
    bRetVal = SP_GetAppDevCnt(bNumDevicesShared)

    
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "AFTER DLL_InstanceInitDeviceList()   " & vbCrLf
       
    If bNumDevicesLocal > 0 Then
        For bArrayIndex = 0 To bNumDevicesLocal - 1
            frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & "    sLLABS_DeviceIDList(" & bArrayIndex & "): " & sLLABS_DeviceIDList(bArrayIndex) & vbCrLf
            fRetValMisc = ScrollText("down")
        Next bArrayIndex
    End If
    
    If bRetVal = 1 Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Success in search for attached devices." & vbCrLf
            fRetValMisc = ScrollText("down")
    Else
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & "FAILED in search for attached devices." & vbCrLf & vbCrLf
        fRetValMisc = ScrollText("down")
    End If
    
    If bNumDevicesShared = 0 Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & vbCrLf & "No available devices found!!" & vbCrLf & "Please check cable connections," & " or Device ID list, and try again" & vbCrLf
        fRetValMisc = ScrollText("down")
    End If
    
    If bNumDevicesShared > 1 Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Found  " & bNumDevicesShared & " of the requested devices.  " & vbCrLf
        fRetValMisc = ScrollText("down")
    Else
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & "Found: " & bNumDevicesShared & " available device " & "of the " & bNumDevicesLocal & " requested devices" & vbCrLf
        fRetValMisc = ScrollText("down")
    End If
    
    If bNumDevicesShared < bNumDevicesLocal Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Found fewer devices than listed in original " & " configuration !" & vbCrLf
        fRetValMisc = ScrollText("down")
        
        Dim tempDeviceObject(MAX_DEV_CNT) As DEVICE_OBJECT
        Dim tempDeviceIDList(MAX_DEV_CNT) As Integer
        Dim tempArrayPtr
        
        tempArrayPtr = 0
        For bArrayIndex = 0 To (bNumDevicesLocal - 1)
            If sLLABS_DeviceIDList(bArrayIndex) > 0 Then
                tempDeviceObject(tempArrayPtr) = DeviceObjectArray(bArrayIndex)
                tempDeviceIDList(tempArrayPtr) = sLLABS_DeviceIDList(bArrayIndex)
                tempArrayPtr = tempArrayPtr + 1
            End If
        Next bArrayIndex
        
        For tempArrayPtr = 0 To (bNumDevicesLocal - 1)
           DeviceObjectArray(tempArrayPtr) = tempDeviceObject(tempArrayPtr)
           sLLABS_DeviceIDList(tempArrayPtr) = tempDeviceIDList(tempArrayPtr)
        Next tempArrayPtr
        
        'Update our device count to reflect actual count revealed by DLL
        bNumDevicesLocal = bNumDevicesShared
    End If
    
    If bNumDevicesLocal = 0 Then
        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "There are no available devices. " & vbCrLf
        fRetValMisc = ScrollText("down")
        GoTo EXIT_ERROR
    End If
EXIT_ERROR:
EXIT1:

End Sub
Public Sub UpdateAvailDevListAndControls()
    Dim tempDeviceObject(MAX_DEV_CNT) As DEVICE_OBJECT: Dim tempDeviceIDList(MAX_DEV_CNT) As Integer: Dim tempArrayPtr: tempArrayPtr = 0: Dim bTotDev As Byte: bTotDev = 0: Dim bArrayIndex As Byte: Dim bCurDevListIndex As Byte
    
    For bArrayIndex = 0 To MAX_DEV_CNT_MINUS_ONE
        If sLLABS_DeviceIDList(bArrayIndex) > 0 Then
            tempDeviceObject(tempArrayPtr) = DeviceObjectArray(bArrayIndex)
            tempDeviceIDList(tempArrayPtr) = sLLABS_DeviceIDList(bArrayIndex)
            tempArrayPtr = tempArrayPtr + 1
            bTotDev = bTotDev + 1
        End If
    Next bArrayIndex
    
    For tempArrayPtr = 0 To MAX_DEV_CNT_MINUS_ONE
       DeviceObjectArray(tempArrayPtr) = tempDeviceObject(tempArrayPtr)
       sLLABS_DeviceIDList(tempArrayPtr) = tempDeviceIDList(tempArrayPtr)
    Next tempArrayPtr
    
    frmLL_USB.ComboWhichDevice.Clear
    
    If bTotDev Then
        For bCurDevListIndex = 0 To bTotDev - 1
            frmLL_USB.ComboWhichDevice.List(bCurDevListIndex) = sLLABS_DeviceIDList(bCurDevListIndex)
        Next bCurDevListIndex
    End If
    
    frmLL_USB.ComboWhichDevice.Text = sLLABS_DeviceIDList(0)
    frmLL_USB.ComboRate.Text = DeviceObjectArray(0).DEV_dblRate
    bNumDevicesLocal = bTotDev: bNumDevicesShared = bTotDev
End Sub
Public Sub ReadIniFileDebugLevel()
    On Error GoTo EXIT1
    sDLLDebug = GetPrivateProfileInt("LL_USB", "DebugLvl", 0, "LL_USB.ini")
    If sDLLDebug > 6 Then sDLLDebug = 6
    frmLL_USB.txtDebugLevel = sDLLDebug
    
    frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Debug level:  " & sDLLDebug & vbCrLf
    fRetValMisc = ScrollText("down")
    
EXIT1:
    On Error GoTo 0
End Sub
Public Sub ReadIniFileScanBoostLevel()
    Dim bValRead As Byte
    On Error GoTo EXIT1
    bValRead = GetPrivateProfileInt("LL_USB", "ScanSystemBoostLevel", 0, "LL_USB.ini")
    If bValRead > 100 Then
        frmLL_USB.txtScanBoost = "X"
    Else
        frmLL_USB.txtScanBoost = bValRead
        bScanBoostVal = bValRead
    End If
EXIT1:
    On Error GoTo 0
End Sub
'The following is only used for in-house testing
Public Sub ReadIniFileInHouseConfig()
    On Error GoTo EXIT1
    bUseInHouseAutoConfig = GetPrivateProfileInt("InHouse", "InHouseConfigSetup", 0, "LL_USB.ini")
    If bUseInHouseAutoConfig > 0 Then
        frmLL_USB.CheckUseTestConfig.Visible = True
        frmLL_USB.CheckUseTestConfig.Value = vbChecked
        frmLL_USB.CheckIsJusticeBoard.Visible = True
        frmLL_USB.btnDigIncrement.Visible = True
        
        
    '3-24-09 START
    Else
        frmLL_USB.CheckUseTestConfig.Visible = False
        frmLL_USB.CheckUseTestConfig.Value = vbUnchecked
        frmLL_USB.CheckIsJusticeBoard.Visible = False
        frmLL_USB.btnDigIncrement.Visible = False
    '3-24-09 END
       
        
        
        
    End If
    
EXIT1:
    On Error GoTo 0
End Sub




'Public Sub ReadCfgFile_RetryWithNewConfigStyle()
'    Dim bCurDevListIndex As Byte
'    Dim fCfg As Long
'    Dim sStr As String
'    Dim bDupIndex As Byte
'
'    If fSignOn Then
'        Dim bCurIndex As Byte
'        For bCurIndex = 0 To MAX_DEV_CNT_MINUS_ONE
'            sLLABS_DeviceIDToRelease(bCurIndex) = sLLABS_DeviceIDList(bCurIndex)
'        Next bCurIndex
'        bRetVal = DLL_ReleaseDeviceFromIDList(sLLABS_DeviceIDToRelease(0), FREE_ONLY_APP_OWNED_DEVICES)
'        fSignOn = False
'    End If
'
'    Dim bArrayIndexTemp As Byte
'    For bArrayIndexTemp = 0 To MAX_DEV_CNT_MINUS_ONE
'        sLLABS_DeviceIDList(bArrayIndexTemp) = 0
'        DeviceObjectArray(bArrayIndexTemp).DEV_sID = 0
'        DeviceObjectArray(bArrayIndexTemp).DEV_bChan = 0
'        DeviceObjectArray(bArrayIndexTemp).DEV_dblRate = 0
'        DeviceObjectArray(bArrayIndexTemp).DEV_bStat = 0
'        DeviceObjectArray(bArrayIndexTemp).DEV_lScanBuffSize = 0
'    Next bArrayIndexTemp
'
'    strCfgFileSpec = "LL_USB.cfg"
'    fCfg = FreeFile
'    On Error GoTo DONE_WITH_ERR
'    Open strCfgFileSpec For Input As #fCfg
'
'    Dim SearchString_ID As String: SearchString_ID = "ID="
'    Dim SearchString_RATE As String: SearchString_RATE = "RATE="
'    Dim SearchString_CHAN As String: SearchString_CHAN = "CHAN="
'    Dim ID_String, RATE_String, CHAN_String As String
'    usModelNum = 0
'    Dim DevID  As Integer
'    Dim Chan As Byte
'    Dim Rate As Double
'    Dim i As Long
'    Dim fValidDev As Boolean: fValidDev = False
'    Dim bIndexValidDevice As Byte: bIndexValidDevice = 0
'    Do While Not EOF(fCfg)
'        DevID = 0
'        Do While Not EOF(fCfg)
'            Input #fCfg, sStr
'            i = InStr(1, UCase(sStr), SearchString_ID, vbTextCompare)
'            If i <> 0 Then
'                ID_String = Right(sStr, Len(sStr) - ((i - 1) + Len(SearchString_ID)))
'                ID_String = Trim(ID_String)
'                DevID = Int(Val(ID_String))
'                'DevID = Int(ID_String)
'                GoTo DONE_ID_TEST
'            End If
'        Loop
'
'DONE_ID_TEST:
'        'MsgBox ID_String
'
'        If usModelNum = 0 Then
'            If (DevID > 5000) And (DevID < 14000) Then
'                usModelNum = 302
'                frmLL_USB.Caption = "Model-302 VB sample": frmLL_USB.Label4.Caption = "Model 302 DEMO"
'                frmLL_USB.CheckModel301.Value = vbUnchecked: frmLL_USB.CheckModel302.Value = vbChecked
'                frmLL_USB.Text2.Visible = True: frmLL_USB.txtDAC_Volts.Visible = True: frmLL_USB.btnAnalogOut.Visible = True: frmLL_USB.Label18.Visible = True: frmLL_USB.cmboDAC.Visible = True: frmLL_USB.Label25.Visible = True
'            Else
'                If (DevID > 100) And (DevID < 5000) Then
'                    usModelNum = 301
'                    frmLL_USB.Caption = "Model-301 VB sample": frmLL_USB.Label4.Caption = "Model 301 DEMO"
'                    frmLL_USB.CheckModel301.Value = vbChecked: frmLL_USB.CheckModel302.Value = vbUnchecked
'                    frmLL_USB.Text2.Visible = False: frmLL_USB.txtDAC_Volts.Visible = False: frmLL_USB.btnAnalogOut.Visible = False: frmLL_USB.Label18.Visible = False: frmLL_USB.cmboDAC.Visible = False: frmLL_USB.Label25.Visible = False
'                Else
'                    DevID = 0
'                End If
'            End If
'        End If
'
'
'        'Test if valid device. Whichever device type is seen first is the type
'        '  that I continue to use. For example if the first device in the file
'        '  is a 302 then that's all I store the information for. This application
'        '  will only use one or the other.
'        fValidDev = False
'        If DevID Then
'            If usModelNum = 302 Then
'                If ((DevID > 5000) And (DevID < 14000)) Then
'                    'MsgBox "is 302 and WILL use it"
'                    fValidDev = True
'                Else
'                    'MsgBox "is 301 and NOT using it"
'                End If
'            Else
'                If (DevID > 5000) And (DevID < 14000) Then
'                    'MsgBox "is 302 and NOT using it"
'                Else
'                    'MsgBox "is 301 and WILL use it"
'                    fValidDev = True
'                End If
'            End If
'        End If
'
'        If fValidDev Then
'            For bDupIndex = 0 To (MAX_DEV_CNT - 1)
'                If sLLABS_DeviceIDList(bDupIndex) = DevID Then
'                    fValidDev = False
'                End If
'            Next bDupIndex
'            If fValidDev Then
'                sLLABS_DeviceIDList(bIndexValidDevice) = DevID
'                DeviceObjectArray(bIndexValidDevice).DEV_sID = DevID
'            End If
'        End If
'
'        Do While Not EOF(fCfg)
'            Input #fCfg, sStr
'            i = InStr(1, UCase(sStr), SearchString_RATE, vbTextCompare)
'            If i <> 0 Then
'                RATE_String = Right(sStr, Len(sStr) - ((i - 1) + Len(SearchString_RATE)))
'                RATE_String = Trim(RATE_String)
'                If fValidDev Then
'                    Rate = CDbl(Val(RATE_String))
'
'                    If (Rate < 1000) And (Rate > 49) Then
'                        DeviceObjectArray(bIndexValidDevice).DEV_dblRate = Rate
'                    Else
'                        DeviceObjectArray(bIndexValidDevice).DEV_dblRate = 100#
'                    End If
'                End If
'                GoTo DONE_RATE_TEST
'            Else
'                '12-7-04b after putting on HP
'                If fValidDev Then DeviceObjectArray(bIndexValidDevice).DEV_dblRate = 100#
'            End If
'        Loop
'DONE_RATE_TEST:
'        'MsgBox RATE_String
'
'
'        Do While Not EOF(fCfg)
'            Input #fCfg, sStr
'            i = InStr(1, UCase(sStr), SearchString_CHAN, vbTextCompare)
'            If i <> 0 Then
'                CHAN_String = Right(sStr, Len(sStr) - ((i - 1) + Len(SearchString_CHAN)))
'                CHAN_String = Trim(CHAN_String)
'
'                If fValidDev Then
'                    Chan = CByte(Val(CHAN_String))
'
'                    If usModelNum = 301 Then
'                        If (Chan = 0) Or (Chan = 1) Or (Chan = 6) Or (Chan = 7) Then
'                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = Chan
'                        Else
'                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = 7
'                        End If
'                    Else
'                        If Chan < 8 Then
'                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = Chan
'                        Else
'                            DeviceObjectArray(bIndexValidDevice).DEV_bChan = 7
'                        End If
'                    End If
'
'                End If
'                GoTo DONE_CHAN_TEST
'            Else
'                '12-7-04b after putting on HP
'                If fValidDev Then DeviceObjectArray(bIndexValidDevice).DEV_bChan = 7
'            End If
'        Loop
'DONE_CHAN_TEST:
'        If fValidDev Then bIndexValidDevice = bIndexValidDevice + 1
'        'MsgBox CHAN_String
'    Loop
'
'
'    bNumDevicesLocal = 0
'    For bArrayIndexTemp = 0 To MAX_DEV_CNT_MINUS_ONE
'        If sLLABS_DeviceIDList(bArrayIndexTemp) <> 0 Then bNumDevicesLocal = bNumDevicesLocal + 1
'    Next bArrayIndexTemp
'    If bNumDevicesLocal <= 0 Then
'        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & "No valid devices listed in configuration file!" & vbCrLf
'        fRetValMisc = ScrollText("down")
'        bReadCfgCalled = 0
'    Else
'        frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text & vbCrLf & "Number of devices listed in configuration file: " & bNumDevicesLocal & vbCrLf
'        fRetValMisc = ScrollText("down")
'        For bCurDevListIndex = 0 To (bNumDevicesLocal - 1)
'            frmLL_USB.txtMsgDisplay.Text = frmLL_USB.txtMsgDisplay.Text _
'                & "Configuration for device index: " & bCurDevListIndex _
'                & ",  Device: " & DeviceObjectArray(bCurDevListIndex).DEV_sID & vbCrLf _
'                & "Channel:" & DeviceObjectArray(bCurDevListIndex).DEV_bChan _
'                & vbTab & "Rate:" & DeviceObjectArray(bCurDevListIndex).DEV_dblRate & "Hz" & vbCrLf & vbCrLf
'            fRetValMisc = ScrollText("down")
'        Next
'        bReadCfgCalled = 1
'    End If
'
'    fRetVal = True
'    Close #fCfg
'    Exit Sub
'
'
'DONE_WITH_ERR:
'    MsgBox vbCrLf & "ERROR opening, or incorrect data format in LL_USB.cfg" & vbCrLf & vbCrLf & vbCrLf & "Locate and place configuration file in" & vbCrLf & vbCrLf & "same directory as application and try again." & vbCrLf & vbCrLf & "error", 0
'    fRetValMisc = ScrollText("down")
'    On Error GoTo 0
'    fRetVal = False
'    Close #fCfg
'
'End Sub


