Files
MeshCore-Solo/variants/wio-tracker-l1/variant.cpp
Jakub 5bfebc6559 feat(bot): Actions commands, multi-trigger, and user GPIO pins
- Auto-Reply Bot gains Actions (!buzz/!gps/!advert) behind a new per-target
  toggle nested under Commands (bot_actions_dm/ch/room); off by default.
- Bot Trigger fields accept comma-separated multiple phrases, matching any
  one fires the reply.
- New user-assignable GPIO feature (Wio Tracker L1): !gpio1..!gpio4 bot
  commands plus a Tools > GPIO screen. Each pin cycles Off/Input/Output;
  GPIO1/GPIO2 (P0.02/P0.29, the nRF52840's AIN0/AIN5) also offer a read-only
  Analog mode via direct SAADC access. GPIO3/GPIO4 (P0.09/P0.10) are the
  chip's NFC1/NFC2 pins, repurposed as plain GPIO via a one-time UICR
  NFCPINS bit-clear in initVariant() (adapted from Adafruit's own
  nfc_to_gpio example) -- confirmed working on real hardware.
- Fix: DM/room reply-prefix ("@[nick] ") stripping happened at the wrong
  layer, hiding the "To:" header on DM replies and leaking the raw prefix
  into room messages' list view; a related mismatch had the history
  scrollbar's sizing pass wrap room messages with the sender name still
  attached, disagreeing with the actual rendered text.

Build-verified: WioTrackerL1_companion_solo_dual and
WioTrackerL1Eink_companion_solo_dual both compile and link clean
(sizeof(NodePrefs) confirmed 2720 via real build, not guessed).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-21 20:30:03 +02:00

108 lines
3.4 KiB
C++

#include "variant.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
#include "nrf.h"
const uint32_t g_ADigitalPinMap[] = {
// D0 .. D10 - Peripheral control pins
41, // D0 P1.09 GNSS_WAKEUP
7, // D1 P0.07 LORA_DIO1
39, // D2 P1,07 LORA_RESET
42, // D3 P1.10 LORA_BUSY
46, // D4 P1.14 (A4/SDA) LORA_CS
40, // D5 P1.08 (A5/SCL) LORA_SW
27, // D6 P0.27 (UART_TX) GNSS_TX
26, // D7 P0.26 (UART_RX) GNSS_RX
30, // D8 P0.30 (SPI_SCK) LORA_SCK
3, // D9 P0.3 (SPI_MISO) LORA_MISO
28, // D10 P0.28 (SPI_MOSI) LORA_MOSI
// D11-D12 - LED outputs
33, // D11 P1.1 User LED
// Buzzzer
32, // D12 P1.0 Buzzer
// D13 - User input
8, // D13 P0.08 User Button
// D14-D15 - OLED
6, // D14 P0.06 OLED SDA
5, // D15 P0.05 OLED SCL
// D16 - Battery voltage ADC input
31, // D16 P0.31 VBAT_ADC
// GROVE
43, // D17 P0.00 GROVE SDA
44, // D18 P0.01 GROVE SCL
// FLASH
21, // D19 P0.21 (QSPI_SCK)
25, // D20 P0.25 (QSPI_CSN)
20, // D21 P0.20 (QSPI_SIO_0 DI)
24, // D22 P0.24 (QSPI_SIO_1 DO)
22, // D23 P0.22 (QSPI_SIO_2 WP)
23, // D24 P0.23 (QSPI_SIO_3 HOLD)
// JOYSTICK
36, // D25 TB_UP
12, // D26 TB_DOWN
11, // D27 TB_LEFT
35, // D28 TB_RIGHT
37, // D29 TB_PRESS
// VBAT ENABLE
4, // D30 BAT_CTL
// EINK
13, // 31 SCK
14, // 32 RST
15, // 33 MOSI
16, // 34 DC
17, // 35 BUSY
19, // 36 CS
0xFF, // 37 MISO
};
// GPIO3/GPIO4 (P0.09/P0.10) are the nRF52840's NFC1/NFC2 pins. Factory UICR
// reserves them for NFC antenna operation -- nrf_gpio_cfg_output/cfg_input
// alone won't work on them until UICR.NFCPINS.PROTECT flips from NFC to
// GPIO, which only takes effect after a reset. This clears a single bit
// (1=NFC -> 0=GPIO), which flash permits without an erase cycle, so no other
// UICR field (BOOTLOADERADDR, APPROTECT, ...) is touched. One-way: going back
// to NFC needs a full chip erase via debugger. No-ops on every boot after the
// first (reads as GPIO already). Adapted from Adafruit's own
// Bluefruit52Lib/examples/Hardware/nfc_to_gpio example.
static void ensureNfcPinsAsGpio() {
if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) ==
(UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)) {
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
NVIC_SystemReset(); // UICR is only latched at boot
}
}
void initVariant() {
ensureNfcPinsAsGpio(); // must run first: may reset the board
pinMode(PIN_QSPI_CS, OUTPUT);
digitalWrite(PIN_QSPI_CS, HIGH);
// VBAT_ENABLE: hold HIGH so the battery voltage divider is always on and its
// node stays settled for the ADC read (getBattMilliVolts). Per-read gating
// left it unsettled at sample time -> high/jittery readings.
pinMode(VBAT_ENABLE, OUTPUT);
digitalWrite(VBAT_ENABLE, HIGH);
// set LED pin as output and set it low
pinMode(PIN_LED, OUTPUT);
digitalWrite(PIN_LED, LOW);
// set buzzer pin as output and set it low
pinMode(12, OUTPUT);
digitalWrite(12, LOW);
}