Merge branch 'main' into main

This commit is contained in:
hank 2025-05-26 17:11:23 -07:00 committed by GitHub
commit 468ccf02cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
185 changed files with 14023 additions and 754 deletions

View file

@ -0,0 +1,68 @@
[Generic_E22]
extends = esp32_base
board = esp32doit-devkit-v1
build_flags =
${esp32_base.build_flags}
-I variants/generic-e22
-D GENERIC_E22
-D P_LORA_TX_LED=2
-D PIN_VBAT_READ=35
-D P_LORA_DIO_1=33
-D P_LORA_NSS=18
-D P_LORA_RESET=RADIOLIB_NC
-D P_LORA_BUSY=32
-D P_LORA_SCLK=5
-D P_LORA_MOSI=27
-D P_LORA_MISO=19
-D SX126X_TXEN=13
-D SX126X_RXEN=14
-D PIN_BOARD_SDA=21
-D PIN_BOARD_SCL=22
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=140
build_src_filter = ${esp32_base.build_src_filter}
+<../variants/generic-e22>
lib_deps =
${esp32_base.lib_deps}
adafruit/Adafruit SSD1306 @ ^2.5.13
[env:Generic_E22_sx1262_repeater]
extends = Generic_E22
build_src_filter = ${Generic_E22.build_src_filter}
+<../examples/simple_repeater/main.cpp>
build_flags =
${Generic_E22.build_flags}
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D ADVERT_NAME='"E22 Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
lib_deps =
${Generic_E22.lib_deps}
${esp32_ota.lib_deps}
[env:Generic_E22_sx1268_repeater]
extends = Generic_E22
build_src_filter = ${Generic_E22.build_src_filter}
+<../examples/simple_repeater/main.cpp>
build_flags =
${Generic_E22.build_flags}
-D RADIO_CLASS=CustomSX1268
-D WRAPPER_CLASS=CustomSX1268Wrapper
-D LORA_TX_POWER=22
-D ADVERT_NAME='"E22 Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
lib_deps =
${Generic_E22.lib_deps}
${esp32_ota.lib_deps}

View file

@ -0,0 +1,80 @@
#include <Arduino.h>
#include "target.h"
ESP32Board board;
#if defined(P_LORA_SCLK)
static SPIClass spi;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
#else
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
#endif
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifndef LORA_CR
#define LORA_CR 5
#endif
bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else
float tcxo = 1.6f;
#endif
#if defined(P_LORA_SCLK)
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
#endif
int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo);
if (status != RADIOLIB_ERR_NONE) {
Serial.print("ERROR: radio init failed: ");
Serial.println(status);
return false; // fail
}
radio.setCRC(1);
#if defined(SX126X_RXEN) && defined(SX126X_TXEN)
radio.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
#endif
#ifdef SX126X_CURRENT_LIMIT
radio.setCurrentLimit(SX126X_CURRENT_LIMIT);
#endif
#ifdef SX126X_DIO2_AS_RF_SWITCH
radio.setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH);
#endif
#ifdef SX126X_RX_BOOSTED_GAIN
radio.setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN);
#endif
return true; // success
}
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View file

@ -0,0 +1,21 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/ESP32Board.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/CustomSX1268Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
extern ESP32Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View file

