Browse Source

Merge be76ef041b into 03b6ef4b0d

pull/2999/merge
Fox_exe 2 days ago
committed by GitHub
parent
commit
84f2397f64
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 113
      src/helpers/radiolib/CustomLR1121.h
  2. 63
      src/helpers/radiolib/CustomLR1121Wrapper.h
  3. 63
      variants/ESP32_S3_Supermini/SuperminiBoard.h
  4. 219
      variants/ESP32_S3_Supermini/platformio.ini
  5. 47
      variants/ESP32_S3_Supermini/target.cpp
  6. 53
      variants/ESP32_S3_Supermini/target.h

113
src/helpers/radiolib/CustomLR1121.h

@ -0,0 +1,113 @@
#pragma once
#include <RadioLib.h>
#ifndef LR11X0_DIO3_TCXO_VOLTAGE
#define LR11X0_DIO3_TCXO_VOLTAGE 3.0
#endif
#ifndef LORA_CR
#define LORA_CR 5
#endif
class CustomLR1121 : public LR1121 {
private:
bool _rx_boosted = false;
public:
CustomLR1121(Module* mod) : LR1121(mod) {}
#ifdef RP2040_PLATFORM
bool std_init(SPIClassRP2040* spi = NULL)
#else
bool std_init(SPIClass* spi = NULL)
#endif
{
float tcxo = LR11X0_DIO3_TCXO_VOLTAGE;
uint8_t cr = LORA_CR;
#if defined(P_LORA_SCLK)
#ifdef NRF52_PLATFORM
if (spi) { spi->setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI); spi->begin(); }
#elif defined(RP2040_PLATFORM)
if (spi) {
spi->setMISO(P_LORA_MISO);
//spi->setCS(P_LORA_NSS); // Setting CS results in freeze
spi->setSCK(P_LORA_SCLK);
spi->setMOSI(P_LORA_MOSI);
spi->begin();
}
#else
if (spi) spi->begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
#endif
#endif
int status = begin(LORA_FREQ, LORA_BW, LORA_SF, cr, RADIOLIB_LR11X0_LORA_SYNC_WORD_PRIVATE, 10, 16, tcxo);
if (status != RADIOLIB_ERR_NONE) {
Serial.print("ERROR: radio init failed: ");
Serial.println(status);
return false; // fail
}
// Waveshare Core1121 (LR1121-HF) RFSwitch Table
static const uint32_t rfswitch_dio_pins[] = {
RADIOLIB_LR11X0_DIO5,
RADIOLIB_LR11X0_DIO6,
RADIOLIB_NC, // DIO7 NC
RADIOLIB_NC, // DIO8 NC
RADIOLIB_NC // DIO9 NC
};
static const Module::RfSwitchMode_t rfswitch_table[] = {
{ 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
};
setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
setCRC(2);
explicitHeader();
return true; // success
}
size_t getPacketLength(bool update) override {
size_t len = LR1121::getPacketLength(update);
if (len == 0 && getIrqStatus() & RADIOLIB_LR11X0_IRQ_HEADER_ERR) {
// we've just received a corrupted packet
// this may have triggered a bug causing subsequent packets to be shifted
// call standby() to return radio to known-good state
// recvRaw will call startReceive() to restart rx
MESH_DEBUG_PRINTLN("LR1121: got header err, calling standby()");
standby();
}
return len;
}
bool isReceiving() {
uint16_t irq = getIrqFlags();
bool detected = (irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID) || (irq & RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED);
return detected;
}
int16_t setRxBoostedGainMode(bool en) {
_rx_boosted = en;
return LR1121::setRxBoostedGainMode(en);
}
bool getRxBoostedGainMode() const {
return _rx_boosted;
}
int16_t getSpreadingFactor() const {
return spreadingFactor;
}
float getFreqMHz() const { return freqMHz; }
};

63
src/helpers/radiolib/CustomLR1121Wrapper.h

