mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-03-30 12:45:45 +00:00
Compare commits
66 Commits
repeater-v
...
room-serve
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97b6a1874a | ||
|
|
05fa1ba50e | ||
|
|
fc6aa0ed0f | ||
|
|
75eabd5c66 | ||
|
|
2e5b4eb910 | ||
|
|
b77701ced0 | ||
|
|
0d5c17f7ed | ||
|
|
022b43ef3d | ||
|
|
89bd6c3416 | ||
|
|
ba93867037 | ||
|
|
c0cb57be5c | ||
|
|
2224bddcb5 | ||
|
|
9c165add61 | ||
|
|
d5cc28b0c5 | ||
|
|
8a248bb47d | ||
|
|
32edc934fa | ||
|
|
7cab681697 | ||
|
|
4d262e9e5d | ||
|
|
ee230ab2ca | ||
|
|
321a9425da | ||
|
|
88b88cbc90 | ||
|
|
753e6a69dc | ||
|
|
d32e641225 | ||
|
|
1220c69aa9 | ||
|
|
8355543366 | ||
|
|
7bd7bfb14a | ||
|
|
f33e1b22b3 | ||
|
|
16039eebfb | ||
|
|
0d9201b560 | ||
|
|
02edc645bb | ||
|
|
ac71bac4cf | ||
|
|
1677d4db65 | ||
|
|
0d114ecfbd | ||
|
|
edb201ccbe | ||
|
|
d07abc39b6 | ||
|
|
39a4476194 | ||
|
|
7010123619 | ||
|
|
f861b68a09 | ||
|
|
a4bb3782a4 | ||
|
|
30c6a0bc76 | ||
|
|
2b8b6aacbb | ||
|
|
1ff3033372 | ||
|
|
0163c4034b | ||
|
|
965e40eb9e | ||
|
|
bfb4b1c496 | ||
|
|
e1d8179f72 | ||
|
|
1299b6f813 | ||
|
|
8b4662a40a | ||
|
|
ae08ecf8fd | ||
|
|
0a5a115875 | ||
|
|
41e01a0e25 | ||
|
|
390e8407c0 | ||
|
|
182c6d479d | ||
|
|
de67ee29eb | ||
|
|
1c14482bd4 | ||
|
|
61f7f15dc1 | ||
|
|
bd0ce731f1 | ||
|
|
74ec702136 | ||
|
|
a9dde51a9b | ||
|
|
6a78cfd00d | ||
|
|
f671b753da | ||
|
|
88dfa42e47 | ||
|
|
86ece04fe2 | ||
|
|
d59b1d235e | ||
|
|
a67bb8e1e3 | ||
|
|
8b2f783d04 |
21
arch/esp32/AsyncElegantOTA/LICENSE
Normal file
21
arch/esp32/AsyncElegantOTA/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Ayush Sharma
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
2
arch/esp32/AsyncElegantOTA/keywords.txt
Normal file
2
arch/esp32/AsyncElegantOTA/keywords.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
AsyncElegantOTA KEYWORD1
|
||||
begin KEYWORD2
|
||||
9
arch/esp32/AsyncElegantOTA/library.properties
Normal file
9
arch/esp32/AsyncElegantOTA/library.properties
Normal file
@@ -0,0 +1,9 @@
|
||||
name=AsyncElegantOTA
|
||||
version=2.2.8
|
||||
author=Ayush Sharma
|
||||
category=Communication
|
||||
maintainer=Ayush Sharma <asrocks5@gmail.com>
|
||||
sentence=Perform OTAs for ESP8266 & ESP32 Asynchronously.
|
||||
paragraph=A User Interface Library which provides interactive elements for your Over the Air Updates on ESP8266/ESP32.
|
||||
url=https://github.com/ayushsharma82/AsyncElegantOTA
|
||||
architectures=esp8266,esp32
|
||||
129
arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.cpp
Normal file
129
arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
#include <AsyncElegantOTA.h>
|
||||
|
||||
AsyncElegantOtaClass AsyncElegantOTA;
|
||||
|
||||
void AsyncElegantOtaClass::setID(const char* id){
|
||||
_id = id;
|
||||
}
|
||||
|
||||
void AsyncElegantOtaClass::begin(AsyncWebServer *server, const char* username, const char* password){
|
||||
_server = server;
|
||||
|
||||
if(strlen(username) > 0){
|
||||
_authRequired = true;
|
||||
_username = username;
|
||||
_password = password;
|
||||
}else{
|
||||
_authRequired = false;
|
||||
_username = "";
|
||||
_password = "";
|
||||
}
|
||||
|
||||
_server->on("/update/identity", HTTP_GET, [&](AsyncWebServerRequest *request){
|
||||
if(_authRequired){
|
||||
if(!request->authenticate(_username.c_str(), _password.c_str())){
|
||||
return request->requestAuthentication();
|
||||
}
|
||||
}
|
||||
#if defined(ESP8266)
|
||||
request->send(200, "application/json", "{\"id\": \""+_id+"\", \"hardware\": \"ESP8266\"}");
|
||||
#elif defined(ESP32)
|
||||
request->send(200, "application/json", "{\"id\": \""+_id+"\", \"hardware\": \"ESP32\"}");
|
||||
#endif
|
||||
});
|
||||
|
||||
_server->on("/update", HTTP_GET, [&](AsyncWebServerRequest *request){
|
||||
if(_authRequired){
|
||||
if(!request->authenticate(_username.c_str(), _password.c_str())){
|
||||
return request->requestAuthentication();
|
||||
}
|
||||
}
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", ELEGANT_HTML, ELEGANT_HTML_SIZE);
|
||||
response->addHeader("Content-Encoding", "gzip");
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
_server->on("/update", HTTP_POST, [&](AsyncWebServerRequest *request) {
|
||||
if(_authRequired){
|
||||
if(!request->authenticate(_username.c_str(), _password.c_str())){
|
||||
return request->requestAuthentication();
|
||||
}
|
||||
}
|
||||
// the request handler is triggered after the upload has finished...
|
||||
// create the response, add header, and send response
|
||||
AsyncWebServerResponse *response = request->beginResponse((Update.hasError())?500:200, "text/plain", (Update.hasError())?"FAIL":"OK");
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Access-Control-Allow-Origin", "*");
|
||||
request->send(response);
|
||||
restart();
|
||||
}, [&](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||
//Upload handler chunks in data
|
||||
if(_authRequired){
|
||||
if(!request->authenticate(_username.c_str(), _password.c_str())){
|
||||
return request->requestAuthentication();
|
||||
}
|
||||
}
|
||||
|
||||
if (!index) {
|
||||
if(!request->hasParam("MD5", true)) {
|
||||
return request->send(400, "text/plain", "MD5 parameter missing");
|
||||
}
|
||||
|
||||
if(!Update.setMD5(request->getParam("MD5", true)->value().c_str())) {
|
||||
return request->send(400, "text/plain", "MD5 parameter invalid");
|
||||
}
|
||||
|
||||
#if defined(ESP8266)
|
||||
int cmd = (filename == "filesystem") ? U_FS : U_FLASH;
|
||||
Update.runAsync(true);
|
||||
size_t fsSize = ((size_t) &_FS_end - (size_t) &_FS_start);
|
||||
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
|
||||
if (!Update.begin((cmd == U_FS)?fsSize:maxSketchSpace, cmd)){ // Start with max available size
|
||||
#elif defined(ESP32)
|
||||
int cmd = (filename == "filesystem") ? U_SPIFFS : U_FLASH;
|
||||
if (!Update.begin(UPDATE_SIZE_UNKNOWN, cmd)) { // Start with max available size
|
||||
#endif
|
||||
Update.printError(Serial);
|
||||
return request->send(400, "text/plain", "OTA could not begin");
|
||||
}
|
||||
}
|
||||
|
||||
// Write chunked data to the free sketch space
|
||||
if(len){
|
||||
if (Update.write(data, len) != len) {
|
||||
return request->send(400, "text/plain", "OTA could not begin");
|
||||
}
|
||||
}
|
||||
|
||||
if (final) { // if the final flag is set then this is the last frame of data
|
||||
if (!Update.end(true)) { //true to set the size to the current progress
|
||||
Update.printError(Serial);
|
||||
return request->send(400, "text/plain", "Could not end OTA");
|
||||
}
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// deprecated, keeping for backward compatibility
|
||||
void AsyncElegantOtaClass::loop() {
|
||||
}
|
||||
|
||||
void AsyncElegantOtaClass::restart() {
|
||||
yield();
|
||||
delay(1000);
|
||||
yield();
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
String AsyncElegantOtaClass::getID(){
|
||||
String id = "";
|
||||
#if defined(ESP8266)
|
||||
id = String(ESP.getChipId());
|
||||
#elif defined(ESP32)
|
||||
id = String((uint32_t)ESP.getEfuseMac(), HEX);
|
||||
#endif
|
||||
id.toUpperCase();
|
||||
return id;
|
||||
}
|
||||
52
arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.h
Normal file
52
arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef AsyncElegantOTA_h
|
||||
#define AsyncElegantOTA_h
|
||||
|
||||
#warning AsyncElegantOTA library is deprecated, Please consider moving to newer ElegantOTA library which now comes with an Async Mode. Learn More: https://docs.elegantota.pro/async-mode/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "stdlib_noniso.h"
|
||||
|
||||
#if defined(ESP8266)
|
||||
#include "ESP8266WiFi.h"
|
||||
#include "ESPAsyncTCP.h"
|
||||
#include "flash_hal.h"
|
||||
#include "FS.h"
|
||||
#elif defined(ESP32)
|
||||
#include "WiFi.h"
|
||||
#include "AsyncTCP.h"
|
||||
#include "Update.h"
|
||||
#include "esp_int_wdt.h"
|
||||
#include "esp_task_wdt.h"
|
||||
#endif
|
||||
|
||||
#include "Hash.h"
|
||||
#include "ESPAsyncWebServer.h"
|
||||
#include "FS.h"
|
||||
|
||||
#include "elegantWebpage.h"
|
||||
|
||||
|
||||
class AsyncElegantOtaClass{
|
||||
|
||||
public:
|
||||
void
|
||||
setID(const char* id),
|
||||
begin(AsyncWebServer *server, const char* username = "", const char* password = ""),
|
||||
loop(),
|
||||
restart();
|
||||
|
||||
private:
|
||||
AsyncWebServer *_server;
|
||||
|
||||
String getID();
|
||||
|
||||
String _id = getID();
|
||||
String _username = "";
|
||||
String _password = "";
|
||||
bool _authRequired = false;
|
||||
|
||||
};
|
||||
|
||||
extern AsyncElegantOtaClass AsyncElegantOTA;
|
||||
|
||||
#endif
|
||||
38
arch/esp32/AsyncElegantOTA/src/Hash.h
Normal file
38
arch/esp32/AsyncElegantOTA/src/Hash.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file Hash.h
|
||||
* @date 20.05.2015
|
||||
* @author Markus Sattler
|
||||
*
|
||||
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
* This file is part of the esp8266 core for Arduino environment.
|
||||
*
|
||||
* 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 HASH_H_
|
||||
#define HASH_H_
|
||||
|
||||
//#define DEBUG_SHA1
|
||||
|
||||
void sha1(const uint8_t* data, uint32_t size, uint8_t hash[20]);
|
||||
void sha1(const char* data, uint32_t size, uint8_t hash[20]);
|
||||
void sha1(const String& data, uint8_t hash[20]);
|
||||
|
||||
String sha1(const uint8_t* data, uint32_t size);
|
||||
String sha1(const char* data, uint32_t size);
|
||||
String sha1(const String& data);
|
||||
|
||||
#endif /* HASH_H_ */
|
||||
1799
arch/esp32/AsyncElegantOTA/src/elegantWebpage.h
Normal file
1799
arch/esp32/AsyncElegantOTA/src/elegantWebpage.h
Normal file
File diff suppressed because it is too large
Load Diff
2
build.sh
2
build.sh
@@ -58,7 +58,7 @@ build_firmware() {
|
||||
fi
|
||||
|
||||
# build .uf2 for nrf52 boards
|
||||
if [[ $1 == *"RAK_4631"* || $1 == *"t1000e"* || $1 == *"t114"* || $1 == *"T-Echo"* ]]; then
|
||||
if [[ $1 == *"RAK_4631"* || $1 == *"t1000e"* || $1 == *"t114"* || $1 == *"T-Echo"* || $1 == *"Faketec"* || $1 == *"ProMicro"* ]]; then
|
||||
python bin/uf2conv/uf2conv.py .pio/build/$1/firmware.hex -c -o .pio/build/$1/firmware.uf2 -f 0xADA52840
|
||||
fi
|
||||
|
||||
|
||||
@@ -7,15 +7,13 @@
|
||||
#include <SPIFFS.h>
|
||||
#endif
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
#include <helpers/StaticPoolPacketManager.h>
|
||||
#include <helpers/SimpleMeshTables.h>
|
||||
#include <helpers/IdentityStore.h>
|
||||
#include <helpers/BaseSerialInterface.h>
|
||||
#include <RTClib.h>
|
||||
#include <target.h>
|
||||
|
||||
/* ---------------------------------- CONFIGURATION ------------------------------------- */
|
||||
|
||||
@@ -59,59 +57,6 @@
|
||||
|
||||
#define PUBLIC_GROUP_PSK "izOH6cXN6mrJ5e26oRXNcg=="
|
||||
|
||||
#if defined(HELTEC_LORA_V3)
|
||||
#include <helpers/HeltecV3Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static HeltecV3Board board;
|
||||
#elif defined(HELTEC_LORA_V2)
|
||||
#include <helpers/HeltecV2Board.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
static HeltecV2Board board;
|
||||
#elif defined(ARDUINO_XIAO_ESP32C3)
|
||||
#include <helpers/XiaoC3Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/CustomSX1268Wrapper.h>
|
||||
static XiaoC3Board board;
|
||||
#elif defined(SEEED_XIAO_S3) || defined(LILYGO_T3S3)
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static ESP32Board board;
|
||||
#elif defined(LILYGO_TLORA)
|
||||
#include <helpers/LilyGoTLoraBoard.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
static LilyGoTLoraBoard board;
|
||||
#elif defined(RAK_4631)
|
||||
#include <helpers/nrf52/RAK4631Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static RAK4631Board board;
|
||||
#elif defined(T1000_E)
|
||||
#include <helpers/nrf52/T1000eBoard.h>
|
||||
#include <helpers/CustomLR1110Wrapper.h>
|
||||
static T1000eBoard board;
|
||||
#elif defined(HELTEC_T114)
|
||||
#include <helpers/nrf52/T114Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static T114Board board;
|
||||
#elif defined(LILYGO_TECHO)
|
||||
#include <helpers/nrf52/TechoBoard.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static TechoBoard board;
|
||||
|
||||
#elif defined(LILYGO_TBEAM)
|
||||
#include <helpers/TBeamBoard.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
static TBeamBoard board;
|
||||
|
||||
#elif defined(FAKETEC)
|
||||
#include <helpers/nrf52/faketecBoard.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/CustomLLCC68Wrapper.h>
|
||||
static faketecBoard board;
|
||||
|
||||
#else
|
||||
#error "need to provide a 'board' object"
|
||||
#endif
|
||||
|
||||
#ifdef DISPLAY_CLASS
|
||||
#include "UITask.h"
|
||||
#include <helpers/ui/SSD1306Display.h>
|
||||
@@ -141,11 +86,11 @@ static uint32_t _atoi(const char* sp) {
|
||||
#define FIRMWARE_VER_CODE 3
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "19 Mar 2025"
|
||||
#define FIRMWARE_BUILD_DATE "30 Mar 2025"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.4.0"
|
||||
#define FIRMWARE_VERSION "v1.4.2"
|
||||
#endif
|
||||
|
||||
#define CMD_APP_START 1
|
||||
@@ -249,7 +194,6 @@ struct NodePrefs { // persisted to file
|
||||
|
||||
class MyMesh : public BaseChatMesh {
|
||||
FILESYSTEM* _fs;
|
||||
RADIO_CLASS* _phy;
|
||||
IdentityStore* _identity_store;
|
||||
NodePrefs _prefs;
|
||||
uint32_t pending_login;
|
||||
@@ -281,9 +225,9 @@ class MyMesh : public BaseChatMesh {
|
||||
AckTableEntry expected_ack_table[EXPECTED_ACK_TABLE_SIZE]; // circular table
|
||||
int next_ack_idx;
|
||||
|
||||
void loadMainIdentity(mesh::RNG& trng) {
|
||||
void loadMainIdentity() {
|
||||
if (!_identity_store->load("_main", self_id)) {
|
||||
self_id = mesh::LocalIdentity(&trng); // create new random identity
|
||||
self_id = radio_new_identity(); // create new random identity
|
||||
saveMainIdentity(self_id);
|
||||
}
|
||||
}
|
||||
@@ -540,7 +484,7 @@ protected:
|
||||
}
|
||||
|
||||
void logRxRaw(float snr, float rssi, const uint8_t raw[], int len) override {
|
||||
if (_serial->isConnected()) {
|
||||
if (_serial->isConnected() && len+3 <= MAX_FRAME_SIZE) {
|
||||
int i = 0;
|
||||
out_frame[i++] = PUSH_CODE_LOG_RX_DATA;
|
||||
out_frame[i++] = (int8_t)(snr * 4);
|
||||
@@ -739,7 +683,7 @@ protected:
|
||||
memcpy(&out_frame[i], &auth_code, 4); i += 4;
|
||||
memcpy(&out_frame[i], path_hashes, path_len); i += path_len;
|
||||
memcpy(&out_frame[i], path_snrs, path_len); i += path_len;
|
||||
out_frame[i++] = (int8_t)(_radio->getLastSNR() * 4); // extra/final SNR (to this node)
|
||||
out_frame[i++] = (int8_t)(packet->getSNR() * 4); // extra/final SNR (to this node)
|
||||
|
||||
if (_serial->isConnected()) {
|
||||
_serial->writeFrame(out_frame, i);
|
||||
@@ -761,8 +705,8 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
MyMesh(RADIO_CLASS& phy, RadioLibWrapper& rw, mesh::RNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables)
|
||||
: BaseChatMesh(rw, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables), _serial(NULL), _phy(&phy)
|
||||
MyMesh(mesh::Radio& radio, mesh::RNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables)
|
||||
: BaseChatMesh(radio, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables), _serial(NULL)
|
||||
{
|
||||
_iter_started = false;
|
||||
offline_queue_len = 0;
|
||||
@@ -784,7 +728,42 @@ public:
|
||||
//_prefs.rx_delay_base = 10.0f; enable once new algo fixed
|
||||
}
|
||||
|
||||
void begin(FILESYSTEM& fs, mesh::RNG& trng, bool has_display) {
|
||||
void loadPrefsInt(const char* filename) {
|
||||
File file = _fs->open(filename);
|
||||
if (file) {
|
||||
uint8_t pad[8];
|
||||
|
||||
file.read((uint8_t *) &_prefs.airtime_factor, sizeof(float)); // 0
|
||||
file.read((uint8_t *) _prefs.node_name, sizeof(_prefs.node_name)); // 4
|
||||
file.read(pad, 4); // 36
|
||||
file.read((uint8_t *) &_prefs.node_lat, sizeof(_prefs.node_lat)); // 40
|
||||
file.read((uint8_t *) &_prefs.node_lon, sizeof(_prefs.node_lon)); // 48
|
||||
file.read((uint8_t *) &_prefs.freq, sizeof(_prefs.freq)); // 56
|
||||
file.read((uint8_t *) &_prefs.sf, sizeof(_prefs.sf)); // 60
|
||||
file.read((uint8_t *) &_prefs.cr, sizeof(_prefs.cr)); // 61
|
||||
file.read((uint8_t *) &_prefs.reserved1, sizeof(_prefs.reserved1)); // 62
|
||||
file.read((uint8_t *) &_prefs.reserved2, sizeof(_prefs.reserved2)); // 63
|
||||
file.read((uint8_t *) &_prefs.bw, sizeof(_prefs.bw)); // 64
|
||||
file.read((uint8_t *) &_prefs.tx_power_dbm, sizeof(_prefs.tx_power_dbm)); // 68
|
||||
file.read((uint8_t *) _prefs.unused, sizeof(_prefs.unused)); // 69
|
||||
file.read((uint8_t *) &_prefs.rx_delay_base, sizeof(_prefs.rx_delay_base)); // 72
|
||||
file.read(pad, 4); // 76
|
||||
file.read((uint8_t *) &_prefs.ble_pin, sizeof(_prefs.ble_pin)); // 80
|
||||
|
||||
// sanitise bad pref values
|
||||
_prefs.rx_delay_base = constrain(_prefs.rx_delay_base, 0, 20.0f);
|
||||
_prefs.airtime_factor = constrain(_prefs.airtime_factor, 0, 9.0f);
|
||||
_prefs.freq = constrain(_prefs.freq, 400.0f, 2500.0f);
|
||||
_prefs.bw = constrain(_prefs.bw, 62.5f, 500.0f);
|
||||
_prefs.sf = constrain(_prefs.sf, 7, 12);
|
||||
_prefs.cr = constrain(_prefs.cr, 5, 8);
|
||||
_prefs.tx_power_dbm = constrain(_prefs.tx_power_dbm, 1, MAX_LORA_TX_POWER);
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void begin(FILESYSTEM& fs, bool has_display) {
|
||||
_fs = &fs;
|
||||
|
||||
BaseChatMesh::begin();
|
||||
@@ -795,49 +774,23 @@ public:
|
||||
_identity_store = new IdentityStore(fs, "/identity");
|
||||
#endif
|
||||
|
||||
loadMainIdentity(trng);
|
||||
loadMainIdentity();
|
||||
|
||||
// load persisted prefs
|
||||
if (_fs->exists("/node_prefs")) {
|
||||
File file = _fs->open("/node_prefs");
|
||||
if (file) {
|
||||
uint8_t pad[8];
|
||||
|
||||
file.read((uint8_t *) &_prefs.airtime_factor, sizeof(float)); // 0
|
||||
file.read((uint8_t *) _prefs.node_name, sizeof(_prefs.node_name)); // 4
|
||||
file.read(pad, 4); // 36
|
||||
file.read((uint8_t *) &_prefs.node_lat, sizeof(_prefs.node_lat)); // 40
|
||||
file.read((uint8_t *) &_prefs.node_lon, sizeof(_prefs.node_lon)); // 48
|
||||
file.read((uint8_t *) &_prefs.freq, sizeof(_prefs.freq)); // 56
|
||||
file.read((uint8_t *) &_prefs.sf, sizeof(_prefs.sf)); // 60
|
||||
file.read((uint8_t *) &_prefs.cr, sizeof(_prefs.cr)); // 61
|
||||
file.read((uint8_t *) &_prefs.reserved1, sizeof(_prefs.reserved1)); // 62
|
||||
file.read((uint8_t *) &_prefs.reserved2, sizeof(_prefs.reserved2)); // 63
|
||||
file.read((uint8_t *) &_prefs.bw, sizeof(_prefs.bw)); // 64
|
||||
file.read((uint8_t *) &_prefs.tx_power_dbm, sizeof(_prefs.tx_power_dbm)); // 68
|
||||
file.read((uint8_t *) _prefs.unused, sizeof(_prefs.unused)); // 69
|
||||
file.read((uint8_t *) &_prefs.rx_delay_base, sizeof(_prefs.rx_delay_base)); // 72
|
||||
file.read(pad, 4); // 76
|
||||
file.read((uint8_t *) &_prefs.ble_pin, sizeof(_prefs.ble_pin)); // 80
|
||||
|
||||
// sanitise bad pref values
|
||||
_prefs.rx_delay_base = constrain(_prefs.rx_delay_base, 0, 20.0f);
|
||||
_prefs.airtime_factor = constrain(_prefs.airtime_factor, 0, 9.0f);
|
||||
_prefs.freq = constrain(_prefs.freq, 400.0f, 2500.0f);
|
||||
_prefs.bw = constrain(_prefs.bw, 62.5f, 500.0f);
|
||||
_prefs.sf = constrain(_prefs.sf, 7, 12);
|
||||
_prefs.cr = constrain(_prefs.cr, 5, 8);
|
||||
_prefs.tx_power_dbm = constrain(_prefs.tx_power_dbm, 1, MAX_LORA_TX_POWER);
|
||||
|
||||
file.close();
|
||||
}
|
||||
if (_fs->exists("/new_prefs")) {
|
||||
loadPrefsInt("/new_prefs"); // new filename
|
||||
} else if (_fs->exists("/node_prefs")) {
|
||||
loadPrefsInt("/node_prefs");
|
||||
savePrefs(); // save to new filename
|
||||
_fs->remove("/node_prefs"); // remove old
|
||||
}
|
||||
|
||||
#ifdef BLE_PIN_CODE
|
||||
if (_prefs.ble_pin == 0) {
|
||||
#ifdef HAS_UI
|
||||
if (has_display) {
|
||||
_active_ble_pin = trng.nextInt(100000, 999999); // random pin each session
|
||||
StdRNG rng;
|
||||
_active_ble_pin = rng.nextInt(100000, 999999); // random pin each session
|
||||
} else {
|
||||
_active_ble_pin = BLE_PIN_CODE; // otherwise static pin
|
||||
}
|
||||
@@ -858,11 +811,8 @@ public:
|
||||
addChannel("Public", PUBLIC_GROUP_PSK); // pre-configure Andy's public channel
|
||||
loadChannels();
|
||||
|
||||
_phy->setFrequency(_prefs.freq);
|
||||
_phy->setSpreadingFactor(_prefs.sf);
|
||||
_phy->setBandwidth(_prefs.bw);
|
||||
_phy->setCodingRate(_prefs.cr);
|
||||
_phy->setOutputPower(_prefs.tx_power_dbm);
|
||||
radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
|
||||
radio_set_tx_power(_prefs.tx_power_dbm);
|
||||
}
|
||||
|
||||
const char* getNodeName() { return _prefs.node_name; }
|
||||
@@ -875,10 +825,10 @@ public:
|
||||
|
||||
void savePrefs() {
|
||||
#if defined(NRF52_PLATFORM)
|
||||
File file = _fs->open("/node_prefs", FILE_O_WRITE);
|
||||
File file = _fs->open("/new_prefs", FILE_O_WRITE);
|
||||
if (file) { file.seek(0); file.truncate(); }
|
||||
#else
|
||||
File file = _fs->open("/node_prefs", "w", true);
|
||||
File file = _fs->open("/new_prefs", "w", true);
|
||||
#endif
|
||||
if (file) {
|
||||
uint8_t pad[8];
|
||||
@@ -959,7 +909,7 @@ public:
|
||||
memcpy(&msg_timestamp, &cmd_frame[i], 4); i += 4;
|
||||
uint8_t* pub_key_prefix = &cmd_frame[i]; i += 6;
|
||||
ContactInfo* recipient = lookupContactByPubKey(pub_key_prefix, 6);
|
||||
if (recipient && attempt < 4 && (txt_type == TXT_TYPE_PLAIN || txt_type == TXT_TYPE_CLI_DATA)) {
|
||||
if (recipient && (txt_type == TXT_TYPE_PLAIN || txt_type == TXT_TYPE_CLI_DATA)) {
|
||||
char *text = (char *) &cmd_frame[i];
|
||||
int tlen = len - i;
|
||||
uint32_t est_timeout;
|
||||
@@ -1197,10 +1147,7 @@ public:
|
||||
_prefs.bw = (float)bw / 1000.0;
|
||||
savePrefs();
|
||||
|
||||
_phy->setFrequency(_prefs.freq);
|
||||
_phy->setSpreadingFactor(_prefs.sf);
|
||||
_phy->setBandwidth(_prefs.bw);
|
||||
_phy->setCodingRate(_prefs.cr);
|
||||
radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
|
||||
MESH_DEBUG_PRINTLN("OK: CMD_SET_RADIO_PARAMS: f=%d, bw=%d, sf=%d, cr=%d", freq, bw, (uint32_t)sf, (uint32_t)cr);
|
||||
|
||||
writeOKFrame();
|
||||
@@ -1214,7 +1161,7 @@ public:
|
||||
} else {
|
||||
_prefs.tx_power_dbm = cmd_frame[1];
|
||||
savePrefs();
|
||||
_phy->setOutputPower(_prefs.tx_power_dbm);
|
||||
radio_set_tx_power(_prefs.tx_power_dbm);
|
||||
writeOKFrame();
|
||||
}
|
||||
} else if (cmd_frame[0] == CMD_SET_TUNING_PARAMS) {
|
||||
@@ -1473,23 +1420,9 @@ public:
|
||||
#error "need to define a serial interface"
|
||||
#endif
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
|
||||
#elif defined(LILYGO_TLORA)
|
||||
SPIClass spi;
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi);
|
||||
#elif defined(LILYGO_TBEAM)
|
||||
SPIClass spi;
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi);
|
||||
#elif defined(P_LORA_SCLK)
|
||||
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
|
||||
StdRNG fast_rng;
|
||||
SimpleMeshTables tables;
|
||||
MyMesh the_mesh(radio, *new WRAPPER_CLASS(radio, board), fast_rng, *new VolatileRTCClock(), tables);
|
||||
MyMesh the_mesh(radio_driver, fast_rng, *new VolatileRTCClock(), tables); // TODO: test with 'rtc_clock' in target.cpp
|
||||
|
||||
void halt() {
|
||||
while (1) ;
|
||||
@@ -1499,47 +1432,10 @@ void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
board.begin();
|
||||
#ifdef SX126X_DIO3_TCXO_VOLTAGE
|
||||
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
|
||||
#else
|
||||
float tcxo = 1.6f;
|
||||
#endif
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI);
|
||||
SPI.begin();
|
||||
#elif 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 defined(FAKETEC)
|
||||
if (status == RADIOLIB_ERR_SPI_CMD_FAILED || status == RADIOLIB_ERR_SPI_CMD_INVALID) {
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE (0.0f);
|
||||
tcxo = SX126X_DIO3_TCXO_VOLTAGE;
|
||||
status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo);
|
||||
}
|
||||
#endif
|
||||
if (status != RADIOLIB_ERR_NONE) {
|
||||
Serial.print("ERROR: radio init failed: ");
|
||||
Serial.println(status);
|
||||
halt();
|
||||
}
|
||||
if (!radio_init()) { halt(); }
|
||||
|
||||
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
|
||||
|
||||
fast_rng.begin(radio.random(0x7FFFFFFF));
|
||||
|
||||
RadioNoiseListener trng(radio);
|
||||
fast_rng.begin(radio_get_rng_seed());
|
||||
|
||||
#ifdef HAS_UI
|
||||
DisplayDriver* disp = NULL;
|
||||
@@ -1552,7 +1448,7 @@ void setup() {
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
InternalFS.begin();
|
||||
the_mesh.begin(InternalFS, trng,
|
||||
the_mesh.begin(InternalFS,
|
||||
#ifdef HAS_UI
|
||||
disp != NULL
|
||||
#else
|
||||
@@ -1570,7 +1466,7 @@ void setup() {
|
||||
the_mesh.startInterface(serial_interface);
|
||||
#elif defined(ESP32)
|
||||
SPIFFS.begin(true);
|
||||
the_mesh.begin(SPIFFS, trng,
|
||||
the_mesh.begin(SPIFFS,
|
||||
#ifdef HAS_UI
|
||||
disp != NULL
|
||||
#else
|
||||
|
||||
@@ -7,26 +7,24 @@
|
||||
#include <SPIFFS.h>
|
||||
#endif
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
#include <helpers/StaticPoolPacketManager.h>
|
||||
#include <helpers/SimpleMeshTables.h>
|
||||
#include <helpers/IdentityStore.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
#include <helpers/AdvertDataHelpers.h>
|
||||
#include <helpers/TxtDataHelpers.h>
|
||||
#include <helpers/CommonCLI.h>
|
||||
#include <RTClib.h>
|
||||
#include <target.h>
|
||||
|
||||
/* ------------------------------ Config -------------------------------- */
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "19 Mar 2025"
|
||||
#define FIRMWARE_BUILD_DATE "30 Mar 2025"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.4.0"
|
||||
#define FIRMWARE_VERSION "v1.4.2"
|
||||
#endif
|
||||
|
||||
#ifndef LORA_FREQ
|
||||
@@ -59,52 +57,6 @@
|
||||
#define ADMIN_PASSWORD "password"
|
||||
#endif
|
||||
|
||||
#if defined(HELTEC_LORA_V3)
|
||||
#include <helpers/HeltecV3Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static HeltecV3Board board;
|
||||
#elif defined(HELTEC_LORA_V2)
|
||||
#include <helpers/HeltecV2Board.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
static HeltecV2Board board;
|
||||
#elif defined(ARDUINO_XIAO_ESP32C3)
|
||||
#include <helpers/XiaoC3Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/CustomSX1268Wrapper.h>
|
||||
static XiaoC3Board board;
|
||||
#elif defined(SEEED_XIAO_S3) || defined(LILYGO_T3S3)
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static ESP32Board board;
|
||||
#elif defined(LILYGO_TLORA)
|
||||
#include <helpers/LilyGoTLoraBoard.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
static LilyGoTLoraBoard board;
|
||||
#elif defined(STATION_G2)
|
||||
#include <helpers/StationG2Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static StationG2Board board;
|
||||
#elif defined(RAK_4631)
|
||||
#include <helpers/nrf52/RAK4631Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static RAK4631Board board;
|
||||
#elif defined(HELTEC_T114)
|
||||
#include <helpers/nrf52/T114Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static T114Board board;
|
||||
#elif defined(LILYGO_TECHO)
|
||||
#include <helpers/nrf52/TechoBoard.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static TechoBoard board;
|
||||
#elif defined(FAKETEC)
|
||||
#include <helpers/nrf52/faketecBoard.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/CustomLLCC68Wrapper.h>
|
||||
static faketecBoard board;
|
||||
#else
|
||||
#error "need to provide a 'board' object"
|
||||
#endif
|
||||
|
||||
#ifdef DISPLAY_CLASS
|
||||
#include <helpers/ui/SSD1306Display.h>
|
||||
|
||||
@@ -114,6 +66,8 @@
|
||||
static UITask ui_task(display);
|
||||
#endif
|
||||
|
||||
#define FIRMWARE_ROLE "repeater"
|
||||
|
||||
#define PACKET_LOG_FILE "/packet_log"
|
||||
|
||||
/* ------------------------------ Code -------------------------------- */
|
||||
@@ -153,11 +107,8 @@ struct ClientInfo {
|
||||
#define CLI_REPLY_DELAY_MILLIS 1500
|
||||
|
||||
class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
||||
RadioLibWrapper* my_radio;
|
||||
FILESYSTEM* _fs;
|
||||
RADIO_CLASS* _phy;
|
||||
mesh::MainBoard* _board;
|
||||
unsigned long next_local_advert;
|
||||
unsigned long next_local_advert, next_flood_advert;
|
||||
bool _logging;
|
||||
NodePrefs _prefs;
|
||||
CommonCLI _cli;
|
||||
@@ -192,9 +143,9 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
||||
stats.batt_milli_volts = board.getBattMilliVolts();
|
||||
stats.curr_tx_queue_len = _mgr->getOutboundCount();
|
||||
stats.curr_free_queue_len = _mgr->getFreeCount();
|
||||
stats.last_rssi = (int16_t) my_radio->getLastRSSI();
|
||||
stats.n_packets_recv = my_radio->getPacketsRecv();
|
||||
stats.n_packets_sent = my_radio->getPacketsSent();
|
||||
stats.last_rssi = (int16_t) radio_driver.getLastRSSI();
|
||||
stats.n_packets_recv = radio_driver.getPacketsRecv();
|
||||
stats.n_packets_sent = radio_driver.getPacketsSent();
|
||||
stats.total_air_time_secs = getTotalAirTime() / 1000;
|
||||
stats.total_up_time_secs = _ms->getMillis() / 1000;
|
||||
stats.n_sent_flood = getNumSentFlood();
|
||||
@@ -202,7 +153,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
||||
stats.n_recv_flood = getNumRecvFlood();
|
||||
stats.n_recv_direct = getNumRecvDirect();
|
||||
stats.n_full_events = getNumFullEvents();
|
||||
stats.last_snr = (int16_t)(my_radio->getLastSNR() * 4);
|
||||
stats.last_snr = (int16_t)(radio_driver.getLastSNR() * 4);
|
||||
stats.n_direct_dups = ((SimpleMeshTables *)getTables())->getNumDirectDups();
|
||||
stats.n_flood_dups = ((SimpleMeshTables *)getTables())->getNumFloodDups();
|
||||
|
||||
@@ -519,13 +470,12 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
MyMesh(RADIO_CLASS& phy, mesh::MainBoard& board, RadioLibWrapper& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables)
|
||||
MyMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::MeshTables& tables)
|
||||
: mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables),
|
||||
_phy(&phy), _board(&board), _cli(board, this, &_prefs, this)
|
||||
_cli(board, this, &_prefs, this)
|
||||
{
|
||||
my_radio = &radio;
|
||||
memset(known_clients, 0, sizeof(known_clients));
|
||||
next_local_advert = 0;
|
||||
next_local_advert = next_flood_advert = 0;
|
||||
_logging = false;
|
||||
|
||||
// defaults
|
||||
@@ -543,6 +493,7 @@ public:
|
||||
_prefs.cr = LORA_CR;
|
||||
_prefs.tx_power_dbm = LORA_TX_POWER;
|
||||
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
|
||||
_prefs.flood_advert_interval = 3; // 3 hours
|
||||
_prefs.flood_max = 64;
|
||||
}
|
||||
|
||||
@@ -554,17 +505,16 @@ public:
|
||||
// load persisted prefs
|
||||
_cli.loadPrefs(_fs);
|
||||
|
||||
_phy->setFrequency(_prefs.freq);
|
||||
_phy->setSpreadingFactor(_prefs.sf);
|
||||
_phy->setBandwidth(_prefs.bw);
|
||||
_phy->setCodingRate(_prefs.cr);
|
||||
_phy->setOutputPower(_prefs.tx_power_dbm);
|
||||
radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
|
||||
radio_set_tx_power(_prefs.tx_power_dbm);
|
||||
|
||||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
}
|
||||
|
||||
const char* getFirmwareVer() override { return FIRMWARE_VERSION; }
|
||||
const char* getBuildDate() override { return FIRMWARE_BUILD_DATE; }
|
||||
const char* getRole() override { return FIRMWARE_ROLE; }
|
||||
const char* getNodeName() { return _prefs.node_name; }
|
||||
|
||||
void savePrefs() override {
|
||||
@@ -593,11 +543,18 @@ public:
|
||||
|
||||
void updateAdvertTimer() override {
|
||||
if (_prefs.advert_interval > 0) { // schedule local advert timer
|
||||
next_local_advert = futureMillis((uint32_t)_prefs.advert_interval * 2 * 60 * 1000);
|
||||
next_local_advert = futureMillis( ((uint32_t)_prefs.advert_interval) * 2 * 60 * 1000);
|
||||
} else {
|
||||
next_local_advert = 0; // stop the timer
|
||||
}
|
||||
}
|
||||
void updateFloodAdvertTimer() override {
|
||||
if (_prefs.flood_advert_interval > 0) { // schedule flood advert timer
|
||||
next_flood_advert = futureMillis( ((uint32_t)_prefs.flood_advert_interval) * 60 * 60 * 1000);
|
||||
} else {
|
||||
next_flood_advert = 0; // stop the timer
|
||||
}
|
||||
}
|
||||
|
||||
void setLoggingOn(bool enable) override { _logging = enable; }
|
||||
|
||||
@@ -618,17 +575,21 @@ public:
|
||||
}
|
||||
|
||||
void setTxPower(uint8_t power_dbm) override {
|
||||
_phy->setOutputPower(power_dbm);
|
||||
radio_set_tx_power(power_dbm);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
mesh::Mesh::loop();
|
||||
|
||||
if (next_local_advert && millisHasNowPassed(next_local_advert)) {
|
||||
if (next_flood_advert && millisHasNowPassed(next_flood_advert)) {
|
||||
mesh::Packet* pkt = createSelfAdvert();
|
||||
if (pkt) {
|
||||
sendZeroHop(pkt);
|
||||
}
|
||||
if (pkt) sendFlood(pkt);
|
||||
|
||||
updateFloodAdvertTimer(); // schedule next flood advert
|
||||
updateAdvertTimer(); // also schedule local advert (so they don't overlap)
|
||||
} else if (next_local_advert && millisHasNowPassed(next_local_advert)) {
|
||||
mesh::Packet* pkt = createSelfAdvert();
|
||||
if (pkt) sendZeroHop(pkt);
|
||||
|
||||
updateAdvertTimer(); // schedule next local advert
|
||||
}
|
||||
@@ -638,28 +599,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
|
||||
#elif defined(LILYGO_TLORA)
|
||||
SPIClass spi;
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi);
|
||||
#elif defined(P_LORA_SCLK)
|
||||
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
|
||||
StdRNG fast_rng;
|
||||
SimpleMeshTables tables;
|
||||
|
||||
#ifdef ESP32
|
||||
ESP32RTCClock fallback_clock;
|
||||
#else
|
||||
VolatileRTCClock fallback_clock;
|
||||
#endif
|
||||
AutoDiscoverRTCClock rtc_clock(fallback_clock);
|
||||
|
||||
MyMesh the_mesh(radio, board, *new WRAPPER_CLASS(radio, board), *new ArduinoMillis(), fast_rng, rtc_clock, tables);
|
||||
MyMesh the_mesh(board, radio_driver, *new ArduinoMillis(), fast_rng, rtc_clock, tables);
|
||||
|
||||
void halt() {
|
||||
while (1) ;
|
||||
@@ -672,51 +615,10 @@ void setup() {
|
||||
delay(1000);
|
||||
|
||||
board.begin();
|
||||
#ifdef ESP32
|
||||
fallback_clock.begin();
|
||||
#endif
|
||||
rtc_clock.begin(Wire);
|
||||
|
||||
#ifdef SX126X_DIO3_TCXO_VOLTAGE
|
||||
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
|
||||
#else
|
||||
float tcxo = 1.6f;
|
||||
#endif
|
||||
if (!radio_init()) { halt(); }
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI);
|
||||
SPI.begin();
|
||||
#elif 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 defined(FAKETEC)
|
||||
if (status == RADIOLIB_ERR_SPI_CMD_FAILED || status == RADIOLIB_ERR_SPI_CMD_INVALID) {
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE (0.0f);
|
||||
tcxo = SX126X_DIO3_TCXO_VOLTAGE;
|
||||
status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo);
|
||||
}
|
||||
#endif
|
||||
if (status != RADIOLIB_ERR_NONE) {
|
||||
delay(5000);
|
||||
Serial.print("ERROR: radio init failed: ");
|
||||
Serial.println(status);
|
||||
halt();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
fast_rng.begin(radio.random(0x7FFFFFFF));
|
||||
fast_rng.begin(radio_get_rng_seed());
|
||||
|
||||
FILESYSTEM* fs;
|
||||
#if defined(NRF52_PLATFORM)
|
||||
@@ -732,8 +634,7 @@ void setup() {
|
||||
#endif
|
||||
if (!store.load("_main", the_mesh.self_id)) {
|
||||
MESH_DEBUG_PRINTLN("Generating new keypair");
|
||||
RadioNoiseListener rng(radio);
|
||||
the_mesh.self_id = mesh::LocalIdentity(&rng); // create new random identity
|
||||
the_mesh.self_id = radio_new_identity(); // create new random identity
|
||||
store.save("_main", the_mesh.self_id);
|
||||
}
|
||||
|
||||
@@ -750,7 +651,7 @@ void setup() {
|
||||
#endif
|
||||
|
||||
// send out initial Advertisement to the mesh
|
||||
the_mesh.sendSelfAdvertisement(2000);
|
||||
the_mesh.sendSelfAdvertisement(16000);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
@@ -7,26 +7,24 @@
|
||||
#include <SPIFFS.h>
|
||||
#endif
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
#include <helpers/StaticPoolPacketManager.h>
|
||||
#include <helpers/SimpleMeshTables.h>
|
||||
#include <helpers/IdentityStore.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
#include <helpers/AdvertDataHelpers.h>
|
||||
#include <helpers/TxtDataHelpers.h>
|
||||
#include <helpers/CommonCLI.h>
|
||||
#include <RTClib.h>
|
||||
#include <target.h>
|
||||
|
||||
/* ------------------------------ Config -------------------------------- */
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "19 Mar 2025"
|
||||
#define FIRMWARE_BUILD_DATE "30 Mar 2025"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.4.0"
|
||||
#define FIRMWARE_VERSION "v1.4.2"
|
||||
#endif
|
||||
|
||||
#ifndef LORA_FREQ
|
||||
@@ -67,52 +65,6 @@
|
||||
#define MAX_UNSYNCED_POSTS 16
|
||||
#endif
|
||||
|
||||
#if defined(HELTEC_LORA_V3)
|
||||
#include <helpers/HeltecV3Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static HeltecV3Board board;
|
||||
#elif defined(HELTEC_LORA_V2)
|
||||
#include <helpers/HeltecV2Board.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
static HeltecV2Board board;
|
||||
#elif defined(ARDUINO_XIAO_ESP32C3)
|
||||
#include <helpers/XiaoC3Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/CustomSX1268Wrapper.h>
|
||||
static XiaoC3Board board;
|
||||
#elif defined(SEEED_XIAO_S3) || defined(LILYGO_T3S3)
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static ESP32Board board;
|
||||
#elif defined(LILYGO_TLORA)
|
||||
#include <helpers/LilyGoTLoraBoard.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
static LilyGoTLoraBoard board;
|
||||
#elif defined(STATION_G2)
|
||||
#include <helpers/StationG2Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static StationG2Board board;
|
||||
#elif defined(RAK_4631)
|
||||
#include <helpers/nrf52/RAK4631Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static RAK4631Board board;
|
||||
#elif defined(HELTEC_T114)
|
||||
#include <helpers/nrf52/T114Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static T114Board board;
|
||||
#elif defined(LILYGO_TECHO)
|
||||
#include <helpers/nrf52/TechoBoard.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static TechoBoard board;
|
||||
#elif defined(FAKETEC)
|
||||
#include <helpers/nrf52/faketecBoard.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/CustomLLCC68Wrapper.h>
|
||||
static faketecBoard board;
|
||||
#else
|
||||
#error "need to provide a 'board' object"
|
||||
#endif
|
||||
|
||||
#ifdef DISPLAY_CLASS
|
||||
#include <helpers/ui/SSD1306Display.h>
|
||||
|
||||
@@ -122,8 +74,18 @@
|
||||
static UITask ui_task(display);
|
||||
#endif
|
||||
|
||||
#define FIRMWARE_ROLE "room_server"
|
||||
|
||||
#define PACKET_LOG_FILE "/packet_log"
|
||||
|
||||
/* ------------------------------ Code -------------------------------- */
|
||||
|
||||
enum RoomPermission {
|
||||
ADMIN,
|
||||
GUEST,
|
||||
READ_ONLY
|
||||
};
|
||||
|
||||
struct ClientInfo {
|
||||
mesh::Identity id;
|
||||
uint32_t last_timestamp; // by THEIR clock
|
||||
@@ -132,7 +94,7 @@ struct ClientInfo {
|
||||
uint32_t pending_ack;
|
||||
uint32_t push_post_timestamp;
|
||||
unsigned long ack_timeout;
|
||||
bool is_admin;
|
||||
RoomPermission permission;
|
||||
uint8_t push_failures;
|
||||
uint8_t secret[PUB_KEY_SIZE];
|
||||
int out_path_len;
|
||||
@@ -180,11 +142,9 @@ struct ServerStats {
|
||||
};
|
||||
|
||||
class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
||||
RadioLibWrapper* my_radio;
|
||||
FILESYSTEM* _fs;
|
||||
RADIO_CLASS* _phy;
|
||||
mesh::MainBoard* _board;
|
||||
unsigned long next_local_advert;
|
||||
unsigned long next_local_advert, next_flood_advert;
|
||||
bool _logging;
|
||||
NodePrefs _prefs;
|
||||
CommonCLI _cli;
|
||||
uint8_t reply_data[MAX_PACKET_PAYLOAD];
|
||||
@@ -296,6 +256,14 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
||||
return createAdvert(self_id, app_data, app_data_len);
|
||||
}
|
||||
|
||||
File openAppend(const char* fname) {
|
||||
#if defined(NRF52_PLATFORM)
|
||||
return _fs->open(fname, FILE_O_WRITE);
|
||||
#else
|
||||
return _fs->open(fname, "a", true);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
float getAirtimeBudgetFactor() const override {
|
||||
return _prefs.airtime_factor;
|
||||
@@ -310,6 +278,55 @@ protected:
|
||||
#endif
|
||||
}
|
||||
|
||||
void logRx(mesh::Packet* pkt, int len, float score) override {
|
||||
if (_logging) {
|
||||
File f = openAppend(PACKET_LOG_FILE);
|
||||
if (f) {
|
||||
f.print(getLogDateTime());
|
||||
f.printf(": RX, len=%d (type=%d, route=%s, payload_len=%d) SNR=%d RSSI=%d score=%d",
|
||||
len, pkt->getPayloadType(), pkt->isRouteDirect() ? "D" : "F", pkt->payload_len,
|
||||
(int)_radio->getLastSNR(), (int)_radio->getLastRSSI(), (int)(score*1000));
|
||||
|
||||
if (pkt->getPayloadType() == PAYLOAD_TYPE_PATH || pkt->getPayloadType() == PAYLOAD_TYPE_REQ
|
||||
|| pkt->getPayloadType() == PAYLOAD_TYPE_RESPONSE || pkt->getPayloadType() == PAYLOAD_TYPE_TXT_MSG) {
|
||||
f.printf(" [%02X -> %02X]\n", (uint32_t)pkt->payload[1], (uint32_t)pkt->payload[0]);
|
||||
} else {
|
||||
f.printf("\n");
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
void logTx(mesh::Packet* pkt, int len) override {
|
||||
if (_logging) {
|
||||
File f = openAppend(PACKET_LOG_FILE);
|
||||
if (f) {
|
||||
f.print(getLogDateTime());
|
||||
f.printf(": TX, len=%d (type=%d, route=%s, payload_len=%d)",
|
||||
len, pkt->getPayloadType(), pkt->isRouteDirect() ? "D" : "F", pkt->payload_len);
|
||||
|
||||
if (pkt->getPayloadType() == PAYLOAD_TYPE_PATH || pkt->getPayloadType() == PAYLOAD_TYPE_REQ
|
||||
|| pkt->getPayloadType() == PAYLOAD_TYPE_RESPONSE || pkt->getPayloadType() == PAYLOAD_TYPE_TXT_MSG) {
|
||||
f.printf(" [%02X -> %02X]\n", (uint32_t)pkt->payload[1], (uint32_t)pkt->payload[0]);
|
||||
} else {
|
||||
f.printf("\n");
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
void logTxFail(mesh::Packet* pkt, int len) override {
|
||||
if (_logging) {
|
||||
File f = openAppend(PACKET_LOG_FILE);
|
||||
if (f) {
|
||||
f.print(getLogDateTime());
|
||||
f.printf(": TX FAIL!, len=%d (type=%d, route=%s, payload_len=%d)\n",
|
||||
len, pkt->getPayloadType(), pkt->isRouteDirect() ? "D" : "F", pkt->payload_len);
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int calcRxDelay(float score, uint32_t air_time) const override {
|
||||
if (_prefs.rx_delay_base <= 0.0f) return 0;
|
||||
return (int) ((pow(_prefs.rx_delay_base, 0.85f - score) - 1.0) * air_time);
|
||||
@@ -344,13 +361,16 @@ protected:
|
||||
memcpy(&sender_timestamp, data, 4);
|
||||
memcpy(&sender_sync_since, &data[4], 4); // sender's "sync messags SINCE x" timestamp
|
||||
|
||||
bool is_admin;
|
||||
RoomPermission perm;
|
||||
data[len] = 0; // ensure null terminator
|
||||
if (strcmp((char *) &data[8], _prefs.password) == 0) { // check for valid admin password
|
||||
is_admin = true;
|
||||
perm = RoomPermission::ADMIN;
|
||||
} else {
|
||||
is_admin = false;
|
||||
if (strcmp((char *) &data[8], _prefs.guest_password) != 0) { // check the room/public password
|
||||
if (strcmp((char *) &data[8], _prefs.guest_password) == 0) { // check the room/public password
|
||||
perm = RoomPermission::GUEST;
|
||||
} else if (_prefs.allow_read_only) {
|
||||
perm = RoomPermission::READ_ONLY;
|
||||
} else {
|
||||
MESH_DEBUG_PRINTLN("Incorrect room password");
|
||||
return; // no response. Client will timeout
|
||||
}
|
||||
@@ -363,7 +383,7 @@ protected:
|
||||
}
|
||||
|
||||
MESH_DEBUG_PRINTLN("Login success!");
|
||||
client->is_admin = is_admin;
|
||||
client->permission = perm;
|
||||
client->last_timestamp = sender_timestamp;
|
||||
client->sync_since = sender_sync_since;
|
||||
client->pending_ack = 0;
|
||||
@@ -377,7 +397,7 @@ protected:
|
||||
// TODO: maybe reply with count of messages waiting to be synced for THIS client?
|
||||
reply_data[4] = RESP_SERVER_LOGIN_OK;
|
||||
reply_data[5] = (CLIENT_KEEP_ALIVE_SECS >> 4); // NEW: recommended keep-alive interval (secs / 16)
|
||||
reply_data[6] = is_admin ? 1 : 0;
|
||||
reply_data[6] = (perm == RoomPermission::ADMIN ? 1 : (perm == RoomPermission::GUEST ? 0 : 2));
|
||||
reply_data[7] = 0; // FUTURE: reserved
|
||||
memcpy(&reply_data[8], "OK", 2); // REVISIT: not really needed
|
||||
|
||||
@@ -454,7 +474,7 @@ protected:
|
||||
uint8_t temp[166];
|
||||
bool send_ack;
|
||||
if (flags == TXT_TYPE_CLI_DATA) {
|
||||
if (client->is_admin) {
|
||||
if (client->permission == RoomPermission::ADMIN) {
|
||||
if (is_retry) {
|
||||
temp[5] = 0; // no reply
|
||||
} else {
|
||||
@@ -467,11 +487,16 @@ protected:
|
||||
send_ack = false; // and no ACK... user shoudn't be sending these
|
||||
}
|
||||
} else { // TXT_TYPE_PLAIN
|
||||
if (!is_retry) {
|
||||
addPost(client, (const char *) &data[5]);
|
||||
if (client->permission == RoomPermission::READ_ONLY) {
|
||||
temp[5] = 0; // no reply
|
||||
send_ack = false; // no ACK
|
||||
} else {
|
||||
if (!is_retry) {
|
||||
addPost(client, (const char *) &data[5]);
|
||||
}
|
||||
temp[5] = 0; // no reply (ACK is enough)
|
||||
send_ack = true;
|
||||
}
|
||||
temp[5] = 0; // no reply (ACK is enough)
|
||||
send_ack = true;
|
||||
}
|
||||
|
||||
uint32_t delay_millis;
|
||||
@@ -555,9 +580,9 @@ protected:
|
||||
stats.batt_milli_volts = board.getBattMilliVolts();
|
||||
stats.curr_tx_queue_len = _mgr->getOutboundCount();
|
||||
stats.curr_free_queue_len = _mgr->getFreeCount();
|
||||
stats.last_rssi = (int16_t) my_radio->getLastRSSI();
|
||||
stats.n_packets_recv = my_radio->getPacketsRecv();
|
||||
stats.n_packets_sent = my_radio->getPacketsSent();
|
||||
stats.last_rssi = (int16_t) radio_driver.getLastRSSI();
|
||||
stats.n_packets_recv = radio_driver.getPacketsRecv();
|
||||
stats.n_packets_sent = radio_driver.getPacketsSent();
|
||||
stats.total_air_time_secs = getTotalAirTime() / 1000;
|
||||
stats.total_up_time_secs = _ms->getMillis() / 1000;
|
||||
stats.n_sent_flood = getNumSentFlood();
|
||||
@@ -565,7 +590,7 @@ protected:
|
||||
stats.n_recv_flood = getNumRecvFlood();
|
||||
stats.n_recv_direct = getNumRecvDirect();
|
||||
stats.n_full_events = getNumFullEvents();
|
||||
stats.last_snr = (int16_t)(my_radio->getLastSNR() * 4);
|
||||
stats.last_snr = (int16_t)(radio_driver.getLastSNR() * 4);
|
||||
stats.n_direct_dups = ((SimpleMeshTables *)getTables())->getNumDirectDups();
|
||||
stats.n_flood_dups = ((SimpleMeshTables *)getTables())->getNumFloodDups();
|
||||
stats.n_posted = _num_posted;
|
||||
@@ -575,7 +600,7 @@ protected:
|
||||
memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp
|
||||
memcpy(&reply_data[4], &stats, sizeof(stats));
|
||||
uint8_t reply_len = 4 + sizeof(stats);
|
||||
|
||||
|
||||
if (packet->isRouteFlood()) {
|
||||
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the response
|
||||
mesh::Packet* path = createPathReturn(client->id, secret, packet->path, packet->path_len,
|
||||
@@ -624,12 +649,12 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
MyMesh(RADIO_CLASS& phy, mesh::MainBoard& board, RadioLibWrapper& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::MeshTables& tables)
|
||||
MyMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::MeshTables& tables)
|
||||
: mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables),
|
||||
_phy(&phy), _board(&board), _cli(board, this, &_prefs, this)
|
||||
_cli(board, this, &_prefs, this)
|
||||
{
|
||||
my_radio = &radio;
|
||||
next_local_advert = 0;
|
||||
next_local_advert = next_flood_advert = 0;
|
||||
_logging = false;
|
||||
|
||||
// defaults
|
||||
memset(&_prefs, 0, sizeof(_prefs));
|
||||
@@ -647,6 +672,7 @@ public:
|
||||
_prefs.tx_power_dbm = LORA_TX_POWER;
|
||||
_prefs.disable_fwd = 1;
|
||||
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
|
||||
_prefs.flood_advert_interval = 3; // 3 hours
|
||||
_prefs.flood_max = 64;
|
||||
#ifdef ROOM_PASSWORD
|
||||
StrHelper::strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password));
|
||||
@@ -668,17 +694,16 @@ public:
|
||||
// load persisted prefs
|
||||
_cli.loadPrefs(_fs);
|
||||
|
||||
_phy->setFrequency(_prefs.freq);
|
||||
_phy->setSpreadingFactor(_prefs.sf);
|
||||
_phy->setBandwidth(_prefs.bw);
|
||||
_phy->setCodingRate(_prefs.cr);
|
||||
_phy->setOutputPower(_prefs.tx_power_dbm);
|
||||
radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
|
||||
radio_set_tx_power(_prefs.tx_power_dbm);
|
||||
|
||||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
}
|
||||
|
||||
const char* getFirmwareVer() override { return FIRMWARE_VERSION; }
|
||||
const char* getBuildDate() override { return FIRMWARE_BUILD_DATE; }
|
||||
const char* getRole() override { return FIRMWARE_ROLE; }
|
||||
const char* getNodeName() { return _prefs.node_name; }
|
||||
|
||||
void savePrefs() override {
|
||||
@@ -712,13 +737,34 @@ public:
|
||||
next_local_advert = 0; // stop the timer
|
||||
}
|
||||
}
|
||||
void updateFloodAdvertTimer() override {
|
||||
if (_prefs.flood_advert_interval > 0) { // schedule flood advert timer
|
||||
next_flood_advert = futureMillis( ((uint32_t)_prefs.flood_advert_interval) * 60 * 60 * 1000);
|
||||
} else {
|
||||
next_flood_advert = 0; // stop the timer
|
||||
}
|
||||
}
|
||||
|
||||
void setLoggingOn(bool enable) override { /* no-op */ }
|
||||
void eraseLogFile() override { /* no-op */ }
|
||||
void dumpLogFile() override { /* no-op */ }
|
||||
void setLoggingOn(bool enable) override { _logging = enable; }
|
||||
|
||||
void eraseLogFile() override {
|
||||
_fs->remove(PACKET_LOG_FILE);
|
||||
}
|
||||
|
||||
void dumpLogFile() override {
|
||||
File f = _fs->open(PACKET_LOG_FILE);
|
||||
if (f) {
|
||||
while (f.available()) {
|
||||
int c = f.read();
|
||||
if (c < 0) break;
|
||||
Serial.print((char)c);
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
|
||||
void setTxPower(uint8_t power_dbm) override {
|
||||
_phy->setOutputPower(power_dbm);
|
||||
radio_set_tx_power(power_dbm);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
@@ -756,11 +802,15 @@ public:
|
||||
next_push = futureMillis(SYNC_PUSH_INTERVAL);
|
||||
}
|
||||
|
||||
if (next_local_advert && millisHasNowPassed(next_local_advert)) {
|
||||
if (next_flood_advert && millisHasNowPassed(next_flood_advert)) {
|
||||
mesh::Packet* pkt = createSelfAdvert();
|
||||
if (pkt) {
|
||||
sendZeroHop(pkt);
|
||||
}
|
||||
if (pkt) sendFlood(pkt);
|
||||
|
||||
updateFloodAdvertTimer(); // schedule next flood advert
|
||||
updateAdvertTimer(); // also schedule local advert (so they don't overlap)
|
||||
} else if (next_local_advert && millisHasNowPassed(next_local_advert)) {
|
||||
mesh::Packet* pkt = createSelfAdvert();
|
||||
if (pkt) sendZeroHop(pkt);
|
||||
|
||||
updateAdvertTimer(); // schedule next local advert
|
||||
}
|
||||
@@ -773,28 +823,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
|
||||
#elif defined(LILYGO_TLORA)
|
||||
SPIClass spi;
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi);
|
||||
#elif defined(P_LORA_SCLK)
|
||||
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
|
||||
StdRNG fast_rng;
|
||||
SimpleMeshTables tables;
|
||||
|
||||
#ifdef ESP32
|
||||
ESP32RTCClock fallback_clock;
|
||||
#else
|
||||
VolatileRTCClock fallback_clock;
|
||||
#endif
|
||||
AutoDiscoverRTCClock rtc_clock(fallback_clock);
|
||||
|
||||
MyMesh the_mesh(radio, board, *new WRAPPER_CLASS(radio, board), *new ArduinoMillis(), fast_rng, rtc_clock, tables);
|
||||
MyMesh the_mesh(board, radio_driver, *new ArduinoMillis(), fast_rng, rtc_clock, tables);
|
||||
|
||||
void halt() {
|
||||
while (1) ;
|
||||
@@ -807,51 +838,10 @@ void setup() {
|
||||
delay(1000);
|
||||
|
||||
board.begin();
|
||||
#ifdef ESP32
|
||||
fallback_clock.begin();
|
||||
#endif
|
||||
rtc_clock.begin(Wire);
|
||||
|
||||
#ifdef SX126X_DIO3_TCXO_VOLTAGE
|
||||
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
|
||||
#else
|
||||
float tcxo = 1.6f;
|
||||
#endif
|
||||
if (!radio_init()) { halt(); }
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI);
|
||||
SPI.begin();
|
||||
#elif 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 defined(FAKETEC)
|
||||
if (status == RADIOLIB_ERR_SPI_CMD_FAILED || status == RADIOLIB_ERR_SPI_CMD_INVALID) {
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE (0.0f);
|
||||
tcxo = SX126X_DIO3_TCXO_VOLTAGE;
|
||||
status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo);
|
||||
}
|
||||
#endif
|
||||
if (status != RADIOLIB_ERR_NONE) {
|
||||
delay(5000);
|
||||
Serial.print("ERROR: radio init failed: ");
|
||||
Serial.println(status);
|
||||
halt();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
fast_rng.begin(radio.random(0x7FFFFFFF));
|
||||
fast_rng.begin(radio_get_rng_seed());
|
||||
|
||||
FILESYSTEM* fs;
|
||||
#if defined(NRF52_PLATFORM)
|
||||
@@ -866,8 +856,7 @@ void setup() {
|
||||
#error "need to define filesystem"
|
||||
#endif
|
||||
if (!store.load("_main", the_mesh.self_id)) {
|
||||
RadioNoiseListener rng(radio);
|
||||
the_mesh.self_id = mesh::LocalIdentity(&rng); // create new random identity
|
||||
the_mesh.self_id = radio_new_identity(); // create new random identity
|
||||
store.save("_main", the_mesh.self_id);
|
||||
}
|
||||
|
||||
@@ -884,7 +873,7 @@ void setup() {
|
||||
#endif
|
||||
|
||||
// send out initial Advertisement to the mesh
|
||||
the_mesh.sendSelfAdvertisement(2000);
|
||||
the_mesh.sendSelfAdvertisement(16000);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
@@ -7,14 +7,12 @@
|
||||
#include <SPIFFS.h>
|
||||
#endif
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
#include <helpers/StaticPoolPacketManager.h>
|
||||
#include <helpers/SimpleMeshTables.h>
|
||||
#include <helpers/IdentityStore.h>
|
||||
#include <RTClib.h>
|
||||
#include <target.h>
|
||||
|
||||
/* ---------------------------------- CONFIGURATION ------------------------------------- */
|
||||
|
||||
@@ -49,44 +47,6 @@
|
||||
|
||||
#define PUBLIC_GROUP_PSK "izOH6cXN6mrJ5e26oRXNcg=="
|
||||
|
||||
#if defined(HELTEC_LORA_V3)
|
||||
#include <helpers/HeltecV3Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static HeltecV3Board board;
|
||||
#elif defined(HELTEC_LORA_V2)
|
||||
#include <helpers/HeltecV2Board.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
static HeltecV2Board board;
|
||||
#elif defined(ARDUINO_XIAO_ESP32C3)
|
||||
#include <helpers/XiaoC3Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/CustomSX1268Wrapper.h>
|
||||
static XiaoC3Board board;
|
||||
#elif defined(SEEED_XIAO_S3) || defined(LILYGO_T3S3)
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static ESP32Board board;
|
||||
#elif defined(LILYGO_TLORA)
|
||||
#include <helpers/LilyGoTLoraBoard.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
static LilyGoTLoraBoard board;
|
||||
#elif defined(RAK_4631)
|
||||
#include <helpers/nrf52/RAK4631Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
static RAK4631Board board;
|
||||
#elif defined(T1000_E)
|
||||
#include <helpers/nrf52/T1000eBoard.h>
|
||||
#include <helpers/CustomLR1110Wrapper.h>
|
||||
static T1000eBoard board;
|
||||
#elif defined(FAKETEC)
|
||||
#include <helpers/nrf52/faketecBoard.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/CustomLLCC68Wrapper.h>
|
||||
static faketecBoard board;
|
||||
#else
|
||||
#error "need to provide a 'board' object"
|
||||
#endif
|
||||
|
||||
// Believe it or not, this std C function is busted on some platforms!
|
||||
static uint32_t _atoi(const char* sp) {
|
||||
uint32_t n = 0;
|
||||
@@ -230,6 +190,10 @@ protected:
|
||||
return 0; // disable rxdelay
|
||||
}
|
||||
|
||||
bool allowPacketForward(const mesh::Packet* packet) override {
|
||||
return true;
|
||||
}
|
||||
|
||||
void onDiscoveredContact(ContactInfo& contact, bool is_new) override {
|
||||
// TODO: if not in favs, prompt to add as fav(?)
|
||||
|
||||
@@ -299,8 +263,7 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
MyMesh(RadioLibWrapper& radio, mesh::RNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables)
|
||||
MyMesh(mesh::Radio& radio, StdRNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables)
|
||||
: BaseChatMesh(radio, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables)
|
||||
{
|
||||
// defaults
|
||||
@@ -328,6 +291,14 @@ public:
|
||||
IdentityStore store(fs, "/identity");
|
||||
#endif
|
||||
if (!store.load("_main", self_id, _prefs.node_name, sizeof(_prefs.node_name))) { // legacy: node_name was from identity file
|
||||
// Need way to get some entropy to seed RNG
|
||||
Serial.println("Press ENTER to generate key:");
|
||||
char c = 0;
|
||||
while (c != '\n') { // wait for ENTER to be pressed
|
||||
if (Serial.available()) c = Serial.read();
|
||||
}
|
||||
((StdRNG *)getRNG())->begin(millis());
|
||||
|
||||
self_id = mesh::LocalIdentity(getRNG()); // create new random identity
|
||||
store.save("_main", self_id);
|
||||
}
|
||||
@@ -362,6 +333,8 @@ public:
|
||||
Serial.println("===== MeshCore Chat Terminal =====");
|
||||
Serial.println();
|
||||
Serial.printf("WELCOME %s\n", _prefs.node_name);
|
||||
mesh::Utils::printHex(Serial, self_id.pub_key, PUB_KEY_SIZE);
|
||||
Serial.println();
|
||||
Serial.println(" (enter 'help' for basic commands)");
|
||||
Serial.println();
|
||||
}
|
||||
@@ -548,20 +521,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
|
||||
#elif defined(LILYGO_TLORA)
|
||||
SPIClass spi;
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi);
|
||||
#elif defined(P_LORA_SCLK)
|
||||
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
|
||||
StdRNG fast_rng;
|
||||
SimpleMeshTables tables;
|
||||
MyMesh the_mesh(*new WRAPPER_CLASS(radio, board), fast_rng, *new VolatileRTCClock(), tables);
|
||||
MyMesh the_mesh(radio_driver, fast_rng, *new VolatileRTCClock(), tables); // TODO: test with 'rtc_clock' in target.cpp
|
||||
|
||||
void halt() {
|
||||
while (1) ;
|
||||
@@ -571,36 +533,10 @@ void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
board.begin();
|
||||
#ifdef SX126X_DIO3_TCXO_VOLTAGE
|
||||
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
|
||||
#else
|
||||
float tcxo = 1.6f;
|
||||
#endif
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI);
|
||||
SPI.begin();
|
||||
#elif 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);
|
||||
halt();
|
||||
}
|
||||
if (!radio_init()) { halt(); }
|
||||
|
||||
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
|
||||
|
||||
fast_rng.begin(radio.random(0x7FFFFFFF));
|
||||
fast_rng.begin(radio_get_rng_seed());
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
InternalFS.begin();
|
||||
@@ -612,12 +548,8 @@ void setup() {
|
||||
#error "need to define filesystem"
|
||||
#endif
|
||||
|
||||
if (LORA_FREQ != the_mesh.getFreqPref()) {
|
||||
radio.setFrequency(the_mesh.getFreqPref());
|
||||
}
|
||||
if (LORA_TX_POWER != the_mesh.getTxPowerPref()) {
|
||||
radio.setOutputPower(the_mesh.getTxPowerPref());
|
||||
}
|
||||
radio_set_params(the_mesh.getFreqPref(), LORA_BW, LORA_SF, LORA_CR);
|
||||
radio_set_tx_power(the_mesh.getTxPowerPref());
|
||||
|
||||
the_mesh.showWelcome();
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ lib_deps =
|
||||
adafruit/RTClib @ ^2.1.3
|
||||
melopero/Melopero RV3028 @ ^1.1.0
|
||||
build_flags = -w -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1
|
||||
-D LORA_FREQ=867.5
|
||||
-D LORA_FREQ=869.525
|
||||
-D LORA_BW=250
|
||||
-D LORA_SF=10
|
||||
build_src_filter =
|
||||
@@ -41,6 +41,10 @@ build_flags = ${arduino_base.build_flags}
|
||||
; -D ESP32_CPU_FREQ=80 ; change it to your need
|
||||
build_src_filter = ${arduino_base.build_src_filter}
|
||||
|
||||
[esp32_ota]
|
||||
lib_deps =
|
||||
me-no-dev/ESPAsyncWebServer @ ^3.6.0
|
||||
file://arch/esp32/AsyncElegantOTA
|
||||
|
||||
; ----------------- NRF52 ---------------------
|
||||
[nrf52_base]
|
||||
|
||||
@@ -29,6 +29,9 @@ int Dispatcher::calcRxDelay(float score, uint32_t air_time) const {
|
||||
uint32_t Dispatcher::getCADFailRetryDelay() const {
|
||||
return 200;
|
||||
}
|
||||
uint32_t Dispatcher::getCADFailMaxDuration() const {
|
||||
return 4000; // 4 seconds
|
||||
}
|
||||
|
||||
void Dispatcher::loop() {
|
||||
if (outbound) { // waiting for outbound send to be completed
|
||||
@@ -185,9 +188,20 @@ void Dispatcher::checkSend() {
|
||||
if (_mgr->getOutboundCount() == 0) return; // nothing waiting to send
|
||||
if (!millisHasNowPassed(next_tx_time)) return; // still in 'radio silence' phase (from airtime budget setting)
|
||||
if (_radio->isReceiving()) { // LBT - check if radio is currently mid-receive, or if channel activity
|
||||
next_tx_time = futureMillis(getCADFailRetryDelay());
|
||||
return;
|
||||
if (cad_busy_start == 0) {
|
||||
cad_busy_start = _ms->getMillis(); // record when CAD busy state started
|
||||
}
|
||||
|
||||
if (_ms->getMillis() - cad_busy_start > getCADFailMaxDuration()) {
|
||||
MESH_DEBUG_PRINTLN("%s Dispatcher::checkSend(): CAD busy max duration reached!", getLogDateTime());
|
||||
// channel activity has gone on too long... (Radio might be in a bad state)
|
||||
// force the pending transmit below...
|
||||
} else {
|
||||
next_tx_time = futureMillis(getCADFailRetryDelay());
|
||||
return;
|
||||
}
|
||||
}
|
||||
cad_busy_start = 0; // reset busy state
|
||||
|
||||
outbound = _mgr->getNextOutbound(_ms->getMillis());
|
||||
if (outbound) {
|
||||
|
||||
@@ -98,6 +98,7 @@ class Dispatcher {
|
||||
Packet* outbound; // current outbound packet
|
||||
unsigned long outbound_expiry, outbound_start, total_air_time;
|
||||
unsigned long next_tx_time;
|
||||
unsigned long cad_busy_start;
|
||||
uint32_t n_sent_flood, n_sent_direct;
|
||||
uint32_t n_recv_flood, n_recv_direct;
|
||||
uint32_t n_full_events;
|
||||
@@ -113,6 +114,7 @@ protected:
|
||||
: _radio(&radio), _ms(&ms), _mgr(&mgr)
|
||||
{
|
||||
outbound = NULL; total_air_time = 0; next_tx_time = 0;
|
||||
cad_busy_start = 0;
|
||||
}
|
||||
|
||||
virtual DispatcherAction onRecvPacket(Packet* pkt) = 0;
|
||||
@@ -127,6 +129,7 @@ protected:
|
||||
virtual float getAirtimeBudgetFactor() const;
|
||||
virtual int calcRxDelay(float score, uint32_t air_time) const;
|
||||
virtual uint32_t getCADFailRetryDelay() const;
|
||||
virtual uint32_t getCADFailMaxDuration() const;
|
||||
|
||||
public:
|
||||
void begin();
|
||||
|
||||
28
src/Mesh.h
28
src/Mesh.h
@@ -4,34 +4,6 @@
|
||||
|
||||
namespace mesh {
|
||||
|
||||
/**
|
||||
* An abstraction of the device's Realtime Clock.
|
||||
*/
|
||||
class RTCClock {
|
||||
uint32_t last_unique;
|
||||
protected:
|
||||
RTCClock() { last_unique = 0; }
|
||||
|
||||
public:
|
||||
/**
|
||||
* \returns the current time. in UNIX epoch seconds.
|
||||
*/
|
||||
virtual uint32_t getCurrentTime() = 0;
|
||||
|
||||
/**
|
||||
* \param time current time in UNIX epoch seconds.
|
||||
*/
|
||||
virtual void setCurrentTime(uint32_t time) = 0;
|
||||
|
||||
uint32_t getCurrentTimeUnique() {
|
||||
uint32_t t = getCurrentTime();
|
||||
if (t <= last_unique) {
|
||||
return ++last_unique;
|
||||
}
|
||||
return last_unique = t;
|
||||
}
|
||||
};
|
||||
|
||||
class GroupChannel {
|
||||
public:
|
||||
uint8_t hash[PATH_HASH_SIZE];
|
||||
|
||||
@@ -42,7 +42,35 @@ public:
|
||||
virtual void reboot() = 0;
|
||||
virtual void powerOff() { /* no op */ }
|
||||
virtual uint8_t getStartupReason() const = 0;
|
||||
virtual bool startOTAUpdate() { return false; } // not supported
|
||||
virtual bool startOTAUpdate(const char* id, char reply[]) { return false; } // not supported
|
||||
};
|
||||
|
||||
/**
|
||||
* An abstraction of the device's Realtime Clock.
|
||||
*/
|
||||
class RTCClock {
|
||||
uint32_t last_unique;
|
||||
protected:
|
||||
RTCClock() { last_unique = 0; }
|
||||
|
||||
public:
|
||||
/**
|
||||
* \returns the current time. in UNIX epoch seconds.
|
||||
*/
|
||||
virtual uint32_t getCurrentTime() = 0;
|
||||
|
||||
/**
|
||||
* \param time current time in UNIX epoch seconds.
|
||||
*/
|
||||
virtual void setCurrentTime(uint32_t time) = 0;
|
||||
|
||||
uint32_t getCurrentTimeUnique() {
|
||||
uint32_t t = getCurrentTime();
|
||||
if (t <= last_unique) {
|
||||
return ++last_unique;
|
||||
}
|
||||
return last_unique = t;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -229,6 +229,7 @@ void BaseChatMesh::onGroupDataRecv(mesh::Packet* packet, uint8_t type, const mes
|
||||
mesh::Packet* BaseChatMesh::composeMsgPacket(const ContactInfo& recipient, uint32_t timestamp, uint8_t attempt, const char *text, uint32_t& expected_ack) {
|
||||
int text_len = strlen(text);
|
||||
if (text_len > MAX_TEXT_LEN) return NULL;
|
||||
if (attempt > 3 && text_len > MAX_TEXT_LEN-2) return NULL;
|
||||
|
||||
uint8_t temp[5+MAX_TEXT_LEN+1];
|
||||
memcpy(temp, ×tamp, 4); // mostly an extra blob to help make packet_hash unique
|
||||
@@ -238,7 +239,13 @@ mesh::Packet* BaseChatMesh::composeMsgPacket(const ContactInfo& recipient, uint3
|
||||
// calc expected ACK reply
|
||||
mesh::Utils::sha256((uint8_t *)&expected_ack, 4, temp, 5 + text_len, self_id.pub_key, PUB_KEY_SIZE);
|
||||
|
||||
return createDatagram(PAYLOAD_TYPE_TXT_MSG, recipient.id, recipient.shared_secret, temp, 5 + text_len);
|
||||
int len = 5 + text_len;
|
||||
if (attempt > 3) {
|
||||
temp[len++] = 0; // null terminator
|
||||
temp[len++] = attempt; // hide attempt number at tail end of payload
|
||||
}
|
||||
|
||||
return createDatagram(PAYLOAD_TYPE_TXT_MSG, recipient.id, recipient.shared_secret, temp, len);
|
||||
}
|
||||
|
||||
int BaseChatMesh::sendMessage(const ContactInfo& recipient, uint32_t timestamp, uint8_t attempt, const char* text, uint32_t& expected_ack, uint32_t& est_timeout) {
|
||||
|
||||
@@ -14,57 +14,66 @@ static uint32_t _atoi(const char* sp) {
|
||||
}
|
||||
|
||||
void CommonCLI::loadPrefs(FILESYSTEM* fs) {
|
||||
if (fs->exists("/node_prefs")) {
|
||||
File file = fs->open("/node_prefs");
|
||||
if (file) {
|
||||
uint8_t pad[8];
|
||||
if (fs->exists("/com_prefs")) {
|
||||
loadPrefsInt(fs, "/com_prefs"); // new filename
|
||||
} else if (fs->exists("/node_prefs")) {
|
||||
loadPrefsInt(fs, "/node_prefs");
|
||||
savePrefs(fs); // save to new filename
|
||||
fs->remove("/node_prefs"); // remove old
|
||||
}
|
||||
}
|
||||
|
||||
file.read((uint8_t *) &_prefs->airtime_factor, sizeof(_prefs->airtime_factor)); // 0
|
||||
file.read((uint8_t *) &_prefs->node_name, sizeof(_prefs->node_name)); // 4
|
||||
file.read(pad, 4); // 36
|
||||
file.read((uint8_t *) &_prefs->node_lat, sizeof(_prefs->node_lat)); // 40
|
||||
file.read((uint8_t *) &_prefs->node_lon, sizeof(_prefs->node_lon)); // 48
|
||||
file.read((uint8_t *) &_prefs->password[0], sizeof(_prefs->password)); // 56
|
||||
file.read((uint8_t *) &_prefs->freq, sizeof(_prefs->freq)); // 72
|
||||
file.read((uint8_t *) &_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm)); // 76
|
||||
file.read((uint8_t *) &_prefs->disable_fwd, sizeof(_prefs->disable_fwd)); // 77
|
||||
file.read((uint8_t *) &_prefs->advert_interval, sizeof(_prefs->advert_interval)); // 78
|
||||
file.read((uint8_t *) &_prefs->unused, sizeof(_prefs->unused)); // 79
|
||||
file.read((uint8_t *) &_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base)); // 80
|
||||
file.read((uint8_t *) &_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor)); // 84
|
||||
file.read((uint8_t *) &_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
|
||||
file.read((uint8_t *) &_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor)); // 104
|
||||
file.read(pad, 4); // 108
|
||||
file.read((uint8_t *) &_prefs->sf, sizeof(_prefs->sf)); // 112
|
||||
file.read((uint8_t *) &_prefs->cr, sizeof(_prefs->cr)); // 113
|
||||
file.read((uint8_t *) &_prefs->reserved1, sizeof(_prefs->reserved1)); // 114
|
||||
file.read((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2)); // 115
|
||||
file.read((uint8_t *) &_prefs->bw, sizeof(_prefs->bw)); // 116
|
||||
file.read(pad, 4); // 120
|
||||
file.read((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
|
||||
void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
File file = fs->open(filename);
|
||||
if (file) {
|
||||
uint8_t pad[8];
|
||||
|
||||
// sanitise bad pref values
|
||||
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
|
||||
_prefs->tx_delay_factor = constrain(_prefs->tx_delay_factor, 0, 2.0f);
|
||||
_prefs->direct_tx_delay_factor = constrain(_prefs->direct_tx_delay_factor, 0, 2.0f);
|
||||
_prefs->airtime_factor = constrain(_prefs->airtime_factor, 0, 9.0f);
|
||||
_prefs->freq = constrain(_prefs->freq, 400.0f, 2500.0f);
|
||||
_prefs->bw = constrain(_prefs->bw, 62.5f, 500.0f);
|
||||
_prefs->sf = constrain(_prefs->sf, 7, 12);
|
||||
_prefs->cr = constrain(_prefs->cr, 5, 8);
|
||||
_prefs->tx_power_dbm = constrain(_prefs->tx_power_dbm, 1, 30);
|
||||
file.read((uint8_t *) &_prefs->airtime_factor, sizeof(_prefs->airtime_factor)); // 0
|
||||
file.read((uint8_t *) &_prefs->node_name, sizeof(_prefs->node_name)); // 4
|
||||
file.read(pad, 4); // 36
|
||||
file.read((uint8_t *) &_prefs->node_lat, sizeof(_prefs->node_lat)); // 40
|
||||
file.read((uint8_t *) &_prefs->node_lon, sizeof(_prefs->node_lon)); // 48
|
||||
file.read((uint8_t *) &_prefs->password[0], sizeof(_prefs->password)); // 56
|
||||
file.read((uint8_t *) &_prefs->freq, sizeof(_prefs->freq)); // 72
|
||||
file.read((uint8_t *) &_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm)); // 76
|
||||
file.read((uint8_t *) &_prefs->disable_fwd, sizeof(_prefs->disable_fwd)); // 77
|
||||
file.read((uint8_t *) &_prefs->advert_interval, sizeof(_prefs->advert_interval)); // 78
|
||||
file.read((uint8_t *) pad, 1); // 79 was 'unused'
|
||||
file.read((uint8_t *) &_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base)); // 80
|
||||
file.read((uint8_t *) &_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor)); // 84
|
||||
file.read((uint8_t *) &_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
|
||||
file.read((uint8_t *) &_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor)); // 104
|
||||
file.read(pad, 4); // 108
|
||||
file.read((uint8_t *) &_prefs->sf, sizeof(_prefs->sf)); // 112
|
||||
file.read((uint8_t *) &_prefs->cr, sizeof(_prefs->cr)); // 113
|
||||
file.read((uint8_t *) &_prefs->allow_read_only, sizeof(_prefs->allow_read_only)); // 114
|
||||
file.read((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2)); // 115
|
||||
file.read((uint8_t *) &_prefs->bw, sizeof(_prefs->bw)); // 116
|
||||
file.read(pad, 4); // 120
|
||||
file.read((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
|
||||
file.read((uint8_t *) &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
|
||||
|
||||
file.close();
|
||||
}
|
||||
// sanitise bad pref values
|
||||
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
|
||||
_prefs->tx_delay_factor = constrain(_prefs->tx_delay_factor, 0, 2.0f);
|
||||
_prefs->direct_tx_delay_factor = constrain(_prefs->direct_tx_delay_factor, 0, 2.0f);
|
||||
_prefs->airtime_factor = constrain(_prefs->airtime_factor, 0, 9.0f);
|
||||
_prefs->freq = constrain(_prefs->freq, 400.0f, 2500.0f);
|
||||
_prefs->bw = constrain(_prefs->bw, 62.5f, 500.0f);
|
||||
_prefs->sf = constrain(_prefs->sf, 7, 12);
|
||||
_prefs->cr = constrain(_prefs->cr, 5, 8);
|
||||
_prefs->tx_power_dbm = constrain(_prefs->tx_power_dbm, 1, 30);
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
||||
#if defined(NRF52_PLATFORM)
|
||||
File file = fs->open("/node_prefs", FILE_O_WRITE);
|
||||
File file = fs->open("/com_prefs", FILE_O_WRITE);
|
||||
if (file) { file.seek(0); file.truncate(); }
|
||||
#else
|
||||
File file = fs->open("/node_prefs", "w", true);
|
||||
File file = fs->open("/com_prefs", "w", true);
|
||||
#endif
|
||||
if (file) {
|
||||
uint8_t pad[8];
|
||||
@@ -80,7 +89,7 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
||||
file.write((uint8_t *) &_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm)); // 76
|
||||
file.write((uint8_t *) &_prefs->disable_fwd, sizeof(_prefs->disable_fwd)); // 77
|
||||
file.write((uint8_t *) &_prefs->advert_interval, sizeof(_prefs->advert_interval)); // 78
|
||||
file.write((uint8_t *) &_prefs->unused, sizeof(_prefs->unused)); // 79
|
||||
file.write((uint8_t *) pad, 1); // 79 was 'unused'
|
||||
file.write((uint8_t *) &_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base)); // 80
|
||||
file.write((uint8_t *) &_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor)); // 84
|
||||
file.write((uint8_t *) &_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
|
||||
@@ -88,11 +97,12 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
||||
file.write(pad, 4); // 108
|
||||
file.write((uint8_t *) &_prefs->sf, sizeof(_prefs->sf)); // 112
|
||||
file.write((uint8_t *) &_prefs->cr, sizeof(_prefs->cr)); // 113
|
||||
file.write((uint8_t *) &_prefs->reserved1, sizeof(_prefs->reserved1)); // 114
|
||||
file.write((uint8_t *) &_prefs->allow_read_only, sizeof(_prefs->allow_read_only)); // 114
|
||||
file.write((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2)); // 115
|
||||
file.write((uint8_t *) &_prefs->bw, sizeof(_prefs->bw)); // 116
|
||||
file.write(pad, 4); // 120
|
||||
file.write((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
|
||||
file.write((uint8_t *) &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
|
||||
|
||||
file.close();
|
||||
}
|
||||
@@ -129,9 +139,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
strcpy(reply, "ERR: clock cannot go backwards");
|
||||
}
|
||||
} else if (memcmp(command, "start ota", 9) == 0) {
|
||||
if (_board->startOTAUpdate()) {
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
if (!_board->startOTAUpdate(_prefs->node_name, reply)) {
|
||||
strcpy(reply, "Error");
|
||||
}
|
||||
} else if (memcmp(command, "clock", 5) == 0) {
|
||||
@@ -157,6 +165,10 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
const char* config = &command[4];
|
||||
if (memcmp(config, "af", 2) == 0) {
|
||||
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->airtime_factor));
|
||||
} else if (memcmp(config, "allow.read.only", 15) == 0) {
|
||||
sprintf(reply, "> %s", _prefs->allow_read_only ? "on" : "off");
|
||||
} else if (memcmp(config, "flood.advert.interval", 21) == 0) {
|
||||
sprintf(reply, "> %d", ((uint32_t) _prefs->flood_advert_interval));
|
||||
} else if (memcmp(config, "advert.interval", 15) == 0) {
|
||||
sprintf(reply, "> %d", ((uint32_t) _prefs->advert_interval) * 2);
|
||||
} else if (memcmp(config, "guest.password", 14) == 0) {
|
||||
@@ -186,6 +198,11 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
sprintf(reply, "> %d", (uint32_t) _prefs->tx_power_dbm);
|
||||
} else if (memcmp(config, "freq", 4) == 0) {
|
||||
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->freq));
|
||||
} else if (memcmp(config, "public.key", 10) == 0) {
|
||||
strcpy(reply, "> ");
|
||||
mesh::Utils::toHex(&reply[2], _mesh->self_id.pub_key, PUB_KEY_SIZE);
|
||||
} else if (memcmp(config, "role", 4) == 0) {
|
||||
sprintf(reply, "> %s", _callbacks->getRole());
|
||||
} else {
|
||||
sprintf(reply, "??: %s", config);
|
||||
}
|
||||
@@ -195,6 +212,22 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
_prefs->airtime_factor = atof(&config[3]);
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else if (memcmp(config, "allow.read.only ", 16) == 0) {
|
||||
_prefs->allow_read_only = memcmp(&config[16], "on", 2) == 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else if (memcmp(config, "flood.advert.interval ", 22) == 0) {
|
||||
int hours = _atoi(&config[22]);
|
||||
if (hours > 0 && hours < 3) {
|
||||
sprintf(reply, "Error: min is 3 hours");
|
||||
} else if (hours > 48) {
|
||||
strcpy(reply, "Error: max is 48 hours");
|
||||
} else {
|
||||
_prefs->flood_advert_interval = (uint8_t)(hours);
|
||||
_callbacks->updateFloodAdvertTimer();
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
}
|
||||
} else if (memcmp(config, "advert.interval ", 16) == 0) {
|
||||
int mins = _atoi(&config[16]);
|
||||
if (mins > 0 && mins < MIN_LOCAL_ADVERT_INTERVAL) {
|
||||
|
||||
@@ -11,8 +11,8 @@ struct NodePrefs { // persisted to file
|
||||
float freq;
|
||||
uint8_t tx_power_dbm;
|
||||
uint8_t disable_fwd;
|
||||
uint8_t advert_interval; // minutes
|
||||
uint8_t unused;
|
||||
uint8_t advert_interval; // minutes / 2
|
||||
uint8_t flood_advert_interval; // hours
|
||||
float rx_delay_base;
|
||||
float tx_delay_factor;
|
||||
char guest_password[16];
|
||||
@@ -20,7 +20,7 @@ struct NodePrefs { // persisted to file
|
||||
uint32_t guard;
|
||||
uint8_t sf;
|
||||
uint8_t cr;
|
||||
uint8_t reserved1;
|
||||
uint8_t allow_read_only;
|
||||
uint8_t reserved2;
|
||||
float bw;
|
||||
uint8_t flood_max;
|
||||
@@ -31,9 +31,11 @@ public:
|
||||
virtual void savePrefs() = 0;
|
||||
virtual const char* getFirmwareVer() = 0;
|
||||
virtual const char* getBuildDate() = 0;
|
||||
virtual const char* getRole() = 0;
|
||||
virtual bool formatFileSystem() = 0;
|
||||
virtual void sendSelfAdvertisement(int delay_millis) = 0;
|
||||
virtual void updateAdvertTimer() = 0;
|
||||
virtual void updateFloodAdvertTimer() = 0;
|
||||
virtual void setLoggingOn(bool enable) = 0;
|
||||
virtual void eraseLogFile() = 0;
|
||||
virtual void dumpLogFile() = 0;
|
||||
@@ -52,8 +54,10 @@ class CommonCLI {
|
||||
|
||||
void checkAdvertInterval();
|
||||
|
||||
void loadPrefsInt(FILESYSTEM* _fs, const char* filename);
|
||||
|
||||
public:
|
||||
CommonCLI(mesh::MainBoard& board, mesh::Mesh* mesh, NodePrefs* prefs, CommonCLICallbacks* callbacks)
|
||||
CommonCLI(mesh::MainBoard& board, mesh::Mesh* mesh, NodePrefs* prefs, CommonCLICallbacks* callbacks)
|
||||
: _board(&board), _mesh(mesh), _prefs(prefs), _callbacks(callbacks) { }
|
||||
|
||||
void loadPrefs(FILESYSTEM* _fs);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <RadioLib.h>
|
||||
|
||||
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
|
||||
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04
|
||||
|
||||
class CustomLLCC68 : public LLCC68 {
|
||||
public:
|
||||
@@ -10,7 +11,7 @@ class CustomLLCC68 : public LLCC68 {
|
||||
|
||||
bool isReceiving() {
|
||||
uint16_t irq = getIrqFlags();
|
||||
bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID);
|
||||
return hasPreamble;
|
||||
bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
|
||||
return detected;
|
||||
}
|
||||
};
|
||||
@@ -11,7 +11,7 @@ class CustomLR1110 : public LR1110 {
|
||||
|
||||
bool isReceiving() {
|
||||
uint16_t irq = getIrqStatus();
|
||||
bool hasPreamble = ((irq & LR1110_IRQ_HEADER_VALID) && (irq & LR1110_IRQ_HAS_PREAMBLE));
|
||||
return hasPreamble;
|
||||
bool detected = ((irq & LR1110_IRQ_HEADER_VALID) || (irq & LR1110_IRQ_HAS_PREAMBLE));
|
||||
return detected;
|
||||
}
|
||||
};
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <RadioLib.h>
|
||||
|
||||
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
|
||||
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04
|
||||
|
||||
class CustomSX1262 : public SX1262 {
|
||||
public:
|
||||
@@ -10,7 +11,7 @@ class CustomSX1262 : public SX1262 {
|
||||
|
||||
bool isReceiving() {
|
||||
uint16_t irq = getIrqFlags();
|
||||
bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID);
|
||||
return hasPreamble;
|
||||
bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
|
||||
return detected;
|
||||
}
|
||||
};
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <RadioLib.h>
|
||||
|
||||
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
|
||||
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04
|
||||
|
||||
class CustomSX1268 : public SX1268 {
|
||||
public:
|
||||
@@ -10,7 +11,7 @@ class CustomSX1268 : public SX1268 {
|
||||
|
||||
bool isReceiving() {
|
||||
uint16_t irq = getIrqFlags();
|
||||
bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID);
|
||||
return hasPreamble;
|
||||
bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
|
||||
return detected;
|
||||
}
|
||||
};
|
||||
41
src/helpers/ESP32Board.cpp
Normal file
41
src/helpers/ESP32Board.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include "ESP32Board.h"
|
||||
|
||||
#if defined(ADMIN_PASSWORD) // Repeater or Room Server only
|
||||
#include <WiFi.h>
|
||||
#include <AsyncTCP.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <AsyncElegantOTA.h>
|
||||
|
||||
bool ESP32Board::startOTAUpdate(const char* id, char reply[]) {
|
||||
WiFi.softAP("MeshCore-OTA", NULL);
|
||||
|
||||
sprintf(reply, "Started: http://%s/update", WiFi.softAPIP().toString().c_str());
|
||||
MESH_DEBUG_PRINTLN("startOTAUpdate: %s", reply);
|
||||
|
||||
static char id_buf[60];
|
||||
sprintf(id_buf, "%s (%s)", id, getManufacturerName());
|
||||
static char home_buf[90];
|
||||
sprintf(home_buf, "<H2>Hi! I am a MeshCore Repeater. ID: %s</H2>", id);
|
||||
|
||||
AsyncWebServer* server = new AsyncWebServer(80);
|
||||
|
||||
server->on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
request->send(200, "text/html", home_buf);
|
||||
});
|
||||
|
||||
AsyncElegantOTA.setID(id_buf);
|
||||
AsyncElegantOTA.begin(server); // Start ElegantOTA
|
||||
server->begin();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
bool ESP32Board::startOTAUpdate(const char* id, char reply[]) {
|
||||
return false; // not supported
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <rom/rtc.h>
|
||||
#include <sys/time.h>
|
||||
#include <Wire.h>
|
||||
|
||||
class ESP32Board : public mesh::MainBoard {
|
||||
protected:
|
||||
@@ -33,7 +34,9 @@ public:
|
||||
#endif
|
||||
|
||||
#if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
|
||||
#if PIN_BOARD_SDA >= 0 && PIN_BOARD_SCL >= 0
|
||||
Wire.begin(PIN_BOARD_SDA, PIN_BOARD_SCL);
|
||||
#endif
|
||||
#else
|
||||
Wire.begin();
|
||||
#endif
|
||||
@@ -73,6 +76,8 @@ public:
|
||||
void reboot() override {
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
bool startOTAUpdate(const char* id, char reply[]) override;
|
||||
};
|
||||
|
||||
class ESP32RTCClock : public mesh::RTCClock {
|
||||
|
||||
@@ -37,6 +37,8 @@ public:
|
||||
power.setALDO2Voltage(3300);
|
||||
power.enableALDO2();
|
||||
|
||||
pinMode(38,INPUT_PULLUP);
|
||||
|
||||
esp_reset_reason_t reason = esp_reset_reason();
|
||||
if (reason == ESP_RST_DEEPSLEEP) {
|
||||
long wakeup_source = esp_sleep_get_ext1_wakeup_status();
|
||||
|
||||
103
src/helpers/esp32/ESPNOWRadio.cpp
Normal file
103
src/helpers/esp32/ESPNOWRadio.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include "ESPNOWRadio.h"
|
||||
#include <esp_now.h>
|
||||
#include <WiFi.h>
|
||||
#include <esp_wifi.h>
|
||||
|
||||
static uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
static esp_now_peer_info_t peerInfo;
|
||||
static bool is_send_complete = false;
|
||||
static esp_err_t last_send_result;
|
||||
static uint8_t rx_buf[256];
|
||||
static uint8_t last_rx_len = 0;
|
||||
|
||||
// callback when data is sent
|
||||
static void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
|
||||
is_send_complete = true;
|
||||
ESPNOW_DEBUG_PRINTLN("Send Status: %d", (int)status);
|
||||
}
|
||||
|
||||
static void OnDataRecv(const uint8_t *mac, const uint8_t *data, int len) {
|
||||
ESPNOW_DEBUG_PRINTLN("Recv: len = %d", len);
|
||||
memcpy(rx_buf, data, len);
|
||||
last_rx_len = len;
|
||||
}
|
||||
|
||||
void ESPNOWRadio::begin() {
|
||||
// Set device as a Wi-Fi Station
|
||||
WiFi.mode(WIFI_STA);
|
||||
// Long Range mode
|
||||
esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_LR);
|
||||
|
||||
// Init ESP-NOW
|
||||
if (esp_now_init() != ESP_OK) {
|
||||
ESPNOW_DEBUG_PRINTLN("Error initializing ESP-NOW");
|
||||
return;
|
||||
}
|
||||
|
||||
esp_wifi_set_max_tx_power(80); // should be 20dBm
|
||||
|
||||
esp_now_register_send_cb(OnDataSent);
|
||||
esp_now_register_recv_cb(OnDataRecv);
|
||||
|
||||
// Register peer
|
||||
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
|
||||
peerInfo.channel = 0;
|
||||
peerInfo.encrypt = false;
|
||||
|
||||
// Add peer
|
||||
if (esp_now_add_peer(&peerInfo) == ESP_OK) {
|
||||
ESPNOW_DEBUG_PRINTLN("init success");
|
||||
} else {
|
||||
// ESPNOW_DEBUG_PRINTLN("Failed to add peer");
|
||||
}
|
||||
}
|
||||
|
||||
void ESPNOWRadio::setTxPower(uint8_t dbm) {
|
||||
esp_wifi_set_max_tx_power(dbm * 4);
|
||||
}
|
||||
|
||||
uint32_t ESPNOWRadio::intID() {
|
||||
uint8_t mac[8];
|
||||
memset(mac, 0, sizeof(mac));
|
||||
esp_efuse_mac_get_default(mac);
|
||||
uint32_t n, m;
|
||||
memcpy(&n, &mac[0], 4);
|
||||
memcpy(&m, &mac[4], 4);
|
||||
|
||||
return n + m;
|
||||
}
|
||||
|
||||
void ESPNOWRadio::startSendRaw(const uint8_t* bytes, int len) {
|
||||
// Send message via ESP-NOW
|
||||
is_send_complete = false;
|
||||
esp_err_t result = esp_now_send(broadcastAddress, bytes, len);
|
||||
if (result == ESP_OK) {
|
||||
ESPNOW_DEBUG_PRINTLN("Send success");
|
||||
} else {
|
||||
last_send_result = result;
|
||||
is_send_complete = true;
|
||||
ESPNOW_DEBUG_PRINTLN("Send failed: %d", result);
|
||||
}
|
||||
}
|
||||
|
||||
bool ESPNOWRadio::isSendComplete() {
|
||||
return is_send_complete;
|
||||
}
|
||||
void ESPNOWRadio::onSendFinished() {
|
||||
}
|
||||
|
||||
float ESPNOWRadio::getLastRSSI() const { return 0; }
|
||||
float ESPNOWRadio::getLastSNR() const { return 0; }
|
||||
|
||||
int ESPNOWRadio::recvRaw(uint8_t* bytes, int sz) {
|
||||
int len = last_rx_len;
|
||||
if (last_rx_len > 0) {
|
||||
memcpy(bytes, rx_buf, last_rx_len);
|
||||
last_rx_len = 0;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
uint32_t ESPNOWRadio::getEstAirtimeFor(int len_bytes) {
|
||||
return 4; // Fast AF
|
||||
}
|
||||
36
src/helpers/esp32/ESPNOWRadio.h
Normal file
36
src/helpers/esp32/ESPNOWRadio.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <Mesh.h>
|
||||
|
||||
class ESPNOWRadio : public mesh::Radio {
|
||||
protected:
|
||||
uint32_t n_recv, n_sent;
|
||||
|
||||
public:
|
||||
ESPNOWRadio() { n_recv = n_sent = 0; }
|
||||
|
||||
void begin() override;
|
||||
int recvRaw(uint8_t* bytes, int sz) override;
|
||||
uint32_t getEstAirtimeFor(int len_bytes) override;
|
||||
void startSendRaw(const uint8_t* bytes, int len) override;
|
||||
bool isSendComplete() override;
|
||||
void onSendFinished() override;
|
||||
|
||||
uint32_t getPacketsRecv() const { return n_recv; }
|
||||
uint32_t getPacketsSent() const { return n_sent; }
|
||||
virtual float getLastRSSI() const override;
|
||||
virtual float getLastSNR() const override;
|
||||
|
||||
float packetScore(float snr, int packet_len) override { return 0; }
|
||||
uint32_t intID();
|
||||
void setTxPower(uint8_t dbm);
|
||||
};
|
||||
|
||||
#if ESPNOW_DEBUG_LOGGING && ARDUINO
|
||||
#include <Arduino.h>
|
||||
#define ESPNOW_DEBUG_PRINT(F, ...) Serial.printf("ESP-Now: " F, ##__VA_ARGS__)
|
||||
#define ESPNOW_DEBUG_PRINTLN(F, ...) Serial.printf("ESP-Now: " F "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define ESPNOW_DEBUG_PRINT(...) {}
|
||||
#define ESPNOW_DEBUG_PRINTLN(...) {}
|
||||
#endif
|
||||
@@ -1,24 +1,45 @@
|
||||
#include <Arduino.h>
|
||||
#include "faketecBoard.h"
|
||||
#include "FaketecBoard.h"
|
||||
|
||||
#include <bluefruit.h>
|
||||
#include <Wire.h>
|
||||
|
||||
static BLEDfu bledfu;
|
||||
|
||||
void FaketecBoard::begin() {
|
||||
// for future use, sub-classes SHOULD call this from their begin()
|
||||
startup_reason = BD_STARTUP_NORMAL;
|
||||
btn_prev_state = HIGH;
|
||||
|
||||
pinMode(PIN_VBAT_READ, INPUT);
|
||||
|
||||
#ifdef BUTTON_PIN
|
||||
pinMode(BUTTON_PIN, INPUT);
|
||||
#endif
|
||||
|
||||
#if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
|
||||
Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL);
|
||||
#endif
|
||||
|
||||
Wire.begin();
|
||||
|
||||
pinMode(SX126X_POWER_EN, OUTPUT);
|
||||
digitalWrite(SX126X_POWER_EN, HIGH);
|
||||
delay(10); // give sx1262 some time to power up
|
||||
}
|
||||
|
||||
static void connect_callback(uint16_t conn_handle) {
|
||||
(void)conn_handle;
|
||||
MESH_DEBUG_PRINTLN("BLE client connected");
|
||||
(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)conn_handle;
|
||||
(void)reason;
|
||||
MESH_DEBUG_PRINTLN("BLE client disconnected");
|
||||
}
|
||||
|
||||
bool faketecBoard::startOTAUpdate() {
|
||||
bool FaketecBoard::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()
|
||||
@@ -57,5 +78,6 @@ bool faketecBoard::startOTAUpdate() {
|
||||
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;
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <MeshCore.h>
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#define P_LORA_NSS 13 //P1.13 45
|
||||
#define P_LORA_DIO_1 11 //P0.10 10
|
||||
@@ -20,27 +19,13 @@
|
||||
#define PIN_VBAT_READ 17
|
||||
#define ADC_MULTIPLIER (1.815f) // dependent on voltage divider resistors. TODO: more accurate battery tracking
|
||||
|
||||
class faketecBoard : public mesh::MainBoard {
|
||||
class FaketecBoard : public mesh::MainBoard {
|
||||
protected:
|
||||
uint8_t startup_reason;
|
||||
uint8_t btn_prev_state;
|
||||
|
||||
public:
|
||||
void begin() {
|
||||
// for future use, sub-classes SHOULD call this from their begin()
|
||||
startup_reason = BD_STARTUP_NORMAL;
|
||||
|
||||
pinMode(PIN_VBAT_READ, INPUT);
|
||||
|
||||
#if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
|
||||
Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL)
|
||||
#endif
|
||||
|
||||
Wire.begin();
|
||||
|
||||
pinMode(SX126X_POWER_EN, OUTPUT);
|
||||
digitalWrite(SX126X_POWER_EN, HIGH);
|
||||
delay(10); // give sx1262 some time to power up
|
||||
}
|
||||
void begin();
|
||||
|
||||
uint8_t getStartupReason() const override { return startup_reason; }
|
||||
|
||||
@@ -61,9 +46,20 @@ public:
|
||||
return "Faketec DIY";
|
||||
}
|
||||
|
||||
int buttonStateChanged() {
|
||||
#ifdef BUTTON_PIN
|
||||
uint8_t v = digitalRead(BUTTON_PIN);
|
||||
if (v != btn_prev_state) {
|
||||
btn_prev_state = v;
|
||||
return (v == LOW) ? 1 : -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reboot() override {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
bool startOTAUpdate() override;
|
||||
bool startOTAUpdate(const char* id, char reply[]) override;
|
||||
};
|
||||
@@ -37,7 +37,7 @@ void RAK4631Board::begin() {
|
||||
delay(10); // give sx1262 some time to power up
|
||||
}
|
||||
|
||||
bool RAK4631Board::startOTAUpdate() {
|
||||
bool RAK4631Board::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()
|
||||
@@ -76,5 +76,6 @@ bool RAK4631Board::startOTAUpdate() {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -50,5 +50,5 @@ public:
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
bool startOTAUpdate() override;
|
||||
bool startOTAUpdate(const char* id, char reply[]) override;
|
||||
};
|
||||
|
||||
@@ -9,6 +9,8 @@ void T1000eBoard::begin() {
|
||||
startup_reason = BD_STARTUP_NORMAL;
|
||||
btn_prev_state = HIGH;
|
||||
|
||||
sd_power_mode_set(NRF_POWER_MODE_LOWPWR);
|
||||
|
||||
#ifdef BUTTON_PIN
|
||||
pinMode(BATTERY_PIN, INPUT);
|
||||
pinMode(BUTTON_PIN, INPUT);
|
||||
@@ -40,7 +42,7 @@ static void disconnect_callback(uint16_t conn_handle, uint8_t reason) {
|
||||
}
|
||||
|
||||
|
||||
bool TrackerT1000eBoard::startOTAUpdate() {
|
||||
bool TrackerT1000eBoard::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()
|
||||
@@ -79,6 +81,7 @@ bool TrackerT1000eBoard::startOTAUpdate() {
|
||||
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
|
||||
@@ -90,5 +90,5 @@ public:
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
// bool startOTAUpdate() override;
|
||||
// bool startOTAUpdate(const char* id, char reply[]) override;
|
||||
};
|
||||
@@ -42,7 +42,7 @@ void T114Board::begin() {
|
||||
delay(10); // give sx1262 some time to power up
|
||||
}
|
||||
|
||||
bool T114Board::startOTAUpdate() {
|
||||
bool T114Board::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()
|
||||
@@ -81,5 +81,6 @@ bool T114Board::startOTAUpdate() {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
// built-ins
|
||||
#define PIN_VBAT_READ 4
|
||||
#define ADC_MULTIPLIER (3 * 1.73 * 1.187 * 1000)
|
||||
#define PIN_BAT_CTL 6
|
||||
#define MV_LSB (3000.0F / 4096.0F) // 12-bit ADC with 3.0V input range
|
||||
|
||||
class T114Board : public mesh::MainBoard {
|
||||
protected:
|
||||
@@ -37,17 +38,18 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
#define BATTERY_SAMPLES 8
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
int adcvalue = 0;
|
||||
analogReadResolution(12);
|
||||
uint32_t raw = 0;
|
||||
for (int i = 0; i < BATTERY_SAMPLES; i++) {
|
||||
raw += analogRead(PIN_VBAT_READ);
|
||||
}
|
||||
raw = raw / BATTERY_SAMPLES;
|
||||
analogReference(AR_INTERNAL_3_0);
|
||||
pinMode(PIN_BAT_CTL, OUTPUT); // battery adc can be read only ctrl pin 6 set to high
|
||||
digitalWrite(PIN_BAT_CTL, 1);
|
||||
|
||||
return (ADC_MULTIPLIER * raw) / 4096;
|
||||
delay(10);
|
||||
adcvalue = analogRead(PIN_VBAT_READ);
|
||||
digitalWrite(6, 0);
|
||||
|
||||
return (uint16_t)((float)adcvalue * MV_LSB * 4.9);
|
||||
}
|
||||
|
||||
const char* getManufacturerName() const override {
|
||||
@@ -58,5 +60,5 @@ public:
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
bool startOTAUpdate() override;
|
||||
bool startOTAUpdate(const char* id, char reply[]) override;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <Arduino.h>
|
||||
#include "TechoBoard.h"
|
||||
|
||||
#ifdef LILYGO_TECHO
|
||||
|
||||
#include <bluefruit.h>
|
||||
#include <Wire.h>
|
||||
|
||||
@@ -22,11 +24,18 @@ void TechoBoard::begin() {
|
||||
// for future use, sub-classes SHOULD call this from their begin()
|
||||
startup_reason = BD_STARTUP_NORMAL;
|
||||
|
||||
pinMode(PIN_VBAT_READ, INPUT);
|
||||
delay(200);
|
||||
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);
|
||||
delay(200);
|
||||
|
||||
#if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
|
||||
Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL)
|
||||
#endif
|
||||
pinMode(PIN_TXCO, OUTPUT);
|
||||
digitalWrite(PIN_TXCO, HIGH);
|
||||
|
||||
Wire.begin();
|
||||
|
||||
@@ -35,7 +44,21 @@ void TechoBoard::begin() {
|
||||
delay(10); // give sx1262 some time to power up
|
||||
}
|
||||
|
||||
bool TechoBoard::startOTAUpdate() {
|
||||
uint16_t TechoBoard::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 TechoBoard::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()
|
||||
@@ -74,5 +97,7 @@ bool TechoBoard::startOTAUpdate() {
|
||||
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
|
||||
|
||||
@@ -17,28 +17,26 @@
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
|
||||
// built-ins
|
||||
#define PIN_VBAT_READ 4
|
||||
#define ADC_MULTIPLIER (2.0)
|
||||
#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
|
||||
#define VBAT_DIVIDER_COMP (2.0F) // Compensation factor for the VBAT divider
|
||||
|
||||
#define PIN_VBAT_READ (4)
|
||||
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
|
||||
|
||||
class TechoBoard : public mesh::MainBoard {
|
||||
protected:
|
||||
uint8_t startup_reason;
|
||||
|
||||
public:
|
||||
|
||||
void begin();
|
||||
uint8_t getStartupReason() const override { return startup_reason; }
|
||||
uint16_t getBattMilliVolts() override;
|
||||
bool startOTAUpdate(const char* id, char reply[]) override;
|
||||
|
||||
#define BATTERY_SAMPLES 8
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
analogReadResolution(12);
|
||||
uint32_t raw = 0;
|
||||
for (int i = 0; i < BATTERY_SAMPLES; i++) {
|
||||
raw += analogRead(PIN_VBAT_READ);
|
||||
}
|
||||
raw = raw / BATTERY_SAMPLES;
|
||||
|
||||
return (ADC_MULTIPLIER * raw) / 4096;
|
||||
uint8_t getStartupReason() const override {
|
||||
return startup_reason;
|
||||
}
|
||||
|
||||
const char* getManufacturerName() const override {
|
||||
@@ -48,6 +46,4 @@ public:
|
||||
void reboot() override {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
bool startOTAUpdate() override;
|
||||
};
|
||||
|
||||
83
variants/generic_espnow/platformio.ini
Normal file
83
variants/generic_espnow/platformio.ini
Normal file
@@ -0,0 +1,83 @@
|
||||
|
||||
; ----------- Generic ESP32-C3 ------------
|
||||
|
||||
[Generic_ESPNOW]
|
||||
extends = esp32_base
|
||||
board = esp32-c3-devkitm-1
|
||||
;board = esp32-s3-devkitm-1
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-I variants/generic_espnow
|
||||
; -D ESP32_CPU_FREQ=80
|
||||
-D PIN_BOARD_SDA=-1
|
||||
-D PIN_BOARD_SCL=-1
|
||||
; -D P_LORA_TX_LED=8
|
||||
-D PIN_USER_BTN=0
|
||||
; -D ARDUINO_USB_MODE=1
|
||||
; -D ARDUINO_USB_CDC_ON_BOOT=1
|
||||
; -D ESPNOW_DEBUG_LOGGING=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<helpers/esp32/ESPNowRadio.cpp>
|
||||
+<../variants/generic_espnow>
|
||||
|
||||
[env:Generic_ESPNOW_terminal_chat]
|
||||
extends = Generic_ESPNOW
|
||||
build_flags =
|
||||
${Generic_ESPNOW.build_flags}
|
||||
-D MAX_CONTACTS=100
|
||||
-D MAX_GROUP_CHANNELS=1
|
||||
build_src_filter = ${Generic_ESPNOW.build_src_filter}
|
||||
+<../examples/simple_secure_chat/main.cpp>
|
||||
lib_deps =
|
||||
${Generic_ESPNOW.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Generic_ESPNOW_repeatr]
|
||||
extends = Generic_ESPNOW
|
||||
build_flags =
|
||||
${Generic_ESPNOW.build_flags}
|
||||
-D ADVERT_NAME='"ESPNOW Repeater"'
|
||||
-D ADVERT_LAT=-37.0
|
||||
-D ADVERT_LON=145.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
build_src_filter = ${Generic_ESPNOW.build_src_filter}
|
||||
+<../examples/simple_repeater/main.cpp>
|
||||
lib_deps =
|
||||
${Generic_ESPNOW.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Generic_ESPNOW_comp_radio_usb]
|
||||
extends = Generic_ESPNOW
|
||||
build_flags =
|
||||
${Generic_ESPNOW.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
|
||||
; NOTE: DO NOT ENABLE --> -D ESPNOW_DEBUG_LOGGING=1
|
||||
build_src_filter = ${Generic_ESPNOW.build_src_filter}
|
||||
+<../examples/companion_radio/main.cpp>
|
||||
lib_deps =
|
||||
${Generic_ESPNOW.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:Generic_ESPNOW_room_svr]
|
||||
extends = Generic_ESPNOW
|
||||
build_flags =
|
||||
${Generic_ESPNOW.build_flags}
|
||||
-D ADVERT_NAME='"Heltec Room"'
|
||||
-D ADVERT_LAT=-37.0
|
||||
-D ADVERT_LON=145.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D ROOM_PASSWORD='"hello"'
|
||||
build_src_filter = ${Generic_ESPNOW.build_src_filter}
|
||||
+<../examples/simple_room_server/main.cpp>
|
||||
lib_deps =
|
||||
${Generic_ESPNOW.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
33
variants/generic_espnow/target.cpp
Normal file
33
variants/generic_espnow/target.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
|
||||
ESP32Board board;
|
||||
|
||||
ESPNOWRadio radio_driver;
|
||||
|
||||
ESP32RTCClock rtc_clock;
|
||||
|
||||
bool radio_init() {
|
||||
rtc_clock.begin();
|
||||
|
||||
// NOTE: radio_driver.begin() is called by Dispatcher::begin(), so not needed here
|
||||
return true; // success
|
||||
}
|
||||
|
||||
uint32_t radio_get_rng_seed() {
|
||||
return millis() + radio_driver.intID(); // TODO: where to get some entropy?
|
||||
}
|
||||
|
||||
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
void radio_set_tx_power(uint8_t dbm) {
|
||||
radio_driver.setTxPower(dbm);
|
||||
}
|
||||
|
||||
mesh::LocalIdentity radio_new_identity() {
|
||||
StdRNG rng; // TODO: need stronger True-RNG here
|
||||
return mesh::LocalIdentity(&rng); // create new random identity
|
||||
}
|
||||
14
variants/generic_espnow/target.h
Normal file
14
variants/generic_espnow/target.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <helpers/esp32/ESPNOWRadio.h>
|
||||
|
||||
extern ESP32Board board;
|
||||
extern ESPNOWRadio radio_driver;
|
||||
extern ESP32RTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -3,6 +3,7 @@ extends = esp32_base
|
||||
board = heltec_wifi_lora_32_V2 ; heltec_wifi_lora_32_V2
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-I variants/heltec_v2
|
||||
-D HELTEC_LORA_V2
|
||||
-D PIN_BOARD_SDA=4
|
||||
-D PIN_BOARD_SCL=15
|
||||
@@ -13,6 +14,7 @@ build_flags =
|
||||
-D LORA_TX_POWER=20
|
||||
-D P_LORA_TX_LED=25
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<../variants/heltec_v2>
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
adafruit/Adafruit SSD1306 @ ^2.5.13
|
||||
@@ -31,6 +33,9 @@ build_flags =
|
||||
build_src_filter = ${Heltec_lora32_v2.build_src_filter}
|
||||
+<../examples/simple_repeater>
|
||||
+<helpers/ui/*.cpp>
|
||||
lib_deps =
|
||||
${Heltec_lora32_v2.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Heltec_v2_room_server]
|
||||
extends = Heltec_lora32_v2
|
||||
@@ -47,6 +52,9 @@ build_flags =
|
||||
build_src_filter = ${Heltec_lora32_v2.build_src_filter}
|
||||
+<helpers/ui/*.cpp>
|
||||
+<../examples/simple_room_server>
|
||||
lib_deps =
|
||||
${Heltec_lora32_v2.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Heltec_v2_terminal_chat]
|
||||
extends = Heltec_lora32_v2
|
||||
|
||||
59
variants/heltec_v2/target.cpp
Normal file
59
variants/heltec_v2/target.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
|
||||
HeltecV2Board 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);
|
||||
|
||||
#ifndef LORA_CR
|
||||
#define LORA_CR 5
|
||||
#endif
|
||||
|
||||
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
|
||||
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) {
|
||||
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
|
||||
}
|
||||
18
variants/heltec_v2/target.h
Normal file
18
variants/heltec_v2/target.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/HeltecV2Board.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern HeltecV2Board board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -3,6 +3,7 @@ extends = esp32_base
|
||||
board = esp32-s3-devkitc-1
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-I variants/heltec_v3
|
||||
-D HELTEC_LORA_V3
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
-D WRAPPER_CLASS=CustomSX1262Wrapper
|
||||
@@ -16,6 +17,7 @@ build_flags =
|
||||
-D SX126X_CURRENT_LIMIT=130.0f ; for best TX power!
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<../variants/heltec_v3>
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
adafruit/Adafruit SSD1306 @ ^2.5.13
|
||||
@@ -34,6 +36,9 @@ build_flags =
|
||||
build_src_filter = ${Heltec_lora32_v3.build_src_filter}
|
||||
+<helpers/ui/*.cpp>
|
||||
+<../examples/simple_repeater>
|
||||
lib_deps =
|
||||
${Heltec_lora32_v3.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Heltec_v3_room_server]
|
||||
extends = Heltec_lora32_v3
|
||||
@@ -50,6 +55,9 @@ build_flags =
|
||||
build_src_filter = ${Heltec_lora32_v3.build_src_filter}
|
||||
+<helpers/ui/*.cpp>
|
||||
+<../examples/simple_room_server>
|
||||
lib_deps =
|
||||
${Heltec_lora32_v3.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Heltec_v3_terminal_chat]
|
||||
extends = Heltec_lora32_v3
|
||||
@@ -138,6 +146,9 @@ build_flags =
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${Heltec_lora32_v3.build_src_filter}
|
||||
+<../examples/simple_repeater>
|
||||
lib_deps =
|
||||
${Heltec_lora32_v3.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Heltec_WSL3_room_server]
|
||||
extends = Heltec_lora32_v3
|
||||
@@ -152,6 +163,9 @@ build_flags =
|
||||
-D ROOM_PASSWORD='"hello"'
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
lib_deps =
|
||||
${Heltec_lora32_v3.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Heltec_WSL3_companion_radio_ble]
|
||||
extends = Heltec_lora32_v3
|
||||
|
||||
75
variants/heltec_v3/target.cpp
Normal file
75
variants/heltec_v3/target.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.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);
|
||||
|
||||
#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
|
||||
}
|
||||
18
variants/heltec_v3/target.h
Normal file
18
variants/heltec_v3/target.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#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>
|
||||
|
||||
extern HeltecV3Board board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -3,6 +3,7 @@ extends = esp32_base
|
||||
board = t3_s3_v1_x
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-I variants/lilygo_t3s3
|
||||
-D LILYGO_T3S3
|
||||
-D P_LORA_DIO_1=33
|
||||
-D P_LORA_NSS=7
|
||||
@@ -26,6 +27,7 @@ build_flags =
|
||||
-D LORA_TX_POWER=22
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<../variants/lilygo_t3s3>
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
adafruit/Adafruit SSD1306 @ ^2.5.13
|
||||
@@ -45,6 +47,9 @@ build_flags =
|
||||
build_src_filter = ${LilyGo_T3S3_sx1262.build_src_filter}
|
||||
+<helpers/ui/*.cpp>
|
||||
+<../examples/simple_repeater>
|
||||
lib_deps =
|
||||
${LilyGo_T3S3_sx1262.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:LilyGo_T3S3_sx1262_terminal_chat]
|
||||
extends = LilyGo_T3S3_sx1262
|
||||
@@ -75,6 +80,9 @@ build_flags =
|
||||
build_src_filter = ${LilyGo_T3S3_sx1262.build_src_filter}
|
||||
+<helpers/ui/*.cpp>
|
||||
+<../examples/simple_room_server>
|
||||
lib_deps =
|
||||
${LilyGo_T3S3_sx1262.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:LilyGo_T3S3_sx1262_companion_radio_usb]
|
||||
extends = LilyGo_T3S3_sx1262
|
||||
|
||||
75
variants/lilygo_t3s3/target.cpp
Normal file
75
variants/lilygo_t3s3/target.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#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);
|
||||
|
||||
#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
|
||||
}
|
||||
18
variants/lilygo_t3s3/target.h
Normal file
18
variants/lilygo_t3s3/target.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern ESP32Board board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -3,19 +3,29 @@ extends = esp32_base
|
||||
board = ttgo-t-beam
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-I variants/lilygo_tbeam
|
||||
-D LILYGO_TBEAM
|
||||
-D RADIO_CLASS=CustomSX1276
|
||||
-D WRAPPER_CLASS=CustomSX1276Wrapper
|
||||
-D LORA_TX_POWER=20
|
||||
-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>
|
||||
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_companion_radio_ble]
|
||||
extends = LilyGo_TBeam
|
||||
board_build.upload.maximum_ram_size=2000000
|
||||
build_flags =
|
||||
${LilyGo_TBeam.build_flags}
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D MAX_CONTACTS=100
|
||||
-D MAX_GROUP_CHANNELS=1
|
||||
-D BLE_PIN_CODE=123456
|
||||
@@ -29,8 +39,8 @@ build_flags =
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${LilyGo_TBeam.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<../examples/companion_radio/main.cpp>
|
||||
+<helpers/ui/*.cpp>
|
||||
+<../examples/companion_radio>
|
||||
lib_deps =
|
||||
${LilyGo_TBeam.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
lewisxhe/XPowersLib@^0.2.7
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
59
variants/lilygo_tbeam/target.cpp
Normal file
59
variants/lilygo_tbeam/target.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
|
||||
TBeamBoard 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);
|
||||
|
||||
#ifndef LORA_CR
|
||||
#define LORA_CR 5
|
||||
#endif
|
||||
|
||||
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
|
||||
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) {
|
||||
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
|
||||
}
|
||||
18
variants/lilygo_tbeam/target.h
Normal file
18
variants/lilygo_tbeam/target.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/TBeamBoard.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern TBeamBoard board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -6,6 +6,7 @@ build_type = release ; Set build type to release
|
||||
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-I variants/lilygo_tlora_v2_1
|
||||
-Os -ffunction-sections -fdata-sections ; Optimize for size
|
||||
-D LILYGO_TLORA ; LILYGO T-LoRa V2.1-1.6 ESP32 with SX1276
|
||||
-D P_LORA_DIO_0=26 ; SX1276 DIO0 interrupt pin
|
||||
@@ -23,6 +24,8 @@ build_flags =
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D WRAPPER_CLASS=CustomSX1276Wrapper
|
||||
-D LORA_TX_POWER=20
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<../variants/lilygo_tlora_v2_1>
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
adafruit/Adafruit SSD1306 @ ^2.5.13
|
||||
@@ -42,6 +45,9 @@ build_flags =
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
; -D CORE_DEBUG_LEVEL=3
|
||||
lib_deps =
|
||||
${LilyGo_TLora_V2_1_1_6.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:LilyGo_TLora_V2_1_1_6_terminal_chat]
|
||||
extends = LilyGo_TLora_V2_1_1_6
|
||||
@@ -109,3 +115,6 @@ build_flags =
|
||||
-D ROOM_PASSWORD='"hello"'
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
lib_deps =
|
||||
${LilyGo_TLora_V2_1_1_6.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
53
variants/lilygo_tlora_v2_1/target.cpp
Normal file
53
variants/lilygo_tlora_v2_1/target.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
|
||||
LilyGoTLoraBoard board;
|
||||
|
||||
static SPIClass spi;
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi);
|
||||
|
||||
WRAPPER_CLASS radio_driver(radio, board);
|
||||
|
||||
ESP32RTCClock fallback_clock;
|
||||
AutoDiscoverRTCClock rtc_clock(fallback_clock);
|
||||
|
||||
#ifndef LORA_CR
|
||||
#define LORA_CR 5
|
||||
#endif
|
||||
|
||||
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) {
|
||||
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
|
||||
}
|
||||
18
variants/lilygo_tlora_v2_1/target.h
Normal file
18
variants/lilygo_tlora_v2_1/target.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/LilyGoTLoraBoard.h>
|
||||
#include <helpers/CustomSX1276Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern LilyGoTLoraBoard board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -1,18 +1,29 @@
|
||||
[faketec]
|
||||
extends = nrf52840_base
|
||||
board = promicro_nrf52840
|
||||
build_src_filter = ${nrf52840_base.build_src_filter} +<helpers/nrf52/faketecBoard.cpp>
|
||||
build_flags = ${nrf52840_base.build_flags}
|
||||
-I variants/promicro
|
||||
-D FAKETEC
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
-D WRAPPER_CLASS=CustomSX1262Wrapper
|
||||
-D LORA_TX_POWER=22
|
||||
-D SX126X_CURRENT_LIMIT=130
|
||||
-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
|
||||
build_src_filter = ${nrf52840_base.build_src_filter}
|
||||
+<helpers/nrf52/FaketecBoard.cpp>
|
||||
+<../variants/promicro>
|
||||
lib_deps=
|
||||
${nrf52840_base.lib_deps}
|
||||
adafruit/Adafruit SSD1306 @ ^2.5.13
|
||||
|
||||
[env:Faketec_Repeater]
|
||||
extends = faketec
|
||||
build_src_filter = ${faketec.build_src_filter} +<../examples/simple_repeater/main.cpp>
|
||||
build_src_filter = ${faketec.build_src_filter} +<../examples/simple_repeater> +<helpers/ui/*.cpp>
|
||||
build_flags =
|
||||
${faketec.build_flags}
|
||||
-D ADVERT_NAME="\"Faketec Repeater\""
|
||||
@@ -27,7 +38,7 @@ lib_deps =
|
||||
|
||||
[env:Faketec_room_server]
|
||||
extends = faketec
|
||||
build_src_filter = ${faketec.build_src_filter} +<../examples/simple_room_server/main.cpp>
|
||||
build_src_filter = ${faketec.build_src_filter} +<../examples/simple_room_server> +<helpers/ui/*.cpp>
|
||||
build_flags =
|
||||
${faketec.build_flags}
|
||||
-D ADVERT_NAME="\"Test Room\""
|
||||
@@ -63,7 +74,7 @@ build_flags =
|
||||
-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 = ${faketec.build_src_filter} +<../examples/companion_radio/main.cpp>
|
||||
build_src_filter = ${faketec.build_src_filter} +<../examples/companion_radio> +<../examples/companion_radio> +<helpers/ui/*.cpp>
|
||||
lib_deps =
|
||||
${faketec.lib_deps}
|
||||
adafruit/RTClib @ ^2.1.3
|
||||
@@ -81,7 +92,7 @@ build_flags =
|
||||
-D ENABLE_PRIVATE_KEY_IMPORT=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${faketec.build_src_filter} +<helpers/nrf52/SerialBLEInterface.cpp> +<../examples/companion_radio/main.cpp>
|
||||
build_src_filter = ${faketec.build_src_filter} +<helpers/nrf52/SerialBLEInterface.cpp> +<../examples/companion_radio> +<helpers/ui/*.cpp>
|
||||
lib_deps =
|
||||
${faketec.lib_deps}
|
||||
adafruit/RTClib @ ^2.1.3
|
||||
@@ -90,14 +101,17 @@ lib_deps =
|
||||
[ProMicroLLCC68]
|
||||
extends = nrf52840_base
|
||||
board = promicro_nrf52840
|
||||
build_src_filter = ${nrf52840_base.build_src_filter} +<helpers/nrf52/faketecBoard.cpp>
|
||||
build_flags = ${nrf52840_base.build_flags}
|
||||
-I variants/promicro
|
||||
-D FAKETEC
|
||||
-D RADIO_CLASS=CustomLLCC68
|
||||
-D WRAPPER_CLASS=CustomLLCC68Wrapper
|
||||
-D LORA_TX_POWER=22
|
||||
-D SX126X_CURRENT_LIMIT=130
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
build_src_filter = ${nrf52840_base.build_src_filter}
|
||||
+<helpers/nrf52/FaketecBoard.cpp>
|
||||
+<../variants/promicro>
|
||||
|
||||
[env:ProMicroLLCC68_Repeater]
|
||||
extends = ProMicroLLCC68
|
||||
74
variants/promicro/target.cpp
Normal file
74
variants/promicro/target.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
|
||||
FaketecBoard 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);
|
||||
|
||||
#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_SPI_CMD_FAILED || status == RADIOLIB_ERR_SPI_CMD_INVALID) {
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE (0.0f);
|
||||
tcxo = SX126X_DIO3_TCXO_VOLTAGE;
|
||||
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
|
||||
}
|
||||
19
variants/promicro/target.h
Normal file
19
variants/promicro/target.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/nrf52/FaketecBoard.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/CustomLLCC68Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern FaketecBoard board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -4,6 +4,7 @@ platform = https://github.com/maxgerhardt/platform-nordicnrf52.git#rak
|
||||
board = wiscore_rak4631
|
||||
board_check = true
|
||||
build_flags = ${nrf52840_base.build_flags}
|
||||
-I variants/rak4631
|
||||
-D RAK_4631
|
||||
-D PIN_USER_BTN=9
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
@@ -13,6 +14,7 @@ build_flags = ${nrf52840_base.build_flags}
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
build_src_filter = ${nrf52840_base.build_src_filter}
|
||||
+<helpers/nrf52/*.cpp>
|
||||
+<../variants/rak4631>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
adafruit/Adafruit SSD1306 @ ^2.5.13
|
||||
|
||||
69
variants/rak4631/target.cpp
Normal file
69
variants/rak4631/target.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
|
||||
RAK4631Board 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);
|
||||
|
||||
#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
|
||||
}
|
||||
18
variants/rak4631/target.h
Normal file
18
variants/rak4631/target.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/nrf52/RAK4631Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern RAK4631Board board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -3,6 +3,7 @@ extends = esp32_base
|
||||
board = station-g2
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-I variants/station_g2
|
||||
-D STATION_G2
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
-D WRAPPER_CLASS=CustomSX1262Wrapper
|
||||
@@ -16,8 +17,8 @@ build_flags =
|
||||
-D SX126X_CURRENT_LIMIT=130.0f ; for best TX power!
|
||||
; -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}
|
||||
+<../variants/station_g2>
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
|
||||
@@ -33,6 +34,9 @@ build_flags =
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${Station_G2.build_src_filter}
|
||||
+<../examples/simple_repeater>
|
||||
lib_deps =
|
||||
${Station_G2.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Station_G2_room_server]
|
||||
extends = Station_G2
|
||||
@@ -47,3 +51,6 @@ build_flags =
|
||||
-D ROOM_PASSWORD='"hello"'
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
lib_deps =
|
||||
${Station_G2.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
75
variants/station_g2/target.cpp
Normal file
75
variants/station_g2/target.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
|
||||
StationG2Board 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);
|
||||
|
||||
#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
|
||||
}
|
||||
18
variants/station_g2/target.h
Normal file
18
variants/station_g2/target.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/StationG2Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern StationG2Board board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -19,14 +19,14 @@ extends = nrf52840_t1000e
|
||||
board = tracker-t1000-e
|
||||
board_build.ldscript = boards/nrf52840_s140_v7.ld
|
||||
build_flags = ${nrf52840_t1000e.build_flags}
|
||||
-Ivariants/t1000-e
|
||||
-I variants/t1000-e
|
||||
-D T1000_E
|
||||
-D PIN_USER_BTN=6
|
||||
-D USER_BTN_PRESSED=HIGH
|
||||
-D PIN_STATUS_LED=24
|
||||
-D RADIO_CLASS=CustomLR1110
|
||||
-D WRAPPER_CLASS=CustomLR1110Wrapper
|
||||
-D MAX_LORA_TX_POWER=22
|
||||
-D LORA_TX_POWER=22
|
||||
build_src_filter = ${nrf52840_t1000e.build_src_filter}
|
||||
+<helpers/*.cpp>
|
||||
+<helpers/nrf52/T1000eBoard.cpp>
|
||||
@@ -43,6 +43,8 @@ build_flags = ${t1000-e.build_flags}
|
||||
-D BLE_DEBUG_LOGGING=1
|
||||
-D MESH_PACKET_LOGGING=1
|
||||
-D MESH_DEBUG=1
|
||||
-D RX_BOOSTED_GAIN=true
|
||||
-D RF_SWITCH_TABLE
|
||||
-D HAS_UI
|
||||
build_src_filter = ${t1000-e.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
|
||||
88
variants/t1000-e/target.cpp
Normal file
88
variants/t1000-e/target.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
|
||||
T1000eBoard 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);
|
||||
|
||||
#ifndef LORA_CR
|
||||
#define LORA_CR 5
|
||||
#endif
|
||||
|
||||
#ifdef RF_SWITCH_TABLE
|
||||
static const uint32_t rfswitch_dios[Module::RFSWITCH_MAX_PINS] = {
|
||||
RADIOLIB_LR11X0_DIO5,
|
||||
RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_LR11X0_DIO7,
|
||||
RADIOLIB_LR11X0_DIO8,
|
||||
RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6 DIO7 DIO8
|
||||
{ LR11x0::MODE_STBY, {LOW, LOW, LOW, LOW }},
|
||||
{ LR11x0::MODE_RX, {HIGH, LOW, LOW, HIGH }},
|
||||
{ LR11x0::MODE_TX, {HIGH, HIGH, LOW, HIGH }},
|
||||
{ LR11x0::MODE_TX_HP, {LOW, HIGH, LOW, HIGH }},
|
||||
{ LR11x0::MODE_TX_HF, {LOW, LOW, LOW, LOW }},
|
||||
{ LR11x0::MODE_GNSS, {LOW, LOW, HIGH, LOW }},
|
||||
{ LR11x0::MODE_WIFI, {LOW, LOW, LOW, LOW }},
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
#endif
|
||||
|
||||
bool radio_init() {
|
||||
rtc_clock.begin(Wire);
|
||||
|
||||
#ifdef LR11X0_DIO3_TCXO_VOLTAGE
|
||||
float tcxo = LR11X0_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_LR11X0_LORA_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 RF_SWITCH_TABLE
|
||||
radio.setRfSwitchTable(rfswitch_dios, rfswitch_table);
|
||||
#endif
|
||||
#ifdef RX_BOOSTED_GAIN
|
||||
radio.setRxBoostedGainMode(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
|
||||
}
|
||||
18
variants/t1000-e/target.h
Normal file
18
variants/t1000-e/target.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/nrf52/T1000eBoard.h>
|
||||
#include <helpers/CustomLR1110Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern T1000eBoard board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -14,7 +14,7 @@ extends = nrf52840_t114
|
||||
board = heltec_t114
|
||||
board_build.ldscript = boards/nrf52840_s140_v6.ld
|
||||
build_flags = ${nrf52840_t114.build_flags}
|
||||
-Ivariants/t114
|
||||
-I variants/t114
|
||||
-DHELTEC_T114
|
||||
-D P_LORA_TX_LED=35
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
|
||||
69
variants/t114/target.cpp
Normal file
69
variants/t114/target.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
|
||||
T114Board 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);
|
||||
|
||||
#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
|
||||
}
|
||||
18
variants/t114/target.h
Normal file
18
variants/t114/target.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/nrf52/T114Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern T114Board board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -14,7 +14,7 @@ extends = nrf52840_techo
|
||||
board = t-echo
|
||||
board_build.ldscript = boards/nrf52840_s140_v6.ld
|
||||
build_flags = ${nrf52840_techo.build_flags}
|
||||
-Ivariants/techo
|
||||
-I variants/techo
|
||||
-DLILYGO_TECHO
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
-D WRAPPER_CLASS=CustomSX1262Wrapper
|
||||
|
||||
69
variants/techo/target.cpp
Normal file
69
variants/techo/target.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
|
||||
TechoBoard 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);
|
||||
|
||||
#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
|
||||
}
|
||||
18
variants/techo/target.h
Normal file
18
variants/techo/target.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/nrf52/TechoBoard.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern TechoBoard board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -14,12 +14,12 @@
|
||||
#define USE_LFXO // 32.768 kHz crystal oscillator
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
|
||||
#define WIRE_INTERFACES_COUNT (1)
|
||||
|
||||
#define WIRE_INTERFACES_COUNT (1)
|
||||
#define PIN_TXCO (21)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Power
|
||||
|
||||
#define PIN_PWR_EN (6)
|
||||
#define PIN_PWR_EN (12)
|
||||
|
||||
#define BATTERY_PIN (4)
|
||||
#define ADC_MULTIPLIER (4.90F)
|
||||
@@ -62,11 +62,11 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Builtin LEDs
|
||||
|
||||
#define LED_RED (13)
|
||||
#define LED_RED (34)
|
||||
#define LED_GREEN (33)
|
||||
#define LED_BLUE (14)
|
||||
#define LED_GREEN (15)
|
||||
|
||||
#define LED_BUILTIN (15)
|
||||
#define LED_BUILTIN LED_GREEN
|
||||
#define PIN_LED LED_BUILTIN
|
||||
#define LED_PIN LED_BUILTIN
|
||||
#define LED_STATE_ON LOW
|
||||
@@ -80,7 +80,7 @@
|
||||
#define PIN_BUTTON1 (42)
|
||||
#define BUTTON_PIN PIN_BUTTON1
|
||||
|
||||
#define PIN_BUTTON2 (18)
|
||||
#define PIN_BUTTON2 (11)
|
||||
#define BUTTON_PIN2 PIN_BUTTON2
|
||||
|
||||
#define EXTERNAL_FLASH_DEVICES MX25R1635F
|
||||
|
||||
@@ -3,6 +3,7 @@ extends = esp32_base
|
||||
board = seeed_xiao_esp32c3
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-I variants/xiao_c3
|
||||
-D LORA_TX_BOOST_PIN=D3
|
||||
-D P_LORA_TX_LED=D5
|
||||
-D PIN_VBAT_READ=D0
|
||||
@@ -15,6 +16,8 @@ build_flags =
|
||||
-D SX126X_DIO2_AS_RF_SWITCH=true
|
||||
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
|
||||
-D SX126X_CURRENT_LIMIT=130.0f ; for best TX power!
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<../variants/xiao_c3>
|
||||
|
||||
[env:Xiao_C3_Repeater_sx1262]
|
||||
extends = Xiao_esp32_C3
|
||||
@@ -32,6 +35,9 @@ build_flags =
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
lib_deps =
|
||||
${Xiao_esp32_C3.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Xiao_C3_Repeater_sx1268]
|
||||
extends = Xiao_esp32_C3
|
||||
@@ -48,3 +54,6 @@ build_flags =
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
lib_deps =
|
||||
${Xiao_esp32_C3.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
75
variants/xiao_c3/target.cpp
Normal file
75
variants/xiao_c3/target.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <Arduino.h>
|
||||
#include "target.h"
|
||||
|
||||
XiaoC3Board 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);
|
||||
|
||||
#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
|
||||
}
|
||||
19
variants/xiao_c3/target.h
Normal file
19
variants/xiao_c3/target.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/XiaoC3Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/CustomSX1268Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern XiaoC3Board board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
@@ -4,6 +4,7 @@ board = seeed_xiao_esp32s3
|
||||
board_check = true
|
||||
board_build.mcu = esp32s3
|
||||
build_flags = ${esp32_base.build_flags}
|
||||
-I variants/xiao_s3_wio
|
||||
-D SEEED_XIAO_S3
|
||||
-D P_LORA_DIO_1=39
|
||||
-D P_LORA_NSS=41
|
||||
@@ -19,6 +20,8 @@ build_flags = ${esp32_base.build_flags}
|
||||
-D WRAPPER_CLASS=CustomSX1262Wrapper
|
||||
-D LORA_TX_POWER=22
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<../variants/xiao_s3_wio>
|
||||
|
||||
[env:Xiao_S3_WIO_Repeater]
|
||||
extends = Xiao_S3_WIO
|
||||
@@ -32,6 +35,26 @@ build_flags =
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
lib_deps =
|
||||
${Xiao_S3_WIO.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Xiao_S3_WIO_room_server]
|
||||
extends = Xiao_S3_WIO
|
||||
build_src_filter = ${Xiao_S3_WIO.build_src_filter}
|
||||
+<../examples/simple_room_server>
|
||||
build_flags =
|
||||
${Xiao_S3_WIO.build_flags}
|
||||
-D ADVERT_NAME='"XiaoS3 Room"'
|
||||
-D ADVERT_LAT=-37.0
|
||||
-D ADVERT_LON=145.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D ROOM_PASSWORD='"hello"'
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
lib_deps =
|
||||
${Xiao_S3_WIO.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Xiao_S3_WIO_terminal_chat]
|
||||
extends = Xiao_S3_WIO
|
||||
|
||||
75
variants/xiao_s3_wio/target.cpp
Normal file
75
variants/xiao_s3_wio/target.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#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);
|
||||
|
||||
#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
|
||||
}
|
||||
18
variants/xiao_s3_wio/target.h
Normal file
18
variants/xiao_s3_wio/target.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/RadioLibWrappers.h>
|
||||
#include <helpers/ESP32Board.h>
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
|
||||
extern ESP32Board board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
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();
|
||||
Reference in New Issue
Block a user