diff --git a/.github/workflows/esp32s3-build-master.yml b/.github/workflows/esp32s3-build-master.yml index a36526d..0c342b8 100644 --- a/.github/workflows/esp32s3-build-master.yml +++ b/.github/workflows/esp32s3-build-master.yml @@ -106,6 +106,7 @@ jobs: print(m.group(1)) PY ) + cp "binaries-esp32s3/flash_board.py" "release_artifacts/firmware/flash_board.py" for board in adv k132; do src_dir="release_artifacts/firmware/${board}" src="${src_dir}/M5MonsterC5-CardputerADV.bin" @@ -218,57 +219,20 @@ jobs: "firmware/${board}/M5MonsterC5-CardputerADV-${board}-${FW_VERSION}.bin" "firmware/${board}/M5MonsterC5-CardputerADV-${board}-launcher-${FW_VERSION}.bin" "firmware/${board}/M5MonsterC5-CardputerADV-${board}-launcher.bin" - "firmware/${board}/M5MonsterC5-CardputerADV-${board}-${FW_VERSION}.zip" ) out="bundle/M5MonsterC5-CardputerADV-${board}-${FW_VERSION}.zip" rm -f "$out" zip -9 "$out" "${files[@]}" done - - name: Delete existing assets (rebuild) - if: github.event_name == 'workflow_dispatch' && inputs.rebuild_release == 'true' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG: ${{ steps.meta.outputs.tag }} - run: | - set -euo pipefail - assets=( - "flash_board.py" - "adv/flash_board.py" - "bootloader-adv.bin" - "partition-table-adv.bin" - "M5MonsterC5-CardputerADV-adv-full.bin" - "M5MonsterC5-CardputerADV-adv-full-${{ needs.package.outputs.fw_version }}.bin" - "M5MonsterC5-CardputerADV-adv.bin" - "M5MonsterC5-CardputerADV-adv-${{ needs.package.outputs.fw_version }}.bin" - "M5MonsterC5-CardputerADV-adv-launcher.bin" - "M5MonsterC5-CardputerADV-adv-launcher-${{ needs.package.outputs.fw_version }}.bin" - "M5MonsterC5-CardputerADV-adv-${{ needs.package.outputs.fw_version }}.zip" - "k132/flash_board.py" - "bootloader-k132.bin" - "partition-table-k132.bin" - "M5MonsterC5-CardputerADV-k132-full.bin" - "M5MonsterC5-CardputerADV-k132-full-${{ needs.package.outputs.fw_version }}.bin" - "M5MonsterC5-CardputerADV-k132.bin" - "M5MonsterC5-CardputerADV-k132-${{ needs.package.outputs.fw_version }}.bin" - "M5MonsterC5-CardputerADV-k132-launcher.bin" - "M5MonsterC5-CardputerADV-k132-launcher-${{ needs.package.outputs.fw_version }}.bin" - "M5MonsterC5-CardputerADV-k132-${{ needs.package.outputs.fw_version }}.zip" - ) - for name in "${assets[@]}"; do - if gh release view "$TAG" -R "$GITHUB_REPOSITORY" --json assets --jq ".assets[].name" | grep -qx "$name"; then - gh release delete-asset "$TAG" "$name" -R "$GITHUB_REPOSITORY" -y - fi - done - - name: Upload binaries to GitHub Release uses: softprops/action-gh-release@v2 with: tag_name: ${{ steps.meta.outputs.tag }} - name: ${{ format('M5MonsterC5-CardputerADV {0}', needs.package.outputs.fw_version) }} + name: ${{ format('v{0} - M5MonsterC5 Cardputer (ADV + K132)', needs.package.outputs.fw_version) }} + overwrite_files: true files: | release_artifacts/firmware/flash_board.py - release_artifacts/firmware/adv/flash_board.py release_artifacts/firmware/adv/bootloader-adv.bin release_artifacts/firmware/adv/partition-table-adv.bin release_artifacts/firmware/adv/M5MonsterC5-CardputerADV-adv-full.bin @@ -277,8 +241,6 @@ jobs: release_artifacts/firmware/adv/M5MonsterC5-CardputerADV-adv-${{ needs.package.outputs.fw_version }}.bin release_artifacts/firmware/adv/M5MonsterC5-CardputerADV-adv-launcher.bin release_artifacts/firmware/adv/M5MonsterC5-CardputerADV-adv-launcher-${{ needs.package.outputs.fw_version }}.bin - release_artifacts/firmware/adv/M5MonsterC5-CardputerADV-adv-${{ needs.package.outputs.fw_version }}.zip - release_artifacts/firmware/k132/flash_board.py release_artifacts/firmware/k132/bootloader-k132.bin release_artifacts/firmware/k132/partition-table-k132.bin release_artifacts/firmware/k132/M5MonsterC5-CardputerADV-k132-full.bin @@ -287,7 +249,6 @@ jobs: release_artifacts/firmware/k132/M5MonsterC5-CardputerADV-k132-${{ needs.package.outputs.fw_version }}.bin release_artifacts/firmware/k132/M5MonsterC5-CardputerADV-k132-launcher.bin release_artifacts/firmware/k132/M5MonsterC5-CardputerADV-k132-launcher-${{ needs.package.outputs.fw_version }}.bin - release_artifacts/firmware/k132/M5MonsterC5-CardputerADV-k132-${{ needs.package.outputs.fw_version }}.zip release_artifacts/bundle/M5MonsterC5-CardputerADV-adv-${{ needs.package.outputs.fw_version }}.zip release_artifacts/bundle/M5MonsterC5-CardputerADV-k132-${{ needs.package.outputs.fw_version }}.zip env: @@ -381,7 +342,7 @@ jobs: BUILD_TAG: ${{ steps.meta.outputs.tag }} run: | set -euo pipefail - python -c "import os, json; from pathlib import Path; version=os.getenv('FW_VERSION') or os.getenv('BUILD_TAG'); build=os.getenv('BUILD_TAG','manual'); base={'version':version,'build':build,'chipFamily':'ESP32-S3'}; adv={'name':'M5MonsterC5-CardputerADV ESP32-S3 (ADV)','parts':[{'path':'firmware/adv/bootloader.bin','offset':8192},{'path':'firmware/adv/partition-table.bin','offset':32768},{'path':'firmware/adv/M5MonsterC5-CardputerADV.bin','offset':65536}]}; k132={'name':'M5MonsterC5-CardputerADV ESP32-S3 (K132)','parts':[{'path':'firmware/k132/bootloader.bin','offset':8192},{'path':'firmware/k132/partition-table.bin','offset':32768},{'path':'firmware/k132/M5MonsterC5-CardputerADV.bin','offset':65536}]}; Path('docs/manifest.json').write_text(json.dumps({**base, **adv}, indent=2)); Path('docs/manifest_k132.json').write_text(json.dumps({**base, **k132}, indent=2))" + python -c "import os, json; from pathlib import Path; version=os.getenv('FW_VERSION') or os.getenv('BUILD_TAG'); build=os.getenv('BUILD_TAG','manual'); base={'version':version,'build':build,'chipFamily':'ESP32-S3'}; adv={'name':'M5MonsterC5-CardputerADV ESP32-S3 (ADV)','parts':[{'path':'firmware/adv/bootloader.bin','offset':0},{'path':'firmware/adv/partition-table.bin','offset':32768},{'path':'firmware/adv/M5MonsterC5-CardputerADV.bin','offset':65536}]}; k132={'name':'M5MonsterC5-CardputerADV ESP32-S3 (K132)','parts':[{'path':'firmware/k132/bootloader.bin','offset':0},{'path':'firmware/k132/partition-table.bin','offset':32768},{'path':'firmware/k132/M5MonsterC5-CardputerADV.bin','offset':65536}]}; Path('docs/manifest.json').write_text(json.dumps({**base, **adv}, indent=2)); Path('docs/manifest_k132.json').write_text(json.dumps({**base, **k132}, indent=2))" - name: Upload Pages artifact uses: actions/upload-pages-artifact@v3 with: @@ -402,7 +363,7 @@ jobs: DISCORD_WEBHOOK: ${{ secrets.GIT_BUILD }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} FW_VERSION: ${{ needs.package.outputs.fw_version }} - RELEASE_TAG: ${{ github.event.release.tag_name || inputs.release_tag || format('v{0}', needs.firmware.outputs.fw_version) }} + RELEASE_TAG: ${{ github.event.release.tag_name || inputs.release_tag || format('v{0}', needs.package.outputs.fw_version) }} REPO: ${{ github.repository }} PAGES_URL: ${{ needs.pages.outputs.page_url || format('https://{0}.github.io/{1}/', github.repository_owner, github.event.repository.name) }} run: | diff --git a/binaries-esp32s3/adv/flash_board.py b/binaries-esp32s3/adv/flash_board.py index 6fb7f60..bd18246 100644 --- a/binaries-esp32s3/adv/flash_board.py +++ b/binaries-esp32s3/adv/flash_board.py @@ -37,6 +37,32 @@ def ensure_packages(): "app": "0x10000", } +def detect_board_by_files(): + if (os.path.exists("bootloader-k132.bin") and os.path.exists("partition-table-k132.bin")) or \ + os.path.exists("M5MonsterC5-CardputerADV-k132.bin"): + return "k132" + if (os.path.exists("bootloader-adv.bin") and os.path.exists("partition-table-adv.bin")) or \ + os.path.exists("M5MonsterC5-CardputerADV-adv.bin"): + return "adv" + return None + +def detect_board_by_path(): + cwd = os.getcwd().lower() + if cwd.endswith(os.sep + "k132") or (os.sep + "k132" + os.sep) in cwd: + return "k132" + if cwd.endswith(os.sep + "adv") or (os.sep + "adv" + os.sep) in cwd: + return "adv" + return None + +def choose_board_interactive(): + print(f"{YELLOW}Select target board:{RESET}") + print(" 1) ADV") + print(" 2) K132") + choice = input("> ").strip() + if choice == "2": + return "k132" + return "adv" + def board_files(board): suffix = board.lower() return { @@ -159,8 +185,8 @@ def main(): parser.add_argument("--port", help="Known serial port (e.g., COM10 or /dev/ttyACM0)") parser.add_argument("baud", nargs="?", type=int, default=DEFAULT_BAUD, help=f"Optional baud rate (default: {DEFAULT_BAUD})") - parser.add_argument("--board", default=DEFAULT_BOARD, choices=["adv", "k132"], - help="Target board (adv or k132). Default: adv.") + parser.add_argument("--board", default=None, choices=["adv", "k132"], + help="Target board (adv or k132). Default: auto-detect by folder/files.") parser.add_argument("--monitor", action="store_true", help="Open serial monitor after flashing") parser.add_argument("--erase", action="store_true", help="Full erase before flashing (fixes stale NVS/partitions)") parser.add_argument("--flash-mode", default="dio", choices=["dio", "qio", "dout", "qout"], @@ -169,7 +195,10 @@ def main(): help="Flash frequency (default: 80m). If you see boot loops, try 40m.") args = parser.parse_args() - files = board_files(args.board) + board = args.board or detect_board_by_files() or detect_board_by_path() + if not board: + board = choose_board_interactive() + files = board_files(board) check_files(files) print(f"{CYAN}ESP32-S3 flasher version: {VERSION}{RESET}") diff --git a/binaries-esp32s3/flash_board.py b/binaries-esp32s3/flash_board.py index 6fb7f60..bd18246 100644 --- a/binaries-esp32s3/flash_board.py +++ b/binaries-esp32s3/flash_board.py @@ -37,6 +37,32 @@ def ensure_packages(): "app": "0x10000", } +def detect_board_by_files(): + if (os.path.exists("bootloader-k132.bin") and os.path.exists("partition-table-k132.bin")) or \ + os.path.exists("M5MonsterC5-CardputerADV-k132.bin"): + return "k132" + if (os.path.exists("bootloader-adv.bin") and os.path.exists("partition-table-adv.bin")) or \ + os.path.exists("M5MonsterC5-CardputerADV-adv.bin"): + return "adv" + return None + +def detect_board_by_path(): + cwd = os.getcwd().lower() + if cwd.endswith(os.sep + "k132") or (os.sep + "k132" + os.sep) in cwd: + return "k132" + if cwd.endswith(os.sep + "adv") or (os.sep + "adv" + os.sep) in cwd: + return "adv" + return None + +def choose_board_interactive(): + print(f"{YELLOW}Select target board:{RESET}") + print(" 1) ADV") + print(" 2) K132") + choice = input("> ").strip() + if choice == "2": + return "k132" + return "adv" + def board_files(board): suffix = board.lower() return { @@ -159,8 +185,8 @@ def main(): parser.add_argument("--port", help="Known serial port (e.g., COM10 or /dev/ttyACM0)") parser.add_argument("baud", nargs="?", type=int, default=DEFAULT_BAUD, help=f"Optional baud rate (default: {DEFAULT_BAUD})") - parser.add_argument("--board", default=DEFAULT_BOARD, choices=["adv", "k132"], - help="Target board (adv or k132). Default: adv.") + parser.add_argument("--board", default=None, choices=["adv", "k132"], + help="Target board (adv or k132). Default: auto-detect by folder/files.") parser.add_argument("--monitor", action="store_true", help="Open serial monitor after flashing") parser.add_argument("--erase", action="store_true", help="Full erase before flashing (fixes stale NVS/partitions)") parser.add_argument("--flash-mode", default="dio", choices=["dio", "qio", "dout", "qout"], @@ -169,7 +195,10 @@ def main(): help="Flash frequency (default: 80m). If you see boot loops, try 40m.") args = parser.parse_args() - files = board_files(args.board) + board = args.board or detect_board_by_files() or detect_board_by_path() + if not board: + board = choose_board_interactive() + files = board_files(board) check_files(files) print(f"{CYAN}ESP32-S3 flasher version: {VERSION}{RESET}") diff --git a/binaries-esp32s3/k132/flash_board.py b/binaries-esp32s3/k132/flash_board.py index 6fb7f60..bd18246 100644 --- a/binaries-esp32s3/k132/flash_board.py +++ b/binaries-esp32s3/k132/flash_board.py @@ -37,6 +37,32 @@ def ensure_packages(): "app": "0x10000", } +def detect_board_by_files(): + if (os.path.exists("bootloader-k132.bin") and os.path.exists("partition-table-k132.bin")) or \ + os.path.exists("M5MonsterC5-CardputerADV-k132.bin"): + return "k132" + if (os.path.exists("bootloader-adv.bin") and os.path.exists("partition-table-adv.bin")) or \ + os.path.exists("M5MonsterC5-CardputerADV-adv.bin"): + return "adv" + return None + +def detect_board_by_path(): + cwd = os.getcwd().lower() + if cwd.endswith(os.sep + "k132") or (os.sep + "k132" + os.sep) in cwd: + return "k132" + if cwd.endswith(os.sep + "adv") or (os.sep + "adv" + os.sep) in cwd: + return "adv" + return None + +def choose_board_interactive(): + print(f"{YELLOW}Select target board:{RESET}") + print(" 1) ADV") + print(" 2) K132") + choice = input("> ").strip() + if choice == "2": + return "k132" + return "adv" + def board_files(board): suffix = board.lower() return { @@ -159,8 +185,8 @@ def main(): parser.add_argument("--port", help="Known serial port (e.g., COM10 or /dev/ttyACM0)") parser.add_argument("baud", nargs="?", type=int, default=DEFAULT_BAUD, help=f"Optional baud rate (default: {DEFAULT_BAUD})") - parser.add_argument("--board", default=DEFAULT_BOARD, choices=["adv", "k132"], - help="Target board (adv or k132). Default: adv.") + parser.add_argument("--board", default=None, choices=["adv", "k132"], + help="Target board (adv or k132). Default: auto-detect by folder/files.") parser.add_argument("--monitor", action="store_true", help="Open serial monitor after flashing") parser.add_argument("--erase", action="store_true", help="Full erase before flashing (fixes stale NVS/partitions)") parser.add_argument("--flash-mode", default="dio", choices=["dio", "qio", "dout", "qout"], @@ -169,7 +195,10 @@ def main(): help="Flash frequency (default: 80m). If you see boot loops, try 40m.") args = parser.parse_args() - files = board_files(args.board) + board = args.board or detect_board_by_files() or detect_board_by_path() + if not board: + board = choose_board_interactive() + files = board_files(board) check_files(files) print(f"{CYAN}ESP32-S3 flasher version: {VERSION}{RESET}") diff --git a/docs/janos_flash.html b/docs/janos_flash.html index 21005b1..3e47da5 100644 --- a/docs/janos_flash.html +++ b/docs/janos_flash.html @@ -428,10 +428,15 @@

Browser support

let cleaned = path.startsWith("/") ? path.slice(1) : path; const repo = getRepoSlug(); if (!repo) return cleaned; + const branch = getBranch(); + if (branch === "main") { + // Use paths as-is so GitHub Pages can serve /firmware/* + return cleaned; + } + // For non-main branches, fetch from repo's docs/ directory. if (cleaned.startsWith("firmware/")) { - cleaned = cleaned.replace(/^firmware\//, "binaries-esp32s3/"); + cleaned = cleaned.replace(/^firmware\//, "docs/firmware/"); } - const branch = getBranch(); return `https://raw.githubusercontent.com/${repo}/${branch}/${cleaned}`; }; diff --git a/docs/manifest.json b/docs/manifest.json index 7284cac..9e0dc17 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1,11 +1,11 @@ { - "name": "M5MonsterC5-CardputerADV ESP32-S3", + "name": "M5MonsterC5-CardputerADV ESP32-S3 (ADV)", "version": "latest", "build": "latest", "chipFamily": "ESP32-S3", "parts": [ - { "path": "firmware/bootloader.bin", "offset": 0 }, - { "path": "firmware/partition-table.bin", "offset": 32768 }, - { "path": "firmware/M5MonsterC5-CardputerADV.bin", "offset": 65536 } + { "path": "firmware/adv/bootloader.bin", "offset": 0 }, + { "path": "firmware/adv/partition-table.bin", "offset": 32768 }, + { "path": "firmware/adv/M5MonsterC5-CardputerADV.bin", "offset": 65536 } ] } diff --git a/docs/manifest_k132.json b/docs/manifest_k132.json new file mode 100644 index 0000000..56bfc01 --- /dev/null +++ b/docs/manifest_k132.json @@ -0,0 +1,11 @@ +{ + "name": "M5MonsterC5-CardputerADV ESP32-S3 (K132)", + "version": "latest", + "build": "latest", + "chipFamily": "ESP32-S3", + "parts": [ + { "path": "firmware/k132/bootloader.bin", "offset": 0 }, + { "path": "firmware/k132/partition-table.bin", "offset": 32768 }, + { "path": "firmware/k132/M5MonsterC5-CardputerADV.bin", "offset": 65536 } + ] +}