@ -0,0 +1,44 @@
// For OLED LCD
#define I2C_SDA 21
#define I2C_SCL 22
// For GPS, 'undef's not needed
#define GPS_TX_PIN 15
#define GPS_RX_PIN 12
#define PIN_GPS_EN 4
#define GPS_POWER_TOGGLE // Moved definition from platformio.ini to here
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
#define ADC_MULTIPLIER 1.85 // (R1 = 470k, R2 = 680k)
#define EXT_PWR_DETECT 4 // Pin to detect connected external power source for LILYGO® TTGO T-Energy T18 and other DIY boards
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Module (#975).
#define LED_PIN 2 // add status LED (compatible with core-pcb and DIY targets)
// Radio
#define USE_SX1262 // E22-900M30S uses SX1262
#define USE_SX1268 // E22-400M30S uses SX1268
#define SX126X_MAX_POWER 22 // Outputting 22dBm from SX1262 results in ~30dBm E22-900M30S output (module only uses last stage of the YP2233W PA)
#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // E22 series TCXO reference voltage is 1.8V
#define SX126X_CS 18 // EBYTE module's NSS pin
#define SX126X_SCK 5 // EBYTE module's SCK pin
#define SX126X_MOSI 27 // EBYTE module's MOSI pin
#define SX126X_MISO 19 // EBYTE module's MISO pin
#define SX126X_RESET 23 // EBYTE module's NRST pin
#define SX126X_BUSY 32 // EBYTE module's BUSY pin
#define SX126X_DIO1 33 // EBYTE module's DIO1 pin
// The E22's TXEN pin is connected to MCU pin, E22's RXEN pin is connected to MCU pin (allows for ramping up PA before transmission
// Don't define DIO2_AS_RF_SWITCH because we only use DIO2 or an MCU pin mutually exclusively to connect to E22's TXEN (to prevent
// a short if they are both connected at the same time and there's a slight non-neglibible delay and/or voltage difference between
// DIO2 and TXEN).
#define SX126X_TXEN 13 // Schematic connects EBYTE module's TXEN pin to MCU
#define SX126X_RXEN 14 // Schematic connects EBYTE module's RXEN pin to MCU
#define LORA_CS SX126X_CS // Compatibility with variant file configuration structure
#define LORA_SCK SX126X_SCK // Compatibility with variant file configuration structure
#define LORA_MOSI SX126X_MOSI // Compatibility with variant file configuration structure
#define LORA_MISO SX126X_MISO // Compatibility with variant file configuration structure
#define LORA_DIO1 SX126X_DIO1 // Compatibility with variant file configuration structure

View file

@ -19,7 +19,7 @@ build_flags =
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${esp32_base.build_src_filter}
+<helpers/esp32/ESPNowRadio.cpp>
+<helpers/esp32/ESPNOWRadio.cpp>
+<../variants/generic_espnow>
[env:Generic_ESPNOW_terminal_chat]
@ -42,6 +42,7 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
build_src_filter = ${Generic_ESPNOW.build_src_filter}
+<../examples/simple_repeater/main.cpp>
lib_deps =

View file

@ -7,11 +7,13 @@ ESP32Board board;
ESPNOWRadio radio_driver;
ESP32RTCClock rtc_clock;
SensorManager sensors;
bool radio_init() {
rtc_clock.begin();
// NOTE: radio_driver.begin() is called by Dispatcher::begin(), so not needed here
radio_driver.init();
return true; // success
}
@ -27,7 +29,16 @@ void radio_set_tx_power(uint8_t dbm) {
radio_driver.setTxPower(dbm);
}
// NOTE: as we are using the WiFi radio, the ESP_IDF will have enabled hardware RNG:
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html
class ESP_RNG : public mesh::RNG {
public:
void random(uint8_t* dest, size_t sz) override {
esp_fill_random(dest, sz);
}
};
mesh::LocalIdentity radio_new_identity() {
StdRNG rng; // TODO: need stronger True-RNG here
ESP_RNG rng;
return mesh::LocalIdentity(&rng); // create new random identity
}

View file

@ -2,10 +2,12 @@
#include <helpers/ESP32Board.h>
#include <helpers/esp32/ESPNOWRadio.h>
#include <helpers/SensorManager.h>
extern ESP32Board board;
extern ESPNOWRadio radio_driver;
extern ESP32RTCClock rtc_clock;
extern SensorManager sensors;
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -0,0 +1,100 @@
[Heltec_tracker_base]
extends = esp32_base
board = esp32-s3-devkitc-1
build_flags =
${esp32_base.build_flags}
-I variants/heltec_tracker
-D HELTEC_LORA_V3
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D P_LORA_TX_LED=18
-D PIN_BOARD_SDA=45
-D PIN_BOARD_SCL=46
-D PIN_USER_BTN=0
-D PIN_ADC_CTRL=2
-D PIN_TFT_SDA=42 ; SDIN
-D PIN_TFT_SCL=41 ; SCLK
-D PIN_TFT_DC=40 ; RS (register select)
-D PIN_TFT_RST=39 ; RES
-D PIN_TFT_CS=38
-D USE_PIN_TFT=1
-D PIN_VEXT_EN=3 ; Vext is connected to VDD which is also connected to OLED & GPS
-D PIN_TFT_LEDA_CTL=21 ; LEDK (switches on/off via mosfet to create the ground)
-D PIN_GPS_RX=33
-D PIN_GPS_TX=34
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${esp32_base.build_src_filter}
+<../variants/heltec_tracker>
lib_deps =
${esp32_base.lib_deps}
stevemarple/MicroNMEA @ ^2.0.6
adafruit/Adafruit ST7735 and ST7789 Library @ ^1.11.0
[env:Heltec_Wireless_Tracker_companion_radio_ble]
extends = Heltec_tracker_base
build_flags =
${Heltec_tracker_base.build_flags}
-I src/helpers/ui
; -D ARDUINO_USB_CDC_ON_BOOT=1 ; need for debugging
-D DISPLAY_ROTATION=1
-D DISPLAY_CLASS=ST7735Display
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456 ; HWT will use display for pin
-D OFFLINE_QUEUE_SIZE=256
; -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Heltec_tracker_base.build_src_filter}
+<helpers/esp32/*.cpp>
+<../examples/companion_radio>
+<helpers/ui/ST7735Display.cpp>
lib_deps =
${Heltec_tracker_base.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:Heltec_Wireless_Tracker_repeater]
extends = Heltec_tracker_base
build_flags =
${Heltec_tracker_base.build_flags}
-D DISPLAY_ROTATION=1
-D DISPLAY_CLASS=ST7735Display
-D ADVERT_NAME='"Heltec Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Heltec_tracker_base.build_src_filter}
+<helpers/ui/ST7735Display.cpp>
+<../examples/simple_repeater>
lib_deps =
${Heltec_tracker_base.lib_deps}
${esp32_ota.lib_deps}
[env:Heltec_Wireless_Tracker_room_server]
extends = Heltec_tracker_base
build_flags =
${Heltec_tracker_base.build_flags}
-D DISPLAY_ROTATION=1
-D DISPLAY_CLASS=ST7735Display
-D ADVERT_NAME='"Heltec 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 = ${Heltec_tracker_base.build_src_filter}
+<helpers/ui/ST7735Display.cpp>
+<../examples/simple_room_server>
lib_deps =
${Heltec_tracker_base.lib_deps}
${esp32_ota.lib_deps}

View file

@ -0,0 +1,152 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/sensors/MicroNMEALocationProvider.h>
HeltecV3Board board;
#if defined(P_LORA_SCLK)
static SPIClass spi;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
#else
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
#endif
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
HWTSensorManager sensors = HWTSensorManager(nmea);
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display(&board.periph_power); // peripheral power pin is shared
#endif
#ifndef LORA_CR
#define LORA_CR 5
#endif
bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else
float tcxo = 1.6f;
#endif
#if defined(P_LORA_SCLK)
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
#endif
int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo);
if (status != RADIOLIB_ERR_NONE) {
Serial.print("ERROR: radio init failed: ");
Serial.println(status);
return false; // fail
}
radio.setCRC(1);
#ifdef SX126X_CURRENT_LIMIT
radio.setCurrentLimit(SX126X_CURRENT_LIMIT);
#endif
#ifdef SX126X_DIO2_AS_RF_SWITCH
radio.setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH);
#endif
#ifdef SX126X_RX_BOOSTED_GAIN
radio.setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN);
#endif
return true; // success
}
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}
void HWTSensorManager::start_gps() {
if (!gps_active) {
board.periph_power.claim();
gps_active = true;
Serial1.println("$CFGSYS,h35155*68");
}
}
void HWTSensorManager::stop_gps() {
if (gps_active) {
gps_active = false;
board.periph_power.release();
}
}
bool HWTSensorManager::begin() {
// init GPS port
Serial1.begin(115200, SERIAL_8N1, PIN_GPS_RX, PIN_GPS_TX);
return true;
}
bool HWTSensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) {
if (requester_permissions & TELEM_PERM_LOCATION) { // does requester have permission?
telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, node_altitude);
}
return true;
}
void HWTSensorManager::loop() {
static long next_gps_update = 0;
_location->loop();
if (millis() > next_gps_update) {
if (gps_active && _location->isValid()) {
node_lat = ((double)_location->getLatitude())/1000000.;
node_lon = ((double)_location->getLongitude())/1000000.;
node_altitude = ((double)_location->getAltitude()) / 1000.0;
MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon);
}
next_gps_update = millis() + 1000;
}
}
int HWTSensorManager::getNumSettings() const { return 1; } // just one supported: "gps" (power switch)
const char* HWTSensorManager::getSettingName(int i) const {
return i == 0 ? "gps" : NULL;
}
const char* HWTSensorManager::getSettingValue(int i) const {
if (i == 0) {
return gps_active ? "1" : "0";
}
return NULL;
}
bool HWTSensorManager::setSettingValue(const char* name, const char* value) {
if (strcmp(name, "gps") == 0) {
if (strcmp(value, "0") == 0) {
stop_gps();
} else {
start_gps();
}
return true;
}
return false; // not supported
}

View file

@ -0,0 +1,45 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/HeltecV3Board.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#include <helpers/sensors/LocationProvider.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/ST7735Display.h>
#endif
class HWTSensorManager : public SensorManager {
bool gps_active = false;
LocationProvider * _location;
void start_gps();
void stop_gps();
public:
HWTSensorManager(LocationProvider &location): _location(&location) { }
bool begin() override;
bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
void loop() override;
int getNumSettings() const override;
const char* getSettingName(int i) const override;
const char* getSettingValue(int i) const override;
bool setSettingValue(const char* name, const char* value) override;
};
extern HeltecV3Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern HWTSensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View file

@ -5,13 +5,14 @@ build_flags =
${esp32_base.build_flags}
-I variants/heltec_v2
-D HELTEC_LORA_V2
-D RADIO_CLASS=CustomSX1276
-D WRAPPER_CLASS=CustomSX1276Wrapper
-D SX127X_CURRENT_LIMIT=120
-D LORA_TX_POWER=20
-D PIN_BOARD_SDA=4
-D PIN_BOARD_SCL=15
-D PIN_USER_BTN=0
-D PIN_OLED_RESET=16
-D RADIO_CLASS=CustomSX1276
-D WRAPPER_CLASS=CustomSX1276Wrapper
-D LORA_TX_POWER=20
-D P_LORA_TX_LED=25
build_src_filter = ${esp32_base.build_src_filter}
+<../variants/heltec_v2>
@ -28,6 +29,7 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Heltec_lora32_v2.build_src_filter}
@ -96,6 +98,7 @@ build_flags =
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=0
-D BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1

View file

@ -14,6 +14,11 @@ WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5
@ -22,7 +27,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock);
bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#if defined(P_LORA_SCLK)
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
#endif
@ -33,8 +38,12 @@ bool radio_init() {
return false; // fail
}
#ifdef SX127X_CURRENT_LIMIT
radio.setCurrentLimit(SX127X_CURRENT_LIMIT);
#endif
radio.setCRC(1);
return true; // success
}

View file

@ -6,10 +6,19 @@
#include <helpers/HeltecV2Board.h>
#include <helpers/CustomSX1276Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306Display.h>
#endif
extern HeltecV2Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -12,9 +12,10 @@ build_flags =
-D PIN_BOARD_SDA=17
-D PIN_BOARD_SCL=18
-D PIN_USER_BTN=0
-D PIN_VEXT_EN=36
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=130.0f ; for best TX power!
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${esp32_base.build_src_filter}
+<../variants/heltec_v3>
@ -31,7 +32,8 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MESH_PACKET_LOGGING=1
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Heltec_lora32_v3.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
@ -100,6 +102,7 @@ build_flags =
-D DISPLAY_CLASS=SSD1306Display
-D BLE_PIN_CODE=0 ; dynamic, random PIN
-D BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1
@ -142,7 +145,8 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MESH_PACKET_LOGGING=1
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Heltec_lora32_v3.build_src_filter}
+<../examples/simple_repeater>
@ -175,6 +179,7 @@ build_flags =
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1

View file

@ -14,6 +14,11 @@ WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5

View file

@ -6,10 +6,19 @@
#include <helpers/HeltecV3Board.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306Display.h>
#endif
extern HeltecV3Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -21,7 +21,7 @@ build_flags =
-D PIN_OLED_RESET=21
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=130
-D SX126X_CURRENT_LIMIT=140
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
@ -42,6 +42,7 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${LilyGo_T3S3_sx1262.build_src_filter}
@ -111,6 +112,7 @@ build_flags =
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1

View file

@ -14,6 +14,11 @@ WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5

View file

@ -6,10 +6,19 @@
#include <helpers/ESP32Board.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306Display.h>
#endif
extern ESP32Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -7,6 +7,7 @@ build_flags =
-D LILYGO_TBEAM
-D RADIO_CLASS=CustomSX1276
-D WRAPPER_CLASS=CustomSX1276Wrapper
-D SX127X_CURRENT_LIMIT=120
-D LORA_TX_POWER=20
-D P_LORA_TX_LED=4
-D PIN_BOARD_SDA=21
@ -30,9 +31,8 @@ build_flags =
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D MESH_PACKET_LOGGING=1
-D MESH_DEBUG=1
-D RADIOLIB_DEBUG_BASIC=1
-D OFFLINE_QUEUE_SIZE=256
; -D RADIOLIB_DEBUG_BASIC=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1
@ -54,7 +54,8 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MESH_PACKET_LOGGING=1
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${LilyGo_TBeam.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>

View file

@ -39,6 +39,11 @@ WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
static void setPMUIntFlag(){
pmuIntFlag = true;
@ -157,7 +162,7 @@ bool TBeamBoard::power_init()
bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#if defined(P_LORA_SCLK)
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
#endif
@ -168,10 +173,12 @@ bool radio_init() {
return false; // fail
}
#ifdef SX127X_CURRENT_LIMIT
radio.setCurrentLimit(SX127X_CURRENT_LIMIT);
#endif
radio.setCRC(1);
return true; // success
}

View file

@ -6,10 +6,19 @@
#include <helpers/TBeamBoard.h>
#include <helpers/CustomSX1276Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306Display.h>
#endif
extern TBeamBoard board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -0,0 +1,70 @@
[LilyGo_TBeam_SX1262]
extends = esp32_base
board = ttgo-t-beam
build_flags =
${esp32_base.build_flags}
-I variants/lilygo_tbeam_SX1262
-D LILYGO_TBEAM_SX1262
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D P_LORA_TX_LED=4
-D PIN_BOARD_SDA=21
-D PIN_BOARD_SCL=22
-D PIN_USER_BTN=38
build_src_filter = ${esp32_base.build_src_filter}
+<../variants/lilygo_tbeam_SX1262>
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
lib_deps =
${esp32_base.lib_deps}
lewisxhe/XPowersLib@^0.2.7
adafruit/Adafruit SSD1306 @ ^2.5.13
[env:Tbeam_SX1262_companion_radio_ble]
extends = LilyGo_TBeam_SX1262
board_build.upload.maximum_ram_size=2000000
build_flags =
${LilyGo_TBeam_SX1262.build_flags}
-D DISPLAY_CLASS=SSD1306Display
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D OFFLINE_QUEUE_SIZE=256
; -D BLE_DEBUG_LOGGING=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
; -D RADIOLIB_DEBUG_BASIC=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${LilyGo_TBeam_SX1262.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/ui/SSD1306Display.cpp>
+<../examples/companion_radio>
lib_deps =
${LilyGo_TBeam_SX1262.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:Tbeam_SX1262_repeater]
extends = LilyGo_TBeam_SX1262
build_flags =
${LilyGo_TBeam_SX1262.build_flags}
-D DISPLAY_CLASS=SSD1306Display
-D ADVERT_NAME='"Tbeam SX1262 Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${LilyGo_TBeam_SX1262.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<../examples/simple_repeater>
lib_deps =
${LilyGo_TBeam_SX1262.lib_deps}
${esp32_ota.lib_deps}

View file

@ -0,0 +1,70 @@
#include <Arduino.h>
#include "target.h"
TBeamBoardSX1262 board;
#if defined(P_LORA_SCLK)
static SPIClass spi;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
#else
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
#endif
WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5
#endif
bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else
float tcxo = 1.6f;
#endif
#if defined(P_LORA_SCLK)
spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
#endif
int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo);
if (status != RADIOLIB_ERR_NONE) {
Serial.print("ERROR: radio init failed: ");
Serial.println(status);
return false; // fail
}
radio.setCRC(1);
return true; // success
}
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View file

@ -0,0 +1,27 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/TBeamBoardSX1262.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306Display.h>
#endif
extern TBeamBoardSX1262 board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View file

@ -5,18 +5,22 @@ build_flags =
${esp32_base.build_flags}
-I variants/lilygo_tbeam_supreme_SX1262
-D LORA_TX_POWER=22
-D P_LORA_TX_LED=6
-D PIN_BOARD_SDA=17
-D PIN_BOARD_SCL=18
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
;-D DISPLAY_CLASS=SSD1306Display ;Needs to be modified for SH1106
-D SX126X_RX_BOOSTED_GAIN=1
-D SX126X_CURRENT_LIMIT=140
build_src_filter = ${esp32_base.build_src_filter}
+<../variants/lilygo_tbeam_supreme_SX1262>
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
lib_deps =
${esp32_base.lib_deps}
lewisxhe/PCF8563_Library@^1.0.1
lewisxhe/XPowersLib @ ^0.2.7
;adafruit/Adafruit SSD1306 @ ^2.5.13
stevemarple/MicroNMEA @ ^2.0.6
; === LILYGO T-Beam S3 Supreme with SX1262 environments ===
[env:T_Beam_S3_Supreme_SX1262_repeater]
@ -27,6 +31,7 @@ build_flags =
-D ADVERT_LAT=0
-D ADVERT_LON=0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${T_Beam_S3_Supreme_SX1262.build_src_filter}
@ -57,16 +62,17 @@ extends = T_Beam_S3_Supreme_SX1262
build_flags =
${T_Beam_S3_Supreme_SX1262.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
-D MESH_PACKET_LOGGING=8
-D MESH_DEBUG=1
; -D MESH_PACKET_LOGGING=8
; -D MESH_DEBUG=1
build_src_filter = ${T_Beam_S3_Supreme_SX1262.build_src_filter}
+<helpers/esp32/*.cpp>
+<../examples/companion_radio>
lib_deps =
${T_Beam_S3_Supreme_SX1262.lib_deps}
densaugeo/base64 @ ~1.4.0
densaugeo/base64 @ ~1.4.0

View file

@ -1,11 +1,9 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/sensors/MicroNMEALocationProvider.h>
TBeamS3SupremeBoard board;
// Using PMU AXP2102
XPowersAXP2101 PMU;
bool pmuIntFlag;
#ifndef LORA_CR
@ -23,114 +21,273 @@ WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
TbeamSupSensorManager sensors = TbeamSupSensorManager(nmea);
static void setPMUIntFlag(){
pmuIntFlag = true;
}
bool power_init() {
//Start up Wire1 with PMU address
//Serial.println("Starting Wire1 for PMU");
//Wire1.begin(I2C_PMU_ADD);
//Wire1.begin(PIN_BOARD_SDA1,PIN_BOARD_SCL1);
//Set LED to indicate charge state
Serial.println("Setting charge led");
PMU.setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
//Set up PMU interrupts
Serial.println("Setting up PMU interrupts");
pinMode(PIN_PMU_IRQ,INPUT_PULLUP);
attachInterrupt(PIN_PMU_IRQ,setPMUIntFlag,FALLING);
#ifdef MESH_DEBUG
uint32_t deviceOnline = 0x00;
void scanDevices(TwoWire *w)
{
uint8_t err, addr;
int nDevices = 0;
uint32_t start = 0;
//GPS
Serial.println("Setting and enabling a-ldo4 for GPS");
PMU.setALDO4Voltage(3300);
PMU.enableALDO4(); //disable to save power
//Lora
Serial.println("Setting and enabling a-ldo3 for LoRa");
PMU.setALDO3Voltage(3300);
PMU.enableALDO3();
Serial.println("Scanning I2C for Devices");
for (addr = 1; addr < 127; addr++) {
start = millis();
w->beginTransmission(addr); delay(2);
err = w->endTransmission();
if (err == 0) {
nDevices++;
switch (addr) {
case 0x77:
case 0x76:
Serial.println("\tFound BMX280 Sensor");
deviceOnline |= BME280_ONLINE;
break;
case 0x34:
Serial.println("\tFound AXP192/AXP2101 PMU");
deviceOnline |= POWERMANAGE_ONLINE;
break;
case 0x3C:
Serial.println("\tFound SSD1306/SH1106 dispaly");
deviceOnline |= DISPLAY_ONLINE;
break;
case 0x51:
Serial.println("\tFound PCF8563 RTC");
deviceOnline |= PCF8563_ONLINE;
break;
case 0x1C:
Serial.println("\tFound QMC6310 MAG Sensor");
deviceOnline |= QMC6310_ONLINE;
break;
default:
Serial.print("\tI2C device found at address 0x");
if (addr < 16) {
Serial.print("0");
}
Serial.print(addr, HEX);
Serial.println(" !");
break;
}
//To avoid SPI bus issues during power up, reset OLED, sensor, and SD card supplies
Serial.println("Reset a-ldo1&2 and b-ldo1");
if(ESP_SLEEP_WAKEUP_UNDEFINED == esp_sleep_get_wakeup_cause()){
PMU.enableALDO1();
PMU.enableALDO2();
PMU.enableBLDO1();
delay(250);
} else if (err == 4) {
Serial.print("Unknow error at address 0x");
if (addr < 16) {
Serial.print("0");
}
Serial.println(addr, HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
Serial.println("Scan for devices is complete.");
Serial.println("\n");
}
void TBeamS3SupremeBoard::printPMU()
{
Serial.print("isCharging:"); Serial.println(PMU.isCharging() ? "YES" : "NO");
Serial.print("isDischarge:"); Serial.println(PMU.isDischarge() ? "YES" : "NO");
Serial.print("isVbusIn:"); Serial.println(PMU.isVbusIn() ? "YES" : "NO");
Serial.print("getBattVoltage:"); Serial.print(PMU.getBattVoltage()); Serial.println("mV");
Serial.print("getVbusVoltage:"); Serial.print(PMU.getVbusVoltage()); Serial.println("mV");
Serial.print("getSystemVoltage:"); Serial.print(PMU.getSystemVoltage()); Serial.println("mV");
// The battery percentage may be inaccurate at first use, the PMU will automatically
// learn the battery curve and will automatically calibrate the battery percentage
// after a charge and discharge cycle
if (PMU.isBatteryConnect()) {
Serial.print("getBatteryPercent:"); Serial.print(PMU.getBatteryPercent()); Serial.println("%");
}
Serial.println();
}
#endif
bool TBeamS3SupremeBoard::power_init()
{
bool result = PMU.begin(PMU_WIRE_PORT, I2C_PMU_ADD, PIN_BOARD_SDA1, PIN_BOARD_SCL1);
if (result == false) {
MESH_DEBUG_PRINTLN("power is not online..."); while (1)delay(50);
}
//BME280 and OLED
Serial.println("Setting and enabling a-ldo1 for oled");
MESH_DEBUG_PRINTLN("Setting charge led");
PMU.setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
// Set up PMU interrupts
// MESH_DEBUG_PRINTLN("Setting up PMU interrupts");
// pinMode(PIN_PMU_IRQ, INPUT_PULLUP);
// attachInterrupt(PIN_PMU_IRQ, setPMUIntFlag, FALLING);
// GPS
MESH_DEBUG_PRINTLN("Setting and enabling a-ldo4 for GPS");
PMU.setALDO4Voltage(3300);
PMU.enableALDO4(); // disable to save power
// Lora
MESH_DEBUG_PRINTLN("Setting and enabling a-ldo3 for LoRa");
PMU.setALDO3Voltage(3300);
PMU.enableALDO3();
// To avoid SPI bus issues during power up, reset OLED, sensor, and SD card supplies
// MESH_DEBUG_PRINTLN("Reset a-ldo1&2 and b-ldo1");
// if (ESP_SLEEP_WAKEUP_UNDEFINED == esp_sleep_get_wakeup_cause())
// {
// PMU.disableALDO1();
// PMU.disableALDO2();
// PMU.disableBLDO1();
// delay(250);
// }
// m.2 interface
MESH_DEBUG_PRINTLN("Setting and enabling dcdc3 for m.2 interface");
PMU.setDC3Voltage(3300); // doesn't go anywhere in the schematic??
PMU.enableDC3();
// QMC6310U
MESH_DEBUG_PRINTLN("Setting and enabling a-ldo2 for QMC");
PMU.setALDO2Voltage(3300);
PMU.enableALDO2(); // disable to save power
// BME280 and OLED
MESH_DEBUG_PRINTLN("Setting and enabling a-ldo1 for oled");
PMU.setALDO1Voltage(3300);
PMU.enableALDO1();
//QMC6310U
Serial.println("Setting and enabling a-ldo2 for QMC");
PMU.setALDO2Voltage(3300);
PMU.enableALDO2(); //disable to save power
//SD card
Serial.println("Setting and enabling b-ldo2 for SD card");
// SD card
MESH_DEBUG_PRINTLN("Setting and enabling b-ldo2 for SD card");
PMU.setBLDO1Voltage(3300);
PMU.enableBLDO1();
//Out to header pins
Serial.println("Setting and enabling b-ldo2 for output to header");
PMU.setBLDO2Voltage(3300);
PMU.enableBLDO2();
// Out to header pins
// MESH_DEBUG_PRINTLN("Setting and enabling b-ldo2 for output to header");
// PMU.setBLDO2Voltage(3300);
// PMU.enableBLDO2();
Serial.println("Setting and enabling dcdc4 for output to header");
PMU.setDC4Voltage(XPOWERS_AXP2101_DCDC4_VOL2_MAX); //1.8V
PMU.enableDC4();
// MESH_DEBUG_PRINTLN("Setting and enabling dcdc4 for output to header");
// PMU.setDC4Voltage(XPOWERS_AXP2101_DCDC4_VOL2_MAX); // 1.8V
// PMU.enableDC4();
Serial.println("Setting and enabling dcdc5 for output to header");
PMU.setDC5Voltage(3300);
PMU.enableDC5();
// MESH_DEBUG_PRINTLN("Setting and enabling dcdc5 for output to header");
// PMU.setDC5Voltage(3300);
// PMU.enableDC5();
//Other power rails
Serial.println("Setting and enabling dcdc3 for ?");
PMU.setDC3Voltage(3300); //doesn't go anywhere in the schematic??
PMU.enableDC3();
//Unused power rails
Serial.println("Disabling unused supplies dcdc2, dldo1 and dldo2");
// Unused power rails
MESH_DEBUG_PRINTLN("Disabling unused supplies dcdc2, dldo1 and dldo2");
PMU.disableDC2();
PMU.disableDC5();
PMU.disableDLDO1();
PMU.disableDLDO2();
PMU.disableDLDO2();
//Set charge current to 300mA
Serial.println("Setting battery charge current limit and voltage");
PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_300MA);
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
// Set charge current to 500mA
MESH_DEBUG_PRINTLN("Setting battery charge current limit and voltage");
PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA);
PMU.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
//enable battery voltage measurement
Serial.println("Enabling battery measurement");
PMU.enableBattVoltageMeasure();
//Reset and re-enable PMU interrupts
Serial.println("Re-enable interrupts");
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
PMU.clearIrqStatus();
PMU.enableIRQ(
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //Battery interrupts
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS interrupts
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //Power Key interrupts
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ //Charging interrupts
);
PMU.disableTSPinMeasure();
//Set the power key off press time
// enable battery voltage measurement
MESH_DEBUG_PRINTLN("Enabling battery measurement");
PMU.enableBattVoltageMeasure();
PMU.enableVbusVoltageMeasure();
// Reset and re-enable PMU interrupts
// MESH_DEBUG_PRINTLN("Re-enable interrupts");
// PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
// PMU.clearIrqStatus();
// PMU.enableIRQ(
// XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | // Battery interrupts
// XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | // VBUS interrupts
// XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | // Power Key interrupts
// XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ // Charging interrupts
// );
#ifdef MESH_DEBUG
// scanDevices(&Wire);
// scanDevices(&Wire1);
printPMU();
#endif
// Set the power key off press time
PMU.setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
return true;
}
static bool readStringUntil(Stream& s, char dest[], size_t max_len, char term, unsigned int timeout_millis) {
unsigned long timeout = millis() + timeout_millis;
char *dp = dest;
while (millis() < timeout && dp - dest < max_len - 1) {
if (s.available()) {
char c = s.read();
if (c == term) break;
*dp++ = c; // append to dest[]
} else {
delay(1);
}
}
*dp = 0; // null terminator
return millis() < timeout; // false, if timed out
}
static bool l76kProbe()
{
bool result = false;
uint32_t startTimeout ;
Serial1.write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
delay(5);
// Get version information
startTimeout = millis() + 3000;
MESH_DEBUG_PRINTLN("Trying to init L76K GPS");
// Serial1.flush();
while (Serial1.available()) {
int c = Serial1.read();
// Serial.write(c);
// Serial.print(".");
// Serial.flush();
// Serial1.flush();
if (millis() > startTimeout) {
MESH_DEBUG_PRINTLN("L76K NMEA timeout!");
return false;
}
};
Serial1.flush();
delay(200);
Serial1.write("$PCAS06,0*1B\r\n");
char ver[100];
if (!readStringUntil(Serial1, ver, sizeof(ver), '\n', 500)) {
MESH_DEBUG_PRINTLN("Get L76K timeout!");
return false;
}
if (memcmp(ver, "$GPTXT,01,01,02", 15) == 0) {
MESH_DEBUG_PRINTLN("L76K GNSS init succeeded, using L76K GNSS Module\n");
result = true;
}
delay(500);
// Initialize the L76K Chip, use GPS + GLONASS
Serial1.write("$PCAS04,5*1C\r\n");
delay(250);
// only ask for RMC and GGA
Serial1.write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
delay(250);
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
Serial1.write("$PCAS11,3*1E\r\n");
return result;
}
bool radio_init() {
fallback_clock.begin();
Wire1.begin(PIN_BOARD_SDA1,PIN_BOARD_SCL1);
rtc_clock.begin(Wire1);
#ifdef SX126X_DIO3_TCXO_VOLTAGE
@ -154,13 +311,6 @@ bool radio_init() {
return true; // success
}
uint16_t getBattPercent() {
//Read the PMU fuel guage for battery %
uint16_t battPercent = PMU.getBatteryPercent();
return battPercent;
}
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
@ -176,6 +326,83 @@ void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
void TbeamSupSensorManager::start_gps()
{
gps_active = true;
pinMode(P_GPS_WAKE, OUTPUT);
digitalWrite(P_GPS_WAKE, HIGH);
}
void TbeamSupSensorManager::sleep_gps() {
gps_active = false;
pinMode(P_GPS_WAKE, OUTPUT);
digitalWrite(P_GPS_WAKE, LOW);
}
bool TbeamSupSensorManager::begin() {
// init GPS port
Serial1.begin(GPS_BAUD_RATE, SERIAL_8N1, P_GPS_RX, P_GPS_TX);
bool result = false;
for ( int i = 0; i < 3; ++i) {
result = l76kProbe();
if (result) {
gps_active = true;
return result;
}
}
return result;
}
bool TbeamSupSensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) {
if (requester_permissions & TELEM_PERM_LOCATION) { // does requester have permission?
telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, node_altitude);
}
return true;
}
void TbeamSupSensorManager::loop() {
static long next_gps_update = 0;
_nmea->loop();
if (millis() > next_gps_update) {
if (_nmea->isValid()) {
node_lat = ((double)_nmea->getLatitude())/1000000.;
node_lon = ((double)_nmea->getLongitude())/1000000.;
node_altitude = ((double)_nmea->getAltitude()) / 1000.0;
//Serial.printf("lat %f lon %f\r\n", _lat, _lon);
}
next_gps_update = millis() + 1000;
}
}
int TbeamSupSensorManager::getNumSettings() const { return 1; } // just one supported: "gps" (power switch)
const char* TbeamSupSensorManager::getSettingName(int i) const {
return i == 0 ? "gps" : NULL;
}
const char* TbeamSupSensorManager::getSettingValue(int i) const {
if (i == 0) {
return gps_active ? "1" : "0";
}
return NULL;
}
bool TbeamSupSensorManager::setSettingValue(const char* name, const char* value) {
if (strcmp(name, "gps") == 0) {
if (strcmp(value, "0") == 0) {
sleep_gps();
} else {
start_gps();
}
return true;
}
return false; // not supported
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity

View file

@ -1,15 +1,54 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/TBeamS3SupremeBoard.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#include <helpers/sensors/LocationProvider.h>
class TbeamSupSensorManager: public SensorManager {
bool gps_active = false;
LocationProvider * _nmea;
void start_gps();
void sleep_gps();
public:
TbeamSupSensorManager(LocationProvider &nmea): _nmea(&nmea) { }
bool begin() override;
bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
void loop() override;
int getNumSettings() const override;
const char* getSettingName(int i) const override;
const char* getSettingValue(int i) const override;
bool setSettingValue(const char* name, const char* value) override;
};
extern TBeamS3SupremeBoard board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern TbeamSupSensorManager sensors;
enum {
POWERMANAGE_ONLINE = _BV(0),
DISPLAY_ONLINE = _BV(1),
RADIO_ONLINE = _BV(2),
GPS_ONLINE = _BV(3),
PSRAM_ONLINE = _BV(4),
SDCARD_ONLINE = _BV(5),
AXDL345_ONLINE = _BV(6),
BME280_ONLINE = _BV(7),
BMP280_ONLINE = _BV(8),
BME680_ONLINE = _BV(9),
QMC6310_ONLINE = _BV(10),
QMI8658_ONLINE = _BV(11),
PCF8563_ONLINE = _BV(12),
OSC32768_ONLINE = _BV(13),
};
bool power_init();
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);

View file

@ -19,10 +19,11 @@ build_flags =
-D P_LORA_TX_LED=2 ; LED pin for TX indication
-D PIN_VBAT_READ=35 ; Battery voltage reading (analog pin)
-D PIN_USER_BTN=0
-D RADIO_CLASS=CustomSX1276
-D ARDUINO_LOOP_STACK_SIZE=16384
-D DISPLAY_CLASS=SSD1306Display
-D RADIO_CLASS=CustomSX1276
-D WRAPPER_CLASS=CustomSX1276Wrapper
-D SX127X_CURRENT_LIMIT=120
-D LORA_TX_POWER=20
build_src_filter = ${esp32_base.build_src_filter}
+<../variants/lilygo_tlora_v2_1>
@ -42,6 +43,7 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
; -D CORE_DEBUG_LEVEL=3
@ -88,6 +90,7 @@ build_flags =
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D OFFLINE_QUEUE_SIZE=256
; -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1

View file

@ -10,6 +10,11 @@ WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5
@ -18,7 +23,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock);
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_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8);
if (status != RADIOLIB_ERR_NONE) {
@ -27,8 +32,12 @@ bool radio_init() {
return false; // fail
}
#ifdef SX127X_CURRENT_LIMIT
radio.setCurrentLimit(SX127X_CURRENT_LIMIT);
#endif
radio.setCRC(1);
return true; // success
}

View file

@ -6,10 +6,19 @@
#include <helpers/LilyGoTLoraBoard.h>
#include <helpers/CustomSX1276Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306Display.h>
#endif
extern LilyGoTLoraBoard board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -0,0 +1,102 @@
#include <Arduino.h>
#include "nano-g2.h"
#ifdef NANO_G2_ULTRA
#include <bluefruit.h>
#include <Wire.h>
static BLEDfu bledfu;
static void connect_callback(uint16_t conn_handle)
{
(void)conn_handle;
MESH_DEBUG_PRINTLN("BLE client connected");
}
static void disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
(void)conn_handle;
(void)reason;
MESH_DEBUG_PRINTLN("BLE client disconnected");
}
void NanoG2Ultra::begin()
{
// for future use, sub-classes SHOULD call this from their begin()
startup_reason = BD_STARTUP_NORMAL;
// set user button
pinMode(PIN_BUTTON1, INPUT);
// the external notification circuit is shared for both buzzer and led
pinMode(EXT_NOTIFY_OUT, OUTPUT);
digitalWrite(EXT_NOTIFY_OUT, LOW);
Wire.begin();
pinMode(SX126X_POWER_EN, OUTPUT);
digitalWrite(SX126X_POWER_EN, HIGH);
delay(10);
}
uint16_t NanoG2Ultra::getBattMilliVolts()
{
int adcvalue = 0;
analogReference(AR_INTERNAL_3_0);
analogReadResolution(12);
delay(10);
// ADC range is 0..3000mV and resolution is 12-bit (0..4095)
adcvalue = analogRead(PIN_VBAT_READ);
// Convert the raw value to compensated mv, taking the resistor-
// divider into account (providing the actual LIPO voltage)
return (uint16_t)((float)adcvalue * REAL_VBAT_MV_PER_LSB);
}
bool NanoG2Ultra::startOTAUpdate(const char *id, char reply[])
{
// Config the peripheral connection with maximum bandwidth
// more SRAM required by SoftDevice
// Note: All config***() function must be called before begin()
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
Bluefruit.configPrphConn(92, BLE_GAP_EVENT_LENGTH_MIN, 16, 16);
Bluefruit.begin(1, 0);
// Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4
Bluefruit.setTxPower(4);
// Set the BLE device name
Bluefruit.setName("TECHO_OTA");
Bluefruit.Periph.setConnectCallback(connect_callback);
Bluefruit.Periph.setDisconnectCallback(disconnect_callback);
// To be consistent OTA DFU should be added first if it exists
bledfu.begin();
// Set up and start advertising
// Advertising packet
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
Bluefruit.Advertising.addName();
/* Start Advertising
- Enable auto advertising if disconnected
- Interval: fast mode = 20 ms, slow mode = 152.5 ms
- Timeout for fast mode is 30 seconds
- Start(timeout) with timeout = 0 will advertise forever (until connected)
For recommended advertising interval
https://developer.apple.com/library/content/qa/qa1931/_index.html
*/
Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
strcpy(reply, "OK - started");
return true;
}
#endif

