New version of Windows EBB updater v3.0.2, with the new COM port finding functionality after the update.

pull/231/head
EmbeddedMan 2024-05-09 21:03:28 -05:00
rodzic 65f648591f
commit 16bbf9710e
2 zmienionych plików z 263 dodań i 111 usunięć

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -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"