feat(variants): add Waveshare ESP32-S3-LR1121

ESP32-S3FH4R2 (4MB flash, 2MB PSRAM, native USB-CDC) with an LR1121.
Pins, the DIO5/DIO6 RF switch table and the 1.8 V TCXO follow the HF
schematic and Waveshare's examples. Envs: repeater, room server,
companion USB/BLE and KISS modem, all on min_spiffs so roles share one
partition layout.

Only RFO_HP_LF is wired (R4 on RFO_LP_LF is not fitted), so the new
opt-in LR1121_FORCE_HP_PA flag keeps RadioLib on the HP PA at <= 14 dBm,
where it would otherwise select the unconnected LP PA.
This commit is contained in:
agessaman
2026-10-11 20:51:18 -07:00
parent 2dbd463eda
commit 3d1a5d4c64
5 changed files with 200 additions and 0 deletions
+7
View File
@@ -36,6 +36,13 @@ class CustomLR1121 : public LR1121 {
return len;
}
#ifdef LR1121_FORCE_HP_PA
// boards with only RFO_HP_LF wired: stop RadioLib switching to the LP PA at <= 14 dBm (2.4 GHz still uses the HF PA)
int16_t setOutputPower(int8_t power) override {
return LR1121::setOutputPower(power, true);
}
#endif
float getFreqMHz() const { return freqMHz; }
int16_t setRxBoostedGainMode(bool en) {
@@ -0,0 +1,11 @@
#pragma once
#include <Arduino.h>
#include <helpers/ESP32Board.h>
class WaveshareS3LR1121Board : public ESP32Board {
public:
const char* getManufacturerName() const override {
return "Waveshare ESP32-S3-LR1121";
}
};
@@ -0,0 +1,102 @@
; Waveshare ESP32-S3-LR1121 (HF: 850-930 MHz + 2.4 GHz)
; ESP32-S3FH4R2 (4MB flash, 2MB PSRAM), native USB-CDC via the Tiny-Adapter FPC.
; No user LED, battery sense or user button (BOOT is GPIO0).
[Waveshare_S3_LR1121]
extends = esp32_base
board = esp32-s3-zero
; min_spiffs: 1.9MB OTA app slots; one layout for every role so switching roles keeps the filesystem
board_build.partitions = min_spiffs.csv
build_flags = ${esp32_base.build_flags}
-I variants/waveshare_esp32s3_lr1121
-D BOARD_HAS_PSRAM
-D P_LORA_DIO_1=38
-D P_LORA_NSS=42
-D P_LORA_RESET=39
-D P_LORA_BUSY=41
-D P_LORA_SCLK=40
-D P_LORA_MISO=46
-D P_LORA_MOSI=45
-D RADIO_CLASS=CustomLR1121
-D WRAPPER_CLASS=CustomLR1121Wrapper
-D LR11X0_DIO3_TCXO_VOLTAGE=1.8
-D LR1121_FORCE_HP_PA ; RFO_LP_LF is not fitted (R4 NC)
-D RX_BOOSTED_GAIN=true
-D LORA_TX_POWER=22
build_src_filter = ${esp32_base.build_src_filter}
+<../variants/waveshare_esp32s3_lr1121>
lib_deps =
${esp32_base.lib_deps}
[env:Waveshare_S3_LR1121_repeater]
extends = Waveshare_S3_LR1121
build_flags =
${Waveshare_S3_LR1121.build_flags}
-D ADVERT_NAME='"Waveshare LR1121 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 = ${Waveshare_S3_LR1121.build_src_filter}
+<../examples/simple_repeater/*.cpp>
lib_deps =
${Waveshare_S3_LR1121.lib_deps}
${esp32_ota.lib_deps}
[env:Waveshare_S3_LR1121_room_server]
extends = Waveshare_S3_LR1121
build_flags =
${Waveshare_S3_LR1121.build_flags}
-D ADVERT_NAME='"Waveshare LR1121 Room"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Waveshare_S3_LR1121.build_src_filter}
+<../examples/simple_room_server>
lib_deps =
${Waveshare_S3_LR1121.lib_deps}
${esp32_ota.lib_deps}
[env:Waveshare_S3_LR1121_companion_radio_usb]
extends = Waveshare_S3_LR1121
build_flags =
${Waveshare_S3_LR1121.build_flags}
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
-D ENABLE_USB_INTERFACE
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Waveshare_S3_LR1121.build_src_filter}
+<helpers/esp32/*.cpp>
+<../examples/companion_radio/*.cpp>
lib_deps =
${Waveshare_S3_LR1121.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:Waveshare_S3_LR1121_companion_radio_ble]
extends = Waveshare_S3_LR1121
build_flags =
${Waveshare_S3_LR1121.build_flags}
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
-D BLE_PIN_CODE=123456
; -D BLE_DEBUG_LOGGING=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Waveshare_S3_LR1121.build_src_filter}
+<helpers/esp32/*.cpp>
+<../examples/companion_radio/*.cpp>
lib_deps =
${Waveshare_S3_LR1121.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:Waveshare_S3_LR1121_kiss_modem]
extends = Waveshare_S3_LR1121
build_src_filter = ${Waveshare_S3_LR1121.build_src_filter}
+<../examples/kiss_modem/>
@@ -0,0 +1,63 @@
#include <Arduino.h>
#include "target.h"
WaveshareS3LR1121Board board;
static SPIClass spi;
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);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifndef LORA_CR
#define LORA_CR 5
#endif
// DIO5/DIO6 drive the RTC6603SP sub-GHz T/R switch; the 2.4 GHz port (RFIO_HF) is unswitched
static const uint32_t rfswitch_dios[Module::RFSWITCH_MAX_PINS] = {
RADIOLIB_LR11X0_DIO5,
RADIOLIB_LR11X0_DIO6,
RADIOLIB_NC
};
static const Module::RfSwitchMode_t rfswitch_table[] = {
// mode DIO5 DIO6
{ LR11x0::MODE_STBY, {LOW, LOW}},
{ LR11x0::MODE_RX, {HIGH, LOW}},
{ LR11x0::MODE_TX, {LOW, HIGH}},
{ LR11x0::MODE_TX_HP, {LOW, HIGH}},
{ LR11x0::MODE_TX_HF, {LOW, LOW}},
{ LR11x0::MODE_GNSS, {LOW, LOW}},
{ LR11x0::MODE_WIFI, {LOW, LOW}},
END_OF_MODE_TABLE,
};
bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_LR11X0_LORA_SYNC_WORD_PRIVATE,
LORA_TX_POWER, 16, LR11X0_DIO3_TCXO_VOLTAGE);
if (status != RADIOLIB_ERR_NONE) {
Serial.print("ERROR: radio init failed: ");
Serial.println(status);
return false;
}
radio.setCRC(2);
radio.explicitHeader();
radio.setRfSwitchTable(rfswitch_dios, rfswitch_table);
#ifdef RX_BOOSTED_GAIN
radio.setRxBoostedGainMode(RX_BOOSTED_GAIN);
#endif
return true;
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng);
}
@@ -0,0 +1,17 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/radiolib/RadioLibWrappers.h>
#include <helpers/radiolib/CustomLR1121Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#include "WaveshareS3LR1121Board.h"
extern WaveshareS3LR1121Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
bool radio_init();
mesh::LocalIdentity radio_new_identity();