Skip to content

Commit 6ed292d

Browse files
authored
Merge pull request #788 from tyeth/offline-mode-flattened-new-2025-08-08
Offline mode new boards+components.
2 parents 8fff556 + 346c4c0 commit 6ed292d

36 files changed

+1192
-101
lines changed

.github/workflows/build-clang-doxy.yml

Lines changed: 71 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,23 @@ jobs:
2020
strategy:
2121
fail-fast: false
2222
matrix:
23-
arduino-platform: ["funhouse_noota"]
24-
include:
25-
- offset: "0x1000"
23+
arduino-platform:
24+
[
25+
"feather_esp32s2",
26+
"feather_esp32s2_reverse_tft",
27+
"feather_esp32s2_tft",
28+
"funhouse_noota",
29+
"magtag",
30+
"metroesp32s2",
31+
"qtpy_esp32s2",
32+
"esp32s3_devkitc_1_n8",
33+
"feather_esp32s3_4mbflash_2mbpsram",
34+
"feather_esp32s3_reverse_tft",
35+
"feather_esp32s3_tft",
36+
"qtpy_esp32s3_n4r2",
37+
"xiao_esp32s3",
38+
]
39+
2640
steps:
2741
- uses: actions/setup-python@v5
2842
with:
@@ -48,6 +62,7 @@ jobs:
4862
- name: Install extra Arduino libraries
4963
run: |
5064
git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library
65+
git clone --quiet https://github.com/adafruit/SdFat.git /home/runner/Arduino/libraries/SdFat
5166
git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg
5267
git clone --quiet https://github.com/adafruit/Adafruit_HX8357_Library.git /home/runner/Arduino/libraries/Adafruit_HX8357_Library
5368
git clone --quiet https://github.com/adafruit/Adafruit_ILI9341.git /home/runner/Arduino/libraries/Adafruit_ILI9341
@@ -106,6 +121,7 @@ jobs:
106121
mv examples/Wippersnapper_demo/build/*/Wippersnapper_demo.ino.elf wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.elf
107122
mv examples/Wippersnapper_demo/build/*/Wippersnapper_demo.ino.map wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.map
108123
mv examples/Wippersnapper_demo/build/*/Wippersnapper_demo.ino.bootloader.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.bootloader.bin
124+
mv examples/Wippersnapper_demo/build/*/Wippersnapper_demo.ino.merged.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.merged_auto.bin
109125
mv examples/Wippersnapper_demo/build/*/Wippersnapper_demo.ino.partitions.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.partitions.bin
110126
- name: Get Board Flash Parameters
111127
id: get_board_json
@@ -121,6 +137,52 @@ jobs:
121137
echo $content
122138
echo EOF
123139
} >> "$GITHUB_OUTPUT"
140+
- name: fetch tinyuf2 combined.bin
141+
run: |
142+
BOARD_NAME="${{fromJson(steps.get_board_json.outputs.boardJson).bootloaderBoardName}}"
143+
for attempt in 1 2; do
144+
echo "Attempt $attempt: Fetching tinyuf2 release info for board $BOARD_NAME"
145+
API_RESPONSE=$(curl --silent --fail https://api.github.com/repos/adafruit/tinyuf2/releases/latest)
146+
if [ $? -ne 0 ]; then
147+
echo "Attempt $attempt: curl failed to fetch release info."
148+
if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; continue; fi
149+
fi
150+
DOWNLOAD_URL=$(echo "$API_RESPONSE" | jq -r '.assets[] | select(.browser_download_url | contains("tinyuf2-'$BOARD_NAME'-") and endswith(".zip")) | .browser_download_url // empty')
151+
if [ -z "$DOWNLOAD_URL" ]; then
152+
echo "Attempt $attempt: No matching tinyuf2 zip found for board $BOARD_NAME."
153+
if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; continue; fi
154+
fi
155+
echo "Attempt $attempt: Downloading $DOWNLOAD_URL"
156+
wget "$DOWNLOAD_URL" -O tinyuf2.zip
157+
if [ $? -eq 0 ]; then
158+
unzip -o tinyuf2.zip -d .
159+
break
160+
else
161+
echo "Attempt $attempt: wget failed to download $DOWNLOAD_URL"
162+
if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; fi
163+
fi
164+
done
165+
- name: move partition and bootloader files for tinyuf2 (to match flash_args)
166+
run: |
167+
# Copy files where they're expected to make flash_args happy
168+
mkdir bootloader
169+
cp bootloader.bin bootloader/bootloader.bin
170+
mkdir partition_table
171+
cp partition-table.bin partition_table/partition-table.bin
172+
173+
- name: Create new_flash_args file from flash_args with added app bin + output file
174+
run: |
175+
# Create new_flash_args with esptool parameters first and output file
176+
echo "--flash-mode ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}}" > new_flash_args
177+
echo "--flash-freq ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashFreq}}" >> new_flash_args
178+
echo "--flash-size ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashSize}}" >> new_flash_args
179+
echo "-o wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.combined.bin" >> new_flash_args
180+
181+
# Append flash_args content to new_flash_args, skipping the first line
182+
tail -n +2 flash_args >> new_flash_args
183+
184+
# Append main app to flash_args file
185+
echo "0x10000 wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.bin" >> new_flash_args
124186
- name: Check boot_app0 file existence (esp32sx built from core, not-source)
125187
id: check_files
126188
uses: andstor/file-existence-action@v3
@@ -136,23 +198,17 @@ jobs:
136198
ls /home/runner/Arduino/hardware/espressif/esp32/tools/partitions
137199
- name: boot_app0 file from arduino-cli core
138200
if: steps.check_files.outputs.files_exists == 'true'
139-
run: mv /home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin
201+
run: cp /home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin
140202
- name: boot_app0 file from esp32 source bsp
141203
if: steps.check_files.outputs.files_exists == 'false'
142-
run: mv /home/runner/Arduino/hardware/espressif/esp32/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin
143-
- name: Create combined binary using Esptool merge_bin
204+
run: cp /home/runner/Arduino/hardware/espressif/esp32/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin
205+
- name: Copy boot_app0 file to ota_data_initial.bin (overwrite tinyuf2 boot preference)
206+
run: cp wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin ota_data_initial.bin
207+
- name: Create combined binary using Esptool merge-bin
144208
run: |
145209
echo ${{ steps.get_board_json.outputs.boardJson }}
146210
echo ${{ fromJson(steps.get_board_json.outputs.boardJson) }}
147-
python3 -m esptool --chip ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.chip}} merge_bin \
148-
--flash_mode ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}} \
149-
--flash_freq ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashFreq}} \
150-
--flash_size ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashSize}} \
151-
-o wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.combined.bin \
152-
${{ matrix.offset }} wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.bootloader.bin \
153-
0x8000 wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.partitions.bin \
154-
0xe000 wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.boot_app0.bin \
155-
0x10000 wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.bin
211+
python3 -m esptool --chip ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.chip}} merge-bin @new_flash_args
156212
- name: Zip build artifacts
157213
run: |
158214
zip -r wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.zip wippersnapper.${{ matrix.arduino-platform }}.fatfs.${{ env.WS_VERSION }}.*
@@ -180,19 +236,9 @@ jobs:
180236
matrix:
181237
arduino-platform:
182238
[
183-
"magtag",
184-
"metroesp32s2",
185239
"metro_esp32s3",
186-
"feather_esp32s2",
187-
"feather_esp32s2_tft",
188-
"feather_esp32s2_reverse_tft",
189240
"feather_esp32s3",
190-
"feather_esp32s3_4mbflash_2mbpsram",
191-
"feather_esp32s3_tft",
192241
"qtpy_esp32s3",
193-
"qtpy_esp32s2",
194-
"feather_esp32s3_reverse_tft",
195-
"qtpy_esp32s3_n4r2",
196242
]
197243
steps:
198244
- uses: actions/setup-python@v5

.github/workflows/release-offline.yml

Lines changed: 140 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ jobs:
9696
"qtpy_esp32s2",
9797
"feather_esp32s3_reverse_tft",
9898
"qtpy_esp32s3_n4r2",
99+
"esp32s3_devkitc_1_n8",
100+
"xiao_esp32s3",
99101
]
100102
steps:
101103
- uses: actions/setup-python@v5
@@ -112,6 +114,12 @@ jobs:
112114
repository: adafruit/ci-arduino
113115
ref: ci-wippersnapper
114116
path: ci
117+
- name: Checkout Board Definitions
118+
uses: actions/checkout@v4
119+
with:
120+
repository: adafruit/Wippersnapper_Boards
121+
path: ws-boards
122+
ref: offline-mode
115123
- name: Install CI-Arduino
116124
run: bash ci/actions_install.sh
117125
- name: Install extra Arduino libraries
@@ -161,23 +169,153 @@ jobs:
161169
- name: Copy lv_conf.h file in Adafruit_LittlevGL_Glue_Library to the arduino library folder
162170
run: |
163171
cp /home/runner/Arduino/libraries/Adafruit_LittlevGL_Glue_Library/lv_conf.h /home/runner/Arduino/libraries
172+
- name: Install Dependencies (esptool)
173+
run: |
174+
pip3 install esptool
164175
- name: Build for ESP32-SX
165176
run: |
166177
python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000
167178
- name: list files (tree)
168179
run: |
169-
tree
180+
tree -L 7 -h
170181
- name: Rename build artifacts to reflect the platform name
171182
run: |
172183
mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.uf2 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2
173184
mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bin
185+
mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.elf wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.elf
186+
mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.map wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.map
187+
mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.bootloader.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bootloader.bin
188+
mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.merged.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.merged_auto.bin
189+
mv examples/*/build/*/Wippersnapper_demo_offline_netiface.ino.partitions.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.partitions.bin
190+
- name: Get Board Flash Parameters
191+
id: get_board_json
192+
run: |
193+
board_name=${{ matrix.arduino-platform }}
194+
# Remove '_noota' suffix if present
195+
board_name=${board_name%_noota}
196+
# Remove 'wippersnapper_' prefix if present
197+
board_name=${board_name#wippersnapper_}
198+
# check folder name exists, otherwise do replace of underscore with dash, or blank
199+
if [ ! -d "ws-boards/boards/${board_name}" ]; then
200+
echo "Board definition folder ws-boards/boards/${board_name} does not exist, checking for alternative names."
201+
if [ -d "ws-boards/boards/${board_name//_/-}" ]; then
202+
board_name=${board_name//_/-}
203+
echo "Found alternative board definition folder ws-boards/boards/${board_name//_/-}."
204+
# Remove all underscores if still not found
205+
elif [ -d "ws-boards/boards/${board_name//_}" ]; then
206+
board_name=${board_name//_}
207+
echo "Found alternative board definition folder ws-boards/boards/${board_name//_}."
208+
else
209+
echo "Error: Board definition folder ws-boards/boards/${board_name} does not exist."
210+
exit 1
211+
fi
212+
fi
213+
content=$(cat ws-boards/boards/${board_name}/definition.json)
214+
{
215+
echo 'boardJson<<EOF'
216+
echo $content
217+
echo EOF
218+
} >> "$GITHUB_OUTPUT"
219+
- name: fetch tinyuf2 combined.bin
220+
id: get_tinyuf2
221+
continue-on-error: true
222+
run: |
223+
# check ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}} is not empty
224+
if [ -z "${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode}}" ]; then
225+
echo "Error: esptool.flashMode is not set in board definition, using KEEP for all settings."
226+
fi
227+
BOARD_NAME="${{fromJson(steps.get_board_json.outputs.boardJson).bootloaderBoardName || matrix.arduino-platform}}"
228+
for attempt in 1 2; do
229+
echo "Attempt $attempt: Fetching tinyuf2 release info for board $BOARD_NAME"
230+
API_RESPONSE=$(curl --silent --fail https://api.github.com/repos/adafruit/tinyuf2/releases/latest)
231+
if [ $? -ne 0 ]; then
232+
echo "Attempt $attempt: curl failed to fetch release info."
233+
if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; continue; fi
234+
fi
235+
DOWNLOAD_URL=$(echo "$API_RESPONSE" | jq -r '.assets[] | select(.browser_download_url | contains("tinyuf2-'$BOARD_NAME'-") and endswith(".zip")) | .browser_download_url // empty')
236+
if [ -z "$DOWNLOAD_URL" ]; then
237+
echo "Attempt $attempt: No matching tinyuf2 zip found for board $BOARD_NAME."
238+
if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; continue; fi
239+
fi
240+
echo "Attempt $attempt: Downloading $DOWNLOAD_URL"
241+
wget "$DOWNLOAD_URL" -O tinyuf2.zip
242+
if [ $? -eq 0 ]; then
243+
unzip -o tinyuf2.zip -d .
244+
break
245+
else
246+
echo "Attempt $attempt: wget failed to download $DOWNLOAD_URL"
247+
if [ "$attempt" -eq 2 ]; then exit 1; else sleep 2; fi
248+
fi
249+
done
250+
- if: ${{ steps.get_tinyuf2.outcome == 'success' }}
251+
name: move partition and bootloader files for tinyuf2 (to match flash_args)
252+
run: |
253+
# Copy files where they're expected to make flash_args happy
254+
mkdir bootloader
255+
cp bootloader.bin bootloader/bootloader.bin
256+
mkdir partition_table
257+
cp partition-table.bin partition_table/partition-table.bin
258+
259+
- if: ${{ steps.get_tinyuf2.outcome == 'success' }}
260+
name: Create new_flash_args file from flash_args with added app bin + output file
261+
run: |
262+
# Create new_flash_args with esptool parameters first and output file
263+
echo "--flash-mode ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashMode || 'keep'}}" > new_flash_args
264+
echo "--flash-freq ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashFreq || 'keep'}}" >> new_flash_args
265+
echo "--flash-size ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.flashSize || 'keep'}}" >> new_flash_args
266+
echo "-o wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.combined.bin" >> new_flash_args
267+
268+
# Append flash_args content to new_flash_args, skipping the first line
269+
tail -n +2 flash_args >> new_flash_args
270+
271+
# Append main app to flash_args file
272+
echo "0x10000 wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bin" >> new_flash_args
273+
- if: ${{ steps.get_tinyuf2.outcome == 'success' }}
274+
name: Check boot_app0 file existence (esp32sx built from core, not-source)
275+
id: check_files
276+
uses: andstor/file-existence-action@v3
277+
with:
278+
files: "/home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions/boot_app0.bin"
279+
- if: ${{ steps.get_tinyuf2.outcome == 'success' && steps.check_files.outputs.files_exists == 'true' }}
280+
name: list arduino esp32 core files
281+
run: |
282+
ls /home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions
283+
- if: ${{ steps.get_tinyuf2.outcome == 'success' && steps.check_files.outputs.files_exists == 'false' }}
284+
name: list arduino esp32 bsp core files
285+
run: |
286+
ls /home/runner/Arduino/hardware/espressif/esp32/tools/partitions
287+
- if: ${{ steps.get_tinyuf2.outcome == 'success' && steps.check_files.outputs.files_exists == 'true' }}
288+
name: boot_app0 file from arduino-cli core
289+
run: cp /home/runner/.arduino15/packages/esp32/hardware/esp32/*/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.boot_app0.bin
290+
- if: ${{ steps.get_tinyuf2.outcome == 'success' && steps.check_files.outputs.files_exists == 'false' }}
291+
name: boot_app0 file from esp32 source bsp
292+
run: cp /home/runner/Arduino/hardware/espressif/esp32/tools/partitions/boot_app0.bin wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.boot_app0.bin
293+
- if: ${{ steps.get_tinyuf2.outcome == 'success' }}
294+
name: Copy boot_app0 file to ota_data_initial.bin (overwrite tinyuf2 boot preference)
295+
run: cp wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.boot_app0.bin ota_data_initial.bin
296+
- if: ${{ steps.get_tinyuf2.outcome == 'success' }}
297+
name: Create combined binary using Esptool merge-bin
298+
run: |
299+
echo ${{ steps.get_board_json.outputs.boardJson }}
300+
echo ${{ fromJson(steps.get_board_json.outputs.boardJson) }}
301+
python3 -m esptool --chip ${{fromJson(steps.get_board_json.outputs.boardJson).esptool.chip || fromJson(steps.get_board_json.outputs.boardJson).mcuName}} merge-bin @new_flash_args
302+
- if: ${{ steps.get_tinyuf2.outcome == 'success' }}
303+
name: Zip build artifacts
304+
run: |
305+
zip -r wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.zip wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.*
306+
- if: ${{ steps.get_tinyuf2.outcome == 'success' }}
307+
name: Upload build artifacts zip
308+
uses: actions/upload-artifact@v4
309+
with:
310+
name: build-files-${{ matrix.arduino-platform }}-zip
311+
path: |
312+
wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.zip
174313
- name: upload build artifacts
175314
uses: actions/upload-artifact@v4
176315
with:
177316
name: build-files-${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}
178317
path: |
179318
wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2
180-
wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.bin
181319
182320
build-rp2040:
183321
name: 🏗️ RP2040, RP2350

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ html/*
4141
src/.vscode/settings.json
4242
.DS_STORE
4343
examples/Wippersnapper_demo/build/
44+
src/Wippersnapper_demo.ino.cpp
45+
build_output_*.txt
4446

4547
# Virtual environment directories
4648
.venv/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

0 commit comments

Comments
 (0)