diff --git a/EBB_firmware/EBBUpdater/EBBUpgraderGUI_v302.exe b/EBB_firmware/EBBUpdater/EBBUpgraderGUI_v302.exe index a74b36a..f52120f 100644 Binary files a/EBB_firmware/EBBUpdater/EBBUpgraderGUI_v302.exe and b/EBB_firmware/EBBUpdater/EBBUpgraderGUI_v302.exe differ diff --git a/EBB_firmware/EBBUpdater/EBBUpgraderGUI_v302.tbasic b/EBB_firmware/EBBUpdater/EBBUpgraderGUI_v302.tbasic index cd7f0b8..be7f749 100644 --- a/EBB_firmware/EBBUpdater/EBBUpgraderGUI_v302.tbasic +++ b/EBB_firmware/EBBUpdater/EBBUpgraderGUI_v302.tbasic @@ -12,6 +12,10 @@ Begin ControlID %IDC_TIMER End ControlID +' Results for the FindAndOpenFirstEBBPort() function +%FIND_NO_EBBS = 0 +%FIND_EBB_OPEN = 1 + %TIMER_DELAY = 100 '---Timer delay (in milliseconds, not very accurate below about 100) Global hComm As Long @@ -31,6 +35,8 @@ Global sFirmwareNumber As String Global bConsole As Boolean Global bUpdaterConsole As Boolean Global sCommandLine As String +global sNicknameTag as String +global iStartUpdateButtonPresent as Long ' Replace the filename in the next two lines to change which HEX file gets programmed #BUNDLE File "HEX", ".\EBF_v302.hex", "", ReplaceExisting=1 @@ -60,11 +66,14 @@ Function TBMain() As Long '---Set window minimum size Dialog Set Minsize hDlg, 400, 400 + Dialog Set Timer hDlg, %IDC_TIMER, 1000 + '---Show dialog in modal mode '---cbDialog function is the callback function handling dialog events '---Application control will pass to dialog callback till dialog will exists Dialog Show Modal hDlg, Call cbDialog + '---If execution comes here it means main dialog as been destroyed If (bConsole) Then Console_WriteLine "---Application finished ---" @@ -85,10 +94,12 @@ CallBack Function cbDialog() As Long Case %WM_INITDIALOG If (bConsole) Then Console_WriteLine Time$, "Fired %WM_INITDIALOG dialog message" '---Add controls - Control Add Button, CBHNDL, %ID_StartUpdateButton, "Start Update", 160, 10, 80, 25, %BS_NOTIFY | %WS_TABSTOP Call cbButton + ' Control Add Button, CBHNDL, %ID_StartUpdateButton, "Start Update", 160, 10, 80, 25, %BS_NOTIFY | %WS_TABSTOP Call cbButton Control Add Button, CBHNDL, %ID_ExitButton, "Exit" , 160, 350, 80, 25, %BS_NOTIFY | %WS_TABSTOP Call cbButton + control set resize, CBHNDL, %ID_ExitButton, 1,0,0,1 - Control Add Textbox, CBHNDL, %ID_CommandOutputTexBox, "" , 10, 40, 380, 300, %ES_MULTILINE | %ES_AUTOVSCROLL | %WS_HSCROLL | %ES_AUTOHSCROLL | %WS_VSCROLL |%ES_READONLY + Control Add Textbox, CBHNDL, %ID_CommandOutputTexBox, "" , 10, 40, 380, 300, %ES_MULTILINE | %ES_AUTOVSCROLL | %WS_HSCROLL | %ES_AUTOHSCROLL | %WS_VSCROLL | %ES_READONLY + control set resize, CBHNDL, %ID_CommandOutputTexBox, 1,1,1,1 Case %WM_COMMAND 'If (bConsole) Then Console_Writeline Time$, "Fired %WM_COMMAND dialog message", CBCTL @@ -104,7 +115,7 @@ CallBack Function cbDialog() As Long Case %WM_DESTROY '---Do whatever needed just before dialog is destroyed. - If gPortOpen = TRUE Then + If gPortOpen = TRUE Then gPortOpen = FALSE COMM_Close(hComm) End If @@ -114,11 +125,8 @@ CallBack Function cbDialog() As Long Select Case CBWPARAM Case %IDC_TIMER -'' If gPortOpen = TRUE Then -'' nBytes = COMM_Get(hComm, %COMM_RXQUE) -'' COMM_Recv(hComm, nBytes, sBuffer) -'' add_new_bytes(sBuffer, CBHNDL) -'' EndIf + dialog kill timer Cbhndl, %IDC_TIMER + DoTheWholeThing(CBHNDL) End Select End Select @@ -138,13 +146,255 @@ function DoFirmwareUpdate() as Long DoFirmwareUpdate = pID end function +' We can get all kinds of funky version numbers because Brian isn't consistent with +' development version numbers. For example +' 0.0.0 +' 1.2.3 +' 10.11.12 +' 2.8.0a +' 1.5.5.0 +' 9.9.9_dev1 +' Are all (I guess) possible valid version numbers. +' This function expects a string of the form 'EBBv13_and_above EB Firmware Version 3.0.1.1' +' and it's job is to chop off everything except the actual version number at the right and +' return just that version number. So it looks for the first occurance of a decimal point, +' then walks back to the left of that until it finds a space, and then uses that as the +' starting point of the returned string. +function ParseFirmwareVersion(sVer as String) as String + local sTemp as string + local i as integer + local VerLen as integer + + VerLen = len(sVer) + sTemp = "" + + for i = 1 to VerLen + if mid$(sVer, i, 1) = "." then + exit for + endif + next i + + ' Here, i will be the place of the first decimal point, or the end of the string + while Mid$(sVer, i, 1) <> " " and i > 1 + i = i - 1 + wend + + ' Here, i will be at the place of the first space character preceeding the first decimal, or the beginning of the string + sTemp = right$(sVer, VerLen - i) + + ParseFirmwareVersion = sTemp +end function + +' A function to search for EBBs, and open up the com port to the first one +' It asks the OS for a list of all COM ports, then filters by PID/VID so that +' we only see EBBs. It then opens each one if it can, and sees if the thing on +' that COM Port responds to the V command with a valid version number. If so, +' then it leaves the port open () and returns %FIND_EBB_OPEN. +' If there are no COM ports, or there are COM ports but none are EBBs, then +' it does not open a com port and returns %FIND_NO_EBBS. + +function FindAndOpenFirstEBBPort(theHandle as dword) as Double + local dResult as double + + ' Set up default return value + dResult = %FIND_NO_EBBS + + Control Append Text theHandle, %ID_CommandOutputTexBox, "Building a list of EBB COM ports ..." + Chr$(13) + Chr$(10) + sBuffer = WMI_GetData(ComputerName, "", "", "", "Win32_PnPEntity", "", "Name") + + nItems = Parse(sBuffer, vData(), $CRLF) + + ReDim Ports() + + For Counter = 1 To nItems + Position = InStr(Ucase$(vData(Counter)),"(COM") + If Position Then + console_printLine(vData(Counter)) + Console_printLine(Ucase$(vData(Counter-1))) + ' If we have a "COMxx" port, then look for the PID/VID of EBB + If InStr(Ucase$(vData(Counter-1)), "VID_04D8&PID_FD92") Then + ReDim Preserve Ports(UBound(Ports)+1) + Ports(UBound(Ports)) = Extract$(Position+1,vData(Counter),")") + Console_PrintLine(Ports(UBound(Ports))) + End If + End If + Next + + ' We only need to proceed if we actually found at least one COM port + If LBound(Ports) <> UBound(Ports) Then + ' So we do have at least one COM Port to look at + Control Append Text theHandle, %ID_CommandOutputTexBox, "Found the following EBB COM ports:" + Chr$(13) + Chr$(10) + For Counter = (LBound(Ports) + 1) To UBound(Ports) + Control Append Text theHandle, %ID_CommandOutputTexBox, Ports(Counter) + Chr$(13) + Chr$(10) + Next + For Counter = (LBound(Ports) + 1) To UBound(Ports) + hComm = COMM_FreeFile + Control Append Text theHandle, %ID_CommandOutputTexBox, "Testing port " & Ports(Counter) & " ... " + COMM_Open("\\.\" & Ports(Counter), hComm) + If Err = 0 Then + ' New as of 4/28/2024: Force 'future syntax mode' off so we're always speaking to EBB in legacy mode + ' If this EBB doesn't support this command, and error will be generated, which we will simply ignore. + COMM_Set(hComm, %COMM_BAUD, 123) + COMM_Print(hComm, "CU,10,0" & Chr$(13)) + Sleep 100 + nBytes = COMM_Get(hComm, %COMM_RXQUE) + COMM_TRecv(hComm, nBytes, sBuffer, 1000) ' Eat any response, ignoring it + + COMM_Print(hComm, "V" & Chr$(13)) + Sleep 100 + nBytes = COMM_Get(hComm, %COMM_RXQUE) + COMM_TRecv(hComm, nBytes, sBuffer, 1000) ' This is the version response we actually use + + ' Remove any CR or LFs from the returned version string + sBuffer = Trim$(sBuffer, Any Chr$(13) & Chr$(10)) + + if len(sBuffer) >= 3 then + ' How do we know if we have an EBB? Look for "EBB" as the first three characters of the version response + If LEFT$(sBuffer, 3) = "EBB" Then + dResult = %FIND_EBB_OPEN + ' Since we've found an EBB, and it's COM port is now open, it's time to return + exit for + end if + end if + end if + next + end if + + FindAndOpenFirstEBBPort = dResult +end function + +' This function encapsulates the entire process - +' Find an EBB, update it, check that it updated properly +function DoTheWholeThing(theHandle as DWord) + Local sComPort As String + Local sTemp As String + Local dFloat As Double + local sNickTemp as string + local dwFindEBBResult as DWORD + + ' Can return FIND_NO_EBBS, FIND_EBB_OPEN + dwFindEBBResult = FindAndOpenFirstEBBPort(theHandle) + + if dwFindEBBResult = %FIND_NO_EBBS then + ' There was no EBB found during COM port search. Maybe it's already in bootloader mode?" + Control Append Text theHandle, %ID_CommandOutputTexBox, "No EBB COM ports found on this computer." + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Attempting recovery update directly into bootloader mode..." + Chr$(13) + Chr$(10) + + if (DoFirmwareUpdate() <> 0) then + Control Append Text theHandle, %ID_CommandOutputTexBox, "Update failed." + Chr$(13) + Chr$(10) + else + Control Append Text theHandle, %ID_CommandOutputTexBox, "Update succeded." + Chr$(13) + Chr$(10) + endif + + elseif dwFindEBBResult = %FIND_EBB_OPEN then + ' An EBB was found! Try to update it + sBuffer = ParseFirmwareVersion(sBuffer) + + Control Append Text theHandle, %ID_CommandOutputTexBox, "Found an EBB version " & sBuffer + Chr$(13) + Chr$(10) + + ' New (4/20/24) : Read out EBB nickname tag, and write it back after update is complete + ' Use "QT" and "ST" commands. Note that they only appeared in v2.5.5. So if we are updating from a version + ' before that, then there will be an "!8 Err: Unknown command" error, which is fine. + Control Append Text theHandle, %ID_CommandOutputTexBox, "Checking for EBB nickname " + Chr$(13) + Chr$(10) + Comm_print(hComm, "QT" & Chr$(13)) + Sleep 100 + nBytes = COMM_Get(hComm, %COMM_RXQUE) + COMM_TRecv(hComm, nBytes, sBuffer, 1000) + sBuffer = Trim$(sbuffer, Any Chr$(13) & Chr$(10)) + ' Only if the last two characters (other than line endings) are "OK" did we get a valid response from "QT" + if right$(sBuffer,2) = "OK" and len(sBuffer) > 2 then + sNicknameTag = Left$(sBuffer, len(sBuffer) - 2) + sNicknameTag = Trim$(sNicknameTag, any Chr$(13) & chr$(10)) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Found EBB nickname " & sNicknameTag + Chr$(13) + Chr$(10) + else + Control Append Text theHandle, %ID_CommandOutputTexBox, "No nickname available" + Chr$(13) + Chr$(10) + endif + + Control Append Text theHandle, %ID_CommandOutputTexBox, "Attempting update to version " & sFirmwareNumber + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Please wait during update ... " + Chr$(13) + Chr$(10) + + COMM_Print(hComm, "BL" & Chr$(13)) + Sleep 1000 + COMM_Close(hComm) + Sleep 5000 + + DoFirmwareUpdate() + + Sleep 2000 + + Control Append Text theHandle, %ID_CommandOutputTexBox, "Update finished." + Chr$(13) + Chr$(10) + + ' Check the return code from the command line firmware update process + If pID = 0 Then + ' Now, the EBB may be on a different COM port after it's update. So we have to go through and find the list of + ' COM ports and test them for EBBs all over again. + + dwFindEBBResult = FindAndOpenFirstEBBPort(theHandle) + + if dwFindEBBResult = %FIND_NO_EBBS then + ' There was no EBB found during the second COM port search. + Control Append Text theHandle, %ID_CommandOutputTexBox, "No EBB COM ports found after update. Update may have succeeded." + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Remove and reattach EBB, then click Start Update to retry." + Chr$(13) + Chr$(10) + + elseif dwFindEBBResult = %FIND_EBB_OPEN then + ' An EBB was found! + sBuffer = ParseFirmwareVersion(sBuffer) + ' Check to see if the new firmware version matches what we thought we wrote during the update + If sBuffer <> sFirmwareNumber Then + Control Append Text theHandle, %ID_CommandOutputTexBox, "Unexpected version detected after update." + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Version written to EBB=" & sFirmwareNumber + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Version read from EBB=" & sBuffer + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Update failed" + Chr$(13) + Chr$(10) + Else + Control Append Text theHandle, %ID_CommandOutputTexBox, "Updated to version " & sBuffer & " successfully." + Chr$(13) + Chr$(10) + + ' Write the nickname tag back, if it existed + if len(sNicknameTag) > 0 then + Comm_print(hComm, "ST," & sNicknameTag & Chr$(13)) + Sleep 250 + nBytes = COMM_Get(hComm, %COMM_RXQUE) + COMM_TRecv(hComm, nBytes, sBuffer, 1000) + sBuffer = Trim$(sbuffer, Any Chr$(13) & Chr$(10)) + ' Now read back the nickname to make sure it was set correctly + sNickTemp = "" + Comm_print(hComm, "QT" & Chr$(13)) + Sleep 100 + nBytes = COMM_Get(hComm, %COMM_RXQUE) + COMM_TRecv(hComm, nBytes, sNickTemp, 1000) + sNickTemp = Trim$(sNickTemp, Any Chr$(13) & Chr$(10)) + + if right$(sNickTemp,2) = "OK" and len(sNickTemp) > 2 then + sNickTemp = Left$(sNickTemp, len(sNickTemp) - 2) + sNickTemp = Trim$(sNickTemp, any Chr$(13) & chr$(10)) + if sNickTemp = sNicknameTag then + Control Append Text theHandle, %ID_CommandOutputTexBox, "Wrote nickname successfully " & sNickTemp + Chr$(13) + Chr$(10) + else + Control Append Text theHandle, %ID_CommandOutputTexBox, "Nickname written but did not verify correctly:" & sNicknameTag & ":" & kNickTemp + Chr$(13) + Chr$(10) + endif + endif + endif + EndIf + COMM_Close(hComm) + endif + else + ' pID returned from DoFirmwareUpdate() indicates failure there in some way + Control Append Text theHandle, %ID_CommandOutputTexBox, "EBB HID update failed with error: " & Err + Chr$(13) + Chr$(10) + End If + end if + Control Append Text theHandle, %ID_CommandOutputTexBox, "Click Exit (or click Start Upgrade again to update more EBBs)" + Chr$(13) + Chr$(10) + + ' IF the Start Update button doesn't yet exist, add it + if iStartUpdateButtonPresent = false then + Control Add Button, theHandle, %ID_StartUpdateButton, "Start Update", 160, 10, 80, 25, %BS_NOTIFY | %WS_TABSTOP Call cbButton + iStartUpdateButtonPresent = true + end if + +end function + '------------------------------------------------------------------------------ ' Callback procedure for button control '------------------------------------------------------------------------------ CallBack Function cbButton() As Long - Local sComPort As String - Local sTemp As String - Local dFloat As Double If CBMSG = %WM_COMMAND Then @@ -153,106 +403,8 @@ CallBack Function cbButton() As Long Select Case CBCTL Case %ID_StartUpdateButton - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Building a list of EBB COM ports ..." + Chr$(13) + Chr$(10) - sBuffer = WMI_GetData(ComputerName, "", "", "", "Win32_PnPEntity", "", "Name" ) - - nItems = Parse( sBuffer, vData(), $CRLF) - - ReDim Ports() - - For Counter = 1 To nItems - Position = InStr(Ucase$(vData(Counter)),"(COM") - If Position Then - console_printLine(vData(Counter)) - Console_printLine(Ucase$(vData(Counter-1))) - ' If we have a "COMxx" port, then look for the PID/VID of EBB - If InStr(Ucase$(vData(Counter-1)), "VID_04D8&PID_FD92") Then - ReDim Preserve Ports(UBound(Ports)+1) - Ports(UBound(Ports)) = Extract$(Position+1,vData(Counter),")") - Console_PrintLine(Ports(UBound(Ports))) - End If - End If - Next - - ' Check for no COM ports found - If LBound(Ports) = 1 And UBound(Ports) = 1 Then - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "No EBB COM ports found on this computer." + Chr$(13) + Chr$(10) - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Attempting recovery update directly into bootloader mode..." + Chr$(13) + Chr$(10) - - if (DoFirmwareUpdate() <> 0) then - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Update failed. Click Exit." + Chr$(13) + Chr$(10) - else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Update succeded. Click Exit to quit," + Chr$(13) + Chr$(10) - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "or click Start Update to restart normal firmware update process." + Chr$(13) + Chr$(10) - endif - - Else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Found the following EBB COM ports:" + Chr$(13) + Chr$(10) - For Counter = LBound(Ports) To UBound(Ports) - Control Append Text CBHNDL, %ID_CommandOutputTexBox, Ports(Counter) + Chr$(13) + Chr$(10) - Next - For Counter = LBound(Ports) To UBound(Ports) - hComm = COMM_FreeFile - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Testing port " & Ports(Counter) & " ... " - COMM_Open("\\.\" & Ports(Counter), hComm) - If Err = 0 Then - COMM_Set(hComm, %COMM_BAUD, 123) - COMM_Print(hComm, "V" & Chr$(13)) - Sleep 100 - nBytes = COMM_Get(hComm, %COMM_RXQUE) - COMM_TRecv(hComm, nBytes, sBuffer, 1000) - - COMM_Print(hComm, "V" & Chr$(13)) - Sleep 100 - nBytes = COMM_Get(hComm, %COMM_RXQUE) - COMM_TRecv(hComm, nBytes, sBuffer, 1000) - - sBuffer = Trim$(sbuffer, Any Chr$(13) & Chr$(10)) - If LEFT$(sBuffer, 3) = "EBB" Then - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Found an EBB with firmware version " & RIGHT$(sBuffer, 5) + Chr$(13) + Chr$(10) - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Attempting update to version " & sFirmwareNumber + Chr$(13) + Chr$(10) - COMM_Print(hComm, "BL" & Chr$(13)) - Sleep 1000 - COMM_Close(hComm) - Sleep 5000 - - DoFirmwareUpdate() - - Sleep 2000 - - If pID = 0 Then - COMM_Open("\\.\" & Ports(Counter), hComm) - If Err = 0 Then - COMM_Print(hComm, "V" & Chr$(13)) - Sleep 500 - nBytes = COMM_Get(hComm, %COMM_RXQUE) - COMM_TRecv(hComm, nBytes, sBuffer, 1000) - COMM_Print(hComm, "V" & Chr$(13)) - Sleep 500 - nBytes = COMM_Get(hComm, %COMM_RXQUE) - COMM_TRecv(hComm, nBytes, sBuffer, 1000) - sBuffer = Trim$(sBuffer, Any Chr$(13) & Chr$(10)) - If (RIGHT$(sBuffer,5) = sFirmwareNumber) Then - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Updated to version " & RIGHT$(sBuffer,5) & " successfully" + Chr$(13) + Chr$(10) - Else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Incorrect version detected. EBB=" & RIGHT$(sBuffer,5) & " File=" & sFirmwareNumber & " Updated failed." + Chr$(13) + Chr$(10) - EndIf - COMM_Close(hComm) - EndIf - Else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Programming EBB failed with an error." + Chr$(13) + Chr$(10) - EndIf - Else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, " no EBB found" + Chr$(13) + Chr$(10) - 'If (bConsole) Then Console_WriteLine("...closing port " & "\\.\" & Ports(Counter)) - COMM_Close(hComm) - EndIf - Else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Error: " & Err + Chr$(13) + Chr$(10) - End If - Next - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Click Exit (or click Start Upgrade again to update more EBBs)" + Chr$(13) + Chr$(10) - End If + Control Append Text CBHNDL, %ID_CommandOutputTexBox, "-------------------------------------------" + Chr$(13) + Chr$(10) + call DoTheWholeThing(CBHNDL) Case %ID_ExitButton If (bConsole) Then Console_WriteLine Time$, "CloseCommButton" diff --git a/EBB_firmware/EBBUpdater/deprecated/EBBUpgraderGUI_v301.exe b/EBB_firmware/EBBUpdater/deprecated/EBBUpgraderGUI_v301.exe index d8fdb0e..fc31386 100644 Binary files a/EBB_firmware/EBBUpdater/deprecated/EBBUpgraderGUI_v301.exe and b/EBB_firmware/EBBUpdater/deprecated/EBBUpgraderGUI_v301.exe differ diff --git a/EBB_firmware/EBBUpdater/deprecated/EBBUpgraderGUI_v301.tbasic b/EBB_firmware/EBBUpdater/deprecated/EBBUpgraderGUI_v301.tbasic index 26f8b26..5d6455a 100644 --- a/EBB_firmware/EBBUpdater/deprecated/EBBUpgraderGUI_v301.tbasic +++ b/EBB_firmware/EBBUpdater/deprecated/EBBUpgraderGUI_v301.tbasic @@ -12,6 +12,10 @@ Begin ControlID %IDC_TIMER End ControlID +' Results for the FindAndOpenFirstEBBPort() function +%FIND_NO_EBBS = 0 +%FIND_EBB_OPEN = 1 + %TIMER_DELAY = 100 '---Timer delay (in milliseconds, not very accurate below about 100) Global hComm As Long @@ -31,6 +35,8 @@ Global sFirmwareNumber As String Global bConsole As Boolean Global bUpdaterConsole As Boolean Global sCommandLine As String +global sNicknameTag as String +global iStartUpdateButtonPresent as Long ' Replace the filename in the next two lines to change which HEX file gets programmed #BUNDLE File "HEX", ".\EBF_v301.hex", "", ReplaceExisting=1 @@ -60,11 +66,14 @@ Function TBMain() As Long '---Set window minimum size Dialog Set Minsize hDlg, 400, 400 + Dialog Set Timer hDlg, %IDC_TIMER, 1000 + '---Show dialog in modal mode '---cbDialog function is the callback function handling dialog events '---Application control will pass to dialog callback till dialog will exists Dialog Show Modal hDlg, Call cbDialog + '---If execution comes here it means main dialog as been destroyed If (bConsole) Then Console_WriteLine "---Application finished ---" @@ -85,10 +94,12 @@ CallBack Function cbDialog() As Long Case %WM_INITDIALOG If (bConsole) Then Console_WriteLine Time$, "Fired %WM_INITDIALOG dialog message" '---Add controls - Control Add Button, CBHNDL, %ID_StartUpdateButton, "Start Update", 160, 10, 80, 25, %BS_NOTIFY | %WS_TABSTOP Call cbButton + ' Control Add Button, CBHNDL, %ID_StartUpdateButton, "Start Update", 160, 10, 80, 25, %BS_NOTIFY | %WS_TABSTOP Call cbButton Control Add Button, CBHNDL, %ID_ExitButton, "Exit" , 160, 350, 80, 25, %BS_NOTIFY | %WS_TABSTOP Call cbButton + control set resize, CBHNDL, %ID_ExitButton, 1,0,0,1 - Control Add Textbox, CBHNDL, %ID_CommandOutputTexBox, "" , 10, 40, 380, 300, %ES_MULTILINE | %ES_AUTOVSCROLL | %WS_HSCROLL | %ES_AUTOHSCROLL | %WS_VSCROLL |%ES_READONLY + Control Add Textbox, CBHNDL, %ID_CommandOutputTexBox, "" , 10, 40, 380, 300, %ES_MULTILINE | %ES_AUTOVSCROLL | %WS_HSCROLL | %ES_AUTOHSCROLL | %WS_VSCROLL | %ES_READONLY + control set resize, CBHNDL, %ID_CommandOutputTexBox, 1,1,1,1 Case %WM_COMMAND 'If (bConsole) Then Console_Writeline Time$, "Fired %WM_COMMAND dialog message", CBCTL @@ -104,7 +115,7 @@ CallBack Function cbDialog() As Long Case %WM_DESTROY '---Do whatever needed just before dialog is destroyed. - If gPortOpen = TRUE Then + If gPortOpen = TRUE Then gPortOpen = FALSE COMM_Close(hComm) End If @@ -114,11 +125,8 @@ CallBack Function cbDialog() As Long Select Case CBWPARAM Case %IDC_TIMER -'' If gPortOpen = TRUE Then -'' nBytes = COMM_Get(hComm, %COMM_RXQUE) -'' COMM_Recv(hComm, nBytes, sBuffer) -'' add_new_bytes(sBuffer, CBHNDL) -'' EndIf + dialog kill timer Cbhndl, %IDC_TIMER + DoTheWholeThing(CBHNDL) End Select End Select @@ -138,13 +146,255 @@ function DoFirmwareUpdate() as Long DoFirmwareUpdate = pID end function +' We can get all kinds of funky version numbers because Brian isn't consistent with +' development version numbers. For example +' 0.0.0 +' 1.2.3 +' 10.11.12 +' 2.8.0a +' 1.5.5.0 +' 9.9.9_dev1 +' Are all (I guess) possible valid version numbers. +' This function expects a string of the form 'EBBv13_and_above EB Firmware Version 3.0.1.1' +' and it's job is to chop off everything except the actual version number at the right and +' return just that version number. So it looks for the first occurance of a decimal point, +' then walks back to the left of that until it finds a space, and then uses that as the +' starting point of the returned string. +function ParseFirmwareVersion(sVer as String) as String + local sTemp as string + local i as integer + local VerLen as integer + + VerLen = len(sVer) + sTemp = "" + + for i = 1 to VerLen + if mid$(sVer, i, 1) = "." then + exit for + endif + next i + + ' Here, i will be the place of the first decimal point, or the end of the string + while Mid$(sVer, i, 1) <> " " and i > 1 + i = i - 1 + wend + + ' Here, i will be at the place of the first space character preceeding the first decimal, or the beginning of the string + sTemp = right$(sVer, VerLen - i) + + ParseFirmwareVersion = sTemp +end function + +' A function to search for EBBs, and open up the com port to the first one +' It asks the OS for a list of all COM ports, then filters by PID/VID so that +' we only see EBBs. It then opens each one if it can, and sees if the thing on +' that COM Port responds to the V command with a valid version number. If so, +' then it leaves the port open () and returns %FIND_EBB_OPEN. +' If there are no COM ports, or there are COM ports but none are EBBs, then +' it does not open a com port and returns %FIND_NO_EBBS. + +function FindAndOpenFirstEBBPort(theHandle as dword) as Double + local dResult as double + + ' Set up default return value + dResult = %FIND_NO_EBBS + + Control Append Text theHandle, %ID_CommandOutputTexBox, "Building a list of EBB COM ports ..." + Chr$(13) + Chr$(10) + sBuffer = WMI_GetData(ComputerName, "", "", "", "Win32_PnPEntity", "", "Name") + + nItems = Parse(sBuffer, vData(), $CRLF) + + ReDim Ports() + + For Counter = 1 To nItems + Position = InStr(Ucase$(vData(Counter)),"(COM") + If Position Then + console_printLine(vData(Counter)) + Console_printLine(Ucase$(vData(Counter-1))) + ' If we have a "COMxx" port, then look for the PID/VID of EBB + If InStr(Ucase$(vData(Counter-1)), "VID_04D8&PID_FD92") Then + ReDim Preserve Ports(UBound(Ports)+1) + Ports(UBound(Ports)) = Extract$(Position+1,vData(Counter),")") + Console_PrintLine(Ports(UBound(Ports))) + End If + End If + Next + + ' We only need to proceed if we actually found at least one COM port + If LBound(Ports) <> UBound(Ports) Then + ' So we do have at least one COM Port to look at + Control Append Text theHandle, %ID_CommandOutputTexBox, "Found the following EBB COM ports:" + Chr$(13) + Chr$(10) + For Counter = (LBound(Ports) + 1) To UBound(Ports) + Control Append Text theHandle, %ID_CommandOutputTexBox, Ports(Counter) + Chr$(13) + Chr$(10) + Next + For Counter = (LBound(Ports) + 1) To UBound(Ports) + hComm = COMM_FreeFile + Control Append Text theHandle, %ID_CommandOutputTexBox, "Testing port " & Ports(Counter) & " ... " + COMM_Open("\\.\" & Ports(Counter), hComm) + If Err = 0 Then + ' New as of 4/28/2024: Force 'future syntax mode' off so we're always speaking to EBB in legacy mode + ' If this EBB doesn't support this command, and error will be generated, which we will simply ignore. + COMM_Set(hComm, %COMM_BAUD, 123) + COMM_Print(hComm, "CU,10,0" & Chr$(13)) + Sleep 100 + nBytes = COMM_Get(hComm, %COMM_RXQUE) + COMM_TRecv(hComm, nBytes, sBuffer, 1000) ' Eat any response, ignoring it + + COMM_Print(hComm, "V" & Chr$(13)) + Sleep 100 + nBytes = COMM_Get(hComm, %COMM_RXQUE) + COMM_TRecv(hComm, nBytes, sBuffer, 1000) ' This is the version response we actually use + + ' Remove any CR or LFs from the returned version string + sBuffer = Trim$(sBuffer, Any Chr$(13) & Chr$(10)) + + if len(sBuffer) >= 3 then + ' How do we know if we have an EBB? Look for "EBB" as the first three characters of the version response + If LEFT$(sBuffer, 3) = "EBB" Then + dResult = %FIND_EBB_OPEN + ' Since we've found an EBB, and it's COM port is now open, it's time to return + exit for + end if + end if + end if + next + end if + + FindAndOpenFirstEBBPort = dResult +end function + +' This function encapsulates the entire process - +' Find an EBB, update it, check that it updated properly +function DoTheWholeThing(theHandle as DWord) + Local sComPort As String + Local sTemp As String + Local dFloat As Double + local sNickTemp as string + local dwFindEBBResult as DWORD + + ' Can return FIND_NO_EBBS, FIND_EBB_OPEN + dwFindEBBResult = FindAndOpenFirstEBBPort(theHandle) + + if dwFindEBBResult = %FIND_NO_EBBS then + ' There was no EBB found during COM port search. Maybe it's already in bootloader mode?" + Control Append Text theHandle, %ID_CommandOutputTexBox, "No EBB COM ports found on this computer." + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Attempting recovery update directly into bootloader mode..." + Chr$(13) + Chr$(10) + + if (DoFirmwareUpdate() <> 0) then + Control Append Text theHandle, %ID_CommandOutputTexBox, "Update failed." + Chr$(13) + Chr$(10) + else + Control Append Text theHandle, %ID_CommandOutputTexBox, "Update succeded." + Chr$(13) + Chr$(10) + endif + + elseif dwFindEBBResult = %FIND_EBB_OPEN then + ' An EBB was found! Try to update it + sBuffer = ParseFirmwareVersion(sBuffer) + + Control Append Text theHandle, %ID_CommandOutputTexBox, "Found an EBB version " & sBuffer + Chr$(13) + Chr$(10) + + ' New (4/20/24) : Read out EBB nickname tag, and write it back after update is complete + ' Use "QT" and "ST" commands. Note that they only appeared in v2.5.5. So if we are updating from a version + ' before that, then there will be an "!8 Err: Unknown command" error, which is fine. + Control Append Text theHandle, %ID_CommandOutputTexBox, "Checking for EBB nickname " + Chr$(13) + Chr$(10) + Comm_print(hComm, "QT" & Chr$(13)) + Sleep 100 + nBytes = COMM_Get(hComm, %COMM_RXQUE) + COMM_TRecv(hComm, nBytes, sBuffer, 1000) + sBuffer = Trim$(sbuffer, Any Chr$(13) & Chr$(10)) + ' Only if the last two characters (other than line endings) are "OK" did we get a valid response from "QT" + if right$(sBuffer,2) = "OK" and len(sBuffer) > 2 then + sNicknameTag = Left$(sBuffer, len(sBuffer) - 2) + sNicknameTag = Trim$(sNicknameTag, any Chr$(13) & chr$(10)) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Found EBB nickname " & sNicknameTag + Chr$(13) + Chr$(10) + else + Control Append Text theHandle, %ID_CommandOutputTexBox, "No nickname available" + Chr$(13) + Chr$(10) + endif + + Control Append Text theHandle, %ID_CommandOutputTexBox, "Attempting update to version " & sFirmwareNumber + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Please wait during update ... " + Chr$(13) + Chr$(10) + + COMM_Print(hComm, "BL" & Chr$(13)) + Sleep 1000 + COMM_Close(hComm) + Sleep 5000 + + DoFirmwareUpdate() + + Sleep 2000 + + Control Append Text theHandle, %ID_CommandOutputTexBox, "Update finished." + Chr$(13) + Chr$(10) + + ' Check the return code from the command line firmware update process + If pID = 0 Then + ' Now, the EBB may be on a different COM port after it's update. So we have to go through and find the list of + ' COM ports and test them for EBBs all over again. + + dwFindEBBResult = FindAndOpenFirstEBBPort(theHandle) + + if dwFindEBBResult = %FIND_NO_EBBS then + ' There was no EBB found during the second COM port search. + Control Append Text theHandle, %ID_CommandOutputTexBox, "No EBB COM ports found after update. Update may have succeeded." + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Remove and reattach EBB, then click Start Update to retry." + Chr$(13) + Chr$(10) + + elseif dwFindEBBResult = %FIND_EBB_OPEN then + ' An EBB was found! + sBuffer = ParseFirmwareVersion(sBuffer) + ' Check to see if the new firmware version matches what we thought we wrote during the update + If sBuffer <> sFirmwareNumber Then + Control Append Text theHandle, %ID_CommandOutputTexBox, "Unexpected version detected after update." + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Version written to EBB=" & sFirmwareNumber + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Version read from EBB=" & sBuffer + Chr$(13) + Chr$(10) + Control Append Text theHandle, %ID_CommandOutputTexBox, "Update failed" + Chr$(13) + Chr$(10) + Else + Control Append Text theHandle, %ID_CommandOutputTexBox, "Updated to version " & sBuffer & " successfully." + Chr$(13) + Chr$(10) + + ' Write the nickname tag back, if it existed + if len(sNicknameTag) > 0 then + Comm_print(hComm, "ST," & sNicknameTag & Chr$(13)) + Sleep 250 + nBytes = COMM_Get(hComm, %COMM_RXQUE) + COMM_TRecv(hComm, nBytes, sBuffer, 1000) + sBuffer = Trim$(sbuffer, Any Chr$(13) & Chr$(10)) + ' Now read back the nickname to make sure it was set correctly + sNickTemp = "" + Comm_print(hComm, "QT" & Chr$(13)) + Sleep 100 + nBytes = COMM_Get(hComm, %COMM_RXQUE) + COMM_TRecv(hComm, nBytes, sNickTemp, 1000) + sNickTemp = Trim$(sNickTemp, Any Chr$(13) & Chr$(10)) + + if right$(sNickTemp,2) = "OK" and len(sNickTemp) > 2 then + sNickTemp = Left$(sNickTemp, len(sNickTemp) - 2) + sNickTemp = Trim$(sNickTemp, any Chr$(13) & chr$(10)) + if sNickTemp = sNicknameTag then + Control Append Text theHandle, %ID_CommandOutputTexBox, "Wrote nickname successfully " & sNickTemp + Chr$(13) + Chr$(10) + else + Control Append Text theHandle, %ID_CommandOutputTexBox, "Nickname written but did not verify correctly:" & sNicknameTag & ":" & kNickTemp + Chr$(13) + Chr$(10) + endif + endif + endif + EndIf + COMM_Close(hComm) + endif + else + ' pID returned from DoFirmwareUpdate() indicates failure there in some way + Control Append Text theHandle, %ID_CommandOutputTexBox, "EBB HID update failed with error: " & Err + Chr$(13) + Chr$(10) + End If + end if + Control Append Text theHandle, %ID_CommandOutputTexBox, "Click Exit (or click Start Upgrade again to update more EBBs)" + Chr$(13) + Chr$(10) + + ' IF the Start Update button doesn't yet exist, add it + if iStartUpdateButtonPresent = false then + Control Add Button, theHandle, %ID_StartUpdateButton, "Start Update", 160, 10, 80, 25, %BS_NOTIFY | %WS_TABSTOP Call cbButton + iStartUpdateButtonPresent = true + end if + +end function + '------------------------------------------------------------------------------ ' Callback procedure for button control '------------------------------------------------------------------------------ CallBack Function cbButton() As Long - Local sComPort As String - Local sTemp As String - Local dFloat As Double If CBMSG = %WM_COMMAND Then @@ -153,106 +403,8 @@ CallBack Function cbButton() As Long Select Case CBCTL Case %ID_StartUpdateButton - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Building a list of EBB COM ports ..." + Chr$(13) + Chr$(10) - sBuffer = WMI_GetData(ComputerName, "", "", "", "Win32_PnPEntity", "", "Name" ) - - nItems = Parse( sBuffer, vData(), $CRLF) - - ReDim Ports() - - For Counter = 1 To nItems - Position = InStr(Ucase$(vData(Counter)),"(COM") - If Position Then - console_printLine(vData(Counter)) - Console_printLine(Ucase$(vData(Counter-1))) - ' If we have a "COMxx" port, then look for the PID/VID of EBB - If InStr(Ucase$(vData(Counter-1)), "VID_04D8&PID_FD92") Then - ReDim Preserve Ports(UBound(Ports)+1) - Ports(UBound(Ports)) = Extract$(Position+1,vData(Counter),")") - Console_PrintLine(Ports(UBound(Ports))) - End If - End If - Next - - ' Check for no COM ports found - If LBound(Ports) = 1 And UBound(Ports) = 1 Then - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "No EBB COM ports found on this computer." + Chr$(13) + Chr$(10) - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Attempting recovery update directly into bootloader mode..." + Chr$(13) + Chr$(10) - - if (DoFirmwareUpdate() <> 0) then - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Update failed. Click Exit." + Chr$(13) + Chr$(10) - else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Update succeded. Click Exit to quit," + Chr$(13) + Chr$(10) - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "or click Start Update to restart normal firmware update process." + Chr$(13) + Chr$(10) - endif - - Else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Found the following EBB COM ports:" + Chr$(13) + Chr$(10) - For Counter = LBound(Ports) To UBound(Ports) - Control Append Text CBHNDL, %ID_CommandOutputTexBox, Ports(Counter) + Chr$(13) + Chr$(10) - Next - For Counter = LBound(Ports) To UBound(Ports) - hComm = COMM_FreeFile - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Testing port " & Ports(Counter) & " ... " - COMM_Open("\\.\" & Ports(Counter), hComm) - If Err = 0 Then - COMM_Set(hComm, %COMM_BAUD, 123) - COMM_Print(hComm, "V" & Chr$(13)) - Sleep 100 - nBytes = COMM_Get(hComm, %COMM_RXQUE) - COMM_TRecv(hComm, nBytes, sBuffer, 1000) - - COMM_Print(hComm, "V" & Chr$(13)) - Sleep 100 - nBytes = COMM_Get(hComm, %COMM_RXQUE) - COMM_TRecv(hComm, nBytes, sBuffer, 1000) - - sBuffer = Trim$(sbuffer, Any Chr$(13) & Chr$(10)) - If LEFT$(sBuffer, 3) = "EBB" Then - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Found an EBB with firmware version " & RIGHT$(sBuffer, 5) + Chr$(13) + Chr$(10) - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Attempting update to version " & sFirmwareNumber + Chr$(13) + Chr$(10) - COMM_Print(hComm, "BL" & Chr$(13)) - Sleep 1000 - COMM_Close(hComm) - Sleep 5000 - - DoFirmwareUpdate() - - Sleep 2000 - - If pID = 0 Then - COMM_Open("\\.\" & Ports(Counter), hComm) - If Err = 0 Then - COMM_Print(hComm, "V" & Chr$(13)) - Sleep 500 - nBytes = COMM_Get(hComm, %COMM_RXQUE) - COMM_TRecv(hComm, nBytes, sBuffer, 1000) - COMM_Print(hComm, "V" & Chr$(13)) - Sleep 500 - nBytes = COMM_Get(hComm, %COMM_RXQUE) - COMM_TRecv(hComm, nBytes, sBuffer, 1000) - sBuffer = Trim$(sBuffer, Any Chr$(13) & Chr$(10)) - If (RIGHT$(sBuffer,5) = sFirmwareNumber) Then - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Updated to version " & RIGHT$(sBuffer,5) & " successfully" + Chr$(13) + Chr$(10) - Else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Incorrect version detected. EBB=" & RIGHT$(sBuffer,5) & " File=" & sFirmwareNumber & " Updated failed." + Chr$(13) + Chr$(10) - EndIf - COMM_Close(hComm) - EndIf - Else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Programming EBB failed with an error." + Chr$(13) + Chr$(10) - EndIf - Else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, " no EBB found" + Chr$(13) + Chr$(10) - 'If (bConsole) Then Console_WriteLine("...closing port " & "\\.\" & Ports(Counter)) - COMM_Close(hComm) - EndIf - Else - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Error: " & Err + Chr$(13) + Chr$(10) - End If - Next - Control Append Text CBHNDL, %ID_CommandOutputTexBox, "Click Exit (or click Start Upgrade again to update more EBBs)" + Chr$(13) + Chr$(10) - End If + Control Append Text CBHNDL, %ID_CommandOutputTexBox, "-------------------------------------------" + Chr$(13) + Chr$(10) + call DoTheWholeThing(CBHNDL) Case %ID_ExitButton If (bConsole) Then Console_WriteLine Time$, "CloseCommButton"