Add MeshCore relay_radio firmware for Heltec T114
Some checks failed
Build and deploy Docs site to GitHub Pages / github-pages (push) Has been cancelled
Run Unit Tests / test (push) Has been cancelled
PR Build Check / build (Heltec_v3_companion_radio_ble) (push) Has been cancelled
PR Build Check / build (Heltec_v3_repeater) (push) Has been cancelled
PR Build Check / build (Heltec_v3_room_server) (push) Has been cancelled
PR Build Check / build (LilyGo_Tlora_C6_repeater_) (push) Has been cancelled
PR Build Check / build (PicoW_repeater) (push) Has been cancelled
PR Build Check / build (RAK_4631_companion_radio_ble) (push) Has been cancelled
PR Build Check / build (RAK_4631_repeater) (push) Has been cancelled
PR Build Check / build (RAK_4631_room_server) (push) Has been cancelled
PR Build Check / build (Tbeam_SX1276_repeater) (push) Has been cancelled
PR Build Check / build (wio-e5-mini_repeater) (push) Has been cancelled
PR Build Check / build (wio_wm1110_repeater) (push) Has been cancelled

This commit is contained in:
2026-06-09 15:36:22 +03:00
commit cdd9d32fb5
787 changed files with 108699 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
#include <Arduino.h>
#include <Wire.h>
#include "SenseCapSolarBoard.h"
#ifdef NRF52_POWER_MANAGEMENT
const PowerMgtConfig power_config = {
.lpcomp_ain_channel = PWRMGT_LPCOMP_AIN,
.lpcomp_refsel = PWRMGT_LPCOMP_REFSEL,
.voltage_bootlock = PWRMGT_VOLTAGE_BOOTLOCK
};
void SenseCapSolarBoard::initiateShutdown(uint8_t reason) {
bool enable_lpcomp = (reason == SHUTDOWN_REASON_LOW_VOLTAGE ||
reason == SHUTDOWN_REASON_BOOT_PROTECT);
pinMode(VBAT_ENABLE, OUTPUT);
digitalWrite(VBAT_ENABLE, enable_lpcomp ? LOW : HIGH);
if (enable_lpcomp) {
configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel);
}
enterSystemOff(reason);
}
#endif // NRF52_POWER_MANAGEMENT
void SenseCapSolarBoard::begin() {
NRF52BoardDCDC::begin();
pinMode(BATTERY_PIN, INPUT);
pinMode(VBAT_ENABLE, OUTPUT);
digitalWrite(VBAT_ENABLE, LOW);
analogReadResolution(12);
analogReference(AR_INTERNAL_3_0);
delay(50);
#ifdef PIN_USER_BTN
pinMode(PIN_USER_BTN, INPUT_PULLUP);
#elif defined(PIN_BUTTON1)
pinMode(PIN_BUTTON1, INPUT_PULLUP);
#endif
#if defined(PIN_WIRE_SDA) && defined(PIN_WIRE_SCL)
Wire.setPins(PIN_WIRE_SDA, PIN_WIRE_SCL);
#endif
Wire.begin();
#ifdef LED_WHITE
pinMode(LED_WHITE, OUTPUT);
digitalWrite(LED_WHITE, LOW);
#endif
#ifdef LED_BLUE
pinMode(LED_BLUE, OUTPUT);
digitalWrite(LED_BLUE, LOW);
#endif
#ifdef P_LORA_TX_LED
pinMode(P_LORA_TX_LED, OUTPUT);
digitalWrite(P_LORA_TX_LED, LOW);
#endif
#ifdef NRF52_POWER_MANAGEMENT
checkBootVoltage(&power_config);
#endif
delay(10); // give sx1262 some time to power up
}

View File

