Skip to content

Commit b211033

Browse files
1 parent 1002b09 commit b211033

415 files changed

Lines changed: 229101 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: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
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+
IF "__!MCU!__" == "__esp32s3__" (
160+
@REM We are working with ESP32-S3
161+
SET "OTA_FILENAME=bleota-s3.bin"
162+
) ELSE IF "__!MCU!__" == "__esp32c3__" (
163+
@REM We are working with ESP32-C3
164+
SET "OTA_FILENAME=bleota-c3.bin"
165+
) ELSE (
166+
@REM Everything else
167+
SET "OTA_FILENAME=bleota.bin"
168+
)
169+
CALL :LOG_MESSAGE DEBUG "Set OTA_FILENAME to: !OTA_FILENAME!"
170+
171+
@REM Set SPIFFS filename with "littlefs-" prefix.
172+
SET "SPIFFS_FILENAME=littlefs-!PROGNAME:firmware-=!.bin"
173+
CALL :LOG_MESSAGE DEBUG "Set SPIFFS_FILENAME to: !SPIFFS_FILENAME!"
174+
175+
CALL :LOG_MESSAGE DEBUG "Set OTA_OFFSET to: !OTA_OFFSET!"
176+
CALL :LOG_MESSAGE DEBUG "Set SPIFFS_OFFSET to: !SPIFFS_OFFSET!"
177+
178+
@REM Ensure target files exist before flashing operations.
179+
IF NOT EXIST !FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
180+
IF NOT EXIST !OTA_FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!OTA_FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
181+
IF NOT EXIST !SPIFFS_FILENAME! CALL :LOG_MESSAGE ERROR "File does not exist: "!SPIFFS_FILENAME!". Terminating." & EXIT /B 2 & GOTO eof
182+
183+
@REM Flashing operations.
184+
CALL :LOG_MESSAGE INFO "Trying to flash "!FILENAME!", but first erasing and writing system information..."
185+
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! erase_flash || GOTO eof
186+
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash 0x00 "!FILENAME!" || GOTO eof
187+
188+
CALL :LOG_MESSAGE INFO "Trying to flash BLEOTA "!OTA_FILENAME!" at OTA_OFFSET !OTA_OFFSET!..."
189+
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash !OTA_OFFSET! "!OTA_FILENAME!" || GOTO eof
190+
191+
CALL :LOG_MESSAGE INFO "Trying to flash SPIFFS "!SPIFFS_FILENAME!" at SPIFFS_OFFSET !SPIFFS_OFFSET!..."
192+
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write_flash !SPIFFS_OFFSET! "!SPIFFS_FILENAME!" || GOTO eof
193+
194+
CALL :LOG_MESSAGE INFO "Script complete!."
195+
196+
:eof
197+
ENDLOCAL
198+
EXIT /B %ERRORLEVEL%
199+
200+
201+
:RUN_ESPTOOL
202+
@REM Subroutine used to run ESPTOOL_CMD with arguments.
203+
@REM Also handles %ERRORLEVEL%.
204+
@REM CALL :RUN_ESPTOOL [Baud] [erase_flash|write_flash] [OFFSET] [Filename]
205+
@REM.
206+
@REM Example:: CALL :RUN_ESPTOOL 115200 write_flash 0x10000 "firmwarefile.bin"
207+
IF %DEBUG% EQU 1 CALL :LOG_MESSAGE DEBUG "About to run command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
208+
CALL :RESET_ERROR
209+
!ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4
210+
IF %BPS_RESET% EQU 1 GOTO :eof
211+
IF %ERRORLEVEL% NEQ 0 (
212+
CALL :LOG_MESSAGE ERROR "Error running command: !ESPTOOL_CMD! --baud %~1 %~2 %~3 %~4"
213+
EXIT /B %ERRORLEVEL%
214+
)
215+
GOTO :eof
216+
217+
:LOG_MESSAGE
218+
@REM Subroutine used to print log messages in four different levels.
219+
@REM DEBUG messages only get printed if [-d] flag is passed to script.
220+
@REM CALL :LOG_MESSAGE [ERROR|INFO|WARN|DEBUG] "Message"
221+
@REM.
222+
@REM Example:: CALL :LOG_MESSAGE INFO "Message."
223+
SET /A LOGCOUNTER=LOGCOUNTER+1
224+
IF "%1" == "ERROR" CALL :GET_TIMESTAMP & ECHO %1 ^| !TIMESTAMP! !LOGCOUNTER! %~2
225+
IF "%1" == "INFO" CALL :GET_TIMESTAMP & ECHO %1 ^| !TIMESTAMP! !LOGCOUNTER! %~2
226+
IF "%1" == "WARN" CALL :GET_TIMESTAMP & ECHO %1 ^| !TIMESTAMP! !LOGCOUNTER! %~2
227+
IF "%1" == "DEBUG" IF %DEBUG% EQU 1 CALL :GET_TIMESTAMP & ECHO %1 ^| !TIMESTAMP! !LOGCOUNTER! %~2
228+
GOTO :eof
229+
230+
:GET_TIMESTAMP
231+
@REM Subroutine used to set !TIMESTAMP! to HH:MM:ss.
232+
@REM CALL :GET_TIMESTAMP
233+
@REM.
234+
@REM Updates: !TIMESTAMP!
235+
FOR /F "tokens=1,2,3 delims=:,." %%a IN ("%TIME%") DO (
236+
SET "HH=%%a"
237+
SET "MM=%%b"
238+
SET "ss=%%c"
239+
)
240+
SET "TIMESTAMP=!HH!:!MM!:!ss!"
241+
GOTO :eof
242+
243+
:RESET_ERROR
244+
@REM Subroutine to reset %ERRORLEVEL% to 0.
245+
@REM CALL :RESET_ERROR
246+
@REM.
247+
@REM Updates: %ERRORLEVEL%
248+
EXIT /B 0
249+
GOTO :eof

0 commit comments

Comments
 (0)