From 40fd056922ed49c0703fd9476d0f0d577d2b76d3 Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Thu, 12 Feb 2026 00:58:14 +0100 Subject: [PATCH] Arduino Core 3.3.7 --- .github/workflows/examples.yml | 8 +- FATFS_INTEGRATION.md | 175 ++++++++++++++++++++++++++ README.md | 4 +- boards/esp32-c61-devkitc1.json | 36 ++++++ boards/esp32-p4_r3-evboard.json | 41 ++++++ boards/yb_esp32s3_amp.json | 56 +++++++++ boards/yb_esp32s3_dac.json | 56 +++++++++ builder/frameworks/espidf.py | 2 +- builder/penv_setup.py | 73 +++++++---- examples/espidf-blink/platformio.ini | 2 +- examples/espidf-ulp-lp/platformio.ini | 2 +- platform.json | 16 +-- platform.py | 17 ++- 13 files changed, 439 insertions(+), 49 deletions(-) create mode 100644 FATFS_INTEGRATION.md create mode 100644 boards/esp32-c61-devkitc1.json create mode 100644 boards/esp32-p4_r3-evboard.json create mode 100644 boards/yb_esp32s3_amp.json create mode 100644 boards/yb_esp32s3_dac.json diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index b3820be..ef4ba19 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -52,21 +52,21 @@ jobs: example: "examples/espidf-arduino-matter-light" runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: "recursive" - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.13" - name: Install uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@v7 with: version: "latest" enable-cache: false - name: Install dependencies run: | - uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.18.zip + uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.19.zip pio pkg install --global --platform file://. - name: git clone Tasmota and add to examples if: "matrix.example == 'examples/tasmota'" diff --git a/FATFS_INTEGRATION.md b/FATFS_INTEGRATION.md new file mode 100644 index 0000000..8be1ddb --- /dev/null +++ b/FATFS_INTEGRATION.md @@ -0,0 +1,175 @@ +# FatFS Integration for Platform-Espressif32 + +This platform now supports FatFS as a filesystem option, analogous to the existing LittleFS integration. + +## Features + +- **Build FatFS Image**: Creates a FatFS filesystem image from a directory +- **Upload FatFS Image**: Uploads the FatFS image to the ESP32 device +- **Download FatFS Image**: Downloads the FatFS image from the device and extracts it + +## Configuration + +### platformio.ini + +```ini +[env:myenv] +platform = espressif32 +board = esp32dev +framework = arduino + +; Select FatFS as filesystem +board_build.filesystem = fatfs + +; Optional: Directory for extracted files (default: unpacked_fs) +board_build.unpack_dir = unpacked_fs +``` + +### Partition Table + +The partition table must contain a FAT partition (Subtype 0x81): + +```csv +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x140000, +app1, app, ota_1, 0x150000,0x140000, +ffat, data, fat, 0x290000,0x170000, +``` + +## Usage + +### Build FatFS Image + +```bash +# Place files in data/ directory +mkdir -p data +echo "Hello FatFS" > data/test.txt + +# Build image +pio run -t buildfs +``` + +### Upload FatFS Image + +```bash +pio run -t uploadfs +``` + +### Download FatFS Image from Device + +```bash +pio run -t download_fatfs +``` + +Files will be extracted to the configured directory (default: `unpacked_fs`). + +## Technical Details + +### Python Dependencies + +The integration uses the `fatfs-ng` package, which is automatically installed. + +### Build Process + +1. A RAM disk is created with the configured FAT data size (partition size minus WL overhead) +2. The FatFS is formatted with proper parameters (2 FATs, LFN support) +3. All files from the `data/` directory are copied +4. The FAT image is wrapped with ESP32 Wear Leveling layer +5. The final image is saved as a `.bin` file + +**Important**: The build process automatically adds the ESP32 Wear Leveling layer, which is required by the Arduino FFat library. See [WEAR_LEVELING.md](WEAR_LEVELING.md) for details. + +### Wear Leveling Layer + +ESP32's FFat library requires a wear leveling layer around the FAT filesystem. The build process automatically: +- Reserves sectors for wear leveling metadata +- Wraps the FAT filesystem with WL_State structures +- Calculates proper CRC32 checksums + +### Download Process + +1. The partition table is downloaded from the device +2. The FAT partition is identified (Subtype 0x81) +3. The filesystem image is downloaded +4. The wear leveling layer is automatically detected and removed +5. The FAT data is mounted and extracted + +## Extended Features + +The `pyfatfs` package includes extended features for complete directory traversal: + +- **Complete Directory Traversal**: `walk()`, `listdir()`, `stat()` +- **Path Operations**: `exists()`, `isfile()`, `isdir()` +- **File Operations**: `remove()`, `rmdir()`, `rename()`, `makedirs()` +- **Convenience Methods**: `read_file()`, `write_file()` +- **Bulk Operations**: `copy_tree_from()`, `copy_tree_to()` + +These features enable full filesystem extraction and manipulation. + +## Comparison: LittleFS vs FatFS + +| Feature | LittleFS | FatFS | +|---------|----------|-------| +| Wear Leveling | Yes | Yes | +| Power-Loss Protection | Yes | Limited | +| Compatibility | ESP-IDF specific | Standard FAT | +| Sector Size | 4096 | 4096 | +| Filesystem Size | Flexible | Larger | + +## Example Code (Arduino) + +```cpp +#include + +void setup() { + Serial.begin(115200); + + // Mount FatFS + if (!FFat.begin(true)) { + Serial.println("FFat Mount Failed"); + return; + } + + // Read file + File file = FFat.open("/test.txt", "r"); + if (file) { + Serial.println(file.readString()); + file.close(); + } + + // Write file + file = FFat.open("/output.txt", "w"); + if (file) { + file.println("Hello from ESP32!"); + file.close(); + } +} + +void loop() { + // ... +} +``` + +## Troubleshooting + +### "No FAT filesystem partition found" + +- Check the partition table +- Ensure a partition with subtype `fat` (0x81) exists + +### Build Errors + +```bash +# Recreate Python environment +rm -rf ~/.platformio/penv +pio run +``` + +## Further Information + +- [FatFS Documentation](http://elm-chan.org/fsw/ff/00index_e.html) +- [ESP-IDF FFat Documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/fatfs.html) +- [fatfs-ng Repository](https://github.com/Jason2866/pyfatfs) +- [Original fatfs-python](https://github.com/krakonos/fatfs-python) diff --git a/README.md b/README.md index 655b19e..9ba475c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Espressif Systems is a privately held, fabless semiconductor company renowned fo * No support for the Arduino Nora Nano board, issues needs to be solved by the community ## IDE Preparation Prerequisites: -- Python (3.10, 3.11, 3.12, 3.13) and git is required for pioarduino to function properly. +- Python (3.10, 3.11, 3.12, 3.13, 3.14 not with Windows!) and git is required for pioarduino to function properly. ## Installation - [Download and install Microsoft Visual Studio Code](https://code.visualstudio.com/). pioarduino IDE is on top of it. @@ -57,7 +57,7 @@ pio run -t download_fatfs # Download and extract FatFS from device See the [arduino-fatfs example](examples/arduino-fatfs/) for a complete working example. ### Stable Arduino -currently espressif Arduino 3.3.6 and IDF 5.5.2+ +currently espressif Arduino 3.3.7 and IDF v5.5.2+ ```ini [env:stable] diff --git a/boards/esp32-c61-devkitc1.json b/boards/esp32-c61-devkitc1.json new file mode 100644 index 0000000..03ccd69 --- /dev/null +++ b/boards/esp32-c61-devkitc1.json @@ -0,0 +1,36 @@ +{ + "build": { + "core": "esp32", + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "mcu": "esp32c61", + "variant": "esp32c61" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32c61.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif ESP32-C61-DevKitC-1 (4 MB Flash)", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "espidf": { + "custom_sdkconfig": [ + "CONFIG_IDF_TARGET=\"esp32c61\"" + ] + }, + "url": "https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c61/esp32-c61-devkitc-1/user_guide.html", + "vendor": "Espressif" +} diff --git a/boards/esp32-p4_r3-evboard.json b/boards/esp32-p4_r3-evboard.json new file mode 100644 index 0000000..0f8f7e5 --- /dev/null +++ b/boards/esp32-p4_r3-evboard.json @@ -0,0 +1,41 @@ +{ + "build": { + "core": "esp32", + "extra_flags": [ + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "400000000L", + "f_flash": "80000000L", + "f_psram": "200000000L", + "flash_mode": "qio", + "mcu": "esp32p4", + "chip_variant": "esp32p4", + "variant": "esp32p4" + }, + "arduino": { + "partitions": "default_16MB.csv" + }, + "connectivity": [ + "bluetooth", + "openthread" + ], + "debug": { + "openocd_target": "esp32p4.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif ESP32-P4 Function EV Board v1.6 (rev.301)", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 512000, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 1500000 + }, + "url": "https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/index.html", + "vendor": "Espressif" +} diff --git a/boards/yb_esp32s3_amp.json b/boards/yb_esp32s3_amp.json new file mode 100644 index 0000000..2e938f0 --- /dev/null +++ b/boards/yb_esp32s3_amp.json @@ -0,0 +1,56 @@ +{ + "build": { + "arduino":{ + "partitions": "default_8MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_YB_ESP32S3_AMP", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ], + [ + "0x1A86", + "0x55D3" + ] + ], + "mcu": "esp32s3", + "variant": "yb_esp32s3_amp" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "YelloByte YB-ESP32-S3-AMP", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://github.com/yellobyte/YB-ESP32-S3-AMP", + "vendor": "YelloByte" +} diff --git a/boards/yb_esp32s3_dac.json b/boards/yb_esp32s3_dac.json new file mode 100644 index 0000000..1a7dadf --- /dev/null +++ b/boards/yb_esp32s3_dac.json @@ -0,0 +1,56 @@ +{ + "build": { + "arduino":{ + "partitions": "default_8MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_YB_ESP32S3_DAC", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ], + [ + "0x1A86", + "0x55D3" + ] + ], + "mcu": "esp32s3", + "variant": "yb_esp32s3_dac" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "YelloByte YB-ESP32-S3-DAC", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://github.com/yellobyte/YB-ESP32-S3-DAC", + "vendor": "YelloByte" +} diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index 1d781de..4bae4fb 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -2067,7 +2067,7 @@ def install_python_deps(): # https://github.com/platformio/platform-espressif32/issues/635 "cryptography": "~=44.0.0", "pyparsing": ">=3.1.0,<4", - "idf-component-manager": "~=2.4", + "idf-component-manager": "~=2.4.6", "esp-idf-kconfig": "~=2.5.0" } diff --git a/builder/penv_setup.py b/builder/penv_setup.py index 5c3c23b..9c6a97b 100644 --- a/builder/penv_setup.py +++ b/builder/penv_setup.py @@ -44,7 +44,7 @@ PLATFORMIO_URL_VERSION_RE = re.compile( # Python dependencies required for ESP32 platform builds python_deps = { - "platformio": "https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.18.zip", + "platformio": "https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.19.zip", "littlefs-python": ">=0.16.0", "fatfs-ng": ">=0.1.14", "pyyaml": ">=6.0.2", @@ -219,13 +219,14 @@ def get_packages_to_install(deps, installed_packages): yield package -def install_python_deps(python_exe, external_uv_executable): +def install_python_deps(python_exe, external_uv_executable, uv_cache_dir=None): """ Ensure uv package manager is available in penv and install required Python dependencies. Args: python_exe: Path to Python executable in the penv external_uv_executable: Path to external uv executable used to create the penv (can be None) + uv_cache_dir: Optional path to uv cache directory Returns: bool: True if successful, False otherwise @@ -233,6 +234,12 @@ def install_python_deps(python_exe, external_uv_executable): # Get the penv directory to locate uv within it penv_dir = os.path.dirname(os.path.dirname(python_exe)) penv_uv_executable = get_executable_path(penv_dir, "uv") + + # Build subprocess environment with UV_CACHE_DIR if specified + uv_env = None + if uv_cache_dir: + uv_env = dict(os.environ) + uv_env["UV_CACHE_DIR"] = str(uv_cache_dir) # Check if uv is available in the penv uv_in_penv_available = False @@ -250,28 +257,21 @@ def install_python_deps(python_exe, external_uv_executable): # Install uv into penv if not available if not uv_in_penv_available: if external_uv_executable: - # Use external uv to install uv into the penv + # Try external uv first to install uv into the penv try: subprocess.check_call( [external_uv_executable, "pip", "install", "uv>=0.1.0", f"--python={python_exe}", "--quiet"], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, - timeout=300 + timeout=300, + env=uv_env ) - except subprocess.CalledProcessError as e: - print(f"Error: uv installation failed with exit code {e.returncode}") - return False - except subprocess.TimeoutExpired: - print("Error: uv installation timed out") - return False - except FileNotFoundError: - print("Error: External uv executable not found") - return False - except Exception as e: - print(f"Error installing uv package manager into penv: {e}") - return False - else: - # No external uv available, use pip to install uv into penv + uv_in_penv_available = True + except Exception: + print("Warning: uv installation via external uv failed, falling back to pip") + + if not uv_in_penv_available: + # Fallback to pip to install uv into penv try: subprocess.check_call( [python_exe, "-m", "pip", "install", "uv>=0.1.0", "--quiet"], @@ -308,7 +308,8 @@ def install_python_deps(python_exe, external_uv_executable): capture_output=True, text=True, encoding='utf-8', - timeout=300 + timeout=300, + env=uv_env ) if result_obj.returncode == 0: @@ -356,7 +357,8 @@ def install_python_deps(python_exe, external_uv_executable): cmd, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, - timeout=300 + timeout=300, + env=uv_env ) except subprocess.CalledProcessError as e: @@ -375,7 +377,7 @@ def install_python_deps(python_exe, external_uv_executable): return True -def install_esptool(env, platform, python_exe, uv_executable): +def install_esptool(env, platform, python_exe, uv_executable, uv_cache_dir=None): """ Install esptool from package folder "tool-esptoolpy" using uv package manager. Ensures esptool is installed from the specific tool-esptoolpy package directory. @@ -385,6 +387,7 @@ def install_esptool(env, platform, python_exe, uv_executable): platform: PlatformIO platform object python_exe (str): Path to Python executable in virtual environment uv_executable (str): Path to uv executable + uv_cache_dir: Optional path to uv cache directory Raises: SystemExit: If esptool installation fails or package directory not found @@ -396,6 +399,12 @@ def install_esptool(env, platform, python_exe, uv_executable): ) sys.exit(1) + # Build subprocess environment with UV_CACHE_DIR if specified + uv_env = None + if uv_cache_dir: + uv_env = dict(os.environ) + uv_env["UV_CACHE_DIR"] = str(uv_cache_dir) + # Check if esptool is already installed from the correct path try: result = subprocess.run( @@ -427,7 +436,7 @@ def install_esptool(env, platform, python_exe, uv_executable): uv_executable, "pip", "install", "--quiet", "--force-reinstall", f"--python={python_exe}", "-e", esptool_repo_path - ], timeout=60) + ], timeout=60, env=uv_env) except subprocess.CalledProcessError as e: sys.stderr.write( @@ -468,6 +477,9 @@ def _setup_python_environment_core(env, platform, platformio_dir, should_install tuple[str, str]: (Path to penv Python executable, Path to esptool script) """ penv_dir = str(Path(platformio_dir) / "penv") + + # Determine uv cache directory inside .platformio/.cache + uv_cache_dir = str(Path(platformio_dir) / ".cache" / "uv") # Create virtual environment if not present if env is not None: @@ -498,7 +510,7 @@ def _setup_python_environment_core(env, platform, platformio_dir, should_install # Install required Python dependencies for ESP32 platform if has_internet_connection() or github_actions: - if not install_python_deps(penv_python, used_uv_executable): + if not install_python_deps(penv_python, used_uv_executable, uv_cache_dir): sys.stderr.write("Error: Failed to install Python dependencies into penv\n") sys.exit(1) else: @@ -508,10 +520,10 @@ def _setup_python_environment_core(env, platform, platformio_dir, should_install if should_install_esptool: if env is not None: # SCons version - install_esptool(env, platform, penv_python, uv_executable) + install_esptool(env, platform, penv_python, uv_executable, uv_cache_dir) else: # Minimal setup - install esptool from tool package - _install_esptool_from_tl_install(platform, penv_python, uv_executable) + _install_esptool_from_tl_install(platform, penv_python, uv_executable, uv_cache_dir) # Setup certifi environment variables _setup_certifi_env(env, penv_python) @@ -582,7 +594,7 @@ def _setup_pipenv_minimal(penv_dir): return None -def _install_esptool_from_tl_install(platform, python_exe, uv_executable): +def _install_esptool_from_tl_install(platform, python_exe, uv_executable, uv_cache_dir=None): """ Install esptool from tl-install provided path into penv. @@ -590,6 +602,7 @@ def _install_esptool_from_tl_install(platform, python_exe, uv_executable): platform: PlatformIO platform object python_exe (str): Path to Python executable in virtual environment uv_executable (str): Path to uv executable + uv_cache_dir: Optional path to uv cache directory Raises: SystemExit: If esptool installation fails or package directory not found @@ -599,6 +612,12 @@ def _install_esptool_from_tl_install(platform, python_exe, uv_executable): if not esptool_repo_path or not os.path.isdir(esptool_repo_path): return (None, None) + # Build subprocess environment with UV_CACHE_DIR if specified + uv_env = None + if uv_cache_dir: + uv_env = dict(os.environ) + uv_env["UV_CACHE_DIR"] = str(uv_cache_dir) + # Check if esptool is already installed from the correct path try: result = subprocess.run( @@ -630,7 +649,7 @@ def _install_esptool_from_tl_install(platform, python_exe, uv_executable): uv_executable, "pip", "install", "--quiet", "--force-reinstall", f"--python={python_exe}", "-e", esptool_repo_path - ], timeout=60) + ], timeout=60, env=uv_env) print(f"Installed esptool from tl-install path: {esptool_repo_path}") except subprocess.CalledProcessError as e: diff --git a/examples/espidf-blink/platformio.ini b/examples/espidf-blink/platformio.ini index 5682fd3..cac18e7 100644 --- a/examples/espidf-blink/platformio.ini +++ b/examples/espidf-blink/platformio.ini @@ -40,7 +40,7 @@ build_flags = [env:esp32-p4] platform = espressif32 framework = espidf -board = esp32-p4 +board = esp32-p4_r3 monitor_speed = 115200 build_flags = -D CONFIG_BLINK_GPIO=2 diff --git a/examples/espidf-ulp-lp/platformio.ini b/examples/espidf-ulp-lp/platformio.ini index 2dd34c5..780bdc5 100644 --- a/examples/espidf-ulp-lp/platformio.ini +++ b/examples/espidf-ulp-lp/platformio.ini @@ -15,4 +15,4 @@ board = esp32-c6-devkitc-1 [env:esp32-p4] platform = espressif32 framework = espidf -board = esp32-p4 +board = esp32-p4_r3 diff --git a/platform.json b/platform.json index 2429f77..e74e257 100644 --- a/platform.json +++ b/platform.json @@ -18,7 +18,7 @@ "type": "git", "url": "https://github.com/pioarduino/platform-espressif32.git" }, - "version": "55.03.36", + "version": "55.03.37", "frameworks": { "arduino": { "script": "builder/frameworks/arduino.py" @@ -33,31 +33,31 @@ "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/arduino-esp32/releases/download/3.3.6/esp32-core-3.3.6.tar.xz" + "version": "https://github.com/espressif/arduino-esp32/releases/download/3.3.7/esp32-core-3.3.7.tar.xz" }, "framework-arduinoespressif32-libs": { "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/espressif/arduino-esp32/releases/download/3.3.6/esp32-core-3.3.6-libs.tar.xz" + "version": "https://github.com/espressif/arduino-esp32/releases/download/3.3.7/esp32-core-3.3.7-libs.tar.xz" }, "framework-arduino-c2-skeleton-lib": { "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/pioarduino/platform-espressif32/releases/download/c2-skeleton/c2_366dadf354_compile_skeleton.zip" + "version": "https://github.com/pioarduino/platform-espressif32/releases/download/c2-skeleton/c2_87912cd291_compile_skeleton.zip" }, "framework-arduino-c61-skeleton-lib": { "type": "framework", "optional": true, "owner": "espressif", - "version": "https://github.com/pioarduino/platform-espressif32/releases/download/c61-skeleton/c61_366dadf354_compile_skeleton.zip" + "version": "https://github.com/pioarduino/platform-espressif32/releases/download/c61-skeleton/c61_87912cd291_compile_skeleton.zip" }, "framework-espidf": { "type": "framework", "optional": true, "owner": "pioarduino", - "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.5.2.260116/esp-idf-v5.5.2.tar.xz" + "version": "https://github.com/pioarduino/esp-idf/releases/download/v5.5.2.260206/esp-idf-v5.5.2.tar.xz" }, "toolchain-xtensa-esp-elf": { "type": "toolchain", @@ -98,8 +98,8 @@ "type": "uploader", "optional": true, "owner": "pioarduino", - "package-version": "5.1.0", - "version": "https://github.com/pioarduino/registry/releases/download/0.0.1/esptoolpy-v5.1.0.zip" + "package-version": "5.1.2", + "version": "https://github.com/pioarduino/registry/releases/download/0.0.1/esptoolpy-v5.1.2.zip" }, "tool-esp_install": { "type": "tool", diff --git a/platform.py b/platform.py index f018f5a..a6edd71 100644 --- a/platform.py +++ b/platform.py @@ -14,11 +14,19 @@ # Python Version Check import sys +from platformio.compat import IS_WINDOWS -if not ((3, 10) <= sys.version_info < (3, 14)): - print("ERROR: Python version must be between 3.10 and 3.13.", file=sys.stderr) - print(f"Current Python version: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}", file=sys.stderr) - print("Supported versions: 3.10, 3.11, 3.12, 3.13", file=sys.stderr) +pyver = sys.version_info +if IS_WINDOWS: + allowed = (3, 10) <= pyver < (3, 14) + supported = "3.10, 3.11, 3.12, 3.13" +else: + allowed = (3, 10) <= pyver < (3, 15) + supported = "3.10, 3.11, 3.12, 3.13, 3.14" +if not allowed: + print(f"ERROR: Python version must be {supported}.", file=sys.stderr) + print(f"Current Python version: {pyver.major}.{pyver.minor}.{pyver.micro}", file=sys.stderr) + print(f"Supported versions: {supported}", file=sys.stderr) raise SystemExit(1) # LZMA support check @@ -44,7 +52,6 @@ import subprocess from pathlib import Path from typing import Optional, Dict, List, Any, Union -from platformio.compat import IS_WINDOWS from platformio.public import PlatformBase, to_unix_path from platformio.proc import get_pythonexe_path from platformio.project.config import ProjectConfig