@@ -0,0 +1,60 @@
#pragma once
#include <MeshCore.h>
#include <Arduino.h>
#include <helpers/NRF52Board.h>
class SenseCapSolarBoard : public NRF52BoardDCDC {
protected:
#ifdef NRF52_POWER_MANAGEMENT
void initiateShutdown(uint8_t reason) override;
#endif
public:
SenseCapSolarBoard() : NRF52Board("SENSECAP_SOLAR_OTA") {}
void begin();
#if defined(P_LORA_TX_LED)
void onBeforeTransmit() override {
digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on
}
void onAfterTransmit() override {
digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED off
}
#endif
uint16_t getBattMilliVolts() override {
digitalWrite(VBAT_ENABLE, LOW);
int adcvalue = 0;
analogReadResolution(12);
analogReference(AR_INTERNAL_3_0);
delay(10);
adcvalue = analogRead(BATTERY_PIN);
return (adcvalue * ADC_MULTIPLIER * AREF_VOLTAGE) / 4.096;
}
const char* getManufacturerName() const override {
return "Seeed SenseCap Solar";
}
void powerOff() override {
digitalWrite(LED_WHITE, LOW);
digitalWrite(LED_BLUE, LOW);
#ifdef PIN_USER_BTN
while (digitalRead(PIN_USER_BTN) == LOW);
// Keep pull-up enabled in system-off so the wake line doesn't float low.
nrf_gpio_cfg_sense_input(digitalPinToInterrupt(g_ADigitalPinMap[PIN_USER_BTN]), NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
#elif defined(PIN_BUTTON1)
while (digitalRead(PIN_BUTTON1) == LOW);
// Keep pull-up enabled in system-off so the wake line doesn't float low.
nrf_gpio_cfg_sense_input(digitalPinToInterrupt(g_ADigitalPinMap[PIN_BUTTON1]), NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
#endif
#ifdef NRF52_POWER_MANAGEMENT
initiateShutdown(SHUTDOWN_REASON_USER);
#else
sd_power_system_off();
#endif
}
};

View File

@@ -0,0 +1,102 @@
[SenseCap_Solar]
extends = nrf52_base
board = seeed_sensecap_solar
board_build.ldscript = boards/nrf52840_s140_v7.ld
build_flags = ${nrf52_base.build_flags}
${sensor_base.build_flags}
-I lib/nrf52/s140_nrf52_7.3.0_API/include
-I lib/nrf52/s140_nrf52_7.3.0_API/include/nrf52
-I variants/sensecap_solar
-I src/helpers/nrf52
-D NRF52_PLATFORM=1
-D USE_SX1262
-D NRF52_POWER_MANAGEMENT
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D P_LORA_TX_LED=12
-D P_LORA_DIO_1=1
-D P_LORA_RESET=2
-D P_LORA_BUSY=3
-D P_LORA_NSS=4
-D PIN_USER_BTN=PIN_BUTTON1
-D LORA_TX_POWER=22
-D SX126X_RXEN=5
-D SX126X_TXEN=RADIOLIB_NC
-D SX126X_DIO2_AS_RF_SWITCH=1
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D ENV_INCLUDE_GPS=1
build_src_filter = ${nrf52_base.build_src_filter}
+<helpers/*.cpp>
+<helpers/sensors>
+<../variants/sensecap_solar>
debug_tool = jlink
upload_protocol = nrfutil
lib_deps =
${nrf52_base.lib_deps}
${sensor_base.lib_deps}
[env:SenseCap_Solar_repeater]
extends = SenseCap_Solar
build_flags =
${SenseCap_Solar.build_flags}
-D ADVERT_NAME='"SenseCap_Solar Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${SenseCap_Solar.build_src_filter}
+<../examples/simple_repeater/*.cpp>
[env:SenseCap_Solar_room_server]
extends = SenseCap_Solar
build_flags =
${SenseCap_Solar.build_flags}
-D ADVERT_NAME='"SenseCap_Solar Room"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${SenseCap_Solar.build_src_filter}
+<../examples/simple_room_server/*.cpp>
[env:SenseCap_Solar_companion_radio_ble]
extends = SenseCap_Solar
board_build.ldscript = boards/nrf52840_s140_v7_extrafs.ld
board_upload.maximum_size = 708608
build_flags =
${SenseCap_Solar.build_flags}
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D BLE_PIN_CODE=123456
-D OFFLINE_QUEUE_SIZE=256
; -D BLE_DEBUG_LOGGING=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${SenseCap_Solar.build_src_filter}
+<helpers/nrf52/SerialBLEInterface.cpp>
+<../examples/companion_radio/*.cpp>
lib_deps =
${SenseCap_Solar.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:SenseCap_Solar_companion_radio_usb]
extends = SenseCap_Solar
board_build.ldscript = boards/nrf52840_s140_v7_extrafs.ld
board_upload.maximum_size = 708608
build_flags =
${SenseCap_Solar.build_flags}
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${SenseCap_Solar.build_src_filter}
+<helpers/nrf52/SerialBLEInterface.cpp>
+<../examples/companion_radio/*.cpp>
lib_deps =
${SenseCap_Solar.lib_deps}
densaugeo/base64 @ ~1.4.0

View File

@@ -0,0 +1,32 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/ArduinoHelpers.h>
#ifdef ENV_INCLUDE_GPS
#include <helpers/sensors/MicroNMEALocationProvider.h>
#endif
SenseCapSolarBoard board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#ifdef ENV_INCLUDE_GPS
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);
#else
EnvironmentSensorManager sensors = EnvironmentSensorManager();
#endif
bool radio_init() {
rtc_clock.begin(Wire);
return radio.std_init(&SPI);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View File

@@ -0,0 +1,19 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/radiolib/RadioLibWrappers.h>
#include <SenseCapSolarBoard.h>
#include <helpers/radiolib/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/ArduinoHelpers.h>
#include <helpers/sensors/EnvironmentSensorManager.h>
extern SenseCapSolarBoard board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern EnvironmentSensorManager sensors;
bool radio_init();
mesh::LocalIdentity radio_new_identity();

View File

@@ -0,0 +1,66 @@
#include "variant.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
#include "nrf.h"
const uint32_t g_ADigitalPinMap[] = {
// D0 .. D10 - Peripheral control pins
2, // D0 P0.02 (A0) GNSS_WAKEUP
3, // D1 P0.03 (A1) LORA_DIO1
28, // D2 P0.28 (A2) LORA_RESET
29, // D3 P0.29 (A3) LORA_BUSY
4, // D4 P0.04 (A4/SDA) LORA_CS
5, // D5 P0.05 (A5/SCL) LORA_SW
43, // D6 P1.11 (UART_TX) GNSS_TX
44, // D7 P1.12 (UART_RX) GNSS_RX
45, // D8 P1.13 (SPI_SCK) LORA_SCK
46, // D9 P1.14 (SPI_MISO) LORA_MISO
47, // D10 P1.15 (SPI_MOSI) LORA_MOSI
// D11-D12 - LED outputs
15, // D11 P0.15 User LED (White LED)
19, // D12 P0.19 Breathing LED (Blue LED - LoRa TX)
// D13 - User input
33, // D13 P1.01 User Button
// D14-D15 - Grove/NFC interface
9, // D14 P0.09 NFC1/GROVE_D1
10, // D15 P0.10 NFC2/GROVE_D0
// D16 - Power management
// 31, // D16 P0.31 VBAT_ADC (Battery voltage)
31, // D16 P0.31 VBAT_ADC (Battery voltage)
// D17 - GNSS control
35, // D17 P1.03 GNSS_RESET
37, // D18 P1.05 GNSS_ENABLE
14, // D19 P0.14 BAT_READ
39, // D20 P1.07 USER_BUTTON
//
21, // D21 P0.21 (QSPI_SCK)
25, // D22 P0.25 (QSPI_CSN)
20, // D23 P0.20 (QSPI_SIO_0 DI)
24, // D24 P0.24 (QSPI_SIO_1 DO)
22, // D25 P0.22 (QSPI_SIO_2 WP)
23, // D26 P0.23 (QSPI_SIO_3 HOLD)
};
void initVariant() {
pinMode(GPS_EN, OUTPUT);
digitalWrite(GPS_EN, LOW);
pinMode(BATTERY_PIN, INPUT);
pinMode(VBAT_ENABLE, OUTPUT);
digitalWrite(VBAT_ENABLE, LOW);
pinMode(PIN_QSPI_CS, OUTPUT);
digitalWrite(PIN_QSPI_CS, HIGH);
pinMode(LED_WHITE, OUTPUT);
digitalWrite(LED_WHITE, LOW);
pinMode(LED_BLUE, OUTPUT);
digitalWrite(LED_BLUE, LOW);
}

View File

@@ -0,0 +1,91 @@
#ifndef _SEEED_SENSECAP_SOLAR_H_
#define _SEEED_SENSECAP_SOLAR_H_
/** Master clock frequency */
#define VARIANT_MCK (64000000ul)
#define USE_LFXO // Board uses 32khz crystal for LF
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#define PINS_COUNT (33)
#define NUM_DIGITAL_PINS (33)
#define NUM_ANALOG_INPUTS (8)
#define NUM_ANALOG_OUTPUTS (0)
// LEDs
#define PIN_LED (12)
#define LED_PWR (PINS_COUNT)
#define LED_BUILTIN (PIN_LED)
#define LED_RED (PINS_COUNT)
#define LED_WHITE (11)
#define LED_BLUE (12) // LoRa TX indicator
#define LED_STATE_ON (1) // State when LED is litted
// Buttons
#define PIN_BUTTON1 (13)
#define PIN_BUTTON2 (20)
#define PIN_USER_BTN PIN_BUTTON1
#define VBAT_ENABLE (19) // Output LOW to enable reading of the BAT voltage.
// Analog pins
#define BATTERY_PIN (16) // Read the BAT voltage.
#define AREF_VOLTAGE (3.0F)
#define ADC_MULTIPLIER (3.0F) // 1M, 512k divider bridge
#define ADC_RESOLUTION (12)
// nRF52 power management settings
#define PWRMGT_VOLTAGE_BOOTLOCK (3300) // Won't boot below this voltage (mV)
#define PWRMGT_LPCOMP_AIN (7) // AIN7 = P0.31 = BATTERY_PIN
#define PWRMGT_LPCOMP_REFSEL (2) // 3/8 VDD (~3.38-3.71V)
// Serial interfaces
#define PIN_SERIAL1_RX (7)
#define PIN_SERIAL1_TX (6)
// SPI Interfaces
#define SPI_INTERFACES_COUNT (1)
#define PIN_SPI_MISO (9)
#define PIN_SPI_MOSI (10)
#define PIN_SPI_SCK (8)
// Lora SPI is on SPI0
#define P_LORA_SCLK PIN_SPI_SCK
#define P_LORA_MISO PIN_SPI_MISO
#define P_LORA_MOSI PIN_SPI_MOSI
// Wire Interfaces
#define WIRE_INTERFACES_COUNT (1)
#define PIN_WIRE_SDA (14)
#define PIN_WIRE_SCL (15)
// GPS L76KB
#define GPS_BAUDRATE 9600
#define GPS_THREAD_INTERVAL 50
#define PIN_GPS_TX PIN_SERIAL1_RX
#define PIN_GPS_RX PIN_SERIAL1_TX
#define PIN_GPS_STANDBY (0)
#define GPS_EN (18)
// QSPI Pins
#define PIN_QSPI_SCK (21)
#define PIN_QSPI_CS (22)
#define PIN_QSPI_IO0 (23)
#define PIN_QSPI_IO1 (24)
#define PIN_QSPI_IO2 (25)
#define PIN_QSPI_IO3 (26)
#define EXTERNAL_FLASH_DEVICES P25Q16H
#define EXTERNAL_FLASH_USE_QSPI
#endif