@ -0,0 +1,63 @@
#pragma once
#include "RadioLibWrappers.h"
#include "CustomLR1121.h"
#include "LR11x0Reset.h"
#ifndef USE_LR1121
#define USE_LR1121
#endif
class CustomLR1121Wrapper : public RadioLibWrapper {
public:
CustomLR1121Wrapper(CustomLR1121& radio, mesh::MainBoard& board) : RadioLibWrapper(radio, board) {}
void setParams(float freq, float bw, uint8_t sf, uint8_t cr) override {
((CustomLR1121*)_radio)->setFrequency(freq);
((CustomLR1121*)_radio)->setSpreadingFactor(sf);
((CustomLR1121*)_radio)->setBandwidth(bw);
((CustomLR1121*)_radio)->setCodingRate(cr);
updatePreamble(sf);
}
void doResetAGC() override {
lr11x0ResetAGC((LR11x0*)_radio, ((CustomLR1121*)_radio)->getFreqMHz());
}
bool isReceivingPacket() override {
return ((CustomLR1121*)_radio)->isReceiving();
}
float getCurrentRSSI() override {
float rssi = -110;
((CustomLR1121*)_radio)->getRssiInst(&rssi);
return rssi;
}
void onSendFinished() override {
RadioLibWrapper::onSendFinished();
((CustomLR1121*)_radio)->explicitHeader();
_radio->setPreambleLength(preambleLengthForSF(getSpreadingFactor()));
}
float getLastRSSI() const override {
return ((CustomLR1121*)_radio)->getRSSI();
}
float getLastSNR() const override {
return ((CustomLR1121*)_radio)->getSNR();
}
uint8_t getSpreadingFactor() const override {
return ((CustomLR1121*)_radio)->getSpreadingFactor();
}
void setRxBoostedGainMode(bool en) override {
((CustomLR1121*)_radio)->setRxBoostedGainMode(en);
}
bool getRxBoostedGainMode() const override {
return ((CustomLR1121*)_radio)->getRxBoostedGainMode();
}
};

63
variants/ESP32_S3_Supermini/SuperminiBoard.h

