Add Meshnology W10 AIOT Dev Kit (SX1262 via MCP23017 I2C expander) (#10911)
* Add software LoRa IRQ polling and an MCP23017 expander HAL for radios behind an I2C expander
Some boards route the SX126x control lines (NRESET/DIO1/BUSY) through an I2C
GPIO expander instead of native GPIOs, and don't wire the expander's /INT to
the MCU, so RadioLib cannot take a hardware DIO1 interrupt.
Two reusable pieces, both gated behind USE_MCP23017 / LORA_DIO1_SOFTWARE_POLL
so builds that don't define them are unaffected:
- ExtensionIOMCP23017 + MCP23017LockingArduinoHal: a RadioLib HAL that maps
virtual pins (MCP23017_VPIN_BASE .. +15) onto an MCP23017's GPIO, so
RESET/BUSY/DIO1 reads and writes become I2C transactions while the real SPI
GPIOs (SCK/MOSI/MISO/CS) pass straight through. A failed I2C read skips the
read-modify-write rather than clobbering the rest of the bank.
- LORA_DIO1_SOFTWARE_POLL: with no DIO1 interrupt available, the SX126x
interface polls the radio IRQ status register from the radio thread and
synthesizes the ISR_TX/ISR_RX events, filtering noisy preamble/header IRQs so
they can't starve TX. A 1 ms ISR_POLL_TICK drives the poll; TX timers may
overwrite the pending tick (pollMissedIrqs() is the backup that bounds the
latency of the busy-Rx contention window). Behaviour is unchanged on all
boards that keep the hardware interrupt.
* Add Meshnology W10 AIOT Dev Kit variant (SX1262 via MCP23017 expander)
ESP32-S3R8 + EBYTE E22-900MM22S (SX1262) + AXP2101 PMIC + Quectel L76KB GPS +
SPI TFT, with the radio's RESET/DIO1/BUSY and the LCD reset routed through an
MCP23017 I2C expander at 0x20. The expander's /INT is not wired to the ESP32,
so DIO1 uses the software poll. Pins come from the board schematic and the
vendor firmware; the expander is an MCP23017 despite the V1.1 schematic's stale
'TCA9555' label (the V1.2 placement diagram and all vendor code use the MCP23017
register map).
A local pins_arduino.h shadows the generic esp32s3 variant to drop RGB_BUILTIN,
which otherwise pulls the Arduino RMT HAL into the link and fails against this
build's trimmed FreeRTOS config.
Reports HardwareModel 140 (MESHNOLOGY_W10, already present in the protobufs).
Hardware-verified on a real W10 AIOT Dev Kit: AXP2101 PMU, MCP23017, SX1262
init + a full over-the-air TX/RX round trip through the expander, PCF85063 RTC,
SHT41 and QMI8658 auto-detected, and an L76KB GPS fix.
* meshnology-w10: enable ES8311 speaker for notification tones
Bring up the ES8311 codec (I2C 0x18) -> NS4150 amp -> speaker so the board can
play notification tones / ringtones over the I2S buzzer path (the
use_i2s_as_buzzer external-notification option). Codec2 voice stays out of
scope: it is SX1280-only and this is a sub-GHz board.
- variant.h: HAS_I2S + DAC_I2S pins (MCLK=1, BCK=2, WS=4, DOUT=5, DIN=3)
- platformio.ini: arduino-audio-driver + ESP8266Audio + ESP8266SAM
- extra_variants/meshnology_w10/variant.cpp: lateInitVariant() configures the
ES8311, mirroring the other Meshtastic ES8311 boards. Kept codec-only (no
main.h) so the audio driver's 'using namespace audio_driver' does not pull a
conflicting GpioPin into scope alongside Meshtastic's class GpioPin.
- AudioThread.h: toggle the NS4150 amp (MCP23017 EXIO_PA_CTRL) around playback.
Verified on hardware: a test tune played audibly through the speaker.
* meshnology-w10: address review feedback on the MCP23017 driver
- ExtensionIOMCP23017: serialize register access with a mutex, since the radio
HAL (BUSY/DIO1/RESET) and AudioThread (amp enable) now reach the expander from
different threads and the read-modify-write paths are not atomic.
- digitalRead: return a fail-safe HIGH on a failed read instead of LOW, so a
transient I2C error on the LoRa BUSY line can't look like 'ready' and let
RadioLib start an SPI transaction early. (DIO1 is polled via the radio IRQ
register, not this pin.)
- enablePinChangeInterrupt: use the checked readReg() overload and skip on a
failed read, matching the other read-modify-write helpers.
- meshnology_w10 variant.cpp: log a warning if an ES8311 register write NACKs
instead of silently leaving the codec half-configured.
- RadioInterface.cpp: guard the MCP23017 HAL branch with ARCH_ESP32 to match the
include and driver-file guards.
* Replace board-model audio/sleep ifdefs with reusable variant capability macros
Two shared-code spots keyed off specific hardware models; move the board-specific
detail into opt-in macros the variants define, so the core code stays generic and
new boards can opt into the behavior class without touching shared files.
- AudioThread amp control: drop the T_LORA_PAGER / MESHNOLOGY_W10 ifdefs. A board
with an I2S amp now defines AUDIO_AMP_ENABLE(on) in its variant.h (T-LoRa Pager
and Meshnology W10 do), and AudioThread just calls it around playback. The
expander includes are keyed on USE_XL9555 / USE_MCP23017 (capabilities) instead
of the model name.
- Light-sleep / DIO1 wakeup: drop the SENSECAP_INDICATOR check. Boards whose
LORA_DIO1 is an expander pin (not an ESP32 GPIO) define LORA_DIO1_EXTENDED_IO
(SenseCAP Indicator and Meshnology W10), and sleep.cpp keys off that for both
the light-sleep skip and the DIO1 GPIO-wakeup skip. This also fixes a latent
issue on the SenseCAP: it previously reached the GPIO-wakeup path and called
gpio_pulldown_en() on a virtual expander pin; it now skips that cleanly.
Builds verified on meshnology_w10, tlora-pager, and seeed-sensecap-indicator.
* meshnology-w10: silence cppcheck constParameterPointer on the ISR-callback helper
isIsrTxCallback() takes a function pointer it only compares; cppcheck's
constParameterPointer wants it 'pointer to const', which is meaningless for a
function pointer (the codebase already globally suppresses the sibling
constParameterCallback). Inline-suppress it to keep the check green.
* HopScaling: qualify the member assignment as this->count
cppcheck (CI's version) flags 'count = newCount;' at the end of trimIfNeeded()
as uselessAssignmentArg ('assignment of function parameter has no effect') - a
false positive, since count is a member that outlives the call. Write it as
this->count (matching the Step-1 assignment above) so the analyzer sees a member
write. This finding comes in via the develop merge, not this board; fixing it
here to unblock the PR's cppcheck check.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
// Meshnology W10 - shadows the generic esp32s3 variant pins.
|
||||
// Deliberately omits PIN_RGB_LED / LED_BUILTIN / RGB_BUILTIN: the generic definitions make the
|
||||
// core's digitalWrite() reference the RMT-backed RGB LED HAL, which fails to link against this
|
||||
// build's trimmed FreeRTOS config (no xEventGroupSetBitsFromISR).
|
||||
#ifndef Pins_Arduino_h
|
||||
#define Pins_Arduino_h
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define USB_VID 0x303a
|
||||
#define USB_PID 0x1001
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
static const uint8_t SDA = 8;
|
||||
static const uint8_t SCL = 7;
|
||||
|
||||
// Shared LoRa/LCD SPI bus (E22_NSS is the default SS)
|
||||
static const uint8_t SS = 14;
|
||||
static const uint8_t MOSI = 13;
|
||||
static const uint8_t MISO = 11;
|
||||
static const uint8_t SCK = 12;
|
||||
|
||||
static const uint8_t A0 = 1;
|
||||
static const uint8_t A1 = 2;
|
||||
static const uint8_t A2 = 3;
|
||||
static const uint8_t A3 = 4;
|
||||
static const uint8_t A4 = 5;
|
||||
static const uint8_t A5 = 6;
|
||||
static const uint8_t A6 = 7;
|
||||
static const uint8_t A7 = 8;
|
||||
static const uint8_t A8 = 9;
|
||||
static const uint8_t A9 = 10;
|
||||
static const uint8_t A10 = 11;
|
||||
static const uint8_t A11 = 12;
|
||||
static const uint8_t A12 = 13;
|
||||
static const uint8_t A13 = 14;
|
||||
static const uint8_t A14 = 15;
|
||||
static const uint8_t A15 = 16;
|
||||
static const uint8_t A16 = 17;
|
||||
static const uint8_t A17 = 18;
|
||||
static const uint8_t A18 = 19;
|
||||
static const uint8_t A19 = 20;
|
||||
|
||||
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 T7 = 7;
|
||||
static const uint8_t T8 = 8;
|
||||
static const uint8_t T9 = 9;
|
||||
static const uint8_t T10 = 10;
|
||||
static const uint8_t T11 = 11;
|
||||
static const uint8_t T12 = 12;
|
||||
static const uint8_t T13 = 13;
|
||||
static const uint8_t T14 = 14;
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
||||
@@ -0,0 +1,41 @@
|
||||
[env:meshnology_w10]
|
||||
custom_meshtastic_hw_model = 140
|
||||
custom_meshtastic_hw_model_slug = MESHNOLOGY_W10
|
||||
custom_meshtastic_architecture = esp32-s3
|
||||
custom_meshtastic_actively_supported = true
|
||||
custom_meshtastic_support_level = 1
|
||||
custom_meshtastic_display_name = Meshnology W10
|
||||
custom_meshtastic_requires_dfu = true
|
||||
custom_meshtastic_partition_scheme = 16MB
|
||||
|
||||
; ESP32-S3R8: 8 MB OPI PSRAM, W25Q128JVSIQ = 16 MB QIO flash (pg1)
|
||||
board = esp32-s3-devkitc-1
|
||||
board_level = pr
|
||||
board_build.partitions = default_16MB.csv
|
||||
board_upload.flash_size = 16MB
|
||||
board_build.flash_mode = qio
|
||||
board_build.psram_type = opi
|
||||
board_build.arduino.memory_type = qio_opi
|
||||
|
||||
extends = esp32s3_base
|
||||
build_flags =
|
||||
${esp32s3_base.build_flags}
|
||||
-D MESHNOLOGY_W10
|
||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||
-I variants/esp32s3/meshnology-w10
|
||||
|
||||
lib_deps =
|
||||
${esp32s3_base.lib_deps}
|
||||
; ST7789/ST7796 TFT (USE_TFTDISPLAY)
|
||||
; renovate: datasource=custom.pio depName=LovyanGFX packageName=lovyan03/library/LovyanGFX
|
||||
lovyan03/LovyanGFX@1.2.21
|
||||
; PCF85063 RTC driver (PCF85063_RTC)
|
||||
; renovate: datasource=custom.pio depName=SensorLib packageName=lewisxhe/library/SensorLib
|
||||
lewisxhe/SensorLib@0.3.4
|
||||
; ES8311 audio codec + I2S notification tones (HAS_I2S)
|
||||
; renovate: datasource=github-tags depName=pschatzmann_arduino-audio-driver packageName=pschatzmann/arduino-audio-driver
|
||||
https://github.com/pschatzmann/arduino-audio-driver/archive/v0.3.0.zip
|
||||
# renovate: datasource=git-refs depName=ESP8266Audio packageName=https://github.com/meshtastic/ESP8266Audio gitBranch=meshtastic-2.0.0-dacfix
|
||||
https://github.com/meshtastic/ESP8266Audio/archive/343024632ee78d6216907b2353fc943a62422d80.zip
|
||||
# renovate: datasource=custom.pio depName=ESP8266SAM packageName=earlephilhower/library/ESP8266SAM
|
||||
earlephilhower/ESP8266SAM@1.1.0
|
||||
@@ -0,0 +1,171 @@
|
||||
#pragma once
|
||||
|
||||
// Meshnology W10 "LoRa AIOT Dev Kit" - ESP32-S3R8 + EBYTE E22-900MM22S (SX1262) + AXP2101 PMIC +
|
||||
// Quectel L76KB-A58 GPS + SPI TFT. The SX1262 RESET/DIO1/BUSY and the LCD reset are wired to an
|
||||
// MCP23017 I2C expander (0x20) whose /INT is not routed to the MCU, so DIO1 uses a software poll.
|
||||
|
||||
// ─── I2C bus ──────────────────────────────────────────────────────────────────
|
||||
// Shared by: AXP2101 PMIC, MCP23017 I/O expander, PCF85063ATL RTC, QMI8658 IMU,
|
||||
// ES8311 codec, SHT41 temp/humidity sensor (pg1: ESP_SDA=GPIO8, ESP_SCL=GPIO7)
|
||||
#define I2C_SDA 8
|
||||
#define I2C_SCL 7
|
||||
|
||||
// ─── Power management ─────────────────────────────────────────────────────────
|
||||
// AXP2101 PMIC on I2C (pg3). AXP_IRQ → EXIO5 (expander, whose /INT is not routed to the
|
||||
// ESP32), so no PMU_IRQ is possible; battery state is polled via the AXP2101 fuel gauge.
|
||||
// There is no direct battery ADC - the PMIC is the only voltage source.
|
||||
#define HAS_AXP2101
|
||||
|
||||
// ─── RTC ──────────────────────────────────────────────────────────────────────
|
||||
// PCF85063ATL on I2C (pg3); RTC_INT → EXIO4 (unused)
|
||||
#define PCF85063_RTC 0x51
|
||||
|
||||
// ─── I/O expander ─────────────────────────────────────────────────────────────
|
||||
// U7 is drawn as "TCA9555PWR(UMW)" on schematic V1.1, but production boards use the MCP23017
|
||||
// register map (V1.2 placement labels the part MCP23017T-E, and all vendor firmware/demo code
|
||||
// drives IODIR 0x00/01, GPIO 0x12/13, OLAT 0x14/15). A0/A1/A2 = 0 → I2C address 0x20.
|
||||
// The expander /INT output is NOT routed to the ESP32.
|
||||
#define USE_MCP23017
|
||||
#define MCP23017_ADDR 0x20
|
||||
#define MCP23017_VPIN_BASE 100 // RadioLib virtual pins 100..115 = expander GPA0..GPB7
|
||||
#define MCP23017_INT_ESP32_PIN (-1) // /INT not wired to any ESP32 GPIO
|
||||
#if MCP23017_INT_ESP32_PIN < 0
|
||||
// No hardware DIO1 interrupt possible: SX126x IRQ status register is polled from the radio thread
|
||||
#define LORA_DIO1_SOFTWARE_POLL 1
|
||||
#endif
|
||||
|
||||
// LORA_DIO1 is an expander pin, not an ESP32 GPIO, so it can't be used as a sleep/GPIO wakeup source
|
||||
// (shared capability; see its use in sleep.cpp).
|
||||
#define LORA_DIO1_EXTENDED_IO
|
||||
|
||||
// Expander pin map (pg2 "I/O Extensions"; EXIO0..7 = GPA0..7 / P00..P07, EXIO8..15 = GPB0..7 / P10..P17)
|
||||
// Not wired up here: EXIO0 CAM_PWDN, EXIO2 TP_INT, EXIO5 AXP_IRQ, EXIO6 SYS_OUT,
|
||||
// EXIO11 GPS RESET_N (driver FET Q3 unpopulated), EXIO13 TP_RST
|
||||
#define EXIO_LCD_RST 1 // GPA1: LCD reset
|
||||
#define EXIO_LORA_NRST 3 // GPA3: E22 NRST
|
||||
#define EXIO_RTC_INT 4 // GPA4: PCF85063 INT (unused)
|
||||
#define EXIO_PA_CTRL 7 // GPA7: NS4150 speaker amp enable (driven by AudioThread during playback)
|
||||
#define EXIO_IMU_INT1 8 // GPB0: QMI8658 INT1 (input only, no MCU interrupt)
|
||||
#define EXIO_LORA_DIO1 9 // GPB1: E22 DIO1
|
||||
#define EXIO_LORA_BUSY 10 // GPB2: E22 BUSY
|
||||
#define EXIO_GPS_WAKE 12 // GPB4: L76KB WAKE_UP (driven high at boot)
|
||||
|
||||
// ─── LoRa radio ───────────────────────────────────────────────────────────────
|
||||
// EBYTE E22-900MM22S (SX1262) - pg4 U10. SPI shared with the LCD, separate chip selects.
|
||||
// Bus pins via 0R links: E22_SCK=GPIO12, E22_MOSI=GPIO13, E22_MISO=GPIO11, E22_NSS=GPIO14 (pg4)
|
||||
#define USE_SX1262
|
||||
#define LORA_SCK 12
|
||||
#define LORA_MOSI 13
|
||||
#define LORA_MISO 11
|
||||
#define LORA_CS 14
|
||||
|
||||
// Control lines route through the MCP23017 (pg4: E22_NRST=EXIO3, E22_DIO1=EXIO9, E22_BUSY=EXIO10),
|
||||
// handled as RadioLib virtual pins by MCP23017LockingArduinoHal
|
||||
#define LORA_DIO1 (MCP23017_VPIN_BASE + EXIO_LORA_DIO1) // 109
|
||||
#define LORA_BUSY (MCP23017_VPIN_BASE + EXIO_LORA_BUSY) // 110
|
||||
#define LORA_RESET (MCP23017_VPIN_BASE + EXIO_LORA_NRST) // 103
|
||||
|
||||
#define SX126X_CS LORA_CS
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_BUSY LORA_BUSY
|
||||
#define SX126X_RESET LORA_RESET
|
||||
|
||||
// RF switch is fully hardware-automatic on this board: DIO2 drives TXEN directly and RXEN through
|
||||
// inverting FET Q4 (pg4). Do not assign TXEN/RXEN GPIOs.
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_TXEN RADIOLIB_NC
|
||||
#define SX126X_RXEN RADIOLIB_NC
|
||||
|
||||
// E22-900MM22S uses a plain 32 MHz crystal (no TCXO) - SX126X_DIO3_TCXO_VOLTAGE deliberately not defined
|
||||
#define SX126X_MAX_POWER 22
|
||||
|
||||
// ─── Display ──────────────────────────────────────────────────────────────────
|
||||
// SPI TFT on the "OLED"-silkscreened header / LCD FPC, sharing the LoRa SPI bus (pg1).
|
||||
// Vendor ships two panels on identical pins; the default kit has the ST7789 1.54" IPS 240x240.
|
||||
// Build with -D MESHNOLOGY_W10_LCD_ST7796_35 for the 3.5" ST7796 320x480 panel instead.
|
||||
#define TFT_CS 10 // pg1: OLED_CS=GPIO10
|
||||
#define TFT_DC 16 // pg1: OLED_DC=GPIO16
|
||||
#define TFT_BL 6 // pg1: OLED_BL=GPIO6 (backlight PWM)
|
||||
#define TFT_RST -1 // panel reset is EXIO1 on the expander, toggled in mcp23017EarlyInit()
|
||||
#define USE_TFTDISPLAY 1
|
||||
|
||||
#define SPI_FREQUENCY 75000000
|
||||
#define SPI_READ_FREQUENCY 16000000
|
||||
|
||||
#ifdef MESHNOLOGY_W10_LCD_ST7796_35
|
||||
// ST7796 3.5" 320x480 (capacitive touch on I2C - not enabled yet)
|
||||
#define ST7796_SPI_HOST SPI2_HOST
|
||||
#define ST7796_CS TFT_CS
|
||||
#define ST7796_RS TFT_DC
|
||||
#define ST7796_SDA LORA_MOSI
|
||||
#define ST7796_SCK LORA_SCK
|
||||
#define ST7796_MISO LORA_MISO
|
||||
#define ST7796_RESET TFT_RST
|
||||
#define ST7796_BL TFT_BL
|
||||
#define ST7796_BUSY -1
|
||||
#define TFT_WIDTH 320
|
||||
#define TFT_HEIGHT 480
|
||||
#define TFT_OFFSET_ROTATION 3
|
||||
#else
|
||||
// ST7789 1.54" IPS 240x240 (default kit panel)
|
||||
#define ST7789_SPI_HOST SPI2_HOST
|
||||
#define ST7789_CS TFT_CS
|
||||
#define ST7789_RS TFT_DC
|
||||
#define ST7789_SDA LORA_MOSI
|
||||
#define ST7789_SCK LORA_SCK
|
||||
#define ST7789_MISO LORA_MISO
|
||||
#define ST7789_RESET TFT_RST
|
||||
#define ST7789_BL TFT_BL
|
||||
#define ST7789_BUSY -1
|
||||
#define TFT_WIDTH 240
|
||||
#define TFT_HEIGHT 240
|
||||
#define TFT_OFFSET_ROTATION 1
|
||||
#endif
|
||||
#define TFT_OFFSET_X 0
|
||||
#define TFT_OFFSET_Y 0
|
||||
|
||||
// ─── GPS ──────────────────────────────────────────────────────────────────────
|
||||
// Quectel L76KB-A58 on UART0 pins (pg4: GPS_TXD→U0RXD=GPIO44, GPS_RXD→U0TXD=GPIO43; console is USB)
|
||||
// 1PPS only drives LED3 (pg3); RESET_N driver FET is unpopulated; WAKE_UP = EXIO12, driven high at boot
|
||||
#define HAS_GPS 1
|
||||
#define GPS_RX_PIN 44
|
||||
#define GPS_TX_PIN 43
|
||||
#define GPS_BAUDRATE 9600
|
||||
|
||||
// ─── User input ───────────────────────────────────────────────────────────────
|
||||
// pg1: SW2 pulls GPIO0 to GND (BOOT doubles as user button). SW3 is the AXP2101 power button.
|
||||
#define BUTTON_PIN 0
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
// ─── LED ──────────────────────────────────────────────────────────────────────
|
||||
// TX1812 (WS2812-compatible) RGB LED on GPIO48 via 33R (pg1, U35). The other LEDs are
|
||||
// hardware-driven: AXP2101 CHGLED, VSYS power LED, GPS 1PPS LED, UART0 TX/RX activity LEDs.
|
||||
// TODO: enabling HAS_NEOPIXEL currently fails to link (Adafruit NeoPixel pulls in the Arduino RMT
|
||||
// HAL, which needs xEventGroupSetBitsFromISR - not present in this build's FreeRTOS config)
|
||||
// #define HAS_NEOPIXEL
|
||||
// #define NEOPIXEL_COUNT 1
|
||||
// #define NEOPIXEL_DATA 48
|
||||
// #define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800)
|
||||
|
||||
// ─── Audio ────────────────────────────────────────────────────────────────────
|
||||
// ES8311 codec (I2C 0x18) -> NS4150 amp -> speaker, initialized in the variant's lateInitVariant().
|
||||
// Used for notification tones / ringtones over the I2S "buzzer" path (turn on the
|
||||
// use_i2s_as_buzzer external-notification option). Codec2 voice is SX1280-only, so it does not
|
||||
// apply to this sub-GHz board. The NS4150 amp enable is on the MCP23017 (EXIO_PA_CTRL / GPA7) and
|
||||
// is toggled by AudioThread around playback. pg3 I2S wiring below.
|
||||
#define HAS_I2S
|
||||
#define DAC_I2S_MCLK 1 // pg3: ES8311 MCLK
|
||||
#define DAC_I2S_BCK 2 // pg3: ES8311 BCLK/SCLK
|
||||
#define DAC_I2S_WS 4 // pg3: ES8311 LRCK
|
||||
#define DAC_I2S_DOUT 5 // pg3: playback data (ESP32 -> ES8311)
|
||||
#define DAC_I2S_DIN 3 // pg3: record data (ES8311 -> ESP32)
|
||||
// AudioThread powers the NS4150 amp on/off around playback via this (opt-in) hook.
|
||||
#define AUDIO_AMP_ENABLE(on) mcpIoExpander.digitalWrite(EXIO_PA_CTRL, (on) ? HIGH : LOW)
|
||||
|
||||
// ─── On-board peripherals not wired up yet ────────────────────────────────────
|
||||
// SHT41 temp/humidity (0x44) and QMI8658 IMU (0x6B): auto-detected on the I2C scan
|
||||
// microSD: CS on GPIO9, shares the LCD/LoRa SPI bus - not enabled
|
||||
// Camera interface: GPIO38-42/45-48 (pg1) - not enabled
|
||||
|
||||
// ─── Board identity ───────────────────────────────────────────────────────────
|
||||
#define MESHNOLOGY_W10 1
|
||||
@@ -68,6 +68,9 @@
|
||||
#define LORA_DIO1 (3 | IO_EXPANDER) // SX1262 IRQ
|
||||
#define LORA_DIO2 (2 | IO_EXPANDER) // SX1262 BUSY
|
||||
#define LORA_DIO3
|
||||
// LORA_DIO1 is an expander pin, not an ESP32 GPIO, so it can't be used as a sleep/GPIO wakeup source
|
||||
// (shared capability; see its use in sleep.cpp).
|
||||
#define LORA_DIO1_EXTENDED_IO
|
||||
|
||||
#define SX126X_CS LORA_CS
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
|
||||
@@ -92,6 +92,8 @@
|
||||
#define EXPANDS_DRV_EN (0)
|
||||
#define EXPANDS_AMP_EN (1)
|
||||
#define EXPANDS_KB_RST (2)
|
||||
// AudioThread powers the amp on/off around playback via this (opt-in) hook.
|
||||
#define AUDIO_AMP_ENABLE(on) io.digitalWrite(EXPANDS_AMP_EN, (on) ? HIGH : LOW)
|
||||
#define EXPANDS_LORA_EN (3)
|
||||
#define EXPANDS_GPS_EN (4)
|
||||
#define EXPANDS_NFC_EN (5)
|
||||
|
||||
Reference in New Issue
Block a user