diff --git a/.gitignore b/.gitignore index ead248a..5363a54 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,194 @@ -# ---> esp-idf -# gitignore template for esp-idf, the official development framework for ESP32 -# https://github.com/espressif/esp-idf +Containerfile +models.json -build/ -sdkconfig -sdkconfig.old +# Created by https://www.toptal.com/developers/gitignore/api/windows,linux,macos,direnv,vim,clion+all,esp-idf +# Edit at https://www.toptal.com/developers/gitignore?templates=windows,linux,macos,direnv,vim,clion+all,esp-idf +### CLion+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### CLion+all Patch ### +# Ignore everything but code style settings and run configurations +# that are supposed to be shared within teams. + +.idea/* + +!.idea/codeStyles +!.idea/runConfigurations + +### direnv ### +.direnv +.envrc + +#!! ERROR: esp-idf is undefined. Use list command to see defined gitignore types !!# + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/windows,linux,macos,direnv,vim,clion+all,esp-idf diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..7dabf8a --- /dev/null +++ b/flake.nix @@ -0,0 +1,150 @@ +{ + description = "ESP32 development tools"; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; + flake-utils.url = "github:numtide/flake-utils"; + nixpkgs-esp-dev = { + #url = "github:mirrexagon/nixpkgs-esp-dev"; + url = "github:dvdvgt/nixpkgs-esp-dev/update-v6.0.1"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; + }; + }; + outputs = + { + self, + nixpkgs, + flake-utils, + nixpkgs-esp-dev, + }: + flake-utils.lib.eachDefaultSystem ( + system: + let + idfVersion = "v6.0.1"; + pkgs = import nixpkgs { + inherit system; + overlays = [ (import "${nixpkgs-esp-dev}/overlay.nix") ]; + config.permittedInsecurePackages = [ + "python3.13-ecdsa-0.19.1" + ]; + }; + autoSerialPort = pkgs.writeShellScriptBin "esp-port" '' + set -euo pipefail + + # Try common ESP USB serial patterns + # TODO: reduce to Waveshare ESP32-S3 detection + PORT=$( + for p in /dev/serial/by-id/*; do + case "$p" in + *CP210*|*ch340*|*USB*|*ESP*) echo "$p"; break ;; + esac + done + ) + + if [ -z "$PORT" ]; then + echo "No ESP serial device found in /dev/serial/by-id" + echo "Fallback: listing /dev/ttyUSB* /dev/ttyACM*" + ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null || true + exit 1 + fi + + echo "$PORT" + ''; + esp-idf = pkgs.esp-idf-full.override { + rev = idfVersion; + sha256 = "sha256-4KJa686qc+u7XkF/GS2o53l1SpwP2EmdqAn/qmlL1yU="; + }; + in + { + apps = { + run-agent = { + type = "app"; + program = "${pkgs.writeShellScript "run-agent" '' + podman run -it --rm -v ./:/src -v ./models.json:/root/.pi/agent/models.json --device=/dev/ttyACM0 pidev:latest + ''}"; + }; + build-agent = { + type = "app"; + program = "${pkgs.writeShellScript "build-agent" '' + podman build -t pidev:latest -f Containerfile . + ''}"; + }; + menuconfig = { + type = "app"; + meta.description = "โš™๏ธ Open ESP-IDF configuration menu (sdkconfig)"; + program = "${pkgs.writeShellScriptBin "idf-menuconfig" '' + ${esp-idf}/tools/idf.py menuconfig + ''}/bin/idf-menuconfig"; + }; + build = { + type = "app"; + meta.description = "๐Ÿงฑ Build ESP32 firmware using ESP-IDF ${idfVersion}"; + program = "${pkgs.writeShellScriptBin "idf-build" '' + ${esp-idf}/tools/idf.py build + ''}/bin/idf-build"; + }; + flash = { + type = "app"; + meta.description = "โšก Flash firmware to ESP32-S3 over auto-detected serial port"; + program = "${pkgs.writeShellScriptBin "idf-flash" '' + set -euo pipefail + + PORT=$(${autoSerialPort}/bin/esp-port) + echo "Flashing on: $PORT" + + ${esp-idf}/tools/idf.py -p "$PORT" flash + ''}/bin/idf-flash"; + }; + monitor = { + type = "app"; + meta.description = "๐Ÿ“ก Open serial monitor for ESP32 logs"; + program = "${pkgs.writeShellScriptBin "idf-monitor" '' + set -euo pipefail + + PORT=$(${autoSerialPort}/bin/esp-port) + echo "Monitoring: $PORT" + + ${esp-idf}/tools/idf.py -p "$PORT" monitor + ''}/bin/idf-monitor"; + }; + clean = { + type = "app"; + meta.description = "๐Ÿงน Clean ESP-IDF build directory"; + program = "${pkgs.writeShellScriptBin "idf-clean" '' + ${esp-idf}/tools/idf.py clean + ''}/bin/idf-clean"; + }; + full = { + type = "app"; + meta.description = "๐Ÿš€ Full pipeline: build โ†’ flash โ†’ monitor"; + program = "${pkgs.writeShellScriptBin "idf-full" '' + set -euo pipefail + + PORT=$(${autoSerialPort}/bin/esp-port) + + echo "๐Ÿงฑ Building..." + ${esp-idf}/tools/idf.py build + echo "โšก Flashing on $PORT..." + ${esp-idf}/tools/idf.py -p "$PORT" flash + echo "๐Ÿ“ก Starting monitor..." + ${esp-idf}/tools/idf.py -p "$PORT" monitor + ''}/bin/idf-full"; + }; + }; + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ + esp-idf + git + minicom + usbutils + gawk + coreutils + cmake + ninja + ]; + }; + } + ); +}