Added the zig_main project to software for zig based implementation of code for robot

This commit is contained in:
2026-05-05 20:14:04 +12:00
parent 7d752f2534
commit f21f909a71
83 changed files with 13631 additions and 0 deletions

View File

@@ -0,0 +1,820 @@
# Getting Started with Zig ESP-IDF Sample
A complete guide to building ESP32 firmware using Zig and ESP-IDF.
## Table of Contents
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Project Structure](#project-structure)
- [Building Your First Project](#building-your-first-project)
- [Working with Components](#working-with-components)
- [Examples](#examples)
- [Troubleshooting](#troubleshooting)
- [Next Steps](#next-steps)
---
## Prerequisites
### Required Software
- **Python 3.12+** (for ESP-IDF tools)
- **Git** (for cloning repositories)
- **CMake 3.16+** (bundled with ESP-IDF)
- **Ninja** or **Make** (bundled with ESP-IDF)
- **Zig compiler** (optional - will be auto-downloaded if not found)
### Supported Operating Systems
- **Linux** (Ubuntu 20.04+, Debian, Fedora, Arch)
- **macOS** (10.15+)
- **Windows** (10/11 with PowerShell or WSL2)
- **Nix/NixOS** (via `flake.nix`)
### Supported ESP32 Targets
| Architecture | Targets |
|--------------|---------|
| **RISC-V** | ESP32-C2, C3, C5, C6, C61, H2, H21, H4, P4 |
| **Xtensa** | ESP32, ESP32-S2, ESP32-S3 |
---
## Installation
### Step 1: Install ESP-IDF
**Option A: Standard Installation**
```bash
# Clone ESP-IDF
git clone --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
# Linux/macOS:
./install.sh
# Windows (PowerShell):
.\install.ps1
# Windows (Command Prompt):
install.bat
```
**Option B: Using Nix Flakes** (Linux/macOS)
```bash
# Enter development environment with all dependencies
nix develop
# Or use direnv for automatic activation
echo "use flake" > .envrc
direnv allow
```
**Option C: ESP-IDF installer** (Windows/macOS)
Download from: https://dl.espressif.com/dl/esp-idf/
### Step 2: Set up ESP-IDF Environment
Every time you open a new terminal, activate ESP-IDF:
```bash
# Linux/macOS:
. $HOME/esp/esp-idf/export.sh
# Windows (PowerShell):
. $HOME/esp/esp-idf/export.ps1
# Windows (Command Prompt):
%USERPROFILE%\esp\esp-idf\export.bat
```
### Step 3: Clone This Project
```bash
git clone https://github.com/kassane/zig-esp-idf-sample.git
cd zig-esp-idf-sample
```
### Step 4: Verify Installation
```bash
idf.py --version
# Expected output: ESP-IDF v5.x.x or v6.x.x
```
---
## Quick Start
### 1. Set Your Target Device
```bash
# For ESP32-C6 (RISC-V)
idf.py set-target esp32c6
# For ESP32-S3 (Xtensa)
idf.py set-target esp32s3
# For ESP32 (original, Xtensa)
idf.py set-target esp32
```
### 2. Build the Project
```bash
idf.py build
```
**What happens during build:**
- ✅ CMake detects your target and configures the build
- ✅ Zig toolchain is automatically downloaded (if needed)
- ✅ C bindings are generated from ESP-IDF headers
- ✅ Target-specific patches are applied
- ✅ Zig code is compiled to object files
- ✅ Everything is linked with ESP-IDF libraries
- ✅ Firmware binaries are generated
### 3. Flash to Device
```bash
# Connect your ESP32 via USB, then:
idf.py -p PORT flash
# Find your port:
# Linux: /dev/ttyUSB0 or /dev/ttyACM0
# macOS: /dev/cu.usbserial-*
# Windows: COM3, COM4, etc.
# Example:
idf.py -p /dev/ttyUSB0 flash
```
### 4. Monitor Output
```bash
idf.py -p PORT monitor
# Or combine flash + monitor:
idf.py -p PORT flash monitor
# Exit monitor: Ctrl+]
```
---
## Project Structure
```
zig-esp-idf-sample/
├── build.zig # Zig build script (compiles Zig code)
├── build.zig.zon # Zig package manifest
├── CMakeLists.txt # Root CMake config
├── sdkconfig # ESP-IDF configuration (generated)
├── sdkconfig.defaults # Default SDK config
├── sdkconfig.defaults.esp32 # ESP32-specific defaults
├── partitions_matter.csv # Custom partition table for Matter (3 MB app, 4 MB flash)
├── dependencies.lock # Component version lock
├── wokwi.toml # Wokwi simulator config
├── main/
│ ├── CMakeLists.txt # Main component config
│ ├── placeholder.c # Minimal C entry point (required by CMake)
│ ├── matter_wrappers.cpp # C++ shims for esp_matter C++ API (activated when component present)
│ ├── app.zig # Main Zig application entry
│ ├── idf_component.yml # Component dependencies
│ ├── Kconfig.projbuild # Project configuration options
│ └── examples/
│ ├── gpio-blink.zig # Toggle LED on GPIO2
│ ├── uart-echo.zig # UART echo
│ ├── i2c-scan.zig # I2C bus scan
│ ├── wifi-station.zig # WiFi station
│ ├── http-server.zig # HTTP server
│ ├── ble-gatt-server.zig # BLE GATT server
│ ├── smartled-rgb.zig # WS2812B LED strip
│ ├── dsp-math.zig # DSP/FFT operations
│ └── matter-light.zig # Matter On/Off Light
├── imports/ # Zig API wrappers and bindings
│ ├── idf.zig # Main ESP-IDF facade module
│ ├── idf-sys.zig # Generated C bindings (auto-generated)
│ ├── sys.zig # Re-exports idf-sys
│ ├── error.zig # esp_err_t → Zig error mapping
│ ├── logger.zig # std.log integration (espLogFn)
│ ├── version.zig # ESP-IDF version info (ver)
│ ├── heap.zig # HeapCapsAllocator, MultiHeapAllocator
│ ├── bootloader.zig # Partition/bootloader control
│ ├── gpio.zig # GPIO wrapper
│ ├── wifi.zig # WiFi station/AP/scan
│ ├── uart.zig # UART driver
│ ├── i2c.zig # I2C master
│ ├── spi.zig # SPI master (+ SDSPI)
│ ├── i2s.zig # I2S audio (STD, PDM, TDM)
│ ├── http.zig # HTTP server + client
│ ├── mqtt.zig # MQTT client
│ ├── lwip.zig # lwIP sockets, DNS, SNTP
│ ├── crc.zig # ESP-ROM CRC-8/16/32
│ ├── bluetooth.zig # Bluedroid BLE
│ ├── nimble.zig # NimBLE BLE (compile-time guarded)
│ ├── now.zig # ESP-NOW protocol
│ ├── nvs.zig # NVS flash key-value storage
│ ├── partition.zig # Partition table operations
│ ├── sleep.zig # Deep/light sleep + wakeup
│ ├── event.zig # ESP event loop
│ ├── wdt.zig # Task watchdog timer
│ ├── rtos.zig # FreeRTOS tasks/queues/semaphores/timers
│ ├── pcnt.zig # Pulse counter (pulse)
│ ├── phy.zig # Wireless PHY / RF calibration
│ ├── segger.zig # Segger SystemView profiling
│ ├── led-strip.zig # LED strip — requires espressif/led_strip
│ ├── dsp.zig # DSP/FFT — requires espressif/esp-dsp
│ ├── hosted.zig # ESP-Hosted coexistence — requires espressif/esp_hosted
│ ├── wifi_remote.zig # WiFi remote — requires espressif/esp_wifi_remote
│ ├── timer.zig # High-resolution esp_timer (one-shot + periodic)
│ ├── ledc.zig # LED PWM controller (duty, fade)
│ ├── twai.zig # TWAI/CAN bus driver
│ ├── pm.zig # Power management locks
│ ├── pthread.zig # POSIX threads (FreeRTOS-backed)
│ └── panic.zig # Zig panic handler
├── include/ # C headers for binding generation
│ ├── stubs.h # Core ESP-IDF headers (input to zig translate-c)
│ ├── wifi_stubs.h # WiFi macro wrappers
│ ├── bt_stubs.h # Bluetooth macro wrappers
│ ├── matter_stubs.h # C wrapper interface for esp_matter (C++ component)
│ ├── matter_closure_patch.h # GCC 14 C++23 fix for closure-control cluster
│ └── bindings.h # Additional bindings
├── cmake/ # CMake build system scripts
│ ├── zig-config.cmake # Main Zig configuration
│ ├── zig-download.cmake # Auto-download Zig toolchain
│ ├── zig-runner.cmake # Helper functions for Zig
│ ├── bindings.cmake # Binding generation
│ ├── extra-components.cmake # Managed component detection
│ └── patch.cmake # Post-processing patches
├── patches/ # Binding fixes for translate-c issues
│ ├── *.zig
├── docs/ # Documentation
│ ├── build-internals.md # Build system details
│ ├── build-scheme.png # Build flow diagram
│ └── zig-xtensa.md # Xtensa toolchain info
└── flake.nix # Nix development environment
```
---
## Building Your First Project
### Example 1: Hello World
```zig
const std = @import("std");
const idf = @import("esp_idf");
comptime {
@export(&main, .{ .name = "app_main" });
}
fn main() callconv(.c) void {
log.info("Hello from Zig on ESP32!", .{});
log.info("Zig version: {s}", .{@import("builtin").zig_version_string});
// Show memory info
var heap = idf.heap.HeapCapsAllocator.init(null); // default: MALLOC_CAP_DEFAULT
log.info("Free heap: {} bytes", .{heap.freeSize()});
// Sleep forever
while (true) {
idf.rtos.Task.delayMs(1000);
}
}
// overwrite zig std_options config
pub const std_options: std.Options = .{
.logFn = idf.log.espLogFn,
};
// rename log instance
const log = std.log.scoped(.@"esp-idf");
// overwrite std panic-handler
pub const panic = idf.esp_panic.panic;
```
**Build and run:**
```bash
idf.py build flash monitor
```
### Example 2: Blinking LED
**Create `main/examples/blink.zig`:**
```zig
const std = @import("std");
const idf = @import("esp_idf");
const LED_PIN = .@"18"; // Change to your LED pin
comptime {
@export(&main, .{ .name = "app_main" });
}
fn main() callconv(.c) void {
// Configure GPIO as output
idf.gpio.Direction.set(LED_PIN, .output) catch {
log.err("Failed to configure GPIO", .{});
return;
};
log.info("Blinking LED on GPIO {d}", .{LED_PIN});
while (true) {
// LED ON
idf.gpio.Level.set(LED_PIN, 1) catch {};
log.info("LED ON", .{});
idf.rtos.Task.delayMs(1000);
// LED OFF
idf.gpio.Level.set(LED_PIN, 0) catch {};
log.info("LED OFF", .{});
idf.rtos.Task.delayMs(1000);
}
}
// overwrite zig std_options config
pub const std_options: std.Options = .{
.logFn = idf.log.espLogFn,
};
// rename log instance
const log = std.log.scoped(.blink);
// overwrite std panic-handler
pub const panic = idf.esp_panic.panic;
```
---
## Working with Components
### Adding Managed Components
Components are specified in `main/idf_component.yml`:
**Add a component:**
```bash
# Use idf.py command:
idf.py add-dependency espressif/led_strip
# then
idf.py reconfigure
```
### Using LED Strip Component
**The build system automatically:**
1. ✅ Detects components in `dependencies.lock`
2. ✅ Adds include paths to binding generation
3. ✅ Generates `HAS_*` defines (e.g., `HAS_LED_STRIP=1`)
4. ✅ Includes headers in `include/stubs.h` conditionally
5. ✅ Makes APIs available in Zig via `idf.*` modules
**1. Ensure LED strip is in `main/idf_component.yml`:**
```yaml
dependencies:
espressif/led_strip: "*"
```
**2. Reconfigure:**
```bash
idf.py reconfigure
```
**3. Check provided example:**
The example in [examples/smartled-rgb.zig](../main/examples/smartled-rgb.zig) demonstrates:
- Configuring WS2812B LED strip on GPIO 2
- Setting individual pixel colors
- Refreshing the display
- Blinking pattern
### DSP basics (FFT + math)
[examples/dsp-math.zig](../main/examples/dsp-math.zig)
- Generates a sine tone (freq = 0.2 normalized)
- Applies Hann window
- Does FFT (1024 points, float32, radix-2)
- Computes power spectrum in dB
- Prints ASCII plot of the spectrum (64×10 chars, -120 to +40 dB)
### Using WiFi
**Use the WiFi station example:**
[examples/wifi-station.zig](../main/examples/wifi-station.zig)
**Configure WiFi credentials:**
```bash
idf.py menuconfig
# Navigate to: Example Configuration
# Set WiFi SSID and Password
```
Or edit [main/Kconfig.projbuild](../main/Kconfig.projbuild) to change default values.
### Available Wrapper APIs
The project provides comprehensive Zig wrappers in `imports/`:
| Module | Description | Notes |
|--------|-------------|-------|
| `idf.gpio` | GPIO control | Any target |
| `idf.wifi` | WiFi station/AP/scan | Not on H2/H4/P4 |
| `idf.bt` | Bluedroid BLE | Requires `CONFIG_BT_ENABLED` |
| `idf.nimble` | NimBLE BLE | Requires `CONFIG_BT_NIMBLE_ENABLED` |
| `idf.heap` | HeapCapsAllocator, MultiHeapAllocator | Any target |
| `idf.rtos` | FreeRTOS tasks/queues/semaphores/timers | Any target |
| `idf.nvs` | NVS flash key-value storage | Any target |
| `idf.partition` | Partition table operations | Any target |
| `idf.sleep` | Deep/light sleep + wakeup sources | Any target |
| `idf.event` | ESP event loop | Any target |
| `idf.wdt` | Task watchdog timer | Any target |
| `idf.bl` | Bootloader/partition control | Any target |
| `idf.i2c` | I2C master | Any target |
| `idf.spi` | SPI master + SDSPI | Any target |
| `idf.uart` | UART driver | Any target |
| `idf.i2s` | I2S audio (STD, PDM, TDM) | Any target |
| `idf.http` | HTTP server (httpd) + client | Any target |
| `idf.mqtt` | MQTT client | Any target |
| `idf.lwip` | lwIP sockets, DNS, SNTP | Any target |
| `idf.crc` | ESP-ROM CRC-8/16/32 | Any target |
| `idf.esp_now` | ESP-NOW protocol | Any target |
| `idf.pulse` | Pulse counter (PCNT) | Any target |
| `idf.phy` | Wireless PHY / RF calibration | Any target |
| `idf.segger` | Segger SystemView profiling | Any target |
| `idf.ver` | ESP-IDF version info | Any target |
| `idf.led` | LED strip WS2812B | Requires `espressif/led_strip` |
| `idf.dsp` | DSP/FFT operations | Requires `espressif/esp-dsp` |
| `idf.esp_hosted` | ESP-Hosted coexistence | Requires `espressif/esp_hosted` |
| `idf.wifi_remote` | WiFi via slave MCU | Requires `espressif/esp_wifi_remote` |
| `idf.timer` | High-resolution esp_timer | Any target |
| `idf.ledc` | LED PWM controller | Any target |
| `idf.twai` | TWAI/CAN bus driver | Any target |
| `idf.pm` | Power management locks | Any target |
| `idf.pthread` | POSIX threads (FreeRTOS-backed) | Any target |
| `idf.matter` | Matter/CHIP protocol | Requires `espressif/esp_matter` |
| `idf.log` | std.log integration (`espLogFn`) | Any target |
| `idf.err` | esp_err_t → Zig error mapping | Any target |
| `idf.sys` | Raw C bindings | Direct ESP-IDF API access |
---
## Examples
### FreeRTOS Tasks
```zig
const idf = @import("esp_idf");
const std = @import("std");
// overwrite std panic-handler
pub const panic = idf.esp_panic.panic;
// overwrite std.log
pub const std_options: std.Options = .{
.logFn = idf.log.espLogFn,
};
export fn myTask(_: ?*anyopaque) callconv(.c) void {
const log = std.log.scoped(.task);
while (true) {
log.info("Task running!", .{});
idf.rtos.Task.delayMs(1000);
}
}
export fn app_main() callconv(.c) void {
_ = idf.rtos.Task.create(myTask, "my_task", 2048, null, 5) catch @panic("Failed to create task");
// Main task continues...
while (true) {
idf.rtos.Task.delayMs(1000);
}
}
```
### Using Custom Allocators
```zig
const idf = @import("esp_idf");
const std = @import("std");
export fn app_main() callconv(.c) void {
var arena = std.heap.ArenaAllocator.init(std.heap.c_allocator);
defer arena.deinit();
const allocator = arena.allocator();
var list: std.ArrayList(u32) = .empty;
defer list.deinit(allocator);
list.append(allocator, 10) catch {};
list.append(allocator, 20) catch {};
list.append(allocator, 30) catch {};
// ...
}
```
### Accessing Raw C APIs
When wrappers aren't available, use raw bindings:
```zig
const idf = @import("esp_idf");
const std = @import("std");
const sys = idf.sys;
const log = std.log.scoped(.@"esp-idf");
export fn app_main() callconv(.c) void {
var mac_addr: [6]u8 = undefined;
// Direct ESP-IDF C API call
const result = sys.esp_efuse_mac_get_default(&mac_addr);
if (result != sys.ESP_OK) {
std.log.err("Failed to get MAC address", .{});
return;
}
log.info("MAC: {X:0>2}:{X:0>2}:{X:0>2}:{X:0>2}:{X:0>2}:{X:0>2}", .{
mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5],
});
}
pub const std_options: std.Options = .{
.logFn = idf.log.espLogFn,
};
```
---
## Troubleshooting
### Build Errors
**"zig: command not found"**
- The Zig toolchain should auto-download. Check `build/zig-relsafe-*` directory
- Or install manually: https://ziglang.org/download/
- For Nix users: `nix develop`
**"Component not found: espressif__led_strip"**
```bash
# Check idf_component.yml
cat main/idf_component.yml
# Reconfigure to download components
idf.py reconfigure
```
**"translate-c failed"**
- Check `include/stubs.h` and `include/wifi_stubs.h` for syntax errors
- Ensure managed components exist in `managed_components/`
- Check that `HAS_*` defines match components in `cmake/extra-components.cmake`
**Binding generation errors**
- The `patches/` directory contains fixes for common `translate-c` issues
- If you see struct layout errors, a patch likely needs updating
- Check `cmake/patch.cmake` for how patches are applied
### Flash Errors
**"Serial port not found"**
```bash
# Linux: Add user to dialout group
sudo usermod -a -G dialout $USER
# Log out and back in
# Check available ports
ls /dev/tty*
# Windows: Check Device Manager for COM port
```
**"Failed to connect to ESP32"**
- Hold BOOT button while connecting
- Try different USB cable/port (must be data cable, not power-only)
- Verify target matches your device: `idf.py set-target esp32c6`
- Check USB drivers are installed (CP210x or CH340)
### Runtime Errors
**"Guru Meditation Error: Core panic"**
- Check stack size (increase in `xTaskCreate`, default 2048 often too small)
- Verify GPIO pins match your hardware
- Enable debug build: `idf.py menuconfig` → Compiler options → Debug (-Og)
- Check `sdkconfig` for panic handler settings
**"Out of memory" / Heap errors**
- Use arena allocators: `std.heap.ArenaAllocator`
- Check available heap: `heap.freeSize()`
- Reduce allocations in hot paths
- Consider enabling PSRAM if available
- Check `idf.py size-components` for memory usage
**WiFi not connecting**
- Verify SSID and password in menuconfig
- Check WiFi country code matches your region
- Ensure 2.4GHz WiFi (5GHz not supported)
- Check WiFi credentials don't contain special characters
**Matter example: "app partition is too small"**
The Matter binary is ~2.2 MB and requires a 4 MB flash chip and custom partition table:
```bash
# Ensure sdkconfig has 4 MB flash and custom partition:
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# CONFIG_PARTITION_TABLE_CUSTOM=y
# CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_matter.csv"
# If sdkconfig doesn't reflect sdkconfig.defaults changes, update it:
idf.py reconfigure
idf.py build -DCONFIG_ZIG_EXAMPLE_MATTER_LIGHT=y
```
**Matter example: IDF version incompatibility**
- `espressif/esp_matter` 1.4.x requires IDF **v5.x** (tested with v5.5)
- Not compatible with IDF v6.x (depends on `json`/`mqtt` components removed in v6)
- Check your IDF version: `idf.py --version`
---
## Next Steps
### Learn More
- **Zig Language:** https://ziglang.org/documentation/master/
- **ESP-IDF Docs:** https://docs.espressif.com/projects/esp-idf/
- **Project Wiki:**
- [Build Internals](./build-internals.md)
- [Xtensa Toolchain](./zig-xtensa.md)
### Explore Examples
All examples are in `main/examples/`:
- `gpio-blink.zig` - Toggle an LED on GPIO2 (any target)
- `uart-echo.zig` - Read UART1 and echo back
- `i2c-scan.zig` - Scan I2C bus for devices
- `wifi-station.zig` - Connect to a WiFi AP
- `http-server.zig` - Serve a web page over WiFi
- `ble-gatt-server.zig` - BLE peripheral with GATT notifications (requires `CONFIG_BT_ENABLED`)
- `smartled-rgb.zig` - WS2812B LED strip control (requires `espressif/led_strip`)
- `dsp-math.zig` - FFT + power spectrum via DSP (requires `espressif/esp-dsp`)
- `matter-light.zig` - Matter On/Off Light device (requires `espressif/esp_matter`, IDF v5.x, 4 MB flash)
### Configuration
```bash
# Interactive configuration menu
idf.py menuconfig
# Key settings to explore:
# - Component config → FreeRTOS → Tick rate (Hz)
# - Component config → ESP System Settings → Panic handler behavior
# - Partition Table → Choose partition scheme
# - Example Configuration → WiFi credentials
# - Compiler options → Optimization level
```
### Testing with Wokwi Simulator
The project includes `wokwi.toml` for simulation:
1. Install Wokwi CLI: https://docs.wokwi.com/wokwi-ci/idf-wokwi-usage
2. Edit `wokwi.toml` to match your project
3. Run: `idf.py wokwi --timeout 30000`
or use VSCode Extension
* More info: https://docs.wokwi.com/vscode/getting-started
### Advanced Topics
- **Custom Components:** Create reusable Zig modules in `imports/`
- **WiFi & Networking:** HTTP servers, WebSockets, mDNS
- **OTA Updates:** Over-the-air firmware updates
- **Bluetooth:** BLE advertising, GATT services
- **Deep Sleep:** Ultra-low power modes
- **File Systems:** SPIFFS, FAT, LittleFS
- **Cryptography:** Hardware-accelerated crypto
### Development Tips
**Use `sdkconfig.defaults` for version control:**
- Base config: `sdkconfig.defaults`
- Target-specific: `sdkconfig.defaults.esp32`
- Don't commit `sdkconfig` (it's generated)
**Debugging:**
```bash
# Monitor with timestamps
idf.py monitor --timestamps
# Filter logs by tag
idf.py monitor --print-filter "tag:app"
# Save logs to file
idf.py monitor | tee output.log
```
**Clean builds when needed:**
```bash
# Clean Zig cache
rm -rf .zig-cache
# Full CMake clean
idf.py fullclean
# Regenerate bindings
idf.py reconfigure
```
### Contributing
Found a bug or want to contribute?
- **GitHub:** https://github.com/kassane/zig-esp-idf-sample
- **Issues:** https://github.com/kassane/zig-esp-idf-sample/issues
- **Pull Requests:** See [CONTRIBUTING.md](../CONTRIBUTING.md)
---
## Quick Reference
### Common Commands
```bash
# Setup
idf.py set-target esp32c6 # Set target device
idf.py reconfigure # Regenerate build config / update deps
# Build
idf.py build # Build project
idf.py clean # Clean build files
idf.py fullclean # Full clean (including config)
# Flash
idf.py -p PORT flash # Flash firmware
idf.py -p PORT monitor # Monitor serial output
idf.py -p PORT flash monitor # Flash and monitor
idf.py -p PORT app-flash # Flash app only (faster)
# Config
idf.py menuconfig # Interactive configuration
idf.py size # Show binary sizes
idf.py size-components # Component size breakdown
# Dependencies
idf.py add-dependency PKG # Add managed component
# Help
idf.py --help # Show all commands
idf.py --list-targets # List supported targets
```
### File Locations
- **Main app:** `main/app.zig`
- **Examples:** `main/examples/*.zig`
- **Dependencies:** `main/idf_component.yml`
- **Configuration:** `sdkconfig`, `sdkconfig.defaults*`
- **Bindings:** `imports/idf-sys.zig` (auto-generated)
- **Wrappers:** `imports/*.zig`
- **Build scripts:** `cmake/*.cmake`
### Pin Configuration
Check your board's pinout:
- **GPIO Pins:** Varies by model (ESP32: 0-39, ESP32-C6: 0-30)
- **Built-in LED:** Often GPIO 2, 8, or 18
- **UART:** Usually GPIO 1 (TX), GPIO 3 (RX)
- **I2C:** SDA/SCL pins vary by board
- **SPI:** MOSI/MISO/CLK pins vary by board
### Hardware Requirements
- **ESP32 Development Board** (any supported variant)
- **USB Cable** (must be data cable, not power-only)
- **LEDs/Components** (optional, for examples)
- **LED Strip WS2812B** (optional, for smartled-rgb example)
---
## Support
- **Documentation:** [docs/](.)
- **Issues:** https://github.com/kassane/zig-esp-idf-sample/issues
- **Discussions:** https://github.com/kassane/zig-esp-idf-sample/discussions