diff --git a/config.json b/config.json index a8072c8..f077dc3 100644 --- a/config.json +++ b/config.json @@ -1,955 +1,3711 @@ { - "staticPath": "/firmware", - "role": { - "gui": { - "icon": "gradient", - "title": "Client GUI", - "tooltip": "all your device settings are saved on internal flash" - }, - "guiSD": { - "icon": "gradient", - "title": "Client GUI: data on SD card", - "tooltip": "all your device settings are saved on SD card" - }, - "companionBle": { - "icon": "smartphone", - "class": "primary-text", - "title": "Companion radio", - "subTitle": "Bluetooth", - "tooltip": "Chat via mobile phone App or Web Client" - }, - "companionUsb": { - "icon": "usb", - "title": "Companion radio", - "subTitle": "USB", - "tooltip": "Chat via Web client or command line client" - }, - "repeater": { - "icon": "cell_tower", - "title": "Repeater", - "tooltip": "Special role just for routing packets. Configured via Config/Console on flasher main page" - }, - "roomServer": { - "icon": "forum", - "title": "Room Server", - "tooltip": "Special role for local room and routing packets. Configured via Config/Console on flasher main page" - } - }, - "device": [ - { - "name": "Lilygo T-Deck", - "tooltip": "", - "type": "esp32", - "firmware": [ - { - "role": "gui", - "version": { - "v6.6": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-TDeck-v6.6-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-TDeck-v6.6.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ], - "notes": "* now saves repeater and room server passwords.\n* new 'auto advert ON/OFF' option" - }, - "v6.5": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-TDeck-v6.5-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-TDeck-v6.5.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ], - "notes": "* Existing profiles have SF editable" - }, - "v6.3": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-TDeck-v6.3-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-TDeck-v6.3.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ], - "notes": "* BUG Fix: advert verify caused memory corruption" - }, - "v6.2": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-TDeck-v6.2-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-TDeck-v6.2.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ] - }, - "v6.0-beta22": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-TDeck-v6.0-beta22-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-TDeck-v6.0-beta22.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ] - } - } - }, - { - "role": "guiSD", - "version": { - "v6.6": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-TDeck-SD-v6.6-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-TDeck-SD-v6.6.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ], - "notes": "* now saves repeater and room server passwords.\n* new 'auto advert ON/OFF' option" - }, - "v6.5": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-TDeck-SD-v6.5-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-TDeck-SD-v6.5.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ], - "notes": "* Existing profiles have SF editable" - }, - "v6.3": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-TDeck-SD-v6.3-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-TDeck-SD-v6.3.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ], - "notes": "* BUG Fix: advert verify caused memory corruption" - }, - "v6.2": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-TDeck-SD-v6.2-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-TDeck-SD-v6.2.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ] - }, - "v6.0-beta22": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-TDeck-SD-v6.0-beta22-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-TDeck-SD-v6.0-beta22.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ] - } - } - } - ] - }, - { - "name": "Lilygo T5 E-Paper S3 Pro", - "tooltip": "", - "type": "esp32", - "firmware": [ - { - "role": "gui", - "version": { - "v6.6": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-T5-epaper-v6.6-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-T5-epaper-v6.6.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ], - "notes": "* now saves repeater and room server passwords.\n* new 'auto advert ON/OFF' option" - }, - "v6.5": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-T5-epaper-v6.5-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-T5-epaper-v6.5.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ], - "notes": "* Existing profiles have SF editable" - }, - "v6.3": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-T5-epaper-v6.3-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-T5-epaper-v6.3.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ], - "notes": "* BUG Fix: advert verify caused memory corruption" - }, - "v6.0-beta22": { - "files": [ - { - "type": "flash", - "name": "RippleUltra-T5-epaper-v6.0-beta21-merged.bin", - "title": "Combined app+partition+bootloader firmware bin" - }, - { - "type": "download", - "name": "RippleUltra-T5-epaper-v6.0-beta21.bin", - "title": "App firmware bin (use with m5 booloader)" - } - ] - } - } - } - ] - }, - { - "name": "Lilygo T3 S3 (SX126x)", - "type": "esp32", - "tooltip": "", - "firmware": [ - { - "role": "companionUsb", - "github": { - "type": "companion", - "files": { - "flash": "LilyGo_T3S3_sx1262_companion_radio_usb.*?-merged\\.bin", - "download": "LilyGo_T3S3_sx1262_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "LilyGo_T3S3_sx1262_companion_radio_ble.*?-merged\\.bin", - "download": "LilyGo_T3S3_sx1262_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "LilyGo_T3S3_sx1262_Repeater.*?-merged\\.bin", - "download": "LilyGo_T3S3_sx1262_Repeater.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "LilyGo_T3S3_sx1262_room_server.*?-merged\\.bin", - "download": "LilyGo_T3S3_sx1262_room_server.*?-[a-f0-9]{7}\\.bin" - } - } - } - ] - }, - { - "name": "Lilygo T-Beam 1.2 (SX1276)", - "type": "esp32", - "tooltip": "", - "firmware": [ - { - "role": "companionUsb", - "github": { - "type": "companion", - "files": { - "flash": "Tbeam_companion_radio_usb.*?-merged\\.bin", - "download": "Tbeam_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "Tbeam_companion_radio_ble.*?-merged\\.bin", - "download": "Tbeam_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "Tbeam_repeater.*?-merged\\.bin", - "download": "Tbeam_repeater.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "Tbeam_room_server.*?-merged\\.bin", - "download": "Tbeam_room_server.*?-[a-f0-9]{7}\\.bin" - } - } - } - ] - }, - { - "name": "Lilygo T-Beam Supreme (SX1262)", - "type": "esp32", - "tooltip": "", - "firmware": [ - { - "role": "companionUsb", - "github": { - "type": "companion", - "files": { - "flash": "T_Beam_S3_Supreme_SX1262_companion_radio_usb.*?-merged\\.bin", - "download": "T_Beam_S3_Supreme_SX1262_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "T_Beam_S3_Supreme_SX1262_companion_radio_ble.*?-merged\\.bin", - "download": "T_Beam_S3_Supreme_SX1262_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "T_Beam_S3_Supreme_SX1262_repeater.*?-merged\\.bin", - "download": "T_Beam_S3_Supreme_SX1262_repeater.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "T_Beam_S3_Supreme_SX1262_room_server.*?-merged\\.bin", - "download": "T_Beam_S3_Supreme_SX1262_room_server.*?-[a-f0-9]{7}\\.bin" - } - } - } - ] - }, - { - "name": "Lilygo T-Echo", - "type": "nrf52", - "tooltip": "", - "firmware": [ - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "LilyGo_T-Echo_companion_radio_ble.*?\\.zip", - "download": "LilyGo_T-Echo_companion_radio_ble.*?\\.uf2" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "LilyGo_T-Echo_repeater.*?\\.zip", - "download": "LilyGo_T-Echo_repeater.*?\\.uf2" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "LilyGo_T-Echo_room_server.*?\\.zip", - "download": "LilyGo_T-Echo_room_server.*?\\.uf2" - } - } - } - ] - }, - { - "name": "Lilygo LoRa32 V2.1_1.6", - "type": "esp32", - "tooltip": "", - "firmware": [ - { - "role": "companionUsb", - "github": { - "type": "companion", - "files": { - "flash": "LilyGo_TLora_V2_1_1_6_companion_radio_usb.*?-merged\\.bin", - "download": "LilyGo_TLora_V2_1_1_6_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "LilyGo_TLora_V2_1_1_6_companion_radio_ble.*?-merged\\.bin", - "download": "LilyGo_TLora_V2_1_1_6_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "LilyGo_TLora_V2_1_1_6_Repeater.*?-merged\\.bin", - "download": "LilyGo_TLora_V2_1_1_6_Repeater.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "LilyGo_TLora_V2_1_1_6_room_server.*?-merged\\.bin", - "download": "LilyGo_TLora_V2_1_1_6_room_server.*?-[a-f0-9]{7}\\.bin" - } - } - } - ] - }, - { - "name": "Heltec v2", - "type": "esp32", - "tooltip": "", - "firmware": [ - { - "role": "companionUsb", - "github": { - "type": "companion", - "files": { - "flash": "Heltec_v2_companion_radio_usb.*?-merged\\.bin", - "download": "Heltec_v2_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "Heltec_v2_companion_radio_ble.*?-merged\\.bin", - "download": "Heltec_v2_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "Heltec_v2_repeater.*?-merged\\.bin", - "download": "Heltec_v2_repeater.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "Heltec_v2_room_server.*?-merged\\.bin", - "download": "Heltec_v2_room_server.*?-[a-f0-9]{7}\\.bin" - } - } - } - ] - }, - { - "name": "Heltec v3", - "type": "esp32", - "tooltip": "", - "firmware": [ - { - "role": "companionUsb", - "github": { - "type": "companion", - "files": { - "flash": "Heltec_v3_companion_radio_usb.*?-merged\\.bin", - "download": "Heltec_v3_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "Heltec_v3_companion_radio_ble.*?-merged\\.bin", - "download": "Heltec_v3_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "Heltec_v3_repeater.*?-merged\\.bin", - "download": "Heltec_v3_repeater.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "Heltec_v3_room_server.*?-merged\\.bin", - "download": "Heltec_v3_room_server.*?-[a-f0-9]{7}\\.bin" - } - } - } - ] - }, - { - "name": "Heltec T114", - "type": "nrf52", - "tooltip": "", - "firmware": [ - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "Heltec_t114_companion_radio_ble.*?\\.zip", - "download": "Heltec_t114_companion_radio_ble.*?\\.uf2" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "Heltec_t114_repeater.*?\\.zip", - "download": "Heltec_t114_repeater.*?\\.uf2" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "Heltec_t114_room_server.*?\\.zip", - "download": "Heltec_t114_room_server.*?\\.uf2" - } - } - } - ] - }, - { - "name": "Heltec WSL3", - "type": "esp32", - "tooltip": "", - "firmware": [ - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "Heltec_WSL3_companion_radio_ble.*?-merged\\.bin", - "download": "Heltec_WSL3_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "Heltec_WSL3_repeater.*?-merged\\.bin", - "download": "Heltec_WSL3_repeater.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "Heltec_WSL3_room_server.*?-merged\\.bin", - "download": "Heltec_WSL3_room_server.*?-[a-f0-9]{7}\\.bin" - } - } - } - ] - }, - { - "name": "RAK Wireless WisBlock / WisMesh (RAK 4631)", - "type": "nrf52", - "tooltip": "", - "firmware": [ - { - "role": "companionUsb", - "github": { - "type": "companion", - "files": { - "flash": "RAK_4631_companion_radio_usb.*?\\.zip", - "download": "RAK_4631_companion_radio_usb.*?\\.uf2" - } - } - }, - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "RAK_4631_companion_radio_ble.*?\\.zip", - "download": "RAK_4631_companion_radio_ble.*?\\.uf2" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "RAK_4631_Repeater.*?\\.zip", - "download": "RAK_4631_Repeater.*?\\.uf2" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "RAK_4631_room_server.*?\\.zip", - "download": "RAK_4631_room_server.*?\\.uf2" - } - } - } - ] - }, - { - "name": "Seeed Studio SenseCAP T1000-E", - "tooltip": "", - "type": "nrf52", - "firmware": [ - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "t1000e_companion_radio_ble.*?\\.zip", - "download": "t1000e_companion_radio_ble.*?\\.uf2" - } - } - } - ] - }, - { - "name": "Seeed Studio Xiao C3", - "tooltip": "", - "type": "esp32", - "firmware": [ - { - "role": "repeater", - "subTitle": "(SX1262 version)", - "github": { - "type": "repeater", - "files": { - "flash": "Xiao_C3_Repeater_sx1262.*?-merged\\.bin", - "download": "Xiao_C3_Repeater_sx1262.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "repeater", - "subTitle": "(SX1268 version)", - "github": { - "type": "repeater", - "files": { - "flash": "Xiao_C3_Repeater_sx1268.*?-merged\\.bin", - "download": "Xiao_C3_Repeater_sx1268.*?-[a-f0-9]{7}\\.bin" - } - } - } - ] - }, - { - "name": "Seeed Studio Xiao S3 WIO", - "tooltip": "", - "type": "esp32", - "firmware": [ - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "Xiao_S3_WIO_companion_radio_ble.*?-merged\\.bin", - "download": "Xiao_S3_WIO_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "Xiao_S3_WIO_Repeater.*?-merged\\.bin", - "download": "Xiao_S3_WIO_Repeater.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "Xiao_S3_WIO_room_server.*?-merged\\.bin", - "download": "Xiao_S3_WIO_room_server.*?-[a-f0-9]{7}\\.bin" - } - } - } - ] - }, - { - "name": "Seeed Studio Xiao nRF52 WIO", - "tooltip": "", - "type": "nrf52", - "firmware": [ - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "Xiao_nrf52_companion_radio_ble.*?\\.zip", - "download": "Xiao_nrf52_companion_radio_ble.*?\\.uf2" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "Xiao_nrf52_repeater.*?\\.zip", - "download": "Xiao_nrf52_repeater.*?\\.uf2" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "Xiao_nrf52_room_server.*?\\.zip", - "download": "Xiao_nrf52_room_server.*?\\.uf2" - } - } - } - ] - }, - { - "name": "UnitEng Station G2", - "tooltip": "", - "type": "esp32", - "firmware": [ - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "Station_G2_repeater.*?-merged\\.bin", - "download": "Station_G2_repeater.*?-[a-f0-9]{7}\\.bin" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "Station_G2_room_server.*?-merged\\.bin", - "download": "Station_G2_room_server.*?-[a-f0-9]{7}\\.bin" - } - } - } - ] - }, - { - "name": "ProMicro (SX1262)", - "type": "nrf52", - "tooltip": "", - "firmware": [ - { - "role": "companionUsb", - "github": { - "type": "companion", - "files": { - "flash": "Faketec_companion_radio_usb.*?\\.zip", - "download": "Faketec_companion_radio_usb.*?\\.uf2" - } - } - }, - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "Faketec_companion_radio_ble.*?\\.zip", - "download": "Faketec_companion_radio_ble.*?\\.uf2" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "Faketec_Repeater.*?\\.zip", - "download": "Faketec_Repeater.*?\\.uf2" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "Faketec_room_server.*?\\.zip", - "download": "Faketec_room_server.*?\\.uf2" - } - } - } - ] - }, - { - "name": "ProMicro (LLCC68)", - "type": "nrf52", - "tooltip":"", - "firmware": [ - { - "role": "companionUsb", - "github": { - "type": "companion", - "files": { - "flash": "ProMicroLLCC68_companion_radio_usb.*?\\.zip", - "download": "ProMicroLLCC68_companion_radio_usb.*?\\.uf2" - } - } - }, - { - "role": "companionBle", - "github": { - "type": "companion", - "files": { - "flash": "ProMicroLLCC68_companion_radio_ble.*?\\.zip", - "download": "ProMicroLLCC68_companion_radio_ble.*?\\.uf2" - } - } - }, - { - "role": "repeater", - "github": { - "type": "repeater", - "files": { - "flash": "ProMicroLLCC68_Repeater.*?\\.zip", - "download": "ProMicroLLCC68_Repeater.*?\\.uf2" - } - } - }, - { - "role": "roomServer", - "github": { - "type": "room-server", - "files": { - "flash": "ProMicroLLCC68_room_server.*?\\.zip", - "download": "ProMicroLLCC68_room_server.*?\\.uf2" - } - } - } - ] - } - ] + "staticPath": "/firmware", + "role": { + "gui": { + "icon": "gradient", + "title": "Ripple GUI", + "tooltip": "all your device settings are saved on internal flash" + }, + "guiSD": { + "icon": "gradient", + "title": "Ripple GUI: data on SD card", + "tooltip": "all your device settings are saved on SD card" + }, + "companionBle": { + "icon": "smartphone", + "title": "Companion", + "subTitle": "Bluetooth", + "tooltip": "Chat via mobile phone App or Web Client - Radio can only connect via Bluetooth" + }, + "companionUsb": { + "icon": "usb", + "title": "Companion", + "subTitle": "USB", + "tooltip": "Chat via Web client or command line client - Radio can only connect via USB" + }, + "repeater": { + "icon": "cell_tower", + "title": "Repeater", + "tooltip": "Special role just for routing packets. Configured via Config/Console on flasher main page" + }, + "roomServer": { + "icon": "forum", + "title": "Room Server", + "tooltip": "Special role for local room server. Configured via Config/Console on flasher main page" + } + }, + "maker": { + "elecrow": { + "name": "Elecrow" + }, + "heltec": { + "name": "Heltec" + }, + "seeed": { + "name": "Seeed Studio" + }, + "rak": { + "name": "RAK Wireless" + }, + "promicro": { + "name": "ProMicro" + }, + "lilygo": { + "name": "LilyGo" + }, + "raspberry": { + "name": "Raspberry Pi" + } + }, + "device": [ + { + "maker": "lilygo", + "class": "ripple", + "name": "LilyGo T-Deck", + "tooltip": "", + "icon": "/img/lora.svg", + "type": "esp32", + "firmware": [ + { + "role": "gui", + "version": { + "v7.14": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-v7.14-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-v7.14.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* NEW: 'Scan Local' menu in Discover\n* Message text: now converts accented chars to ASCII equivalent\n* Popular emojis now converted, eg ':thumbsup'\n* Contacts can be tagged and custom notes added\n* Repeater CLI, 'neighbors' command now using binary req/resp\n* Max group channels now upped to 6\n* Bug fix: some CLI responses were lost from dup timestamp.\n* #channel key calc now forces lowercase\n* Better canned messages for CLI screens\n* Group channel message, 'Reply To' menu\n* Kid Mode: now supports up to 1 group channel chat" + }, + "v7.12": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-v7.12-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-v7.12.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Vibe pref now saved\n* Remote admin prefixes, extra spaces allowed\n* Presets updated\n* Msg details: ‘heard by’ \n* Repeater and room CLI: “get” command (get full telemetry)\n* Channel details: Alerts ON/OFF menu" + }, + "v7.11": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-v7.11-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-v7.11.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New: Kid Mode and remote admin\n* message details, ENTER to goto next message\n* Group channel message rendering improved" + }, + "v7.10": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-v7.10-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-v7.10.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New network: region presets\n* Security: new PIN Lock Screen\n* Pixel art: improved colour picker\n* Message details: new ‘Show on Map’ menu\n* New clipboard system: long press for copy/paste" + }, + "v7.9": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-v7.9-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-v7.9.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Max group channels now 4\n* Auto channel support (name starting with ‘#’)\n* Home Screen: ‘$’ key jumps to next contact with unread > 0\n* New message details screen (scroll up to msg, then select)\n* GPS Config screen redesign\n* Home Screen, tap on top-right of screen opens GPS Info\n* Repeater and room server admin CLI: added “setperm” and “get acl” support" + }, + "v7.7": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-v7.7-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-v7.7.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Max contacts now doubled\n* Only (home) contacts can now DM you\n* Home Screen, swipe left/right to go thru filters\n* Identity screen: new advert location pref\n* New “Permissions” screen: set Telemetry permissions\n* Map view: new “Set Advert Loc” menu.\n* Canned Message: special “< prev msg>” item (re-type last msg)" + }, + "v7.6": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-v7.6-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-v7.6.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* \"Multi ACKs\" support (Optimise menu)\n* Advert path details (from node details screen)\n* Group channel chats, message path details\n* Home menu: Brightness DAY/NIGHT\n* Canned Messages support\n* MeshCore lib updates/fixes" + }, + "v7.5": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-v7.5-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-v7.5.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Sensor node support\n* Preamble now 16\n* Home Screen: node ID prefixes displayed\n* Discover list: space to toggle ID prefixes" + }, + "v7.4": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-v7.4-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-v7.4.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Discover, Node details now shows advert path\n* New GPS telemetry permissions: ALLOW:Home, ALLOW:All\n* Group channel outbound messages now with confirmation counters\n* T-Deck Plus (new keyboard model) auto backlight on/off\n* Map labels now non-overlapping\n* Network profiles now with customisable BW and CR" + }, + "v7.3": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-v7.3-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-v7.3.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* GPS tracks!\n* Optimise menu: Interference threshold, AGC reset interval" + }, + "v7.1": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-UKStore-v7.1-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-UKStore-v7.1.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Channel details hex or base64 input\n* Screen off long press shortened to 1 sec\n* A-Z key press now jumps to contacts\n* ‘@‘ key now refreshes/reorders list by most recent advert\n* MeshCore lib updates/fixes\n* better Help/Tutorial screens" + }, + "v7.0": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-UKStore-v7.0-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-UKStore-v7.0.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Saved paths, manual set path,\n* Trackball press is now select, long press for screen off,\n* Room keep-alive packets now not sent,\n* Discover screen, max now 140,\n* New customisable sounds: new-advert.mp3, existing-advert.mp3" + }, + "v6.9": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-UKStore-v6.9-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-UKStore-v6.9.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Sound and other prefs now persisted\n* New “Show on Map” conversation menu\n* MeshCore lib fixes" + }, + "v6.8": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-UKStore-v6.8-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-UKStore-v6.8.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Repeater & Room UI redesign\n* Room, admin CLI now from menu" + }, + "v6.7": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-v6.7-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-v6.7.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Public channel auto-configured (new profiles)\n* Telemetry support (location, ‘online’ indicator)\n* Rooms, unsynced counter (green)\n* Room stats dialog\n* Discover, ‘Send ID Broadcast’ menu" + }, + "v6.6": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-v6.6-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-v6.6.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* now saves repeater and room server passwords.\n* New 'auto advert ON/OFF' option" + }, + "v6.5": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-v6.5-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-v6.5.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Existing profiles have SF editable" + }, + "v6.3": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-v6.3-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-v6.3.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* BUG Fix: advert verify caused memory corruption" + }, + "v6.2": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-v6.2-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-v6.2.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ] + }, + "v6.0-beta22": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-v6.0-beta22-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-v6.0-beta22.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ] + } + } + }, + { + "role": "guiSD", + "version": { + "v7.14": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-v7.14-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-v7.14.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* NEW: 'Scan Local' menu in Discover\n* Message text: now converts accented chars to ASCII equivalent\n* Popular emojis now converted, eg ':thumbsup'\n* Contacts can be tagged and custom notes added\n* Repeater CLI, 'neighbors' command now using binary req/resp\n* Max group channels now upped to 6\n* Bug fix: some CLI responses were lost from dup timestamp.\n* #channel key calc now forces lowercase\n* Better canned messages for CLI screens\n* Group channel message, 'Reply To' menu\n* Kid Mode: now supports up to 1 group channel chat" + }, + "v7.12": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-v7.12-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-v7.12.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Vibe pref now saved\n* Remote admin prefixes, extra spaces allowed\n* Presets updated\n* Msg details: ‘heard by’ \n* Repeater and room CLI: “get” command (get full telemetry)\n* Channel details: Alerts ON/OFF menu" + }, + "v7.11": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-v7.11-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-v7.11.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New: Kid Mode and remote admin\n* message details, ENTER to goto next message\n* Group channel message rendering improved" + }, + "v7.10": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-v7.10-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-v7.10.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New network: region presets\n* Security: new PIN Lock Screen\n* Pixel art: improved colour picker\n* Message details: new ‘Show on Map’ menu\n* New clipboard system: long press for copy/paste" + }, + "v7.9": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-v7.9-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-v7.9.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Max group channels now 4\n* Auto channel support (name starting with ‘#’)\n* Home Screen: ‘$’ key jumps to next contact with unread > 0\n* New message details screen (scroll up to msg, then select)\n* GPS Config screen redesign\n* Home Screen, tap on top-right of screen opens GPS Info\n* Repeater and room server admin CLI: added “setperm” and “get acl” support" + }, + "v7.7": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-v7.7-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-v7.7.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Max contacts now doubled\n* Only (home) contacts can now DM you\n* Home Screen, swipe left/right to go thru filters\n* Identity screen: new advert location pref\n* New “Permissions” screen: set Telemetry permissions\n* Map view: new “Set Advert Loc” menu.\n* Canned Message: special “< prev msg>” item (re-type last msg)" + }, + "v7.6": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-v7.6-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-v7.6.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* \"Multi ACKs\" support (Optimise menu)\n* Advert path details (from node details screen)\n* Group channel chats, message path details\n* Home menu: Brightness DAY/NIGHT\n* Canned Messages support\n* MeshCore lib updates/fixes" + }, + "v7.5": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-v7.5-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-v7.5.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Sensor node support\n* Preamble now 16\n* Home Screen: node ID prefixes displayed\n* Discover list: space to toggle ID prefixes" + }, + "v7.4": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-v7.4-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-v7.4.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Discover, Node details now shows advert path\n* New GPS telemetry permissions: ALLOW:Home, ALLOW:All\n* Group channel outbound messages now with confirmation counters\n* T-Deck Plus (new keyboard model) auto backlight on/off\n* Map labels now non-overlapping\n* Network profiles now with customisable BW and CR" + }, + "v7.3": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-v7.3-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-v7.3.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* GPS tracks!\n* Optimise menu: Interference threshold, AGC reset interval" + }, + "v7.1": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-UKStore-v7.1-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-UKStore-v7.1.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Channel details hex or base64 input\n* Screen off long press shortened to 1 sec\n* A-Z key press now jumps to contacts\n* ‘@‘ key now refreshes/reorders list by most recent advert\n* MeshCore lib updates/fixes\n* better Help/Tutorial screens" + }, + "v7.0": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-UKStore-v7.0-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-UKStore-v7.0.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Saved paths, manual set path,\n* Trackball press is now select, long press for screen off,\n* Room keep-alive packets now not sent,\n* Discover screen, max now 140,\n* New customisable sounds: new-advert.mp3, existing-advert.mp3" + }, + "v6.9": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-UKStore-v6.9-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-UKStore-v6.9.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Sound and other prefs now persisted\n* New “Show on Map” conversation menu\n* MeshCore lib fixes" + }, + "v6.8": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeck-SD-UKStore-v6.8-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeck-SD-UKStore-v6.8.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Repeater & Room UI redesign\n* Room, admin CLI now from menu" + }, + "v6.7": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-SD-v6.7-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-SD-v6.7.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Public channel auto-configured (new profiles)\n* Telemetry support (location, ‘online’ indicator)\n* Rooms, unsynced counter (green)\n* Room stats dialog\n* Discover, ‘Send ID Broadcast’ menu" + }, + "v6.6": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-SD-v6.6-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-SD-v6.6.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* now saves repeater and room server passwords.\n* New 'auto advert ON/OFF' option" + }, + "v6.5": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-SD-v6.5-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-SD-v6.5.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Existing profiles have SF editable" + }, + "v6.3": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-SD-v6.3-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-SD-v6.3.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* BUG Fix: advert verify caused memory corruption" + }, + "v6.2": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-SD-v6.2-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-SD-v6.2.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ] + }, + "v6.0-beta22": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-TDeck-SD-v6.0-beta22-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-TDeck-SD-v6.0-beta22.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ] + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "ripple", + "name": "LilyGo T-Deck Pro", + "tooltip": "", + "icon": "/img/lora.svg", + "type": "esp32", + "firmware": [ + { + "role": "gui", + "version": { + "v7.14": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-v7.14-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-v7.14.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* NEW: 'Scan Local' menu in Discover\n* Message text: now converts accented chars to ASCII equivalent\n* Popular emojis now converted, eg ':thumbsup'\n* Contacts can be tagged and custom notes added\n* Repeater CLI, 'neighbors' command now using binary req/resp\n* Max group channels now upped to 6\n* Bug fix: some CLI responses were lost from dup timestamp.\n* #channel key calc now forces lowercase\n* Better canned messages for CLI screens\n* Group channel message, 'Reply To' menu\n* Kid Mode: now supports up to 1 group channel chat" + }, + "v7.12": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-v7.12-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-v7.12.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Vibe pref now saved\n* Display off pref (to locked screen)\n* UI style updates\n* Remote admin prefixes, extra spaces allowed\n* Presets updated\n* Msg details: ‘heard by’\n* Repeater and room CLI: “get” command (get full telemetry)\n* Channel details: Alerts ON/OFF menu" + }, + "v7.11": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-v7.11-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-v7.11.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New: Kid Mode and remote admin\n* message details, ENTER to goto next message\n* Group channel message rendering improved" + }, + "v7.10": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-v7.10-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-v7.10.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New network: region presets\n* Security: new PIN Lock Screen\n* Map view: keys 0..9 change map contrast\n* Message details: new ‘Show on Map’ menu\n* New clipboard system: long press for copy/paste\n* Locked screen redesign\n* LED alert option: now flashes keyboard backlight" + }, + "v7.9": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-v7.9-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-v7.9.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Max group channels now 4\n* Auto channel support (name starting with ‘#’)\n* Home Screen: ‘$’ key jumps to next contact with unread > 0\n* Home Screen, tap on top-right of screen opens GPS Info\n* Repeater and room server admin CLI: added “setperm” and “get acl” support\n* Map tiles dir now “/tiles-bw” (or “/tiles” as fallback)" + }, + "v7.8": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-v7.8-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-v7.8.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Map support!\n* GPS Config screen fixed\n* Lock screen, current date added\n* Various screen layout fixes" + }, + "v7.7": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-v7.7-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-v7.7.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Initial release" + } + } + }, + { + "role": "guiSD", + "version": { + "v7.14": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-SD-v7.14-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-SD-v7.14.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* NEW: 'Scan Local' menu in Discover\n* Message text: now converts accented chars to ASCII equivalent\n* Popular emojis now converted, eg ':thumbsup'\n* Contacts can be tagged and custom notes added\n* Repeater CLI, 'neighbors' command now using binary req/resp\n* Max group channels now upped to 6\n* Bug fix: some CLI responses were lost from dup timestamp.\n* #channel key calc now forces lowercase\n* Better canned messages for CLI screens\n* Group channel message, 'Reply To' menu\n* Kid Mode: now supports up to 1 group channel chat" + }, + "v7.12": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-SD-v7.12-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-SD-v7.12.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Vibe pref now saved\n* Display off pref (to locked screen)\n* UI style updates\n* Remote admin prefixes, extra spaces allowed\n* Presets updated\n* Msg details: ‘heard by’\n* Repeater and room CLI: “get” command (get full telemetry)\n* Channel details: Alerts ON/OFF menu" + }, + "v7.11": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-SD-v7.11-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-SD-v7.11.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New: Kid Mode and remote admin\n* message details, ENTER to goto next message\n* Group channel message rendering improved" + }, + "v7.10": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-SD-v7.10-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-SD-v7.10.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New network: region presets\n* Security: new PIN Lock Screen\n* Map view: keys 0..9 change map contrast\n* Message details: new ‘Show on Map’ menu\n* New clipboard system: long press for copy/paste\n* Locked screen redesign\n* LED alert option: now flashes keyboard backlight" + }, + "v7.9": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-SD-v7.9-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-SD-v7.9.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Max group channels now 4\n* Auto channel support (name starting with ‘#’)\n* Home Screen: ‘$’ key jumps to next contact with unread > 0\n* Home Screen, tap on top-right of screen opens GPS Info\n* Repeater and room server admin CLI: added “setperm” and “get acl” support\n* Map tiles dir now “/tiles-bw” (or “/tiles” as fallback)" + }, + "v7.8": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-SD-v7.8-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-SD-v7.8.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Map support!\n* GPS Config screen fixed\n* Lock screen, current date added\n* Various screen layout fixes" + }, + "v7.7": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDeckPro-SD-v7.7-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDeckPro-SD-v7.7.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Initial release" + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "ripple", + "name": "LilyGo T5 E-Paper S3 Pro (non-gps, only rev. H752)", + "tooltip": "", + "icon": "/img/lora.svg", + "type": "esp32", + "firmware": [ + { + "role": "gui", + "version": { + "v7.1": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-T5-epaper-UKStore-v7.1-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-T5-epaper-UKStore-v7.1.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Channel details hex or base64 input\n* MeshCore lib updates/fixes" + }, + "v7.0": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-T5-epaper-UKStore-v7.0-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-T5-epaper-UKStore-v7.0.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Saved paths, manual set path,\n* Trackball press is now select, long press for screen off,\n* Room keep-alive packets now not sent,\n* Discover screen, max now 140,\n* New customisable sounds: new-advert.mp3, existing-advert.mp3" + }, + "v6.9": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-T5-epaper-UKStore-v6.9-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-T5-epaper-UKStore-v6.9.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Sound and other prefs now persisted\n* New “Show on Map” conversation menu\n* MeshCore lib fixes" + }, + "v6.8": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-T5-epaper-UKStore-v6.8-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-T5-epaper-UKStore-v6.8.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Repeater & Room UI redesign\n* Room, admin CLI now from menu" + }, + "v6.7": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-T5-epaper-v6.7-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-T5-epaper-v6.7.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Public channel auto-configured (new profiles)\n* Telemetry support (location, ‘online’ indicator)\n* Rooms, unsynced counter (green)\n* Room stats dialog\n* Discover, ‘Send ID Broadcast’ menu" + }, + "v6.6": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-T5-epaper-v6.6-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-T5-epaper-v6.6.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* now saves repeater and room server passwords.\n* New 'auto advert ON/OFF' option" + }, + "v6.5": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-T5-epaper-v6.5-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-T5-epaper-v6.5.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Existing profiles have SF editable" + }, + "v6.3": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-T5-epaper-v6.3-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-T5-epaper-v6.3.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* BUG Fix: advert verify caused memory corruption" + }, + "v6.0-beta22": { + "files": [ + { + "type": "flash-wipe", + "name": "RippleUltra-T5-epaper-v6.0-beta21-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "RippleUltra-T5-epaper-v6.0-beta21.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ] + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "ripple", + "name": "LilyGo T-Lora Pager", + "tooltip": "", + "icon": "/img/lora.svg", + "type": "esp32", + "firmware": [ + { + "role": "gui", + "title": "[SX1262] Ripple GUI", + "version": { + "v7.14": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-sx1262-v7.14-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-sx1262-v7.14.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* NEW: 'Scan Local' menu in Discover\n* Message text: now converts accented chars to ASCII equivalent\n* Popular emojis now converted, eg ':thumbsup'\n* Contacts can be tagged and custom notes added\n* Repeater CLI, 'neighbors' command now using binary req/resp\n* Max group channels now upped to 6\n* Bug fix: some CLI responses were lost from dup timestamp.\n* #channel key calc now forces lowercase\n* Better canned messages for CLI screens\n* Group channel message, 'Reply To' menu\n* Kid Mode: now supports up to 1 group channel chat" + }, + "v7.12": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-v7.12-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-v7.12.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Vibe pref now saved\n* Remote admin prefixes, extra spaces allowed\n* Presets updated\n* Msg details: ‘heard by’\n* Repeater and room CLI: “get” command (get full telemetry)\n* Channel details: Alerts ON/OFF menu" + }, + "v7.11": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-v7.11-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-v7.11.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New: Kid Mode and remote admin\n* message details, ENTER to goto next message\n* Group channel message rendering improved" + }, + "v7.10": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-v7.10-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-v7.10.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New network: region presets\n* Security: new PIN Lock Screen\n* Channel details: “Type ‘#’” menu\n* Message details: new ‘Show on Map’ menu\n* New clipboard system: long press scroll wheel for copy/paste" + }, + "v7.9": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-v7.9-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-v7.9.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Max group channels now 4\n* Auto channel support (name starting with ‘#’)\n* Scroll wheel disabled while screen off\n* Keyboard backlight now flashes on new message (config via LED menu option)\n* Home Screen: ‘$’ key jumps to next contact with unread > 0\n* New message details screen (scroll up to msg, then select)\n* GPS Config screen redesign\n* Home Screen, tap on top-right of screen opens GPS Info\n* Repeater and room server admin CLI: added “setperm” and “get acl” support" + }, + "v7.7": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-v7.7-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-v7.7.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Max contacts now doubled\n* Only (home) contacts can now DM you\n* Home Screen, ‘.’ and ‘,’ keys to go thru filters\n* Identity screen: new advert location pref\n* New “Permissions” screen: set Telemetry permissions\n* Canned Message: special “< prev msg>” item (re-type last msg)\n* Long press Enter and Backspace now more snappy\n* New GPS power ON / OFF setting\n* New Brightness: DAY / NIGHT setting" + }, + "v7.6": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-v7.6-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-v7.6.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* \"Multi ACKs\" support (Optimise menu)\n* Advert path details (from node details screen)\n* Group channel chats, message path details\n* Home menu: Brightness DAY/NIGHT\n* Canned Messages support\n* MeshCore lib updates/fixes" + }, + "v7.5": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-v7.5-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-v7.5.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Sensor node support\n* Map panning, keys: W,S,A,D\n* Preamble now 16\n* Home Screen: node ID prefixes displayed\n* Discover list: space to toggle ID prefixes" + }, + "v7.4": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-v7.4-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-v7.4.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Discover, Node details now shows advert path\n* New GPS telemetry permissions: ALLOW:Home, ALLOW:All\n* Group channel outbound messages now with confirmation counters\n* Map labels now non-overlapping\n* Network profiles now with customisable BW and CR" + }, + "v7.3": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-v7.3-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-v7.3.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* GPS tracks!\n* Optimise menu: Interference threshold, AGC reset interval" + }, + "v7.1": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-UKStore-v7.1-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-UKStore-v7.1.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Channel details hex or base64 input\n* A-Z key press now jumps to contacts\n* ‘@‘ key now refreshes/reorders list by most recent advert\n* MeshCore lib updates/fixes" + }, + "v7.0": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-UKStore-v7.0-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-UKStore-v7.0.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Initial release" + } + } + }, + { + "role": "guiSD", + "title": "[SX1262] Ripple GUI: data on SD card", + "version": { + "v7.14": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-sx1262-v7.14-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-sx1262-v7.14.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* NEW: 'Scan Local' menu in Discover\n* Message text: now converts accented chars to ASCII equivalent\n* Popular emojis now converted, eg ':thumbsup'\n* Contacts can be tagged and custom notes added\n* Repeater CLI, 'neighbors' command now using binary req/resp\n* Max group channels now upped to 6\n* Bug fix: some CLI responses were lost from dup timestamp.\n* #channel key calc now forces lowercase\n* Better canned messages for CLI screens\n* Group channel message, 'Reply To' menu\n* Kid Mode: now supports up to 1 group channel chat" + }, + "v7.12": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-v7.12-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-v7.12.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Vibe pref now saved\n* Remote admin prefixes, extra spaces allowed\n* Presets updated\n* Msg details: ‘heard by’ \n* Repeater and room CLI: “get” command (get full telemetry)\n* Channel details: Alerts ON/OFF menu" + }, + "v7.11": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-v7.11-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-v7.11.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New: Kid Mode and remote admin\n* message details, ENTER to goto next message\n* Group channel message rendering improved" + }, + "v7.10": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-v7.10-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-v7.10.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* New network: region presets\n* Security: new PIN Lock Screen\n* Channel details: “Type ‘#’” menu\n* Message details: new ‘Show on Map’ menu\n* New clipboard system: long press scroll wheel for copy/paste" + }, + "v7.9": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-v7.9-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-v7.9.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Max group channels now 4\n* Auto channel support (name starting with ‘#’)\n* Scroll wheel disabled while screen off\n* Keyboard backlight now flashes on new message (config via LED menu option)\n* Home Screen: ‘$’ key jumps to next contact with unread > 0\n* New message details screen (scroll up to msg, then select)\n* GPS Config screen redesign\n* Home Screen, tap on top-right of screen opens GPS Info\n* Repeater and room server admin CLI: added “setperm” and “get acl” support" + }, + "v7.7": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-v7.7-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-v7.7.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Max contacts now doubled\n* Only (home) contacts can now DM you\n* Home Screen, ‘.’ and ‘,’ keys to go thru filters\n* Identity screen: new advert location pref\n* New “Permissions” screen: set Telemetry permissions\n* Canned Message: special “< prev msg>” item (re-type last msg)\n* Long press Enter and Backspace now more snappy\n* New GPS power ON / OFF setting\n* New Brightness: DAY / NIGHT setting" + }, + "v7.5": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-v7.5-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-v7.5.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Sensor node support\n* Map panning, keys: W,S,A,D\n* Preamble now 16\n* Home Screen: node ID prefixes displayed\n* Discover list: space to toggle ID prefixes" + }, + "v7.4": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-v7.4-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-v7.4.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Discover, Node details now shows advert path\n* New GPS telemetry permissions: ALLOW:Home, ALLOW:All\n* Group channel outbound messages now with confirmation counters\n* Map labels now non-overlapping\n* Network profiles now with customisable BW and CR" + }, + "v7.3": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-v7.3-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-v7.3.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* GPS tracks!\n* Optimise menu: Interference threshold, AGC reset interval" + }, + "v7.1": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-UKStore-v7.1-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-UKStore-v7.1.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Channel details hex or base64 input\n* A-Z key press now jumps to contacts\n* ‘@‘ key now refreshes/reorders list by most recent advert\n* MeshCore lib updates/fixes" + }, + "v7.0": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-UKStore-v7.0-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-UKStore-v7.0.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Initial release" + } + } + }, + { + "role": "gui", + "title": "[LR1121] Ripple GUI", + "version": { + "v7.14": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-LR1121-v7.14-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-LR1121-v7.14.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* NEW: 'Scan Local' menu in Discover\n* Message text: now converts accented chars to ASCII equivalent\n* Popular emojis now converted, eg ':thumbsup'\n* Contacts can be tagged and custom notes added\n* Repeater CLI, 'neighbors' command now using binary req/resp\n* Max group channels now upped to 6\n* Bug fix: some CLI responses were lost from dup timestamp.\n* #channel key calc now forces lowercase\n* Better canned messages for CLI screens\n* Group channel message, 'Reply To' menu\n* Kid Mode: now supports up to 1 group channel chat" + } + } + }, + { + "role": "guiSD", + "title": "[LR1121] Ripple GUI: data on SD card", + "version": { + "v7.14": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TPager-SD-LR1121-v7.14-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TPager-SD-LR1121-v7.14.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* NEW: 'Scan Local' menu in Discover\n* Message text: now converts accented chars to ASCII equivalent\n* Popular emojis now converted, eg ':thumbsup'\n* Contacts can be tagged and custom notes added\n* Repeater CLI, 'neighbors' command now using binary req/resp\n* Max group channels now upped to 6\n* Bug fix: some CLI responses were lost from dup timestamp.\n* #channel key calc now forces lowercase\n* Better canned messages for CLI screens\n* Group channel message, 'Reply To' menu\n* Kid Mode: now supports up to 1 group channel chat" + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "ripple", + "name": "LilyGo T-Display Pro", + "icon": "/img/esp_now.svg", + "tooltip": "", + "type": "esp32", + "firmware": [ + { + "role": "gui", + "version": { + "v7.5": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-ESPNOW-TDisplayPro-v7.5-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-ESPNOW-TDisplayPro-v7.5.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Sensor node support\n* LoRa spreading factor now 16\n* Home Screen: node ID prefixes displayed\n* Discover, Node details now shows advert path\n* new GPS telemetry permissions: ALLOW:Home, ALLOW:All\n* group channel outbound messages now with confirmation counters\n* map labels now non-overlapping\n* network profiles now with customisable BW and CR\n* GPS tracks!\n* Optimise menu: Interference threshold, AGC reset interval\n* Channel details hex or base64 input" + }, + "v6.8": { + "files": [ + { + "type": "flash-wipe", + "name": "Ultra-TDisplayPro-ESPNOW-UKStore-v6.8-merged.bin", + "title": "Combined app+partition+bootloader firmware bin" + }, + { + "type": "flash-update", + "name": "Ultra-TDisplayPro-ESPNOW-UKStore-v6.8.bin", + "title": "App firmware bin (use with m5 booloader)" + } + ], + "notes": "* Repeater & Room UI redesign\n* Room, admin CLI now from menu" + } + } + } + ] + }, + { + "maker": "seeed", + "class": "ripple", + "name": "Seeed Studio Wio Tracker L1 Pro", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "WioTrackerL1_QSPIFlash_Format-v1.2.zip", + "firmware": [ + { + "role": "gui", + "version": { + "v7.14": { + "files": [ + { + "type": "download", + "name": "Ultra-WioTrackerL1-v7.14.uf2", + "title": "UF2 file for manual USB DFU mass storage update" + }, + { + "type": "flash-update", + "name": "Ultra-WioTrackerL1-v7.14.zip", + "title": "App firmware" + } + ], + "notes": "* NEW: 'Scan Local' menu in Discover\n* Message text: now converts accented chars to ASCII equivalent\n* Popular emojis now converted, eg ':thumbsup'\n* Contacts can be tagged and custom notes added\n* Repeater CLI, 'neighbors' command now using binary req/resp\n* Max group channels now upped to 6\n* Bug fix: some CLI responses were lost from dup timestamp.\n* #channel key calc now forces lowercase\n* Better canned messages for CLI screens\n* Group channel message, 'Reply To' menu\n* Kid Mode: now supports up to 1 group channel chat" + }, + "v7.12.1": { + "files": [ + { + "type": "download", + "name": "Ultra-WioTrackerL1-v7.12.1.uf2", + "title": "UF2 file for manual USB DFU mass storage update" + }, + { + "type": "flash-update", + "name": "Ultra-WioTrackerL1-v7.12.1.zip", + "title": "App firmware" + } + ], + "notes": "* Battery scale fix\n* UI style updates\n* Remote admin prefixes, extra spaces allowed\n* Presets updated\n* Msg details: ‘heard by’\n* Repeater and room CLI: “get” command (get full telemetry)\n* Channel details: Alerts ON/OFF menu" + }, + "v7.12": { + "files": [ + { + "type": "download", + "name": "Ultra-WioTrackerL1-v7.12.uf2", + "title": "UF2 file for manual USB DFU mass storage update" + }, + { + "type": "flash-update", + "name": "Ultra-WioTrackerL1-v7.12.zip", + "title": "App firmware" + } + ], + "notes": "* Fixed PIN unlock screen\n* Added kid mode support\n* Repeater and Room CLI: new \"get\" command for full telemetry fetch" + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "community", + "name": "LilyGo T3 S3 (SX126x)", + "group": "LilyGo T3 S3", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "LilyGo_T3S3_sx1262_companion_radio_ble.*?-merged\\.bin", + "flash-update": "LilyGo_T3S3_sx1262_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "LilyGo_T3S3_sx1262_companion_radio_usb.*?-merged\\.bin", + "flash-update": "LilyGo_T3S3_sx1262_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "LilyGo_T3S3_sx1262_[rR]epeater.*?-merged\\.bin", + "flash-update": "LilyGo_T3S3_sx1262_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "LilyGo_T3S3_sx1262_room_server.*?-merged\\.bin", + "flash-update": "LilyGo_T3S3_sx1262_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "community", + "name": "LilyGo T3 S3 (SX127x)", + "group": "LilyGo T3 S3", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "LilyGo_T3S3_sx1276_companion_radio_ble.*?-merged\\.bin", + "flash-update": "LilyGo_T3S3_sx1276_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "LilyGo_T3S3_sx1276_companion_radio_usb.*?-merged\\.bin", + "flash-update": "LilyGo_T3S3_sx1276_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "LilyGo_T3S3_sx1276_[rR]epeater.*?-merged\\.bin", + "flash-update": "LilyGo_T3S3_sx1276_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "LilyGo_T3S3_sx1276_room_server.*?-merged\\.bin", + "flash-update": "LilyGo_T3S3_sx1276_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "community", + "name": "LilyGo T-Beam (SX1262)", + "group": "LilyGo T-Beam", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Tbeam_SX1262_companion_radio_ble.*?-merged\\.bin", + "flash-update": "Tbeam_SX1262_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Tbeam_SX1262_companion_radio_usb.*?-merged\\.bin", + "flash-update": "Tbeam_SX1262_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "Tbeam_SX1262_[rR]epeater.*?-merged\\.bin", + "flash-update": "Tbeam_SX1262_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "Tbeam_SX1262_room_server.*?-merged\\.bin", + "flash-update": "Tbeam_SX1262_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "community", + "name": "LilyGo T-Beam 1.2 (SX1276)", + "group": "LilyGo T-Beam", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Tbeam(_SX1276)?_companion_radio_ble.*?-merged\\.bin", + "flash-update": "Tbeam(_SX1276)?_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + + "flash-wipe": "Tbeam(_SX1276)?_companion_radio_usb.*?-merged\\.bin", + "flash-update": "Tbeam(_SX1276)?_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "Tbeam(_SX1276)?_[rR]epeater.*?-merged\\.bin", + "flash-update": "Tbeam(_SX1276)?_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "Tbeam(_SX1276)?_room_server.*?-merged\\.bin", + "flash-update": "Tbeam(_SX1276)?_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "community", + "name": "LilyGo T-Beam Supreme (SX1262)", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "T_Beam_S3_Supreme_SX1262_companion_radio_ble.*?-merged\\.bin", + "flash-update": "T_Beam_S3_Supreme_SX1262_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "T_Beam_S3_Supreme_SX1262_companion_radio_usb.*?-merged\\.bin", + "flash-update": "T_Beam_S3_Supreme_SX1262_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "T_Beam_S3_Supreme_SX1262_[rR]epeater.*?-merged\\.bin", + "flash-update": "T_Beam_S3_Supreme_SX1262_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "T_Beam_S3_Supreme_SX1262_room_server.*?-merged\\.bin", + "flash-update": "T_Beam_S3_Supreme_SX1262_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "community", + "name": "LilyGo T-Deck (community)", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "LilyGo_TDeck_companion_radio_ble.*?-merged\\.bin", + "flash-update": "LilyGo_TDeck_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "LilyGo_TDeck_companion_radio_usb.*?-merged\\.bin", + "flash-update": "LilyGo_TDeck_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "LilyGo_TDeck_[rR]epeater.*?-merged\\.bin", + "flash-update": "LilyGo_TDeck_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "LilyGo_TDeck_room_server.*?-merged\\.bin", + "flash-update": "LilyGo_TDeck_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "community", + "name": "LilyGo T-Echo", + "icon": "/img/lora.svg", + "type": "nrf52", + "erase": "LilyGo_T-Echo_QSPIFlash_Format-v1.2.zip", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "LilyGo_T-Echo_companion_radio_ble.*?\\.zip", + "download": "LilyGo_T-Echo_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "LilyGo_T-Echo_companion_radio_usb.*?\\.zip", + "download": "LilyGo_T-Echo_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "LilyGo_T-Echo_[rR]epeater.*?\\.zip", + "download": "LilyGo_T-Echo_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "LilyGo_T-Echo_room_server.*?\\.zip", + "download": "LilyGo_T-Echo_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "community", + "name": "LilyGo T-Echo Lite", + "icon": "/img/lora.svg", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v6.zip", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "LilyGo_T-Echo-Lite_companion_radio_ble.*?\\.zip", + "download": "LilyGo_T-Echo-Lite_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "LilyGo_T-Echo-Lite_companion_radio_usb.*?\\.zip", + "download": "LilyGo_T-Echo-Lite_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "LilyGo_T-Echo-Lite_[rR]epeater.*?\\.zip", + "download": "LilyGo_T-Echo-Lite_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "LilyGo_T-Echo-Lite_room_server.*?\\.zip", + "download": "LilyGo_T-Echo-Lite_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "lilygo", + "class": "community", + "name": "LilyGo LoRa32 V2.1_1.6", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "LilyGo_TLora_V2_1_1_6_companion_radio_ble.*?-merged\\.bin", + "flash-update": "LilyGo_TLora_V2_1_1_6_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "LilyGo_TLora_V2_1_1_6_companion_radio_usb.*?-merged\\.bin", + "flash-update": "LilyGo_TLora_V2_1_1_6_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "LilyGo_TLora_V2_1_1_6_[rR]epeater.*?-merged\\.bin", + "flash-update": "LilyGo_TLora_V2_1_1_6_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "LilyGo_TLora_V2_1_1_6_room_server.*?-merged\\.bin", + "flash-update": "LilyGo_TLora_V2_1_1_6_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "heltec", + "class": "community", + "name": "Heltec v2", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Heltec_v2_companion_radio_ble.*?-merged\\.bin", + "flash-update": "Heltec_v2_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Heltec_v2_companion_radio_usb.*?-merged\\.bin", + "flash-update": "Heltec_v2_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "Heltec_v2_[rR]epeater.*?-merged\\.bin", + "flash-update": "Heltec_v2_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "Heltec_v2_room_server.*?-merged\\.bin", + "flash-update": "Heltec_v2_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "heltec", + "class": "community", + "name": "Heltec v3", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Heltec_v3_companion_radio_ble.*?-merged\\.bin", + "flash-update": "Heltec_v3_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Heltec_v3_companion_radio_usb.*?-merged\\.bin", + "flash-update": "Heltec_v3_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "Heltec_v3_[rR]epeater.*?-merged\\.bin", + "flash-update": "Heltec_v3_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "Heltec_v3_room_server.*?-merged\\.bin", + "flash-update": "Heltec_v3_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "heltec", + "class": "community", + "name": "Heltec v4", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "heltec_v4_companion_radio_ble.*?-merged\\.bin", + "flash-update": "heltec_v4_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "heltec_v4_companion_radio_usb.*?-merged\\.bin", + "flash-update": "heltec_v4_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "heltec_v4_[rR]epeater.*?-merged\\.bin", + "flash-update": "heltec_v4_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "heltec_v4_room_server.*?-merged\\.bin", + "flash-update": "heltec_v4_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "heltec", + "class": "community", + "name": "Heltec T114", + "icon": "/img/lora.svg", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v6.zip", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "Heltec_t114_companion_radio_ble.*?\\.zip", + "download": "Heltec_t114_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "Heltec_t114_companion_radio_usb.*?\\.zip", + "download": "Heltec_t114_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "companionBle", + "title": "Companion", + "subTitle": "Bluetooth [no display]", + "github": { + "type": "companion", + "files": { + "flash": "Heltec_t114_without_display_companion_radio_ble.*?\\.zip", + "download": "Heltec_t114_without_display_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "Heltec_t114_[rR]epeater.*?\\.zip", + "download": "Heltec_t114_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "Heltec_t114_room_server.*?\\.zip", + "download": "Heltec_t114_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "heltec", + "class": "community", + "name": "Heltec MeshPocket", + "icon": "/img/lora.svg", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v6.zip", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "Mesh_pocket_companion_radio_ble.*?\\.zip", + "download": "Mesh_pocket_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "Mesh_pocket_companion_radio_usb.*?\\.zip", + "download": "Mesh_pocket_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "Mesh_pocket_[rR]epeater.*?\\.zip", + "download": "Mesh_pocket_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "Mesh_pocket_room_server.*?\\.zip", + "download": "Mesh_pocket_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "heltec", + "class": "community", + "name": "Heltec MeshSolar / MeshTower", + "icon": "/img/lora.svg", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v6.zip", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "Heltec_mesh_solar_companion_radio_ble.*?\\.zip", + "download": "Heltec_mesh_solar_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "Heltec_mesh_solar_companion_radio_usb.*?\\.zip", + "download": "Heltec_mesh_solar_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "Heltec_mesh_solar_[rR]epeater.*?\\.zip", + "download": "Heltec_mesh_solar_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "Heltec_mesh_solar_room_server.*?\\.zip", + "download": "Heltec_mesh_solar_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "heltec", + "class": "community", + "name": "Heltec Wireless Tracker", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Heltec_Wireless_Tracker_companion_radio_ble.*?-merged\\.bin", + "flash-update": "Heltec_Wireless_Tracker_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Heltec_Wireless_Tracker_companion_radio_usb.*?-merged\\.bin", + "flash-update": "Heltec_Wireless_Tracker_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "Heltec_Wireless_Tracker_[rR]epeater.*?-merged\\.bin", + "flash-update": "Heltec_Wireless_Tracker_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "Heltec_Wireless_Tracker_room_server.*?-merged\\.bin", + "flash-update": "Heltec_Wireless_Tracker_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "heltec", + "class": "community", + "name": "Heltec Heltec Wireless Paper", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Heltec_Wireless_Paper_companion_radio_ble.*?-merged\\.bin", + "flash-update": "Heltec_Wireless_Paper_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Heltec_Wireless_Paper_companion_radio_usb.*?-merged\\.bin", + "flash-update": "Heltec_Wireless_Paper_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "Heltec_Wireless_Paper_[rR]epeater.*?-merged\\.bin", + "flash-update": "Heltec_Wireless_Paper_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "Heltec_Wireless_Paper_room_server.*?-merged\\.bin", + "flash-update": "Heltec_Wireless_Paper_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "heltec", + "class": "community", + "name": "Heltec WSL3", + "icon": "/img/lora.svg", + "type": "esp32", + "tooltip": "", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Heltec_WSL3_companion_radio_ble.*?-merged\\.bin", + "flash-update": "Heltec_WSL3_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Heltec_WSL3_companion_radio_usb.*?-merged\\.bin", + "flash-update": "Heltec_WSL3_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "Heltec_WSL3_[rR]epeater.*?-merged\\.bin", + "flash-update": "Heltec_WSL3_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "Heltec_WSL3_room_server.*?-merged\\.bin", + "flash-update": "Heltec_WSL3_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "Ikoka", + "class": "community", + "name": "Ikoka Stick", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v7.zip", + "firmware": [ + { + "role": "companionBle", + "title": "Companion radio - 22dBm", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_stick_nrf_22dbm_companion_radio_ble.*?\\.zip", + "download": "ikoka_stick_nrf_22dbm_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "title": "Companion radio - 22dBm", + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_stick_nrf_22dbm_companion_radio_usb.*?\\.zip", + "download": "ikoka_stick_nrf_22dbm_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "title": "Repeater - 22dBm", + "github": { + "type": "repeater", + "files": { + "flash": "ikoka_stick_nrf_22dbm_[Rr]epeater.*?\\.zip", + "download": "ikoka_stick_nrf_22dbm_[Rr]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "title": "Room Server - 22dBm", + "github": { + "type": "room-server", + "files": { + "flash": "ikoka_stick_nrf_22dbm_room_server.*?\\.zip", + "download": "ikoka_stick_nrf_22dbm_room_server.*?\\.uf2" + } + } + }, + { + "role": "companionBle", + "title": "Companion radio - 30dBm", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_stick_nrf_30dbm_companion_radio_ble.*?\\.zip", + "download": "ikoka_stick_nrf_30dbm_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "title": "Companion radio - 30dBm", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_stick_nrf_30dbm_companion_radio_usb.*?\\.zip", + "download": "ikoka_stick_nrf_30dbm_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "title": "Repeater - 30dBm", + "github": { + "type": "repeater", + "files": { + "flash": "ikoka_stick_nrf_30dbm_[Rr]epeater.*?\\.zip", + "download": "ikoka_stick_nrf_30dbm_[Rr]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "title": "Room Server - 30dBm", + "github": { + "type": "room-server", + "files": { + "flash": "ikoka_stick_nrf_30dbm_room_server.*?\\.zip", + "download": "ikoka_stick_nrf_30dbm_room_server.*?\\.uf2" + } + } + }, + { + "role": "companionBle", + "title": "Companion radio - 33dBm", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_stick_nrf_33dbm_companion_radio_ble.*?\\.zip", + "download": "ikoka_stick_nrf_33dbm_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "title": "Companion radio - 33dBm", + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_stick_nrf_33dbm_companion_radio_usb.*?\\.zip", + "download": "ikoka_stick_nrf_33dbm_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "title": "Repeater - 33dBm", + "github": { + "type": "repeater", + "files": { + "flash": "ikoka_stick_nrf_33dbm_[Rr]epeater.*?\\.zip", + "download": "ikoka_stick_nrf_33dbm_[Rr]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "title": "Room Server - 33dBm", + "github": { + "type": "room-server", + "files": { + "flash": "ikoka_stick_nrf_33dbm_room_server.*?\\.zip", + "download": "ikoka_stick_nrf_33dbm_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "Ikoka", + "class": "community", + "name": "Ikoka Nano", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v7.zip", + "firmware": [ + { + "role": "companionBle", + "title": "Companion radio - 22dBm", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_nano_nrf_22dbm_companion_radio_ble.*?\\.zip", + "download": "ikoka_nano_nrf_22dbm_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "title": "Companion radio - 22dBm", + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_nano_nrf_22dbm_companion_radio_usb.*?\\.zip", + "download": "ikoka_nano_nrf_22dbm_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "title": "Repeater - 22dBm", + "github": { + "type": "repeater", + "files": { + "flash": "ikoka_nano_nrf_22dbm_[Rr]epeater.*?\\.zip", + "download": "ikoka_nano_nrf_22dbm_[Rr]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "title": "Room Server - 22dBm", + "github": { + "type": "room-server", + "files": { + "flash": "ikoka_nano_nrf_22dbm_room_server.*?\\.zip", + "download": "ikoka_nano_nrf_22dbm_room_server.*?\\.uf2" + } + } + }, + { + "role": "companionBle", + "title": "Companion radio - 30dBm", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_nano_nrf_30dbm_companion_radio_ble.*?\\.zip", + "download": "ikoka_nano_nrf_30dbm_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "title": "Companion radio - 30dBm", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_nano_nrf_30dbm_companion_radio_usb.*?\\.zip", + "download": "ikoka_nano_nrf_30dbm_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "title": "Repeater - 30dBm", + "github": { + "type": "repeater", + "files": { + "flash": "ikoka_nano_nrf_30dbm_[Rr]epeater.*?\\.zip", + "download": "ikoka_nano_nrf_30dbm_[Rr]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "title": "Room Server - 30dBm", + "github": { + "type": "room-server", + "files": { + "flash": "ikoka_nano_nrf_30dbm_room_server.*?\\.zip", + "download": "ikoka_nano_nrf_30dbm_room_server.*?\\.uf2" + } + } + }, + { + "role": "companionBle", + "title": "Companion radio - 33dBm", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_nano_nrf_33dbm_companion_radio_ble.*?\\.zip", + "download": "ikoka_nano_nrf_33dbm_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "title": "Companion radio - 33dBm", + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "ikoka_nano_nrf_33dbm_companion_radio_usb.*?\\.zip", + "download": "ikoka_nano_nrf_33dbm_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "title": "Repeater - 33dBm", + "github": { + "type": "repeater", + "files": { + "flash": "ikoka_nano_nrf_33dbm_[Rr]epeater.*?\\.zip", + "download": "ikoka_nano_nrf_33dbm_[Rr]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "title": "Room Server - 33dBm", + "github": { + "type": "room-server", + "files": { + "flash": "ikoka_nano_nrf_33dbm_room_server.*?\\.zip", + "download": "ikoka_nano_nrf_33dbm_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "keepteen", + "class": "community", + "name": "Keepteen LT1", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v6.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "KeepteenLT1_companion_radio_ble.*?\\.zip", + "download": "KeepteenLT1_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "KeepteenLT1_companion_radio_usb.*?\\.zip", + "download": "KeepteenLT1_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "KeepteenLT1_[rR]epeater.*?\\.zip", + "download": "KeepteenLT1_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "KeepteenLT1_room_server.*?\\.zip", + "download": "KeepteenLT1_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "rak", + "class": "community", + "name": "RAK Wireless WisBlock / WisMesh (RAK 4631)", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v6.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "RAK_4631_companion_radio_ble.*?\\.zip", + "download": "RAK_4631_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "RAK_4631_companion_radio_usb.*?\\.zip", + "download": "RAK_4631_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "RAK_4631_[rR]epeater.*?\\.zip", + "download": "RAK_4631_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "RAK_4631_room_server.*?\\.zip", + "download": "RAK_4631_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "rak", + "class": "community", + "name": "RAK WisMesh Tag", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v6.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "RAK_WisMesh_Tag_companion_radio_ble.*?\\.zip", + "download": "RAK_WisMesh_Tag_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "RAK_WisMesh_Tag_companion_radio_usb.*?\\.zip", + "download": "RAK_WisMesh_Tag_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "RAK_WisMesh_Tag_[rR]epeater.*?\\.zip", + "download": "RAK_WisMesh_Tag_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "RAK_WisMesh_Tag_room_server.*?\\.zip", + "download": "RAK_WisMesh_Tag_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "seeed", + "class": "community", + "name": "Seeed Studio SenseCAP Solar", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v7.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "SenseCap_Solar_companion_radio_ble.*?\\.zip", + "download": "SenseCap_Solar_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "SenseCap_Solar_companion_radio_usb.*?\\.zip", + "download": "SenseCap_Solar_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "SenseCap_Solar_[rR]epeater.*?\\.zip", + "download": "SenseCap_Solar_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "SenseCap_Solar_room_server.*?\\.zip", + "download": "SenseCap_Solar_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "seeed", + "class": "community", + "name": "Seeed Studio SenseCAP T1000-E", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v7.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "t1000e_companion_radio_ble.*?\\.zip", + "download": "t1000e_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "t1000e_companion_radio_usb.*?\\.zip", + "download": "t1000e_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "t1000e_[rR]epeater.*?\\.zip", + "download": "t1000e_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "t1000e_room_server.*?\\.zip", + "download": "t1000e_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "seeed", + "class": "community", + "name": "Seeed Studio Wio Tracker L1 Pro", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "WioTrackerL1_QSPIFlash_Format-v1.2.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "WioTrackerL1_companion_radio_ble.*?\\.zip", + "download": "WioTrackerL1_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "WioTrackerL1_companion_radio_usb.*?\\.zip", + "download": "WioTrackerL1_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "WioTrackerL1_[rR]epeater.*?\\.zip", + "download": "WioTrackerL1_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "WioTrackerL1_room_server.*?\\.zip", + "download": "WioTrackerL1_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "seeed", + "class": "community", + "name": "Seeed Studio Wio Tracker L1 EINK", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "WioTrackerL1_QSPIFlash_Format-v1.2.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "WioTrackerL1Eink_companion_radio_ble.*?\\.zip", + "download": "WioTrackerL1Eink_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "WioTrackerL1Eink_companion_radio_usb.*?\\.zip", + "download": "WioTrackerL1Eink_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "WioTrackerL1Eink_[rR]epeater.*?\\.zip", + "download": "WioTrackerL1Eink_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "WioTrackerL1Eink_room_server.*?\\.zip", + "download": "WioTrackerL1Eink_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "seeed", + "class": "community", + "name": "Seeed Studio Xiao C3", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "esp32", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Xiao_C3_companion_radio_ble.*?-merged\\.bin", + "flash-update": "Xiao_C3_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Xiao_C3_companion_radio_usb.*?-merged\\.bin", + "flash-update": "Xiao_C3_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "subTitle": "(SX1262 version)", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "Xiao_C3_sx1262_[rR]epeater.*?-merged\\.bin", + "flash-update": "Xiao_C3_sx1262_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "subTitle": "(SX1268 version)", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "Xiao_C3_sx1268_[rR]epeater.*?-merged\\.bin", + "flash-update": "Xiao_C3_sx1268_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "seeed", + "class": "community", + "name": "Seeed Studio Xiao S3 WIO", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "esp32", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Xiao_S3_WIO_companion_radio_ble.*?-merged\\.bin", + "flash-update": "Xiao_S3_WIO_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Xiao_S3_WIO_companion_radio_usb.*?-merged\\.bin", + "flash-update": "Xiao_S3_WIO_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "Xiao_S3_WIO_[rR]epeater.*?-merged\\.bin", + "flash-update": "Xiao_S3_WIO_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "Xiao_S3_WIO_room_server.*?-merged\\.bin", + "flash-update": "Xiao_S3_WIO_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "seeed", + "class": "community", + "name": "Seeed Studio Xiao nRF52 WIO", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "Xiao_nrf52_QSPIFlash_Format-v1.2.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "Xiao_nrf52_companion_radio_ble.*?\\.zip", + "download": "Xiao_nrf52_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "Xiao_nrf52_companion_radio_usb.*?\\.zip", + "download": "Xiao_nrf52_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "Xiao_nrf52_[rR]epeater.*?\\.zip", + "download": "Xiao_nrf52_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "Xiao_nrf52_room_server.*?\\.zip", + "download": "Xiao_nrf52_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "elecrow", + "class": "community", + "name": "Elecrow ThinkNode M1", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "ThinkNode_M1_QSPIFlash_Format-v1.2.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "ThinkNode_M1_companion_radio_ble.*?\\.zip", + "download": "ThinkNode_M1_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "ThinkNode_M1_companion_radio_usb.*?\\.zip", + "download": "ThinkNode_M1_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "ThinkNode_M1_[rR]epeater.*?\\.zip", + "download": "ThinkNode_M1_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "ThinkNode_M1_room_server.*?\\.zip", + "download": "ThinkNode_M1_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "elecrow", + "class": "community", + "name": "Elecrow ThinkNode M2", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "esp32", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "ThinkNode_M2_companion_radio_ble.*?-merged\\.bin", + "flash-update": "ThinkNode_M2_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "ThinkNode_M2_companion_radio_usb.*?-merged\\.bin", + "flash-update": "ThinkNode_M2_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "ThinkNode_M2_repeater.*?-merged\\.bin", + "flash-update": "ThinkNode_M2_repeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "ThinkNode_M2_room_server.*?-merged\\.bin", + "flash-update": "ThinkNode_M2_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "elecrow", + "class": "community", + "name": "Elecrow ThinkNode M3", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v6.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "ThinkNode_M3_companion_radio_ble.*?\\.zip", + "download": "ThinkNode_M3_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "ThinkNode_M3_companion_radio_usb.*?\\.zip", + "download": "ThinkNode_M3_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "ThinkNode_M3_[rR]epeater.*?\\.zip", + "download": "ThinkNode_M3_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "ThinkNode_M3_room_server.*?\\.zip", + "download": "ThinkNode_M3_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "elecrow", + "class": "community", + "name": "Elecrow ThinkNode M5", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "esp32", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "ThinkNode_M5_companion_radio_ble.*?-merged\\.bin", + "flash-update": "ThinkNode_M5_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "ThinkNode_M5_companion_radio_usb.*?-merged\\.bin", + "flash-update": "ThinkNode_M5_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "ThinkNode_M5_repeater.*?-merged\\.bin", + "flash-update": "ThinkNode_M5_repeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "ThinkNode_M5_room_server.*?-merged\\.bin", + "flash-update": "ThinkNode_M5_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "elecrow", + "class": "community", + "name": "Elecrow ThinkNode M6", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v6.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "ThinkNode_M6_companion_radio_ble.*?\\.zip", + "download": "ThinkNode_M6_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "ThinkNode_M6_companion_radio_usb.*?\\.zip", + "download": "ThinkNode_M6_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "ThinkNode_M6_[rR]epeater.*?\\.zip", + "download": "ThinkNode_M6_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "ThinkNode_M6_room_server.*?\\.zip", + "download": "ThinkNode_M6_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "uniteng", + "class": "community", + "name": "UnitEng Station G2", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "esp32", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Station_G2_companion_radio_ble.*?-merged\\.bin", + "flash-update": "Station_G2_companion_radio_ble.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash-wipe": "Station_G2_companion_radio_usb.*?-merged\\.bin", + "flash-update": "Station_G2_companion_radio_usb.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash-wipe": "Station_G2_[rR]epeater.*?-merged\\.bin", + "flash-update": "Station_G2_[rR]epeater.*?-[a-f0-9]{7}\\.bin" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash-wipe": "Station_G2_room_server.*?-merged\\.bin", + "flash-update": "Station_G2_room_server.*?-[a-f0-9]{7}\\.bin" + } + } + } + ] + }, + { + "maker": "uniteng", + "class": "community", + "name": "UnitEng Nano G2 Ultra", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "Nano_G2_Ultra_QSPIFlash_Format-v1.2.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "Nano_G2_Ultra_companion_radio_ble.*?\\.zip", + "download": "Nano_G2_Ultra_companion_radio_ble.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "promicro", + "class": "community", + "name": "ProMicro nrf52 (faketec)", + "icon": "/img/lora.svg", + "tooltip": "", + "type": "nrf52", + "erase": "FLASH_ERASE_nrf52_softdevice_v6.zip", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "flash": "(?:ProMicro|Faketec)_companion_radio_ble.*?\\.zip", + "download": "(?:ProMicro|Faketec)_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "flash": "(?:ProMicro|Faketec)_companion_radio_usb.*?\\.zip", + "download": "(?:ProMicro|Faketec)_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "flash": "(?:ProMicro|Faketec)_[rR]epeater.*?\\.zip", + "download": "(?:ProMicro|Faketec)_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "flash": "(?:ProMicro|Faketec)_room_server.*?\\.zip", + "download": "(?:ProMicro|Faketec)_room_server.*?\\.uf2" + } + } + } + ] + }, + { + "maker": "raspberry", + "class": "community", + "name": "Raspberry Pi Pico RP2040 + WaveShare SX1262", + "icon": "/img/lora.svg", + "type": "noflash", + "tooltip":"", + "firmware": [ + { + "role": "companionBle", + "github": { + "type": "companion", + "files": { + "download": "PicoW_companion_radio_ble.*?\\.uf2" + } + } + }, + { + "role": "companionUsb", + "github": { + "type": "companion", + "files": { + "download": "PicoW_companion_radio_usb.*?\\.uf2" + } + } + }, + { + "role": "repeater", + "github": { + "type": "repeater", + "files": { + "download": "PicoW_[rR]epeater.*?\\.uf2" + } + } + }, + { + "role": "roomServer", + "github": { + "type": "room-server", + "files": { + "download": "PicoW_room_server.*?\\.uf2" + } + } + } + ] + } + ] } \ No newline at end of file diff --git a/css/flasher.css b/css/flasher.css index f88e525..48c0d90 100644 --- a/css/flasher.css +++ b/css/flasher.css @@ -7,14 +7,59 @@ body { height: 100vh; } +body:has([v-cloak]):after { + content: ''; + position: absolute; + top: calc(50% - 50px); + left: calc(50% - 50px); + width: 50px; + aspect-ratio: 1; + border-radius: 50%; + border: 8px solid #f0f0f0; + animation: + l20-1 0.8s infinite linear alternate, + l20-2 1.6s infinite linear; +} +@keyframes l20-1{ + 0% {clip-path: polygon(50% 50%,0 0, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0% )} + 12.5% {clip-path: polygon(50% 50%,0 0, 50% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0% )} + 25% {clip-path: polygon(50% 50%,0 0, 50% 0%, 100% 0%, 100% 100%, 100% 100%, 100% 100% )} + 50% {clip-path: polygon(50% 50%,0 0, 50% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100% )} + 62.5% {clip-path: polygon(50% 50%,100% 0, 100% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100% )} + 75% {clip-path: polygon(50% 50%,100% 100%, 100% 100%, 100% 100%, 100% 100%, 50% 100%, 0% 100% )} + 100% {clip-path: polygon(50% 50%,50% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 0% 100% )} +} +@keyframes l20-2{ + 0% {transform:scaleY(1) rotate(0deg)} + 49.99%{transform:scaleY(1) rotate(135deg)} + 50% {transform:scaleY(-1) rotate(0deg)} + 100% {transform:scaleY(-1) rotate(-135deg)} +} + #app { flex-grow: 1; } + +#app h5.logo-top img { + height: 16px; + margin-top: -4px; +} + +#app h5.logo-top span { + font-style: italic; font-weight: bold; line-height: 0.9 +} + #app select { cursor: pointer } +#app .tooltip:has(>.device) { + background: #f0f0f055; + width: auto; +} #app img.device { - width: 300px; + width: 400px; + max-width: 400px; + max-height: 400px; } #app div.autoscroller { overflow: auto; @@ -62,4 +107,23 @@ body { } #app .version div.field { min-width: 140px; + align-self: flex-start; +} +#app .version .pre { + padding-bottom: 10px; +} +#app img.icon { + height: 20px; +} + +.flash-container { + padding-bottom: 150px; +} + +.strong { + font-weight: 700; +} + +.text-wrap { + text-wrap: auto; } \ No newline at end of file diff --git a/flasher.js b/flasher.js index 65e3698..7361a55 100644 --- a/flasher.js +++ b/flasher.js @@ -41,6 +41,10 @@ const commandReference = { 'get lon': 'Get the advertisement map longitude', }; +async function delay(milis) { + return await new Promise((resolve) => setTimeout(resolve, milis)); +} + function getGithubReleases(roleType, files) { const versions = {}; for(const [fileType, matchRE] of Object.entries(files)) { @@ -78,25 +82,62 @@ function addGithubFiles() { } } + config.device = config.device.filter(device => device.firmware.some(firmware => Object.keys(firmware.version).length > 0 )); + return config; } +async function digestMessage(message) { + const msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array + const hashBuffer = await window.crypto.subtle.digest("SHA-256", msgUint8); // hash the message + const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array + + const hashHex = hashArray + .map((b) => b.toString(16).padStart(2, "0")) + .join(""); // convert bytes to hex string + + return hashHex; +} + +async function blobToBinaryString(blob) { + const bytes = new Uint8Array(await blob.arrayBuffer()) + let binString = ''; + + for (let i = 0; i < bytes.length; i++) { + binString += String.fromCharCode(bytes[i]); + } + + return binString; +} + console.log(addGithubFiles()); function setup() { const consoleEditBox = ref(); const consoleWindow = ref(); + const deviceFilterText = ref(''); + + const snackbar = reactive({ + text: '', + class: '', + icon: '', + }); + const selected = reactive({ device: null, firmware: null, version: null, wipe: false, + nrfEraserFlashingPercent: 0, + nrfEraserFlashing: false, port: null, }); const getRoleFwValue = (firmware, key) => { - return firmware[key] || config.role[firmware.role][key] || ''; + const role = config.role[firmware.role] ?? {}; + + return firmware[key] ?? role[key] ?? ''; } const getSelFwValue = (key) => { @@ -108,8 +149,8 @@ function setup() { const flashing = reactive({ supported: 'Serial' in window, instance: null, - active: false, - percentage: 0, + locked: false, + percent: 0, log: '', error: '', dfuComplete: false, @@ -130,8 +171,20 @@ function setup() { writeLine(data) { flashing.log += data + '\n' } }; - const refresh = () => { - location.reload(); + const retry = async() => { + flashing.active = false; + flashing.log = ''; + flashing.error = ''; + flashing.dfuComplete = false; + flashing.percent = 0; + if(flashing.instance instanceof ESPLoader) { + await flashing.instance?.hr.reset(); + await flashing.instance?.transport?.disconnect(); + } + } + + const close = () => { + location.reload() } const getFirmwarePath = (file) => { @@ -172,15 +225,25 @@ function setup() { flashing.log = ''; flashing.error = ''; flashing.dfuComplete = false; - flashing.percentage = 0; + flashing.percent = 0; selected.firmware = null; selected.version = null; selected.wipe = false; selected.device = null; + selected.nrfEraserFlashingPercent = 0; + selected.nrfEraserFlashing = false; if(flashing.instance instanceof ESPLoader) { await flashing.instance?.hr.reset(); await flashing.instance?.transport?.disconnect(); } + else if(flashing.instance instanceof Dfu) { + try { + flashing.instance.port.close() + } + catch(e) { + console.error(e); + } + } flashing.instance = null; } @@ -191,12 +254,12 @@ function setup() { const openSerialCon = async() => { const port = selected.port = await navigator.serial.requestPort(); const serialConsole = serialCon.instance = new SerialConsole(port); - serialCon.content = 'Welcome to MeshCore serial console.\n' - serialCon.content += '-------------------------------------------------------------------------\n'; - serialCon.content += 'WARNING: This console only works with *Repeater* and *Room server* roles.\n'; - serialCon.content += '-------------------------------------------------------------------------\n'; - serialCon.content += 'If you came here right after flashing, please restart your device.\n'; - serialCon.content += 'Click on the cursor to get all supported commands.\n\n'; + + serialCon.content = '-------------------------------------------------------------------------\n'; + serialCon.content += 'Welcome to MeshCore serial console.\n' + serialCon.content += 'Click on the cursor to get all supported commands.\n'; + serialCon.content += '-------------------------------------------------------------------------\n\n'; + serialConsole.onOutput = (text) => { serialCon.content += text; }; @@ -227,10 +290,19 @@ function setup() { const customFirmwareLoad = async(ev) => { const firmwareFile = ev.target.files[0]; const type = firmwareFile.name.endsWith('.bin') ? 'esp32' : 'nrf52'; - selected.device = { + selected.device = { name: 'Custom device', type, }; + if(firmwareFile.name.endsWith('-merged.bin')) { + alert( + 'You selected custom file that ends with "merged.bin".'+ + 'This will erase your flash! Proceed with caution.'+ + 'If you want just to update your firmware, please use non-merged bin.' + ); + + selected.wipe = true; + } selected.firmware = { icon: 'unknown_document', @@ -244,55 +316,100 @@ function setup() { } } + const espReset = async(t) => { + await t.setRTS(true); + await delay(100) + await t.setRTS(false); + } + + const nrfErase = async() => { + if(!(selected.device.type === 'nrf52' && selected.device.erase)) { + console.error('nRF erase called for non-nrf device or device.erase is not defined') + return; + } + + const url = `${config.staticPath}/${selected.device.erase}`; + + console.log('downloading: ' + url); + const resp = await fetch(url); + if(resp.status !== 200) { + alert(`Could not download the firmware file from the server, reported: HTTP ${resp.status}.\nPlease try again.`) + return; + } + const flashData = await resp.blob(); + + const port = selected.port = await navigator.serial.requestPort({}); + const dfu = new Dfu(port); + + try { + selected.nrfEraserFlashing = true; + await dfu.dfuUpdate(flashData, async (progress) => { + selected.nrfEraserFlashingPercent = progress; + if(progress === 100 && selected.nrfEraserFlashing) { + selected.nrfEraserFlashing = false; + selected.dfuComplete = false; + setTimeout(() => { + alert('Device erase firmware has been flashed and flash has been erased.\nYou can flash MeshCore now.'); + }, 200); + } + }, 60000); + + } + catch(e) { + alert(`nRF flashing erase firmware failed: ${e}.\nDid you put the device into DFU mode before attempting erasing?`); + selected.nrfEraserFlashing = false; + selected.nrfEraserFlashingPercent = 0; + return; + } + } + + const canFlash = (device) => { + return device.type !== 'noflash' + } + const flashDevice = async() => { const device = selected.device; const firmware = selected.firmware.version[selected.version]; - let flashFile; - flashFile = firmware.files.find(f => f.type === 'flash'); - if(!flashFile) { + const flashFiles = firmware.files.filter(f => f.type.startsWith('flash')); + if(!flashFiles[0]) { alert('Cannot find configuration for flash file! please report this to Discord.') flasherCleanup(); return; } - console.log({flashFile, instanceFile: flashFile instanceof File}); + console.log({flashFiles}); - if(flashFile.file) { - flashFile = flashFile.file; + let flashData; + if(flashFiles[0].file) { + flashData = flashFiles[0].file; } else { + let flashFile; + if(device.type === 'esp32') { + flashFile = flashFiles.find(f => f.type === (selected.wipe ? 'flash-wipe' : 'flash-update')); + } + else { + flashFile = flashFiles[0]; + } + console.log({flashFiles, flashFile}); + const url = getFirmwarePath(flashFile); console.log('downloading: ' + url); const resp = await fetch(url); - flashFile = await resp.blob(); + if(resp.status !== 200) { + alert(`Could not download the firmware file from the server, reported: HTTP ${resp.status}.\nPlease try again.`) + return; + } + + flashData = await resp.blob(); } const port = selected.port = await navigator.serial.requestPort({}); if(device.type === 'esp32') { let esploader; - let fileData; let transport; - try { - const reader = new FileReader(); - fileData = await new Promise((resolve, reject) => { - reader.addEventListener('error', () => { - reader.abort(); - reject(new DOMException('Problem parsing input file.')); - }); - - reader.addEventListener('load', () => resolve(reader.result)); - - reader.readAsBinaryString(flashFile); - }); - } - catch(e) { - console.error(e); - flashing.error = `Cannot read flash file: ${e}`; - return; - } - const flashOptions = { terminal: log, compress: true, @@ -304,18 +421,18 @@ function setup() { romBaudrate: 115200, enableTracing: false, fileArray: [{ - data: fileData, - address: 0 + data: await blobToBinaryString(flashData), + address: selected.wipe ? 0x00000 : 0x10000 }], reportProgress: async (_, written, total) => { - flashing.percentage = (written / total) * 100; + flashing.percent = (written / total) * 100; }, }; try { flashing.active = true; transport = new Transport(port, true); - flashOptions.transport = transport + flashOptions.transport = transport; flashing.instance = esploader = new ESPLoader(flashOptions); esploader.hr = new HardReset(transport); await esploader.main(); @@ -330,44 +447,87 @@ function setup() { try { await esploader.writeFlash(flashOptions); - await esploader.after(); + await delay(100); + await esploader.after('hard_reset'); + await delay(100); + await espReset(transport); + await transport.disconnect(); } catch(e) { console.error(e); flashing.error = `ESP32 flashing failed: ${e}`; - await esploader.hardReset(); + await espReset(transport); await transport.disconnect(); return; } } else if(device.type === 'nrf52') { - const dfu = flashing.instance = new Dfu(port, selected.wipe); + const dfu = flashing.instance = new Dfu(port); flashing.active = true; try { - await dfu.dfuUpdate(flashFile, async (progress) => { - flashing.percentage = progress; - }); + await dfu.dfuUpdate(flashData, async (progress) => { + flashing.percent = progress; + }, 60000); + } catch(e) { console.error(e); - flashing.error = `nRF flashing failed: ${e}`; + flashing.error = `nRF flashing failed: ${e}. Please reset the device and try again.`; return; } } }; + const devices = computed(() => { + const classSortPrefix = (d) => d.class === 'ripple' ? '1' : '2'; + const deviceGroups = {}; + + for(const cls of ['ripple', 'community']) { + const devices = config.device.toSorted( + (a, b) => (classSortPrefix(a) + a.maker + a.name).localeCompare(classSortPrefix(b) + b.maker + b.name) + ).filter( + d => d.class === cls && (deviceFilterText.value == '' || d.name.toLowerCase().includes(deviceFilterText.value?.toLowerCase())) + ) + if(devices.length > 0) deviceGroups[cls] = devices; + } + + return deviceGroups; + }); + + const showMessage = (text, icon, displayMs) => { + snackbar.class = 'active'; + snackbar.text = text; + snackbar.icon = icon || ''; + + setTimeout(() => { + snackbar.icon = ''; + snackbar.text = ''; + snackbar.class = ''; + }, displayMs || 2000); + } + + const consoleMouseUp = (ev) => { + if(window.getSelection().toString().length) { + navigator.clipboard.writeText(window.getSelection().toString()) + showMessage('text copied to clipboard'); + } + consoleEditBox.value.focus(); + } + return { - consoleEditBox, consoleWindow, - config, selected, flashing, + snackbar, + consoleEditBox, consoleWindow, consoleMouseUp, + config, devices, selected, flashing, deviceFilterText, flashDevice, flasherCleanup, dfuMode, serialCon, closeSerialCon, openSerialCon, sendCommand, openSerialGUI, - refresh, commandReference, + retry, close, commandReference, stepBack, customFirmwareLoad, getFirmwarePath, getSelFwValue, getRoleFwValue, - firmwareHasData + firmwareHasData, + canFlash, nrfErase } } diff --git a/img/esp32.svg b/img/esp32.svg new file mode 100644 index 0000000..b5cc14a --- /dev/null +++ b/img/esp32.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/esp_now.svg b/img/esp_now.svg new file mode 100644 index 0000000..7e5b234 --- /dev/null +++ b/img/esp_now.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/img/faketec.svg b/img/faketec.svg new file mode 100644 index 0000000..3ee55f3 --- /dev/null +++ b/img/faketec.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/heltec_mesh_solar.svg b/img/heltec_mesh_solar.svg new file mode 100644 index 0000000..bbd203b --- /dev/null +++ b/img/heltec_mesh_solar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/heltec_meshpocket.svg b/img/heltec_meshpocket.svg new file mode 100644 index 0000000..4b2f259 --- /dev/null +++ b/img/heltec_meshpocket.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/heltec_paper.svg b/img/heltec_paper.svg new file mode 100644 index 0000000..4403e19 --- /dev/null +++ b/img/heltec_paper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/heltec_t114.png b/img/heltec_t114.png deleted file mode 100644 index aaa09b5..0000000 Binary files a/img/heltec_t114.png and /dev/null differ diff --git a/img/heltec_t114.svg b/img/heltec_t114.svg new file mode 100644 index 0000000..0c0cdc1 --- /dev/null +++ b/img/heltec_t114.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/heltec_v2.svg b/img/heltec_v2.svg new file mode 100644 index 0000000..a598b0f --- /dev/null +++ b/img/heltec_v2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/heltec_v3.png b/img/heltec_v3.png deleted file mode 100644 index 515de13..0000000 Binary files a/img/heltec_v3.png and /dev/null differ diff --git a/img/heltec_v3.svg b/img/heltec_v3.svg new file mode 100644 index 0000000..89470fb --- /dev/null +++ b/img/heltec_v3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/heltec_v4.svg b/img/heltec_v4.svg new file mode 100644 index 0000000..39a9991 --- /dev/null +++ b/img/heltec_v4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/heltec_wp.svg b/img/heltec_wp.svg new file mode 100644 index 0000000..4020b43 --- /dev/null +++ b/img/heltec_wp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/heltec_wsl3.png b/img/heltec_wsl3.png deleted file mode 100644 index 34c5c15..0000000 Binary files a/img/heltec_wsl3.png and /dev/null differ diff --git a/img/heltec_wsl3.svg b/img/heltec_wsl3.svg new file mode 100644 index 0000000..20ef8c8 --- /dev/null +++ b/img/heltec_wsl3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/heltec_wt3.svg b/img/heltec_wt3.svg new file mode 100644 index 0000000..26aeb6c --- /dev/null +++ b/img/heltec_wt3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/ikoka_nano.svg b/img/ikoka_nano.svg new file mode 100644 index 0000000..3f0bfc5 --- /dev/null +++ b/img/ikoka_nano.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/ikoka_stick.svg b/img/ikoka_stick.svg new file mode 100644 index 0000000..ea96c17 --- /dev/null +++ b/img/ikoka_stick.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/keepteen_lt1.svg b/img/keepteen_lt1.svg new file mode 100644 index 0000000..44addc8 --- /dev/null +++ b/img/keepteen_lt1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_pager.svg b/img/lilygo_pager.svg new file mode 100644 index 0000000..6c801b2 --- /dev/null +++ b/img/lilygo_pager.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_t3s3.png b/img/lilygo_t3s3.png deleted file mode 100644 index cf2f18d..0000000 Binary files a/img/lilygo_t3s3.png and /dev/null differ diff --git a/img/lilygo_t3s3.svg b/img/lilygo_t3s3.svg new file mode 100644 index 0000000..b130f93 --- /dev/null +++ b/img/lilygo_t3s3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_t5_pro.png b/img/lilygo_t5_pro.png deleted file mode 100644 index afa8409..0000000 Binary files a/img/lilygo_t5_pro.png and /dev/null differ diff --git a/img/lilygo_t5_pro.svg b/img/lilygo_t5_pro.svg new file mode 100644 index 0000000..df1f87c --- /dev/null +++ b/img/lilygo_t5_pro.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_tbeam.png b/img/lilygo_tbeam.png deleted file mode 100644 index fad7ad0..0000000 Binary files a/img/lilygo_tbeam.png and /dev/null differ diff --git a/img/lilygo_tbeam.svg b/img/lilygo_tbeam.svg new file mode 100644 index 0000000..aa8fa8b --- /dev/null +++ b/img/lilygo_tbeam.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_tbeam_supreme.png b/img/lilygo_tbeam_supreme.png deleted file mode 100644 index 35a024b..0000000 Binary files a/img/lilygo_tbeam_supreme.png and /dev/null differ diff --git a/img/lilygo_tbeam_supreme.svg b/img/lilygo_tbeam_supreme.svg new file mode 100644 index 0000000..5ad636a --- /dev/null +++ b/img/lilygo_tbeam_supreme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_tdeck.png b/img/lilygo_tdeck.png deleted file mode 100644 index d2e07d0..0000000 Binary files a/img/lilygo_tdeck.png and /dev/null differ diff --git a/img/lilygo_tdeck.svg b/img/lilygo_tdeck.svg new file mode 100644 index 0000000..46bb85b --- /dev/null +++ b/img/lilygo_tdeck.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_tdeck_pro.svg b/img/lilygo_tdeck_pro.svg new file mode 100644 index 0000000..ab34520 --- /dev/null +++ b/img/lilygo_tdeck_pro.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_tdisplay.svg b/img/lilygo_tdisplay.svg new file mode 100644 index 0000000..3b9bf5d --- /dev/null +++ b/img/lilygo_tdisplay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_techo.png b/img/lilygo_techo.png deleted file mode 100644 index 3ca6a1b..0000000 Binary files a/img/lilygo_techo.png and /dev/null differ diff --git a/img/lilygo_techo.svg b/img/lilygo_techo.svg new file mode 100644 index 0000000..b052e64 --- /dev/null +++ b/img/lilygo_techo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_techo_lite.svg b/img/lilygo_techo_lite.svg new file mode 100644 index 0000000..f55b7f2 --- /dev/null +++ b/img/lilygo_techo_lite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_tlora_1.6.svg b/img/lilygo_tlora_1.6.svg new file mode 100644 index 0000000..f7dc6d7 --- /dev/null +++ b/img/lilygo_tlora_1.6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lilygo_tlora_c6.svg b/img/lilygo_tlora_c6.svg new file mode 100644 index 0000000..89d7a23 --- /dev/null +++ b/img/lilygo_tlora_c6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/lora.svg b/img/lora.svg new file mode 100644 index 0000000..741433f --- /dev/null +++ b/img/lora.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/img/meshcore-logo.png b/img/meshcore-logo.png deleted file mode 100644 index 1ec8508..0000000 Binary files a/img/meshcore-logo.png and /dev/null differ diff --git a/img/meshcore.svg b/img/meshcore.svg new file mode 100644 index 0000000..eb1b7bc --- /dev/null +++ b/img/meshcore.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/img/nano_g2.svg b/img/nano_g2.svg new file mode 100644 index 0000000..1375236 --- /dev/null +++ b/img/nano_g2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/nrf52.svg b/img/nrf52.svg new file mode 100644 index 0000000..9d31219 --- /dev/null +++ b/img/nrf52.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/promicro_sx1262.png b/img/promicro_sx1262.png deleted file mode 100644 index d24947d..0000000 Binary files a/img/promicro_sx1262.png and /dev/null differ diff --git a/img/rak_11300.svg b/img/rak_11300.svg new file mode 100644 index 0000000..e06e038 --- /dev/null +++ b/img/rak_11300.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/rak_4631.png b/img/rak_4631.png deleted file mode 100644 index 7fe3b5e..0000000 Binary files a/img/rak_4631.png and /dev/null differ diff --git a/img/rak_4631.svg b/img/rak_4631.svg new file mode 100644 index 0000000..4ddef1b --- /dev/null +++ b/img/rak_4631.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/rak_wismesh_tag.svg b/img/rak_wismesh_tag.svg new file mode 100644 index 0000000..275b0a9 --- /dev/null +++ b/img/rak_wismesh_tag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/rpi.svg b/img/rpi.svg new file mode 100644 index 0000000..6b6c7f3 --- /dev/null +++ b/img/rpi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/rpi_picow.svg b/img/rpi_picow.svg new file mode 100644 index 0000000..c892a29 --- /dev/null +++ b/img/rpi_picow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/seeed_t1000e.png b/img/seeed_t1000e.png deleted file mode 100644 index 42fd034..0000000 Binary files a/img/seeed_t1000e.png and /dev/null differ diff --git a/img/sensecap_solar.svg b/img/sensecap_solar.svg new file mode 100644 index 0000000..d928218 --- /dev/null +++ b/img/sensecap_solar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/sensecap_t1000e.svg b/img/sensecap_t1000e.svg new file mode 100644 index 0000000..cf41e7f --- /dev/null +++ b/img/sensecap_t1000e.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/station_g2.png b/img/station_g2.png deleted file mode 100644 index c6fc51a..0000000 Binary files a/img/station_g2.png and /dev/null differ diff --git a/img/station_g2.svg b/img/station_g2.svg new file mode 100644 index 0000000..8a67dbf --- /dev/null +++ b/img/station_g2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/thinknode_m1.svg b/img/thinknode_m1.svg new file mode 100644 index 0000000..e4124fd --- /dev/null +++ b/img/thinknode_m1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/thinknode_m2.svg b/img/thinknode_m2.svg new file mode 100644 index 0000000..2635b30 --- /dev/null +++ b/img/thinknode_m2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/thinknode_m3.svg b/img/thinknode_m3.svg new file mode 100644 index 0000000..d652d40 --- /dev/null +++ b/img/thinknode_m3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/thinknode_m5.svg b/img/thinknode_m5.svg new file mode 100644 index 0000000..73b3a9d --- /dev/null +++ b/img/thinknode_m5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/thinknode_m6.svg b/img/thinknode_m6.svg new file mode 100644 index 0000000..2dcc666 --- /dev/null +++ b/img/thinknode_m6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/wio_tracker_l1.svg b/img/wio_tracker_l1.svg new file mode 100644 index 0000000..72179df --- /dev/null +++ b/img/wio_tracker_l1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/wio_tracker_l1_eink.svg b/img/wio_tracker_l1_eink.svg new file mode 100644 index 0000000..b711fdc --- /dev/null +++ b/img/wio_tracker_l1_eink.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/xiao_esp32c3.svg b/img/xiao_esp32c3.svg new file mode 100644 index 0000000..037d792 --- /dev/null +++ b/img/xiao_esp32c3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/xiao_esp32c6.svg b/img/xiao_esp32c6.svg new file mode 100644 index 0000000..f4e894d --- /dev/null +++ b/img/xiao_esp32c6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/xiao_esp32s3.svg b/img/xiao_esp32s3.svg new file mode 100644 index 0000000..e22a6c5 --- /dev/null +++ b/img/xiao_esp32s3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/xiao_nrf52.png b/img/xiao_nrf52.png deleted file mode 100644 index 91064da..0000000 Binary files a/img/xiao_nrf52.png and /dev/null differ diff --git a/img/xiao_nrf52.svg b/img/xiao_nrf52.svg new file mode 100644 index 0000000..5f8feb9 --- /dev/null +++ b/img/xiao_nrf52.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/xiao_s3.png b/img/xiao_s3.png deleted file mode 100644 index 3b4a08d..0000000 Binary files a/img/xiao_s3.png and /dev/null differ diff --git a/index.html b/index.html index cd90e9f..147447e 100644 --- a/index.html +++ b/index.html @@ -9,9 +9,14 @@ +
-
+
+ {{ snackbar.icon }} + +
+
@@ -27,31 +32,49 @@
Flashing failed!

{{ flashing.error }}

-

+
-
+
Flashing...

Please do not disconnect the device

Flashing complete!
-

- Before you use Repeater/Room server setup, please restart your device. -

-

- -

+
{{ flashing.log }}
@@ -62,9 +85,18 @@ developer_board {{ selected.device.name }} chevron_right - {{ getRoleFwValue(selected.firmware, 'icon') }} - {{ getRoleFwValue(selected.firmware, 'title') }} +
+
    +
  • + {{ getRoleFwValue(selected.firmware, 'icon') }}  +
    +
    {{ getRoleFwValue(selected.firmware, 'title') }} {{ getRoleFwValue(selected.firmware, 'subTitle') }}
    + {{ getRoleFwValue(selected.firmware, 'tooltip') }} +
    +
  • +
+
@@ -209,7 +296,7 @@
Serial Console
-
+      
         {{ serialCon.content }}
         
> @@ -217,8 +304,7 @@
- + - \ No newline at end of file diff --git a/lib/console.js b/lib/console.js index c590598..707b6bd 100644 --- a/lib/console.js +++ b/lib/console.js @@ -1,6 +1,7 @@ function delay(msecs) { return new Promise((resolve) => setTimeout(resolve, msecs)); } + class LineBreakTransformer { chunks = ''; port = null; diff --git a/lib/dfu.js b/lib/dfu.js index 09bc799..8b8ddce 100644 --- a/lib/dfu.js +++ b/lib/dfu.js @@ -80,7 +80,30 @@ function calcCrc16(data, crc = 0xFFFF) { } function sleep(milliseconds) { - return new Promise((resolve) => setTimeout(resolve, milliseconds)) + return new Promise((resolve) => { + const startTime = performance.now(); + const targetTime = startTime + milliseconds; + + function checkTime() { + if (performance.now() >= targetTime) { + resolve(); + } else { + requestAnimationFrame(checkTime); + } + } + + const initialDelay = Math.max(0, milliseconds - 16); // Wake up ~1 frame early to start polling + + if (initialDelay > 0) { + setTimeout(() => { + // Now start the more precise polling + checkTime(); + }, initialDelay); + } else { + // If the desired sleep is very short, go straight to polling + checkTime(); + } + }); } // --- HciPacket Class (adapted from dfu/dfu_transport_serial.py) --- @@ -128,6 +151,29 @@ export class Dfu { this.eraseBeforeUpdate = eraseBeforeUpdate; // Store the erase flag } + getReader() { + const reader = this.port.readable.getReader(); + + return { + read() { + return new Promise((resolve, reject) => { + const timeoutHandle = setTimeout(() => { + reader.releaseLock(); + reject(new Error("Read timeout")); + }, DEFAULT_SERIAL_PORT_TIMEOUT * 1000 * 5) + + reader.read().then(result => { + clearTimeout(timeoutHandle); + resolve(result); + }); + }); + }, + releaseLock() { + return reader.releaseLock(); + } + } + } + async sendPacket(pkt) { if (!this.port || !this.port.writable) { throw new Error("Serial port not open or not writable."); @@ -149,7 +195,7 @@ export class Dfu { throw new Error("Serial port not open or not readable."); } - const reader = this.port.readable.getReader(); + const reader = this.getReader(); let buffer = []; let c0Count = 0; @@ -169,13 +215,12 @@ export class Dfu { } } } - - if (Date.now() - startTime > DEFAULT_SERIAL_PORT_TIMEOUT * 1000 * 5) { // Increased timeout for safety - HciPacket.sequenceNumber = 0; // Reset sequence number on timeout. - throw new Error("Timeout waiting for ACK."); - } } - } finally { + } + catch(e) { + HciPacket.sequenceNumber = 0; + } + finally { reader.releaseLock(); } // Decode SLIP @@ -216,7 +261,7 @@ export class Dfu { } else if (data[i] === 0xC0) { // Ignore 0xC0 (start/end of packet) } - else { + else { result.push(data[i]); } i++; diff --git a/lib/iframeResizer.contentWindow.min.js b/lib/iframeResizer.contentWindow.min.js new file mode 100644 index 0000000..48809cc --- /dev/null +++ b/lib/iframeResizer.contentWindow.min.js @@ -0,0 +1,9 @@ +/*! iFrame Resizer (iframeSizer.contentWindow.min.js) - v4.3.5 - 2023-03-08 + * Desc: Include this file in any page being loaded into an iframe + * to force the iframe to resize to the content size. + * Requires: iframeResizer.min.js on host page. + * Copyright: (c) 2023 David J. Bradshaw - dave@bradshaw.net + * License: MIT + */ +!function(a){if("undefined"!=typeof window){var r=!0,P="",u=0,c="",s=null,D="",d=!1,j={resize:1,click:1},l=128,q=!0,f=1,n="bodyOffset",m=n,H=!0,W="",h={},g=32,B=null,p=!1,v=!1,y="[iFrameSizer]",J=y.length,w="",U={max:1,min:1,bodyScroll:1,documentElementScroll:1},b="child",V=!0,X=window.parent,T="*",E=0,i=!1,Y=null,O=16,S=1,K="scroll",M=K,Q=window,G=function(){x("onMessage function not defined")},Z=function(){},$=function(){},_={height:function(){return x("Custom height calculation function not defined"),document.documentElement.offsetHeight},width:function(){return x("Custom width calculation function not defined"),document.body.scrollWidth}},ee={},te=!1;try{var ne=Object.create({},{passive:{get:function(){te=!0}}});window.addEventListener("test",ae,ne),window.removeEventListener("test",ae,ne)}catch(e){}var oe,o,I,ie,N,A,C={bodyOffset:function(){return document.body.offsetHeight+ye("marginTop")+ye("marginBottom")},offset:function(){return C.bodyOffset()},bodyScroll:function(){return document.body.scrollHeight},custom:function(){return _.height()},documentElementOffset:function(){return document.documentElement.offsetHeight},documentElementScroll:function(){return document.documentElement.scrollHeight},max:function(){return Math.max.apply(null,e(C))},min:function(){return Math.min.apply(null,e(C))},grow:function(){return C.max()},lowestElement:function(){return Math.max(C.bodyOffset()||C.documentElementOffset(),we("bottom",Te()))},taggedElement:function(){return be("bottom","data-iframe-height")}},z={bodyScroll:function(){return document.body.scrollWidth},bodyOffset:function(){return document.body.offsetWidth},custom:function(){return _.width()},documentElementScroll:function(){return document.documentElement.scrollWidth},documentElementOffset:function(){return document.documentElement.offsetWidth},scroll:function(){return Math.max(z.bodyScroll(),z.documentElementScroll())},max:function(){return Math.max.apply(null,e(z))},min:function(){return Math.min.apply(null,e(z))},rightMostElement:function(){return we("right",Te())},taggedElement:function(){return be("right","data-iframe-width")}},re=(oe=Ee,N=null,A=0,function(){var e=Date.now(),t=O-(e-(A=A||e));return o=this,I=arguments,t<=0||O