View file

@ -0,0 +1,57 @@
#pragma once
#include <MeshCore.h>
#include <Arduino.h>
// LoRa radio module pins
#define P_LORA_DIO_1 (32 + 10)
#define P_LORA_NSS (32 + 13)
#define P_LORA_RESET (32 + 15)
#define P_LORA_BUSY (32 + 11)
#define P_LORA_SCLK (0 + 12)
#define P_LORA_MISO (32 + 9)
#define P_LORA_MOSI (0 + 11)
#define SX126X_DIO2_AS_RF_SWITCH true
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define SX126X_POWER_EN 37
// buttons
#define PIN_BUTTON1 (32 + 6)
#define BUTTON_PIN PIN_BUTTON1
#define PIN_USER_BTN BUTTON_PIN
// built-ins
#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
#define VBAT_DIVIDER (0.5F) // 150K + 150K voltage divider on VBAT, actually 100K + 100K
#define VBAT_DIVIDER_COMP (2.0F) // Compensation factor for the VBAT divider
#define PIN_VBAT_READ (0 + 2)
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
class NanoG2Ultra : public mesh::MainBoard
{
protected:
uint8_t startup_reason;
public:
void begin();
uint16_t getBattMilliVolts() override;
bool startOTAUpdate(const char *id, char reply[]) override;
uint8_t getStartupReason() const override
{
return startup_reason;
}
const char *getManufacturerName() const override
{
return "Nano G2 Ultra";
}
void reboot() override
{
NVIC_SystemReset();
}
};

