diff --git a/.github/ISSUE_TEMPLATE/Issue-report.yml b/.github/ISSUE_TEMPLATE/Issue-report.yml index 9dba5e0ca8f..6dc1b0de171 100644 --- a/.github/ISSUE_TEMPLATE/Issue-report.yml +++ b/.github/ISSUE_TEMPLATE/Issue-report.yml @@ -43,6 +43,7 @@ body: - latest stable Release (if not listed below) - latest development Release Candidate (RC-X) - latest master (checkout manually) + - v3.2.1 - v3.2.0 - v3.1.3 - v3.1.2 diff --git a/.github/scripts/package_esptool.sh b/.github/scripts/package_esptool.sh deleted file mode 100755 index 32b87b277e9..00000000000 --- a/.github/scripts/package_esptool.sh +++ /dev/null @@ -1,129 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -# Check version argument -if [[ $# -ne 3 ]]; then - echo "Usage: $0 " - echo "Example: $0 5.0.dev1 /tmp/esptool /tmp/esptool-5.0.dev1.json" - exit 1 -fi - -VERSION=$1 -BASE_FOLDER=$2 -JSON_PATH=$3 - -export COPYFILE_DISABLE=1 - -shopt -s nullglob # So for loop doesn't run if no matches - -# Function to update JSON for a given host -function update_json_for_host { - local host=$1 - local archive=$2 - - # Extract the old url from the JSON for this host, then replace only the filename - old_url=$(jq -r --arg host "$host" ' - .packages[].tools[] | select(.name == "esptool_py") | .systems[] | select(.host == $host) | .url // empty - ' "$tmp_json") - if [[ -n "$old_url" ]]; then - base_url="${old_url%/*}" - url="$base_url/$archive" - else - echo "No old url found for $host" - exit 1 - fi - - archiveFileName="$archive" - checksum="SHA-256:$(shasum -a 256 "$archive" | awk '{print $1}')" - size=$(stat -f%z "$archive") - - # Use jq to update the JSON - jq --arg host "$host" \ - --arg url "$url" \ - --arg archiveFileName "$archiveFileName" \ - --arg checksum "$checksum" \ - --arg size "$size" \ - ' - .packages[].tools[] - |= if .name == "esptool_py" then - .systems = ( - ((.systems // []) | map(select(.host != $host))) + [{ - host: $host, - url: $url, - archiveFileName: $archiveFileName, - checksum: $checksum, - size: $size - }] - ) - else - . - end - ' "$tmp_json" > "$tmp_json.new" && mv "$tmp_json.new" "$tmp_json" -} - -cd "$BASE_FOLDER" - -# Delete all archives before starting -rm -f esptool-*.tar.gz esptool-*.zip - -for dir in esptool-*; do - # Check if directory exists and is a directory - if [[ ! -d "$dir" ]]; then - continue - fi - - base="${dir#esptool-}" - - # Add 'linux-' prefix if base doesn't contain linux/macos/win64 - if [[ "$base" != *linux* && "$base" != *macos* && "$base" != *win64* ]]; then - base="linux-${base}" - fi - - if [[ "$dir" == esptool-win* ]]; then - # Windows zip archive - zipfile="esptool-v${VERSION}-${base}.zip" - echo "Creating $zipfile from $dir ..." - zip -r "$zipfile" "$dir" - else - # Non-Windows: set permissions and tar.gz archive - tarfile="esptool-v${VERSION}-${base}.tar.gz" - echo "Setting permissions and creating $tarfile from $dir ..." - chmod -R u=rwx,g=rx,o=rx "$dir" - tar -cvzf "$tarfile" "$dir" - fi -done - -# After the for loop, update the JSON for each archive -# Create a temporary JSON file to accumulate changes -tmp_json="${JSON_PATH}.tmp" -cp "$JSON_PATH" "$tmp_json" - -for archive in esptool-v"${VERSION}"-*.tar.gz esptool-v"${VERSION}"-*.zip; do - [ -f "$archive" ] || continue - - echo "Updating JSON for $archive" - - # Determine host from archive name - case "$archive" in - *linux-amd64*) host="x86_64-pc-linux-gnu" ;; - *linux-armv7*) host="arm-linux-gnueabihf" ;; - *linux-aarch64*) host="aarch64-linux-gnu" ;; - *macos-amd64*) host="x86_64-apple-darwin" ;; - *macos-arm64*) host="arm64-apple-darwin" ;; - *win64*) hosts=("x86_64-mingw32" "i686-mingw32") ;; - *) echo "Unknown host for $archive"; continue ;; - esac - - # For win64, loop over both hosts; otherwise, use a single host - if [[ "$archive" == *win64* ]]; then - for host in "${hosts[@]}"; do - update_json_for_host "$host" "$archive" - done - else - update_json_for_host "$host" "$archive" - fi -done - -# After all archives are processed, move the temporary JSON to the final file -mv "$tmp_json" "$JSON_PATH" diff --git a/.github/scripts/update_esptool.py b/.github/scripts/update_esptool.py new file mode 100644 index 00000000000..d99462fcb8f --- /dev/null +++ b/.github/scripts/update_esptool.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python3 + +# This script is used to re-package the esptool if needed and update the JSON file +# for the Arduino ESP32 platform. +# +# The script has only been tested on macOS. +# +# For regular esptool releases, the generated packages already contain the correct permissions, +# extensions and are uploaded to the GitHub release assets. In this case, the script will only +# update the JSON file with the information from the GitHub release. +# +# The script can be used in two modes: +# 1. Local build: The build artifacts must be already downloaded and extracted in the base_folder. +# This is useful for esptool versions that are not yet released and that are grabbed from the +# GitHub build artifacts. +# 2. Release build: The script will get the release information from GitHub and update the JSON file. +# This is useful for esptool versions that are already released and that are uploaded to the +# GitHub release assets. +# +# For local build, the artifacts must be already downloaded and extracted in the base_folder +# set with the -l option. +# For example, a base folder "esptool" should contain the following folders extracted directly +# from the GitHub build artifacts: +# esptool/esptool-linux-aarch64 +# esptool/esptool-linux-amd64 +# esptool/esptool-linux-armv7 +# esptool/esptool-macos-amd64 +# esptool/esptool-macos-arm64 +# esptool/esptool-windows-amd64 + +import argparse +import json +import os +import shutil +import stat +import tarfile +import zipfile +import hashlib +import requests +from pathlib import Path + +def compute_sha256(filepath): + sha256 = hashlib.sha256() + with open(filepath, "rb") as f: + for block in iter(lambda: f.read(4096), b""): + sha256.update(block) + return f"SHA-256:{sha256.hexdigest()}" + +def get_file_size(filepath): + return os.path.getsize(filepath) + +def update_json_for_host(tmp_json_path, version, host, url, archiveFileName, checksum, size): + with open(tmp_json_path) as f: + data = json.load(f) + + for pkg in data.get("packages", []): + for tool in pkg.get("tools", []): + if tool.get("name") == "esptool_py": + tool["version"] = version + + if url is None: + # If the URL is not set, we need to find the old URL and update it + for system in tool.get("systems", []): + if system.get("host") == host: + url = system.get("url").replace(system.get("archiveFileName"), archiveFileName) + break + else: + print(f"No old URL found for host {host}. Using empty URL.") + url = "" + + # Preserve existing systems order and update or append the new system + systems = tool.get("systems", []) + system_updated = False + for i, system in enumerate(systems): + if system.get("host") == host: + systems[i] = { + "host": host, + "url": url, + "archiveFileName": archiveFileName, + "checksum": checksum, + "size": str(size), + } + system_updated = True + break + + if not system_updated: + systems.append({ + "host": host, + "url": url, + "archiveFileName": archiveFileName, + "checksum": checksum, + "size": str(size), + }) + tool["systems"] = systems + + with open(tmp_json_path, "w") as f: + json.dump(data, f, indent=2, sort_keys=False, ensure_ascii=False) + f.write("\n") + +def update_tools_dependencies(tmp_json_path, version): + with open(tmp_json_path) as f: + data = json.load(f) + + for pkg in data.get("packages", []): + for platform in pkg.get("platforms", []): + for dep in platform.get("toolsDependencies", []): + if dep.get("name") == "esptool_py": + dep["version"] = version + + with open(tmp_json_path, "w") as f: + json.dump(data, f, indent=2, sort_keys=False, ensure_ascii=False) + f.write("\n") + +def create_archives(version, base_folder): + archive_files = [] + + for dirpath in Path(base_folder).glob("esptool-*"): + if not dirpath.is_dir(): + continue + + base = dirpath.name[len("esptool-"):] + + if "windows" in dirpath.name: + zipfile_name = f"esptool-v{version}-{base}.zip" + print(f"Creating {zipfile_name} from {dirpath} ...") + with zipfile.ZipFile(zipfile_name, "w", zipfile.ZIP_DEFLATED) as zipf: + for root, _, files in os.walk(dirpath): + for file in files: + full_path = os.path.join(root, file) + zipf.write(full_path, os.path.relpath(full_path, start=dirpath)) + archive_files.append(zipfile_name) + else: + tarfile_name = f"esptool-v{version}-{base}.tar.gz" + print(f"Creating {tarfile_name} from {dirpath} ...") + for root, dirs, files in os.walk(dirpath): + for name in dirs + files: + os.chmod(os.path.join(root, name), stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | + stat.S_IRGRP | stat.S_IXGRP | + stat.S_IROTH | stat.S_IXOTH) + with tarfile.open(tarfile_name, "w:gz") as tar: + tar.add(dirpath, arcname=dirpath.name) + archive_files.append(tarfile_name) + + return archive_files + +def determine_hosts(archive_name): + if "linux-amd64" in archive_name: + return ["x86_64-pc-linux-gnu"] + elif "linux-armv7" in archive_name: + return ["arm-linux-gnueabihf"] + elif "linux-aarch64" in archive_name: + return ["aarch64-linux-gnu"] + elif "macos-amd64" in archive_name: + return ["x86_64-apple-darwin"] + elif "macos-arm64" in archive_name: + return ["arm64-apple-darwin"] + elif "windows-amd64" in archive_name: + return ["x86_64-mingw32", "i686-mingw32"] + else: + return [] + +def update_json_from_local_build(tmp_json_path, version, base_folder, archive_files): + for archive in archive_files: + print(f"Processing archive: {archive}") + hosts = determine_hosts(archive) + if not hosts: + print(f"Skipping unknown archive type: {archive}") + continue + + archive_path = Path(archive) + checksum = compute_sha256(archive_path) + size = get_file_size(archive_path) + + for host in hosts: + update_json_for_host(tmp_json_path, version, host, None, archive_path.name, checksum, size) + +def update_json_from_release(tmp_json_path, version, release_info): + assets = release_info.get("assets", []) + for asset in assets: + if (asset.get("name").endswith(".tar.gz") or asset.get("name").endswith(".zip")) and "esptool" in asset.get("name"): + asset_fname = asset.get("name") + print(f"Processing asset: {asset_fname}") + hosts = determine_hosts(asset_fname) + if not hosts: + print(f"Skipping unknown archive type: {asset_fname}") + continue + + asset_url = asset.get("browser_download_url") + asset_checksum = asset.get("digest").replace("sha256:", "SHA-256:") + asset_size = asset.get("size") + if asset_checksum is None: + asset_checksum = "" + print(f"Asset {asset_fname} has no checksum. Please set the checksum in the JSON file.") + + for host in hosts: + update_json_for_host(tmp_json_path, version, host, asset_url, asset_fname, asset_checksum, asset_size) + +def get_release_info(version): + url = f"https://api.github.com/repos/espressif/esptool/releases/tags/v{version}" + response = requests.get(url) + response.raise_for_status() + return response.json() + +def main(): + parser = argparse.ArgumentParser(description="Repack esptool and update JSON metadata.") + parser.add_argument("version", help="Version of the esptool (e.g. 5.0.dev1)") + parser.add_argument("-l", "--local", dest="base_folder", help="Enable local build mode and set the base folder with unpacked artifacts") + args = parser.parse_args() + + script_dir = Path(__file__).resolve().parent + json_path = (script_dir / "../../package/package_esp32_index.template.json").resolve() + tmp_json_path = Path(str(json_path) + ".tmp") + shutil.copy(json_path, tmp_json_path) + + local_build = args.base_folder is not None + + if local_build: + os.chdir(args.base_folder) + os.environ['COPYFILE_DISABLE'] = 'true' # this disables including resource forks in tar files on macOS + # Clear any existing archive files + for file in Path(args.base_folder).glob("esptool-*.*"): + file.unlink() + archive_files = create_archives(args.version, args.base_folder) + update_json_from_local_build(tmp_json_path, args.version, args.base_folder, archive_files) + else: + release_info = get_release_info(args.version) + update_json_from_release(tmp_json_path, args.version, release_info) + + print(f"Updating esptool version fields to {args.version}") + update_tools_dependencies(tmp_json_path, args.version) + + shutil.move(tmp_json_path, json_path) + print(f"Done. JSON updated at {json_path}") + +if __name__ == "__main__": + main() diff --git a/.github/workflows/dangerjs.yml b/.github/workflows/dangerjs.yml index 13bc907566b..bba96bfedee 100644 --- a/.github/workflows/dangerjs.yml +++ b/.github/workflows/dangerjs.yml @@ -24,4 +24,5 @@ jobs: instructions-cla-link: "https://cla-assistant.io/espressif/arduino-esp32" instructions-contributions-file: "docs/en/contributing.rst" rule-max-commits: "false" + rule-target-branch: "false" commit-messages-min-summary-length: "10" diff --git a/.github/workflows/lib.json b/.github/workflows/lib.json index 5b93d6689ef..f1ff111d25b 100644 --- a/.github/workflows/lib.json +++ b/.github/workflows/lib.json @@ -9,7 +9,8 @@ { "name": "ArduinoBLE", "exclude_targets": [ - "esp32s2" + "esp32s2", + "esp32p4" ], "sketch_path": [ "~/Arduino/libraries/ArduinoBLE/examples/Central/Scan/Scan.ino" diff --git a/CMakeLists.txt b/CMakeLists.txt index e8f44ac5ee0..f21183ee11e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -305,6 +305,7 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS libraries/Zigbee/src/ep/ZigbeeElectricalMeasurement.cpp libraries/Zigbee/src/ep/ZigbeeBinary.cpp libraries/Zigbee/src/ep/ZigbeePowerOutlet.cpp + libraries/Zigbee/src/ep/ZigbeeFanControl.cpp ) set(ARDUINO_LIBRARY_BLE_SRCS diff --git a/boards.txt b/boards.txt index b51a8840757..ac2b1a336e4 100644 --- a/boards.txt +++ b/boards.txt @@ -33287,6 +33287,229 @@ deneyapkart.menu.EraseFlash.all.upload.erase_cmd=-e ############################################################## +deneyapkartv2.name=Deneyap Kart v2 + +deneyapkartv2.vid.0=0x303a +deneyapkartv2.pid.0=0x82EB + +deneyapkartv2.bootloader.tool=esptool_py +deneyapkartv2.bootloader.tool.default=esptool_py + +deneyapkartv2.upload.tool=esptool_py +deneyapkartv2.upload.tool.default=esptool_py +deneyapkartv2.upload.tool.network=esp_ota + +deneyapkartv2.upload.maximum_size=1310720 +deneyapkartv2.upload.maximum_data_size=327680 +deneyapkartv2.upload.flags= +deneyapkartv2.upload.extra_flags= +deneyapkartv2.upload.use_1200bps_touch=false +deneyapkartv2.upload.wait_for_upload_port=false + +deneyapkartv2.serial.disableDTR=false +deneyapkartv2.serial.disableRTS=false + +deneyapkartv2.build.tarch=xtensa +deneyapkartv2.build.bootloader_addr=0x0 +deneyapkartv2.build.target=esp32s3 +deneyapkartv2.build.mcu=esp32s3 +deneyapkartv2.build.core=esp32 +deneyapkartv2.build.variant=deneyapkartv2 +deneyapkartv2.build.board=DYDKV2 + +deneyapkartv2.build.usb_mode=1 +deneyapkartv2.build.cdc_on_boot=1 +deneyapkartv2.build.msc_on_boot=0 +deneyapkartv2.build.dfu_on_boot=0 +deneyapkartv2.build.f_cpu=240000000L +deneyapkartv2.build.flash_size=4MB +deneyapkartv2.build.flash_freq=80m +deneyapkartv2.build.flash_mode=dio +deneyapkartv2.build.boot=qio +deneyapkartv2.build.boot_freq=80m +deneyapkartv2.build.partitions=default +deneyapkartv2.build.defines=-DBOARD_HAS_PSRAM +deneyapkartv2.build.loop_core= +deneyapkartv2.build.event_core= +deneyapkartv2.build.psram_type=opi +deneyapkartv2.build.memory_type={build.boot}_{build.psram_type} + +## IDE 2.0 Seems to not update the value +deneyapkartv2.menu.JTAGAdapter.default=Disabled +deneyapkartv2.menu.JTAGAdapter.default.build.copy_jtag_files=0 +deneyapkartv2.menu.JTAGAdapter.builtin=Integrated USB JTAG +deneyapkartv2.menu.JTAGAdapter.builtin.build.openocdscript=esp32s3-builtin.cfg +deneyapkartv2.menu.JTAGAdapter.builtin.build.copy_jtag_files=1 +deneyapkartv2.menu.JTAGAdapter.external=FTDI Adapter +deneyapkartv2.menu.JTAGAdapter.external.build.openocdscript=esp32s3-ftdi.cfg +deneyapkartv2.menu.JTAGAdapter.external.build.copy_jtag_files=1 +deneyapkartv2.menu.JTAGAdapter.bridge=ESP USB Bridge +deneyapkartv2.menu.JTAGAdapter.bridge.build.openocdscript=esp32s3-bridge.cfg +deneyapkartv2.menu.JTAGAdapter.bridge.build.copy_jtag_files=1 + +deneyapkartv2.menu.PSRAM.opi=OPI PSRAM +deneyapkartv2.menu.PSRAM.opi.build.defines=-DBOARD_HAS_PSRAM +deneyapkartv2.menu.PSRAM.opi.build.psram_type=opi +deneyapkartv2.menu.PSRAM.disabled=Disabled +deneyapkartv2.menu.PSRAM.disabled.build.defines= +deneyapkartv2.menu.PSRAM.disabled.build.psram_type=qspi + +deneyapkartv2.menu.FlashMode.qio=QIO 80MHz +deneyapkartv2.menu.FlashMode.qio.build.flash_mode=dio +deneyapkartv2.menu.FlashMode.qio.build.boot=qio +deneyapkartv2.menu.FlashMode.qio.build.boot_freq=80m +deneyapkartv2.menu.FlashMode.qio.build.flash_freq=80m +deneyapkartv2.menu.FlashMode.qio120=QIO 120MHz +deneyapkartv2.menu.FlashMode.qio120.build.flash_mode=dio +deneyapkartv2.menu.FlashMode.qio120.build.boot=qio +deneyapkartv2.menu.FlashMode.qio120.build.boot_freq=120m +deneyapkartv2.menu.FlashMode.qio120.build.flash_freq=80m +deneyapkartv2.menu.FlashMode.dio=DIO 80MHz +deneyapkartv2.menu.FlashMode.dio.build.flash_mode=dio +deneyapkartv2.menu.FlashMode.dio.build.boot=dio +deneyapkartv2.menu.FlashMode.dio.build.boot_freq=80m +deneyapkartv2.menu.FlashMode.dio.build.flash_freq=80m +deneyapkartv2.menu.FlashMode.opi=OPI 80MHz +deneyapkartv2.menu.FlashMode.opi.build.flash_mode=dout +deneyapkartv2.menu.FlashMode.opi.build.boot=opi +deneyapkartv2.menu.FlashMode.opi.build.boot_freq=80m +deneyapkartv2.menu.FlashMode.opi.build.flash_freq=80m + +deneyapkartv2.menu.FlashSize.4M=4MB (32Mb) +deneyapkartv2.menu.FlashSize.4M.build.flash_size=4MB + +deneyapkartv2.menu.LoopCore.1=Core 1 +deneyapkartv2.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1 +deneyapkartv2.menu.LoopCore.0=Core 0 +deneyapkartv2.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0 + +deneyapkartv2.menu.EventsCore.1=Core 1 +deneyapkartv2.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1 +deneyapkartv2.menu.EventsCore.0=Core 0 +deneyapkartv2.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0 + +deneyapkartv2.menu.USBMode.hwcdc=Hardware CDC and JTAG +deneyapkartv2.menu.USBMode.hwcdc.build.usb_mode=1 +deneyapkartv2.menu.USBMode.default=USB-OTG (TinyUSB) +deneyapkartv2.menu.USBMode.default.build.usb_mode=0 + +deneyapkartv2.menu.CDCOnBoot.cdc=Enabled +deneyapkartv2.menu.CDCOnBoot.cdc.build.cdc_on_boot=1 +deneyapkartv2.menu.CDCOnBoot.default=Disabled +deneyapkartv2.menu.CDCOnBoot.default.build.cdc_on_boot=0 + +deneyapkartv2.menu.MSCOnBoot.default=Disabled +deneyapkartv2.menu.MSCOnBoot.default.build.msc_on_boot=0 +deneyapkartv2.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode) +deneyapkartv2.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +deneyapkartv2.menu.DFUOnBoot.default=Disabled +deneyapkartv2.menu.DFUOnBoot.default.build.dfu_on_boot=0 +deneyapkartv2.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode) +deneyapkartv2.menu.DFUOnBoot.dfu.build.dfu_on_boot=1 + +deneyapkartv2.menu.UploadMode.default=UART0 / Hardware CDC +deneyapkartv2.menu.UploadMode.default.upload.use_1200bps_touch=false +deneyapkartv2.menu.UploadMode.default.upload.wait_for_upload_port=false +deneyapkartv2.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB) +deneyapkartv2.menu.UploadMode.cdc.upload.use_1200bps_touch=true +deneyapkartv2.menu.UploadMode.cdc.upload.wait_for_upload_port=true + +deneyapkartv2.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +deneyapkartv2.menu.PartitionScheme.default.build.partitions=default +deneyapkartv2.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +deneyapkartv2.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +deneyapkartv2.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) +deneyapkartv2.menu.PartitionScheme.minimal.build.partitions=minimal +deneyapkartv2.menu.PartitionScheme.no_fs=No FS 4MB (2MB APP x2) +deneyapkartv2.menu.PartitionScheme.no_fs.build.partitions=no_fs +deneyapkartv2.menu.PartitionScheme.no_fs.upload.maximum_size=2031616 +deneyapkartv2.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +deneyapkartv2.menu.PartitionScheme.no_ota.build.partitions=no_ota +deneyapkartv2.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +deneyapkartv2.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +deneyapkartv2.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +deneyapkartv2.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +deneyapkartv2.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +deneyapkartv2.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +deneyapkartv2.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +deneyapkartv2.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +deneyapkartv2.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +deneyapkartv2.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +deneyapkartv2.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +deneyapkartv2.menu.PartitionScheme.huge_app.build.partitions=huge_app +deneyapkartv2.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 +deneyapkartv2.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) +deneyapkartv2.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +deneyapkartv2.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 +deneyapkartv2.menu.PartitionScheme.rainmaker=RainMaker 4MB +deneyapkartv2.menu.PartitionScheme.rainmaker.build.partitions=rainmaker +deneyapkartv2.menu.PartitionScheme.rainmaker.upload.maximum_size=1966080 +deneyapkartv2.menu.PartitionScheme.rainmaker_4MB=RainMaker 4MB No OTA +deneyapkartv2.menu.PartitionScheme.rainmaker_4MB.build.partitions=rainmaker_4MB_no_ota +deneyapkartv2.menu.PartitionScheme.rainmaker_4MB.upload.maximum_size=4038656 +deneyapkartv2.menu.PartitionScheme.zigbee_zczr=Zigbee ZCZR 4MB with spiffs +deneyapkartv2.menu.PartitionScheme.zigbee_zczr.build.partitions=zigbee_zczr +deneyapkartv2.menu.PartitionScheme.zigbee_zczr.upload.maximum_size=1310720 +deneyapkartv2.menu.PartitionScheme.custom=Custom +deneyapkartv2.menu.PartitionScheme.custom.build.partitions= +deneyapkartv2.menu.PartitionScheme.custom.upload.maximum_size=16777216 + +deneyapkartv2.menu.CPUFreq.240=240MHz (WiFi) +deneyapkartv2.menu.CPUFreq.240.build.f_cpu=240000000L +deneyapkartv2.menu.CPUFreq.160=160MHz (WiFi) +deneyapkartv2.menu.CPUFreq.160.build.f_cpu=160000000L +deneyapkartv2.menu.CPUFreq.80=80MHz (WiFi) +deneyapkartv2.menu.CPUFreq.80.build.f_cpu=80000000L +deneyapkartv2.menu.CPUFreq.40=40MHz +deneyapkartv2.menu.CPUFreq.40.build.f_cpu=40000000L +deneyapkartv2.menu.CPUFreq.20=20MHz +deneyapkartv2.menu.CPUFreq.20.build.f_cpu=20000000L +deneyapkartv2.menu.CPUFreq.10=10MHz +deneyapkartv2.menu.CPUFreq.10.build.f_cpu=10000000L + +deneyapkartv2.menu.UploadSpeed.921600=921600 +deneyapkartv2.menu.UploadSpeed.921600.upload.speed=921600 +deneyapkartv2.menu.UploadSpeed.115200=115200 +deneyapkartv2.menu.UploadSpeed.115200.upload.speed=115200 +deneyapkartv2.menu.UploadSpeed.256000.windows=256000 +deneyapkartv2.menu.UploadSpeed.256000.upload.speed=256000 +deneyapkartv2.menu.UploadSpeed.230400.windows.upload.speed=256000 +deneyapkartv2.menu.UploadSpeed.230400=230400 +deneyapkartv2.menu.UploadSpeed.230400.upload.speed=230400 +deneyapkartv2.menu.UploadSpeed.460800.linux=460800 +deneyapkartv2.menu.UploadSpeed.460800.macosx=460800 +deneyapkartv2.menu.UploadSpeed.460800.upload.speed=460800 +deneyapkartv2.menu.UploadSpeed.512000.windows=512000 +deneyapkartv2.menu.UploadSpeed.512000.upload.speed=512000 + +deneyapkartv2.menu.DebugLevel.none=None +deneyapkartv2.menu.DebugLevel.none.build.code_debug=0 +deneyapkartv2.menu.DebugLevel.error=Error +deneyapkartv2.menu.DebugLevel.error.build.code_debug=1 +deneyapkartv2.menu.DebugLevel.warn=Warn +deneyapkartv2.menu.DebugLevel.warn.build.code_debug=2 +deneyapkartv2.menu.DebugLevel.info=Info +deneyapkartv2.menu.DebugLevel.info.build.code_debug=3 +deneyapkartv2.menu.DebugLevel.debug=Debug +deneyapkartv2.menu.DebugLevel.debug.build.code_debug=4 +deneyapkartv2.menu.DebugLevel.verbose=Verbose +deneyapkartv2.menu.DebugLevel.verbose.build.code_debug=5 + +deneyapkartv2.menu.EraseFlash.none=Disabled +deneyapkartv2.menu.EraseFlash.none.upload.erase_cmd= +deneyapkartv2.menu.EraseFlash.all=Enabled +deneyapkartv2.menu.EraseFlash.all.upload.erase_cmd=-e + +deneyapkartv2.menu.ZigbeeMode.default=Disabled +deneyapkartv2.menu.ZigbeeMode.default.build.zigbee_mode= +deneyapkartv2.menu.ZigbeeMode.default.build.zigbee_libs= +deneyapkartv2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) +deneyapkartv2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR +deneyapkartv2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote + +############################################################## + deneyapkart1A.name=Deneyap Kart 1A deneyapkart1A.bootloader.tool=esptool_py @@ -40993,7 +41216,7 @@ sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2=TinyUF2 4MB (1.3MB APP/960KB F sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.build.custom_bootloader=bootloader-tinyuf2 sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.build.custom_partitions=partitions-4MB-tinyuf2 sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.upload.maximum_size=1441792 -sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.upload.extra_flags=0x2d0000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin" +sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.upload.extra_flags=0x2d0000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin" 0x170000 "{runtime.platform.path}/variants/{build.variant}/APOTA.bin" sensebox_mcu_esp32s2.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) sensebox_mcu_esp32s2.menu.PartitionScheme.default.build.partitions=default sensebox_mcu_esp32s2.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) @@ -50547,3 +50770,405 @@ cyobot_v2_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR cyobot_v2_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## + +rakwireless_rak3112.name=RAKwireless RAK3112 + +rakwireless_rak3112.upload.tool=esptool_py +rakwireless_rak3112.upload.tool.default=esptool_py +rakwireless_rak3112.upload.tool.network=esp_ota +rakwireless_rak3112.upload.maximum_size=1310720 +rakwireless_rak3112.upload.maximum_data_size=327680 +rakwireless_rak3112.upload.wait_for_upload_port=false +rakwireless_rak3112.upload.speed=460800 +rakwireless_rak3112.upload.flags= +rakwireless_rak3112.upload.extra_flags= + +rakwireless_rak3112.bootloader.tool=esptool_py +rakwireless_rak3112.bootloader.tool.default=esptool_py + +rakwireless_rak3112.serial.disableDTR=true +rakwireless_rak3112.serial.disableRTS=true + +rakwireless_rak3112.build.tarch=xtensa +rakwireless_rak3112.build.bootloader_addr=0x0 +rakwireless_rak3112.build.mcu=esp32s3 +rakwireless_rak3112.build.core=esp32 +rakwireless_rak3112.build.target=esp32s3 +rakwireless_rak3112.build.variant=rakwireless_rak3112 +rakwireless_rak3112.build.board=RAKWIRELESS_RAK3112 + +rakwireless_rak3112.build.usb_mode=1 +rakwireless_rak3112.build.cdc_on_boot=1 +rakwireless_rak3112.build.msc_on_boot=0 +rakwireless_rak3112.build.dfu_on_boot=0 + +rakwireless_rak3112.build.f_cpu=240000000L +rakwireless_rak3112.build.flash_size=16MB +rakwireless_rak3112.build.flash_freq=80m +rakwireless_rak3112.build.flash_mode=qio +rakwireless_rak3112.build.boot=qio +rakwireless_rak3112.build.partitions=default +rakwireless_rak3112.build.defines= +rakwireless_rak3112.build.psram_type=opi +rakwireless_rak3112.build.memory_type={build.boot}_{build.psram_type} + +rakwireless_rak3112.menu.PSRAM.enabled=Enabled +rakwireless_rak3112.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM +rakwireless_rak3112.menu.PSRAM.enabled.build.psram_type=opi +rakwireless_rak3112.menu.PSRAM.disabled=Disabled +rakwireless_rak3112.menu.PSRAM.disabled.build.defines= + +rakwireless_rak3112.menu.LoopCore.1=Core 1 +rakwireless_rak3112.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1 +rakwireless_rak3112.menu.LoopCore.0=Core 0 +rakwireless_rak3112.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0 + +rakwireless_rak3112.menu.EventsCore.1=Core 1 +rakwireless_rak3112.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1 +rakwireless_rak3112.menu.EventsCore.0=Core 0 +rakwireless_rak3112.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0 + +rakwireless_rak3112.menu.USBMode.hwcdc=Hardware CDC and JTAG +rakwireless_rak3112.menu.USBMode.hwcdc.build.usb_mode=1 +rakwireless_rak3112.menu.USBMode.default=USB-OTG (TinyUSB) +rakwireless_rak3112.menu.USBMode.default.build.usb_mode=0 + +rakwireless_rak3112.menu.CDCOnBoot.default=Enabled +rakwireless_rak3112.menu.CDCOnBoot.default.build.cdc_on_boot=1 +rakwireless_rak3112.menu.CDCOnBoot.cdc=Disabled +rakwireless_rak3112.menu.CDCOnBoot.cdc.build.cdc_on_boot=0 + +rakwireless_rak3112.menu.MSCOnBoot.default=Disabled +rakwireless_rak3112.menu.MSCOnBoot.default.build.msc_on_boot=0 +rakwireless_rak3112.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode) +rakwireless_rak3112.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +rakwireless_rak3112.menu.DFUOnBoot.default=Disabled +rakwireless_rak3112.menu.DFUOnBoot.default.build.dfu_on_boot=0 +rakwireless_rak3112.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode) +rakwireless_rak3112.menu.DFUOnBoot.dfu.build.dfu_on_boot=1 + +rakwireless_rak3112.menu.UploadMode.default=UART0 / Hardware CDC +rakwireless_rak3112.menu.UploadMode.default.upload.use_1200bps_touch=false +rakwireless_rak3112.menu.UploadMode.default.upload.wait_for_upload_port=false +rakwireless_rak3112.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB) +rakwireless_rak3112.menu.UploadMode.cdc.upload.use_1200bps_touch=true +rakwireless_rak3112.menu.UploadMode.cdc.upload.wait_for_upload_port=true + +rakwireless_rak3112.menu.PartitionScheme.default_16MB=Default (6.25MB APP/3.43MB SPIFFS) +rakwireless_rak3112.menu.PartitionScheme.default_16MB.build.partitions=default_16MB +rakwireless_rak3112.menu.PartitionScheme.default_16MB.upload.maximum_size=6553600 +rakwireless_rak3112.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9MB FATFS) +rakwireless_rak3112.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB +rakwireless_rak3112.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728 +rakwireless_rak3112.menu.PartitionScheme.tinyuf2=TinyUF2 16MB (2MB APP/11.6MB FATFS) +rakwireless_rak3112.menu.PartitionScheme.tinyuf2.build.custom_bootloader=bootloader-tinyuf2 +rakwireless_rak3112.menu.PartitionScheme.tinyuf2.build.partitions=tinyuf2-partitions-16MB +rakwireless_rak3112.menu.PartitionScheme.tinyuf2.upload.maximum_size=2097152 +rakwireless_rak3112.menu.PartitionScheme.tinyuf2.upload.extra_flags=0x410000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin" +rakwireless_rak3112.menu.PartitionScheme.tinyuf2_noota=TinyUF2 16MB No OTA(4MB APP/11.6MB FATFS) +rakwireless_rak3112.menu.PartitionScheme.tinyuf2_noota.build.custom_bootloader=bootloader-tinyuf2 +rakwireless_rak3112.menu.PartitionScheme.tinyuf2_noota.build.partitions=tinyuf2-partitions-16MB-noota +rakwireless_rak3112.menu.PartitionScheme.tinyuf2_noota.upload.maximum_size=4194304 +rakwireless_rak3112.menu.PartitionScheme.tinyuf2_noota.upload.extra_flags=0x410000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin" +rakwireless_rak3112.menu.PartitionScheme.large_spiffs=Large SPIFFS (4.5MB APP/6.93MB SPIFFS) +rakwireless_rak3112.menu.PartitionScheme.large_spiffs.build.partitions=large_spiffs_16MB +rakwireless_rak3112.menu.PartitionScheme.large_spiffs.upload.maximum_size=4718592 +rakwireless_rak3112.menu.PartitionScheme.custom=Custom +rakwireless_rak3112.menu.PartitionScheme.custom.build.partitions= +rakwireless_rak3112.menu.PartitionScheme.custom.upload.maximum_size=16777216 + +rakwireless_rak3112.menu.CPUFreq.240=240MHz (WiFi/BT) +rakwireless_rak3112.menu.CPUFreq.240.build.f_cpu=240000000L +rakwireless_rak3112.menu.CPUFreq.160=160MHz (WiFi/BT) +rakwireless_rak3112.menu.CPUFreq.160.build.f_cpu=160000000L +rakwireless_rak3112.menu.CPUFreq.80=80MHz (WiFi/BT) +rakwireless_rak3112.menu.CPUFreq.80.build.f_cpu=80000000L + +rakwireless_rak3112.menu.FlashMode.qio=QIO +rakwireless_rak3112.menu.FlashMode.qio.build.flash_mode=dio +rakwireless_rak3112.menu.FlashMode.qio.build.boot=qio +rakwireless_rak3112.menu.FlashMode.dio=DIO +rakwireless_rak3112.menu.FlashMode.dio.build.flash_mode=dio +rakwireless_rak3112.menu.FlashMode.dio.build.boot=dio + +rakwireless_rak3112.menu.FlashFreq.80=80MHz +rakwireless_rak3112.menu.FlashFreq.80.build.flash_freq=80m +rakwireless_rak3112.menu.FlashFreq.40=40MHz +rakwireless_rak3112.menu.FlashFreq.40.build.flash_freq=40m + +rakwireless_rak3112.menu.UploadSpeed.921600=921600 +rakwireless_rak3112.menu.UploadSpeed.921600.upload.speed=921600 +rakwireless_rak3112.menu.UploadSpeed.115200=115200 +rakwireless_rak3112.menu.UploadSpeed.115200.upload.speed=115200 +rakwireless_rak3112.menu.UploadSpeed.256000.windows=256000 +rakwireless_rak3112.menu.UploadSpeed.256000.upload.speed=256000 +rakwireless_rak3112.menu.UploadSpeed.230400.windows.upload.speed=256000 +rakwireless_rak3112.menu.UploadSpeed.230400=230400 +rakwireless_rak3112.menu.UploadSpeed.230400.upload.speed=230400 +rakwireless_rak3112.menu.UploadSpeed.460800.linux=460800 +rakwireless_rak3112.menu.UploadSpeed.460800.macosx=460800 +rakwireless_rak3112.menu.UploadSpeed.460800.upload.speed=460800 +rakwireless_rak3112.menu.UploadSpeed.512000.windows=512000 +rakwireless_rak3112.menu.UploadSpeed.512000.upload.speed=512000 + +rakwireless_rak3112.menu.DebugLevel.none=None +rakwireless_rak3112.menu.DebugLevel.none.build.code_debug=0 +rakwireless_rak3112.menu.DebugLevel.error=Error +rakwireless_rak3112.menu.DebugLevel.error.build.code_debug=1 +rakwireless_rak3112.menu.DebugLevel.warn=Warn +rakwireless_rak3112.menu.DebugLevel.warn.build.code_debug=2 +rakwireless_rak3112.menu.DebugLevel.info=Info +rakwireless_rak3112.menu.DebugLevel.info.build.code_debug=3 +rakwireless_rak3112.menu.DebugLevel.debug=Debug +rakwireless_rak3112.menu.DebugLevel.debug.build.code_debug=4 +rakwireless_rak3112.menu.DebugLevel.verbose=Verbose +rakwireless_rak3112.menu.DebugLevel.verbose.build.code_debug=5 + +rakwireless_rak3112.menu.EraseFlash.none=Disabled +rakwireless_rak3112.menu.EraseFlash.none.upload.erase_cmd= +rakwireless_rak3112.menu.EraseFlash.all=Enabled +rakwireless_rak3112.menu.EraseFlash.all.upload.erase_cmd=-e + +############################################################## +kodedot.name=kode dot + +kodedot.bootloader.tool=esptool_py +kodedot.bootloader.tool.default=esptool_py + +kodedot.upload.tool=esptool_py_app_only +kodedot.upload.tool.default=esptool_py_app_only +kodedot.upload.tool.network=esp_ota + +kodedot.upload.maximum_size=8388608 +kodedot.upload.maximum_data_size=327680 +kodedot.upload.flags= +kodedot.upload.extra_flags= +kodedot.upload.use_1200bps_touch=false +kodedot.upload.wait_for_upload_port=false +kodedot.upload.speed=921600 + +kodedot.upload.erase_cmd= + +kodedot.serial.disableDTR=false +kodedot.serial.disableRTS=false + +kodedot.build.tarch=xtensa +kodedot.build.bootloader_addr=0x0 +kodedot.build.target=esp32s3 +kodedot.build.mcu=esp32s3 +kodedot.build.core=esp32 +kodedot.build.variant=kodedot +kodedot.build.board=KODE_DOT + +kodedot.build.usb_mode=1 +kodedot.build.cdc_on_boot=1 +kodedot.build.msc_on_boot=0 +kodedot.build.dfu_on_boot=0 + +kodedot.build.f_cpu=240000000L + +kodedot.build.flash_offset=0x400000 +kodedot.build.flash_size=16MB +kodedot.build.flash_freq=80m +kodedot.build.flash_mode=dio + +kodedot.build.custom_partitions=kodedot_partitions + +kodedot.build.psram_type=qspi +kodedot.build.defines= + +kodedot.build.loop_core=-DARDUINO_RUNNING_CORE=1 +kodedot.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1 + +kodedot.recipe.hooks.objcopy.postobjcopy.3.pattern= +kodedot.recipe.hooks.objcopy.postobjcopy.3.pattern_args= + +kodedot.recipe.output.save_file={build.project_name}.ino.bin + +############################################################## + +# FED4 Board +fed4.name=FED4 +fed4.vid.0=0x303A +fed4.pid.0=0x82E5 +fed4.upload_port.0.vid=0x303A +fed4.upload_port.0.pid=0x82E5 +fed4.bootloader.tool=esptool_py +fed4.bootloader.tool.default=esptool_py + +fed4.upload.tool=esptool_py +fed4.upload.tool.default=esptool_py +fed4.upload.tool.network=esp_ota + +fed4.upload.maximum_size=1310720 +fed4.upload.maximum_data_size=327680 +fed4.upload.flags= +fed4.upload.extra_flags= +fed4.upload.use_1200bps_touch=false +fed4.upload.wait_for_upload_port=false + +fed4.serial.disableDTR=false +fed4.serial.disableRTS=false + +fed4.build.tarch=xtensa +fed4.build.bootloader_addr=0x0 +fed4.build.target=esp32s3 +fed4.build.mcu=esp32s3 +fed4.build.core=esp32 +fed4.build.variant=fed4 +fed4.build.board=FED4 + +fed4.build.usb_mode=1 +fed4.build.cdc_on_boot=0 +fed4.build.msc_on_boot=0 +fed4.build.dfu_on_boot=0 +fed4.build.f_cpu=240000000L +fed4.build.flash_size=16MB +fed4.build.flash_freq=80m +fed4.build.flash_mode=dio +fed4.build.boot=qio +fed4.build.boot_freq=80m +fed4.build.partitions=default_16MB +fed4.build.defines= +fed4.build.loop_core= +fed4.build.event_core= +fed4.build.psram_type=qspi +fed4.build.memory_type={build.boot}_{build.psram_type} + +## IDE 2.0 Seems to not update the value +fed4.menu.JTAGAdapter.default=Disabled +fed4.menu.JTAGAdapter.default.build.copy_jtag_files=0 +fed4.menu.JTAGAdapter.builtin=Integrated USB JTAG +fed4.menu.JTAGAdapter.builtin.build.openocdscript=fed4-builtin.cfg +fed4.menu.JTAGAdapter.builtin.build.copy_jtag_files=1 +fed4.menu.JTAGAdapter.external=FTDI Adapter +fed4.menu.JTAGAdapter.external.build.openocdscript=fed4-ftdi.cfg +fed4.menu.JTAGAdapter.external.build.copy_jtag_files=1 +fed4.menu.JTAGAdapter.bridge=ESP USB Bridge +fed4.menu.JTAGAdapter.bridge.build.openocdscript=fed4-bridge.cfg +fed4.menu.JTAGAdapter.bridge.build.copy_jtag_files=1 + +fed4.menu.FlashMode.qio=QIO 80MHz +fed4.menu.FlashMode.qio.build.flash_mode=dio +fed4.menu.FlashMode.qio.build.boot=qio +fed4.menu.FlashMode.qio.build.boot_freq=80m +fed4.menu.FlashMode.qio.build.flash_freq=80m +fed4.menu.FlashMode.qio120=QIO 120MHz +fed4.menu.FlashMode.qio120.build.flash_mode=dio +fed4.menu.FlashMode.qio120.build.boot=qio +fed4.menu.FlashMode.qio120.build.boot_freq=120m +fed4.menu.FlashMode.qio120.build.flash_freq=80m +fed4.menu.FlashMode.dio=DIO 80MHz +fed4.menu.FlashMode.dio.build.flash_mode=dio +fed4.menu.FlashMode.dio.build.boot=dio +fed4.menu.FlashMode.dio.build.boot_freq=80m +fed4.menu.FlashMode.dio.build.flash_freq=80m + +fed4.menu.FlashSize.16M=16MB (128Mb) +fed4.menu.FlashSize.16M.build.flash_size=16MB + +fed4.menu.LoopCore.1=Core 1 +fed4.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1 +fed4.menu.LoopCore.0=Core 0 +fed4.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0 + +fed4.menu.EventsCore.1=Core 1 +fed4.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1 +fed4.menu.EventsCore.0=Core 0 +fed4.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0 + +fed4.menu.USBMode.hwcdc=Hardware CDC and JTAG +fed4.menu.USBMode.hwcdc.build.usb_mode=1 +fed4.menu.USBMode.default=USB-OTG (TinyUSB) +fed4.menu.USBMode.default.build.usb_mode=0 + +fed4.menu.CDCOnBoot.default=Disabled +fed4.menu.CDCOnBoot.default.build.cdc_on_boot=0 +fed4.menu.CDCOnBoot.cdc=Enabled +fed4.menu.CDCOnBoot.cdc.build.cdc_on_boot=1 + +fed4.menu.MSCOnBoot.default=Disabled +fed4.menu.MSCOnBoot.default.build.msc_on_boot=0 +fed4.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode) +fed4.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +fed4.menu.DFUOnBoot.default=Disabled +fed4.menu.DFUOnBoot.default.build.dfu_on_boot=0 +fed4.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode) +fed4.menu.DFUOnBoot.dfu.build.dfu_on_boot=1 + +fed4.menu.UploadMode.default=UART0 / Hardware CDC +fed4.menu.UploadMode.default.upload.use_1200bps_touch=false +fed4.menu.UploadMode.default.upload.wait_for_upload_port=false +fed4.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB) +fed4.menu.UploadMode.cdc.upload.use_1200bps_touch=true +fed4.menu.UploadMode.cdc.upload.wait_for_upload_port=true + +fed4.menu.PartitionScheme.default_16MB=Default (6.25MB APP/3.43MB SPIFFS) +fed4.menu.PartitionScheme.default_16MB.build.partitions=default_16MB +fed4.menu.PartitionScheme.default_16MB.upload.maximum_size=6553600 +fed4.menu.PartitionScheme.large_spiffs=Large SPIFFS (4.5MB APP/6.93MB SPIFFS) +fed4.menu.PartitionScheme.large_spiffs.build.partitions=large_spiffs_16MB +fed4.menu.PartitionScheme.large_spiffs.upload.maximum_size=4718592 +fed4.menu.PartitionScheme.app3M_fat9M_16MB=FFAT (3MB APP/9MB FATFS) +fed4.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB +fed4.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728 +fed4.menu.PartitionScheme.fatflash=Large FFAT (2MB APP/12.5MB FATFS) +fed4.menu.PartitionScheme.fatflash.build.partitions=ffat +fed4.menu.PartitionScheme.fatflash.upload.maximum_size=2097152 + +fed4.menu.CPUFreq.240=240MHz (WiFi) +fed4.menu.CPUFreq.240.build.f_cpu=240000000L +fed4.menu.CPUFreq.160=160MHz (WiFi) +fed4.menu.CPUFreq.160.build.f_cpu=160000000L +fed4.menu.CPUFreq.80=80MHz (WiFi) +fed4.menu.CPUFreq.80.build.f_cpu=80000000L +fed4.menu.CPUFreq.40=40MHz +fed4.menu.CPUFreq.40.build.f_cpu=40000000L +fed4.menu.CPUFreq.20=20MHz +fed4.menu.CPUFreq.20.build.f_cpu=20000000L +fed4.menu.CPUFreq.10=10MHz +fed4.menu.CPUFreq.10.build.f_cpu=10000000L + +fed4.menu.UploadSpeed.921600=921600 +fed4.menu.UploadSpeed.921600.upload.speed=921600 +fed4.menu.UploadSpeed.115200=115200 +fed4.menu.UploadSpeed.115200.upload.speed=115200 +fed4.menu.UploadSpeed.256000.windows=256000 +fed4.menu.UploadSpeed.256000.upload.speed=256000 +fed4.menu.UploadSpeed.230400.windows.upload.speed=256000 +fed4.menu.UploadSpeed.230400=230400 +fed4.menu.UploadSpeed.230400.upload.speed=230400 +fed4.menu.UploadSpeed.460800.linux=460800 +fed4.menu.UploadSpeed.460800.macosx=460800 +fed4.menu.UploadSpeed.460800.upload.speed=460800 +fed4.menu.UploadSpeed.512000.windows=512000 +fed4.menu.UploadSpeed.512000.upload.speed=512000 + +fed4.menu.DebugLevel.none=None +fed4.menu.DebugLevel.none.build.code_debug=0 +fed4.menu.DebugLevel.error=Error +fed4.menu.DebugLevel.error.build.code_debug=1 +fed4.menu.DebugLevel.warn=Warn +fed4.menu.DebugLevel.warn.build.code_debug=2 +fed4.menu.DebugLevel.info=Info +fed4.menu.DebugLevel.info.build.code_debug=3 +fed4.menu.DebugLevel.debug=Debug +fed4.menu.DebugLevel.debug.build.code_debug=4 +fed4.menu.DebugLevel.verbose=Verbose +fed4.menu.DebugLevel.verbose.build.code_debug=5 + +fed4.menu.EraseFlash.none=Disabled +fed4.menu.EraseFlash.none.upload.erase_cmd= +fed4.menu.EraseFlash.all=Enabled +fed4.menu.EraseFlash.all.upload.erase_cmd=-e + +fed4.menu.ZigbeeMode.default=Disabled +fed4.menu.ZigbeeMode.default.build.zigbee_mode= +fed4.menu.ZigbeeMode.default.build.zigbee_libs= +fed4.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) +fed4.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR +fed4.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote + +############################################################## diff --git a/cores/esp32/WString.cpp b/cores/esp32/WString.cpp index 18e64767545..6632aa5f85d 100644 --- a/cores/esp32/WString.cpp +++ b/cores/esp32/WString.cpp @@ -180,7 +180,7 @@ bool String::changeBuffer(unsigned int maxStrLen) { if (maxStrLen < sizeof(sso.buff) - 1) { if (isSSO() || !buffer()) { // Already using SSO, nothing to do - uint16_t oldLen = len(); + size_t oldLen = len(); setSSO(true); setLen(oldLen); } else { // if bufptr && !isSSO() @@ -188,7 +188,7 @@ bool String::changeBuffer(unsigned int maxStrLen) { char temp[sizeof(sso.buff)]; memcpy(temp, buffer(), maxStrLen); free(wbuffer()); - uint16_t oldLen = len(); + size_t oldLen = len(); setSSO(true); memcpy(wbuffer(), temp, maxStrLen); setLen(oldLen); @@ -201,7 +201,7 @@ bool String::changeBuffer(unsigned int maxStrLen) { if (newSize > CAPACITY_MAX) { return false; } - uint16_t oldLen = len(); + size_t oldLen = len(); char *newbuffer = (char *)realloc(isSSO() ? nullptr : wbuffer(), newSize); if (newbuffer) { size_t oldSize = capacity() + 1; // include NULL. diff --git a/cores/esp32/esp32-hal-i2c-ng.c b/cores/esp32/esp32-hal-i2c-ng.c index 8e48d0e0397..a3b2307b8a8 100644 --- a/cores/esp32/esp32-hal-i2c-ng.c +++ b/cores/esp32/esp32-hal-i2c-ng.c @@ -56,6 +56,13 @@ static bool i2cDetachBus(void *bus_i2c_num) { return true; } +void *i2cBusHandle(uint8_t i2c_num) { + if (i2c_num >= SOC_I2C_NUM) { + return NULL; + } + return bus[i2c_num].bus_handle; +} + bool i2cIsInit(uint8_t i2c_num) { if (i2c_num >= SOC_I2C_NUM) { return false; diff --git a/cores/esp32/esp32-hal-i2c.h b/cores/esp32/esp32-hal-i2c.h index 35783d350b0..0e4f484bb46 100644 --- a/cores/esp32/esp32-hal-i2c.h +++ b/cores/esp32/esp32-hal-i2c.h @@ -19,6 +19,7 @@ #include "soc/soc_caps.h" #if SOC_I2C_SUPPORTED +#include "esp_idf_version.h" #ifdef __cplusplus extern "C" { @@ -39,6 +40,10 @@ esp_err_t i2cWriteReadNonStop( ); bool i2cIsInit(uint8_t i2c_num); +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) +void *i2cBusHandle(uint8_t i2c_num); +#endif + #ifdef __cplusplus } #endif diff --git a/cores/esp32/esp32-hal-spi.c b/cores/esp32/esp32-hal-spi.c index d39aceb5f8d..107b94da0d6 100644 --- a/cores/esp32/esp32-hal-spi.c +++ b/cores/esp32/esp32-hal-spi.c @@ -60,6 +60,7 @@ #elif CONFIG_IDF_TARGET_ESP32P4 #include "esp32p4/rom/ets_sys.h" #include "esp32p4/rom/gpio.h" +#include "hal/spi_ll.h" #else #error Target CONFIG_IDF_TARGET is not supported #endif @@ -639,9 +640,6 @@ spi_t *spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t } else if (spi_num == HSPI) { DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN); DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST); - } else { - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN); - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST); } #elif CONFIG_IDF_TARGET_ESP32S3 if (spi_num == FSPI) { @@ -662,6 +660,31 @@ spi_t *spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN); DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST); } +#elif CONFIG_IDF_TARGET_ESP32P4 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" + if (spi_num == FSPI) { + PERIPH_RCC_ACQUIRE_ATOMIC(PERIPH_GPSPI2_MODULE, ref_count) { + if (ref_count == 0) { + PERIPH_RCC_ATOMIC() { + spi_ll_enable_bus_clock(SPI2_HOST, true); + spi_ll_reset_register(SPI2_HOST); + spi_ll_enable_clock(SPI2_HOST, true); + } + } + } + } else if (spi_num == HSPI) { + PERIPH_RCC_ACQUIRE_ATOMIC(PERIPH_GPSPI3_MODULE, ref_count) { + if (ref_count == 0) { + PERIPH_RCC_ATOMIC() { + spi_ll_enable_bus_clock(SPI3_HOST, true); + spi_ll_reset_register(SPI3_HOST); + spi_ll_enable_clock(SPI3_HOST, true); + } + } + } + } +#pragma GCC diagnostic pop #elif defined(__PERIPH_CTRL_ALLOW_LEGACY_API) periph_ll_reset(PERIPH_SPI2_MODULE); periph_ll_enable_clk_clear_rst(PERIPH_SPI2_MODULE); diff --git a/cores/esp32/esp_arduino_version.h b/cores/esp32/esp_arduino_version.h index b1355e908ae..97bb3ac794b 100644 --- a/cores/esp32/esp_arduino_version.h +++ b/cores/esp32/esp_arduino_version.h @@ -23,7 +23,7 @@ extern "C" { /** Minor version number (x.X.x) */ #define ESP_ARDUINO_VERSION_MINOR 2 /** Patch version number (x.x.X) */ -#define ESP_ARDUINO_VERSION_PATCH 0 +#define ESP_ARDUINO_VERSION_PATCH 1 /** * Macro to convert ARDUINO version number into an integer diff --git a/libraries/ArduinoOTA/library.properties b/libraries/ArduinoOTA/library.properties index 0796eddf318..18de5aa2180 100644 --- a/libraries/ArduinoOTA/library.properties +++ b/libraries/ArduinoOTA/library.properties @@ -1,5 +1,5 @@ name=ArduinoOTA -version=3.2.0 +version=3.2.1 author=Ivan Grokhotkov and Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables Over The Air upgrades, via wifi and espota.py UDP request/TCP download. diff --git a/libraries/AsyncUDP/library.properties b/libraries/AsyncUDP/library.properties index 116dcbacaa8..c64c60d0421 100644 --- a/libraries/AsyncUDP/library.properties +++ b/libraries/AsyncUDP/library.properties @@ -1,5 +1,5 @@ name=ESP32 Async UDP -version=3.2.0 +version=3.2.1 author=Me-No-Dev maintainer=Me-No-Dev sentence=Async UDP Library for ESP32 diff --git a/libraries/AsyncUDP/src/AsyncUDP.cpp b/libraries/AsyncUDP/src/AsyncUDP.cpp index cab9c951921..2d533831cd5 100644 --- a/libraries/AsyncUDP/src/AsyncUDP.cpp +++ b/libraries/AsyncUDP/src/AsyncUDP.cpp @@ -582,8 +582,8 @@ bool AsyncUDP::listen(const ip_addr_t *addr, uint16_t port) { } close(); if (addr) { - IP_SET_TYPE_VAL(_pcb->local_ip, addr->type); - IP_SET_TYPE_VAL(_pcb->remote_ip, addr->type); + IP_SET_TYPE_VAL(_pcb->local_ip, IP_GET_TYPE(addr)); + IP_SET_TYPE_VAL(_pcb->remote_ip, IP_GET_TYPE(addr)); } if (_udp_bind(_pcb, addr, port) != ERR_OK) { return false; @@ -692,17 +692,8 @@ bool AsyncUDP::listenMulticast(const ip_addr_t *addr, uint16_t port, uint8_t ttl return false; } -#if CONFIG_LWIP_IPV6 - if (IP_IS_V6(addr)) { - IP_SET_TYPE(&bind_addr, IPADDR_TYPE_V6); - ip6_addr_set_any(&bind_addr.u_addr.ip6); - } else { -#endif - IP_SET_TYPE(&bind_addr, IPADDR_TYPE_V4); - ip4_addr_set_any(&bind_addr.u_addr.ip4); -#if CONFIG_LWIP_IPV6 - } -#endif + IP_SET_TYPE(&bind_addr, IP_GET_TYPE(addr)); + ip_addr_set_any(IP_IS_V6(addr), &bind_addr); if (!listen(&bind_addr, port)) { return false; } diff --git a/libraries/BLE/library.properties b/libraries/BLE/library.properties index 7ef636223ec..b009b14e194 100644 --- a/libraries/BLE/library.properties +++ b/libraries/BLE/library.properties @@ -1,5 +1,5 @@ name=BLE -version=3.2.0 +version=3.2.1 author=Neil Kolban maintainer=Dariusz Krempa sentence=BLE functions for ESP32 diff --git a/libraries/BluetoothSerial/library.properties b/libraries/BluetoothSerial/library.properties index 0a382410bba..4bc1427e3f8 100644 --- a/libraries/BluetoothSerial/library.properties +++ b/libraries/BluetoothSerial/library.properties @@ -1,5 +1,5 @@ name=BluetoothSerial -version=3.2.0 +version=3.2.1 author=Evandro Copercini maintainer=Evandro Copercini sentence=Simple UART to Classical Bluetooth bridge for ESP32 diff --git a/libraries/DNSServer/library.properties b/libraries/DNSServer/library.properties index 5e70a6ec03a..42e4c38dc9d 100644 --- a/libraries/DNSServer/library.properties +++ b/libraries/DNSServer/library.properties @@ -1,5 +1,5 @@ name=DNSServer -version=3.2.0 +version=3.2.1 author=Kristijan Novoselić maintainer=Kristijan Novoselić, sentence=A simple DNS server for ESP32. diff --git a/libraries/EEPROM/library.properties b/libraries/EEPROM/library.properties index c7e48501c04..ee1caae0792 100644 --- a/libraries/EEPROM/library.properties +++ b/libraries/EEPROM/library.properties @@ -1,5 +1,5 @@ name=EEPROM -version=3.2.0 +version=3.2.1 author=Ivan Grokhotkov maintainer=Paolo Becchi sentence=Enables reading and writing data a sequential, addressable FLASH storage diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino b/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino index d483e11b1df..83733d4b5cf 100644 --- a/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino +++ b/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino @@ -1,37 +1,10 @@ #include "esp_camera.h" #include -// -// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality -// Ensure ESP32 Wrover Module or other board with PSRAM is selected -// Partial images will be transmitted if image exceeds buffer size -// -// You must select partition scheme from the board menu that has at least 3MB APP space. -// Face Recognition is DISABLED for ESP32 and ESP32-S2, because it takes up from 15 -// seconds to process single frame. Face Detection is ENABLED if PSRAM is enabled as well - -// =================== -// Select camera model -// =================== -//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM -#define CAMERA_MODEL_ESP_EYE // Has PSRAM -//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM -//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM -//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM -//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM -//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM -//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM -//#define CAMERA_MODEL_M5STACK_CAMS3_UNIT // Has PSRAM -//#define CAMERA_MODEL_AI_THINKER // Has PSRAM -//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM -//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM -// ** Espressif Internal Boards ** -//#define CAMERA_MODEL_ESP32_CAM_BOARD -//#define CAMERA_MODEL_ESP32S2_CAM_BOARD -//#define CAMERA_MODEL_ESP32S3_CAM_LCD -//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM -//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM -#include "camera_pins.h" +// =========================== +// Select camera model in board_config.h +// =========================== +#include "board_config.h" // =========================== // Enter your WiFi credentials @@ -40,7 +13,7 @@ const char *ssid = "**********"; const char *password = "**********"; void startCameraServer(); -void setupLedFlash(int pin); +void setupLedFlash(); void setup() { Serial.begin(115200); @@ -130,7 +103,7 @@ void setup() { // Setup LED FLash if LED pin is defined in camera_pins.h #if defined(LED_GPIO_NUM) - setupLedFlash(LED_GPIO_NUM); + setupLedFlash(); #endif WiFi.begin(ssid, password); diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp index cc924bd5b3b..589fea33b7f 100644 --- a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp +++ b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp @@ -19,18 +19,14 @@ #include "esp32-hal-ledc.h" #include "sdkconfig.h" #include "camera_index.h" +#include "board_config.h" #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG) #include "esp32-hal-log.h" #endif -// Enable LED FLASH setting -#define CONFIG_LED_ILLUMINATOR_ENABLED 1 - // LED FLASH setup -#if CONFIG_LED_ILLUMINATOR_ENABLED - -#define LED_LEDC_GPIO 22 //configure LED pin +#if defined(LED_GPIO_NUM) #define CONFIG_LED_MAX_INTENSITY 255 int led_duty = 0; @@ -91,13 +87,13 @@ static int ra_filter_run(ra_filter_t *filter, int value) { } #endif -#if CONFIG_LED_ILLUMINATOR_ENABLED +#if defined(LED_GPIO_NUM) void enable_led(bool en) { // Turn LED On or Off int duty = en ? led_duty : 0; if (en && isStreaming && (led_duty > CONFIG_LED_MAX_INTENSITY)) { duty = CONFIG_LED_MAX_INTENSITY; } - ledcWrite(LED_LEDC_GPIO, duty); + ledcWrite(LED_GPIO_NUM, duty); //ledc_set_duty(CONFIG_LED_LEDC_SPEED_MODE, CONFIG_LED_LEDC_CHANNEL, duty); //ledc_update_duty(CONFIG_LED_LEDC_SPEED_MODE, CONFIG_LED_LEDC_CHANNEL); log_i("Set LED intensity to %d", duty); @@ -162,7 +158,7 @@ static esp_err_t capture_handler(httpd_req_t *req) { int64_t fr_start = esp_timer_get_time(); #endif -#if CONFIG_LED_ILLUMINATOR_ENABLED +#if defined(LED_GPIO_NUM) enable_led(true); vTaskDelay(150 / portTICK_PERIOD_MS); // The LED needs to be turned on ~150ms before the call to esp_camera_fb_get() fb = esp_camera_fb_get(); // or it won't be visible in the frame. A better way to do this is needed. @@ -230,7 +226,7 @@ static esp_err_t stream_handler(httpd_req_t *req) { httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); httpd_resp_set_hdr(req, "X-Framerate", "60"); -#if CONFIG_LED_ILLUMINATOR_ENABLED +#if defined(LED_GPIO_NUM) isStreaming = true; enable_led(true); #endif @@ -293,7 +289,7 @@ static esp_err_t stream_handler(httpd_req_t *req) { ); } -#if CONFIG_LED_ILLUMINATOR_ENABLED +#if defined(LED_GPIO_NUM) isStreaming = false; enable_led(false); #endif @@ -393,7 +389,7 @@ static esp_err_t cmd_handler(httpd_req_t *req) { } else if (!strcmp(variable, "ae_level")) { res = s->set_ae_level(s, val); } -#if CONFIG_LED_ILLUMINATOR_ENABLED +#if defined(LED_GPIO_NUM) else if (!strcmp(variable, "led_intensity")) { led_duty = val; if (isStreaming) { @@ -481,7 +477,7 @@ static esp_err_t status_handler(httpd_req_t *req) { p += sprintf(p, "\"vflip\":%u,", s->status.vflip); p += sprintf(p, "\"dcw\":%u,", s->status.dcw); p += sprintf(p, "\"colorbar\":%u", s->status.colorbar); -#if CONFIG_LED_ILLUMINATOR_ENABLED +#if defined(LED_GPIO_NUM) p += sprintf(p, ",\"led_intensity\":%u", led_duty); #else p += sprintf(p, ",\"led_intensity\":%d", -1); @@ -843,10 +839,10 @@ void startCameraServer() { } } -void setupLedFlash(int pin) { -#if CONFIG_LED_ILLUMINATOR_ENABLED - ledcAttach(pin, 5000, 8); +void setupLedFlash() { +#if defined(LED_GPIO_NUM) + ledcAttach(LED_GPIO_NUM, 5000, 8); #else - log_i("LED flash is disabled -> CONFIG_LED_ILLUMINATOR_ENABLED = 0"); + log_i("LED flash is disabled -> LED_GPIO_NUM undefined"); #endif } diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/board_config.h b/libraries/ESP32/examples/Camera/CameraWebServer/board_config.h new file mode 100644 index 00000000000..ca7edbab73e --- /dev/null +++ b/libraries/ESP32/examples/Camera/CameraWebServer/board_config.h @@ -0,0 +1,34 @@ +#ifndef BOARD_CONFIG_H +#define BOARD_CONFIG_H + +// +// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality +// Ensure ESP32 Wrover Module or other board with PSRAM is selected +// Partial images will be transmitted if image exceeds buffer size +// +// You must select partition scheme from the board menu that has at least 3MB APP space. + +// =================== +// Select camera model +// =================== +//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM +#define CAMERA_MODEL_ESP_EYE // Has PSRAM +//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM +//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM +//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM +//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM +//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM +//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM +//#define CAMERA_MODEL_M5STACK_CAMS3_UNIT // Has PSRAM +//#define CAMERA_MODEL_AI_THINKER // Has PSRAM +//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM +//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM +// ** Espressif Internal Boards ** +//#define CAMERA_MODEL_ESP32_CAM_BOARD +//#define CAMERA_MODEL_ESP32S2_CAM_BOARD +//#define CAMERA_MODEL_ESP32S3_CAM_LCD +//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM +//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM +#include "camera_pins.h" + +#endif // BOARD_CONFIG_H diff --git a/libraries/ESP32/library.properties b/libraries/ESP32/library.properties index 7ebc69be71f..0815a69ce6b 100644 --- a/libraries/ESP32/library.properties +++ b/libraries/ESP32/library.properties @@ -1,5 +1,5 @@ name=ESP32 -version=3.2.0 +version=3.2.1 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 sketches examples diff --git a/libraries/ESP_I2S/library.properties b/libraries/ESP_I2S/library.properties index 263e9823275..ff1ad5d59da 100644 --- a/libraries/ESP_I2S/library.properties +++ b/libraries/ESP_I2S/library.properties @@ -1,5 +1,5 @@ name=ESP_I2S -version=3.2.0 +version=3.2.1 author=me-no-dev maintainer=me-no-dev sentence=Library for ESP I2S communication diff --git a/libraries/ESP_NOW/examples/ESP_NOW_Broadcast_Master/ESP_NOW_Broadcast_Master.ino b/libraries/ESP_NOW/examples/ESP_NOW_Broadcast_Master/ESP_NOW_Broadcast_Master.ino index 025a53c913b..7b71c0e432d 100644 --- a/libraries/ESP_NOW/examples/ESP_NOW_Broadcast_Master/ESP_NOW_Broadcast_Master.ino +++ b/libraries/ESP_NOW/examples/ESP_NOW_Broadcast_Master/ESP_NOW_Broadcast_Master.ino @@ -86,6 +86,8 @@ void setup() { ESP.restart(); } + Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen()); + Serial.println("Setup complete. Broadcasting messages every 5 seconds."); } diff --git a/libraries/ESP_NOW/examples/ESP_NOW_Broadcast_Slave/ESP_NOW_Broadcast_Slave.ino b/libraries/ESP_NOW/examples/ESP_NOW_Broadcast_Slave/ESP_NOW_Broadcast_Slave.ino index e61524b64f9..ca0ece2fff8 100644 --- a/libraries/ESP_NOW/examples/ESP_NOW_Broadcast_Slave/ESP_NOW_Broadcast_Slave.ino +++ b/libraries/ESP_NOW/examples/ESP_NOW_Broadcast_Slave/ESP_NOW_Broadcast_Slave.ino @@ -104,6 +104,8 @@ void setup() { ESP.restart(); } + Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen()); + // Register the new peer callback ESP_NOW.onNewPeer(register_new_master, nullptr); diff --git a/libraries/ESP_NOW/examples/ESP_NOW_Network/ESP_NOW_Network.ino b/libraries/ESP_NOW/examples/ESP_NOW_Network/ESP_NOW_Network.ino index 6731340c922..d30d6cd40cf 100644 --- a/libraries/ESP_NOW/examples/ESP_NOW_Network/ESP_NOW_Network.ino +++ b/libraries/ESP_NOW/examples/ESP_NOW_Network/ESP_NOW_Network.ino @@ -75,7 +75,12 @@ // The following struct is used to send data to the peer device. // We use the attribute "packed" to ensure that the struct is not padded (all data // is contiguous in the memory and without gaps). -// The maximum size of the complete message is 250 bytes (ESP_NOW_MAX_DATA_LEN). +// The maximum size of the payload is 250 bytes (ESP_NOW_MAX_DATA_LEN) for ESP-NOW v1.0. +// For ESP-NOW v2.0, the maximum size of the payload is 1470 bytes (ESP_NOW_MAX_DATA_LEN_V2). +// You can use ESP_NOW.getMaxDataLen() after calling ESP_NOW.begin() to get the maximum size +// of the data that can be sent. +// Read about the compatibility between ESP-NOW v1.0 and v2.0 in the ESP-IDF documentation: +// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html#frame-format typedef struct { uint32_t count; @@ -276,6 +281,8 @@ void setup() { fail_reboot(); } + Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen()); + if (!broadcast_peer.begin()) { Serial.println("Failed to initialize broadcast peer"); fail_reboot(); diff --git a/libraries/ESP_NOW/examples/ESP_NOW_Serial/ESP_NOW_Serial.ino b/libraries/ESP_NOW/examples/ESP_NOW_Serial/ESP_NOW_Serial.ino index e1f28382fe2..2a5406cd844 100644 --- a/libraries/ESP_NOW/examples/ESP_NOW_Serial/ESP_NOW_Serial.ino +++ b/libraries/ESP_NOW/examples/ESP_NOW_Serial/ESP_NOW_Serial.ino @@ -64,6 +64,7 @@ void setup() { // Start the ESP-NOW communication Serial.println("ESP-NOW communication starting..."); NowSerial.begin(115200); + Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen()); Serial.println("You can now send data to the peer device using the Serial Monitor.\n"); } diff --git a/libraries/ESP_NOW/library.properties b/libraries/ESP_NOW/library.properties index f3e5c109a9b..426a9464ace 100644 --- a/libraries/ESP_NOW/library.properties +++ b/libraries/ESP_NOW/library.properties @@ -1,5 +1,5 @@ name=ESP_NOW -version=3.2.0 +version=3.2.1 author=me-no-dev maintainer=P-R-O-C-H-Y sentence=Library for ESP_NOW diff --git a/libraries/ESP_NOW/src/ESP32_NOW.cpp b/libraries/ESP_NOW/src/ESP32_NOW.cpp index 25a5609e8db..b5cdc3f3da7 100644 --- a/libraries/ESP_NOW/src/ESP32_NOW.cpp +++ b/libraries/ESP_NOW/src/ESP32_NOW.cpp @@ -140,7 +140,10 @@ static void _esp_now_tx_cb(const uint8_t *mac_addr, esp_now_send_status_t status } } -ESP_NOW_Class::ESP_NOW_Class() {} +ESP_NOW_Class::ESP_NOW_Class() { + max_data_len = 0; + version = 0; +} ESP_NOW_Class::~ESP_NOW_Class() {} @@ -155,6 +158,23 @@ bool ESP_NOW_Class::begin(const uint8_t *pmk) { return false; } + // Unfortunately we can't get the ESP-NOW version before initializing the Wi-Fi + uint32_t esp_now_version; + err = esp_now_get_version(&esp_now_version); + if (err != ESP_OK) { + log_w("esp_now_get_version failed! Assuming ESP-NOW v1.0"); + esp_now_version = 1; + } + + if (esp_now_version == 1) { + max_data_len = ESP_NOW_MAX_DATA_LEN; + } else { + max_data_len = ESP_NOW_MAX_DATA_LEN_V2; + } + + version = esp_now_version; + log_i("ESP-NOW version: %lu, max_data_len: %lu", version, max_data_len); + _esp_now_has_begun = true; memset(_esp_now_peers, 0, sizeof(ESP_NOW_Peer *) * ESP_NOW_MAX_TOTAL_PEER_NUM); @@ -212,7 +232,7 @@ bool ESP_NOW_Class::end() { return true; } -int ESP_NOW_Class::getTotalPeerCount() { +int ESP_NOW_Class::getTotalPeerCount() const { if (!_esp_now_has_begun) { return -1; } @@ -225,7 +245,7 @@ int ESP_NOW_Class::getTotalPeerCount() { return num.total_num; } -int ESP_NOW_Class::getEncryptedPeerCount() { +int ESP_NOW_Class::getEncryptedPeerCount() const { if (!_esp_now_has_begun) { return -1; } @@ -238,16 +258,38 @@ int ESP_NOW_Class::getEncryptedPeerCount() { return num.encrypt_num; } +int ESP_NOW_Class::getMaxDataLen() const { + if (max_data_len == 0) { + log_e("ESP-NOW not initialized. Please call begin() first to get the max data length."); + return -1; + } + + return max_data_len; +} + +int ESP_NOW_Class::getVersion() const { + if (version == 0) { + log_e("ESP-NOW not initialized. Please call begin() first to get the version."); + return -1; + } + + return version; +} + int ESP_NOW_Class::availableForWrite() { - return ESP_NOW_MAX_DATA_LEN; + int available = getMaxDataLen(); + if (available < 0) { + return 0; + } + return available; } size_t ESP_NOW_Class::write(const uint8_t *data, size_t len) { if (!_esp_now_has_begun) { return 0; } - if (len > ESP_NOW_MAX_DATA_LEN) { - len = ESP_NOW_MAX_DATA_LEN; + if (len > max_data_len) { + len = max_data_len; } esp_err_t result = esp_now_send(nullptr, data, len); if (result == ESP_OK) { @@ -386,8 +428,15 @@ size_t ESP_NOW_Peer::send(const uint8_t *data, int len) { log_e("Peer not added."); return 0; } - if (len > ESP_NOW_MAX_DATA_LEN) { - len = ESP_NOW_MAX_DATA_LEN; + + int max_data_len = ESP_NOW.getMaxDataLen(); + if (max_data_len < 0) { + log_e("Error getting max data length."); + return 0; + } + + if (len > max_data_len) { + len = max_data_len; } esp_err_t result = esp_now_send(mac, data, len); if (result == ESP_OK) { diff --git a/libraries/ESP_NOW/src/ESP32_NOW.h b/libraries/ESP_NOW/src/ESP32_NOW.h index 5940cfa2221..5b5bbe72673 100644 --- a/libraries/ESP_NOW/src/ESP32_NOW.h +++ b/libraries/ESP_NOW/src/ESP32_NOW.h @@ -23,8 +23,10 @@ class ESP_NOW_Class : public Print { bool begin(const uint8_t *pmk = nullptr /* 16 bytes */); bool end(); - int getTotalPeerCount(); - int getEncryptedPeerCount(); + int getTotalPeerCount() const; + int getEncryptedPeerCount() const; + int getMaxDataLen() const; + int getVersion() const; int availableForWrite(); size_t write(const uint8_t *data, size_t len); @@ -34,6 +36,10 @@ class ESP_NOW_Class : public Print { void onNewPeer(void (*cb)(const esp_now_recv_info_t *info, const uint8_t *data, int len, void *arg), void *arg); bool removePeer(ESP_NOW_Peer &peer); + +protected: + size_t max_data_len; + uint32_t version; }; class ESP_NOW_Peer { diff --git a/libraries/ESP_NOW/src/ESP32_NOW_Serial.cpp b/libraries/ESP_NOW/src/ESP32_NOW_Serial.cpp index edd6e32aacc..c86c8546c5b 100644 --- a/libraries/ESP_NOW/src/ESP32_NOW_Serial.cpp +++ b/libraries/ESP_NOW/src/ESP32_NOW_Serial.cpp @@ -70,8 +70,25 @@ bool ESP_NOW_Serial_Class::begin(unsigned long baud) { //xSemaphoreTake(tx_sem, 0); xSemaphoreGive(tx_sem); } - setRxBufferSize(1024); //default if not preset - setTxBufferSize(1024); //default if not preset + + size_t buf_size = 0; + if (ESP_NOW.getVersion() == 2) { + // ESP-NOW v2.0 has a larger maximum data length, so we need to increase the buffer sizes + // to hold around 3-4 packets + buf_size = setRxBufferSize(4096); + buf_size &= setTxBufferSize(4096); + } else { + // ESP-NOW v1.0 has a smaller maximum data length, so we can use the default buffer sizes + // to hold around 3-4 packets + buf_size = setRxBufferSize(1024); + buf_size &= setTxBufferSize(1024); + } + + if (buf_size == 0) { + log_e("Failed to set buffer size"); + return false; + } + return true; } @@ -164,7 +181,6 @@ void ESP_NOW_Serial_Class::onReceive(const uint8_t *data, size_t len, bool broad //Print int ESP_NOW_Serial_Class::availableForWrite() { - //return ESP_NOW_MAX_DATA_LEN; if (tx_ring_buf == nullptr) { return 0; } @@ -189,7 +205,7 @@ bool ESP_NOW_Serial_Class::checkForTxData() { //do we have something that failed the last time? resend_count = 0; if (queued_buff == nullptr) { - queued_buff = (uint8_t *)xRingbufferReceiveUpTo(tx_ring_buf, &queued_size, 0, ESP_NOW_MAX_DATA_LEN); + queued_buff = (uint8_t *)xRingbufferReceiveUpTo(tx_ring_buf, &queued_size, 0, ESP_NOW.getMaxDataLen()); } else { log_d(MACSTR " : PREVIOUS", MAC2STR(addr())); } diff --git a/libraries/ESP_SR/library.properties b/libraries/ESP_SR/library.properties index 295761bd9fb..3b9777bca8f 100644 --- a/libraries/ESP_SR/library.properties +++ b/libraries/ESP_SR/library.properties @@ -1,5 +1,5 @@ name=ESP_SR -version=3.2.0 +version=3.2.1 author=me-no-dev maintainer=me-no-dev sentence=Library for ESP Sound Recognition diff --git a/libraries/ESPmDNS/library.properties b/libraries/ESPmDNS/library.properties index 6d36d61b783..b99a5f58e5c 100644 --- a/libraries/ESPmDNS/library.properties +++ b/libraries/ESPmDNS/library.properties @@ -1,5 +1,5 @@ name=ESPmDNS -version=3.2.0 +version=3.2.1 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 mDNS Library diff --git a/libraries/Ethernet/library.properties b/libraries/Ethernet/library.properties index d34ae036417..cd2d8ead018 100644 --- a/libraries/Ethernet/library.properties +++ b/libraries/Ethernet/library.properties @@ -1,5 +1,5 @@ name=Ethernet -version=3.2.0 +version=3.2.1 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection (local and Internet) using the ESP32 Ethernet. diff --git a/libraries/FFat/library.properties b/libraries/FFat/library.properties index 35940fd5472..898982536b0 100644 --- a/libraries/FFat/library.properties +++ b/libraries/FFat/library.properties @@ -1,5 +1,5 @@ name=FFat -version=3.2.0 +version=3.2.1 author=Hristo Gochkov, Ivan Grokhtkov, Larry Bernstone maintainer=Hristo Gochkov sentence=ESP32 FAT on Flash File System diff --git a/libraries/FS/library.properties b/libraries/FS/library.properties index 07bd296bb83..fe86d613bdf 100644 --- a/libraries/FS/library.properties +++ b/libraries/FS/library.properties @@ -1,5 +1,5 @@ name=FS -version=3.2.0 +version=3.2.1 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 File System diff --git a/libraries/HTTPClient/library.properties b/libraries/HTTPClient/library.properties index f2dafc36d1b..76da4c857e1 100644 --- a/libraries/HTTPClient/library.properties +++ b/libraries/HTTPClient/library.properties @@ -1,5 +1,5 @@ name=HTTPClient -version=3.2.0 +version=3.2.1 author=Markus Sattler maintainer=Markus Sattler sentence=HTTP Client for ESP32 diff --git a/libraries/HTTPUpdate/library.properties b/libraries/HTTPUpdate/library.properties index 419f3b97b3f..dfe0474c3f3 100644 --- a/libraries/HTTPUpdate/library.properties +++ b/libraries/HTTPUpdate/library.properties @@ -1,5 +1,5 @@ name=HTTPUpdate -version=3.2.0 +version=3.2.1 author=Markus Sattler maintainer=Markus Sattler sentence=Http Update for ESP32 diff --git a/libraries/HTTPUpdateServer/library.properties b/libraries/HTTPUpdateServer/library.properties index 9c793a26ac8..90aa966d27f 100644 --- a/libraries/HTTPUpdateServer/library.properties +++ b/libraries/HTTPUpdateServer/library.properties @@ -1,5 +1,5 @@ name=HTTPUpdateServer -version=3.2.0 +version=3.2.1 author=Hristo Kapanakov maintainer= sentence=Simple HTTP Update server based on the WebServer diff --git a/libraries/HTTPUpdateServer/src/HTTPUpdateServer.h b/libraries/HTTPUpdateServer/src/HTTPUpdateServer.h index bb32bc03fdb..65d8cbaa783 100644 --- a/libraries/HTTPUpdateServer/src/HTTPUpdateServer.h +++ b/libraries/HTTPUpdateServer/src/HTTPUpdateServer.h @@ -27,6 +27,7 @@ static const char serverIndex[] PROGMEM = )"; static const char successResponse[] PROGMEM = "Update Success! Rebooting..."; +static const char *csrfHeaders[2] = {"Origin", "Host"}; class HTTPUpdateServer { public: @@ -56,6 +57,9 @@ class HTTPUpdateServer { _username = username; _password = password; + // collect headers for CSRF verification + _server->collectHeaders(csrfHeaders, 2); + // handler for the /update form page _server->on(path.c_str(), HTTP_GET, [&]() { if (_username != emptyString && _password != emptyString && !_server->authenticate(_username.c_str(), _password.c_str())) { @@ -69,6 +73,10 @@ class HTTPUpdateServer { path.c_str(), HTTP_POST, [&]() { if (!_authenticated) { + if (_username == emptyString || _password == emptyString) { + _server->send(200, F("text/html"), String(F("Update error: Wrong origin received!"))); + return; + } return _server->requestAuthentication(); } if (Update.hasError()) { @@ -100,6 +108,17 @@ class HTTPUpdateServer { return; } + String origin = _server->header(String(csrfHeaders[0])); + String host = _server->header(String(csrfHeaders[1])); + String expectedOrigin = String("http://") + host; + if (origin != expectedOrigin) { + if (_serial_output) { + Serial.printf("Wrong origin received! Expected: %s, Received: %s\n", expectedOrigin.c_str(), origin.c_str()); + } + _authenticated = false; + return; + } + if (_serial_output) { Serial.printf("Update: %s\n", upload.filename.c_str()); } diff --git a/libraries/Insights/library.properties b/libraries/Insights/library.properties index fefe5aab177..c1ad9c72ce1 100644 --- a/libraries/Insights/library.properties +++ b/libraries/Insights/library.properties @@ -1,5 +1,5 @@ name=ESP Insights -version=3.2.0 +version=3.2.1 author=Sanket Wadekar maintainer=Sanket Wadekar sentence=ESP Insights diff --git a/libraries/LittleFS/library.properties b/libraries/LittleFS/library.properties index a9dae69b7f8..e00ed49c312 100644 --- a/libraries/LittleFS/library.properties +++ b/libraries/LittleFS/library.properties @@ -1,5 +1,5 @@ name=LittleFS -version=3.2.0 +version=3.2.1 author= maintainer= sentence=LittleFS for esp32 diff --git a/libraries/Matter/library.properties b/libraries/Matter/library.properties index ac9e0964ab5..b601fce0ff5 100644 --- a/libraries/Matter/library.properties +++ b/libraries/Matter/library.properties @@ -1,5 +1,5 @@ name=Matter -version=3.2.0 +version=3.2.1 author=Rodrigo Garcia | GitHub @SuGlider maintainer=Rodrigo Garcia sentence=Library for supporting Matter environment on ESP32. diff --git a/libraries/NetBIOS/library.properties b/libraries/NetBIOS/library.properties index 5f134bfdc55..a4bbf93c0ed 100644 --- a/libraries/NetBIOS/library.properties +++ b/libraries/NetBIOS/library.properties @@ -1,5 +1,5 @@ name=NetBIOS -version=3.2.0 +version=3.2.1 author=Pablo@xpablo.cz maintainer=Hristo Gochkov sentence=Enables NBNS (NetBIOS) name resolution. diff --git a/libraries/Network/library.properties b/libraries/Network/library.properties index 0b821e08d77..f2284981704 100644 --- a/libraries/Network/library.properties +++ b/libraries/Network/library.properties @@ -1,5 +1,5 @@ name=Networking -version=3.2.0 +version=3.2.1 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=General network management library. diff --git a/libraries/NetworkClientSecure/library.properties b/libraries/NetworkClientSecure/library.properties index 455dea6a2bf..31af7a1bc8c 100644 --- a/libraries/NetworkClientSecure/library.properties +++ b/libraries/NetworkClientSecure/library.properties @@ -1,5 +1,5 @@ name=NetworkClientSecure -version=3.2.0 +version=3.2.1 author=Evandro Luis Copercini maintainer=Github Community sentence=Enables secure network connection (local and Internet) using the ESP32 built-in WiFi. diff --git a/libraries/OpenThread/library.properties b/libraries/OpenThread/library.properties index 0e547d188aa..2687b1dcd1c 100644 --- a/libraries/OpenThread/library.properties +++ b/libraries/OpenThread/library.properties @@ -1,5 +1,5 @@ name=OpenThread -version=3.2.0 +version=3.2.1 author=Rodrigo Garcia | GitHub @SuGlider maintainer=Rodrigo Garcia sentence=Library for OpenThread Network on ESP32. diff --git a/libraries/PPP/library.properties b/libraries/PPP/library.properties index 7158a027b0a..c39647cbe56 100644 --- a/libraries/PPP/library.properties +++ b/libraries/PPP/library.properties @@ -1,5 +1,5 @@ name=PPP -version=3.2.0 +version=3.2.1 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection using GSM Modem. diff --git a/libraries/Preferences/library.properties b/libraries/Preferences/library.properties index eb0158e4932..6e0d38348c0 100644 --- a/libraries/Preferences/library.properties +++ b/libraries/Preferences/library.properties @@ -1,5 +1,5 @@ name=Preferences -version=3.2.0 +version=3.2.1 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Provides friendly access to ESP32's Non-Volatile Storage diff --git a/libraries/RainMaker/library.properties b/libraries/RainMaker/library.properties index 95ce14d6708..71b4082a0a7 100644 --- a/libraries/RainMaker/library.properties +++ b/libraries/RainMaker/library.properties @@ -1,5 +1,5 @@ name=ESP RainMaker -version=3.2.0 +version=3.2.1 author=Sweety Mhaiske maintainer=Hristo Gochkov sentence=ESP RainMaker Support diff --git a/libraries/SD/library.properties b/libraries/SD/library.properties index 66c4f5cfafd..cc51196ed54 100644 --- a/libraries/SD/library.properties +++ b/libraries/SD/library.properties @@ -1,5 +1,5 @@ name=SD -version=3.2.0 +version=3.2.1 author=Arduino, SparkFun maintainer=Arduino sentence=Enables reading and writing on SD cards. For all Arduino boards. diff --git a/libraries/SD/src/SD.cpp b/libraries/SD/src/SD.cpp index 2d646276d87..077a7c1121f 100644 --- a/libraries/SD/src/SD.cpp +++ b/libraries/SD/src/SD.cpp @@ -22,6 +22,10 @@ using namespace fs; SDFS::SDFS(FSImplPtr impl) : FS(impl), _pdrv(0xFF) {} +SDFS::~SDFS() { + end(); +} + bool SDFS::begin(uint8_t ssPin, SPIClass &spi, uint32_t frequency, const char *mountpoint, uint8_t max_files, bool format_if_empty) { if (_pdrv != 0xFF) { return true; diff --git a/libraries/SD/src/SD.h b/libraries/SD/src/SD.h index aebc781a5e3..d8252ee44f7 100644 --- a/libraries/SD/src/SD.h +++ b/libraries/SD/src/SD.h @@ -26,6 +26,7 @@ class SDFS : public FS { public: SDFS(FSImplPtr impl); + ~SDFS(); bool begin( uint8_t ssPin = SS, SPIClass &spi = SPI, uint32_t frequency = 4000000, const char *mountpoint = "/sd", uint8_t max_files = 5, bool format_if_empty = false ); diff --git a/libraries/SD_MMC/library.properties b/libraries/SD_MMC/library.properties index 855390e5057..590eb8ebc52 100644 --- a/libraries/SD_MMC/library.properties +++ b/libraries/SD_MMC/library.properties @@ -1,5 +1,5 @@ name=SD_MMC -version=3.2.0 +version=3.2.1 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 SDMMC File System diff --git a/libraries/SPI/library.properties b/libraries/SPI/library.properties index 64db93aceeb..724137030d1 100644 --- a/libraries/SPI/library.properties +++ b/libraries/SPI/library.properties @@ -1,5 +1,5 @@ name=SPI -version=3.2.0 +version=3.2.1 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. For all Arduino boards, BUT Arduino DUE. diff --git a/libraries/SPIFFS/library.properties b/libraries/SPIFFS/library.properties index 78f77fe9794..fc4601e512c 100644 --- a/libraries/SPIFFS/library.properties +++ b/libraries/SPIFFS/library.properties @@ -1,5 +1,5 @@ name=SPIFFS -version=3.2.0 +version=3.2.1 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 SPIFFS File System diff --git a/libraries/SimpleBLE/library.properties b/libraries/SimpleBLE/library.properties index ad5e10d3acb..768449ee1c4 100644 --- a/libraries/SimpleBLE/library.properties +++ b/libraries/SimpleBLE/library.properties @@ -1,5 +1,5 @@ name=SimpleBLE -version=3.2.0 +version=3.2.1 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Provides really simple BLE advertizer with just on and off diff --git a/libraries/TFLiteMicro/library.properties b/libraries/TFLiteMicro/library.properties index 1e8db045610..6ad0c32c7d5 100644 --- a/libraries/TFLiteMicro/library.properties +++ b/libraries/TFLiteMicro/library.properties @@ -1,5 +1,5 @@ name=TFLite Micro -version=3.2.0 +version=3.2.1 author=Sanket Wadekar maintainer=Sanket Wadekar sentence=TensorFlow Lite for Microcontrollers diff --git a/libraries/Ticker/library.properties b/libraries/Ticker/library.properties index 975db96d1ad..8a2af554906 100644 --- a/libraries/Ticker/library.properties +++ b/libraries/Ticker/library.properties @@ -1,5 +1,5 @@ name=Ticker -version=3.2.0 +version=3.2.1 author=Bert Melis maintainer=Hristo Gochkov sentence=Allows to call functions with a given interval. diff --git a/libraries/USB/library.properties b/libraries/USB/library.properties index 9d47dfc6719..677d736a635 100644 --- a/libraries/USB/library.properties +++ b/libraries/USB/library.properties @@ -1,5 +1,5 @@ name=USB -version=3.2.0 +version=3.2.1 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=ESP32S2 USB Library diff --git a/libraries/Update/examples/OTAWebUpdater/OTAWebUpdater.ino b/libraries/Update/examples/OTAWebUpdater/OTAWebUpdater.ino index 7059bef4496..39d6cbce4af 100644 --- a/libraries/Update/examples/OTAWebUpdater/OTAWebUpdater.ino +++ b/libraries/Update/examples/OTAWebUpdater/OTAWebUpdater.ino @@ -8,10 +8,17 @@ #define SSID_FORMAT "ESP32-%06lX" // 12 chars total //#define PASSWORD "test123456" // generate if remarked +// Set the username and password for firmware upload +const char *authUser = "........"; +const char *authPass = "........"; + WebServer server(80); Ticker tkSecond; uint8_t otaDone = 0; +const char *csrfHeaders[2] = {"Origin", "Host"}; +static bool authenticated = false; + const char *alphanum = "0123456789!@#$%^&*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; String generatePass(uint8_t str_len) { String buff; @@ -38,6 +45,9 @@ void apMode() { } void handleUpdateEnd() { + if (!authenticated) { + return server.requestAuthentication(); + } server.sendHeader("Connection", "close"); if (Update.hasError()) { server.send(502, "text/plain", Update.errorString()); @@ -45,6 +55,7 @@ void handleUpdateEnd() { server.sendHeader("Refresh", "10"); server.sendHeader("Location", "/"); server.send(307); + delay(500); ESP.restart(); } } @@ -56,18 +67,34 @@ void handleUpdate() { } HTTPUpload &upload = server.upload(); if (upload.status == UPLOAD_FILE_START) { + authenticated = server.authenticate(authUser, authPass); + if (!authenticated) { + Serial.println("Authentication fail!"); + otaDone = 0; + return; + } + String origin = server.header(String(csrfHeaders[0])); + String host = server.header(String(csrfHeaders[1])); + String expectedOrigin = String("http://") + host; + if (origin != expectedOrigin) { + Serial.printf("Wrong origin received! Expected: %s, Received: %s\n", expectedOrigin.c_str(), origin.c_str()); + authenticated = false; + otaDone = 0; + return; + } + Serial.printf("Receiving Update: %s, Size: %d\n", upload.filename.c_str(), fsize); if (!Update.begin(fsize)) { otaDone = 0; Update.printError(Serial); } - } else if (upload.status == UPLOAD_FILE_WRITE) { + } else if (authenticated && upload.status == UPLOAD_FILE_WRITE) { if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) { Update.printError(Serial); } else { otaDone = 100 * Update.progress() / Update.size(); } - } else if (upload.status == UPLOAD_FILE_END) { + } else if (authenticated && upload.status == UPLOAD_FILE_END) { if (Update.end(true)) { Serial.printf("Update Success: %u bytes\nRebooting...\n", upload.totalSize); } else { @@ -78,6 +105,7 @@ void handleUpdate() { } void webServerInit() { + server.collectHeaders(csrfHeaders, 2); server.on( "/update", HTTP_POST, []() { @@ -92,6 +120,9 @@ void webServerInit() { server.send_P(200, "image/x-icon", favicon_ico_gz, favicon_ico_gz_len); }); server.onNotFound([]() { + if (!server.authenticate(authUser, authPass)) { + return server.requestAuthentication(); + } server.send(200, "text/html", indexHtml); }); server.begin(); diff --git a/libraries/Update/library.properties b/libraries/Update/library.properties index c3ee8f7e506..4c756397aba 100644 --- a/libraries/Update/library.properties +++ b/libraries/Update/library.properties @@ -1,5 +1,5 @@ name=Update -version=3.2.0 +version=3.2.1 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=ESP32 Sketch Update Library diff --git a/libraries/WebServer/examples/WebUpdate/WebUpdate.ino b/libraries/WebServer/examples/WebUpdate/WebUpdate.ino index 10ddb5e7b64..9e45de7d985 100644 --- a/libraries/WebServer/examples/WebUpdate/WebUpdate.ino +++ b/libraries/WebServer/examples/WebUpdate/WebUpdate.ino @@ -12,10 +12,17 @@ const char *host = "esp32-webupdate"; const char *ssid = "........"; const char *password = "........"; +// Set the username and password for firmware upload +const char *authUser = "........"; +const char *authPass = "........"; + WebServer server(80); const char *serverIndex = "
"; +const char *csrfHeaders[2] = {"Origin", "Host"}; +static bool authenticated = false; + void setup(void) { Serial.begin(115200); Serial.println(); @@ -24,37 +31,63 @@ void setup(void) { WiFi.begin(ssid, password); if (WiFi.waitForConnectResult() == WL_CONNECTED) { MDNS.begin(host); + server.collectHeaders(csrfHeaders, 2); server.on("/", HTTP_GET, []() { + if (!server.authenticate(authUser, authPass)) { + return server.requestAuthentication(); + } server.sendHeader("Connection", "close"); server.send(200, "text/html", serverIndex); }); server.on( "/update", HTTP_POST, []() { + if (!authenticated) { + return server.requestAuthentication(); + } server.sendHeader("Connection", "close"); - server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK"); - ESP.restart(); + if (Update.hasError()) { + server.send(200, "text/plain", "FAIL"); + } else { + server.send(200, "text/plain", "Success! Rebooting..."); + delay(500); + ESP.restart(); + } }, []() { HTTPUpload &upload = server.upload(); if (upload.status == UPLOAD_FILE_START) { Serial.setDebugOutput(true); + authenticated = server.authenticate(authUser, authPass); + if (!authenticated) { + Serial.println("Authentication fail!"); + return; + } + String origin = server.header(String(csrfHeaders[0])); + String host = server.header(String(csrfHeaders[1])); + String expectedOrigin = String("http://") + host; + if (origin != expectedOrigin) { + Serial.printf("Wrong origin received! Expected: %s, Received: %s\n", expectedOrigin.c_str(), origin.c_str()); + authenticated = false; + return; + } + Serial.printf("Update: %s\n", upload.filename.c_str()); if (!Update.begin()) { //start with max available size Update.printError(Serial); } - } else if (upload.status == UPLOAD_FILE_WRITE) { + } else if (authenticated && upload.status == UPLOAD_FILE_WRITE) { if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) { Update.printError(Serial); } - } else if (upload.status == UPLOAD_FILE_END) { + } else if (authenticated && upload.status == UPLOAD_FILE_END) { if (Update.end(true)) { //true to set the size to the current progress Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize); } else { Update.printError(Serial); } Serial.setDebugOutput(false); - } else { + } else if (authenticated) { Serial.printf("Update Failed Unexpectedly (likely broken connection): status=%d\n", upload.status); } } diff --git a/libraries/WebServer/library.properties b/libraries/WebServer/library.properties index 2a9ff530d57..bf6c26c65e7 100644 --- a/libraries/WebServer/library.properties +++ b/libraries/WebServer/library.properties @@ -1,5 +1,5 @@ name=WebServer -version=3.2.0 +version=3.2.1 author=Ivan Grokhotkov maintainer=Ivan Grokhtkov sentence=Simple web server library diff --git a/libraries/WiFi/library.properties b/libraries/WiFi/library.properties index 03112c2fcc6..a282570ff8a 100644 --- a/libraries/WiFi/library.properties +++ b/libraries/WiFi/library.properties @@ -1,5 +1,5 @@ name=WiFi -version=3.2.0 +version=3.2.1 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection (local and Internet) using the ESP32 built-in WiFi. diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index bddcb5fd448..ec661ef7d8f 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -246,29 +246,67 @@ extern "C" { extern esp_err_t esp_hosted_init(); extern esp_err_t esp_hosted_deinit(); }; +typedef struct { + uint8_t pin_clk; + uint8_t pin_cmd; + uint8_t pin_d0; + uint8_t pin_d1; + uint8_t pin_d2; + uint8_t pin_d3; + uint8_t pin_reset; +} sdio_pin_config_t; + static bool hosted_initialized = false; +static sdio_pin_config_t sdio_pin_config = { +#ifdef BOARD_HAS_SDIO_ESP_HOSTED + .pin_clk = BOARD_SDIO_ESP_HOSTED_CLK, + .pin_cmd = BOARD_SDIO_ESP_HOSTED_CMD, + .pin_d0 = BOARD_SDIO_ESP_HOSTED_D0, + .pin_d1 = BOARD_SDIO_ESP_HOSTED_D1, + .pin_d2 = BOARD_SDIO_ESP_HOSTED_D2, + .pin_d3 = BOARD_SDIO_ESP_HOSTED_D3, + .pin_reset = BOARD_SDIO_ESP_HOSTED_RESET +#else + .pin_clk = CONFIG_ESP_SDIO_PIN_CLK, + .pin_cmd = CONFIG_ESP_SDIO_PIN_CMD, + .pin_d0 = CONFIG_ESP_SDIO_PIN_D0, + .pin_d1 = CONFIG_ESP_SDIO_PIN_D1, + .pin_d2 = CONFIG_ESP_SDIO_PIN_D2, + .pin_d3 = CONFIG_ESP_SDIO_PIN_D3, + .pin_reset = CONFIG_ESP_SDIO_GPIO_RESET_SLAVE +#endif +}; + +bool WiFiGenericClass::setPins(int8_t clk, int8_t cmd, int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t rst) { + if (clk < 0 || cmd < 0 || d0 < 0 || d1 < 0 || d2 < 0 || d3 < 0 || rst < 0) { + log_e("All SDIO pins must be defined"); + return false; + } + if (hosted_initialized) { + log_e("SDIO pins must be set before WiFi is initialized"); + return false; + } + sdio_pin_config.pin_clk = clk; + sdio_pin_config.pin_cmd = cmd; + sdio_pin_config.pin_d0 = d0; + sdio_pin_config.pin_d1 = d1; + sdio_pin_config.pin_d2 = d2; + sdio_pin_config.pin_d3 = d3; + sdio_pin_config.pin_reset = rst; + return true; +} static bool wifiHostedInit() { if (!hosted_initialized) { hosted_initialized = true; struct esp_hosted_sdio_config conf = INIT_DEFAULT_HOST_SDIO_CONFIG(); -#ifdef BOARD_HAS_SDIO_ESP_HOSTED - conf.pin_clk.pin = BOARD_SDIO_ESP_HOSTED_CLK; - conf.pin_cmd.pin = BOARD_SDIO_ESP_HOSTED_CMD; - conf.pin_d0.pin = BOARD_SDIO_ESP_HOSTED_D0; - conf.pin_d1.pin = BOARD_SDIO_ESP_HOSTED_D1; - conf.pin_d2.pin = BOARD_SDIO_ESP_HOSTED_D2; - conf.pin_d3.pin = BOARD_SDIO_ESP_HOSTED_D3; - conf.pin_reset.pin = BOARD_SDIO_ESP_HOSTED_RESET; -#else - conf.pin_clk.pin = CONFIG_ESP_SDIO_PIN_CLK; - conf.pin_cmd.pin = CONFIG_ESP_SDIO_PIN_CMD; - conf.pin_d0.pin = CONFIG_ESP_SDIO_PIN_D0; - conf.pin_d1.pin = CONFIG_ESP_SDIO_PIN_D1; - conf.pin_d2.pin = CONFIG_ESP_SDIO_PIN_D2; - conf.pin_d3.pin = CONFIG_ESP_SDIO_PIN_D3; - conf.pin_reset.pin = CONFIG_ESP_SDIO_GPIO_RESET_SLAVE; -#endif + conf.pin_clk.pin = sdio_pin_config.pin_clk; + conf.pin_cmd.pin = sdio_pin_config.pin_cmd; + conf.pin_d0.pin = sdio_pin_config.pin_d0; + conf.pin_d1.pin = sdio_pin_config.pin_d1; + conf.pin_d2.pin = sdio_pin_config.pin_d2; + conf.pin_d3.pin = sdio_pin_config.pin_d3; + conf.pin_reset.pin = sdio_pin_config.pin_reset; // esp_hosted_sdio_set_config() will fail on second attempt but here temporarily to not cause exception on reinit if (esp_hosted_sdio_set_config(&conf) != ESP_OK || esp_hosted_init() != ESP_OK) { log_e("esp_hosted_init failed!"); @@ -279,13 +317,13 @@ static bool wifiHostedInit() { } // Attach pins to PeriMan here // Slave chip model is CONFIG_IDF_SLAVE_TARGET - // CONFIG_ESP_SDIO_PIN_CMD - // CONFIG_ESP_SDIO_PIN_CLK - // CONFIG_ESP_SDIO_PIN_D0 - // CONFIG_ESP_SDIO_PIN_D1 - // CONFIG_ESP_SDIO_PIN_D2 - // CONFIG_ESP_SDIO_PIN_D3 - // CONFIG_ESP_SDIO_GPIO_RESET_SLAVE + // sdio_pin_config.pin_clk + // sdio_pin_config.pin_cmd + // sdio_pin_config.pin_d0 + // sdio_pin_config.pin_d1 + // sdio_pin_config.pin_d2 + // sdio_pin_config.pin_d3 + // sdio_pin_config.pin_reset return true; } diff --git a/libraries/WiFi/src/WiFiGeneric.h b/libraries/WiFi/src/WiFiGeneric.h index ed216229ed4..bdfa7b5dd85 100644 --- a/libraries/WiFi/src/WiFiGeneric.h +++ b/libraries/WiFi/src/WiFiGeneric.h @@ -82,6 +82,11 @@ class WiFiGenericClass { public: WiFiGenericClass(); +#if CONFIG_ESP_WIFI_REMOTE_ENABLED + // Set SDIO pins for connection to external ESP MCU + static bool setPins(int8_t clk, int8_t cmd, int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t rst); +#endif + wifi_event_id_t onEvent(WiFiEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); wifi_event_id_t onEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); diff --git a/libraries/WiFiProv/library.properties b/libraries/WiFiProv/library.properties index 13a63c50bb1..1cc8e4b0f91 100644 --- a/libraries/WiFiProv/library.properties +++ b/libraries/WiFiProv/library.properties @@ -1,5 +1,5 @@ name=WiFiProv -version=3.2.0 +version=3.2.1 author=Switi Mhaiske maintainer=Hristo Gochkov sentence=Enables provisioning. diff --git a/libraries/Wire/library.properties b/libraries/Wire/library.properties index 655f4bd3194..22cc7f26d86 100644 --- a/libraries/Wire/library.properties +++ b/libraries/Wire/library.properties @@ -1,5 +1,5 @@ name=Wire -version=3.2.0 +version=3.2.1 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. For esp8266 boards. diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index f8d9496389f..34c814b5117 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -39,7 +39,7 @@ extern "C" { #include "Arduino.h" TwoWire::TwoWire(uint8_t bus_num) - : num(bus_num & 1), sda(-1), scl(-1), bufferSize(I2C_BUFFER_LENGTH) // default Wire Buffer Size + : num(bus_num), sda(-1), scl(-1), bufferSize(I2C_BUFFER_LENGTH) // default Wire Buffer Size , rxBuffer(NULL), rxIndex(0), rxLength(0), txBuffer(NULL), txLength(0), txAddress(0), _timeOutMillis(50), nonStop(false) #if !CONFIG_DISABLE_HAL_LOCKS @@ -62,6 +62,10 @@ TwoWire::~TwoWire() { #endif } +uint8_t TwoWire::getBusNum() { + return num; +} + bool TwoWire::initPins(int sdaPin, int sclPin) { if (sdaPin < 0) { // default param passed if (num == 0) { diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index 0deab7d4a57..b84aa5b2131 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -105,6 +105,8 @@ class TwoWire : public HardwareI2C { bool end() override; + uint8_t getBusNum(); + bool setClock(uint32_t freq) override; void beginTransmission(uint8_t address) override; diff --git a/libraries/Zigbee/examples/Zigbee_Fan_Control/README.md b/libraries/Zigbee/examples/Zigbee_Fan_Control/README.md new file mode 100644 index 00000000000..91700b669a0 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Fan_Control/README.md @@ -0,0 +1,83 @@ +# Arduino-ESP32 Zigbee Fan Control Example + +This example demonstrates how to use the Zigbee library to create a router device fan control and use it as a Home Automation (HA) fan control device. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +## Fan Control Functions + +1. Initialize a Zigbee fan control device. +2. Control fan modes (OFF, LOW, MEDIUM, HIGH, ON). +3. Respond to fan control commands from the Zigbee network. + +## Hardware Required + +* ESP32-H2 or ESP32-C6 development board +* A USB cable for power supply and programming +* RGB LED for visual feedback (built-in on most development boards) + +### Configure the Project + +In this example the RGB LED is used to indicate the current fan control mode. +The LED colors represent different fan modes: +- OFF: No light +- LOW: Blue +- MEDIUM: Yellow +- HIGH: Red +- ON: White + +Set the button GPIO by changing the `button` variable. By default, it's the pin `BOOT_PIN` (BOOT button on ESP32-C6 and ESP32-H2). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the End device Zigbee mode: `Tools -> Zigbee mode: Zigbee ZCZR (coordinator/router)` +* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee ZCZR 4MB with spiffs` +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. +* Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`. + +## Troubleshooting + +If the End device flashed with this example is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board. It is recommended to do this if you re-flash the coordinator. +You can do the following: + +* In the Arduino IDE go to the Tools menu and set `Erase All Flash Before Sketch Upload` to `Enabled`. +* Add to the sketch `Zigbee.factoryReset();` to reset the device and Zigbee stack. + +By default, the coordinator network is closed after rebooting or flashing new firmware. +To open the network you have 2 options: + +* Open network after reboot by setting `Zigbee.setRebootOpenNetwork(time);` before calling `Zigbee.begin();`. +* In application you can anytime call `Zigbee.openNetwork(time);` to open the network for devices to join. + + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/Zigbee/examples/Zigbee_Fan_Control/Zigbee_Fan_Control.ino b/libraries/Zigbee/examples/Zigbee_Fan_Control/Zigbee_Fan_Control.ino new file mode 100644 index 00000000000..4c0d15aa563 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Fan_Control/Zigbee_Fan_Control.ino @@ -0,0 +1,129 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @brief This example demonstrates simple Zigbee fan control. + * + * The example demonstrates how to use Zigbee library to create a router device fan control. + * The fan control is a Zigbee router device, which is controlled by a Zigbee coordinator. + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode + * and also the correct partition scheme must be selected in Tools->Partition Scheme. + * + * Please check the README.md for instructions and more detailed description. + * + * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) + */ + +#ifndef ZIGBEE_MODE_ZCZR +#error "Zigbee coordinator mode is not selected in Tools->Zigbee mode" +#endif + +#include "Zigbee.h" + +/* Zigbee light bulb configuration */ +#define ZIGBEE_FAN_CONTROL_ENDPOINT 1 + +#ifdef RGB_BUILTIN +uint8_t led = RGB_BUILTIN; // To demonstrate the current fan control mode +#else +uint8_t led = 2; +#endif + +uint8_t button = BOOT_PIN; + +ZigbeeFanControl zbFanControl = ZigbeeFanControl(ZIGBEE_FAN_CONTROL_ENDPOINT); + +/********************* fan control callback function **************************/ +void setFan(ZigbeeFanMode mode) { + switch (mode) { + case FAN_MODE_OFF: + rgbLedWrite(led, 0, 0, 0); // Off + Serial.println("Fan mode: OFF"); + break; + case FAN_MODE_LOW: + rgbLedWrite(led, 0, 0, 255); // Blue + Serial.println("Fan mode: LOW"); + break; + case FAN_MODE_MEDIUM: + rgbLedWrite(led, 255, 255, 0); // Yellow + Serial.println("Fan mode: MEDIUM"); + break; + case FAN_MODE_HIGH: + rgbLedWrite(led, 255, 0, 0); // Red + Serial.println("Fan mode: HIGH"); + break; + case FAN_MODE_ON: + rgbLedWrite(led, 255, 255, 255); // White + Serial.println("Fan mode: ON"); + break; + default: log_e("Unhandled fan mode: %d", mode); break; + } +} + +/********************* Arduino functions **************************/ +void setup() { + Serial.begin(115200); + + // Init LED that will be used to indicate the current fan control mode + rgbLedWrite(led, 0, 0, 0); + + // Init button for factory reset + pinMode(button, INPUT_PULLUP); + + //Optional: set Zigbee device name and model + zbFanControl.setManufacturerAndModel("Espressif", "ZBFanControl"); + + // Set the fan mode sequence to LOW_MED_HIGH + zbFanControl.setFanModeSequence(FAN_MODE_SEQUENCE_LOW_MED_HIGH); + + // Set callback function for fan mode change + zbFanControl.onFanModeChange(setFan); + + //Add endpoint to Zigbee Core + Serial.println("Adding ZigbeeFanControl endpoint to Zigbee Core"); + Zigbee.addEndpoint(&zbFanControl); + + // When all EPs are registered, start Zigbee in ROUTER mode + if (!Zigbee.begin(ZIGBEE_ROUTER)) { + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } + Serial.println("Connecting to network"); + while (!Zigbee.connected()) { + Serial.print("."); + delay(100); + } + Serial.println(); +} + +void loop() { + // Checking button for factory reset + if (digitalRead(button) == LOW) { // Push button pressed + // Key debounce handling + delay(100); + int startTime = millis(); + while (digitalRead(button) == LOW) { + delay(50); + if ((millis() - startTime) > 3000) { + // If key pressed for more than 3secs, factory reset Zigbee and reboot + Serial.println("Resetting Zigbee to factory and rebooting in 1s."); + delay(1000); + Zigbee.factoryReset(); + } + } + } + delay(100); +} diff --git a/libraries/Zigbee/examples/Zigbee_Fan_Control/ci.json b/libraries/Zigbee/examples/Zigbee_Fan_Control/ci.json new file mode 100644 index 00000000000..15d6190e4ae --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Fan_Control/ci.json @@ -0,0 +1,6 @@ +{ + "fqbn_append": "PartitionScheme=zigbee_zczr,ZigbeeMode=zczr", + "requires": [ + "CONFIG_ZB_ENABLED=y" + ] +} diff --git a/libraries/Zigbee/keywords.txt b/libraries/Zigbee/keywords.txt index 556b6408ea2..23f3af3bf02 100644 --- a/libraries/Zigbee/keywords.txt +++ b/libraries/Zigbee/keywords.txt @@ -12,25 +12,31 @@ Zigbee KEYWORD1 ZigbeeEP KEYWORD1 # Endpoint Classes -ZigbeeLight KEYWORD1 -ZigbeeSwitch KEYWORD1 -ZigbeeColorDimmableLight KEYWORD1 -ZigbeeColorDimmerSwitch KEYWORD1 -ZigbeeTempSensor KEYWORD1 -ZigbeeThermostat KEYWORD1 -ZigbeeFlowSensor KEYWORD1 -ZigbeePressureSensor KEYWORD1 -ZigbeeOccupancySensor KEYWORD1 ZigbeeAnalog KEYWORD1 +ZigbeeBinary KEYWORD1 ZigbeeCarbonDioxideSensor KEYWORD1 +ZigbeeColorDimmableLight KEYWORD1 +ZigbeeColorDimmerSwitch KEYWORD1 ZigbeeContactSwitch KEYWORD1 +ZigbeeDimableLight KEYWORD1 ZigbeeDoorWindowHandle KEYWORD1 +ZigbeeElectricalMeasurement KEYWORD1 +ZigbeeFanControl KEYWORD1 +ZigbeeFlowSensor KEYWORD1 ZigbeeGateway KEYWORD1 +ZigbeeIlluminanceSensor KEYWORD1 +ZigbeeLight KEYWORD1 +ZigbeeOccupancySensor KEYWORD1 +ZigbeePM25Sensor KEYWORD1 +ZigbeePowerOutlet KEYWORD1 +ZigbeePressureSensor KEYWORD1 ZigbeeRangeExtender KEYWORD1 +ZigbeeSwitch KEYWORD1 +ZigbeeTempSensor KEYWORD1 +ZigbeeThermostat KEYWORD1 ZigbeeVibrationSensor KEYWORD1 ZigbeeWindowCovering KEYWORD1 -ZigbeeIlluminanceSensor KEYWORD1 -ZigbeePowerOutlet KEYWORD1 +ZigbeeWindSpeedSensor KEYWORD1 # Other zigbee_role_t KEYWORD1 @@ -39,6 +45,8 @@ zb_device_params_t KEYWORD1 zigbee_scan_result_t KEYWORD1 zb_power_source_t KEYWORD1 ZigbeeWindowCoveringType KEYWORD1 +ZigbeeFanMode KEYWORD1 +ZigbeeFanModeSequence KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) @@ -73,6 +81,7 @@ printBoundDevices KEYWORD2 getBoundDevices KEYWORD2 bound KEYWORD2 allowMultipleBinding KEYWORD2 +setManualBinding KEYWORD2 setManufacturerAndModel KEYWORD2 setPowerSource KEYWORD2 setBatteryPercentage KEYWORD2 @@ -80,6 +89,13 @@ reportBatteryPercentage KEYWORD2 readManufacturer KEYWORD2 readModel KEYWORD2 onIdentify KEYWORD2 +addTimeCluster KEYWORD2 +setTime KEYWORD2 +setTimezone KEYWORD2 +getTime KEYWORD2 +getTimezone KEYWORD2 +addOTAClient KEYWORD2 +clearBoundDevices KEYWORD2 # ZigbeeLight + ZigbeeColorDimmableLight onLightChange KEYWORD2 @@ -171,7 +187,7 @@ setTilted KEYWORD2 # ZigbeeVibrationSensor setVibration KEYWORD2 -ZigbeeWindowCovering +# ZigbeeWindowCovering onOpen KEYWORD2 onClose KEYWORD2 onGoToLiftPercentage KEYWORD2 @@ -186,6 +202,26 @@ setConfigStatus KEYWORD2 setMode KEYWORD2 setLimits KEYWORD2 +# ZigbeeBinary +addBinaryInput KEYWORD2 +addBinaryOutput KEYWORD2 +onBinaryOutputChange KEYWORD2 +setBinaryInput KEYWORD2 +setBinaryOutput KEYWORD2 +getBinaryOutput KEYWORD2 +reportBinaryInput KEYWORD2 +reportBinaryOutput KEYWORD2 +setBinaryInputApplication KEYWORD2 +setBinaryInputDescription KEYWORD2 +setBinaryOutputApplication KEYWORD2 +setBinaryOutputDescription KEYWORD2 + +# ZigbeeFanControl +setFanModeSequence KEYWORD2 +getFanMode KEYWORD2 +getFanModeSequence KEYWORD2 +onFanModeChange KEYWORD2 + ####################################### # Constants (LITERAL1) ####################################### diff --git a/libraries/Zigbee/library.properties b/libraries/Zigbee/library.properties index 9a558d70216..d9587f49fd5 100644 --- a/libraries/Zigbee/library.properties +++ b/libraries/Zigbee/library.properties @@ -1,5 +1,5 @@ name=Zigbee -version=3.2.0 +version=3.2.1 author=P-R-O-C-H-Y maintainer=Jan Procházka sentence=Enables zigbee connection with the ESP32 diff --git a/libraries/Zigbee/src/Zigbee.h b/libraries/Zigbee/src/Zigbee.h index b2e2e5dd027..65c9e7f0daa 100644 --- a/libraries/Zigbee/src/Zigbee.h +++ b/libraries/Zigbee/src/Zigbee.h @@ -16,6 +16,7 @@ #include "ep/ZigbeeLight.h" //// Controllers #include "ep/ZigbeeThermostat.h" +#include "ep/ZigbeeFanControl.h" ////Outlets #include "ep/ZigbeePowerOutlet.h" //// Sensors diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp index caac73b5c68..2fb07fc2187 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp @@ -1,3 +1,4 @@ +#include #include "ZigbeeColorDimmableLight.h" #if CONFIG_ZB_ENABLED @@ -127,7 +128,8 @@ bool ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red, espXyColor_t xy_color = espRgbColorToXYColor(_current_color); espHsvColor_t hsv_color = espRgbColorToHsvColor(_current_color); - uint8_t hue = (uint8_t)hsv_color.h; + uint8_t hue = std::min((uint8_t)hsv_color.h, (uint8_t)254); // Clamp to 0-254 + uint8_t saturation = std::min((uint8_t)hsv_color.s, (uint8_t)254); // Clamp to 0-254 log_v("Updating light state: %d, level: %d, color: %d, %d, %d", state, level, red, green, blue); /* Update light clusters */ @@ -174,7 +176,7 @@ bool ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red, } //set saturation ret = esp_zb_zcl_set_attribute_val( - _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID, &hsv_color.s, false + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID, &saturation, false ); if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) { log_e("Failed to set light saturation: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret)); diff --git a/libraries/Zigbee/src/ep/ZigbeeFanControl.cpp b/libraries/Zigbee/src/ep/ZigbeeFanControl.cpp new file mode 100644 index 00000000000..f4b32ce1200 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeFanControl.cpp @@ -0,0 +1,60 @@ +#include "ZigbeeFanControl.h" +#if CONFIG_ZB_ENABLED + +ZigbeeFanControl::ZigbeeFanControl(uint8_t endpoint) : ZigbeeEP(endpoint) { + _device_id = ESP_ZB_HA_THERMOSTAT_DEVICE_ID; //There is no FAN_CONTROL_DEVICE_ID in the Zigbee spec + + //Create basic analog sensor clusters without configuration + _cluster_list = esp_zb_zcl_cluster_list_create(); + esp_zb_cluster_list_add_basic_cluster(_cluster_list, esp_zb_basic_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(_cluster_list, esp_zb_identify_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_fan_control_cluster(_cluster_list, esp_zb_fan_control_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + + _ep_config = { + .endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_HEATING_COOLING_UNIT_DEVICE_ID, .app_device_version = 0 + }; +} + +bool ZigbeeFanControl::setFanModeSequence(ZigbeeFanModeSequence sequence) { + esp_zb_attribute_list_t *fan_control_cluster = + esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_FAN_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_err_t ret = esp_zb_cluster_update_attr(fan_control_cluster, ESP_ZB_ZCL_ATTR_FAN_CONTROL_FAN_MODE_SEQUENCE_ID, (void *)&sequence); + if (ret != ESP_OK) { + log_e("Failed to set min value: 0x%x: %s", ret, esp_err_to_name(ret)); + return false; + } + _current_fan_mode_sequence = sequence; + _current_fan_mode = FAN_MODE_OFF; + // Set initial fan mode to OFF + ret = esp_zb_cluster_update_attr(fan_control_cluster, ESP_ZB_ZCL_ATTR_FAN_CONTROL_FAN_MODE_ID, (void *)&_current_fan_mode); + if (ret != ESP_OK) { + log_e("Failed to set fan mode: 0x%x: %s", ret, esp_err_to_name(ret)); + return false; + } + return true; +} + +//set attribute method -> method overridden in child class +void ZigbeeFanControl::zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) { + //check the data and call right method + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_FAN_CONTROL) { + if (message->attribute.id == ESP_ZB_ZCL_ATTR_FAN_CONTROL_FAN_MODE_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_8BIT_ENUM) { + _current_fan_mode = *(ZigbeeFanMode *)message->attribute.data.value; + fanModeChanged(); + } else { + log_w("Received message ignored. Attribute ID: %d not supported for Fan Control", message->attribute.id); + } + } else { + log_w("Received message ignored. Cluster ID: %d not supported for Fan Control", message->info.cluster); + } +} + +void ZigbeeFanControl::fanModeChanged() { + if (_on_fan_mode_change) { + _on_fan_mode_change(_current_fan_mode); + } else { + log_w("No callback function set for fan mode change"); + } +} + +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeFanControl.h b/libraries/Zigbee/src/ep/ZigbeeFanControl.h new file mode 100644 index 00000000000..25b5862c5c4 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeFanControl.h @@ -0,0 +1,65 @@ +/* Class of Zigbee Pressure sensor endpoint inherited from common EP class */ + +#pragma once + +#include "soc/soc_caps.h" +#include "sdkconfig.h" +#if CONFIG_ZB_ENABLED + +#include "ZigbeeEP.h" +#include "ha/esp_zigbee_ha_standard.h" + +// Custom Arduino-friendly enums for fan mode values +enum ZigbeeFanMode { + FAN_MODE_OFF = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_OFF, + FAN_MODE_LOW = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_LOW, + FAN_MODE_MEDIUM = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_MEDIUM, + FAN_MODE_HIGH = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_HIGH, + FAN_MODE_ON = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_ON, + FAN_MODE_AUTO = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_AUTO, + FAN_MODE_SMART = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_SMART, +}; + +// Custom Arduino-friendly enums for fan mode sequence +enum ZigbeeFanModeSequence { + FAN_MODE_SEQUENCE_LOW_MED_HIGH = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_SEQUENCE_LOW_MED_HIGH, + FAN_MODE_SEQUENCE_LOW_HIGH = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_SEQUENCE_LOW_HIGH, + FAN_MODE_SEQUENCE_LOW_MED_HIGH_AUTO = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_SEQUENCE_LOW_MED_HIGH_AUTO, + FAN_MODE_SEQUENCE_LOW_HIGH_AUTO = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_SEQUENCE_LOW_HIGH_AUTO, + FAN_MODE_SEQUENCE_ON_AUTO = ESP_ZB_ZCL_FAN_CONTROL_FAN_MODE_SEQUENCE_ON_AUTO, +}; + +class ZigbeeFanControl : public ZigbeeEP { +public: + ZigbeeFanControl(uint8_t endpoint); + ~ZigbeeFanControl() {} + + // Set the fan mode sequence value + bool setFanModeSequence(ZigbeeFanModeSequence sequence); + + // Use to get fan mode + ZigbeeFanMode getFanMode() { + return _current_fan_mode; + } + + // Use to get fan mode sequence + ZigbeeFanModeSequence getFanModeSequence() { + return _current_fan_mode_sequence; + } + + // On fan mode change callback + void onFanModeChange(void (*callback)(ZigbeeFanMode mode)) { + _on_fan_mode_change = callback; + } + +private: + void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override; + //callback function to be called on fan mode change + void (*_on_fan_mode_change)(ZigbeeFanMode mode); + void fanModeChanged(); + + ZigbeeFanMode _current_fan_mode; + ZigbeeFanModeSequence _current_fan_mode_sequence; +}; + +#endif // CONFIG_ZB_ENABLED diff --git a/package.json b/package.json index 9c918733209..85a15ab3615 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "framework-arduinoespressif32", - "version": "3.2.0", + "version": "3.2.1", "description": "Arduino Wiring-based Framework for the Espressif ESP32, ESP32-P4, ESP32-S and ESP32-C series of SoCs", "keywords": [ "framework", diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index 9c1516dbacd..5f5d1f0e08b 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -51,7 +51,7 @@ { "packager": "esp32", "name": "esp32-arduino-libs", - "version": "idf-release_v5.4-f0f2980d-v1" + "version": "idf-release_v5.4-858a988d-v1" }, { "packager": "esp32", @@ -81,7 +81,7 @@ { "packager": "esp32", "name": "esptool_py", - "version": "5.0.dev1" + "version": "5.0.0" }, { "packager": "esp32", @@ -104,63 +104,63 @@ "tools": [ { "name": "esp32-arduino-libs", - "version": "idf-release_v5.4-f0f2980d-v1", + "version": "idf-release_v5.4-858a988d-v1", "systems": [ { "host": "i686-mingw32", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "checksum": "SHA-256:b1a77c83634111d78a356f1d1756dc815eeeb91605c5d8714a0db7cccbd0bede", - "size": "353978504" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "checksum": "SHA-256:4fc6eace642735036404c722d5602a379fe16378c72ffd060096cbef1c62d69d", + "size": "354134726" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "checksum": "SHA-256:b1a77c83634111d78a356f1d1756dc815eeeb91605c5d8714a0db7cccbd0bede", - "size": "353978504" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "checksum": "SHA-256:4fc6eace642735036404c722d5602a379fe16378c72ffd060096cbef1c62d69d", + "size": "354134726" }, { "host": "arm64-apple-darwin", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "checksum": "SHA-256:b1a77c83634111d78a356f1d1756dc815eeeb91605c5d8714a0db7cccbd0bede", - "size": "353978504" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "checksum": "SHA-256:4fc6eace642735036404c722d5602a379fe16378c72ffd060096cbef1c62d69d", + "size": "354134726" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "checksum": "SHA-256:b1a77c83634111d78a356f1d1756dc815eeeb91605c5d8714a0db7cccbd0bede", - "size": "353978504" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "checksum": "SHA-256:4fc6eace642735036404c722d5602a379fe16378c72ffd060096cbef1c62d69d", + "size": "354134726" }, { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "checksum": "SHA-256:b1a77c83634111d78a356f1d1756dc815eeeb91605c5d8714a0db7cccbd0bede", - "size": "353978504" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "checksum": "SHA-256:4fc6eace642735036404c722d5602a379fe16378c72ffd060096cbef1c62d69d", + "size": "354134726" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "checksum": "SHA-256:b1a77c83634111d78a356f1d1756dc815eeeb91605c5d8714a0db7cccbd0bede", - "size": "353978504" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "checksum": "SHA-256:4fc6eace642735036404c722d5602a379fe16378c72ffd060096cbef1c62d69d", + "size": "354134726" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "checksum": "SHA-256:b1a77c83634111d78a356f1d1756dc815eeeb91605c5d8714a0db7cccbd0bede", - "size": "353978504" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "checksum": "SHA-256:4fc6eace642735036404c722d5602a379fe16378c72ffd060096cbef1c62d69d", + "size": "354134726" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-f0f2980d-v1.zip", - "checksum": "SHA-256:b1a77c83634111d78a356f1d1756dc815eeeb91605c5d8714a0db7cccbd0bede", - "size": "353978504" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-858a988d-v1.zip", + "checksum": "SHA-256:4fc6eace642735036404c722d5602a379fe16378c72ffd060096cbef1c62d69d", + "size": "354134726" } ] }, @@ -469,56 +469,56 @@ }, { "name": "esptool_py", - "version": "5.0.dev1", + "version": "5.0.0", "systems": [ { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/arduino-esp32/releases/download/3.2.0/esptool-v5.0.dev1-linux-aarch64.tar.gz", - "archiveFileName": "esptool-v5.0.dev1-linux-aarch64.tar.gz", - "checksum": "SHA-256:bfafa7a7723ebbabfd8b6e3ca5ae00bfead0331de923754aeddb43b2c116a078", - "size": "58241736" + "url": "https://github.com/espressif/esptool/releases/download/v5.0.0/esptool-v5.0.0-linux-aarch64.tar.gz", + "archiveFileName": "esptool-v5.0.0-linux-aarch64.tar.gz", + "checksum": "SHA-256:2bf239f3ed76141a957cadb205b94414ec6da9ace4e85f285e247d20a92b83e3", + "size": "58231895" }, { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/arduino-esp32/releases/download/3.2.0/esptool-v5.0.dev1-linux-amd64.tar.gz", - "archiveFileName": "esptool-v5.0.dev1-linux-amd64.tar.gz", - "checksum": "SHA-256:acd0486e96586b99d053a1479acbbbfcae8667227c831cdc53a171f9ccfa27ee", - "size": "100740042" + "url": "https://github.com/espressif/esptool/releases/download/v5.0.0/esptool-v5.0.0-linux-amd64.tar.gz", + "archiveFileName": "esptool-v5.0.0-linux-amd64.tar.gz", + "checksum": "SHA-256:3b3835d266ac61f3242758f2fe34e3b33dbe6ee4b5acde005da793356f9f7043", + "size": "100783748" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/arduino-esp32/releases/download/3.2.0/esptool-v5.0.dev1-linux-armv7.tar.gz", - "archiveFileName": "esptool-v5.0.dev1-linux-armv7.tar.gz", - "checksum": "SHA-256:ea77a38681506761bbb7b0b39c130811ed565667b67ebbdb4d6dcc6cb6e07368", - "size": "53451939" + "url": "https://github.com/espressif/esptool/releases/download/v5.0.0/esptool-v5.0.0-linux-armv7.tar.gz", + "archiveFileName": "esptool-v5.0.0-linux-armv7.tar.gz", + "checksum": "SHA-256:e55cd321abecfcf27f72a2bff5d5e19a5365fd400de66d71c5e7218e77556315", + "size": "53461760" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/arduino-esp32/releases/download/3.2.0/esptool-v5.0.dev1-macos-amd64.tar.gz", - "archiveFileName": "esptool-v5.0.dev1-macos-amd64.tar.gz", - "checksum": "SHA-256:900a8e90731208bee96647e0e207a43612b9452c2120c4fdc0ff4c6be226257b", - "size": "59631998" + "url": "https://github.com/espressif/esptool/releases/download/v5.0.0/esptool-v5.0.0-macos-amd64.tar.gz", + "archiveFileName": "esptool-v5.0.0-macos-amd64.tar.gz", + "checksum": "SHA-256:424da2bdf0435257ad81bcb7eae6fd8dd7f675ce5b2ee60032f4ecec4d6a5d45", + "size": "59629533" }, { "host": "arm64-apple-darwin", - "url": "https://github.com/espressif/arduino-esp32/releases/download/3.2.0/esptool-v5.0.dev1-macos-arm64.tar.gz", - "archiveFileName": "esptool-v5.0.dev1-macos-arm64.tar.gz", - "checksum": "SHA-256:3653f4de73cb4fc6a25351eaf663708e91c65ae3265d75bd54ca4315a4350bb4", - "size": "56349992" + "url": "https://github.com/espressif/esptool/releases/download/v5.0.0/esptool-v5.0.0-macos-arm64.tar.gz", + "archiveFileName": "esptool-v5.0.0-macos-arm64.tar.gz", + "checksum": "SHA-256:b91dfe1da7b0041376683dec10a91dfb266fbda2fb86ed87c4a034ff7182ee56", + "size": "56343104" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/arduino-esp32/releases/download/3.2.0/esptool-v5.0.dev1-win64.zip", - "archiveFileName": "esptool-v5.0.dev1-win64.zip", - "checksum": "SHA-256:1e8fd89645daf94f2d4406ec73c9004e617ea921079515f9fd749205eece4d6d", - "size": "59102658" + "url": "https://github.com/espressif/esptool/releases/download/v5.0.0/esptool-v5.0.0-windows-amd64.zip", + "archiveFileName": "esptool-v5.0.0-windows-amd64.zip", + "checksum": "SHA-256:2294107f66db6f09b886b337728a981173c9e7eab45a030928a8a5a1370611ca", + "size": "59105322" }, { "host": "i686-mingw32", - "url": "https://github.com/espressif/arduino-esp32/releases/download/3.2.0/esptool-v5.0.dev1-win64.zip", - "archiveFileName": "esptool-v5.0.dev1-win64.zip", - "checksum": "SHA-256:1e8fd89645daf94f2d4406ec73c9004e617ea921079515f9fd749205eece4d6d", - "size": "59102658" + "url": "https://github.com/espressif/esptool/releases/download/v5.0.0/esptool-v5.0.0-windows-amd64.zip", + "archiveFileName": "esptool-v5.0.0-windows-amd64.zip", + "checksum": "SHA-256:2294107f66db6f09b886b337728a981173c9e7eab45a030928a8a5a1370611ca", + "size": "59105322" } ] }, diff --git a/platform.txt b/platform.txt index 8c7f4432377..62cb829dcf0 100644 --- a/platform.txt +++ b/platform.txt @@ -1,5 +1,5 @@ name=ESP32 Arduino -version=3.2.0 +version=3.2.1 tools.esp32-arduino-libs.path={runtime.platform.path}/tools/esp32-arduino-libs tools.esp32-arduino-libs.path.windows={runtime.platform.path}\tools\esp32-arduino-libs @@ -330,3 +330,19 @@ tools.dfu-util.cmd=dfu-util tools.dfu-util.upload.params.verbose=-d tools.dfu-util.upload.params.quiet= tools.dfu-util.upload.pattern="{path}/{cmd}" --device {vid.0}:{pid.0} -D "{build.path}/{build.project_name}.bin" -Q + +## -------------------------------------------------------------------------- +## esptool_py_app_only is used to upload only the application image +## It won't upload the bootloader or any other binary except for the main application +## -------------------------------------------------------------------------- +tools.esptool_py_app_only.path={runtime.tools.esptool_py.path} +tools.esptool_py_app_only.cmd=esptool +tools.esptool_py_app_only.cmd.windows=esptool.exe + +tools.esptool_py_app_only.upload.protocol=serial +tools.esptool_py_app_only.upload.params.verbose= +tools.esptool_py_app_only.upload.params.quiet= + +tools.esptool_py_app_only.upload.pattern_args=--chip {build.mcu} --port "{serial.port}" --baud {upload.speed} {upload.flags} --before default_reset --after hard_reset write_flash --flash_mode {build.flash_mode} --flash_freq {build.flash_freq} --flash_size {build.flash_size} {build.flash_offset} "{build.path}/{build.project_name}.bin" {upload.extra_flags} + +tools.esptool_py_app_only.upload.pattern="{path}/{cmd}" {tools.esptool_py_app_only.upload.pattern_args} diff --git a/tools/pioarduino-build.py b/tools/pioarduino-build.py index b6a0c0435c5..4d4161dd9ca 100644 --- a/tools/pioarduino-build.py +++ b/tools/pioarduino-build.py @@ -95,7 +95,7 @@ def generate_bootloader_image(bootloader_elf): env.VerboseAction( " ".join( [ - '"$PYTHONEXE" "$OBJCOPY"', + "$OBJCOPY", "--chip", build_mcu, "elf2image", @@ -216,8 +216,14 @@ def add_tinyuf2_extra_image(): "0x1000" if build_mcu in ["esp32", "esp32s2"] else ("0x2000" if build_mcu in ["esp32p4"] else "0x0000"), get_bootloader_image(variants_dir), ), - ("0x8000", join(env.subst("$BUILD_DIR"), "partitions.bin")), - ("0xe000", join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin")), + ( + board_config.get("upload.arduino.partitions_bin", "0x8000"), + join(env.subst("$BUILD_DIR"), "partitions.bin"), + ), + ( + board_config.get("upload.arduino.boot_app0", "0xe000"), + join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin"), + ), ] + [(offset, join(FRAMEWORK_DIR, img)) for offset, img in board_config.get("upload.arduino.flash_extra_images", [])], ) diff --git a/variants/deneyapkartv2/pins_arduino.h b/variants/deneyapkartv2/pins_arduino.h new file mode 100644 index 00000000000..f7eccadb13c --- /dev/null +++ b/variants/deneyapkartv2/pins_arduino.h @@ -0,0 +1,123 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include +#include "soc/soc_caps.h" + +#define USB_VID 0x303A +#define USB_PID 0x82EB +#define USB_MANUFACTURER "Turkish Technology Team Foundation (T3)" +#define USB_PRODUCT "DENEYAP KART v2" +#define USB_SERIAL "" // Empty string for MAC address + +static const uint8_t LED_BUILTIN = SOC_GPIO_PIN_COUNT + 46; +#define BUILTIN_LED LED_BUILTIN // backward compatibility +#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN +#define RGB_BUILTIN LED_BUILTIN +#define RGBLED LED_BUILTIN +#define RGB_BRIGHTNESS 64 + +static const uint8_t GPKEY = 0; +#define KEY_BUILTIN GPKEY +#define BUILTIN_KEY GPKEY + +static const uint8_t TX = 43; +static const uint8_t RX = 44; +#define TX1 TX +#define RX1 RX + +static const uint8_t SDA = 47; +static const uint8_t SCL = 21; + +static const uint8_t SS = 42; +static const uint8_t MOSI = 39; +static const uint8_t MISO = 40; +static const uint8_t SCK = 41; + +static const uint8_t A0 = 4; +static const uint8_t A1 = 5; +static const uint8_t A2 = 6; +static const uint8_t A3 = 7; +static const uint8_t A4 = 15; +static const uint8_t A5 = 16; +static const uint8_t A6 = 17; +static const uint8_t A7 = 18; +static const uint8_t A8 = 8; +static const uint8_t A9 = 9; +static const uint8_t A10 = 10; +static const uint8_t A11 = 11; +static const uint8_t A12 = 2; +static const uint8_t A13 = 1; +static const uint8_t A14 = 3; +static const uint8_t A15 = 12; +static const uint8_t A16 = 13; +static const uint8_t A17 = 14; + +static const uint8_t T0 = 4; +static const uint8_t T1 = 5; +static const uint8_t T2 = 6; +static const uint8_t T3 = 7; +static const uint8_t T4 = 8; +static const uint8_t T5 = 9; +static const uint8_t T6 = 10; +static const uint8_t T7 = 11; +static const uint8_t T8 = 2; +static const uint8_t T9 = 1; +static const uint8_t T10 = 3; +static const uint8_t T11 = 12; +static const uint8_t T12 = 13; +static const uint8_t T13 = 14; + +static const uint8_t D0 = 1; +static const uint8_t D1 = 2; +static const uint8_t D2 = 43; +static const uint8_t D3 = 44; +static const uint8_t D4 = 42; +static const uint8_t D5 = 41; +static const uint8_t D6 = 40; +static const uint8_t D7 = 39; +static const uint8_t D8 = 38; +static const uint8_t D9 = 48; +static const uint8_t D10 = 47; +static const uint8_t D11 = 21; +static const uint8_t D12 = 11; +static const uint8_t D13 = 10; +static const uint8_t D14 = 9; +static const uint8_t D15 = 8; +static const uint8_t D16 = 18; +static const uint8_t D17 = 17; +static const uint8_t D18 = 16; +static const uint8_t D19 = 15; +static const uint8_t D20 = 7; +static const uint8_t D21 = 6; +static const uint8_t D22 = 5; +static const uint8_t D23 = 4; +static const uint8_t D24 = 46; +static const uint8_t D25 = 0; +static const uint8_t D26 = 3; +static const uint8_t D27 = 12; +static const uint8_t D28 = 13; +static const uint8_t D29 = 14; + +static const uint8_t CAMSD = 4; +static const uint8_t CAMSC = 5; +static const uint8_t CAMD2 = 41; +static const uint8_t CAMD3 = 2; +static const uint8_t CAMD4 = 1; +static const uint8_t CAMD5 = 42; +static const uint8_t CAMD6 = 40; +static const uint8_t CAMD7 = 38; +static const uint8_t CAMD8 = 17; +static const uint8_t CAMD9 = 15; +static const uint8_t CAMPC = 39; +static const uint8_t CAMXC = 16; +static const uint8_t CAMH = 7; +static const uint8_t CAMV = 6; + +static const uint8_t SDCM = 12; +static const uint8_t SDCK = 13; +static const uint8_t SDDA = 14; + +static const uint8_t BAT = 3; + +#endif /* Pins_Arduino_h */ diff --git a/variants/fed4/pins_arduino.h b/variants/fed4/pins_arduino.h new file mode 100644 index 00000000000..f3741700ffa --- /dev/null +++ b/variants/fed4/pins_arduino.h @@ -0,0 +1,79 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include +#include "soc/soc_caps.h" + +#define USB_VID 0x303A +#define USB_PID 0x82E5 +#define USB_MANUFACTURER "Smart Bee Designs LLC" +#define USB_PRODUCT "FED4" +#define USB_SERIAL "" + +static const uint8_t TX = 43; +static const uint8_t RX = 44; + +static const uint8_t SDA = 8; +static const uint8_t SCL = 9; +static const uint8_t SDA2 = 20; +static const uint8_t SCL2 = 19; + +static const uint8_t SS = 47; +static const uint8_t MOSI = 11; +static const uint8_t MISO = 13; +static const uint8_t SCK = 12; +static const uint8_t SDCS = 10; // sd cs pin +static const uint8_t DSCS = 14; //display cs pin + +static const uint8_t A1 = 1; +static const uint8_t A2 = 2; +static const uint8_t A3 = 3; +static const uint8_t A4 = 4; +static const uint8_t A5 = 5; +static const uint8_t A6 = 6; + +static const uint8_t D1 = 1; +static const uint8_t D2 = 2; +static const uint8_t D3 = 3; +static const uint8_t D4 = 4; +static const uint8_t D5 = 5; +static const uint8_t D6 = 6; +static const uint8_t D8 = 8; +static const uint8_t D13 = 13; +static const uint8_t D9 = 9; + +static const uint8_t T1 = 1; +static const uint8_t T2 = 2; +static const uint8_t T3 = 3; +static const uint8_t T4 = 4; +static const uint8_t T5 = 5; +static const uint8_t T6 = 6; + +static const uint8_t BOOT_BTN = 0; +static const uint8_t VBAT_VOLTAGE = 7; +static const uint8_t LDO2 = 47; +static const uint8_t STATUS_RGB = 35; +static const uint8_t RGB_STRIP = 36; +static const uint8_t INTERRUPT_PIN = 18; +static const uint8_t USER_BTN_1 = 14; +static const uint8_t USER_BTN_2 = 39; +static const uint8_t USER_BTN_3 = 40; +static const uint8_t AMP_DIN = 39; +static const uint8_t AMP_SD = 42; +static const uint8_t AMP_BCLK = 45; +static const uint8_t AMP_LRCLK = 48; +static const uint8_t MSBY = 15; +static const uint8_t TRRS_1 = 4; +static const uint8_t TRRS_2 = 2; +static const uint8_t TRRS_3 = 3; + +#define PIN_RGB_LED STATUS_RGB +// BUILTIN_LED can be used in new Arduino API digitalWrite() like in Blink.ino +static const uint8_t LED_BUILTIN = SOC_GPIO_PIN_COUNT + PIN_RGB_LED; +#define BUILTIN_LED LED_BUILTIN // backward compatibility +#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN +// RGB_BUILTIN and RGB_BRIGHTNESS can be used in new Arduino API rgbLedWrite() +#define RGB_BUILTIN LED_BUILTIN +#define RGB_BRIGHTNESS 64 + +#endif /* Pins_Arduino_h */ diff --git a/variants/kodedot/custom_ota_override.cpp b/variants/kodedot/custom_ota_override.cpp new file mode 100644 index 00000000000..a41db01db16 --- /dev/null +++ b/variants/kodedot/custom_ota_override.cpp @@ -0,0 +1,14 @@ +// custom_ota_override.cpp +// This function overrides the weak definition of `verifyRollbackLater()` in the kode dot board. + +extern "C" { +// Declare the weak function symbol to override it +bool verifyRollbackLater() __attribute__((weak)); +} + +// Custom implementation of verifyRollbackLater() +// Returning `true` prevents the OTA image from being automatically marked as valid. +// This ensures that the system will roll back to the previous image unless it is explicitly validated later. +bool verifyRollbackLater() { + return true; +} diff --git a/variants/kodedot/kodedot_partitions.csv b/variants/kodedot/kodedot_partitions.csv new file mode 100644 index 00000000000..f0732330850 --- /dev/null +++ b/variants/kodedot/kodedot_partitions.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +otadata, data, ota, 0x10000, 0x2000, +ota_0, app, ota_0, 0x20000, 0x3E0000, +ota_1, app, ota_1, 0x400000, 0x800000, +storage, data, spiffs, 0xC00000, 0x400000, diff --git a/variants/kodedot/pins_arduino.h b/variants/kodedot/pins_arduino.h new file mode 100644 index 00000000000..f19ddb8a616 --- /dev/null +++ b/variants/kodedot/pins_arduino.h @@ -0,0 +1,107 @@ +/* + ──────────────────────────────────────────────────────────────────────── + KodeDot – ESP32-S3R8 Variant + Pin definition file for the Arduino-ESP32 core + ──────────────────────────────────────────────────────────────────────── + * External 2 × 10 connector → simple aliases PIN1 … PIN20 + * On-board QSPI LCD 410×502 @40 MHz (SPI3_HOST) + * micro-SD on SPI2_HOST + * Dual-I²C: external (GPIO37/36) + internal-sensors (GPIO48/47) + * USB VID/PID 0x303A:0x1001 +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include +#include + +/*──────────────── USB device descriptor ────────────────*/ +#define USB_VID 0x303A // Espressif Systems VID +#define USB_PID 0x1001 // Product ID: KodeDot-S3 + +/*──────────────── UART0 (Arduino Serial) ────────────────*/ +static const uint8_t TX = 43; // U0TXD – PIN16 on the 2×10 header +static const uint8_t RX = 44; // U0RXD – PIN18 on the 2×10 header + +/*──────────────── I²C buses ─────────────────────────────*/ +/* External expansion bus → header pins 11/13 */ +static const uint8_t SCL = 37; // GPIO37 – PIN12 +static const uint8_t SDA = 36; // GPIO36 – PIN14 + +/* Internal sensor/touch bus (not on header) */ +#define INT_I2C_SCL 47 // GPIO47 +#define INT_I2C_SDA 48 // GPIO48 + +/*──────────────── SPI2 – micro-SD ───────────────────────*/ +static const uint8_t SS = 15; // SD_CS +static const uint8_t MOSI = 16; // SD_MOSI +static const uint8_t MISO = 18; // SD_MISO +static const uint8_t SCK = 17; // SD_CLK +#define BOARD_HAS_SD_SPI +#define SD_CS SS + +/*──────────────── QSPI LCD (SPI3_HOST) ─────────────────– + * Controller: ST7789 / 4-line SPI (no D/C pin) + * Resolution: 410×502 px, 16 bpp, RGB color-space + * Clock: 40 MHz + */ +#define BOARD_HAS_SPI_LCD +#define LCD_MODEL ST7789 +#define LCD_WIDTH 410 +#define LCD_HEIGHT 502 + +#define LCD_HOST SPI3_HOST +#define LCD_SCK 35 // GPIO35 • QSPI_CLK +#define LCD_MOSI 33 // GPIO33 • QSPI_IO0 (D0) +#define LCD_IO1 34 // GPIO34 • QSPI_IO1 (D1) +#define LCD_IO2 37 // GPIO37 • QSPI_IO2 (D2) +#define LCD_IO3 36 // GPIO36 • QSPI_IO3 (D3) +#define LCD_CS 10 // GPIO10 +#define LCD_RST 9 // GPIO09 +#define LCD_DC -1 // not used in 4-line SPI +/* Optional: back-light enable shares the NeoPixel pin */ +#define LCD_BL 5 // GPIO05 (same as NEOPIXEL) + +/*──────────────── Analog / Touch pads ────────────────*/ +static const uint8_t A0 = 11; // PIN4 – GPIO11 / TOUCH11 / ADC2_CH0 +static const uint8_t A1 = 12; // PIN6 – GPIO12 / TOUCH12 / ADC2_CH1 +static const uint8_t A2 = 13; // PIN8 – GPIO13 / TOUCH13 / ADC2_CH2 +static const uint8_t A3 = 14; // PIN10 – GPIO14 / TOUCH14 / ADC2_CH3 +static const uint8_t T0 = A0, T1 = A1, T2 = A2, T3 = A3; + +/*──────────────── On-board controls & indicator ─────────*/ +#define BUTTON_TOP 0 // GPIO00 – BOOT • active-LOW +#define BUTTON_BOTTOM 6 // GPIO06 • active-LOW +#define NEOPIXEL_PIN 5 // GPIO05 – WS2812 +#define LED_BUILTIN NEOPIXEL_PIN + +/*──────────────── JTAG (also on connector) ──────────────*/ +#define MTCK 39 // PIN11 – GPIO39 +#define MTDO 40 // PIN13 – GPIO40 +#define MTDI 41 // PIN15 – GPIO41 +#define MTMS 42 // PIN17 – GPIO42 + +/*──────────────── 2×10 header: simple aliases ─────────── + NOTE: power pins (1 = 5 V, 2 = 3 V3, 19/20 = GND) are **not** + exposed as GPIO numbers – they remain undefined here. */ +#define PIN3 1 // GPIO01 / TOUCH1 / ADC1_CH0 +#define PIN4 11 // GPIO11 / TOUCH11 / ADC2_CH0 +#define PIN5 2 // GPIO02 / TOUCH2 / ADC1_CH1 +#define PIN6 12 // GPIO12 / TOUCH12 / ADC2_CH1 +#define PIN7 3 // GPIO03 / TOUCH3 / ADC1_CH2 +#define PIN8 13 // GPIO13 / TOUCH13 / ADC2_CH2 +#define PIN9 4 // GPIO04 / TOUCH4 / ADC1_CH3 +#define PIN10 14 // GPIO14 / TOUCH14 / ADC2_CH3 +#define PIN11 39 // MTCK +#define PIN12 37 // SCL (external I²C) +#define PIN13 40 // MTDO +#define PIN14 36 // SDA (external I²C) +#define PIN15 41 // MTDI +#define PIN16 43 // TX (U0TXD) +#define PIN17 42 // MTMS +#define PIN18 44 // RX (U0RXD) +/* PIN1, PIN2, PIN19, PIN20 are power/ground and deliberately + left undefined – they are **not** usable as GPIO. */ + +#endif /* Pins_Arduino_h */ diff --git a/variants/rakwireless_rak3112/pins_arduino.h b/variants/rakwireless_rak3112/pins_arduino.h new file mode 100644 index 00000000000..f1bcc7a6120 --- /dev/null +++ b/variants/rakwireless_rak3112/pins_arduino.h @@ -0,0 +1,63 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +// Reference: RAK3112 Module Datasheet +// https://docs.rakwireless.com/product-categories/wisduo/rak3112-module/datasheet/ + +// Note:GPIO33,GPIO34,GPIO35.GPIO36,GPIO37 is not available in the 8MB and 16MB Octal PSRAM version + +#define USB_VID 0x303a +#define USB_PID 0x1001 + +#define LED_GREEN 46 +#define LED_BLUE 45 + +static const uint8_t LED_BUILTIN = LED_GREEN; +#define BUILTIN_LED LED_BUILTIN // backward compatibility +#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN + +static const uint8_t BAT_VOLT = 21; + +static const uint8_t TX = 43; +static const uint8_t RX = 44; + +static const uint8_t SDA = 9; +static const uint8_t SCL = 40; + +#define WIRE1_PIN_DEFINED +static const uint8_t SDA1 = 17; +static const uint8_t SCL1 = 18; + +static const uint8_t SS = 12; +static const uint8_t MOSI = 11; +static const uint8_t MISO = 10; +static const uint8_t SCK = 13; + +#define LORA_ANT_SWITCH 4 // Antenna switch power control pin + +#define LORA_SCK 5 // SX1262 SCK +#define LORA_MISO 3 // SX1262 MISO +#define LORA_MOSI 6 // SX1262 MOSI +#define LORA_CS 7 // SX1262 CS +#define LORA_RST 8 // SX1262 RST + +#define LORA_DIO1 47 //SX1262 DIO1 +#define LORA_BUSY 48 +#define LORA_IRQ LORA_DIO1 + +// For WisBlock modules, see: https://docs.rakwireless.com/Product-Categories/WisBlock/ +#define WB_IO1 21 +#define WB_IO2 14 +#define WB_IO3 41 +#define WB_IO4 42 +#define WB_IO5 38 +#define WB_IO6 39 +#define WB_A0 1 +#define WB_A1 2 +#define WB_CS 12 +#define WB_LED1 46 +#define WB_LED2 45 + +#endif /* Pins_Arduino_h */ diff --git a/variants/sensebox_mcu_esp32s2/APOTA.bin b/variants/sensebox_mcu_esp32s2/APOTA.bin new file mode 100644 index 00000000000..0ea39335dce Binary files /dev/null and b/variants/sensebox_mcu_esp32s2/APOTA.bin differ diff --git a/variants/sensebox_mcu_esp32s2/APOTA.ino b/variants/sensebox_mcu_esp32s2/APOTA.ino new file mode 100644 index 00000000000..5f683752abc --- /dev/null +++ b/variants/sensebox_mcu_esp32s2/APOTA.ino @@ -0,0 +1,283 @@ +#define DISPLAY_ENABLED + +#include +#include +#include +#include +#include +#include +#ifdef DISPLAY_ENABLED +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 +#define OLED_RESET -1 +#include +#include +Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); +#include +Adafruit_NeoPixel rgb_led_1 = Adafruit_NeoPixel(1, 1, NEO_GRB + NEO_KHZ800); + +#endif +#include "esp_partition.h" +#include "esp_ota_ops.h" +#include "esp_system.h" + +String ssid; +uint8_t mac[6]; + +// Create an instance of the server +WebServer server(80); +bool displayEnabled; + +const int BUTTON_PIN = 0; // GPIO for the button +volatile unsigned long lastPressTime = 0; // Time of last button press +volatile bool doublePressDetected = false; // Flag for double press +const unsigned long doublePressInterval = 500; // Max. time (in ms) between two presses for double press +volatile int pressCount = 0; // Counts the button presses + +const unsigned char epd_bitmap_wifi[] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0xff, 0x00, 0x00, + 0x00, 0x3f, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x7c, 0x00, 0x03, 0xe0, 0x00, 0x00, 0xf0, 0x00, 0x01, 0xf0, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x78, 0x00, + 0x03, 0xc0, 0x00, 0x00, 0x38, 0x00, 0x07, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x7f, 0xe0, 0x0e, 0x00, + 0x0c, 0x01, 0xff, 0xf0, 0x06, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x02, 0x00, 0x00, 0x0f, 0x80, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x1c, 0x00, 0x07, 0x80, 0x00, 0x00, 0x38, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x70, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x70, 0x00, 0x00, 0xc0, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, + 0x00, 0x01, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x78, 0x00, 0x00, 0x00, 0x03, 0x80, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +// 'checkmark', 44x44px +const unsigned char epd_bitmap_checkmark[] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x00, + 0x00, 0x0f, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0x83, 0xc0, 0x00, 0x00, 0x00, 0x07, 0xc7, 0x80, 0x00, 0x00, 0x00, 0x03, 0xef, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +void IRAM_ATTR handleButtonPress() { + unsigned long currentTime = millis(); // Get current time + + // Debounce: If the current press is too close to the last one, ignore it + if (currentTime - lastPressTime > 50) { + pressCount++; // Count the button press + + // Check if this is the second press within the double-press interval + if (pressCount == 2 && (currentTime - lastPressTime <= doublePressInterval)) { + doublePressDetected = true; // Double press detected + pressCount = 0; // Reset counter + } + + lastPressTime = currentTime; // Update the time of the last press + } +} + +// Function to switch the boot partition to OTA1 +void setBootPartitionToOTA0() { + const esp_partition_t *ota0_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL); + + if (ota0_partition) { + // Set OTA1 as new boot partition + esp_ota_set_boot_partition(ota0_partition); + Serial.println("Boot partition changed to OTA0. Restarting..."); + + // Restart to boot from the new partition + esp_restart(); + } else { + Serial.println("OTA1 partition not found!"); + } +} + +void setupDisplay() { + displayEnabled = display.begin(SSD1306_SWITCHCAPVCC, 0x3D); + if (displayEnabled) { + display.display(); + delay(100); + display.clearDisplay(); + } +} + +void displayStatusBar(int progress) { + display.clearDisplay(); + display.setCursor(24, 8); + display.println("Sketch wird"); + display.setCursor(22, 22); + display.println("hochgeladen!"); + + display.fillRect(0, SCREEN_HEIGHT - 24, SCREEN_WIDTH - 4, 8, BLACK); // Clear status bar area + display.drawRect(0, SCREEN_HEIGHT - 24, SCREEN_WIDTH - 4, 8, WHITE); // Draw border + int filledWidth = (progress * SCREEN_WIDTH - 4) / 100; // Calculate progress width + display.fillRect(1, SCREEN_HEIGHT - 23, filledWidth - 4, 6, WHITE); // Fill progress bar + + display.setCursor((SCREEN_WIDTH / 2) - 12, SCREEN_HEIGHT - 10); + display.setTextSize(1); + display.setTextColor(WHITE, BLACK); + display.print(progress); + display.println(" %"); + display.display(); +} + +void displayWelcomeScreen() { + display.clearDisplay(); + + // Draw WiFi symbol + display.drawBitmap(0, 12, epd_bitmap_wifi, 44, 44, WHITE); + + // Display SSID text + display.setCursor(40, 13); + display.setTextSize(1); + display.setTextColor(WHITE, BLACK); + display.println("Verbinde dich"); // "Connect" + display.setCursor(60, 27); + display.println("mit:"); // "with" + + // Display SSID + display.setCursor(40, 43); + display.setTextSize(1); // Larger text for SSID + display.print(ssid); + + display.display(); +} + +void displaySuccessScreen() { + display.clearDisplay(); + + // Draw WiFi symbol + display.drawBitmap(0, 12, epd_bitmap_checkmark, 44, 44, WHITE); + + // Display SSID text + display.setCursor(48, 22); + display.setTextSize(1); + display.setTextColor(WHITE, BLACK); + display.println("Erfolgreich"); // "Successfully" + display.setCursor(48, 36); + display.println("hochgeladen!"); // "uploaded!" + + display.display(); +} + +void wipeDisplay() { + display.clearDisplay(); + display.println(""); + display.display(); +} + +void setupWiFi() { + WiFi.macAddress(mac); + char macLastFour[5]; + snprintf(macLastFour, sizeof(macLastFour), "%02X%02X", mac[4], mac[5]); + ssid = "senseBox:" + String(macLastFour); + + // Define the IP address, gateway, and subnet mask + IPAddress local_IP(192, 168, 1, 1); // The new IP address + IPAddress gateway(192, 168, 1, 1); // Gateway address (can be the same as the AP's IP) + IPAddress subnet(255, 255, 255, 0); // Subnet mask + + // Set the IP address, gateway, and subnet mask of the access point + WiFi.softAPConfig(local_IP, gateway, subnet); + + // Start the access point + WiFi.softAP(ssid.c_str()); +} + +void setupOTA() { + // Handle updating process + server.on( + "/sketch", HTTP_POST, + []() { + server.sendHeader("Connection", "close"); + server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK"); + ESP.restart(); + }, + []() { + HTTPUpload &upload = server.upload(); + + if (upload.status == UPLOAD_FILE_START) { + Serial.setDebugOutput(true); + size_t fsize = UPDATE_SIZE_UNKNOWN; + if (server.clientContentLength() > 0) { + fsize = server.clientContentLength(); + } + Serial.printf("Receiving Update: %s, Size: %d\n", upload.filename.c_str(), fsize); + + Serial.printf("Update: %s\n", upload.filename.c_str()); + if (!Update.begin(fsize)) { //start with max available size + Update.printError(Serial); + } + } else if (upload.status == UPLOAD_FILE_WRITE) { + /* flashing firmware to ESP*/ + if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) { + Update.printError(Serial); + } else { + int progress = (Update.progress() * 100) / Update.size(); + displayStatusBar(progress); // Update progress on status bar + } + } else if (upload.status == UPLOAD_FILE_END) { + if (Update.end(true)) { //true to set the size to the current progress + displaySuccessScreen(); + delay(3000); + wipeDisplay(); + } else { + Update.printError(Serial); + } + Serial.setDebugOutput(false); + } + yield(); + } + ); +} + +void setup() { + // Start Serial communication + Serial.begin(115200); + rgb_led_1.begin(); + rgb_led_1.setBrightness(30); + rgb_led_1.setPixelColor(0, rgb_led_1.Color(51, 51, 255)); + rgb_led_1.show(); + + // Configure button pin as input + pinMode(BUTTON_PIN, INPUT_PULLUP); + + // Interrupt for the button + attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), handleButtonPress, FALLING); + +#ifdef DISPLAY_ENABLED + setupDisplay(); +#endif + setupWiFi(); + // Set the ESP32 as an access point + setupOTA(); + server.begin(); +} + +void loop() { + // Handle client requests + server.handleClient(); + +#ifdef DISPLAY_ENABLED + displayWelcomeScreen(); +#endif + + if (doublePressDetected) { + Serial.println("Doppeldruck erkannt!"); // "Double press detected!" + setBootPartitionToOTA0(); +#ifdef DISPLAY_ENABLED + display.setCursor(0, 0); + display.setTextSize(1); + display.setTextColor(WHITE, BLACK); + display.println(""); + display.display(); + delay(50); +#endif + // Restart to boot from the new partition + esp_restart(); + } +} diff --git a/variants/sensebox_mcu_esp32s2/variant.cpp b/variants/sensebox_mcu_esp32s2/variant.cpp index 0c58ef2cbe2..aa1eb3dc7c5 100644 --- a/variants/sensebox_mcu_esp32s2/variant.cpp +++ b/variants/sensebox_mcu_esp32s2/variant.cpp @@ -1,29 +1,10 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2021 Ha Thach (tinyusb.org) for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - #include "esp32-hal-gpio.h" #include "pins_arduino.h" +#include "esp_partition.h" +#include "esp_system.h" +#include "esp_ota_ops.h" +#include "esp_log.h" +#include extern "C" { @@ -41,12 +22,51 @@ void initVariant(void) { pinMode(PIN_XB1_ENABLE, OUTPUT); digitalWrite(PIN_XB1_ENABLE, LOW); - //enable UART by default - pinMode(PIN_UART_ENABLE, OUTPUT); - digitalWrite(PIN_UART_ENABLE, LOW); + //enable UART only for chip without PSRAM + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + if (chip_info.revision <= 0) { + pinMode(PIN_UART_ENABLE, OUTPUT); + digitalWrite(PIN_UART_ENABLE, LOW); + } //enable PD-Sensor by default pinMode(PD_ENABLE, OUTPUT); digitalWrite(PD_ENABLE, HIGH); + + // define button pin + const int PIN_BUTTON = 0; + pinMode(PIN_BUTTON, INPUT_PULLUP); + + // keep button pressed + unsigned long pressStartTime = 0; + bool buttonPressed = false; + + // Wait 5 seconds for the button to be pressed + unsigned long startTime = millis(); + + // Check if button is pressed + while (millis() - startTime < 5000) { + if (digitalRead(PIN_BUTTON) == LOW) { + if (!buttonPressed) { + // The button was pressed + buttonPressed = true; + } + } else if (buttonPressed) { + // When the button is pressed and then released, boot into the OTA1 partition + const esp_partition_t *ota1_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_1, NULL); + + if (ota1_partition) { + esp_err_t err = esp_ota_set_boot_partition(ota1_partition); + if (err == ESP_OK) { + esp_restart(); // restart, to boot OTA1 partition + } else { + ESP_LOGE("OTA", "Error setting OTA1 partition: %s", esp_err_to_name(err)); + } + } + // Abort after releasing the button + break; + } + } } }