Some checks failed
Build and deploy Docs site to GitHub Pages / github-pages (push) Has been cancelled
PR Build Check / build (Heltec_v3_companion_radio_ble) (push) Has been cancelled
PR Build Check / build (Heltec_v3_repeater) (push) Has been cancelled
PR Build Check / build (Heltec_v3_room_server) (push) Has been cancelled
PR Build Check / build (LilyGo_Tlora_C6_repeater_) (push) Has been cancelled
PR Build Check / build (PicoW_repeater) (push) Has been cancelled
PR Build Check / build (RAK_4631_companion_radio_ble) (push) Has been cancelled
PR Build Check / build (RAK_4631_repeater) (push) Has been cancelled
PR Build Check / build (RAK_4631_room_server) (push) Has been cancelled
PR Build Check / build (wio-e5-mini_repeater) (push) Has been cancelled
117 lines
3.7 KiB
Python
117 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
PlatformIO extra script: generate DFU .zip after build.
|
|
|
|
Add to platformio.ini:
|
|
extra_scripts = post:flasher/pio_create_dfu_zip.py
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
import json
|
|
import struct
|
|
import zipfile
|
|
|
|
# Add flasher dir to path for importing the main module
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
|
|
|
|
try:
|
|
from create_dfu_zip import hex_to_bin, uf2_to_bin, create_dfu_zip
|
|
except ImportError:
|
|
# Fallback: define minimal conversion inline
|
|
def hex_to_bin(hex_path):
|
|
from intelhex import IntelHex
|
|
ih = IntelHex(hex_path)
|
|
min_addr = ih.minaddr() or 0
|
|
max_addr = ih.maxaddr() or 0
|
|
size = max_addr - min_addr + 1
|
|
page_size = 0x1000
|
|
aligned = ((size + page_size - 1) // page_size) * page_size
|
|
return bytes(ih.tobinarray(start=min_addr, size=aligned)), min_addr
|
|
|
|
def create_dfu_zip(bin_data, base_addr, fw_version=1, hw_version=52):
|
|
init_packet = bytearray()
|
|
init_packet.append(0x01)
|
|
init_packet.append(0x04)
|
|
init_packet += struct.pack('<I', 0xFFFE)
|
|
init_packet += struct.pack('<I', 0xFFFFFFFF)
|
|
init_packet += struct.pack('<I', hw_version)
|
|
init_packet += struct.pack('<I', fw_version)
|
|
init_packet += struct.pack('<II', 0, 0)
|
|
manifest = {
|
|
"manifest": {
|
|
"application": {
|
|
"bin_file": "firmware.bin",
|
|
"dat_file": "firmware.dat",
|
|
"init_packet_data": {
|
|
"fw_version": fw_version,
|
|
"hw_version": hw_version,
|
|
"softdevice_req": [0xFFFE],
|
|
"components": [{"data": list(init_packet)}]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return manifest, bin_data, bytes(init_packet)
|
|
|
|
|
|
def create_dfu_zip_from_build(target, source, env):
|
|
"""PlatformIO post-build hook."""
|
|
build_dir = env.subst("$BUILD_DIR")
|
|
prog_name = env.subst("$PROGNAME")
|
|
hex_file = os.path.join(build_dir, prog_name + ".hex")
|
|
|
|
if not os.path.isfile(hex_file):
|
|
print(f" [DFU] {hex_file} not found, skipping")
|
|
return
|
|
|
|
try:
|
|
bin_data, base_addr = hex_to_bin(hex_file)
|
|
except Exception as e:
|
|
print(f" [DFU] Error: {e}")
|
|
return
|
|
|
|
manifest, fw_bin, fw_dat = create_dfu_zip(bin_data, base_addr)
|
|
|
|
# Name the zip after the build target (environment name)
|
|
env_name = env.subst("$PIOENV")
|
|
# Extract firmware name from env: e.g. Heltec_t114_without_display_beacon_sensor_ble -> Heltec_T114_Beacon_BLE
|
|
parts = env_name.split("_")
|
|
if "beacon" in parts:
|
|
fw_name = "Heltec_T114_Beacon"
|
|
elif "companion" in parts:
|
|
fw_name = "Heltec_T114_Companion_Radio"
|
|
elif "repeater" in parts:
|
|
fw_name = "Heltec_T114_Repeater"
|
|
elif "room" in parts:
|
|
fw_name = "Heltec_T114_Room_Server"
|
|
else:
|
|
fw_name = "firmware"
|
|
|
|
if "ble" in parts:
|
|
fw_name += "_BLE"
|
|
elif "usb" in parts:
|
|
fw_name += "_USB"
|
|
|
|
zip_name = f"{fw_name}.dfu.zip"
|
|
zip_path = os.path.join(build_dir, zip_name)
|
|
|
|
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
|
|
zf.writestr("manifest.json", json.dumps(manifest, indent=2))
|
|
zf.writestr("firmware.bin", fw_bin)
|
|
zf.writestr("firmware.dat", fw_dat)
|
|
|
|
size = os.path.getsize(zip_path)
|
|
print(f" [DFU] Created: {zip_path} ({size / 1024:.0f} KB)")
|
|
|
|
|
|
# Register hook
|
|
Import("env")
|
|
env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex", create_dfu_zip_from_build)
|
|
|
|
# Also trigger after .uf2 creation if that action exists
|
|
try:
|
|
env.AddPostAction("$BUILD_DIR/${PROGNAME}.uf2", create_dfu_zip_from_build)
|
|
except:
|
|
pass
|