View file

@ -0,0 +1,59 @@
[nrf52840_g2_ultra]
extends = nrf52_base
platform_packages = framework-arduinoadafruitnrf52
build_flags = ${nrf52_base.build_flags}
-I src/helpers/nrf52
-I lib/nrf52/s140_nrf52_6.1.1_API/include
-I lib/nrf52/s140_nrf52_6.1.1_API/include/nrf52
lib_deps =
${nrf52_base.lib_deps}
rweather/Crypto @ ^0.4.0
lewisxhe/PCF8563_Library@^1.0.1
[Nano_G2_Ultra]
extends = nrf52840_g2_ultra
board = nano-g2-ultra
board_build.ldscript = boards/nrf52840_s140_v6.ld
build_flags = ${nrf52840_g2_ultra.build_flags}
-I variants/nano_g2_ultra
-D NANO_G2_ULTRA
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D PIN_USER_BTN=38
build_src_filter = ${nrf52840_g2_ultra.build_src_filter}
+<helpers/*.cpp>
+<../variants/nano_g2_ultra>
debug_tool = jlink
upload_protocol = nrfutil
[env:Nano_G2_Ultra_companion_radio_ble]
extends = Nano_G2_Ultra
build_flags =
${Nano_G2_Ultra.build_flags}
-I src/helpers/ui
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=0
-D BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
-D DISPLAY_CLASS=SH1106Display
-D PIN_BUZZER=4
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Nano_G2_Ultra.build_src_filter}
+<helpers/nrf52/SerialBLEInterface.cpp>
+<helpers/ui/SH1106Display.cpp>
+<helpers/ui/buzzer.cpp>
+<../examples/companion_radio>
lib_deps =
${Nano_G2_Ultra.lib_deps}
densaugeo/base64 @ ~1.4.0
adafruit/Adafruit SH110X @ ~2.1.13
adafruit/Adafruit GFX Library @ ^1.12.1
stevemarple/MicroNMEA @ ^2.0.6
end2endzone/NonBlockingRTTTL@^1.3.0

View file

@ -0,0 +1,183 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/ArduinoHelpers.h>
#include <helpers/sensors/MicroNMEALocationProvider.h>
NanoG2Ultra 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);
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
NanoG2UltraSensorManager sensors = NanoG2UltraSensorManager(nmea);
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5
#endif
bool radio_init()
{
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else
float tcxo = 1.6f;
#endif
SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI);
SPI.begin();
int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo);
if (status != RADIOLIB_ERR_NONE)
{
Serial.print("ERROR: radio init failed: ");
Serial.println(status);
return false; // fail
}
radio.setCRC(1);
#ifdef SX126X_CURRENT_LIMIT
radio.setCurrentLimit(SX126X_CURRENT_LIMIT);
#endif
#ifdef SX126X_DIO2_AS_RF_SWITCH
radio.setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH);
#endif
#ifdef SX126X_RX_BOOSTED_GAIN
radio.setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN);
#endif
return true; // success
}
uint32_t radio_get_rng_seed()
{
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr)
{
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm)
{
radio.setOutputPower(dbm);
}
void NanoG2UltraSensorManager::start_gps()
{
if (!gps_active)
{
MESH_DEBUG_PRINTLN("starting GPS");
digitalWrite(PIN_GPS_STANDBY, HIGH);
gps_active = true;
}
}
void NanoG2UltraSensorManager::stop_gps()
{
if (gps_active)
{
MESH_DEBUG_PRINTLN("stopping GPS");
digitalWrite(PIN_GPS_STANDBY, LOW);
gps_active = false;
}
}
bool NanoG2UltraSensorManager::begin()
{
Serial1.setPins(PIN_GPS_TX, PIN_GPS_RX); // be sure to tx into rx and rx into tx
Serial1.begin(115200);
pinMode(PIN_GPS_STANDBY, OUTPUT);
digitalWrite(PIN_GPS_STANDBY, HIGH); // Wake GPS from standby
delay(500);
// We'll consider GPS detected if we see any data on Serial1
if (Serial1.available() > 0)
{
MESH_DEBUG_PRINTLN("GPS detected");
}
else
{
MESH_DEBUG_PRINTLN("No GPS detected");
}
digitalWrite(GPS_EN, LOW); // Put GPS back into standby mode
return true;
}
bool NanoG2UltraSensorManager::querySensors(uint8_t requester_permissions, CayenneLPP &telemetry)
{
if (requester_permissions & TELEM_PERM_LOCATION)
{ // does requester have permission?
telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, node_altitude);
}
return true;
}
void NanoG2UltraSensorManager::loop()
{
static long next_gps_update = 0;
_location->loop();
if (millis() > next_gps_update && gps_active) // don't bother if gps position is not enabled
{
if (_location->isValid())
{
node_lat = ((double)_location->getLatitude()) / 1000000.;
node_lon = ((double)_location->getLongitude()) / 1000000.;
node_altitude = ((double)_location->getAltitude()) / 1000.0;
MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon);
}
next_gps_update = millis() + (1000 * 60); // after initial update, only check every minute TODO: should be configurable
}
}
int NanoG2UltraSensorManager::getNumSettings() const { return 1; } // just one supported: "gps" (power switch)
const char *NanoG2UltraSensorManager::getSettingName(int i) const
{
return i == 0 ? "gps" : NULL;
}
const char *NanoG2UltraSensorManager::getSettingValue(int i) const
{
if (i == 0)
{
return gps_active ? "1" : "0";
}
return NULL;
}
bool NanoG2UltraSensorManager::setSettingValue(const char *name, const char *value)
{
if (strcmp(name, "gps") == 0)
{
if (strcmp(value, "0") == 0)
{
stop_gps();
}
else
{
start_gps();
}
return true;
}
return false; // not supported
}
mesh::LocalIdentity radio_new_identity()
{
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View file

@ -0,0 +1,47 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include "nano-g2.h"
#include <helpers/RadioLibWrappers.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SH1106Display.h>
#endif
#include <helpers/sensors/LocationProvider.h>
class NanoG2UltraSensorManager : public SensorManager
{
bool gps_active = false;
LocationProvider *_location;
void start_gps();
void stop_gps();
public:
NanoG2UltraSensorManager(LocationProvider &location) : _location(&location) {}
bool begin() override;
bool querySensors(uint8_t requester_permissions, CayenneLPP &telemetry) override;
void loop() override;
int getNumSettings() const override;
const char *getSettingName(int i) const override;
const char *getSettingValue(int i) const override;
bool setSettingValue(const char *name, const char *value) override;
};
extern NanoG2Ultra board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern NanoG2UltraSensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View file

@ -0,0 +1,36 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
Copyright (c) 2018, Adafruit Industries (adafruit.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include "nrf.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
const uint32_t g_ADigitalPinMap[] = {
// P0 - pins 0 and 1 are hardwired for xtal and should never be enabled
0xff, 0xff, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
// P1
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
void initVariant()
{
// Nothing need to be inited for now
}

View file

@ -0,0 +1,193 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
Copyright (c) 2018, Adafruit Industries (adafruit.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _VARIANT_Nano_G2_
#define _VARIANT_Nano_G2_
/** Master clock frequency */
#define VARIANT_MCK (64000000ul)
#define USE_LFXO // Board uses 32khz crystal for LF
// #define USE_LFRC // Board uses 32khz RC for LF
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
// Number of pins defined in PinDescription array
#define PINS_COUNT (48)
#define NUM_DIGITAL_PINS (48)
#define NUM_ANALOG_INPUTS (1)
#define NUM_ANALOG_OUTPUTS (0)
// LEDs
#define PIN_LED1 (-1)
#define PIN_LED2 (-1)
#define PIN_LED3 (-1)
#define LED_RED PIN_LED3
#define LED_BLUE PIN_LED1
#define LED_GREEN PIN_LED2
#define LED_BUILTIN LED_BLUE
#define LED_CONN PIN_GREEN
#define LED_STATE_ON 0 // State when LED is lit
/*
* Buttons
*/
#define PIN_BUTTON1 (32 + 6)
#define EXT_NOTIFY_OUT (0 + 4) // Default pin to use for Ext Notify Module.
/*
* Analog pins
*/
#define PIN_A4 (0 + 2) // Battery ADC
#define BATTERY_PIN PIN_A4
static const uint8_t A4 = PIN_A4;
#define ADC_RESOLUTION 14
/*
* Serial interfaces
*/
#define PIN_SERIAL2_RX (0 + 22)
#define PIN_SERIAL2_TX (0 + 20)
/**
Wire Interfaces
*/
#define WIRE_INTERFACES_COUNT 1
#define PIN_WIRE_SDA (0 + 17)
#define PIN_WIRE_SCL (0 + 15)
#define PIN_RTC_INT (0 + 14) // Interrupt from the PCF8563 RTC
/*
External serial flash W25Q16JV_IQ
*/
// QSPI Pins
#define PIN_QSPI_SCK (0 + 8)
#define PIN_QSPI_CS (32 + 7)
#define PIN_QSPI_IO0 (0 + 6) // MOSI if using two bit interface
#define PIN_QSPI_IO1 (0 + 26) // MISO if using two bit interface
#define PIN_QSPI_IO2 (32 + 4) // WP if using two bit interface (i.e. not used)
#define PIN_QSPI_IO3 (32 + 2) // HOLD if using two bit interface (i.e. not used)
// On-board QSPI Flash
#define EXTERNAL_FLASH_DEVICES W25Q16JV_IQ
#define EXTERNAL_FLASH_USE_QSPI
/*
* Lora radio
*/
#define USE_SX1262
#define SX126X_CS (32 + 13) // FIXME - we really should define LORA_CS instead
#define SX126X_DIO1 (32 + 10)
// Note DIO2 is attached internally to the module to an analog switch for TX/RX switching
// #define SX1262_DIO3 (0 + 21)
// This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main CPU?
#define SX126X_BUSY (32 + 11)
#define SX126X_RESET (32 + 15)
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...)
// #undef SX126X_CS
/*
* GPS pins
*/
#define HAS_GPS 1
#define GPS_L76K
#define PIN_GPS_STANDBY (0 + 13) // An output to wake GPS, low means allow sleep, high means force wake STANDBY
#define PIN_GPS_TX (0 + 9) // This is for bits going TOWARDS the CPU
#define PIN_GPS_RX (0 + 10) // This is for bits going TOWARDS the GPS
#define GPS_RX_PIN PIN_GPS_RX
#define GPS_TX_PIN PIN_GPS_TX
// #define GPS_THREAD_INTERVAL 50
#define PIN_SERIAL1_RX PIN_GPS_TX
#define PIN_SERIAL1_TX PIN_GPS_RX
// PCF8563 RTC Module
#define PCF8563_RTC 0x51
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 1
// For LORA, spi 0
#define PIN_SPI_MISO (32 + 9)
#define PIN_SPI_MOSI (0 + 11)
#define PIN_SPI_SCK (0 + 12)
// #define PIN_PWR_EN (0 + 6)
// To debug via the segger JLINK console rather than the CDC-ACM serial device
// #define USE_SEGGER
// Battery
// The battery sense is hooked to pin A0 (2)
// it is defined in the anlaolgue pin section of this file
// and has 12 bit resolution
#define BATTERY_SENSE_RESOLUTION_BITS 12
#define BATTERY_SENSE_RESOLUTION 4096.0
#undef AREF_VOLTAGE
#define AREF_VOLTAGE 3.0
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
#define ADC_MULTIPLIER (2.0F)
#define HAS_RTC 1
/**
OLED Screen Model
*/
#define ARDUINO_ARCH_AVR
#define USE_SH1107_128_64
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------------
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#endif