@ -0,0 +1,63 @@
#pragma once
#include <Arduino.h>
#include "target.h"
#include <MeshCore.h>
#include <helpers/ESP32Board.h>
#include <driver/rtc_io.h>
class SuperminiBoard : public ESP32Board {
private:
float adc_mult = ADC_MULTIPLIER;
public:
SuperminiBoard() {}
void begin() {
ESP32Board::begin();
pinMode(PIN_VBAT_READ, INPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
esp_reset_reason_t reason = esp_reset_reason();
if (reason == ESP_RST_DEEPSLEEP) {
long wakeup_source = esp_sleep_get_ext1_wakeup_status();
if (wakeup_source & (1 << P_LORA_DIO_1)) { // received a LoRa packet (while in deep sleep)
startup_reason = BD_STARTUP_RX_PACKET;
}
rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS);
rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1);
}
}
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1) {
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
if (pin_wake_btn < 0) {
esp_sleep_enable_ext1_wakeup((1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
}
else {
esp_sleep_enable_ext1_wakeup((1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
}
if (secs > 0) {
esp_sleep_enable_timer_wakeup(secs * 1000000);
}
esp_deep_sleep_start();
}
void powerOff() override {
enterDeepSleep(0);
}
const char* getManufacturerName() const override {
return "ESP32 Supermini";
}
};

219
variants/ESP32_S3_Supermini/platformio.ini

@ -0,0 +1,219 @@
[ESP32_S3_Supermini]
extends=esp32_base
board=esp32-s3-zero
board_build.partitions = huge_app.csv ; FW weight: ~1.7MB, but default partition is only ~1.3MB. Remove OTA and raise APP partition upto 3MB
;build_type = debug
;debug_tool = esp-builtin
monitor_echo = yes
;monitor_filters = esp32_exception_decoder
build_flags =
${esp32_base.build_flags}
${sensor_base.build_flags}
-I variants/ESP32_S3_Supermini
-D ESP32_CPU_FREQ=80
-D BOARD_HAS_PSRAM
; SPI-0 / LoRa (LR1121-HF)
-D PIN_SPI_MISO=11
-D PIN_SPI_MOSI=10
-D PIN_SPI_SCK=9
-D PIN_SPI_NSS=8
-D P_LORA_MISO=PIN_SPI_MISO
-D P_LORA_MOSI=PIN_SPI_MOSI
-D P_LORA_SCLK=PIN_SPI_SCK
-D P_LORA_NSS=PIN_SPI_NSS
-D P_LORA_DIO_1=1 ; IRQ
-D P_LORA_RESET=12
-D P_LORA_BUSY=13
-D LORA_TX_POWER=22 ; Max 14 for 2.4GHz or 22 for <900MHz
-D LR11X0_DIO3_TCXO_VOLTAGE=3.0
-D LR11X0_DIO_AS_RF_SWITCH=1
-D RX_BOOSTED_GAIN=1
; Wire/i2c
-D PIN_BOARD_SDA=4
-D PIN_BOARD_SCL=5
; 2nd wire for sensors
;-D ENV_PIN_SDA=4
;-D ENV_PIN_SCL=5
; Serial / UART (For GPS)
-D ENV_INCLUDE_GPS=0 ; Disable GPS support
;-D PIN_GPS_TX=6
;-D PIN_GPS_RX=7
;-D PIN_GPS_EN=-1
;-D GPS_BAUD_RATE=9600
;-D ENV_SKIP_GPS_DETECT
;-D FORCE_GPS_ALIVE
; Builtin LEDs
-D LED_PIN=48
-D LED_STATE_ON=0
-D PIN_LED=LED_PIN
-D LED_RED=LED_PIN
-D LED_BLUE=-1
; Button
-D PIN_BUTTON1=0
-D BUTTON_PIN=PIN_BUTTON1
-D PIN_USER_BTN=PIN_BUTTON1
; Battery ADC
-D PIN_VBAT_READ=16
-D ADC_MULTIPLIER=2.085 ; BAT- -> 1M -> ADC -> 1M -> BAT+
; SPI-1 / Display
-D PIN_SPI1_SCK=45
-D PIN_SPI1_MISO=47 ; NC
-D PIN_SPI1_MOSI=46
-D UI_RECENT_LIST_SIZE=4
;-D UI_SENSORS_PAGE=1
-D AUTO_OFF_MILLIS=0 ; Disable display off (eink wont need it)
-D BOOT_SCREEN_MILLIS=1000 ; Reduce boot time
-D DISPLAY_CLASS=GxEPDDisplay
-D EINK_DISPLAY_MODEL=GxEPD2_290_BS
-D EINK_LOGICAL_W=128
-D EINK_LOGICAL_H=296
-D EINK_SCALE_X=1.0f
-D EINK_SCALE_Y=1.0f
-D EINK_X_OFFSET=0
-D EINK_Y_OFFSET=0
-D PIN_DISPLAY_SCLK=PIN_SPI1_SCK
-D PIN_DISPLAY_MISO=PIN_SPI1_MISO
-D PIN_DISPLAY_MOSI=PIN_SPI1_MOSI
-D PIN_DISPLAY_CS=42
-D PIN_DISPLAY_DC=41
-D PIN_DISPLAY_RST=40
-D PIN_DISPLAY_BUSY=39
; Logging
-D DISABLE_DIAGNOSTIC_OUTPUT ; GxEPD2 debug off
;-D BLE_DEBUG_LOGGING=1
;-D MESH_PACKET_LOGGING=1
;-D MESH_DEBUG=1
;-D RADIOLIB_DEBUG_BASIC=1
;-D RADIOLIB_DEBUG_PROTOCOL=1
;-D RADIOLIB_DEBUG_SPI=0
;-D RADIOLIB_VERBOSE_ASSERT=1
;-D CORE_DEBUG_LEVEL=3
;-D ARDUINO_USB_CDC_ON_BOOT=1
;-D ARDUINO_USB_MODE=1
build_src_filter=${esp32_base.build_src_filter}
+<../variants/ESP32_S3_Supermini>
+<helpers/sensors>
; Display
+<helpers/ui/GxEPDDisplay.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
${esp32_base.lib_deps}
${sensor_base.lib_deps}
bakercp/CRC32
;densaugeo/base64
;end2endzone/NonBlockingRTTTL
;zinggjm/GxEPD2 ; ePaper displays drivers
GxEPD2
[env:ESP32_S3_Supermini_repeater]
extends=ESP32_S3_Supermini
build_flags =
${ESP32_S3_Supermini.build_flags}
-D ADVERT_NAME='"Meshcore Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
build_src_filter=${ESP32_S3_Supermini.build_src_filter}
+<../examples/simple_repeater>
lib_deps =
${ESP32_S3_Supermini.lib_deps}
${esp32_ota.lib_deps}
bakercp/CRC32 @ ^2.0.0
[env:ESP32_S3_Supermini_bridge_rs232]
extends=ESP32_S3_Supermini
build_flags =
${ESP32_S3_Supermini.build_flags}
-D ADVERT_NAME='"RS232 Bridge"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_RS232_BRIDGE=Serial2 ; TODO
-D WITH_RS232_BRIDGE_RX=5
-D WITH_RS232_BRIDGE_TX=6
build_src_filter=${ESP32_S3_Supermini.build_src_filter}
+<helpers/bridges/RS232Bridge.cpp>
+<../examples/simple_repeater>
lib_deps =
${ESP32_S3_Supermini.lib_deps}
${esp32_ota.lib_deps}
[env:ESP32_S3_Supermini_room_server]
extends=ESP32_S3_Supermini
build_flags =
${ESP32_S3_Supermini.build_flags}
-D ADVERT_NAME='"Room server"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
build_src_filter=${ESP32_S3_Supermini.build_src_filter}
+<../examples/simple_room_server>
lib_deps =
${ESP32_S3_Supermini.lib_deps}
${esp32_ota.lib_deps}
[env:ESP32_S3_Supermini_terminal_chat]
extends=ESP32_S3_Supermini
build_flags =
${ESP32_S3_Supermini.build_flags}
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=1
build_src_filter=${ESP32_S3_Supermini.build_src_filter}
+<../examples/simple_secure_chat/main.cpp>
lib_deps =
${ESP32_S3_Supermini.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:ESP32_S3_Supermini_sensor]
extends=ESP32_S3_Supermini
build_flags =
${ESP32_S3_Supermini.build_flags}
-D ADVERT_NAME='"Meshcore Sensor"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
build_src_filter=${ESP32_S3_Supermini.build_src_filter}
+<../examples/simple_sensor>
lib_deps =
${ESP32_S3_Supermini.lib_deps}
${esp32_ota.lib_deps}
[env:ESP32_S3_Supermini_companion_radio_uni]
extends=ESP32_S3_Supermini
build_flags =
${ESP32_S3_Supermini.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
-D WITH_COMPANION_CLI
-D WITH_WIFI_SWITCHING
build_src_filter=${ESP32_S3_Supermini.build_src_filter}
+<helpers/esp32/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
${ESP32_S3_Supermini.lib_deps}
densaugeo/base64 @ ~1.4.0

47
variants/ESP32_S3_Supermini/target.cpp

@ -0,0 +1,47 @@
#pragma once
#include "target.h"
static SPIClass spi(HSPI); // FSPI = SPI-1 (Display), HSPI = SPI-2 (LoRa)
CustomLR1121 radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
CustomLR1121Wrapper radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
GxEPDDisplay display;
// (pin, long_press_mills, reverse, pulldownup, multiclick)
MomentaryButton user_btn(PIN_USER_BTN, 1000, true, true, true);
#if ENV_INCLUDE_GPS
#include <helpers/sensors/MicroNMEALocationProvider.h>
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);
#else
EnvironmentSensorManager sensors;
#endif
SuperminiBoard board;
bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
bool result = radio.std_init(&spi);
if (result) {
#ifdef RX_BOOSTED_GAIN
radio.setRxBoostedGainMode(RX_BOOSTED_GAIN);
#endif
}
return result;
};
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
};

53
variants/ESP32_S3_Supermini/target.h

@ -0,0 +1,53 @@
#pragma once
/* ESP32-S3 Supermini + Waveshare Core1121 (LR1121-HF) + WeAct ePaper 2.9"
*
* _____[:::::]_____
* IN/OUT - 5v - | [] [] | - ?? - UART-0 Tx
* GND - | B+ B- | - ?? - UART-0 Rx
* OUT - 3.3v - | --- | - 01 - LORA_IRQ
* LORA_BUSY - 13 - | BOOST | - 02 -
* LORA_RESET - 12 - | | - 03 -
* LORA_MISO - 11 - | | - 04 - I2C_SDA
* LORA_MOSI - 10 - | | - 05 - I2C_SCL
* LORA_SCK - 09 - | | - 06 - GPS_Rx / Serial1_Tx
* LORA_CS - 08 - | | - 07 - GPS_Tx / Serial1_Rx
* *****************
*
* Additional pins on board:
*
* 34 38 LED - 48 NOTE: Regular LED and WS2818 RGB led IN at same pin!
* 33 37 EINK_MISO - 47
* 21 36 EINK_MOSI - 46
* 18 35 EINK_SCK - 45
* 17 EINK_CS - 42
* BAT_ADC - 16 EINK_DC - 41
* 15 EINK_RST - 40
* 14 EINK_BUSY - 39
*
*/
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/radiolib/CustomLR1121Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#include <helpers/sensors/EnvironmentSensorManager.h>
#include "SuperminiBoard.h"
// Display
#include <helpers/ui/GxEPDDisplay.h>
#include <helpers/ui/MomentaryButton.h>
extern GxEPDDisplay display;
extern MomentaryButton user_btn;
// Board
extern SuperminiBoard board;
extern AutoDiscoverRTCClock rtc_clock;
extern EnvironmentSensorManager sensors;
// Radio / LoRa module
extern CustomLR1121Wrapper radio_driver;
bool radio_init();
mesh::LocalIdentity radio_new_identity();
Loading…
Cancel
Save