Skip to content

Commit f881791

Browse files
1 parent 877f7af commit f881791

454 files changed

Lines changed: 239174 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Binary file not shown.
Binary file not shown.
498 KB
Binary file not shown.
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
@ECHO OFF
2+
SETLOCAL EnableDelayedExpansion
3+
TITLE Meshtastic device-install
4+
5+
SET "SCRIPT_NAME=%~nx0"
6+
SET "DEBUG=0"
7+
SET "PYTHON="
8+
SET "ESPTOOL_BAUD=115200"
9+
SET "ESPTOOL_CMD="
10+
SET "LOGCOUNTER=0"
11+
SET "BPS_RESET=0"
12+
@REM Default offsets.
13+
@REM https://github.com/meshtastic/web-flasher/blob/main/stores/firmwareStore.ts#L202
14+
SET "OTA_OFFSET=0x260000"
15+
SET "SPIFFS_OFFSET=0x300000"
16+
17+
GOTO getopts
18+
:help
19+
ECHO Flash image file to device, but first erasing and writing system information.
20+
ECHO.
21+
ECHO Usage: %SCRIPT_NAME% -f filename [-p PORT] [-P python] [--1200bps-reset]
22+
ECHO.
23+
ECHO Options:
24+
ECHO -f filename The firmware .factory.bin file to flash. Custom to your device type and region. (required)
25+
ECHO The file must be located in this current directory.
26+
ECHO -p PORT Set the environment variable for ESPTOOL_PORT.
27+
ECHO If not set, ESPTOOL iterates all ports (Dangerous).
28+
ECHO -P python Specify alternate python interpreter to use to invoke esptool. (default: python)
29+
ECHO If supplied the script will use python.
30+
ECHO If not supplied the script will try to find esptool in Path.
31+
ECHO --1200bps-reset Attempt to place the device in correct mode. (1200bps Reset)
32+
ECHO Some hardware requires this twice.
33+
ECHO.
34+
ECHO Example: %SCRIPT_NAME% -p COM17 --1200bps-reset
35+
ECHO Example: %SCRIPT_NAME% -f firmware-t-deck-tft-2.6.0.0b106d4.factory.bin -p COM11
36+
ECHO Example: %SCRIPT_NAME% -f firmware-unphone-2.6.0.0b106d4.factory.bin -p COM11
37+
GOTO eof
38+
39+
:version
40+
ECHO %SCRIPT_NAME% [Version 2.7.0]
41+
ECHO Meshtastic
42+
GOTO eof
43+
44+
:getopts
45+
IF "%~1"=="" GOTO endopts
46+
IF /I "%~1"=="-?" GOTO help
47+
IF /I "%~1"=="-h" GOTO help
48+
IF /I "%~1"=="--help" GOTO help
49+
IF /I "%~1"=="-v" GOTO version
50+
IF /I "%~1"=="--version" GOTO version
51+
IF /I "%~1"=="--debug" SET "DEBUG=1" & CALL :LOG_MESSAGE DEBUG "DEBUG mode: enabled."
52+
IF /I "%~1"=="-f" SET "FILENAME=%~2" & SHIFT
53+
IF "%~1"=="-p" SET "ESPTOOL_PORT=%~2" & SHIFT
54+
IF /I "%~1"=="--port" SET "ESPTOOL_PORT=%~2" & SHIFT
55+
IF "%~1"=="-P" SET "PYTHON=%~2" & SHIFT
56+
IF /I "%~1"=="--1200bps-reset" SET "BPS_RESET=1"
57+
SHIFT
58+
GOTO getopts
59+
:endopts
60+
61+
IF %BPS_RESET% EQU 1 GOTO skip-filename
62+
63+
CALL :LOG_MESSAGE DEBUG "Checking FILENAME parameter..."
64+
IF "__!FILENAME!__"=="____" (
65+
CALL :LOG_MESSAGE DEBUG "Missing -f filename input."
66+
GOTO help
67+
) ELSE (
68+
CALL :LOG_MESSAGE DEBUG "Filename: !FILENAME!"
69+
IF NOT "__!FILENAME: =!__"=="__!FILENAME!__" (
70+
CALL :LOG_MESSAGE ERROR "Filename containing spaces are not supported."
71+
GOTO help
72+
)
73+
IF NOT "__!FILENAME:.factory.bin=!__"=="__!FILENAME!__" (
74+
CALL :LOG_MESSAGE ERROR "Filename must be a firmware-*.factory.bin file."
75+
GOTO help
76+
)
77+
@REM Remove ".\" or "./" file prefix if present.
78+
SET "FILENAME=!FILENAME:.\=!"
79+
SET "FILENAME=!FILENAME:./=!"
80+
)
81+
82+
CALL :LOG_MESSAGE DEBUG "Checking if !FILENAME! exists..."
83+
IF NOT EXIST !FILENAME! (
84+
CALL :LOG_MESSAGE ERROR "File does not exist: !FILENAME!. Terminating."
85+
GOTO eof
86+
)
87+
88+
CALL :LOG_MESSAGE DEBUG "Checking for metadata..."
89+
@REM Derive metadata filename from firmware filename.
90+
SET "METAFILE=!FILENAME:.factory.bin=!.mt.json"
91+
IF EXIST !METAFILE! (
92+
@REM Print parsed json with powershell
93+
CALL :LOG_MESSAGE INFO "Firmware metadata: !METAFILE!"
94+
powershell -NoProfile -Command "(Get-Content '!METAFILE!' | ConvertFrom-Json | Out-String).Trim()"
95+
96+
@REM Save metadata values to variables for later use.
97+
FOR /f "usebackq" %%A IN (`powershell -NoProfile -Command ^
98+
"(Get-Content '!METAFILE!' | ConvertFrom-Json).mcu"`) DO SET "MCU=%%A"
99+
FOR /f "usebackq" %%A IN (`powershell -NoProfile -Command ^
100+
"(Get-Content '!METAFILE!' | ConvertFrom-Json).part | Where-Object { $_.subtype -eq 'ota_1' } | Select-Object -ExpandProperty offset"`
101+
) DO SET "OTA_OFFSET=%%A"
102+
FOR /f "usebackq" %%A IN (`powershell -NoProfile -Command ^
103+
"(Get-Content '!METAFILE!' | ConvertFrom-Json).part | Where-Object { $_.subtype -eq 'spiffs' } | Select-Object -ExpandProperty offset"`
104+
) DO SET "SPIFFS_OFFSET=%%A"
105+
) ELSE (
106+
CALL :LOG_MESSAGE ERROR "No metadata file found: !METAFILE!"
107+
GOTO eof
108+
)
109+
110+
:skip-filename
111+
112+
CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..."
113+
IF NOT "__%PYTHON%__"=="____" (
114+
SET "ESPTOOL_CMD=!PYTHON! -m esptool"
115+
CALL :LOG_MESSAGE DEBUG "Python interpreter supplied."
116+
) ELSE (
117+
CALL :LOG_MESSAGE DEBUG "Python interpreter NOT supplied. Looking for esptool..."
118+
WHERE esptool >nul 2>&1
119+
IF %ERRORLEVEL% EQU 0 (
120+
@REM WHERE exits with code 0 if esptool is found.
121+
SET "ESPTOOL_CMD=esptool"
122+
) ELSE (
123+
SET "ESPTOOL_CMD=python -m esptool"
124+
CALL :RESET_ERROR
125+
)
126+
)
127+
128+
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
129+
!ESPTOOL_CMD! >nul 2>&1
130+
IF %ERRORLEVEL% EQU 9009 (
131+
@REM 9009 = command not found on Windows
132+
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
133+
EXIT /B 1
134+
)
135+
IF %DEBUG% EQU 1 (
136+
CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps."
137+
SET "ESPTOOL_CMD=REM !ESPTOOL_CMD!"
138+
)
139+
140+
CALL :LOG_MESSAGE DEBUG "Using esptool command: !ESPTOOL_CMD!"
141+
IF "__!ESPTOOL_PORT!__" == "____" (
142+
CALL :LOG_MESSAGE WARN "Using esptool port: UNSET."
143+
) ELSE (
144+
SET "ESPTOOL_CMD=!ESPTOOL_CMD! --port !ESPTOOL_PORT!"
145+
CALL :LOG_MESSAGE INFO "Using esptool port: !ESPTOOL_PORT!."
146+
)
147+
CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."
148+
149+
IF %BPS_RESET% EQU 1 (
150+
@REM Attempt to change mode via 1200bps Reset.
151+
CALL :RUN_ESPTOOL 1200 --after no_reset read_flash_status
152+
GOTO eof
153+
)
154+
155+
@REM Extract PROGNAME from %FILENAME% for later use.
156+
SET "PROGNAME=!FILENAME:.factory.bin=!"
157+
CALL :LOG_MESSAGE DEBUG "Computed PROGNAME: !PROGNAME!"
158+
159+
@REM Determine OTA filename based on MCU type (unified OTA format)
160+
SET "OTA_FILENAME=mt-!MCU!-ota.bin"
161+
CALL :LOG_MESSAGE DEBUG "Set OTA_FILENAME to: !OTA_FILENAME!"
162+
163+
@REM Set SPIFFS filename with "littlefs-" prefix.
164+
SET "SPIFFS_FILENAME=littlefs-!PROGNAME:firmware-=!.bin"
165+
CALL :LOG_MESSAGE DEBUG "Set SPIFFS_FILENAME to: !SPIFFS_FILENAME!"
166+
167+
CALL :LOG_MESSAGE DEBUG "Set OTA_OFFSET to: !OTA_OFFSET!"
168+
CALL :LOG_MESSAGE DEBUG "Set SPIFFS_OFFSET to: !SPIFFS_OFFSET!"
169+
170+
@REM Ensure target files exist before flashing operations.
171+
IF NOT EXIST !FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
172+
IF NOT EXIST !OTA_FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!OTA_FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
173+
IF NOT EXIST !SPIFFS_FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!SPIFFS_FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
174+
175+
@REM Flashing operations.
176+
CALL :LOG_MESSAGE INFO "Trying to flash "!FILENAME!", but first erasing and writing system information..."
177+
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! erase_flash || GOTO eof
178+
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash 0x00 "!FILENAME!" || GOTO eof
179+
180+
CALL :LOG_MESSAGE INFO "Trying to flash BLEOTA "!OTA_FILENAME!" at OTA_OFFSET !OTA_OFFSET!..."
181+
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash !OTA_OFFSET! "!OTA_FILENAME!" || GOTO eof
182+
183+
CALL :LOG_MESSAGE INFO "Trying to flash SPIFFS "!SPIFFS_FILENAME!" at SPIFFS_OFFSET !SPIFFS_OFFSET!..."
184+
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash !SPIFFS_OFFSET! "!SPIFFS_FILENAME!" || GOTO eof
185+
186+
CALL :LOG_MESSAGE INFO "Script complete!."
187+
188+
:eof
189+
ENDLOCAL
190+
EXIT /B %ERRORLEVEL%
191+
192+
193+
:RUN_ESPTOOL
194+
@REM Subroutine used to run ESPTOOL_CMD with arguments.
195+
@REM Also handles %ERRORLEVEL%.
196+
@REM CALL :RUN_ESPTOOL [Baud] [erase_flash|write_flash] [OFFSET] [Filename]
197+
@REM.
198+
@REM Example:: CALL :RUN_ESPTOOL 115200 write_flash 0x10000 "firmwarefile.bin"
199+
IF %DEBUG% EQU 1 CALL :LOG_MESSAGE DEBUG "About to run command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
200+
CALL :RESET_ERROR
201+
!ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4
202+
IF %BPS_RESET% EQU 1 GOTO :eof
203+
IF %ERRORLEVEL% NEQ 0 (
204+
CALL :LOG_MESSAGE ERROR "Error running command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
205+
EXIT /B %ERRORLEVEL%
206+
)
207+
GOTO :eof
208+
209+
:LOG_MESSAGE
210+
@REM Subroutine used to print log messages in four different levels.
211+
@REM DEBUG messages only get printed if [-d] flag is passed to script.
212+
@REM CALL :LOG_MESSAGE [ERROR|INFO|WARN|DEBUG] "Message"
213+
@REM.
214+
@REM Example:: CALL :LOG_MESSAGE INFO "Message."
215+
SET /A LOGCOUNTER=LOGCOUNTER+1
216+
IF "%1" == "ERROR" CALL :GET_TIMESTAMP & ECHO %1 ^| !TIMESTAMP! !LOGCOUNTER! %~2
217+
IF "%1" == "INFO" CALL :GET_TIMESTAMP & ECHO %1 ^| !TIMESTAMP! !LOGCOUNTER! %~2
218+
IF "%1" == "WARN" CALL :GET_TIMESTAMP & ECHO %1 ^| !TIMESTAMP! !LOGCOUNTER! %~2
219+
IF "%1" == "DEBUG" IF %DEBUG% EQU 1 CALL :GET_TIMESTAMP & ECHO %1 ^| !TIMESTAMP! !LOGCOUNTER! %~2
220+
GOTO :eof
221+
222+
:GET_TIMESTAMP
223+
@REM Subroutine used to set !TIMESTAMP! to HH:MM:ss.
224+
@REM CALL :GET_TIMESTAMP
225+
@REM.
226+
@REM Updates: !TIMESTAMP!
227+
FOR /F "tokens=1,2,3 delims=:,." %%a IN ("%TIME%") DO (
228+
SET "HH=%%a"
229+
SET "MM=%%b"
230+
SET "ss=%%c"
231+
)
232+
SET "TIMESTAMP=!HH!:!MM!:!ss!"
233+
GOTO :eof
234+
235+
:RESET_ERROR
236+
@REM Subroutine to reset %ERRORLEVEL% to 0.
237+
@REM CALL :RESET_ERROR
238+
@REM.
239+
@REM Updates: %ERRORLEVEL%
240+
EXIT /B 0
241+
GOTO :eof

0 commit comments

Comments
 (0)