View file

@ -0,0 +1,104 @@
[picow]
extends = rp2040_base
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
board = rpipicow
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
build_flags = ${rp2040_base.build_flags}
-I variants/picow
; -D PICOW
; -D HW_SPI1_DEVICE
-D SX126X_CURRENT_LIMIT=130
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${rp2040_base.build_src_filter}
+<helpers/rp2040/*.cpp>
+<../variants/picow>
lib_deps = ${rp2040_base.lib_deps}
[env:PicoW_Repeater]
extends = picow
build_flags = ${picow.build_flags}
-D ADVERT_NAME='"PicoW Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${picow.build_src_filter}
+<../examples/simple_repeater>
[env:PicoW_room_server]
extends = picow
build_flags = ${picow.build_flags}
-D ADVERT_NAME='"Test 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 = ${picow.build_src_filter}
+<../examples/simple_room_server>
[env:PicoW_companion_radio_usb]
extends = picow
build_flags = ${picow.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1
build_src_filter = ${picow.build_src_filter}
+<../examples/companion_radio>
lib_deps = ${picow.lib_deps}
densaugeo/base64 @ ~1.4.0
; [env:PicoW_companion_radio_ble]
; extends = picow
; build_flags = ${picow.build_flags}
; -D MAX_CONTACTS=100
; -D MAX_GROUP_CHANNELS=8
; -D BLE_PIN_CODE=123456
; -D BLE_DEBUG_LOGGING=1
; ; -D ENABLE_PRIVATE_KEY_IMPORT=1
; ; -D ENABLE_PRIVATE_KEY_EXPORT=1
; ; -D MESH_PACKET_LOGGING=1
; ; -D MESH_DEBUG=1
; build_src_filter = ${picow.build_src_filter}
; +<../examples/companion_radio>
; lib_deps = ${picow.lib_deps}
; densaugeo/base64 @ ~1.4.0
; [env:PicoW_companion_radio_wifi]
; extends = picow
; build_flags = ${picow.build_flags}
; -D MAX_CONTACTS=100
; -D MAX_GROUP_CHANNELS=8
; -D WIFI_DEBUG_LOGGING=1
; -D WIFI_SSID='"myssid"'
; -D WIFI_PWD='"mypwd"'
; ; -D ENABLE_PRIVATE_KEY_IMPORT=1
; ; -D ENABLE_PRIVATE_KEY_EXPORT=1
; ; -D MESH_PACKET_LOGGING=1
; ; -D MESH_DEBUG=1
; build_src_filter = ${picow.build_src_filter}
; +<../examples/companion_radio>
; lib_deps = ${picow.lib_deps}
; densaugeo/base64 @ ~1.4.0
[env:PicoW_terminal_chat]
extends = picow
build_flags = ${picow.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${picow.build_src_filter}
+<../examples/simple_secure_chat/main.cpp>
lib_deps = ${picow.lib_deps}
densaugeo/base64 @ ~1.4.0

74
variants/picow/target.cpp Normal file
View file

@ -0,0 +1,74 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/ArduinoHelpers.h>
PicoWBoard board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI1);
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifndef LORA_CR
#define LORA_CR 5
#endif
bool radio_init() {
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else
float tcxo = 1.6f;
#endif
SPI1.setMISO(P_LORA_MISO);
//SPI1.setCS(P_LORA_NSS); // Setting CS results in freeze
SPI1.setSCK(P_LORA_SCLK);
SPI1.setMOSI(P_LORA_MOSI);
SPI1.begin();
int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo);
if (status != RADIOLIB_ERR_NONE) {
Serial.print("ERROR: radio init failed: ");
Serial.println(status);
return false; // fail
}
radio.setCRC(1);
#ifdef SX126X_CURRENT_LIMIT
radio.setCurrentLimit(SX126X_CURRENT_LIMIT);
#endif
#ifdef SX126X_DIO2_AS_RF_SWITCH
radio.setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH);
#endif
#ifdef SX126X_RX_BOOSTED_GAIN
radio.setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN);
#endif
return true; // success
}
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

20
variants/picow/target.h Normal file
View file

@ -0,0 +1,20 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/rp2040/PicoWBoard.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
extern PicoWBoard board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View file

@ -7,94 +7,113 @@ build_flags = ${nrf52840_base.build_flags}
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D DISPLAY_CLASS=SSD1306Display
-D PIN_BOARD_SCL=7
-D PIN_BOARD_SDA=8
-D PIN_OLED_RESET=-1
-D PIN_USER_BTN=6
-D PIN_GPS_RX=3
-D PIN_GPS_TX=4
-D PIN_GPS_EN=5
-D ENV_INCLUDE_GPS=1
-D ENV_INCLUDE_AHTX0=1
-D ENV_INCLUDE_BME280=1
-D ENV_INCLUDE_INA3221=1
-D ENV_INCLUDE_INA219=1
build_src_filter = ${nrf52840_base.build_src_filter}
+<helpers/nrf52/PromicroBoard.cpp>
+<helpers/sensors>
+<../variants/promicro>
lib_deps=
${nrf52840_base.lib_deps}
lib_deps= ${nrf52840_base.lib_deps}
adafruit/Adafruit SSD1306 @ ^2.5.13
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
stevemarple/MicroNMEA @ ^2.0.6
[env:Faketec_Repeater]
extends = Faketec
build_src_filter = ${Faketec.build_src_filter} +<../examples/simple_repeater> +<helpers/ui/*.cpp>
build_src_filter = ${Faketec.build_src_filter}
+<../examples/simple_repeater>
+<helpers/ui/SSD1306Display.cpp>
build_flags =
${Faketec.build_flags}
-D ADVERT_NAME="\"Faketec Repeater\""
-D ADVERT_NAME='"Faketec Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD="\"password\""
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
-D DISPLAY_CLASS=SSD1306Display
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
lib_deps =
${Faketec.lib_deps}
lib_deps = ${Faketec.lib_deps}
adafruit/RTClib @ ^2.1.3
[env:Faketec_room_server]
extends = Faketec
build_src_filter = ${Faketec.build_src_filter} +<../examples/simple_room_server> +<helpers/ui/*.cpp>
build_flags =
${Faketec.build_flags}
-D ADVERT_NAME="\"Test Room\""
build_src_filter = ${Faketec.build_src_filter}
+<../examples/simple_room_server>
+<helpers/ui/SSD1306Display.cpp>
build_flags = ${Faketec.build_flags}
-D ADVERT_NAME='"Faketec Room"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD="\"password\""
-D ROOM_PASSWORD="\"hello\""
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D DISPLAY_CLASS=SSD1306Display
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
lib_deps =
${Faketec.lib_deps}
lib_deps = ${Faketec.lib_deps}
adafruit/RTClib @ ^2.1.3
[env:Faketec_terminal_chat]
extends = Faketec
build_flags =
${Faketec.build_flags}
build_flags = ${Faketec.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Faketec.build_src_filter} +<../examples/simple_secure_chat/main.cpp>
lib_deps =
${Faketec.lib_deps}
build_src_filter = ${Faketec.build_src_filter}
+<../examples/simple_secure_chat/main.cpp>
lib_deps = ${Faketec.lib_deps}
densaugeo/base64 @ ~1.4.0
adafruit/RTClib @ ^2.1.3
[env:Faketec_companion_radio_usb]
extends = Faketec
build_flags =
${Faketec.build_flags}
build_flags = ${Faketec.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D DISPLAY_CLASS=SSD1306Display
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1
build_src_filter = ${Faketec.build_src_filter} +<../examples/companion_radio> +<../examples/companion_radio> +<helpers/ui/*.cpp>
lib_deps =
${Faketec.lib_deps}
build_src_filter = ${Faketec.build_src_filter}
+<../examples/companion_radio>
+<helpers/ui/SSD1306Display.cpp>
lib_deps = ${Faketec.lib_deps}
adafruit/RTClib @ ^2.1.3
densaugeo/base64 @ ~1.4.0
[env:Faketec_companion_radio_ble]
extends = Faketec
build_flags =
${Faketec.build_flags}
build_flags = ${Faketec.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D ENABLE_PRIVATE_KEY_EXPORT=1
-D ENABLE_PRIVATE_KEY_IMPORT=1
-D OFFLINE_QUEUE_SIZE=256
-D DISPLAY_CLASS=SSD1306Display
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Faketec.build_src_filter} +<helpers/nrf52/SerialBLEInterface.cpp> +<../examples/companion_radio> +<helpers/ui/*.cpp>
lib_deps =
${Faketec.lib_deps}
-D MESH_DEBUG=1
build_src_filter = ${Faketec.build_src_filter}
+<helpers/nrf52/SerialBLEInterface.cpp>
+<../examples/companion_radio>
+<helpers/ui/SSD1306Display.cpp>
lib_deps = ${Faketec.lib_deps}
adafruit/RTClib @ ^2.1.3
densaugeo/base64 @ ~1.4.0
@ -107,81 +126,86 @@ build_flags = ${nrf52840_base.build_flags}
-D RADIO_CLASS=CustomLLCC68
-D WRAPPER_CLASS=CustomLLCC68Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${nrf52840_base.build_src_filter}
build_src_filter =
${nrf52840_base.build_src_filter}
+<helpers/nrf52/PromicroBoard.cpp>
+<helpers/sensors>
+<../variants/promicro>
lib_deps= ${nrf52840_base.lib_deps}
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
[env:ProMicroLLCC68_Repeater]
extends = ProMicroLLCC68
build_src_filter = ${ProMicroLLCC68.build_src_filter} +<../examples/simple_repeater/main.cpp>
build_flags =
${ProMicroLLCC68.build_flags}
-D ADVERT_NAME="\"ProMicroLLCC68 Repeater\""
-D ADMIN_PASSWORD="\"password\""
build_src_filter = ${ProMicroLLCC68.build_src_filter}
+<../examples/simple_repeater/main.cpp>
build_flags = ${ProMicroLLCC68.build_flags}
-D ADVERT_NAME='"ProMicroLLCC68 Repeater"'
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
lib_deps =
${ProMicroLLCC68.lib_deps}
lib_deps = ${ProMicroLLCC68.lib_deps}
adafruit/RTClib @ ^2.1.3
[env:ProMicroLLCC68_room_server]
extends = ProMicroLLCC68
build_src_filter = ${ProMicroLLCC68.build_src_filter} +<../examples/simple_room_server/main.cpp>
build_flags =
${ProMicroLLCC68.build_flags}
-D ADVERT_NAME="\"ProMicroLLCC68 Room\""
-D ADMIN_PASSWORD="\"password\""
-D ROOM_PASSWORD="\"hello\""
build_src_filter = ${ProMicroLLCC68.build_src_filter}
+<../examples/simple_room_server/main.cpp>
build_flags = ${ProMicroLLCC68.build_flags}
-D ADVERT_NAME='"ProMicroLLCC68 Room"'
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
lib_deps =
${ProMicroLLCC68.lib_deps}
lib_deps = ${ProMicroLLCC68.lib_deps}
adafruit/RTClib @ ^2.1.3
[env:ProMicroLLCC68_terminal_chat]
extends = ProMicroLLCC68
build_flags =
${ProMicroLLCC68.build_flags}
build_flags = ${ProMicroLLCC68.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${ProMicroLLCC68.build_src_filter} +<../examples/simple_secure_chat/main.cpp>
lib_deps =
${ProMicroLLCC68.lib_deps}
build_src_filter = ${ProMicroLLCC68.build_src_filter}
+<../examples/simple_secure_chat/main.cpp>
lib_deps = ${ProMicroLLCC68.lib_deps}
densaugeo/base64 @ ~1.4.0
adafruit/RTClib @ ^2.1.3
[env:ProMicroLLCC68_companion_radio_usb]
extends = ProMicroLLCC68
build_flags =
${ProMicroLLCC68.build_flags}
build_flags = ${ProMicroLLCC68.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1
build_src_filter = ${ProMicroLLCC68.build_src_filter} +<../examples/companion_radio/main.cpp>
lib_deps =
${ProMicroLLCC68.lib_deps}
build_src_filter = ${ProMicroLLCC68.build_src_filter}
+<../examples/companion_radio/main.cpp>
lib_deps = ${ProMicroLLCC68.lib_deps}
adafruit/RTClib @ ^2.1.3
densaugeo/base64 @ ~1.4.0
[env:ProMicroLLCC68_companion_radio_ble]
extends = ProMicroLLCC68
build_flags =
${ProMicroLLCC68.build_flags}
build_flags = ${ProMicroLLCC68.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D ENABLE_PRIVATE_KEY_EXPORT=1
-D ENABLE_PRIVATE_KEY_IMPORT=1
-D OFFLINE_QUEUE_SIZE=256
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${ProMicroLLCC68.build_src_filter} +<helpers/nrf52/SerialBLEInterface.cpp> +<../examples/companion_radio/main.cpp>
lib_deps =
${ProMicroLLCC68.lib_deps}
build_src_filter = ${ProMicroLLCC68.build_src_filter}
+<helpers/nrf52/SerialBLEInterface.cpp>
+<../examples/companion_radio/main.cpp>
lib_deps = ${ProMicroLLCC68.lib_deps}
adafruit/RTClib @ ^2.1.3
densaugeo/base64 @ ~1.4.0

View file

@ -2,6 +2,9 @@
#include "target.h"
#include <helpers/ArduinoHelpers.h>
#if ENV_INCLUDE_GPS
#endif
PromicroBoard board;
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
@ -10,6 +13,17 @@ WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
#if ENV_INCLUDE_GPS
#include <helpers/sensors/MicroNMEALocationProvider.h>
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);
#else
EnvironmentSensorManager sensors;
#endif
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5
@ -73,3 +87,4 @@ mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View file

@ -7,13 +7,24 @@
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/CustomLLCC68Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306Display.h>
#endif
#include <helpers/sensors/EnvironmentSensorManager.h>
extern PromicroBoard board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern EnvironmentSensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View file

@ -0,0 +1,33 @@
[rak3x72]
extends = stm32_base
board = rak3172
board_upload.maximum_size = 229376 ; 32kb for FS
build_flags = ${stm32_base.build_flags}
-D RADIO_CLASS=CustomSTM32WLx
-D WRAPPER_CLASS=CustomSTM32WLxWrapper
-D SPI_INTERFACES_COUNT=0
-D RX_BOOSTED_GAIN=true
-I variants/rak3x72
build_src_filter = ${stm32_base.build_src_filter}
+<../variants/rak3x72>
[env:rak3x72-repeater]
extends = rak3x72
build_flags = ${rak3x72.build_flags}
-D LORA_TX_POWER=22
-D ADVERT_NAME='"RAK3x72 Repeater"'
-D ADMIN_PASSWORD='"password"'
build_src_filter = ${rak3x72.build_src_filter}
+<../examples/simple_repeater/main.cpp>
[env:rak3x72_companion_radio_usb]
extends = rak3x72
build_flags = ${rak3x72.build_flags}
; -D FORMAT_FS=true
-D LORA_TX_POWER=22
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
build_src_filter = ${rak3x72.build_src_filter}
+<../examples/companion_radio/*.cpp>
lib_deps = ${rak3x72.lib_deps}
densaugeo/base64 @ ~1.4.0

View file

@ -0,0 +1,67 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/ArduinoHelpers.h>
RAK3x72Board board;
RADIO_CLASS radio = new STM32WLx_Module();
WRAPPER_CLASS radio_driver(radio, board);
static const uint32_t rfswitch_pins[] = {LORAWAN_RFSWITCH_PINS, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC};
static const Module::RfSwitchMode_t rfswitch_table[] = {
{STM32WLx::MODE_IDLE, {LOW, LOW}},
{STM32WLx::MODE_RX, {HIGH, LOW}},
{STM32WLx::MODE_TX_LP, {LOW, HIGH}},
{STM32WLx::MODE_TX_HP, {LOW, HIGH}},
END_OF_MODE_TABLE,
};
VolatileRTCClock rtc_clock;
SensorManager sensors;
#ifndef LORA_CR
#define LORA_CR 5
#endif
bool radio_init() {
// rtc_clock.begin(Wire);
radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, 0, 0); // TCXO set to 0 for RAK3172
if (status != RADIOLIB_ERR_NONE) {
Serial.print("ERROR: radio init failed: ");
Serial.println(status);
return false; // fail
}
#ifdef RX_BOOSTED_GAIN
radio.setRxBoostedGainMode(RX_BOOSTED_GAIN);
#endif
radio.setCRC(1);
return true; // success
}
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

35
variants/rak3x72/target.h Normal file
View file

@ -0,0 +1,35 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/stm32/STM32Board.h>
#include <helpers/CustomSTM32WLxWrapper.h>
#include <helpers/ArduinoHelpers.h>
#include <helpers/SensorManager.h>
#define PIN_VBAT_READ A0
#define ADC_MULTIPLIER (5 * 1.73 * 1000)
class RAK3x72Board : public STM32Board {
public:
const char* getManufacturerName() const override {
return "RAK 3x72";
}
uint16_t getBattMilliVolts() override {
uint32_t raw = analogRead(PIN_VBAT_READ);
return (ADC_MULTIPLIER * raw) / 1024;
}
};
extern RAK3x72Board board;
extern WRAPPER_CLASS radio_driver;
extern VolatileRTCClock rtc_clock;
extern SensorManager sensors;
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View file

@ -0,0 +1,5 @@
#pragma once
#include <variant_RAK3172_MODULE.h>
#undef RNG

View file

@ -7,13 +7,14 @@ build_flags = ${nrf52840_base.build_flags}
-I variants/rak4631
-D RAK_4631
-D PIN_USER_BTN=9
-D PIN_USER_BTN_ANA=31
-D PIN_BOARD_SCL=14
-D PIN_BOARD_SDA=13
-D PIN_OLED_RESET=-1
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${nrf52840_base.build_src_filter}
+<helpers/nrf52/RAK4631Board.cpp>
@ -31,6 +32,7 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${rak4631.build_src_filter}
@ -80,6 +82,7 @@ build_flags =
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1
@ -98,8 +101,8 @@ build_flags =
${rak4631.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
-D MESH_PACKET_LOGGING=1
-D MESH_DEBUG=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${rak4631.build_src_filter}
+<../examples/simple_secure_chat/main.cpp>
lib_deps =

View file

@ -10,6 +10,11 @@ WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5

View file

@ -6,10 +6,19 @@
#include <helpers/nrf52/RAK4631Board.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306Display.h>
#endif
extern RAK4631Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -14,7 +14,7 @@ build_flags =
-D PIN_USER_BTN=0
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=130.0f ; for best TX power!
-D SX126X_CURRENT_LIMIT=140
; -D SX126X_RX_BOOSTED_GAIN=1 - DO NOT ENABLE THIS!
; https://wiki.uniteng.com/en/meshtastic/station-g2#impact-of-lora-node-dense-areashigh-noise-environments-on-rf-performance
build_src_filter = ${esp32_base.build_src_filter}
@ -30,7 +30,8 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MESH_PACKET_LOGGING=1
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Station_G2.build_src_filter}
+<../examples/simple_repeater>

View file

@ -14,6 +14,7 @@ WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifndef LORA_CR
#define LORA_CR 5

View file

@ -6,10 +6,12 @@
#include <helpers/StationG2Board.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
extern StationG2Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -0,0 +1,24 @@
#pragma once
#include <helpers/ui/DisplayDriver.h>
class NullDisplayDriver : public DisplayDriver {
public:
NullDisplayDriver() : DisplayDriver(128, 64) { }
bool begin() { return false; } // not present
bool isOn() override { return false; }
void turnOn() override { }
void turnOff() override { }
void clear() override { }
void startFrame(Color bkg = DARK) override { }
void setTextSize(int sz) override { }
void setColor(Color c) override { }
void setCursor(int x, int y) override { }
void print(const char* str) override { }
void fillRect(int x, int y, int w, int h) override { }
void drawRect(int x, int y, int w, int h) override { }
void drawXbm(int x, int y, const uint8_t* bits, int w, int h) override { }
uint16_t getTextWidth(const char* str) override { return 0; }
void endFrame() { }
};

View file

@ -40,14 +40,20 @@ build_flags = ${t1000-e.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D MESH_PACKET_LOGGING=1
-D MESH_DEBUG=1
; -D BLE_DEBUG_LOGGING=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
-D OFFLINE_QUEUE_SIZE=256
-D RX_BOOSTED_GAIN=true
-D RF_SWITCH_TABLE
-D HAS_UI
-D DISPLAY_CLASS=NullDisplayDriver
-D PIN_BUZZER=25
-D PIN_BUZZER_EN=37 ; P1/5 - required for T1000-E
build_src_filter = ${t1000-e.build_src_filter}
+<helpers/nrf52/SerialBLEInterface.cpp>
+<helpers/ui/buzzer.cpp>
+<../examples/companion_radio/*.cpp>
lib_deps = ${t1000-e.lib_deps}
densaugeo/base64 @ ~1.4.0
stevemarple/MicroNMEA @ ^2.0.6
end2endzone/NonBlockingRTTTL@^1.3.0

View file

@ -1,5 +1,6 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/sensors/MicroNMEALocationProvider.h>
T1000eBoard board;
@ -8,6 +9,12 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock rtc_clock;
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
T1000SensorManager sensors = T1000SensorManager(nmea);
#ifdef DISPLAY_CLASS
NullDisplayDriver display;
#endif
#ifndef LORA_CR
#define LORA_CR 5
@ -84,3 +91,113 @@ mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}
void T1000SensorManager::start_gps() {
gps_active = true;
//_nmea->begin();
// this init sequence should be better
// comes from seeed examples and deals with all gps pins
pinMode(GPS_EN, OUTPUT);
digitalWrite(GPS_EN, HIGH);
delay(10);
pinMode(GPS_VRTC_EN, OUTPUT);
digitalWrite(GPS_VRTC_EN, HIGH);
delay(10);
pinMode(GPS_RESET, OUTPUT);
digitalWrite(GPS_RESET, HIGH);
delay(10);
digitalWrite(GPS_RESET, LOW);
pinMode(GPS_SLEEP_INT, OUTPUT);
digitalWrite(GPS_SLEEP_INT, HIGH);
pinMode(GPS_RTC_INT, OUTPUT);
digitalWrite(GPS_RTC_INT, LOW);
pinMode(GPS_RESETB, INPUT_PULLUP);
}
void T1000SensorManager::sleep_gps() {
gps_active = false;
digitalWrite(GPS_VRTC_EN, HIGH);
digitalWrite(GPS_EN, LOW);
digitalWrite(GPS_RESET, HIGH);
digitalWrite(GPS_SLEEP_INT, HIGH);
digitalWrite(GPS_RTC_INT, LOW);
pinMode(GPS_RESETB, OUTPUT);
digitalWrite(GPS_RESETB, LOW);
//_nmea->stop();
}
void T1000SensorManager::stop_gps() {
gps_active = false;
digitalWrite(GPS_VRTC_EN, LOW);
digitalWrite(GPS_EN, LOW);
digitalWrite(GPS_RESET, HIGH);
digitalWrite(GPS_SLEEP_INT, HIGH);
digitalWrite(GPS_RTC_INT, LOW);
pinMode(GPS_RESETB, OUTPUT);
digitalWrite(GPS_RESETB, LOW);
//_nmea->stop();
}
bool T1000SensorManager::begin() {
// init GPS
Serial1.begin(115200);
// make sure gps pin are off
digitalWrite(GPS_VRTC_EN, LOW);
digitalWrite(GPS_RESET, LOW);
digitalWrite(GPS_SLEEP_INT, LOW);
digitalWrite(GPS_RTC_INT, LOW);
pinMode(GPS_RESETB, OUTPUT);
digitalWrite(GPS_RESETB, LOW);
return true;
}
bool T1000SensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) {
if (requester_permissions & TELEM_PERM_LOCATION) { // does requester have permission?
telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, node_altitude);
}
return true;
}
void T1000SensorManager::loop() {
static long next_gps_update = 0;
_nmea->loop();
if (millis() > next_gps_update) {
if (_nmea->isValid()) {
node_lat = ((double)_nmea->getLatitude())/1000000.;
node_lon = ((double)_nmea->getLongitude())/1000000.;
node_altitude = ((double)_nmea->getAltitude()) / 1000.0;
//Serial.printf("lat %f lon %f\r\n", _lat, _lon);
}
next_gps_update = millis() + 1000;
}
}
int T1000SensorManager::getNumSettings() const { return 1; } // just one supported: "gps" (power switch)
const char* T1000SensorManager::getSettingName(int i) const {
return i == 0 ? "gps" : NULL;
}
const char* T1000SensorManager::getSettingValue(int i) const {
if (i == 0) {
return gps_active ? "1" : "0";
}
return NULL;
}
bool T1000SensorManager::setSettingValue(const char* name, const char* value) {
if (strcmp(name, "gps") == 0) {
if (strcmp(value, "0") == 0) {
sleep_gps(); // sleep for faster fix !
} else {
start_gps();
}
return true;
}
return false; // not supported
}

View file

@ -6,10 +6,38 @@
#include <helpers/nrf52/T1000eBoard.h>
#include <helpers/CustomLR1110Wrapper.h>
#include <helpers/ArduinoHelpers.h>
#include <helpers/SensorManager.h>
#include <helpers/sensors/LocationProvider.h>
#ifdef DISPLAY_CLASS
#include "NullDisplayDriver.h"
#endif
class T1000SensorManager: public SensorManager {
bool gps_active = false;
LocationProvider * _nmea;
void start_gps();
void sleep_gps();
void stop_gps();
public:
T1000SensorManager(LocationProvider &nmea): _nmea(&nmea) { }
bool begin() override;
bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
void loop() override;
int getNumSettings() const override;
const char* getSettingName(int i) const override;
const char* getSettingValue(int i) const override;
bool setSettingValue(const char* name, const char* value) override;
};
#ifdef DISPLAY_CLASS
extern NullDisplayDriver display;
#endif
extern T1000eBoard board;
extern WRAPPER_CLASS radio_driver;
extern VolatileRTCClock rtc_clock;
extern T1000SensorManager sensors;
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -20,12 +20,15 @@ build_flags = ${nrf52840_t114.build_flags}
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${nrf52840_t114.build_src_filter}
+<helpers/*.cpp>
+<helpers/nrf52/T114Board.cpp>
+<../variants/t114>
lib_deps =
${nrf52840_t114.lib_deps}
stevemarple/MicroNMEA @ ^2.0.6
debug_tool = jlink
upload_protocol = nrfutil
@ -39,6 +42,7 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@ -60,32 +64,30 @@ build_flags =
extends = Heltec_t114
build_flags =
${Heltec_t114.build_flags}
-I src/helpers/ui
-D ST7789
-D DISPLAY_CLASS=ST7789Display
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Heltec_t114.build_src_filter}
+<helpers/nrf52/*.cpp>
+<helpers/nrf52/T114Board.cpp>
+<helpers/nrf52/SerialBLEInterface.cpp>
+<../examples/companion_radio/main.cpp>
lib_deps =
${Heltec_t114.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:Heltec_t114_companion_radio_ble_screen]
extends = env:Heltec_t114_companion_radio_ble
build_flags = ${env:Heltec_t114_companion_radio_ble.build_flags}
-I src/helpers/ui
-D ST7789
-D DISPLAY_CLASS=ST7789Display
build_src_filter = ${env:Heltec_t114_companion_radio_ble.build_src_filter}
+<../examples/companion_radio/UITask.cpp>
+<helpers/ui/ST7789Display.cpp>
lib_deps = ${env:Heltec_t114_companion_radio_ble.lib_deps}
adafruit/Adafruit ST7735 and ST7789 Library @ ^1.11.0
+<helpers/ui/OLEDDisplay.cpp>
+<helpers/ui/OLEDDisplayFonts.cpp>
lib_deps =
adafruit/Adafruit GFX Library @ ^1.12.1
${Heltec_t114.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:Heltec_t114_companion_radio_usb]
extends = Heltec_t114

View file

@ -1,6 +1,7 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/ArduinoHelpers.h>
#include <helpers/sensors/MicroNMEALocationProvider.h>
T114Board board;
@ -10,6 +11,12 @@ WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
T114SensorManager sensors = T114SensorManager(nmea);
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5
@ -67,3 +74,91 @@ mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}
void T114SensorManager::start_gps() {
if (!gps_active) {
gps_active = true;
_location->begin();
}
}
void T114SensorManager::stop_gps() {
if (gps_active) {
gps_active = false;
_location->stop();
}
}
bool T114SensorManager::begin() {
Serial1.begin(9600);
// Try to detect if GPS is physically connected to determine if we should expose the setting
pinMode(GPS_EN, OUTPUT);
digitalWrite(GPS_EN, HIGH); // Power on GPS
// Give GPS a moment to power up and send data
delay(1500);
// We'll consider GPS detected if we see any data on Serial1
gps_detected = (Serial1.available() > 0);
if (gps_detected) {
MESH_DEBUG_PRINTLN("GPS detected");
digitalWrite(GPS_EN, LOW); // Power off GPS until the setting is changed
} else {
MESH_DEBUG_PRINTLN("No GPS detected");
digitalWrite(GPS_EN, LOW);
}
return true;
}
bool T114SensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) {
if (requester_permissions & TELEM_PERM_LOCATION) { // does requester have permission?
telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, node_altitude);
}
return true;
}
void T114SensorManager::loop() {
static long next_gps_update = 0;
_location->loop();
if (millis() > next_gps_update) {
if (_location->isValid()) {
node_lat = ((double)_location->getLatitude())/1000000.;
node_lon = ((double)_location->getLongitude())/1000000.;
node_altitude = ((double)_location->getAltitude()) / 1000.0;
MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon);
}
next_gps_update = millis() + 1000;
}
}
int T114SensorManager::getNumSettings() const {
return gps_detected ? 1 : 0; // only show GPS setting if GPS is detected
}
const char* T114SensorManager::getSettingName(int i) const {
return (gps_detected && i == 0) ? "gps" : NULL;
}
const char* T114SensorManager::getSettingValue(int i) const {
if (gps_detected && i == 0) {
return gps_active ? "1" : "0";
}
return NULL;
}
bool T114SensorManager::setSettingValue(const char* name, const char* value) {
if (gps_detected && strcmp(name, "gps") == 0) {
if (strcmp(value, "0") == 0) {
stop_gps();
} else {
start_gps();
}
return true;
}
return false; // not supported
}

View file

@ -6,10 +6,38 @@
#include <helpers/nrf52/T114Board.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#include <helpers/sensors/LocationProvider.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/ST7789Display.h>
#endif
class T114SensorManager : public SensorManager {
bool gps_active = false;
bool gps_detected = false;
LocationProvider* _location;
void start_gps();
void stop_gps();
public:
T114SensorManager(LocationProvider &location): _location(&location) { }
bool begin() override;
bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
void loop() override;
int getNumSettings() const override;
const char* getSettingName(int i) const override;
const char* getSettingValue(int i) const override;
bool setSettingValue(const char* name, const char* value) override;
};
extern T114Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern T114SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -11,4 +11,5 @@ const uint32_t g_ADigitalPinMap[] = {
void initVariant()
{
pinMode(PIN_USER_BTN, INPUT);
}

View file

@ -41,8 +41,8 @@
////////////////////////////////////////////////////////////////////////////////
// UART pin definition
#define PIN_SERIAL1_RX (39)
#define PIN_SERIAL1_TX (37)
#define PIN_SERIAL1_RX (37)
#define PIN_SERIAL1_TX (39)
#define PIN_SERIAL2_RX (9)
#define PIN_SERIAL2_TX (10)
@ -69,10 +69,10 @@
#define LED_BUILTIN (35)
#define PIN_LED LED_BUILTIN
#define LED_RED LED_BUILTIN
#define LED_BLUE LED_BUILTIN
#define LED_BLUE (-1) // No blue led, prevents Bluefruit flashing the green LED during advertising
#define LED_PIN LED_BUILTIN
#define LED_STATE_ON HIGH
#define LED_STATE_ON LOW
#define PIN_NEOPIXEL (14)
#define NEOPIXEL_NUM (2)
@ -109,9 +109,15 @@
////////////////////////////////////////////////////////////////////////////////
// Buzzer
#define PIN_BUZZER (46)
// #define PIN_BUZZER (46)
////////////////////////////////////////////////////////////////////////////////
// GPS
#define GPS_EN (21)
#define GPS_RESET (38)
////////////////////////////////////////////////////////////////////////////////
// TFT
#define PIN_TFT_SCL (40)

View file

@ -19,7 +19,7 @@ build_flags = ${nrf52840_techo.build_flags}
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${nrf52840_techo.build_src_filter}
+<helpers/*.cpp>
@ -37,6 +37,7 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
@ -62,7 +63,7 @@ build_flags =
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D DISPLAY_CLASS=GxEPDDisplay
-D HAS_GxEPD
-D OFFLINE_QUEUE_SIZE=256
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1

View file

@ -10,6 +10,11 @@ WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5

View file

@ -6,10 +6,20 @@
#include <helpers/nrf52/TechoBoard.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/GxEPDDisplay.h>
#endif
extern TechoBoard board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -0,0 +1,86 @@
[nrf52840_thinknode_m1]
extends = nrf52_base
platform_packages = framework-arduinoadafruitnrf52
build_flags = ${nrf52_base.build_flags}
-I src/helpers/nrf52
-I lib/nrf52/s140_nrf52_6.1.1_API/include
-I lib/nrf52/s140_nrf52_6.1.1_API/include/nrf52
lib_deps =
${nrf52_base.lib_deps}
rweather/Crypto @ ^0.4.0
[ThinkNode_M1]
extends = nrf52840_thinknode_m1
board = thinknode_m1
board_build.ldscript = boards/nrf52840_s140_v6.ld
build_flags = ${nrf52840_thinknode_m1.build_flags}
-I variants/thinknode_m1
-D THINKNODE_M1=1
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${nrf52840_thinknode_m1.build_src_filter}
+<helpers/*.cpp>
+<helpers/nrf52/ThinkNodeM1Board.cpp>
+<../variants/thinknode_m1>
debug_tool = jlink
upload_protocol = nrfutil
[env:ThinkNode_M1_repeater]
extends = ThinkNode_M1
build_flags =
${ThinkNode_M1.build_flags}
-D ADVERT_NAME='"ThinkNode Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${ThinkNode_M1.build_src_filter}
+<../examples/simple_repeater/main.cpp>
lib_deps =
${ThinkNode_M1.lib_deps}
[env:ThinkNode_M1_room_server]
extends = ThinkNode_M1
build_flags =
${ThinkNode_M1.build_flags}
-D ADVERT_NAME='"ThinkNode 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 = ${ThinkNode_M1.build_src_filter}
+<../examples/simple_room_server/main.cpp>
lib_deps =
${ThinkNode_M1.lib_deps}
[env:ThinkNode_M1_companion_radio_ble]
extends = ThinkNode_M1
build_flags =
${ThinkNode_M1.build_flags}
-I src/helpers/ui
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D DISPLAY_ROTATION=4
-D DISPLAY_CLASS=GxEPDDisplay
-D OFFLINE_QUEUE_SIZE=256
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${ThinkNode_M1.build_src_filter}
+<helpers/nrf52/ThinkNodeM1.cpp>
+<helpers/nrf52/SerialBLEInterface.cpp>
+<helpers/ui/GxEPDDisplay.cpp>
+<../examples/companion_radio>
lib_deps =
${ThinkNode_M1.lib_deps}
densaugeo/base64 @ ~1.4.0
zinggjm/GxEPD2 @ 1.6.2

View file

@ -0,0 +1,74 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/ArduinoHelpers.h>
ThinkNodeM1Board 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);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5
#endif
bool radio_init() {
rtc_clock.begin(Wire);
#ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
#else
float tcxo = 1.6f;
#endif
SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI);
SPI.begin();
int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo);
if (status != RADIOLIB_ERR_NONE) {
Serial.print("ERROR: radio init failed: ");
Serial.println(status);
return false; // fail
}
radio.setCRC(1);
#ifdef SX126X_CURRENT_LIMIT
radio.setCurrentLimit(SX126X_CURRENT_LIMIT);
#endif
#ifdef SX126X_DIO2_AS_RF_SWITCH
radio.setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH);
#endif
#ifdef SX126X_RX_BOOSTED_GAIN
radio.setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN);
#endif
return true; // success
}
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

View file

@ -0,0 +1,27 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/nrf52/ThinkNodeM1Board.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/GxEPDDisplay.h>
#endif
extern ThinkNodeM1Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

View file

@ -0,0 +1,34 @@
#include "variant.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
const int MISO = PIN_SPI1_MISO;
const int MOSI = PIN_SPI1_MOSI;
const int SCK = PIN_SPI1_SCK;
const uint32_t g_ADigitalPinMap[] = {
0xff, 0xff, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47
};
void initVariant() {
pinMode(PIN_PWR_EN, OUTPUT);
digitalWrite(PIN_PWR_EN, HIGH);
pinMode(PIN_BUTTON1, INPUT_PULLUP);
pinMode(PIN_BUTTON2, INPUT_PULLUP);
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
digitalWrite(LED_BLUE, HIGH);
pinMode(PIN_TXCO, OUTPUT);
digitalWrite(PIN_TXCO, HIGH);
// shutdown gps
pinMode(PIN_GPS_STANDBY, OUTPUT);
digitalWrite(PIN_GPS_STANDBY, LOW);
}

View file

@ -0,0 +1,133 @@
/*
* variant.h
* Copyright (C) 2023 Seeed K.K.
* MIT License
*/
#pragma once
#include "WVariant.h"
////////////////////////////////////////////////////////////////////////////////
// Low frequency clock source
#define USE_LFXO // 32.768 kHz crystal oscillator
#define VARIANT_MCK (64000000ul)
#define WIRE_INTERFACES_COUNT (1)
#define PIN_TXCO (21)
////////////////////////////////////////////////////////////////////////////////
// Power
#define PIN_PWR_EN (12)
#define BATTERY_PIN (4)
#define ADC_MULTIPLIER (4.90F)
#define ADC_RESOLUTION (14)
#define BATTERY_SENSE_RES (12)
#define AREF_VOLTAGE (3.0)
////////////////////////////////////////////////////////////////////////////////
// Number of pins
#define PINS_COUNT (48)
#define NUM_DIGITAL_PINS (48)
#define NUM_ANALOG_INPUTS (1)
#define NUM_ANALOG_OUTPUTS (0)
////////////////////////////////////////////////////////////////////////////////
// UART pin definition
#define PIN_SERIAL1_RX (41) // GPS TX
#define PIN_SERIAL1_TX (40) // GPS RX
////////////////////////////////////////////////////////////////////////////////
// I2C pin definition
#define PIN_WIRE_SDA (26) // P0.26
#define PIN_WIRE_SCL (27) // P0.27
////////////////////////////////////////////////////////////////////////////////
// SPI pin definition
#define SPI_INTERFACES_COUNT (2)
#define PIN_SPI_MISO (23)
#define PIN_SPI_MOSI (22)
#define PIN_SPI_SCK (19)
#define PIN_SPI_NSS (24)
////////////////////////////////////////////////////////////////////////////////
// Builtin LEDs
#define LED_RED (38)
#define LED_GREEN (36)
#define LED_BLUE (14)
#define PIN_STATUS_LED LED_GREEN
#define LED_BUILTIN LED_GREEN
#define PIN_LED LED_BUILTIN
#define LED_PIN LED_BUILTIN
#define LED_STATE_ON LOW
#define PIN_NEOPIXEL (14)
#define NEOPIXEL_NUM (2)
////////////////////////////////////////////////////////////////////////////////
// Builtin buttons
#define PIN_BUTTON1 (42)
#define BUTTON_PIN PIN_BUTTON1
#define PIN_USER_BTN BUTTON_PIN
#define PIN_BUTTON2 (11)
#define BUTTON_PIN2 PIN_BUTTON2
#define EXTERNAL_FLASH_DEVICES MX25R1635F
#define EXTERNAL_FLASH_USE_QSPI
////////////////////////////////////////////////////////////////////////////////
// Lora
#define USE_SX1262
#define LORA_CS (24)
#define SX126X_DIO1 (20)
#define SX126X_BUSY (17)
#define SX126X_RESET (25)
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
////////////////////////////////////////////////////////////////////////////////
// SPI1
#define PIN_SPI1_MISO (38)
#define PIN_SPI1_MOSI (29)
#define PIN_SPI1_SCK (31)
// GxEPD2 needs that for a panel that is not even used !
extern const int MISO;
extern const int MOSI;
extern const int SCK;
////////////////////////////////////////////////////////////////////////////////
// Display
#define DISP_MISO (38)
#define DISP_MOSI (29)
#define DISP_SCLK (31)
#define DISP_CS (30)
#define DISP_DC (28)
#define DISP_RST (2)
#define DISP_BUSY (3)
#define DISP_BACKLIGHT (43)
////////////////////////////////////////////////////////////////////////////////
// GPS
#define PIN_GPS_RX (41)
#define PIN_GPS_TX (40)
#define PIN_GPS_WAKEUP (34)
#define PIN_GPS_RESET (37)
#define PIN_GPS_PPS (36)
#define PIN_GPS_STANDBY (34)

