2021-03-15 02:00:20 +00:00
|
|
|
#include "GPS.h"
|
2020-03-19 02:15:51 +00:00
|
|
|
#include "MeshRadio.h"
|
2020-02-02 20:45:32 +00:00
|
|
|
#include "MeshService.h"
|
2020-02-08 04:59:21 +00:00
|
|
|
#include "NodeDB.h"
|
2020-03-19 02:15:51 +00:00
|
|
|
#include "PowerFSM.h"
|
2020-12-27 06:39:43 +00:00
|
|
|
#include "airtime.h"
|
2021-03-15 02:00:20 +00:00
|
|
|
#include "buzz.h"
|
2022-05-07 10:31:21 +00:00
|
|
|
#include "configuration.h"
|
2020-04-14 18:40:49 +00:00
|
|
|
#include "error.h"
|
2020-03-26 16:24:53 +00:00
|
|
|
#include "power.h"
|
2020-04-15 03:22:27 +00:00
|
|
|
// #include "rom/rtc.h"
|
2022-03-16 00:52:18 +00:00
|
|
|
//#include "DSRRouter.h"
|
|
|
|
#include "ReliableRouter.h"
|
2020-07-10 02:57:55 +00:00
|
|
|
// #include "debug.h"
|
2020-11-19 01:25:02 +00:00
|
|
|
#include "FSCommon.h"
|
2020-10-07 23:28:57 +00:00
|
|
|
#include "RTC.h"
|
2020-08-29 00:38:23 +00:00
|
|
|
#include "SPILock.h"
|
2020-10-10 00:28:00 +00:00
|
|
|
#include "concurrency/OSThread.h"
|
2020-10-09 06:16:51 +00:00
|
|
|
#include "concurrency/Periodic.h"
|
2022-08-10 09:31:29 +00:00
|
|
|
#include "detect/axpDebug.h"
|
|
|
|
#include "detect/einkScan.h"
|
|
|
|
#include "detect/i2cScan.h"
|
2020-07-07 08:46:49 +00:00
|
|
|
#include "graphics/Screen.h"
|
2020-07-08 01:33:33 +00:00
|
|
|
#include "main.h"
|
2022-02-27 08:18:35 +00:00
|
|
|
#include "modules/Modules.h"
|
2022-02-28 21:19:38 +00:00
|
|
|
#include "shutdown.h"
|
2022-05-07 10:31:21 +00:00
|
|
|
#include "sleep.h"
|
2020-09-06 16:24:08 +00:00
|
|
|
#include "target_specific.h"
|
2020-07-01 17:08:38 +00:00
|
|
|
#include <Wire.h>
|
2020-04-15 03:22:27 +00:00
|
|
|
// #include <driver/rtc_io.h>
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2021-08-18 16:25:17 +00:00
|
|
|
#include "mesh/http/WiFiAPClient.h"
|
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#ifdef ARCH_ESP32
|
2022-05-07 10:31:21 +00:00
|
|
|
#include "mesh/http/WebServer.h"
|
2022-08-22 21:41:23 +00:00
|
|
|
#include "nimble/NimbleBluetooth.h"
|
2020-04-10 19:18:48 +00:00
|
|
|
#endif
|
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#if HAS_WIFI
|
2021-02-07 01:17:46 +00:00
|
|
|
#include "mesh/wifi/WiFiServerAPI.h"
|
2021-04-03 06:54:10 +00:00
|
|
|
#include "mqtt/MQTT.h"
|
2021-02-07 01:17:46 +00:00
|
|
|
#endif
|
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
#include "LLCC68Interface.h"
|
2020-06-17 00:01:50 +00:00
|
|
|
#include "RF95Interface.h"
|
|
|
|
#include "SX1262Interface.h"
|
2021-09-03 14:15:58 +00:00
|
|
|
#include "SX1268Interface.h"
|
2020-06-17 00:01:50 +00:00
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#if HAS_BUTTON
|
2022-03-01 18:40:21 +00:00
|
|
|
#include "ButtonThread.h"
|
2022-07-31 12:11:47 +00:00
|
|
|
#endif
|
2022-03-01 18:40:21 +00:00
|
|
|
#include "PowerFSMThread.h"
|
2020-06-17 00:01:50 +00:00
|
|
|
|
2020-10-10 01:57:57 +00:00
|
|
|
using namespace concurrency;
|
|
|
|
|
2020-04-23 20:56:15 +00:00
|
|
|
// We always create a screen object, but we only init it if we find the hardware
|
2020-10-10 01:57:57 +00:00
|
|
|
graphics::Screen *screen;
|
2020-03-15 23:47:38 +00:00
|
|
|
|
2020-06-28 04:19:49 +00:00
|
|
|
// Global power status
|
2020-06-29 01:17:52 +00:00
|
|
|
meshtastic::PowerStatus *powerStatus = new meshtastic::PowerStatus();
|
2020-06-28 04:19:49 +00:00
|
|
|
|
|
|
|
// Global GPS status
|
2020-06-29 01:17:52 +00:00
|
|
|
meshtastic::GPSStatus *gpsStatus = new meshtastic::GPSStatus();
|
2020-06-28 04:19:49 +00:00
|
|
|
|
|
|
|
// Global Node status
|
2020-06-29 01:17:52 +00:00
|
|
|
meshtastic::NodeStatus *nodeStatus = new meshtastic::NodeStatus();
|
2020-02-23 18:49:37 +00:00
|
|
|
|
2020-10-23 10:00:43 +00:00
|
|
|
/// The I2C address of our display (if found)
|
|
|
|
uint8_t screen_found;
|
2022-03-24 16:36:56 +00:00
|
|
|
uint8_t screen_model;
|
2020-10-23 10:00:43 +00:00
|
|
|
|
2022-03-28 14:55:58 +00:00
|
|
|
// The I2C address of the cardkb or RAK14004 (if found)
|
|
|
|
uint8_t cardkb_found;
|
2022-05-09 18:12:49 +00:00
|
|
|
// 0x02 for RAK14004 and 0x00 for cardkb
|
|
|
|
uint8_t kb_model;
|
2022-03-28 14:55:58 +00:00
|
|
|
|
2022-04-27 09:05:08 +00:00
|
|
|
// The I2C address of the RTC Module (if found)
|
|
|
|
uint8_t rtc_found;
|
|
|
|
|
2022-04-25 05:13:41 +00:00
|
|
|
bool eink_found = true;
|
|
|
|
|
2022-04-02 14:02:26 +00:00
|
|
|
uint32_t serialSinceMsec;
|
|
|
|
|
2022-09-08 02:32:12 +00:00
|
|
|
bool pmu_found;
|
2020-02-23 18:49:37 +00:00
|
|
|
|
2022-06-05 14:50:06 +00:00
|
|
|
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
|
2022-09-10 22:28:01 +00:00
|
|
|
uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_LPS22+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
2020-02-23 18:49:37 +00:00
|
|
|
|
2020-10-10 01:57:57 +00:00
|
|
|
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
|
2020-04-17 18:52:20 +00:00
|
|
|
|
2020-02-02 20:55:26 +00:00
|
|
|
const char *getDeviceName()
|
|
|
|
{
|
2020-03-19 02:15:51 +00:00
|
|
|
uint8_t dmac[6];
|
2020-04-15 03:22:27 +00:00
|
|
|
|
|
|
|
getMacAddr(dmac);
|
2020-02-02 20:55:26 +00:00
|
|
|
|
2022-06-16 18:54:50 +00:00
|
|
|
// Meshtastic_ab3c or Shortname_abcd
|
|
|
|
static char name[20];
|
|
|
|
sprintf(name, "%02x%02x", dmac[4], dmac[5]);
|
|
|
|
// if the shortname exists and is NOT the new default of ab3c, use it for BLE name.
|
2022-06-22 12:26:33 +00:00
|
|
|
if ((owner.short_name != NULL) && (strcmp(owner.short_name, name) != 0)) {
|
2022-06-16 18:54:50 +00:00
|
|
|
sprintf(name, "%s_%02x%02x", owner.short_name, dmac[4], dmac[5]);
|
2022-04-30 21:48:31 +00:00
|
|
|
} else {
|
2022-06-16 18:54:50 +00:00
|
|
|
sprintf(name, "Meshtastic_%02x%02x", dmac[4], dmac[5]);
|
2022-04-30 21:48:31 +00:00
|
|
|
}
|
2020-03-19 02:15:51 +00:00
|
|
|
return name;
|
2020-02-02 20:55:26 +00:00
|
|
|
}
|
|
|
|
|
2020-10-10 01:57:57 +00:00
|
|
|
static int32_t ledBlinker()
|
2020-04-25 17:59:40 +00:00
|
|
|
{
|
|
|
|
static bool ledOn;
|
|
|
|
ledOn ^= 1;
|
|
|
|
|
|
|
|
setLed(ledOn);
|
|
|
|
|
|
|
|
// have a very sparse duty cycle of LED being on, unless charging, then blink 0.5Hz square wave rate to indicate that
|
2020-10-10 01:57:57 +00:00
|
|
|
return powerStatus->getIsCharging() ? 1000 : (ledOn ? 1 : 1000);
|
2020-04-25 17:59:40 +00:00
|
|
|
}
|
|
|
|
|
2021-12-06 02:37:35 +00:00
|
|
|
uint32_t timeLastPowered = 0;
|
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#if HAS_BUTTON
|
2021-03-15 02:00:20 +00:00
|
|
|
bool ButtonThread::shutdown_on_long_stop = false;
|
2022-07-31 12:11:47 +00:00
|
|
|
#endif
|
2021-03-15 02:00:20 +00:00
|
|
|
|
2020-10-12 00:25:17 +00:00
|
|
|
static Periodic *ledPeriodic;
|
|
|
|
static OSThread *powerFSMthread, *buttonThread;
|
2022-07-31 12:11:47 +00:00
|
|
|
#if HAS_BUTTON
|
2020-11-23 02:50:14 +00:00
|
|
|
uint32_t ButtonThread::longPressTime = 0;
|
2022-07-31 12:11:47 +00:00
|
|
|
#endif
|
2020-10-12 00:25:17 +00:00
|
|
|
|
2020-10-07 22:23:05 +00:00
|
|
|
RadioInterface *rIf = NULL;
|
2020-04-29 21:54:03 +00:00
|
|
|
|
2021-04-28 07:11:55 +00:00
|
|
|
/**
|
|
|
|
* Some platforms (nrf52) might provide an alterate version that supresses calling delay from sleep.
|
|
|
|
*/
|
2022-05-07 10:31:21 +00:00
|
|
|
__attribute__((weak, noinline)) bool loopCanSleep()
|
|
|
|
{
|
2021-04-28 07:11:55 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-02-02 00:14:34 +00:00
|
|
|
void setup()
|
|
|
|
{
|
2021-01-08 05:15:49 +00:00
|
|
|
concurrency::hasBeenSetup = true;
|
|
|
|
|
2020-11-12 23:48:25 +00:00
|
|
|
#ifdef SEGGER_STDOUT_CH
|
2021-03-11 02:00:08 +00:00
|
|
|
auto mode = false ? SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL : SEGGER_RTT_MODE_NO_BLOCK_TRIM;
|
2021-03-08 09:10:48 +00:00
|
|
|
#ifdef NRF52840_XXAA
|
|
|
|
auto buflen = 4096; // this board has a fair amount of ram
|
|
|
|
#else
|
|
|
|
auto buflen = 256; // this board has a fair amount of ram
|
|
|
|
#endif
|
|
|
|
SEGGER_RTT_ConfigUpBuffer(SEGGER_STDOUT_CH, NULL, NULL, buflen, mode);
|
2020-04-24 15:06:29 +00:00
|
|
|
#endif
|
2020-04-24 15:52:49 +00:00
|
|
|
|
2020-02-02 00:14:34 +00:00
|
|
|
#ifdef DEBUG_PORT
|
2022-09-11 13:36:47 +00:00
|
|
|
if (!config.has_device || config.device.serial_enabled) {
|
2021-03-30 00:08:56 +00:00
|
|
|
consoleInit(); // Set serial baud rate and init our mesh console
|
|
|
|
}
|
2020-02-02 00:14:34 +00:00
|
|
|
#endif
|
2022-05-07 10:31:21 +00:00
|
|
|
|
2022-04-02 14:02:26 +00:00
|
|
|
serialSinceMsec = millis();
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2022-01-11 23:56:58 +00:00
|
|
|
DEBUG_MSG("\n\n//\\ E S H T /\\ S T / C\n\n");
|
2022-01-10 15:57:25 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
initDeepSleep();
|
2022-04-27 13:30:27 +00:00
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
// Testing this fix für erratic T-Echo boot behaviour
|
2022-04-27 13:30:27 +00:00
|
|
|
#if defined(TTGO_T_ECHO) && defined(PIN_EINK_PWR_ON)
|
2022-04-26 09:43:32 +00:00
|
|
|
pinMode(PIN_EINK_PWR_ON, OUTPUT);
|
|
|
|
digitalWrite(PIN_EINK_PWR_ON, HIGH);
|
|
|
|
#endif
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-02-01 22:23:21 +00:00
|
|
|
#ifdef VEXT_ENABLE
|
2020-03-19 02:15:51 +00:00
|
|
|
pinMode(VEXT_ENABLE, OUTPUT);
|
|
|
|
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
|
2020-02-02 00:14:34 +00:00
|
|
|
#endif
|
2020-02-01 22:23:21 +00:00
|
|
|
|
|
|
|
#ifdef RESET_OLED
|
2020-03-19 02:15:51 +00:00
|
|
|
pinMode(RESET_OLED, OUTPUT);
|
|
|
|
digitalWrite(RESET_OLED, 1);
|
2020-02-02 00:14:34 +00:00
|
|
|
#endif
|
2020-02-01 22:23:21 +00:00
|
|
|
|
2021-08-17 23:58:21 +00:00
|
|
|
bool forceSoftAP = 0;
|
2021-08-18 02:59:56 +00:00
|
|
|
|
2021-01-18 18:43:15 +00:00
|
|
|
#ifdef BUTTON_PIN
|
2022-07-31 12:11:47 +00:00
|
|
|
#ifdef ARCH_ESP32
|
2021-02-20 08:34:25 +00:00
|
|
|
|
|
|
|
// If the button is connected to GPIO 12, don't enable the ability to use
|
|
|
|
// meshtasticAdmin on the device.
|
2020-12-12 21:54:14 +00:00
|
|
|
pinMode(BUTTON_PIN, INPUT);
|
2021-02-20 08:34:25 +00:00
|
|
|
|
2021-01-18 18:43:15 +00:00
|
|
|
#ifdef BUTTON_NEED_PULLUP
|
|
|
|
gpio_pullup_en((gpio_num_t)BUTTON_PIN);
|
2021-02-20 08:34:25 +00:00
|
|
|
delay(10);
|
2021-01-18 18:43:15 +00:00
|
|
|
#endif
|
2020-12-12 21:54:14 +00:00
|
|
|
|
|
|
|
// BUTTON_PIN is pulled high by a 12k resistor.
|
|
|
|
if (!digitalRead(BUTTON_PIN)) {
|
|
|
|
forceSoftAP = 1;
|
2021-01-18 18:43:15 +00:00
|
|
|
DEBUG_MSG("Setting forceSoftAP = 1\n");
|
2020-12-12 21:54:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2020-10-10 01:57:57 +00:00
|
|
|
OSThread::setup();
|
|
|
|
|
|
|
|
ledPeriodic = new Periodic("Blink", ledBlinker);
|
|
|
|
|
2020-11-19 01:25:02 +00:00
|
|
|
fsInit();
|
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
// router = new DSRRouter();
|
2022-03-16 00:52:18 +00:00
|
|
|
router = new ReliableRouter();
|
2020-10-10 00:28:00 +00:00
|
|
|
|
2020-02-04 15:31:32 +00:00
|
|
|
#ifdef I2C_SDA
|
2020-03-19 02:15:51 +00:00
|
|
|
Wire.begin(I2C_SDA, I2C_SCL);
|
2022-07-31 12:11:47 +00:00
|
|
|
#elif HAS_WIRE
|
2020-04-23 20:53:51 +00:00
|
|
|
Wire.begin();
|
2020-02-04 15:31:32 +00:00
|
|
|
#endif
|
2020-10-17 05:15:12 +00:00
|
|
|
|
|
|
|
#ifdef PIN_LCD_RESET
|
2020-10-23 10:00:43 +00:00
|
|
|
// FIXME - move this someplace better, LCD is at address 0x3F
|
2020-10-17 05:15:12 +00:00
|
|
|
pinMode(PIN_LCD_RESET, OUTPUT);
|
|
|
|
digitalWrite(PIN_LCD_RESET, 0);
|
2020-10-24 00:16:15 +00:00
|
|
|
delay(1);
|
2020-10-23 09:10:48 +00:00
|
|
|
digitalWrite(PIN_LCD_RESET, 1);
|
2020-10-24 00:16:15 +00:00
|
|
|
delay(1);
|
2020-06-15 21:43:16 +00:00
|
|
|
#endif
|
2020-04-23 20:53:51 +00:00
|
|
|
|
2020-10-17 05:15:12 +00:00
|
|
|
scanI2Cdevice();
|
2022-04-25 05:13:41 +00:00
|
|
|
#ifdef RAK4630
|
|
|
|
// scanEInkDevice();
|
|
|
|
#endif
|
2020-10-17 05:15:12 +00:00
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#if HAS_BUTTON
|
2020-03-19 02:15:51 +00:00
|
|
|
// Buttons & LED
|
2020-10-12 00:25:17 +00:00
|
|
|
buttonThread = new ButtonThread();
|
2022-07-31 12:11:47 +00:00
|
|
|
#endif
|
2020-10-29 01:38:27 +00:00
|
|
|
|
2020-02-01 16:30:53 +00:00
|
|
|
#ifdef LED_PIN
|
2020-03-19 02:15:51 +00:00
|
|
|
pinMode(LED_PIN, OUTPUT);
|
2020-04-15 03:22:27 +00:00
|
|
|
digitalWrite(LED_PIN, 1 ^ LED_INVERTED); // turn on for now
|
2020-02-01 16:30:53 +00:00
|
|
|
#endif
|
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// Hello
|
2022-03-20 10:53:37 +00:00
|
|
|
DEBUG_MSG("Meshtastic hwvendor=%d, swver=%s\n", HW_VENDOR, optstr(APP_VERSION));
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#ifdef ARCH_ESP32
|
2020-03-19 02:15:51 +00:00
|
|
|
// Don't init display if we don't have one or we are waking headless due to a timer event
|
|
|
|
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER)
|
2020-10-23 10:00:43 +00:00
|
|
|
screen_found = 0; // forget we even have the hardware
|
2020-04-24 15:52:49 +00:00
|
|
|
|
|
|
|
esp32Setup();
|
2020-04-17 16:48:54 +00:00
|
|
|
#endif
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#ifdef ARCH_NRF52
|
2020-09-24 23:36:07 +00:00
|
|
|
nrf52Setup();
|
|
|
|
#endif
|
2021-03-15 02:00:20 +00:00
|
|
|
playStartMelody();
|
2020-12-26 05:36:21 +00:00
|
|
|
// We do this as early as possible because this loads preferences from flash
|
|
|
|
// but we need to do this after main cpu iniot (esp32setup), because we need the random seed set
|
|
|
|
nodeDB.init();
|
|
|
|
|
2020-07-01 17:08:38 +00:00
|
|
|
// Currently only the tbeam has a PMU
|
2020-06-28 04:19:49 +00:00
|
|
|
power = new Power();
|
2020-06-29 01:17:52 +00:00
|
|
|
power->setStatusHandler(powerStatus);
|
|
|
|
powerStatus->observe(&power->newStatus);
|
2020-09-21 19:41:39 +00:00
|
|
|
power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-08-29 00:38:23 +00:00
|
|
|
// Init our SPI controller (must be before screen and lora)
|
|
|
|
initSPI();
|
2022-07-31 12:11:47 +00:00
|
|
|
#ifndef ARCH_ESP32
|
2020-08-29 00:38:23 +00:00
|
|
|
SPI.begin();
|
|
|
|
#else
|
|
|
|
// ESP32
|
|
|
|
SPI.begin(RF95_SCK, RF95_MISO, RF95_MOSI, RF95_NSS);
|
|
|
|
SPI.setFrequency(4000000);
|
|
|
|
#endif
|
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// Initialize the screen first so we can show the logo while we start up everything else.
|
2020-10-23 10:00:43 +00:00
|
|
|
screen = new graphics::Screen(screen_found);
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-05-04 18:15:05 +00:00
|
|
|
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
|
|
|
|
|
2021-03-15 02:00:20 +00:00
|
|
|
gps = createGps();
|
2020-10-13 06:43:28 +00:00
|
|
|
|
2020-09-06 21:45:43 +00:00
|
|
|
if (gps)
|
|
|
|
gpsStatus->observe(&gps->newStatus);
|
|
|
|
else
|
|
|
|
DEBUG_MSG("Warning: No GPS found - running without GPS\n");
|
2020-10-23 10:00:43 +00:00
|
|
|
|
2020-06-29 01:17:52 +00:00
|
|
|
nodeStatus->observe(&nodeDB.newStatus);
|
2020-03-18 22:00:17 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
service.init();
|
2020-06-21 21:11:38 +00:00
|
|
|
|
2022-02-27 08:29:05 +00:00
|
|
|
// Now that the mesh service is created, create any modules
|
2022-02-27 09:49:24 +00:00
|
|
|
setupModules();
|
2021-01-08 05:15:49 +00:00
|
|
|
|
2020-12-26 05:36:21 +00:00
|
|
|
// Do this after service.init (because that clears error_code)
|
2022-09-08 02:36:53 +00:00
|
|
|
#ifdef HAS_PMU
|
2022-09-08 02:32:12 +00:00
|
|
|
if (!pmu_found)
|
2022-09-09 10:51:41 +00:00
|
|
|
RECORD_CRITICALERROR(CriticalErrorCode_NO_AXP192); // Record a hardware fault for missing hardware
|
2021-01-08 05:15:49 +00:00
|
|
|
#endif
|
2020-12-26 05:36:21 +00:00
|
|
|
|
2021-01-08 05:15:49 +00:00
|
|
|
// Don't call screen setup until after nodedb is setup (because we need
|
|
|
|
// the current region name)
|
2022-07-31 12:11:47 +00:00
|
|
|
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER)
|
2020-10-21 09:27:13 +00:00
|
|
|
screen->setup();
|
|
|
|
#else
|
2020-10-23 10:00:43 +00:00
|
|
|
if (screen_found)
|
2020-10-21 09:27:13 +00:00
|
|
|
screen->setup();
|
|
|
|
#endif
|
|
|
|
|
2020-10-23 10:00:43 +00:00
|
|
|
screen->print("Started...\n");
|
2020-10-21 09:27:13 +00:00
|
|
|
|
2020-08-21 17:14:03 +00:00
|
|
|
// We have now loaded our saved preferences from flash
|
|
|
|
|
|
|
|
// ONCE we will factory reset the GPS for bug #327
|
2021-03-15 02:00:20 +00:00
|
|
|
if (gps && !devicestate.did_gps_reset) {
|
2022-05-18 16:16:23 +00:00
|
|
|
DEBUG_MSG("GPS FactoryReset requested\n");
|
2021-03-15 02:00:20 +00:00
|
|
|
if (gps->factoryReset()) { // If we don't succeed try again next time
|
2020-08-21 17:14:03 +00:00
|
|
|
devicestate.did_gps_reset = true;
|
|
|
|
nodeDB.saveToDisk();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-14 09:25:25 +00:00
|
|
|
#ifdef SX126X_ANT_SW
|
|
|
|
// make analog PA vs not PA switch on SX126x eval board work properly
|
|
|
|
pinMode(SX126X_ANT_SW, OUTPUT);
|
|
|
|
digitalWrite(SX126X_ANT_SW, 1);
|
2021-09-03 14:15:58 +00:00
|
|
|
#endif
|
|
|
|
|
2020-10-07 22:23:05 +00:00
|
|
|
// radio init MUST BE AFTER service.init, so we have our radio config settings (from nodedb init)
|
2020-08-20 22:42:36 +00:00
|
|
|
|
2020-07-10 21:37:01 +00:00
|
|
|
#if defined(RF95_IRQ)
|
2020-08-20 22:42:36 +00:00
|
|
|
if (!rIf) {
|
|
|
|
rIf = new RF95Interface(RF95_NSS, RF95_IRQ, RF95_RESET, SPI);
|
|
|
|
if (!rIf->init()) {
|
|
|
|
DEBUG_MSG("Warning: Failed to find RF95 radio\n");
|
|
|
|
delete rIf;
|
|
|
|
rIf = NULL;
|
2021-02-07 02:26:11 +00:00
|
|
|
} else {
|
2021-04-21 10:00:34 +00:00
|
|
|
DEBUG_MSG("RF95 Radio init succeeded, using RF95 radio\n");
|
2020-08-20 22:42:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-09-12 10:58:56 +00:00
|
|
|
#if defined(USE_SX1262)
|
2020-08-20 22:42:36 +00:00
|
|
|
if (!rIf) {
|
2021-09-11 21:35:16 +00:00
|
|
|
rIf = new SX1262Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
|
2020-08-20 22:42:36 +00:00
|
|
|
if (!rIf->init()) {
|
|
|
|
DEBUG_MSG("Warning: Failed to find SX1262 radio\n");
|
|
|
|
delete rIf;
|
|
|
|
rIf = NULL;
|
2021-02-07 02:26:11 +00:00
|
|
|
} else {
|
2021-04-21 10:00:34 +00:00
|
|
|
DEBUG_MSG("SX1262 Radio init succeeded, using SX1262 radio\n");
|
2020-08-20 22:42:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-09-12 10:58:56 +00:00
|
|
|
#if defined(USE_SX1268)
|
2021-09-03 14:15:58 +00:00
|
|
|
if (!rIf) {
|
2021-09-12 10:58:56 +00:00
|
|
|
rIf = new SX1268Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
|
2021-09-03 14:15:58 +00:00
|
|
|
if (!rIf->init()) {
|
|
|
|
DEBUG_MSG("Warning: Failed to find SX1268 radio\n");
|
|
|
|
delete rIf;
|
|
|
|
rIf = NULL;
|
|
|
|
} else {
|
|
|
|
DEBUG_MSG("SX1268 Radio init succeeded, using SX1268 radio\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-11-17 10:28:08 +00:00
|
|
|
#if defined(USE_LLCC68)
|
|
|
|
if (!rIf) {
|
|
|
|
rIf = new LLCC68Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
|
|
|
|
if (!rIf->init()) {
|
|
|
|
DEBUG_MSG("Warning: Failed to find LLCC68 radio\n");
|
|
|
|
delete rIf;
|
|
|
|
rIf = NULL;
|
|
|
|
} else {
|
|
|
|
DEBUG_MSG("LLCC68 Radio init succeeded, using LLCC68 radio\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#if !HAS_RADIO
|
2020-08-20 22:42:36 +00:00
|
|
|
if (!rIf) {
|
|
|
|
rIf = new SimRadio;
|
|
|
|
if (!rIf->init()) {
|
|
|
|
DEBUG_MSG("Warning: Failed to find simulated radio\n");
|
|
|
|
delete rIf;
|
|
|
|
rIf = NULL;
|
2021-02-07 02:26:11 +00:00
|
|
|
} else {
|
|
|
|
DEBUG_MSG("Using SIMULATED radio!\n");
|
2020-08-20 22:42:36 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-29 21:54:03 +00:00
|
|
|
#endif
|
2020-04-14 18:40:49 +00:00
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#if HAS_WIFI
|
2021-08-18 02:59:56 +00:00
|
|
|
mqttInit();
|
|
|
|
#endif
|
|
|
|
|
2020-09-13 04:43:41 +00:00
|
|
|
// Initialize Wifi
|
2020-12-13 02:33:52 +00:00
|
|
|
initWifi(forceSoftAP);
|
2020-09-13 04:43:41 +00:00
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#ifdef ARCH_ESP32
|
2021-01-09 04:06:11 +00:00
|
|
|
// Start web server thread.
|
2021-01-09 04:43:51 +00:00
|
|
|
webServerThread = new WebServerThread();
|
2021-01-09 06:59:37 +00:00
|
|
|
#endif
|
2021-01-09 04:06:11 +00:00
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#ifdef ARCH_PORTDUINO
|
2021-02-07 01:17:46 +00:00
|
|
|
initApiServer();
|
|
|
|
#endif
|
|
|
|
|
2021-01-09 04:43:51 +00:00
|
|
|
// Start airtime logger thread.
|
|
|
|
airTime = new AirTime();
|
2021-01-09 04:06:11 +00:00
|
|
|
|
2020-08-20 22:42:36 +00:00
|
|
|
if (!rIf)
|
2022-09-09 10:51:41 +00:00
|
|
|
RECORD_CRITICALERROR(CriticalErrorCode_NO_RADIO);
|
2022-05-07 10:31:21 +00:00
|
|
|
else {
|
2020-10-10 01:57:57 +00:00
|
|
|
router->addInterface(rIf);
|
2020-04-14 18:40:49 +00:00
|
|
|
|
2022-01-28 20:02:02 +00:00
|
|
|
// Calculate and save the bit rate to myNodeInfo
|
|
|
|
// TODO: This needs to be added what ever method changes the channel from the phone.
|
2022-05-07 10:31:21 +00:00
|
|
|
myNodeInfo.bitrate = (float(Constants_DATA_PAYLOAD_LEN) / (float(rIf->getPacketTime(Constants_DATA_PAYLOAD_LEN)))) * 1000;
|
2022-01-28 20:02:02 +00:00
|
|
|
DEBUG_MSG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
|
|
|
|
}
|
2021-12-24 02:18:07 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values
|
|
|
|
PowerFSM_setup(); // we will transition to ON in a couple of seconds, FIXME, only do this for cold boots, not waking from SDS
|
2020-10-11 00:12:53 +00:00
|
|
|
powerFSMthread = new PowerFSMThread();
|
2020-03-18 22:00:17 +00:00
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// setBluetoothEnable(false); we now don't start bluetooth until we enter the proper state
|
|
|
|
setCPUFast(false); // 80MHz is fine for our slow peripherals
|
2020-02-01 16:30:53 +00:00
|
|
|
}
|
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reboot shortly after the update completes)
|
2022-01-21 21:03:26 +00:00
|
|
|
uint32_t shutdownAtMsec; // If not zero we will shutdown at this time (used to shutdown from python or mobile client)
|
2021-03-27 02:19:59 +00:00
|
|
|
|
2021-03-28 04:16:37 +00:00
|
|
|
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag
|
|
|
|
// This will supress the current delay and instead try to run ASAP.
|
|
|
|
bool runASAP;
|
|
|
|
|
2020-02-02 00:14:34 +00:00
|
|
|
void loop()
|
|
|
|
{
|
2021-03-28 04:16:37 +00:00
|
|
|
runASAP = false;
|
|
|
|
|
2020-03-19 02:15:51 +00:00
|
|
|
// axpDebugOutput.loop();
|
2020-04-10 19:18:48 +00:00
|
|
|
|
2020-06-13 15:28:01 +00:00
|
|
|
// heap_caps_check_integrity_all(true); // FIXME - disable this expensive check
|
|
|
|
|
2022-07-31 12:11:47 +00:00
|
|
|
#ifdef ARCH_ESP32
|
2020-04-24 15:52:49 +00:00
|
|
|
esp32Loop();
|
2020-04-10 19:18:48 +00:00
|
|
|
#endif
|
2022-07-31 12:11:47 +00:00
|
|
|
#ifdef ARCH_NRF52
|
2021-03-09 07:07:16 +00:00
|
|
|
nrf52Loop();
|
|
|
|
#endif
|
2022-01-21 21:03:26 +00:00
|
|
|
powerCommandsCheck();
|
2020-02-01 16:30:53 +00:00
|
|
|
|
2020-10-07 22:23:05 +00:00
|
|
|
// For debugging
|
|
|
|
// if (rIf) ((RadioLibInterface *)rIf)->isActivelyReceiving();
|
2020-03-15 23:47:38 +00:00
|
|
|
|
2020-06-12 23:37:03 +00:00
|
|
|
#ifdef DEBUG_STACK
|
|
|
|
static uint32_t lastPrint = 0;
|
2020-09-05 19:34:48 +00:00
|
|
|
if (millis() - lastPrint > 10 * 1000L) {
|
|
|
|
lastPrint = millis();
|
2020-06-12 23:37:03 +00:00
|
|
|
meshtastic::printThreadInfo("main");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-10-10 01:57:57 +00:00
|
|
|
// TODO: This should go into a thread handled by FreeRTOS.
|
2021-01-09 06:25:44 +00:00
|
|
|
// handleWebResponse();
|
2020-09-16 16:22:03 +00:00
|
|
|
|
2020-10-10 01:57:57 +00:00
|
|
|
service.loop();
|
2020-02-08 01:48:12 +00:00
|
|
|
|
2020-10-10 01:57:57 +00:00
|
|
|
long delayMsec = mainController.runOrDelay();
|
2020-02-21 12:57:08 +00:00
|
|
|
|
2020-10-11 00:12:53 +00:00
|
|
|
/* if (mainController.nextThread && delayMsec)
|
|
|
|
DEBUG_MSG("Next %s in %ld\n", mainController.nextThread->ThreadName.c_str(),
|
2020-10-12 00:25:17 +00:00
|
|
|
mainController.nextThread->tillRun(millis())); */
|
2020-09-14 05:22:49 +00:00
|
|
|
|
2020-10-10 01:57:57 +00:00
|
|
|
// We want to sleep as long as possible here - because it saves power
|
2021-08-15 17:34:57 +00:00
|
|
|
if (!runASAP && loopCanSleep()) {
|
|
|
|
// if(delayMsec > 100) DEBUG_MSG("sleeping %ld\n", delayMsec);
|
2021-03-28 04:16:37 +00:00
|
|
|
mainDelay.delay(delayMsec);
|
2021-08-15 17:34:57 +00:00
|
|
|
}
|
2020-10-12 00:25:17 +00:00
|
|
|
// if (didWake) DEBUG_MSG("wake!\n");
|
2020-03-15 20:27:00 +00:00
|
|
|
}
|