From 80f8611e65637d93ca00fdff6eeed416e3d4dc1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 19 Aug 2026 17:05:34 +0000 Subject: [PATCH] feat(variants): add Seeed Wio Tracker L1 Pro 1W (#11542) * fix(sx126x): allow boards to opt out of the PA optimization table Boards driving an external PA can define SX126X_NO_POWER_OPTIMIZATION_TABLE to use the fixed PA config instead of RadioLib's table, which is tuned for a bare SX126x. Default behaviour is unchanged. init() applies the fixed config after begin(), which programs power through the table. * feat(variants): add Seeed Wio Tracker L1 Pro 1W nRF52840 + SX1262 with a 1 W external PA, L76K GNSS, SH1106 OLED. Uses hw_model 144 (meshtastic/protobufs#1038), opts into SX126X_NO_POWER_OPTIMIZATION_TABLE and declares SX126X_MAX_POWER explicitly. The PA gain table is indexed by SX1262 output power in dBm. Requires protobufs#1038 and a protobuf regen before it builds. * chore(deps): bump RadioLib to 510e00cf Carries the current LR11x0 and LR2021 fixes. * fix(variants): correct L1 Pro 1W QSPI pins and clean up comments PIN_QSPI_* are logical pin indices. The QSPI flash sits at D19-D24 in variant.cpp, but the defines carried D21-D26 from seeed_solar_node, where that block does start at D21. D25 and D26 are trackball pins. Also replaces mis-encoded characters in the pin comments and drops the migration note, which referenced a private repo path and a stale PINS_COUNT. * fix(variants): move L1 Pro 1W out of the per-PR build matrix board_level = pr is the high-attention tier that builds on every PR. This board belongs with the mainline set, which uses board_level = release. --- boards/seeed_wio_tracker_L1_Pro_1W.json | 57 +++++ platformio.ini | 2 +- src/configuration.h | 9 +- src/mesh/SX126xInterface.cpp | 12 +- src/platform/nrf52/architecture.h | 2 + .../platformio.ini | 22 ++ .../seeed_wio_tracker_L1_Pro_1W/variant.cpp | 93 ++++++++ .../seeed_wio_tracker_L1_Pro_1W/variant.h | 201 ++++++++++++++++++ 8 files changed, 395 insertions(+), 3 deletions(-) create mode 100644 boards/seeed_wio_tracker_L1_Pro_1W.json create mode 100644 variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/platformio.ini create mode 100644 variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/variant.cpp create mode 100644 variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/variant.h diff --git a/boards/seeed_wio_tracker_L1_Pro_1W.json b/boards/seeed_wio_tracker_L1_Pro_1W.json new file mode 100644 index 0000000000..f87074a01e --- /dev/null +++ b/boards/seeed_wio_tracker_L1_Pro_1W.json @@ -0,0 +1,57 @@ +{ + "build": { + "arduino": { + "ldscript": "nrf52840_s140_v7.ld" + }, + "core": "nRF5", + "cpu": "cortex-m4", + "extra_flags": "-DARDUINO_MDBT50Q_RX -DNRF52840_XXAA", + "f_cpu": "64000000L", + "hwids": [ + ["0x2886", "0x1668"], + ["0x2886", "0x1667"] + ], + "usb_product": "TRACKER L1 Pro 1W", + "mcu": "nrf52840", + "variant": "seeed_wio_tracker_L1_Pro_1W", + "bsp": { + "name": "adafruit" + }, + "softdevice": { + "sd_flags": "-DS140", + "sd_name": "s140", + "sd_version": "7.3.0", + "sd_fwid": "0x0123" + }, + "bootloader": { + "settings_addr": "0xFF000" + } + }, + "connectivity": ["bluetooth"], + "debug": { + "jlink_device": "nRF52840_xxAA", + "svd_path": "nrf52840.svd", + "openocd_target": "nrf52840-mdk-rs" + }, + "frameworks": ["arduino"], + "name": "seeed_wio_tracker_L1_Pro_1W", + "upload": { + "maximum_ram_size": 248832, + "maximum_size": 815104, + "speed": 115200, + "protocol": "nrfutil", + "protocols": [ + "jlink", + "nrfjprog", + "nrfutil", + "stlink", + "cmsis-dap", + "blackmagic" + ], + "use_1200bps_touch": true, + "require_upload_port": true, + "wait_for_upload_port": true + }, + "url": "https://www.seeedstudio.com/Wio-Tracker-L1-Pro-p-6454.html", + "vendor": "Seeed Studio" +} diff --git a/platformio.ini b/platformio.ini index 74916381f0..555aa376d2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -132,7 +132,7 @@ lib_deps = [radiolib_base] lib_deps = # renovate: datasource=github-tags depName=RadioLib packageName=jgromes/RadioLib - https://github.com/jgromes/RadioLib/archive/6d8934836678d8894e3d556550475b37dce3e2b6.zip + https://github.com/jgromes/RadioLib/archive/510e00cfb05bbc3c2b7b524262785454944adb6e.zip [device-ui_base] lib_deps = diff --git a/src/configuration.h b/src/configuration.h index 5c9cdf9566..b55ce262f7 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -205,6 +205,13 @@ along with this program. If not, see . #define TX_GAIN_LORA 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8 #endif +#ifdef SEEED_WIO_TRACKER_L1_PRO_1W +// Indexed by SX1262 output power in dBm, matching RadioInterface::limitPower(). +// TODO: verify against measured output. +#define NUM_PA_POINTS 22 +#define TX_GAIN_LORA 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10 +#endif + // Default system gain to 0 if not defined #ifndef NUM_PA_POINTS #define NUM_PA_POINTS 1 @@ -234,7 +241,7 @@ along with this program. If not, see . #define SSD1306_ADDRESS_L 0x3C // Addr = 0 #define SSD1306_ADDRESS_H 0x3D // Addr = 1 -#if defined(SEEED_WIO_TRACKER_L1) && !defined(SEEED_WIO_TRACKER_L1_EINK) +#if (defined(SEEED_WIO_TRACKER_L1) || defined(SEEED_WIO_TRACKER_L1_PRO_1W)) && !defined(SEEED_WIO_TRACKER_L1_EINK) #define SSD1306_ADDRESS SSD1306_ADDRESS_H #define USE_SH1106 #endif diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 750ebbbefb..2400a8e03f 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -176,6 +176,12 @@ template bool SX126xInterface::init() if (res == RADIOLIB_ERR_NONE) res = lora.setCRC(RADIOLIB_SX126X_LORA_CRC_ON); +#ifdef SX126X_NO_POWER_OPTIMIZATION_TABLE + // begin() applied the optimization table; re-apply the fixed PA config. + if (res == RADIOLIB_ERR_NONE) + res = lora.setOutputPower(power, false); +#endif + if (res == RADIOLIB_ERR_NONE) startReceive(); // start receiving @@ -226,7 +232,11 @@ template bool SX126xInterface::reconfigure() if (power < -9) power = -9; +#ifdef SX126X_NO_POWER_OPTIMIZATION_TABLE + err = lora.setOutputPower(power, false); // external PA: fixed PA config +#else err = lora.setOutputPower(power); +#endif if (err != RADIOLIB_ERR_NONE) { // Don't abort: this power is operator config (tx_power/SX126X_MAX_POWER); a value above the // driver's max would crash the daemon before reloadConfig() persists. Flag it and keep prior power. @@ -525,4 +535,4 @@ template void SX126xInterface::setTransmitEnable(bool txon) #endif } -#endif \ No newline at end of file +#endif diff --git a/src/platform/nrf52/architecture.h b/src/platform/nrf52/architecture.h index 0193eeb5c8..e9abbbc293 100644 --- a/src/platform/nrf52/architecture.h +++ b/src/platform/nrf52/architecture.h @@ -137,6 +137,8 @@ #define HW_VENDOR meshtastic_HardwareModel_HELTEC_MESH_POCKET #elif defined(SEEED_WIO_TRACKER_L1_EINK) #define HW_VENDOR meshtastic_HardwareModel_SEEED_WIO_TRACKER_L1_EINK +#elif defined(SEEED_WIO_TRACKER_L1_PRO_1W) +#define HW_VENDOR meshtastic_HardwareModel_SEEED_WIO_TRACKER_L1_PRO_1W #elif defined(SEEED_WIO_TRACKER_L1) #define HW_VENDOR meshtastic_HardwareModel_SEEED_WIO_TRACKER_L1 #elif defined(HELTEC_MESH_SOLAR) diff --git a/variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/platformio.ini b/variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/platformio.ini new file mode 100644 index 0000000000..772c0152e6 --- /dev/null +++ b/variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/platformio.ini @@ -0,0 +1,22 @@ +[env:seeed_wio_tracker_L1_Pro_1W] +custom_meshtastic_hw_model = 144 +custom_meshtastic_hw_model_slug = SEEED_WIO_TRACKER_L1_PRO_1W +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = Seeed Wio Tracker L1 Pro 1W +custom_meshtastic_images = wio_tracker_l1_case.svg +custom_meshtastic_tags = Seeed +custom_meshtastic_requires_dfu = true + +board = seeed_wio_tracker_L1_Pro_1W +board_level = release +extends = nrf52840_base +build_flags = ${nrf52840_base.build_flags} + -I variants/nrf52840/seeed_wio_tracker_L1_Pro_1W + -D SEEED_WIO_TRACKER_L1_PRO_1W + -I src/platform/nrf52/softdevice + -I src/platform/nrf52/softdevice/nrf52 +board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/seeed_wio_tracker_L1_Pro_1W> +debug_tool = jlink diff --git a/variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/variant.cpp b/variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/variant.cpp new file mode 100644 index 0000000000..b957db314e --- /dev/null +++ b/variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/variant.cpp @@ -0,0 +1,93 @@ +/* + * Digital pin mapping (logical Dx to nRF Port.Pin) and initVariant() for the + * Seeed Wio Tracker L1 Pro 1W. + */ + +#include "variant.h" +#include "nrf.h" +#include "wiring_constants.h" +#include "wiring_digital.h" + +/** + * @brief Digital pin to GPIO port/pin mapping table + * + * Format: Logical Pin (Dx) -> nRF Port.Pin (Px.xx) + */ +extern "C" { +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 LORA_CS + 29, // D5 P0.29 (AIN5) LORA_VDET, Pro 1W uses P0.29 not P1.08 + 27, // D6 P0.27 GNSS_TX + 26, // D7 P0.26 GNSS_RX + 30, // D8 P0.30 SPI_SCK + 3, // D9 P0.03 SPI_MISO + 28, // D10 P0.28 SPI_MOSI + + // D11-D12 - LED outputs / Buzzer + 33, // D11 P1.01 Mesh_LED (orange), Pro 1W uses P1.01 not P1.15 + 32, // D12 P1.00 Buzzer, shared with the LED_BLUE macro alias + + // D13 - User input + 8, // D13 P0.08 User Button + + // D14-D15 - OLED I2C0 + 6, // D14 P0.06 OLED SDA + 5, // D15 P0.05 OLED SCL + + // D16 - Battery voltage ADC + 31, // D16 P0.31 VBAT_ADC + + // D17-D18 - Grove I2C1 + 43, // D17 P1.11 GROVE SCL + 44, // D18 P1.12 GROVE SDA + + // D19-D24 - QSPI Flash + 21, // D19 P0.21 QSPI_SCK + 25, // D20 P0.25 QSPI_CSN + 20, // D21 P0.20 QSPI_SIO_0 + 24, // D22 P0.24 QSPI_SIO_1 + 22, // D23 P0.22 QSPI_SIO_2 + 23, // D24 P0.23 QSPI_SIO_3 + + // D25-D29 - Trackball + 36, // D25 TB_UP + 12, // D26 TB_DOWN + 11, // D27 TB_LEFT + 35, // D28 TB_RIGHT + 37, // D29 TB_PRESS + + // D30 - Battery divider enable + 4, // D30 P0.04 BAT_CTL + + // D31-D33 - Pro 1W only + 13, // D31 P0.13 BOOST_EN (Grove 5V Boost) + 47, // D32 P1.15 nRF_Sig_Charge_State (BQ25616 STAT) + 14, // D33 P0.14 LORA_PWR_EN (SX1262 + 1 W PA LDO) +}; +} + +void initVariant() +{ + pinMode(PIN_QSPI_CS, OUTPUT); + digitalWrite(PIN_QSPI_CS, HIGH); + + // Enable battery divider for ADC sampling + pinMode(BAT_READ, OUTPUT); + digitalWrite(BAT_READ, HIGH); + + // Grove 5V Boost: default OFF to save power at boot / shipping state. + // Apps that need Grove 5V can re-enable by writing BOOST_EN_ACTIVE to PIN_BOOST_EN. + pinMode(PIN_BOOST_EN, OUTPUT); + digitalWrite(PIN_BOOST_EN, !BOOST_EN_ACTIVE); + + // LED: default off + pinMode(PIN_LED1, OUTPUT); + digitalWrite(PIN_LED1, LOW); + // PIN_LED2 (D12) shares the buzzer pin; ExternalNotification configures it. + // Forcing it LOW here would prevent PWM output. +} diff --git a/variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/variant.h b/variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/variant.h new file mode 100644 index 0000000000..75bfe887b6 --- /dev/null +++ b/variants/nrf52840/seeed_wio_tracker_L1_Pro_1W/variant.h @@ -0,0 +1,201 @@ +#ifndef _SEEED_TRACKER_L1_PRO_1W_H_ +#define _SEEED_TRACKER_L1_PRO_1W_H_ + +#include "WVariant.h" + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Clock Configuration +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +#define VARIANT_MCK (64000000ul) // Master clock frequency +#define USE_LFXO // 32.768kHz crystal for LFCLK + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Pin Capacity Definitions +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +#define PINS_COUNT (34u) // Total GPIO pins (D0-D33) +#define NUM_DIGITAL_PINS (34u) // Digital I/O pins +#define NUM_ANALOG_INPUTS (8u) // Analog inputs (A0-A5 + VBAT + AREF) +#define NUM_ANALOG_OUTPUTS (0u) + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// LED Configuration +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Only one real LED (orange, P1.01). PIN_LED2/LED_BLUE/LED_CONN alias D12 (buzzer) for +// ABI compatibility with app code; they drive no hardware LED. +#define PIN_LED1 (11) // Mesh_LED orange P1.01 +#define PIN_LED2 (12) // buzzer pin (no real LED on L1 Pro 1W) + +#define LED_GREEN PIN_LED1 +#define LED_BLUE PIN_LED2 +#define LED_STATE_ON 1 // State when LED is lit + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Button Configuration +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +#define CANCEL_BUTTON_PIN D13 // Program Button +#define CANCEL_BUTTON_ACTIVE_LOW true +#define CANCEL_BUTTON_ACTIVE_PULLUP false + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Digital Pin Mapping (D0-D32) +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// D5 / D11 / D31 / D32 are the Pro 1W V1.0 hardware-revision pins +#define D0 0 // P1.09 GNSS_WAKEUP/IO0 +#define D1 1 // P0.07 LORA_DIO1 +#define D2 2 // P1.07 LORA_RESET +#define D3 3 // P1.10 LORA_BUSY +#define D4 4 // P1.14 LORA_CS +#define D5 5 // P0.29 LORA_VDET (AIN5), replaces the stock L1 LORA_SW on P1.08 +#define D6 6 // P0.27 GNSS_TX +#define D7 7 // P0.26 GNSS_RX +#define D8 8 // P0.30 SPI_SCK +#define D9 9 // P0.03 SPI_MISO +#define D10 10 // P0.28 SPI_MOSI +#define D11 11 // P1.01 Mesh_LED (orange) +#define D12 12 // P1.00 Buzzer +#define D13 13 // P0.08 User Button +#define D14 14 // P0.06 OLED SDA +#define D15 15 // P0.05 OLED SCL +#define D16 16 // P0.31 VBAT_ADC +#define D17 17 // P1.11 Grove I2C1 SCL +#define D18 18 // P1.12 Grove I2C1 SDA +#define D31 31 // P0.13 BOOST_EN (Grove 5V Boost enable), new on Pro 1W +#define D32 32 // P1.15 nRF_Sig_Charge_State (BQ25616 STAT), new on Pro 1W +#define D33 33 // P0.14 LORA_PWR_EN (SX1262 + 1 W PA LDO), new on Pro 1W + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Analog Pin Definitions +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +#define PIN_A0 0 // P0.02 Analog Input 0 +#define PIN_A1 1 // P0.03 Analog Input 1 +#define PIN_A2 2 // P0.28 Analog Input 2 +#define PIN_A3 3 // P0.29 Analog Input 3 +#define PIN_A4 4 // P0.04 Analog Input 4 +#define PIN_A5 5 // P0.05 Analog Input 5 +#define PIN_VBAT D16 // P0.31 Battery voltage sense + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Communication Interfaces +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// I2C Configuration +#define PIN_WIRE_SDA D14 // P0.06 OLED SDA +#define PIN_WIRE_SCL D15 // P0.05 OLED SCL +#define WIRE_INTERFACES_COUNT 2 +#define PIN_WIRE1_SDA D18 +#define PIN_WIRE1_SCL D17 +#define I2C_NO_RESCAN + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +#define HAS_SCREEN 1 +#define USE_SSD1306 1 + +// SPI Configuration (SX1262) +#define SPI_INTERFACES_COUNT 1 +#define PIN_SPI_MISO 9 // P0.03 (D9) +#define PIN_SPI_MOSI 10 // P0.28 (D10) +#define PIN_SPI_SCK 8 // P0.30 (D8) + +// SX1262 LoRa Module Pins +#define USE_SX1262 +#define SX126X_CS D4 // Chip select +#define SX126X_DIO1 D1 // Digital IO 1 (Interrupt) +#define SX126X_BUSY D3 // Busy status +#define SX126X_RESET D2 // Reset control +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // TCXO supply voltage +#define SX126X_RXEN RADIOLIB_NC +#define SX126X_TXEN RADIOLIB_NC +#define SX126X_DIO2_AS_RF_SWITCH // DIO2 controls antenna switch (no external RXEN/TXEN) + +// SX1262 drives a 1 W external PA; use the fixed PA config, not RadioLib's table. +#define SX126X_NO_POWER_OPTIMIZATION_TABLE + +// Chip-side drive ceiling; limitPower() already subtracted the PA gain. TODO: verify on bench. +#define SX126X_MAX_POWER 22 + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Power Management +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +#define BAT_READ 30 // D30 = P0.04 Battery divider enable (BAT_CTL) on signal board. +#define ADC_CTRL BAT_READ +#define ADC_CTRL_ENABLED HIGH +#define BATTERY_SENSE_RESOLUTION_BITS 12 +#define ADC_MULTIPLIER 2.0 +#define BATTERY_PIN PIN_VBAT +#define AREF_VOLTAGE 3.6 +// We rely on the nrf52840 USB controller to tell us if we are hooked to a power supply +#define NRF_APM + +// BQ25616 single-wire charge status (Pro 1W) +#define PIN_BOOST_EN D31 // D31 / P0.13, Grove 5V Boost enable +#define EXT_CHRG_DETECT D32 // D32 / P1.15, BQ25616 STAT +#define EXT_CHRG_DETECT_VALUE LOW // 0 = charging, 1 = full / charger sleep +#define BOOST_EN_ACTIVE HIGH // HIGH enables Grove 5V Boost + +// External LDO enable for the SX1262 + 1 W PA. D33 rather than raw GPIO 14 because +// g_ADigitalPinMap[14] is D14 (OLED SDA). init() drives it HIGH; deep sleep does not clear it. +#define LORA_PWR_EN D33 +#define SX126X_POWER_EN LORA_PWR_EN + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// GPS L76KB +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +#define GPS_L76K +#ifdef GPS_L76K +#define GPS_TX_PIN D6 // P0.26 - This is data from the MCU +#define GPS_RX_PIN D7 // P0.27 - This is data from the GNSS +#define HAS_GPS 1 +#define GPS_BAUDRATE 9600 +#define GPS_THREAD_INTERVAL 50 +#define PIN_SERIAL1_RX GPS_RX_PIN +#define PIN_SERIAL1_TX GPS_TX_PIN + +#define PIN_GPS_STANDBY D0 +#endif + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// On-board QSPI Flash +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Logical pin indices; the QSPI block is at D19-D24 in variant.cpp. +#define PIN_QSPI_SCK (19) +#define PIN_QSPI_CS (20) +#define PIN_QSPI_IO0 (21) +#define PIN_QSPI_IO1 (22) +#define PIN_QSPI_IO2 (23) +#define PIN_QSPI_IO3 (24) + +#define EXTERNAL_FLASH_DEVICES P25Q16H +#define EXTERNAL_FLASH_USE_QSPI + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Buzzer +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +#define PIN_BUZZER D12 // P1.00, pwm output + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Trackball +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +#define CANNED_MESSAGE_ADD_CONFIRMATION 1 + +#define HAS_TRACKBALL 1 +#define TB_UP 25 +#define TB_DOWN 26 +#define TB_LEFT 27 +#define TB_RIGHT 28 +#define TB_PRESS 29 +#define TB_DIRECTION FALLING + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// Compatibility Definitions +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +#ifdef __cplusplus +extern "C" { +#endif +#define PIN_SERIAL2_RX (-1) +#define PIN_SERIAL2_TX (-1) +#ifdef __cplusplus +} +#endif + +#endif // _SEEED_TRACKER_L1_PRO_1W_H_