mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-28 21:50:35 +00:00
Compare commits
45 Commits
portexpand
...
store-and-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d657177f0e | ||
|
|
d3fc155186 | ||
|
|
3fb4ab35f1 | ||
|
|
6d8bedb027 | ||
|
|
aca9ceebfa | ||
|
|
9dee6030e4 | ||
|
|
0d19f766e8 | ||
|
|
91986db1b0 | ||
|
|
1e54d3bfc7 | ||
|
|
b2401100de | ||
|
|
7e7792aa51 | ||
|
|
d237d4f311 | ||
|
|
9f2a3fd23b | ||
|
|
61901c37bb | ||
|
|
64f8203abc | ||
|
|
f0ca0b947c | ||
|
|
db376532ad | ||
|
|
372b62aa35 | ||
|
|
95fe4aed04 | ||
|
|
b19d358dcc | ||
|
|
4ec0134606 | ||
|
|
5aa4946e6f | ||
|
|
e67b84ee06 | ||
|
|
443922b947 | ||
|
|
35fc93752e | ||
|
|
a6aa84431c | ||
|
|
9ab50d5feb | ||
|
|
45ff66e713 | ||
|
|
f7feea63f7 | ||
|
|
7c08ff35f3 | ||
|
|
96277ed804 | ||
|
|
37a03c2ef9 | ||
|
|
ef602a7d81 | ||
|
|
1f1d785ca5 | ||
|
|
37da78aec2 | ||
|
|
beb69e93d0 | ||
|
|
5d25c304ad | ||
|
|
fbe6a3c4d2 | ||
|
|
91933c66f3 | ||
|
|
a13a299b92 | ||
|
|
94155f170e | ||
|
|
840996c755 | ||
|
|
1027b45ee9 | ||
|
|
7532052edc | ||
|
|
b1125513f3 |
@@ -31,8 +31,9 @@ build_flags =
|
||||
-fmerge-all-constants
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp> -<.pio/*/*/I2CKeyPad/*>
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp>
|
||||
|
||||
board_upload.offset_address = 0x08000000
|
||||
upload_protocol = stlink
|
||||
@@ -46,5 +47,4 @@ lib_deps =
|
||||
https://github.com/caveman99/Crypto/archive/eae9c768054118a9399690f8af202853d1ae8516.zip
|
||||
|
||||
lib_ignore =
|
||||
I2CKeyPad
|
||||
OneButton
|
||||
|
||||
@@ -72,7 +72,6 @@ lib_deps =
|
||||
nanopb/Nanopb@0.4.91
|
||||
# renovate: datasource=custom.pio depName=ErriezCRC32 packageName=erriez/library/ErriezCRC32
|
||||
erriez/ErriezCRC32@1.0.1
|
||||
robtillaart/I2CKeyPad@0.5.0
|
||||
|
||||
; Used for the code analysis in PIO Home / Inspect
|
||||
check_tool = cppcheck
|
||||
|
||||
@@ -23,11 +23,16 @@ SPIClass SPI_HSPI(HSPI);
|
||||
#else
|
||||
#define SDHandler SPI
|
||||
#endif
|
||||
|
||||
#elif defined(ARCH_NRF52)
|
||||
#if defined(SDCARD_USE_SPI1)
|
||||
#define SDHandler SPI1
|
||||
#elif defined(SDCARD_USE_SPI)
|
||||
#define SDHandler SPI
|
||||
#endif // NRF52 SPI or SPI1
|
||||
#endif // ESP32/NRF52
|
||||
#ifndef SD_SPI_FREQUENCY
|
||||
#define SD_SPI_FREQUENCY 4000000U
|
||||
#endif
|
||||
|
||||
#endif // HAS_SDCARD
|
||||
|
||||
/**
|
||||
@@ -309,7 +314,13 @@ void setupSDCard()
|
||||
{
|
||||
#if defined(HAS_SDCARD) && !defined(SDCARD_USE_SOFT_SPI)
|
||||
concurrency::LockGuard g(spiLock);
|
||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52))
|
||||
#if (defined(ARCH_ESP32))
|
||||
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
||||
#elif (defined(ARCH_NRF52))
|
||||
SDHandler.begin();
|
||||
#endif
|
||||
|
||||
if (!SD.begin(SDCARD_CS, SDHandler, SD_SPI_FREQUENCY)) {
|
||||
LOG_DEBUG("No SD_MMC card detected");
|
||||
return;
|
||||
@@ -319,20 +330,23 @@ void setupSDCard()
|
||||
LOG_DEBUG("No SD_MMC card attached");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("SD_MMC Card Type: ");
|
||||
if (cardType == CARD_MMC) {
|
||||
LOG_DEBUG("MMC");
|
||||
LOG_DEBUG("SD_MMC Card Type: MMC");
|
||||
} else if (cardType == CARD_SD) {
|
||||
LOG_DEBUG("SDSC");
|
||||
LOG_DEBUG("SD_MMC Card Type: SDSC");
|
||||
} else if (cardType == CARD_SDHC) {
|
||||
LOG_DEBUG("SDHC");
|
||||
LOG_DEBUG("SD_MMC Card Type: SDHC");
|
||||
} else {
|
||||
LOG_DEBUG("UNKNOWN");
|
||||
LOG_DEBUG("SD_MMC Card Type: UNKNOWN");
|
||||
}
|
||||
|
||||
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
|
||||
LOG_DEBUG("SD Card Size: %lu MB", (uint32_t)cardSize);
|
||||
LOG_DEBUG("Total space: %lu MB", (uint32_t)(SD.totalBytes() / (1024 * 1024)));
|
||||
LOG_DEBUG("Used space: %lu MB", (uint32_t)(SD.usedBytes() / (1024 * 1024)));
|
||||
LOG_INFO("Now scanning free clusters on SD card, this may take some time...");
|
||||
delay(100); // let serial print the above statement properly
|
||||
LOG_DEBUG("Used space: %lu MB", (uint32_t)(SD.usedBytes() / (1024 * 1024))); // This might take some time during boot
|
||||
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -150,12 +150,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// Define if screen should be mirrored left to right
|
||||
// #define SCREEN_MIRROR
|
||||
|
||||
// I2C Keyboards (M5Stack, RAK14004, T-Deck, PCF8574A passive)
|
||||
// I2C Keyboards (M5Stack, RAK14004, T-Deck)
|
||||
#define CARDKB_ADDR 0x5F
|
||||
#define TDECK_KB_ADDR 0x55
|
||||
#define BBQ10_KB_ADDR 0x1F
|
||||
#define MPR121_KB_ADDR 0x5A
|
||||
#define PCF8574A_ADDRESS 0x20
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SENSOR
|
||||
|
||||
@@ -31,8 +31,8 @@ ScanI2C::FoundDevice ScanI2C::firstRTC() const
|
||||
|
||||
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
||||
{
|
||||
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004, PCF8574A, MPR121KB, TCA8418KB};
|
||||
return firstOfOrNONE(7, types);
|
||||
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004, MPR121KB, TCA8418KB};
|
||||
return firstOfOrNONE(6, types);
|
||||
}
|
||||
|
||||
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
||||
|
||||
@@ -18,7 +18,6 @@ class ScanI2C
|
||||
TDECKKB,
|
||||
BBQ10KB,
|
||||
RAK14004,
|
||||
PCF8574A,
|
||||
PMU_AXP192_AXP2101, // has the same adress as the TCA8418KB
|
||||
BME_680,
|
||||
BME_280,
|
||||
|
||||
@@ -210,9 +210,6 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10", (uint8_t)addr.address);
|
||||
|
||||
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "ST7567", (uint8_t)addr.address);
|
||||
#ifndef HAS_TCA9535
|
||||
SCAN_SIMPLE_CASE(PCF8574A_ADDRESS, PCF8574A, "PCF8574A", (uint8_t)addr.address);
|
||||
#endif
|
||||
#ifdef HAS_NCP5623
|
||||
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623", (uint8_t)addr.address);
|
||||
#endif
|
||||
|
||||
@@ -62,6 +62,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "modules/ExternalNotificationModule.h"
|
||||
#include "modules/TextMessageModule.h"
|
||||
#include "modules/WaypointModule.h"
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#endif
|
||||
#include "sleep.h"
|
||||
#include "target_specific.h"
|
||||
|
||||
@@ -76,10 +79,13 @@ extern uint16_t TFT_MESH;
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
<<<<<<< store-and-forward
|
||||
#include "esp_task_wdt.h"
|
||||
=======
|
||||
>>>>>>> master
|
||||
#endif
|
||||
|
||||
#if ARCH_PORTDUINO
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#include "platform/portduino/PortduinoGlue.h"
|
||||
#endif
|
||||
|
||||
@@ -1230,6 +1236,327 @@ void Screen::setFastFramerate()
|
||||
runASAP = true;
|
||||
}
|
||||
|
||||
<<<<<<< store-and-forward
|
||||
void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
display->setFont(FONT_SMALL);
|
||||
|
||||
// The coordinates define the left starting point of the text
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
|
||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
|
||||
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
||||
display->setColor(BLACK);
|
||||
}
|
||||
|
||||
char channelStr[20];
|
||||
{
|
||||
concurrency::LockGuard guard(&lock);
|
||||
snprintf(channelStr, sizeof(channelStr), "#%s", channels.getName(channels.getPrimaryIndex()));
|
||||
}
|
||||
|
||||
// Display power status
|
||||
if (powerStatus->getHasBattery()) {
|
||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
|
||||
drawBattery(display, x, y + 2, imgBattery, powerStatus);
|
||||
} else {
|
||||
drawBattery(display, x + 1, y + 3, imgBattery, powerStatus);
|
||||
}
|
||||
} else if (powerStatus->knowsUSB()) {
|
||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
|
||||
display->drawFastImage(x, y + 2, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
|
||||
} else {
|
||||
display->drawFastImage(x + 1, y + 3, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
|
||||
}
|
||||
}
|
||||
// Display nodes status
|
||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
|
||||
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatus);
|
||||
} else {
|
||||
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 3, nodeStatus);
|
||||
}
|
||||
#if HAS_GPS
|
||||
// Display GPS status
|
||||
if (config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
||||
drawGPSpowerstat(display, x, y + 2, gpsStatus);
|
||||
} else {
|
||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
|
||||
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 2, gpsStatus);
|
||||
} else {
|
||||
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 3, gpsStatus);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
display->setColor(WHITE);
|
||||
// Draw the channel name
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL, channelStr);
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
// Draw our hardware ID to assist with bluetooth pairing. Either prefix with Info or S&F Logo
|
||||
if (moduleConfig.store_forward.enabled) {
|
||||
if (!Throttle::isWithinTimespanMs(storeForwardModule->lastHeartbeat,
|
||||
(storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || ARCH_PORTDUINO) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||
imgQuestionL1);
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
|
||||
imgQuestionL2);
|
||||
#else
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 10 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 8, 8,
|
||||
imgQuestion);
|
||||
#endif
|
||||
} else {
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
|
||||
imgSFL1);
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 16, 8,
|
||||
imgSFL2);
|
||||
#else
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 13 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 11, 8,
|
||||
imgSF);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
// No store and forward, show a exclamation mark
|
||||
if (false) {
|
||||
#endif
|
||||
} else {
|
||||
// TODO: Raspberry Pi supports more than just the one screen size
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || ARCH_PORTDUINO) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||
imgInfoL1);
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
|
||||
imgInfoL2);
|
||||
#else
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 10 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 8, 8, imgInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(ourId), y + FONT_HEIGHT_SMALL, ourId);
|
||||
|
||||
// Draw any log messages
|
||||
display->drawLogBuffer(x, y + (FONT_HEIGHT_SMALL * 2));
|
||||
|
||||
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
|
||||
#ifdef SHOW_REDRAWS
|
||||
if (heartbeat)
|
||||
display->setPixel(0, 0);
|
||||
heartbeat = !heartbeat;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Jm
|
||||
void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
#if HAS_WIFI && !defined(ARCH_PORTDUINO)
|
||||
const char *wifiName = config.network.wifi_ssid;
|
||||
|
||||
display->setFont(FONT_SMALL);
|
||||
|
||||
// The coordinates define the left starting point of the text
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
|
||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
|
||||
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
||||
display->setColor(BLACK);
|
||||
}
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
display->drawString(x, y, String("WiFi: Not Connected"));
|
||||
if (config.display.heading_bold)
|
||||
display->drawString(x + 1, y, String("WiFi: Not Connected"));
|
||||
} else {
|
||||
display->drawString(x, y, String("WiFi: Connected"));
|
||||
if (config.display.heading_bold)
|
||||
display->drawString(x + 1, y, String("WiFi: Connected"));
|
||||
|
||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("RSSI " + String(WiFi.RSSI())), y,
|
||||
"RSSI " + String(WiFi.RSSI()));
|
||||
if (config.display.heading_bold) {
|
||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("RSSI " + String(WiFi.RSSI())) - 1, y,
|
||||
"RSSI " + String(WiFi.RSSI()));
|
||||
}
|
||||
}
|
||||
|
||||
display->setColor(WHITE);
|
||||
|
||||
/*
|
||||
- WL_CONNECTED: assigned when connected to a WiFi network;
|
||||
- WL_NO_SSID_AVAIL: assigned when no SSID are available;
|
||||
- WL_CONNECT_FAILED: assigned when the connection fails for all the attempts;
|
||||
- WL_CONNECTION_LOST: assigned when the connection is lost;
|
||||
- WL_DISCONNECTED: assigned when disconnected from a network;
|
||||
- WL_IDLE_STATUS: it is a temporary status assigned when WiFi.begin() is called and remains active until the number of
|
||||
attempts expires (resulting in WL_CONNECT_FAILED) or a connection is established (resulting in WL_CONNECTED);
|
||||
- WL_SCAN_COMPLETED: assigned when the scan networks is completed;
|
||||
- WL_NO_SHIELD: assigned when no WiFi shield is present;
|
||||
|
||||
*/
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.localIP().toString().c_str()));
|
||||
} else if (WiFi.status() == WL_NO_SSID_AVAIL) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "SSID Not Found");
|
||||
} else if (WiFi.status() == WL_CONNECTION_LOST) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Lost");
|
||||
} else if (WiFi.status() == WL_CONNECT_FAILED) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
|
||||
} else if (WiFi.status() == WL_IDLE_STATUS) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Idle ... Reconnecting");
|
||||
}
|
||||
#ifdef ARCH_ESP32
|
||||
else {
|
||||
// Codes:
|
||||
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1,
|
||||
WiFi.disconnectReasonName(static_cast<wifi_err_reason_t>(getWifiDisconnectReason())));
|
||||
}
|
||||
#else
|
||||
else {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Unkown status: " + String(WiFi.status()));
|
||||
}
|
||||
#endif
|
||||
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
|
||||
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 3, "http://meshtastic.local");
|
||||
|
||||
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
|
||||
#ifdef SHOW_REDRAWS
|
||||
if (heartbeat)
|
||||
display->setPixel(0, 0);
|
||||
heartbeat = !heartbeat;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
display->setFont(FONT_SMALL);
|
||||
|
||||
// The coordinates define the left starting point of the text
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
|
||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
|
||||
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
||||
display->setColor(BLACK);
|
||||
}
|
||||
|
||||
char batStr[20];
|
||||
if (powerStatus->getHasBattery()) {
|
||||
int batV = powerStatus->getBatteryVoltageMv() / 1000;
|
||||
int batCv = (powerStatus->getBatteryVoltageMv() % 1000) / 10;
|
||||
|
||||
snprintf(batStr, sizeof(batStr), "B %01d.%02dV %3d%% %c%c", batV, batCv, powerStatus->getBatteryChargePercent(),
|
||||
powerStatus->getIsCharging() ? '+' : ' ', powerStatus->getHasUSB() ? 'U' : ' ');
|
||||
|
||||
// Line 1
|
||||
display->drawString(x, y, batStr);
|
||||
if (config.display.heading_bold)
|
||||
display->drawString(x + 1, y, batStr);
|
||||
} else {
|
||||
// Line 1
|
||||
display->drawString(x, y, String("USB"));
|
||||
if (config.display.heading_bold)
|
||||
display->drawString(x + 1, y, String("USB"));
|
||||
}
|
||||
|
||||
// auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, true);
|
||||
|
||||
// display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
|
||||
// if (config.display.heading_bold)
|
||||
// display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode) - 1, y, mode);
|
||||
|
||||
uint32_t currentMillis = millis();
|
||||
uint32_t seconds = currentMillis / 1000;
|
||||
uint32_t minutes = seconds / 60;
|
||||
uint32_t hours = minutes / 60;
|
||||
uint32_t days = hours / 24;
|
||||
// currentMillis %= 1000;
|
||||
// seconds %= 60;
|
||||
// minutes %= 60;
|
||||
// hours %= 24;
|
||||
|
||||
// Show uptime as days, hours, minutes OR seconds
|
||||
std::string uptime = screen->drawTimeDelta(days, hours, minutes, seconds);
|
||||
|
||||
// Line 1 (Still)
|
||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(uptime.c_str()), y, uptime.c_str());
|
||||
if (config.display.heading_bold)
|
||||
display->drawString(x - 1 + SCREEN_WIDTH - display->getStringWidth(uptime.c_str()), y, uptime.c_str());
|
||||
|
||||
display->setColor(WHITE);
|
||||
|
||||
// Setup string to assemble analogClock string
|
||||
std::string analogClock = "";
|
||||
|
||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // Display local timezone
|
||||
if (rtc_sec > 0) {
|
||||
long hms = rtc_sec % SEC_PER_DAY;
|
||||
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
||||
// hms -= tz.tz_minuteswest * SEC_PER_MIN;
|
||||
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
|
||||
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
|
||||
|
||||
// Tear apart hms into h:m:s
|
||||
int hour = hms / SEC_PER_HOUR;
|
||||
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
|
||||
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
|
||||
|
||||
char timebuf[12];
|
||||
|
||||
if (config.display.use_12h_clock) {
|
||||
std::string meridiem = "am";
|
||||
if (hour >= 12) {
|
||||
if (hour > 12)
|
||||
hour -= 12;
|
||||
meridiem = "pm";
|
||||
}
|
||||
if (hour == 00) {
|
||||
hour = 12;
|
||||
}
|
||||
snprintf(timebuf, sizeof(timebuf), "%d:%02d:%02d%s", hour, min, sec, meridiem.c_str());
|
||||
} else {
|
||||
snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d", hour, min, sec);
|
||||
}
|
||||
analogClock += timebuf;
|
||||
}
|
||||
|
||||
// Line 2
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, analogClock.c_str());
|
||||
|
||||
// Display Channel Utilization
|
||||
char chUtil[13];
|
||||
snprintf(chUtil, sizeof(chUtil), "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
|
||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
|
||||
|
||||
#if HAS_GPS
|
||||
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
||||
// Line 3
|
||||
if (config.display.gps_format !=
|
||||
meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
|
||||
drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
||||
|
||||
// Line 4
|
||||
drawGPScoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus);
|
||||
} else {
|
||||
drawGPSpowerstat(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
||||
}
|
||||
#endif
|
||||
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
|
||||
#ifdef SHOW_REDRAWS
|
||||
if (heartbeat)
|
||||
display->setPixel(0, 0);
|
||||
heartbeat = !heartbeat;
|
||||
#endif
|
||||
}
|
||||
|
||||
=======
|
||||
>>>>>>> master
|
||||
int Screen::handleStatusUpdate(const meshtastic::Status *arg)
|
||||
{
|
||||
// LOG_DEBUG("Screen got status update %d", arg->getStatusType());
|
||||
|
||||
@@ -9,10 +9,6 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
|
||||
|
||||
void CardKbI2cImpl::init()
|
||||
{
|
||||
if (kb_model == 0x12) {
|
||||
disable();
|
||||
return;
|
||||
}
|
||||
#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(I2C_NO_RESCAN)
|
||||
if (cardkb_found.address == 0x00) {
|
||||
LOG_DEBUG("Rescan for I2C keyboard");
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
#include "peMatrixBase.h"
|
||||
|
||||
#include "configuration.h"
|
||||
#include "detect/ScanI2C.h"
|
||||
|
||||
extern ScanI2C::DeviceAddress cardkb_found;
|
||||
extern uint8_t kb_model;
|
||||
|
||||
#if WIRE_INTERFACES_COUNT == 2 // defined in architecture.h
|
||||
I2CKeyPad keyPad(cardkb_found.address, cardkb_found.port == ScanI2C::WIRE1 ? &Wire1 : &Wire);
|
||||
#else
|
||||
I2CKeyPad keyPad(cardkb_found.address, &Wire);
|
||||
#endif
|
||||
|
||||
PeMatrixBase::PeMatrixBase(const char *name) : concurrency::OSThread(name)
|
||||
{
|
||||
this->_originName = name;
|
||||
}
|
||||
|
||||
int32_t PeMatrixBase::runOnce()
|
||||
{
|
||||
if (kb_model != 0x12) {
|
||||
// Input device is not detected.
|
||||
return disable();
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
// This is the first time the OSThread library has called this function, so do port setup
|
||||
firstTime = 0;
|
||||
if (!keyPad.begin()) {
|
||||
LOG_ERROR("Failed to initialize I2C keypad");
|
||||
return disable();
|
||||
}
|
||||
keyPad.loadKeyMap(keymap);
|
||||
} else {
|
||||
if (keyPad.isPressed()) {
|
||||
key = keyPad.getChar();
|
||||
// debounce
|
||||
if (key != prevkey) {
|
||||
if (key != 0) {
|
||||
LOG_DEBUG("Key 0x%x pressed\n", key);
|
||||
// reset shift now that we have a keypress
|
||||
InputEvent e;
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
e.source = this->_originName;
|
||||
switch (key) {
|
||||
case 0x1b: // ESC
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
|
||||
break;
|
||||
case 0x08: // Back
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
|
||||
e.kbchar = key;
|
||||
break;
|
||||
case 0xb5: // Up
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
|
||||
break;
|
||||
case 0xb6: // Down
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
|
||||
break;
|
||||
case 0xb4: // Left
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
|
||||
e.kbchar = key;
|
||||
break;
|
||||
case 0xb7: // Right
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
|
||||
e.kbchar = key;
|
||||
break;
|
||||
case 0x0d: // Enter
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
|
||||
break;
|
||||
case 0x00: // nopress
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
break;
|
||||
default: // all other keys
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = key;
|
||||
break;
|
||||
}
|
||||
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
|
||||
this->notifyObservers(&e);
|
||||
}
|
||||
}
|
||||
prevkey = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 100; // Keyscan every 100msec to avoid key bounce
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "InputBroker.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include <I2CKeyPad.h>
|
||||
|
||||
class PeMatrixBase : public Observable<const InputEvent *>, public concurrency::OSThread
|
||||
{
|
||||
public:
|
||||
explicit PeMatrixBase(const char *name);
|
||||
|
||||
protected:
|
||||
virtual int32_t runOnce() override;
|
||||
|
||||
private:
|
||||
const char *_originName;
|
||||
bool firstTime = 1;
|
||||
// char keymap[19] = "123A456B789C*0#DNF"; // N = NoKey, F = Fail
|
||||
char keymap[19] = {0x1b, 0xb5, '3', 'A', 0xb4, 0x0d, 0xb7, 'B', '7', 0xb6, '9', 'C', 0x09, '0', 0x08, 'D', 'N', 'F'};
|
||||
char key = 0;
|
||||
char prevkey = 0;
|
||||
};
|
||||
@@ -1,16 +0,0 @@
|
||||
#include "peMatrixImpl.h"
|
||||
#include "InputBroker.h"
|
||||
|
||||
PeMatrixImpl *peMatrixImpl;
|
||||
|
||||
PeMatrixImpl::PeMatrixImpl() : PeMatrixBase("matrixPE") {}
|
||||
|
||||
void PeMatrixImpl::init()
|
||||
{
|
||||
if (kb_model != 0x12) {
|
||||
disable();
|
||||
return;
|
||||
}
|
||||
|
||||
inputBroker->registerSource(this);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
#include "main.h"
|
||||
#include "peMatrixBase.h"
|
||||
|
||||
/**
|
||||
* @brief The idea behind this class to have static methods for the event handlers.
|
||||
* Check attachInterrupt() at RotaryEncoderInteruptBase.cpp
|
||||
* Technically you can have as many rotary encoders hardver attached
|
||||
* to your device as you wish, but you always need to have separate event
|
||||
* handlers, thus you need to have a RotaryEncoderInterrupt implementation.
|
||||
*/
|
||||
class PeMatrixImpl : public PeMatrixBase
|
||||
{
|
||||
public:
|
||||
PeMatrixImpl();
|
||||
void init();
|
||||
};
|
||||
|
||||
extern PeMatrixImpl *peMatrixImpl;
|
||||
@@ -607,9 +607,6 @@ void setup()
|
||||
// assign an arbitrary value to distinguish from other models
|
||||
kb_model = 0x11;
|
||||
break;
|
||||
case ScanI2C::DeviceType::PCF8574A:
|
||||
kb_model = 0x12;
|
||||
break;
|
||||
case ScanI2C::DeviceType::MPR121KB:
|
||||
// assign an arbitrary value to distinguish from other models
|
||||
kb_model = 0x37;
|
||||
@@ -703,6 +700,8 @@ void setup()
|
||||
i2cScanner.reset();
|
||||
#endif
|
||||
|
||||
// initSPI() must have called at this point (must be before screen and lora)
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
setupSDCard();
|
||||
#endif
|
||||
@@ -795,7 +794,6 @@ void setup()
|
||||
drv.setMode(DRV2605_MODE_INTTRIG);
|
||||
#endif
|
||||
|
||||
// Init our SPI controller (must be before screen and lora)
|
||||
#ifdef ARCH_RP2040
|
||||
#ifdef HW_SPI1_DEVICE
|
||||
SPI1.setSCK(LORA_SCK);
|
||||
|
||||
@@ -57,6 +57,8 @@ uint32_t MemGet::getFreePsram()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
return ESP.getFreePsram();
|
||||
#elif (defined(HAS_SDCARD) && defined(ARCH_ESP32))
|
||||
return SD.totalBytes() - SD.usedBytes();
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
return 4194252;
|
||||
#else
|
||||
@@ -73,6 +75,8 @@ uint32_t MemGet::getPsramSize()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
return ESP.getPsramSize();
|
||||
#elif (defined(HAS_SDCARD) && defined(ARCH_ESP32))
|
||||
return SD.totalBytes();
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
return 4194252;
|
||||
#else
|
||||
|
||||
@@ -283,7 +283,6 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
||||
{
|
||||
perhapsDecode(p);
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
if (moduleConfig.store_forward.enabled && storeForwardModule->isServer() &&
|
||||
p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) {
|
||||
@@ -291,7 +290,6 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
||||
fromNum++; // Notify observers for packet from radio
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (toPhoneQueue.numFree() == 0) {
|
||||
|
||||
@@ -13,11 +13,9 @@
|
||||
#if defined(ARCH_PORTDUINO)
|
||||
#include "../platform/portduino/SimRadio.h"
|
||||
#endif
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern Allocator<meshtastic_QueueStatus> &queueStatusPool;
|
||||
extern Allocator<meshtastic_MqttClientProxyMessage> &mqttClientProxyMessagePool;
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
#include "mesh-pb-constants.h"
|
||||
#include "meshUtils.h"
|
||||
#include "modules/NeighborInfoModule.h"
|
||||
// #if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
// #include "modules/StoreForwardModule.h"
|
||||
// #endif
|
||||
#include <ErriezCRC32.h>
|
||||
#include <algorithm>
|
||||
#include <pb_decode.h>
|
||||
@@ -32,8 +35,6 @@
|
||||
#if HAS_WIFI
|
||||
#include "mesh/wifi/WiFiAPClient.h"
|
||||
#endif
|
||||
#include "SPILock.h"
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#include <Preferences.h>
|
||||
#include <esp_efuse.h>
|
||||
#include <esp_efuse_table.h>
|
||||
@@ -42,8 +43,10 @@
|
||||
#include <soc/soc.h>
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#include "SPILock.h"
|
||||
#include "modules/StoreForwardModule.h"
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#include "platform/portduino/PortduinoGlue.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ bool RF95Interface::init()
|
||||
#endif
|
||||
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
res = lora->setCRC(RADIOLIB_SX126X_LORA_CRC_ON);
|
||||
res = lora->setCRC(true);
|
||||
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
startReceive(); // start receiving
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "input/cardKbI2cImpl.h"
|
||||
#endif
|
||||
#include "input/kbMatrixImpl.h"
|
||||
#include "input/peMatrixImpl.h"
|
||||
#endif
|
||||
#if !MESHTASTIC_EXCLUDE_PKI
|
||||
#include "KeyVerificationModule.h"
|
||||
@@ -76,7 +75,6 @@
|
||||
#if !MESHTASTIC_EXCLUDE_GENERIC_THREAD_MODULE
|
||||
#include "modules/GenericThreadModule.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
#if defined(USE_SX1280) && !MESHTASTIC_EXCLUDE_AUDIO
|
||||
#include "modules/esp32/AudioModule.h"
|
||||
@@ -84,9 +82,6 @@
|
||||
#if !MESHTASTIC_EXCLUDE_PAXCOUNTER
|
||||
#include "modules/esp32/PaxcounterModule.h"
|
||||
#endif
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#endif
|
||||
#endif
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO)
|
||||
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
|
||||
@@ -182,10 +177,6 @@ void setupModules()
|
||||
kbMatrixImpl = new KbMatrixImpl();
|
||||
kbMatrixImpl->init();
|
||||
#endif // INPUTBROKER_MATRIX_TYPE
|
||||
|
||||
peMatrixImpl = new PeMatrixImpl();
|
||||
peMatrixImpl->init();
|
||||
|
||||
#ifdef INPUTBROKER_SERIAL_TYPE
|
||||
aSerialKeyboardImpl = new SerialKeyboardImpl();
|
||||
aSerialKeyboardImpl->init();
|
||||
@@ -258,7 +249,7 @@ void setupModules()
|
||||
paxcounterModule = new PaxcounterModule();
|
||||
#endif
|
||||
#endif
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) || defined(HAS_SDCARD)
|
||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||
storeForwardModule = new StoreForwardModule();
|
||||
#endif
|
||||
|
||||
@@ -32,7 +32,7 @@ StoreForwardModule *storeForwardModule;
|
||||
|
||||
int32_t StoreForwardModule::runOnce()
|
||||
{
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) || defined(HAS_SDCARD)
|
||||
if (moduleConfig.store_forward.enabled && is_server) {
|
||||
// Send out the message queue.
|
||||
if (this->busy) {
|
||||
@@ -89,6 +89,32 @@ void StoreForwardModule::populatePSRAM()
|
||||
LOG_DEBUG("After PSRAM init: heap %d/%d PSRAM %d/%d", memGet.getFreeHeap(), memGet.getHeapSize(), memGet.getFreePsram(),
|
||||
memGet.getPsramSize());
|
||||
LOG_DEBUG("numberOfPackets for packetHistory - %u", numberOfPackets);
|
||||
this->storageType = StorageType::ST_PSRAM;
|
||||
}
|
||||
|
||||
/**
|
||||
* if we have an SDCARD, format it for store&forward use
|
||||
*/
|
||||
void StoreForwardModule::populateSDCard()
|
||||
{
|
||||
#if defined(HAS_SDCARD)
|
||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52))
|
||||
spiLock->lock();
|
||||
if (SD.cardType() != CARD_NONE) {
|
||||
if (!SD.exists("/storeforward")) {
|
||||
LOG_INFO("Creating StoreForward directory");
|
||||
SD.mkdir("/storeforward");
|
||||
}
|
||||
this->storageType = StorageType::ST_SDCARD;
|
||||
uint32_t numberOfPackets = (this->records ? this->records : (((SD.totalBytes() / 3) * 2) / sizeof(PacketHistoryStruct)));
|
||||
this->records = numberOfPackets;
|
||||
// only allocate space for one temp copy
|
||||
this->packetHistory = (PacketHistoryStruct *)malloc(sizeof(PacketHistoryStruct));
|
||||
LOG_DEBUG("numberOfPackets for packetHistory - %u", numberOfPackets);
|
||||
}
|
||||
spiLock->unlock();
|
||||
#endif // ARCH_ESP32 || ARCH_NRF52
|
||||
#endif // HAS_SDCARD
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,14 +161,42 @@ uint32_t StoreForwardModule::getNumAvailablePackets(NodeNum dest, uint32_t last_
|
||||
lastRequest.emplace(dest, 0);
|
||||
}
|
||||
for (uint32_t i = lastRequest[dest]; i < this->packetHistoryTotalCount; i++) {
|
||||
if (this->packetHistory[i].time && (this->packetHistory[i].time > last_time)) {
|
||||
// Client is only interested in packets not from itself and only in broadcast packets or packets towards it.
|
||||
if (this->packetHistory[i].from != dest &&
|
||||
(this->packetHistory[i].to == NODENUM_BROADCAST || this->packetHistory[i].to == dest)) {
|
||||
count++;
|
||||
if (this->storageType == StorageType::ST_PSRAM) {
|
||||
if (this->packetHistory[i].time && (this->packetHistory[i].time > last_time)) {
|
||||
// Client is only interested in packets not from itself and only in broadcast packets or packets towards it.
|
||||
if (this->packetHistory[i].from != dest &&
|
||||
(this->packetHistory[i].to == NODENUM_BROADCAST || this->packetHistory[i].to == dest)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} else if (this->storageType == StorageType::ST_SDCARD) {
|
||||
#if defined(HAS_SDCARD)
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
|
||||
spiLock->lock();
|
||||
auto handler = SD.open("/storeforward/" + String(i), FILE_READ);
|
||||
if (handler) {
|
||||
if (handler.read((uint8_t *)&this->packetHistory[0], sizeof(PacketHistoryStruct)) !=
|
||||
sizeof(PacketHistoryStruct)) {
|
||||
LOG_ERROR("SD card reading error");
|
||||
}
|
||||
handler.close();
|
||||
if (this->packetHistory[0].time && (this->packetHistory[0].time > last_time)) {
|
||||
|
||||
// Client is only interested in packets not from itself and only in broadcast packets or packets towards it.
|
||||
if (this->packetHistory[0].from != dest &&
|
||||
(this->packetHistory[0].to == NODENUM_BROADCAST || this->packetHistory[0].to == dest)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
spiLock->unlock();
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
LOG_ERROR("S&F: Unknown storage type");
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -187,23 +241,47 @@ void StoreForwardModule::historyAdd(const meshtastic_MeshPacket &mp)
|
||||
const auto &p = mp.decoded;
|
||||
|
||||
if (this->packetHistoryTotalCount == this->records) {
|
||||
LOG_WARN("S&F - PSRAM Full. Starting overwrite");
|
||||
LOG_WARN("S&F - Storage Full. Starting overwrite");
|
||||
this->packetHistoryTotalCount = 0;
|
||||
for (auto &i : lastRequest) {
|
||||
i.second = 0; // Clear the last request index for each client device
|
||||
}
|
||||
}
|
||||
|
||||
this->packetHistory[this->packetHistoryTotalCount].time = getTime();
|
||||
this->packetHistory[this->packetHistoryTotalCount].to = mp.to;
|
||||
this->packetHistory[this->packetHistoryTotalCount].channel = mp.channel;
|
||||
this->packetHistory[this->packetHistoryTotalCount].from = getFrom(&mp);
|
||||
this->packetHistory[this->packetHistoryTotalCount].id = mp.id;
|
||||
this->packetHistory[this->packetHistoryTotalCount].reply_id = p.reply_id;
|
||||
this->packetHistory[this->packetHistoryTotalCount].emoji = (bool)p.emoji;
|
||||
this->packetHistory[this->packetHistoryTotalCount].payload_size = p.payload.size;
|
||||
memcpy(this->packetHistory[this->packetHistoryTotalCount].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||
|
||||
if (this->storageType == StorageType::ST_PSRAM) {
|
||||
this->packetHistory[this->packetHistoryTotalCount].time = getTime();
|
||||
this->packetHistory[this->packetHistoryTotalCount].to = mp.to;
|
||||
this->packetHistory[this->packetHistoryTotalCount].channel = mp.channel;
|
||||
this->packetHistory[this->packetHistoryTotalCount].from = getFrom(&mp);
|
||||
this->packetHistory[this->packetHistoryTotalCount].id = mp.id;
|
||||
this->packetHistory[this->packetHistoryTotalCount].reply_id = p.reply_id;
|
||||
this->packetHistory[this->packetHistoryTotalCount].emoji = (bool)p.emoji;
|
||||
this->packetHistory[this->packetHistoryTotalCount].payload_size = p.payload.size;
|
||||
memcpy(this->packetHistory[this->packetHistoryTotalCount].payload, p.payload.bytes,
|
||||
meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||
} else if (this->storageType == StorageType::ST_SDCARD) {
|
||||
// Save to SDCARD
|
||||
#if defined(HAS_SDCARD)
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
|
||||
this->packetHistory[0].time = getTime();
|
||||
this->packetHistory[0].to = mp.to;
|
||||
this->packetHistory[0].channel = mp.channel;
|
||||
this->packetHistory[0].from = getFrom(&mp);
|
||||
this->packetHistory[0].id = mp.id;
|
||||
this->packetHistory[0].reply_id = p.reply_id;
|
||||
this->packetHistory[0].emoji = (bool)p.emoji;
|
||||
this->packetHistory[0].payload_size = p.payload.size;
|
||||
memcpy(this->packetHistory[0].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||
spiLock->lock();
|
||||
auto handler = SD.open("/storeforward/" + String(this->packetHistoryTotalCount), FILE_WRITE, true);
|
||||
handler.write((uint8_t *)&this->packetHistory[0], sizeof(PacketHistoryStruct));
|
||||
handler.close();
|
||||
spiLock->unlock();
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
LOG_ERROR("S&F: Unknown storage type");
|
||||
}
|
||||
this->packetHistoryTotalCount++;
|
||||
}
|
||||
|
||||
@@ -236,50 +314,108 @@ bool StoreForwardModule::sendPayload(NodeNum dest, uint32_t last_time)
|
||||
meshtastic_MeshPacket *StoreForwardModule::preparePayload(NodeNum dest, uint32_t last_time, bool local)
|
||||
{
|
||||
for (uint32_t i = lastRequest[dest]; i < this->packetHistoryTotalCount; i++) {
|
||||
if (this->packetHistory[i].time && (this->packetHistory[i].time > last_time)) {
|
||||
/* Copy the messages that were received by the server in the last msAgo
|
||||
to the packetHistoryTXQueue structure.
|
||||
Client not interested in packets from itself and only in broadcast packets or packets towards it. */
|
||||
if (this->packetHistory[i].from != dest &&
|
||||
(this->packetHistory[i].to == NODENUM_BROADCAST || this->packetHistory[i].to == dest)) {
|
||||
if (this->storageType == StorageType::ST_PSRAM) {
|
||||
|
||||
meshtastic_MeshPacket *p = allocDataPacket();
|
||||
if (this->packetHistory[i].time && (this->packetHistory[i].time > last_time)) {
|
||||
/* Copy the messages that were received by the server in the last msAgo
|
||||
to the packetHistoryTXQueue structure.
|
||||
Client not interested in packets from itself and only in broadcast packets or packets towards it. */
|
||||
if (this->packetHistory[i].from != dest &&
|
||||
(this->packetHistory[i].to == NODENUM_BROADCAST || this->packetHistory[i].to == dest)) {
|
||||
|
||||
p->to = local ? this->packetHistory[i].to : dest; // PhoneAPI can handle original `to`
|
||||
p->from = this->packetHistory[i].from;
|
||||
p->id = this->packetHistory[i].id;
|
||||
p->channel = this->packetHistory[i].channel;
|
||||
p->decoded.reply_id = this->packetHistory[i].reply_id;
|
||||
p->rx_time = this->packetHistory[i].time;
|
||||
p->decoded.emoji = (uint32_t)this->packetHistory[i].emoji;
|
||||
meshtastic_MeshPacket *p = allocDataPacket();
|
||||
|
||||
// Let's assume that if the server received the S&F request that the client is in range.
|
||||
// TODO: Make this configurable.
|
||||
p->want_ack = false;
|
||||
p->to = local ? this->packetHistory[i].to : dest; // PhoneAPI can handle original `to`
|
||||
p->from = this->packetHistory[i].from;
|
||||
p->id = this->packetHistory[i].id;
|
||||
p->channel = this->packetHistory[i].channel;
|
||||
p->decoded.reply_id = this->packetHistory[i].reply_id;
|
||||
p->rx_time = this->packetHistory[i].time;
|
||||
p->decoded.emoji = (uint32_t)this->packetHistory[i].emoji;
|
||||
|
||||
// Let's assume that if the server received the S&F request that the client is in range.
|
||||
// TODO: Make this configurable.
|
||||
p->want_ack = false;
|
||||
|
||||
if (local) { // PhoneAPI gets normal TEXT_MESSAGE_APP
|
||||
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
||||
memcpy(p->decoded.payload.bytes, this->packetHistory[i].payload, this->packetHistory[i].payload_size);
|
||||
p->decoded.payload.size = this->packetHistory[i].payload_size;
|
||||
|
||||
if (local) { // PhoneAPI gets normal TEXT_MESSAGE_APP
|
||||
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
||||
memcpy(p->decoded.payload.bytes, this->packetHistory[i].payload, this->packetHistory[i].payload_size);
|
||||
p->decoded.payload.size = this->packetHistory[i].payload_size;
|
||||
} else {
|
||||
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
|
||||
sf.which_variant = meshtastic_StoreAndForward_text_tag;
|
||||
sf.variant.text.size = this->packetHistory[i].payload_size;
|
||||
memcpy(sf.variant.text.bytes, this->packetHistory[i].payload, this->packetHistory[i].payload_size);
|
||||
if (this->packetHistory[i].to == NODENUM_BROADCAST) {
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_BROADCAST;
|
||||
} else {
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_DIRECT;
|
||||
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
|
||||
sf.which_variant = meshtastic_StoreAndForward_text_tag;
|
||||
sf.variant.text.size = this->packetHistory[i].payload_size;
|
||||
memcpy(sf.variant.text.bytes, this->packetHistory[i].payload, this->packetHistory[i].payload_size);
|
||||
if (this->packetHistory[i].to == NODENUM_BROADCAST) {
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_BROADCAST;
|
||||
} else {
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_DIRECT;
|
||||
}
|
||||
|
||||
p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes),
|
||||
&meshtastic_StoreAndForward_msg, &sf);
|
||||
}
|
||||
|
||||
p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes),
|
||||
&meshtastic_StoreAndForward_msg, &sf);
|
||||
lastRequest[dest] = i + 1; // Update the last request index for the client device
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
lastRequest[dest] = i + 1; // Update the last request index for the client device
|
||||
|
||||
return p;
|
||||
}
|
||||
} else if (this->storageType == StorageType::ST_SDCARD) {
|
||||
#if defined(HAS_SDCARD)
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
|
||||
spiLock->lock();
|
||||
auto handler = SD.open("/storeforward/" + String(i), FILE_READ);
|
||||
if (handler) {
|
||||
handler.read((uint8_t *)&this->packetHistory[0], sizeof(PacketHistoryStruct));
|
||||
handler.close();
|
||||
spiLock->unlock();
|
||||
if (this->packetHistory[0].time && (this->packetHistory[0].time > last_time)) {
|
||||
if (this->packetHistory[0].from != dest &&
|
||||
(this->packetHistory[0].to == NODENUM_BROADCAST || this->packetHistory[0].to == dest)) {
|
||||
|
||||
meshtastic_MeshPacket *p = allocDataPacket();
|
||||
|
||||
p->to = local ? this->packetHistory[0].to : dest; // PhoneAPI can handle original `to`
|
||||
p->from = this->packetHistory[0].from;
|
||||
p->channel = this->packetHistory[0].channel;
|
||||
p->rx_time = this->packetHistory[0].time;
|
||||
|
||||
// Let's assume that if the server received the S&F request that the client is in range.
|
||||
p->want_ack = false;
|
||||
|
||||
if (local) { // PhoneAPI gets normal TEXT_MESSAGE_APP
|
||||
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
||||
memcpy(p->decoded.payload.bytes, this->packetHistory[0].payload, this->packetHistory[0].payload_size);
|
||||
p->decoded.payload.size = this->packetHistory[0].payload_size;
|
||||
} else {
|
||||
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
|
||||
sf.which_variant = meshtastic_StoreAndForward_text_tag;
|
||||
sf.variant.text.size = this->packetHistory[0].payload_size;
|
||||
memcpy(sf.variant.text.bytes, this->packetHistory[0].payload, this->packetHistory[0].payload_size);
|
||||
if (this->packetHistory[0].to == NODENUM_BROADCAST) {
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_BROADCAST;
|
||||
} else {
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_DIRECT;
|
||||
}
|
||||
|
||||
p->decoded.payload.size = pb_encode_to_bytes(
|
||||
p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &meshtastic_StoreAndForward_msg, &sf);
|
||||
}
|
||||
|
||||
lastRequest[dest] = i + 1; // Update the last request index for the client device
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
spiLock->unlock();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
LOG_ERROR("S&F: Unknown storage type");
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@@ -383,7 +519,7 @@ void StoreForwardModule::statsSend(uint32_t to)
|
||||
*/
|
||||
ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &mp)
|
||||
{
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) || defined(HAS_SDCARD)
|
||||
if (moduleConfig.store_forward.enabled) {
|
||||
|
||||
if ((mp.decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) && is_server) {
|
||||
@@ -562,7 +698,7 @@ StoreForwardModule::StoreForwardModule()
|
||||
ProtobufModule("StoreForward", meshtastic_PortNum_STORE_FORWARD_APP, &meshtastic_StoreAndForward_msg)
|
||||
{
|
||||
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) || defined(HAS_SDCARD)
|
||||
|
||||
isPromiscuous = true; // Brown chicken brown cow
|
||||
|
||||
@@ -613,7 +749,14 @@ StoreForwardModule::StoreForwardModule()
|
||||
} else {
|
||||
LOG_INFO("S&F: device doesn't have PSRAM, Disable");
|
||||
}
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
// If we have an SDCARD, format it for store&forward use
|
||||
if (SD.cardType() != CARD_NONE) {
|
||||
this->populateSDCard();
|
||||
LOG_INFO("S&F: SDCARD initialized");
|
||||
is_server = true;
|
||||
}
|
||||
#endif
|
||||
// Client
|
||||
} else {
|
||||
is_client = true;
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
#include "SPILock.h"
|
||||
#include <SD.h>
|
||||
#endif
|
||||
|
||||
struct PacketHistoryStruct {
|
||||
uint32_t time;
|
||||
uint32_t to;
|
||||
@@ -21,6 +26,9 @@ struct PacketHistoryStruct {
|
||||
pb_size_t payload_size;
|
||||
};
|
||||
|
||||
// enum for the storage type
|
||||
enum StorageType { ST_PSRAM, ST_SDCARD };
|
||||
|
||||
class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<meshtastic_StoreAndForward>
|
||||
{
|
||||
bool busy = 0;
|
||||
@@ -83,6 +91,10 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
|
||||
|
||||
private:
|
||||
void populatePSRAM();
|
||||
void populateSDCard();
|
||||
|
||||
// Storage Type
|
||||
StorageType storageType = ST_PSRAM;
|
||||
|
||||
// S&F Defaults
|
||||
uint32_t historyReturnMax = 25; // Return maximum of 25 records by default.
|
||||
|
||||
@@ -61,7 +61,9 @@ class XModemAdapter
|
||||
|
||||
uint16_t packetno = 0;
|
||||
|
||||
#if defined(ARCH_NRF52) || defined(ARCH_STM32WL)
|
||||
#if defined(ARCH_NRF52)
|
||||
Adafruit_LittleFS_Namespace::File file = Adafruit_LittleFS_Namespace::File(FSCom);
|
||||
#elif defined(ARCH_STM32WL)
|
||||
File file = File(FSCom);
|
||||
#else
|
||||
File file;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
// SD card - TODO: test, currently untested, copied from T3S3 variant
|
||||
#define HAS_SDCARD
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
||||
// TODO: rename this to make this SD-card specific
|
||||
#define SPI_CS 13
|
||||
#define SPI_SCK 14
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// #define HAS_SCREEN 0
|
||||
|
||||
// #define HAS_SDCARD
|
||||
// #define SDCARD_USE_SPI1
|
||||
// #define SDCARD_USE_HSPI
|
||||
|
||||
#define USE_SSD1306
|
||||
#define I2C_SDA 12
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
#endif
|
||||
|
||||
#define HAS_SDCARD // Have SPI interface SD card slot
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
||||
|
||||
#define LORA_RESET 3
|
||||
#define LORA_SCK 12
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
// #define HAS_SCREEN 0
|
||||
// #define HAS_SDCARD
|
||||
// #define SDCARD_USE_SPI1
|
||||
// #define SDCARD_USE_HSPI
|
||||
|
||||
// #define USE_SSD1306
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ lib_deps =
|
||||
rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2
|
||||
beegee-tokyo/RAK12035_SoilMoisture@^1.0.4
|
||||
https://github.com/RAKWireless/RAK12034-BMX160/archive/dcead07ffa267d3c906e9ca4a1330ab989e957e2.zip
|
||||
https://github.com/Woutvstk/SdFat_wrapper25.git#6f8f48d56c15cbeac753560dfeede4a487f81f4c
|
||||
|
||||
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds
|
||||
|
||||
@@ -113,11 +113,14 @@ static const uint8_t AREF = PIN_AREF;
|
||||
* SPI Interfaces
|
||||
*/
|
||||
#define SPI_INTERFACES_COUNT 2
|
||||
#define SPI_32MHZ_INTERFACE 0 // 0: use SPIM3 for SPI and SPIM2 for SPI1; 1: the opposite
|
||||
|
||||
// SPI pins for SX1262
|
||||
#define PIN_SPI_MISO (45)
|
||||
#define PIN_SPI_MOSI (44)
|
||||
#define PIN_SPI_SCK (43)
|
||||
|
||||
// SPI1 pins for external(rak4630) spi (incl. SDCard)
|
||||
#define PIN_SPI1_MISO (29) // (0 + 29)
|
||||
#define PIN_SPI1_MOSI (30) // (0 + 30)
|
||||
#define PIN_SPI1_SCK (3) // (0 + 3)
|
||||
@@ -127,6 +130,19 @@ static const uint8_t MOSI = PIN_SPI_MOSI;
|
||||
static const uint8_t MISO = PIN_SPI_MISO;
|
||||
static const uint8_t SCK = PIN_SPI_SCK;
|
||||
|
||||
// SD card SPI pin definitions
|
||||
|
||||
#define HAS_SDCARD 1
|
||||
#define SDCARD_USE_SPI1 1
|
||||
|
||||
#define SDCARD_CS (26)
|
||||
|
||||
// Some settings for the SdFat library to optimize flash usage
|
||||
#define SDFAT_FILE_TYPE 1 // only support FAT16/FAT32, not exFAT
|
||||
#define CHECK_FLASH_PROGRAMMING \
|
||||
0 // this reduces flash usage but may cause higher power usage when sd card is idle TODO:Check if power usage is higher
|
||||
#define MAINTAIN_FREE_CLUSTER_COUNT 1 // maintain free cluster count
|
||||
|
||||
/*
|
||||
* eink display pins
|
||||
*/
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
// #define ADC_CHANNEL ADC1_GPIO27_CHANNEL
|
||||
// #define ADC_MULTIPLIER 2
|
||||
|
||||
// Portexpander
|
||||
#define HAS_TCA9535
|
||||
|
||||
// ST7701 TFT LCD
|
||||
#define ST7701_CS (4 | IO_EXPANDER)
|
||||
#define ST7701_RS -1 // DC
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
#define GPS_1PPS_PIN 6
|
||||
|
||||
#define HAS_SDCARD // Have SPI interface SD card slot
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
||||
|
||||
// PCF8563 RTC Module
|
||||
// #define PCF8563_RTC 0x51 //Putting definitions in variant. h does not compile correctly
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#define HAS_SDCARD
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
||||
|
||||
// Display (E-Ink)
|
||||
#define PIN_EINK_CS 15
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#define HAS_SDCARD
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
||||
|
||||
#define USE_SSD1306
|
||||
|
||||
@@ -76,4 +76,4 @@
|
||||
#endif
|
||||
|
||||
#define HAS_SDCARD // Have SPI interface SD card slot
|
||||
#define SDCARD_USE_SPI1
|
||||
#define SDCARD_USE_HSPI
|
||||
@@ -3,6 +3,11 @@ extends = esp32_base
|
||||
board = ttgo-lora32-v21
|
||||
board_check = true
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D TLORA_V2_1_16 -I variants/tlora_v2_1_16
|
||||
${esp32_base.build_flags}
|
||||
-D TLORA_V2_1_16
|
||||
-I variants/tlora_v2_1_16
|
||||
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||
upload_speed = 115200
|
||||
-DRADIOLIB_EXCLUDE_SX128X=1
|
||||
-DRADIOLIB_EXCLUDE_SX126X=1
|
||||
-DRADIOLIB_EXCLUDE_LR11X0=1
|
||||
upload_speed = 115200
|
||||
|
||||
@@ -22,4 +22,15 @@
|
||||
#define LORA_DIO1 33 // https://www.thethingsnetwork.org/forum/t/big-esp32-sx127x-topic-part-3/18436
|
||||
#endif
|
||||
|
||||
#define LORA_DIO2 32 // Not really used
|
||||
#define LORA_DIO2 32 // Not really used
|
||||
|
||||
/*
|
||||
* Use SD Card for Store and Forward
|
||||
*/
|
||||
#define HAS_SDCARD
|
||||
#define SDCARD_USE_HSPI
|
||||
#define SPI_MOSI 15
|
||||
#define SPI_MISO 2
|
||||
#define SPI_SCK 14
|
||||
#define SPI_CS 13
|
||||
#define SDCARD_CS SPI_CS
|
||||
@@ -51,6 +51,9 @@
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
|
||||
// #define HAS_SDCARD 1 // causes hang if defined
|
||||
#define SDCARD_USE_HSPI
|
||||
|
||||
#define SD_SPI_FREQUENCY 25000000
|
||||
#define SDCARD_CS 43
|
||||
|
||||
|
||||
Reference in New Issue
Block a user