diff --git a/zephcore/CMakeLists.txt b/zephcore/CMakeLists.txt index e7caac1..ee1d2e1 100644 --- a/zephcore/CMakeLists.txt +++ b/zephcore/CMakeLists.txt @@ -231,7 +231,7 @@ if(BOARD MATCHES ".*nrf52.*" OR BOARD MATCHES "rak4631" OR BOARD MATCHES "rak_wi set(ZEPHCORE_PLATFORM_CONF "${CMAKE_CURRENT_SOURCE_DIR}/boards/common/nrf52_common.conf") elseif(DEFINED BOARD_QUALIFIERS AND BOARD_QUALIFIERS MATCHES ".*nrf52.*") set(ZEPHCORE_PLATFORM_CONF "${CMAKE_CURRENT_SOURCE_DIR}/boards/common/nrf52_common.conf") -elseif(BOARD MATCHES ".*esp32.*" OR BOARD MATCHES "station_g2" OR BOARD MATCHES "lilygo_tlora_c6") +elseif(BOARD MATCHES ".*esp32.*" OR BOARD MATCHES "station_g2" OR BOARD MATCHES "lilygo_tlora_c6" OR BOARD MATCHES "heltec_wifi_lora32_v3") set(ZEPHCORE_PLATFORM_CONF "${CMAKE_CURRENT_SOURCE_DIR}/boards/common/esp32_common.conf") elseif(DEFINED BOARD_QUALIFIERS AND BOARD_QUALIFIERS MATCHES ".*esp32.*") set(ZEPHCORE_PLATFORM_CONF "${CMAKE_CURRENT_SOURCE_DIR}/boards/common/esp32_common.conf") diff --git a/zephcore/boards/esp32/heltec_wifi_lora32_v3/board.conf b/zephcore/boards/esp32/heltec_wifi_lora32_v3/board.conf new file mode 100644 index 0000000..1b1eca6 --- /dev/null +++ b/zephcore/boards/esp32/heltec_wifi_lora32_v3/board.conf @@ -0,0 +1,16 @@ +# Heltec WiFi LoRa 32 V3 — ESP32-S3 + SX1262 +# +# Hardware: +# ESP32-S3 (8MB flash, no PSRAM) +# SX1262 on SPI2 (direct output, no PA) +# SSD1306 128x64 OLED on I2C0 +# User button on GPIO0 +# +# Include order: prj.conf → zephcore_common.conf → esp32_common.conf → board.conf + +# Board identification +CONFIG_ZEPHCORE_BOARD_NAME="Heltec V3" +CONFIG_BT_DIS_MODEL_NUMBER_STR="Heltec WiFi LoRa 32 V3" + +# Flash size — 8MB (override esp32_common.conf 4MB default) +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y diff --git a/zephcore/boards/esp32/heltec_wifi_lora32_v3/board.overlay b/zephcore/boards/esp32/heltec_wifi_lora32_v3/board.overlay new file mode 100644 index 0000000..802670c --- /dev/null +++ b/zephcore/boards/esp32/heltec_wifi_lora32_v3/board.overlay @@ -0,0 +1,126 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Heltec WiFi LoRa 32 V3 — ZephCore overlay + * + * The upstream Zephyr DTS already defines SX1262, SSD1306 OLED, button, + * LED, battery ADC, Vext/ADC control, I2C0, SPI2, BLE, and WiFi. + * This overlay adds ZephCore-specific integration on top. + * + * LoRa SPI2 pins: SCLK=9, MOSI=10, MISO=11, NSS=8 + * LoRa control: DIO1=14, BUSY=13, RESET=12 + * Display I2C0: SDA=17, SCL=18 (SSD1306 @ 0x3C) + * Battery ADC: GPIO1 (ADC1 ch0), enable GPIO37, divider 100K/390K + * Vext: GPIO36 (active-LOW, powers OLED) + * Button: GPIO0 + * LED: GPIO35 + */ + +#include + +/ { + chosen { + /* Override upstream UART0 console → USB serial for ZephCore */ + zephyr,console = &usb_serial; + zephyr,shell-uart = &usb_serial; + }; + + /* Add label to upstream buttons node (defined without one) */ + buttons: buttons { + }; + + /* Battery ADC — ZephCore reads via zephyr,user { io-channels } + * Upstream vbatt node uses voltage-divider compatible which ZephCore + * doesn't use. Multiplier: 3300mV full-scale * 5.42x = 17886. + * (5.42x is Arduino's empirical divider factor for V3/V4.) */ + zephyr,user { + io-channels = <&adc1 0>; + vbat-mv-multiplier = <17886>; + }; + + /* Battery ADC enable — GPIO37 (gpio1 pin 5) must be driven to read. + * Upstream has adc_ctrl power-domain-gpio; ZephCore expects a + * regulator-fixed named vbat_enable. */ + vbat_enable: vbat-enable { + compatible = "regulator-fixed"; + regulator-name = "vbat-enable"; + enable-gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; + }; + + /* ---- Button input filter chain ---- + * Upstream button emits INPUT_KEY_0. Split into: + * short press → KEY_A (consumed by multi-tap) + * long press (1s) → KEY_POWER (deep sleep) */ + user_btn_longpress { + compatible = "zephyr,input-longpress"; + input = <&buttons>; + input-codes = ; + short-codes = ; + long-codes = ; + long-delay-ms = <1000>; + }; + + /* Multi-tap decodes short presses: + * 1 tap (400ms wait) → KEY_1 = page next + * 2 taps (400ms wait) → KEY_B = flood advert + * 3 taps (400ms wait) → KEY_D = buzzer mute toggle + * 4 taps (immediate) → KEY_C = GPS on/off */ + user_btn_multitap { + compatible = "zephcore,input-multi-tap"; + /* No 'input' phandle — listen to ALL devices. + * KEY_A is emitted by the longpress pseudo-device, + * not by &buttons, so we must not filter by device. */ + input-codes = ; + tap-codes = ; + tap-delay-ms = <400>; + }; +}; + +/* Enable native USB serial for console/CLI */ +&usb_serial { + status = "okay"; +}; + +/* Add RX boosted mode and DIO1 pull-down to LoRa radio. + * Upstream omits rx-boosted and has no pull-down on DIO1. */ +&lora0 { + dio1-gpios = <&gpio0 14 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + rx-boosted; +}; + +/* Reduce CPU clock from 240 MHz to 160 MHz — saves power, HAL minimum */ +&cpu0 { + clock-frequency = ; +}; + +&cpu1 { + clock-frequency = ; +}; + +/* I2C sensors — auto-detected at runtime */ +&i2c0 { + #include "../../common/sensors-i2c.dtsi" +}; + +/* + * Flash partitions — reclaim unused space from 8MB layout. + * Delete lpcore slots, storage, scratch, and coredump partitions. + * Repurpose 0x7A0000 - 0x800000 (384KB) for LittleFS. + */ +/delete-node/ &slot0_lpcore_partition; +/delete-node/ &slot1_lpcore_partition; +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; +/delete-node/ &coredump_partition; + +&flash0 { + partitions { + /* LittleFS 384KB for DataStore + file-based BLE settings */ + lfs_partition: partition@7a0000 { + label = "lfs"; + reg = <0x7A0000 0x60000>; + }; + }; +}; + +/* LittleFS auto-mount — standard /lfs mount point */ +#include "../../common/filesystem.dtsi" diff --git a/zephcore/boards/example_board/README.md b/zephcore/boards/example_board/README.md index e213250..3400f69 100644 --- a/zephcore/boards/example_board/README.md +++ b/zephcore/boards/example_board/README.md @@ -29,6 +29,7 @@ SWD flash: `west flash` (requires J-Link, pyocd, or nrfjprog connected). | XIAO ESP32-C6 | `west build -b xiao_esp32c6 zephcore` | `west flash` | | LilyGo TLoRa C6 | `west build -b lilygo_tlora_c6/esp32c6/hpcore zephcore` | `west flash` | | Station G2 | `west build -b station_g2/esp32s3/procpu zephcore` | `west flash` | +| Heltec V3 | `west build -b heltec_wifi_lora32_v3/esp32s3/procpu zephcore` | `west flash` | ESP32 flash uses esptool over USB. Hold BOOT button if device doesn't enter download mode.