View file

@ -0,0 +1,32 @@
[lora_e5]
extends = stm32_base
board = lora_e5_dev_board
board_upload.maximum_size = 229376 ; 32kb for FS
build_flags = ${stm32_base.build_flags}
-D RADIO_CLASS=CustomSTM32WLx
-D WRAPPER_CLASS=CustomSTM32WLxWrapper
-D SPI_INTERFACES_COUNT=0
-D RX_BOOSTED_GAIN=true
-I variants/wio-e5
build_src_filter = ${stm32_base.build_src_filter}
+<../variants/wio-e5>
[env:wio-e5-repeater]
extends = lora_e5
build_flags = ${lora_e5.build_flags}
-D LORA_TX_POWER=22
-D ADVERT_NAME='"WIO-E5 Repeater"'
-D ADMIN_PASSWORD='"password"'
build_src_filter = ${lora_e5.build_src_filter}
+<../examples/simple_repeater/main.cpp>
[env:wio-e5_companion_radio_usb]
extends = lora_e5
build_flags = ${lora_e5.build_flags}
-D LORA_TX_POWER=22
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
build_src_filter = ${lora_e5.build_src_filter}
+<../examples/companion_radio/*.cpp>
lib_deps = ${lora_e5.lib_deps}
densaugeo/base64 @ ~1.4.0

View file

@ -0,0 +1,73 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/ArduinoHelpers.h>
WIOE5Board board;
RADIO_CLASS radio = new STM32WLx_Module();
WRAPPER_CLASS radio_driver(radio, board);
static const uint32_t rfswitch_pins[] = {PA4, PA5, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC};
static const Module::RfSwitchMode_t rfswitch_table[] = {
{STM32WLx::MODE_IDLE, {LOW, LOW}},
{STM32WLx::MODE_RX, {HIGH, LOW}},
{STM32WLx::MODE_TX_HP, {LOW, HIGH}}, // for LoRa-E5 mini
// {STM32WLx::MODE_TX_LP, {HIGH, HIGH}}, // for LoRa-E5-LE mini
END_OF_MODE_TABLE,
};
VolatileRTCClock rtc_clock;
SensorManager sensors;
#ifndef LORA_CR
#define LORA_CR 5
#endif
bool radio_init() {
// rtc_clock.begin(Wire);
// #ifdef SX126X_DIO3_TCXO_VOLTAGE
// float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
// #else
// float tcxo = 1.6f;
// #endif
radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, 1.7, 0);
if (status != RADIOLIB_ERR_NONE) {
Serial.print("ERROR: radio init failed: ");
Serial.println(status);
return false; // fail
}
#ifdef RX_BOOSTED_GAIN
radio.setRxBoostedGainMode(RX_BOOSTED_GAIN);
#endif
radio.setCRC(1);
return true; // success
}
uint32_t radio_get_rng_seed() {
return radio.random(0x7FFFFFFF);
}
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
radio.setFrequency(freq);
radio.setSpreadingFactor(sf);
radio.setBandwidth(bw);
radio.setCodingRate(cr);
}
void radio_set_tx_power(uint8_t dbm) {
radio.setOutputPower(dbm);
}
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

27
variants/wio-e5/target.h Normal file
View file

@ -0,0 +1,27 @@
#pragma once
#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/RadioLibWrappers.h>
#include <helpers/stm32/STM32Board.h>
#include <helpers/CustomSTM32WLxWrapper.h>
#include <helpers/ArduinoHelpers.h>
#include <helpers/SensorManager.h>
class WIOE5Board : public STM32Board {
public:
const char* getManufacturerName() const override {
return "Seeed Wio E5";
}
};
extern WIOE5Board board;
extern WRAPPER_CLASS radio_driver;
extern VolatileRTCClock rtc_clock;
extern SensorManager sensors;
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

10
variants/wio-e5/variant.h Normal file
View file

@ -0,0 +1,10 @@
#pragma once
// UART Definitions
#ifndef SERIAL_UART_INSTANCE
#define SERIAL_UART_INSTANCE 101
#endif
#include <variant_LORA_E5_MINI.h>
#undef RNG

View file

@ -15,7 +15,7 @@ build_flags =
-D PIN_BOARD_SCL=D7
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=130.0f ; for best TX power!
-D SX126X_CURRENT_LIMIT=140
build_src_filter = ${esp32_base.build_src_filter}
+<../variants/xiao_c3>
@ -33,6 +33,7 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
lib_deps =
@ -52,6 +53,7 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
lib_deps =

View file

@ -14,6 +14,7 @@ WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifndef LORA_CR
#define LORA_CR 5

View file

@ -7,10 +7,12 @@
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/CustomSX1268Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
extern XiaoC3Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -16,6 +16,11 @@ lib_ignore =
lib_deps =
${nrf52_base.lib_deps}
rweather/Crypto @ ^0.4.0
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
[Xiao_nrf52]
extends = nrf52840_xiao
@ -27,10 +32,23 @@ build_flags = ${nrf52840_xiao.build_flags}
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=130
-D P_LORA_DIO_1=D1
-D P_LORA_RESET=D2
-D P_LORA_BUSY=D3
-D P_LORA_NSS=D4
-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 PIN_WIRE_SCL=6
-D PIN_WIRE_SDA=7
-D ENV_INCLUDE_AHTX0=1
-D ENV_INCLUDE_BME280=1
-D ENV_INCLUDE_INA3221=1
-D ENV_INCLUDE_INA219=1
build_src_filter = ${nrf52840_xiao.build_src_filter}
+<helpers/*.cpp>
+<helpers/sensors>
+<helpers/nrf52/XiaoNrf52Board.cpp>
+<../variants/xiao_nrf52>
debug_tool = jlink
@ -43,11 +61,27 @@ build_flags =
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D OFFLINE_QUEUE_SIZE=256
; -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
-D MESH_PACKET_LOGGING=1
-D MESH_DEBUG=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Xiao_nrf52.build_src_filter}
+<helpers/nrf52/SerialBLEInterface.cpp>
+<../examples/companion_radio/main.cpp>
lib_deps =
${Xiao_nrf52.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:Xiao_nrf52_companion_radio_usb]
extends = Xiao_nrf52
build_flags =
${Xiao_nrf52.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Xiao_nrf52.build_src_filter}
+<helpers/nrf52/SerialBLEInterface.cpp>
+<../examples/companion_radio/main.cpp>
@ -57,7 +91,7 @@ lib_deps =
[env:Xiao_nrf52_alt_pinout_companion_radio_ble]
extends = env:Xiao_nrf52_companion_radio_ble
build_flags =
build_flags =
${env:Xiao_nrf52_companion_radio_ble.build_flags}
-D SX1262_XIAO_S3_VARIANT
@ -69,6 +103,7 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Xiao_nrf52.build_src_filter}
@ -76,6 +111,19 @@ build_src_filter = ${Xiao_nrf52.build_src_filter}
[env:Xiao_nrf52_alt_pinout_repeater]
extends = env:Xiao_nrf52_repeater
build_flags =
build_flags =
${env:Xiao_nrf52_repeater.build_flags}
-D SX1262_XIAO_S3_VARIANT
-D SX1262_XIAO_S3_VARIANT
[env:Xiao_nrf52_room_server]
extends = Xiao_nrf52
build_flags =
${Xiao_nrf52.build_flags}
-D ADVERT_NAME='"Xiao_nrf52 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 = ${Xiao_nrf52.build_src_filter}
+<../examples/simple_room_server/main.cpp>

View file

@ -9,6 +9,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
WRAPPER_CLASS radio_driver(radio, board);
VolatileRTCClock rtc_clock;
EnvironmentSensorManager sensors;
#ifndef LORA_CR
#define LORA_CR 5

View file

@ -6,10 +6,12 @@
#include <helpers/nrf52/XiaoNrf52Board.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/ArduinoHelpers.h>
#include <helpers/sensors/EnvironmentSensorManager.h>
extern XiaoNrf52Board board;
extern WRAPPER_CLASS radio_driver;
extern VolatileRTCClock rtc_clock;
extern EnvironmentSensorManager sensors;
bool radio_init();
uint32_t radio_get_rng_seed();

View file

@ -98,20 +98,20 @@ static const uint8_t A5 = PIN_A5;
#define PIN_SPI_MOSI (10)
#define PIN_SPI_SCK (8)
static const uint8_t SS = D3; // NSS for sx ?
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK ;
#define PIN_SPI1_MISO (25)
#define PIN_SPI1_MOSI (26)
#define PIN_SPI1_SCK (29)
// 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 (17) // 4 and 5 are used for the sx1262 !
#define PIN_WIRE_SCL (16) // use WIRE1_SDA
// #define PIN_WIRE_SDA (17) // 4 and 5 are used for the sx1262 !
// #define PIN_WIRE_SCL (16) // use WIRE1_SDA
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;

View file

@ -17,7 +17,7 @@ build_flags = ${esp32_base.build_flags}
-D PIN_STATUS_LED=48
-D SX126X_DIO2_AS_RF_SWITCH=true
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=130
-D SX126X_CURRENT_LIMIT=140
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
@ -35,6 +35,7 @@ build_flags =
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=8
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
lib_deps =
@ -79,17 +80,21 @@ build_flags =
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D DISPLAY_CLASS=SSD1306Display
-D OFFLINE_QUEUE_SIZE=256
; -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Xiao_S3_WIO.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<helpers/esp32/*.cpp>
+<../examples/companion_radio/main.cpp>
+<../examples/companion_radio>
lib_deps =
${Xiao_S3_WIO.lib_deps}
densaugeo/base64 @ ~1.4.0
adafruit/Adafruit SSD1306 @ ^2.5.13
[env:Xiao_S3_WIO_companion_radio_serial]
extends = Xiao_S3_WIO
@ -107,25 +112,3 @@ build_src_filter = ${Xiao_S3_WIO.build_src_filter}
lib_deps =
${Xiao_S3_WIO.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:Xiao_S3_WIO_expansion_companion_radio_ble]
extends = Xiao_S3_WIO
build_flags =
${Xiao_S3_WIO.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D DISPLAY_CLASS=SSD1306Display
; -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${Xiao_S3_WIO.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<helpers/esp32/*.cpp>
+<../examples/companion_radio>
lib_deps =
${Xiao_S3_WIO.lib_deps}
densaugeo/base64 @ ~1.4.0
adafruit/Adafruit SSD1306 @ ^2.5.13

View file

@ -14,6 +14,11 @@ WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
#ifndef LORA_CR
#define LORA_CR 5

View file

@ -6,10 +6,19 @@
#include <helpers/ESP32Board.h>
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306Display.h>
#endif
extern ESP32Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;
#endif
bool radio_init();
uint32_t radio_get_rng_seed();