diff --git a/src/helpers/TBeamBoard.h b/src/helpers/TBeamBoard.h deleted file mode 100644 index 8eba69333..000000000 --- a/src/helpers/TBeamBoard.h +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - - -#include -#include -#include "XPowersLib.h" - -// Defined using AXP2102 -#define XPOWERS_CHIP_AXP2101 -#define PIN_BOARD_SDA1 42 //SDA for PMU and PFC8563 (RTC) -#define PIN_BOARD_SCL1 41 //SCL for PMU and PFC8563 (RTC) -#define PIN_PMU_IRQ 40 //IRQ pin for PMU - -// LoRa radio module pins for TBeam -#define P_LORA_DIO_0 26 -#define P_LORA_DIO_2 32 -#define P_LORA_DIO_1 33 -#define P_LORA_NSS 18 -#define P_LORA_RESET 14 -#define P_LORA_BUSY RADIOLIB_NC -#define P_LORA_SCLK 5 -#define P_LORA_MISO 19 -#define P_LORA_MOSI 27 - -// built-ins -//#define PIN_VBAT_READ 37 -//#define PIN_LED_BUILTIN 25 - -#include "ESP32Board.h" - -#include - -class TBeamBoard : public ESP32Board { - XPowersLibInterface *PMU = NULL; -public: - bool power_init(); - void printPMU(); - - void begin() { - ESP32Board::begin(); - 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(); - if (wakeup_source & (1 << P_LORA_DIO_1)) { // received a LoRa packet (while in deep sleep) - startup_reason = BD_STARTUP_RX_PACKET; - } - - rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS); - rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1); - } - power_init(); - } - - void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1) { - esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - - // Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep - rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY); - rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1); - - rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS); - - if (pin_wake_btn < 0) { - esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet - } else { - esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn - } - - if (secs > 0) { - esp_sleep_enable_timer_wakeup(secs * 1000000); - } - - // Finally set ESP32 into sleep - esp_deep_sleep_start(); // CPU halts here and never returns! - } - - uint16_t getBattMilliVolts() override { - if(PMU) return PMU->getBattVoltage(); - else return 0; - } - - const char* getManufacturerName() const override { - return "LilyGo T-Beam"; - } -}; diff --git a/src/helpers/TBeamBoardSX1262.h b/src/helpers/TBeamBoardSX1262.h deleted file mode 100644 index f47df28e7..000000000 --- a/src/helpers/TBeamBoardSX1262.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - - -#include -#include -#include "XPowersLib.h" - -#define XPOWERS_CHIP_AXP192 - -// LoRa radio module pins for TBeam -#define P_LORA_DIO_1 33 // SX1262 IRQ pin -#define P_LORA_NSS 18 -#define P_LORA_RESET 23 -#define P_LORA_BUSY 32 // SX1262 Busy pin -#define P_LORA_SCLK 5 -#define P_LORA_MISO 19 -#define P_LORA_MOSI 27 - -#include "ESP32Board.h" - -#include - -class TBeamBoardSX1262 : public ESP32Board { - XPowersAXP192 power; - -public: - void begin() { - ESP32Board::begin(); - - power.setLDO2Voltage(3300); - power.enableLDO2(); - - power.enableBattVoltageMeasure(); - - 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(); - if (wakeup_source & (1 << P_LORA_DIO_1)) { // received a LoRa packet (while in deep sleep) - startup_reason = BD_STARTUP_RX_PACKET; - } - - rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS); - rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1); - } - } - - void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1) { - esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - - // Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep - rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY); - rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1); - - rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS); - - if (pin_wake_btn < 0) { - esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet - } else { - esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn - } - - if (secs > 0) { - esp_sleep_enable_timer_wakeup(secs * 1000000); - } - - // Finally set ESP32 into sleep - esp_deep_sleep_start(); // CPU halts here and never returns! - } - - uint16_t getBattMilliVolts() override { - return power.getBattVoltage(); - } - - const char* getManufacturerName() const override { - return "LilyGo T-Beam SX1262"; - } -}; diff --git a/src/helpers/TBeamS3SupremeBoard.h b/src/helpers/TBeamS3SupremeBoard.h deleted file mode 100644 index 47160787d..000000000 --- a/src/helpers/TBeamS3SupremeBoard.h +++ /dev/null @@ -1,116 +0,0 @@ -#pragma once - -#include "ESP32Board.h" -#include -#include -#include -#include "XPowersLib.h" - -// LoRa radio module pins for TBeam S3 Supreme -#define P_LORA_DIO_1 1 //SX1262 IRQ pin -#define P_LORA_NSS 10 //SX1262 SS pin -#define P_LORA_RESET 5 //SX1262 Rest pin -#define P_LORA_BUSY 4 //SX1262 Busy pin -#define P_LORA_SCLK 12 //SX1262 SCLK pin -#define P_LORA_MISO 13 //SX1262 MISO pin -#define P_LORA_MOSI 11 //SX1262 MOSI pin - -//#define PIN_BOARD_SDA 17 //SDA for OLED, BME280, and QMC6310U (0x1C) -//#define PIN_BOARD_SCL 18 //SCL for OLED, BME280, and QMC6310U (0x1C) - -#define PIN_BOARD_SDA1 42 //SDA for PMU and PFC8563 (RTC) -#define PIN_BOARD_SCL1 41 //SCL for PMU and PFC8563 (RTC) -#define PIN_PMU_IRQ 40 //IRQ pin for PMU - -//#define PIN_USER_BTN 0 - -#define P_BOARD_SPI_MOSI 35 //SPI for SD Card and QMI8653 (IMU) -#define P_BOARD_SPI_MISO 37 //SPI for SD Card and QMI8653 (IMU) -#define P_BOARD_SPI_SCK 36 //SPI for SD Card and QMI8653 (IMU) -#define P_BPARD_SPI_CS 47 //Pin for SD Card CS -#define P_BOARD_IMU_CS 34 //Pin for QMI8653 (IMU) CS - -#define P_BOARD_IMU_INT 33 //IMU Int pin -#define P_BOARD_RTC_INT 14 //RTC Int pin - -#define P_GPS_RX 9 //GPS RX pin -#define P_GPS_TX 8 //GPS TX pin -#define P_GPS_WAKE 7 //GPS Wakeup pin -//#define P_GPS_1PPS 6 //GPS 1PPS pin - repurposed for lora tx led -#define GPS_BAUD_RATE 9600 - -//I2C Wire addresses -#define I2C_BME280_ADD 0x76 //BME280 sensor I2C address on Wire -#define I2C_OLED_ADD 0x3C //SH1106 OLED I2C address on Wire -#define I2C_QMC6310U_ADD 0x1C //QMC6310U mag sensor I2C address on Wire - -//I2C Wire1 addresses -#define I2C_RTC_ADD 0x51 //RTC I2C address on Wire1 -#define I2C_PMU_ADD 0x34 //AXP2101 I2C address on Wire1 - -#define PMU_WIRE_PORT Wire1 -#define XPOWERS_CHIP_AXP2101 - -class TBeamS3SupremeBoard : public ESP32Board { - XPowersAXP2101 PMU; -public: -#ifdef MESH_DEBUG - void printPMU(); -#endif - bool power_init(); - - void begin() { - - ESP32Board::begin(); - - power_init(); - - esp_reset_reason_t reason = esp_reset_reason(); - if (reason == ESP_RST_DEEPSLEEP) { - long wakeup_source = esp_sleep_get_ext1_wakeup_status(); - if (wakeup_source & (1 << P_LORA_DIO_1)) { // received a LoRa packet (while in deep sleep) - startup_reason = BD_STARTUP_RX_PACKET; - } - - rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS); - rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1); - } - power_init(); - } - - void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1) { - esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - - // Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep - rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY); - rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1); - - rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS); - - if (pin_wake_btn < 0) { - esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet - } else { - esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn - } - - if (secs > 0) { - esp_sleep_enable_timer_wakeup(secs * 1000000); - } - - // Finally set ESP32 into sleep - esp_deep_sleep_start(); // CPU halts here and never returns! - } - - uint16_t getBattMilliVolts() override { - return PMU.getBattVoltage(); - } - - uint16_t getBattPercent() { - //Read the PMU fuel guage for battery % - uint16_t battPercent = PMU.getBatteryPercent(); - return battPercent; - } - const char* getManufacturerName() const override { - return "LilyGo T-Beam S3 Supreme SX1262"; - } -}; diff --git a/src/helpers/esp32/TBeamBoard.cpp b/src/helpers/esp32/TBeamBoard.cpp new file mode 100644 index 000000000..2e3ea0405 --- /dev/null +++ b/src/helpers/esp32/TBeamBoard.cpp @@ -0,0 +1,346 @@ +#include +#include "TBeamBoard.h" +//#include + +uint32_t deviceOnline = 0x00; + +bool pmuInterrupt; +static void setPmuFlag() +{ + pmuInterrupt = true; +} + +void TBeamBoard::begin() { + + ESP32Board::begin(); + + power_init(); + + //Configure user button + pinMode(PIN_USER_BTN, INPUT); + + #ifndef TBEAM_SUPREME_SX1262 + digitalWrite(P_LORA_TX_LED, HIGH); //inverted pin for SX1276 - HIGH for off + #endif + + //radiotype_detect(); + + esp_reset_reason_t reason = esp_reset_reason(); + if (reason == ESP_RST_DEEPSLEEP) { + long wakeup_source = esp_sleep_get_ext1_wakeup_status(); + if (wakeup_source & (1 << P_LORA_DIO_1)) { // received a LoRa packet (while in deep sleep) + startup_reason = BD_STARTUP_RX_PACKET; + } + + rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS); + rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1); + } +} + +#ifdef MESH_DEBUG +void TBeamBoard::scanDevices(TwoWire *w) +{ + uint8_t err, addr; + int nDevices = 0; + uint32_t start = 0; + + Serial.println("Scanning I2C for Devices"); + for (addr = 1; addr < 127; addr++) { + start = millis(); + w->beginTransmission(addr); delay(2); + err = w->endTransmission(); + if (err == 0) { + nDevices++; + switch (addr) { + case 0x77: + case 0x76: + Serial.println("\tFound BME280 Sensor"); + deviceOnline |= BME280_ONLINE; + break; + case 0x34: + Serial.println("\tFound AXP192/AXP2101 PMU"); + deviceOnline |= POWERMANAGE_ONLINE; + break; + case 0x3C: + Serial.println("\tFound SSD1306/SH1106 display"); + deviceOnline |= DISPLAY_ONLINE; + break; + case 0x51: + Serial.println("\tFound PCF8563 RTC"); + deviceOnline |= PCF8563_ONLINE; + break; + case 0x1C: + Serial.println("\tFound QMC6310 MAG Sensor"); + deviceOnline |= QMC6310_ONLINE; + break; + default: + Serial.print("\tI2C device found at address 0x"); + if (addr < 16) { + Serial.print("0"); + } + Serial.print(addr, HEX); + Serial.println(" !"); + break; + } + + } else if (err == 4) { + Serial.print("Unknow error at address 0x"); + if (addr < 16) { + Serial.print("0"); + } + Serial.println(addr, HEX); + } + } + if (nDevices == 0) + Serial.println("No I2C devices found\n"); + + Serial.println("Scan for devices is complete."); + Serial.println("\n"); + + Serial.printf("GPS RX pin: %d", PIN_GPS_RX); + Serial.printf(" GPS TX pin: %d", PIN_GPS_TX); + Serial.println(); +} +void TBeamBoard::printPMU() +{ + Serial.print("isCharging:"); Serial.println(PMU->isCharging() ? "YES" : "NO"); + Serial.print("isDischarge:"); Serial.println(PMU->isDischarge() ? "YES" : "NO"); + Serial.print("isVbusIn:"); Serial.println(PMU->isVbusIn() ? "YES" : "NO"); + Serial.print("getBattVoltage:"); Serial.print(PMU->getBattVoltage()); Serial.println("mV"); + Serial.print("getVbusVoltage:"); Serial.print(PMU->getVbusVoltage()); Serial.println("mV"); + Serial.print("getSystemVoltage:"); Serial.print(PMU->getSystemVoltage()); Serial.println("mV"); + + // The battery percentage may be inaccurate at first use, the PMU will automatically + // learn the battery curve and will automatically calibrate the battery percentage + // after a charge and discharge cycle + if (PMU->isBatteryConnect()) { + Serial.print("getBatteryPercent:"); Serial.print(PMU->getBatteryPercent()); Serial.println("%"); + } + + Serial.println(); +} +#endif + +bool TBeamBoard::power_init() +{ + if (!PMU) { + #ifdef TBEAM_SUPREME_SX1262 + PMU = new XPowersAXP2101(PMU_WIRE_PORT, PIN_BOARD_SDA1, PIN_BOARD_SCL1, I2C_PMU_ADD); + #else + PMU = new XPowersAXP2101(PMU_WIRE_PORT, PIN_BOARD_SDA, PIN_BOARD_SCL, I2C_PMU_ADD); + #endif + if (!PMU->init()) { + MESH_DEBUG_PRINTLN("Warning: Failed to find AXP2101 power management"); + delete PMU; + PMU = NULL; + } else { + MESH_DEBUG_PRINTLN("AXP2101 PMU init succeeded, using AXP2101 PMU"); + } + } + if (!PMU) { + PMU = new XPowersAXP192(PMU_WIRE_PORT, PIN_BOARD_SDA, PIN_BOARD_SCL, I2C_PMU_ADD); + if (!PMU->init()) { + MESH_DEBUG_PRINTLN("Warning: Failed to find AXP192 power management"); + delete PMU; + PMU = NULL; + } else { + MESH_DEBUG_PRINTLN("AXP192 PMU init succeeded, using AXP192 PMU"); + } + } + + if (!PMU) { + return false; + } + + deviceOnline |= POWERMANAGE_ONLINE; + + PMU->setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG); + + // Set up PMU interrupts + pinMode(PIN_PMU_IRQ, INPUT_PULLUP); + attachInterrupt(PIN_PMU_IRQ, setPmuFlag, FALLING); + + if (PMU->getChipModel() == XPOWERS_AXP192) { + + PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300); //Set up LoRa power rail + PMU->enablePowerOutput(XPOWERS_LDO2); //Enable the LoRa power rail + + PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300); //Set up OLED power rail + PMU->enablePowerOutput(XPOWERS_DCDC1); //Enable the OLED power rail + + PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300); //Set up GPS power rail + PMU->enablePowerOutput(XPOWERS_LDO3); //Enable the GPS power rail + + PMU->setProtectedChannel(XPOWERS_DCDC1); //Protect the OLED power rail + PMU->setProtectedChannel(XPOWERS_DCDC3); //Protect the ESP32 power rail + + PMU->disablePowerOutput(XPOWERS_DCDC2); //Disable unsused power rail DC2 + + PMU->disableIRQ(XPOWERS_AXP192_ALL_IRQ); //Disable PMU IRQ + + PMU->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_450MA); //Set battery charging current + PMU->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2); //Set battery charge-stop voltage + } + else if(PMU->getChipModel() == XPOWERS_AXP2101){ + #ifdef TBEAM_SUPREME_SX1262 + //Set up the GPS power rail + PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO4); + + //Set up the LoRa power rail + PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO3); + + //Set up power rail for the M.2 interface + PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300); + PMU->enablePowerOutput(XPOWERS_DCDC3); + + if (ESP_SLEEP_WAKEUP_UNDEFINED == esp_sleep_get_wakeup_cause()) { + MESH_DEBUG_PRINTLN("Power off and restart ALDO BLDO.."); + PMU->disablePowerOutput(XPOWERS_ALDO1); + PMU->disablePowerOutput(XPOWERS_ALDO2); + PMU->disablePowerOutput(XPOWERS_BLDO1); + delay(250); + } + + //Set up power rail for QMC6310U + PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO2); + + //Set up power rail for BME280 and OLED + PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO1); + + //Set up pwer rail for SD Card + PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300); + PMU->enablePowerOutput(XPOWERS_BLDO1); + + //Set up power rail BLDO2 to headers + PMU->setPowerChannelVoltage(XPOWERS_BLDO2, 3300); + PMU->enablePowerOutput(XPOWERS_BLDO2); + + //Set up power rail DCDC4 to headers + PMU->setPowerChannelVoltage(XPOWERS_DCDC4, XPOWERS_AXP2101_DCDC4_VOL2_MAX); + PMU->enablePowerOutput(XPOWERS_DCDC4); + + //Set up power rail DCDC5 to headers + PMU->setPowerChannelVoltage(XPOWERS_DCDC5, 3300); + PMU->enablePowerOutput(XPOWERS_DCDC5); + + //Disable unused power rails + PMU->disablePowerOutput(XPOWERS_DCDC2); + PMU->disablePowerOutput(XPOWERS_DLDO1); + PMU->disablePowerOutput(XPOWERS_DLDO2); + PMU->disablePowerOutput(XPOWERS_VBACKUP); + #else + //Turn off unused power rails + PMU->disablePowerOutput(XPOWERS_DCDC2); + PMU->disablePowerOutput(XPOWERS_DCDC3); + PMU->disablePowerOutput(XPOWERS_DCDC4); + PMU->disablePowerOutput(XPOWERS_DCDC5); + PMU->disablePowerOutput(XPOWERS_ALDO1); + PMU->disablePowerOutput(XPOWERS_ALDO4); + PMU->disablePowerOutput(XPOWERS_BLDO1); + PMU->disablePowerOutput(XPOWERS_BLDO2); + PMU->disablePowerOutput(XPOWERS_DLDO1); + PMU->disablePowerOutput(XPOWERS_DLDO2); + //PMU->disablePowerOutput(XPOWERS_CPULDO); + + PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300); //Set up GPS RTC power + PMU->enablePowerOutput(XPOWERS_VBACKUP); //Turn on GPS RTC power + + PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); //Set up LoRa power rail + PMU->enablePowerOutput(XPOWERS_ALDO2); //Enable LoRa power rail + + PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); //Set up GPS power rail + PMU->enablePowerOutput(XPOWERS_ALDO3); //Enable GPS power rail + + #endif + + PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ); //Disable all PMU interrupts + + PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA); //Set battery charging current to 500mA + PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2); //Set battery charging cutoff voltage to 4.2V + + } + + PMU->clearIrqStatus(); //Clear interrupt flags + + PMU->disableTSPinMeasure(); //Disable TS detection, since it is not used + + //Enable voltage measurements + PMU->enableSystemVoltageMeasure(); + PMU->enableVbusVoltageMeasure(); + PMU->enableBattVoltageMeasure(); + +#ifdef MESH_DEBUG + scanDevices(&Wire); + printPMU(); +#endif + + // Set the power key off press time + PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S); + return true; +} + +#pragma region "Debug code" +// void TBeamBoard::radiotype_detect(){ + +// static SPIClass spi; +// char chipTypeInfo; + +// #if defined(P_LORA_SCLK) +// spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI); +// #endif + +// for(int i = 0; i +#include +#include "XPowersLib.h" +#include "helpers/ESP32Board.h" +#include +//#include +//#include +//#include +//#include + +#ifdef TBEAM_SUPREME_SX1262 + // LoRa radio module pins for TBeam S3 Supreme SX1262 + #define P_LORA_DIO_0 -1 //NC + #define P_LORA_DIO_1 1 //SX1262 IRQ pin + #define P_LORA_NSS 10 //SX1262 SS pin + #define P_LORA_RESET 5 //SX1262 Rest pin + #define P_LORA_BUSY 4 //SX1262 Busy pin + #define P_LORA_SCLK 12 //SX1262 SCLK pin + #define P_LORA_MISO 13 //SX1262 MISO pin + #define P_LORA_MOSI 11 //SX1262 MOSI pin + + #define PIN_BOARD_SDA1 42 //SDA for PMU and PFC8563 (RTC) + #define PIN_BOARD_SCL1 41 //SCL for PMU and PFC8563 (RTC) + + #define PIN_PMU_IRQ 40 //IRQ pin for PMU + + // #define PIN_GPS_RX 9 + // #define PIN_GPS_TX 8 + // #define PIN_GPS_EN 7 + + #define P_BOARD_SPI_MOSI 35 //SPI for SD Card and QMI8653 (IMU) + #define P_BOARD_SPI_MISO 37 //SPI for SD Card and QMI8653 (IMU) + #define P_BOARD_SPI_SCK 36 //SPI for SD Card and QMI8653 (IMU) + #define P_BPARD_SPI_CS 47 //Pin for SD Card CS + #define P_BOARD_IMU_CS 34 //Pin for QMI8653 (IMU) CS + + #define P_BOARD_IMU_INT 33 //IMU Int pin + #define P_BOARD_RTC_INT 14 //RTC Int pin + + //I2C Wire addresses + #define I2C_BME280_ADD 0x76 //BME280 sensor I2C address on Wire + #define I2C_OLED_ADD 0x3C //SH1106 OLED I2C address on Wire + #define I2C_QMC6310U_ADD 0x1C //QMC6310U mag sensor I2C address on Wire + + //I2C Wire1 addresses + #define I2C_RTC_ADD 0x51 //RTC I2C address on Wire1 + #define I2C_PMU_ADD 0x34 //AXP2101 I2C address on Wire1 + + #define PMU_WIRE_PORT Wire1 + #define RTC_WIRE_PORT Wire1 +#endif + +#ifdef TBEAM_SX1262 + #define P_LORA_BUSY 32 +#endif + +#ifdef TBEAM_SX1276 + #define P_LORA_DIO_2 32 + #define P_LORA_BUSY RADIOLIB_NC +#endif + +#if defined(TBEAM_SX1262) || defined(TBEAM_SX1276) + // LoRa radio module pins for TBeam + // uint32_t P_LORA_BUSY = 0; //shared, so define at run + // uint32_t P_LORA_DIO_2 = 0; //SX1276 only, so define at run + + #define P_LORA_DIO_0 26 + #define P_LORA_DIO_1 33 + #define P_LORA_NSS 18 + #define P_LORA_RESET 23 + #define P_LORA_SCLK 5 + #define P_LORA_MISO 19 + #define P_LORA_MOSI 27 + + // #define PIN_GPS_RX 34 + // #define PIN_GPS_TX 12 + + #define PIN_PMU_IRQ 35 + #define PMU_WIRE_PORT Wire + #define RTC_WIRE_PORT Wire + #define I2C_PMU_ADD 0x34 +#endif + +// enum RadioType { +// SX1262, +// SX1276 +// }; + +class TBeamBoard : public ESP32Board { +XPowersLibInterface *PMU = NULL; +//PhysicalLayer * pl; +//RadioType * radio = NULL; +// int radioVersions = 2; + +enum { + POWERMANAGE_ONLINE = _BV(0), + DISPLAY_ONLINE = _BV(1), + RADIO_ONLINE = _BV(2), + GPS_ONLINE = _BV(3), + PSRAM_ONLINE = _BV(4), + SDCARD_ONLINE = _BV(5), + AXDL345_ONLINE = _BV(6), + BME280_ONLINE = _BV(7), + BMP280_ONLINE = _BV(8), + BME680_ONLINE = _BV(9), + QMC6310_ONLINE = _BV(10), + QMI8658_ONLINE = _BV(11), + PCF8563_ONLINE = _BV(12), + OSC32768_ONLINE = _BV(13), +}; + +bool power_init(); +//void radiotype_detect(); + +public: + +#ifdef MESH_DEBUG + void printPMU(); + void scanDevices(TwoWire *w); +#endif + void begin(); + + #ifndef TBEAM_SUPREME_SX1262 + void onBeforeTransmit() override{ + digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED on - invert pin for SX1276 + } + void onAfterTransmit() override{ + digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED off - invert pin for SX1276 + } + #endif + + void enterDeepSleep(uint32_t secs, int pin_wake_btn) { + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + + // Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep + rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY); + rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1); + + rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS); + + if (pin_wake_btn < 0) { + esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet + } else { + esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn + } + + if (secs > 0) { + esp_sleep_enable_timer_wakeup(secs * 1000000); + } + + // Finally set ESP32 into sleep + esp_deep_sleep_start(); // CPU halts here and never returns! +} + + uint16_t getBattMilliVolts(){ + return PMU->getBattVoltage(); + } + + const char* getManufacturerName() const{ + return "LilyGo T-Beam"; + } +}; diff --git a/src/helpers/sensors/EnvironmentSensorManager.cpp b/src/helpers/sensors/EnvironmentSensorManager.cpp index ed20b8a4e..edd60ebfc 100644 --- a/src/helpers/sensors/EnvironmentSensorManager.cpp +++ b/src/helpers/sensors/EnvironmentSensorManager.cpp @@ -7,7 +7,9 @@ static Adafruit_AHTX0 AHTX0; #endif #if ENV_INCLUDE_BME280 +#ifndef TELEM_BME280_ADDRESS #define TELEM_BME280_ADDRESS 0x76 // BME280 environmental sensor I2C address +#endif #define TELEM_BME280_SEALEVELPRESSURE_HPA (1013.25) // Athmospheric pressure at sea level #include static Adafruit_BME280 BME280; @@ -84,7 +86,7 @@ bool EnvironmentSensorManager::begin() { bool EnvironmentSensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) { next_available_channel = TELEM_CHANNEL_SELF + 1; - if (requester_permissions & TELEM_PERM_LOCATION) { + if (requester_permissions & TELEM_PERM_LOCATION && gps_active) { telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, 0.0f); // allow lat/lon via telemetry even if no GPS is detected } @@ -180,13 +182,25 @@ bool EnvironmentSensorManager::setSettingValue(const char* name, const char* val #if ENV_INCLUDE_GPS void EnvironmentSensorManager::initBasicGPS() { - Serial1.setPins(PIN_GPS_TX, PIN_GPS_RX); + + Serial1.setPins(PIN_GPS_RX, PIN_GPS_TX); + + #ifdef GPS_BAUD_RATE + Serial1.begin(GPS_BAUD_RATE); + #else Serial1.begin(9600); + #endif // Try to detect if GPS is physically connected to determine if we should expose the setting - pinMode(PIN_GPS_EN, OUTPUT); - digitalWrite(PIN_GPS_EN, HIGH); // Power on GPS + #ifdef PIN_GPS_EN + pinMode(PIN_GPS_EN, OUTPUT); + digitalWrite(PIN_GPS_EN, HIGH); // Power on GPS + #endif + #ifndef PIN_GPS_EN + MESH_DEBUG_PRINTLN("No GPS wake/reset pin found for this board. Continuing on..."); + #endif + // Give GPS a moment to power up and send data delay(1000); @@ -195,23 +209,39 @@ void EnvironmentSensorManager::initBasicGPS() { if (gps_detected) { MESH_DEBUG_PRINTLN("GPS detected"); - digitalWrite(PIN_GPS_EN, LOW); // Power off GPS until the setting is changed + #ifdef PERSISTANT_GPS + gps_active = true; + return; + #endif } else { MESH_DEBUG_PRINTLN("No GPS detected"); - digitalWrite(PIN_GPS_EN, LOW); } + #ifdef PIN_GPS_EN + digitalWrite(PIN_GPS_EN, LOW); // Power off GPS until the setting is changed + #endif + gps_active = false; //Set GPS visibility off until setting is changed } void EnvironmentSensorManager::start_gps() { gps_active = true; - pinMode(PIN_GPS_EN, OUTPUT); - digitalWrite(PIN_GPS_EN, HIGH); + #ifdef PIN_GPS_EN + pinMode(PIN_GPS_EN, OUTPUT); + digitalWrite(PIN_GPS_EN, HIGH); + return; + #endif + + MESH_DEBUG_PRINTLN("Start GPS is N/A on this board. Actual GPS state unchanged"); } void EnvironmentSensorManager::stop_gps() { gps_active = false; - pinMode(PIN_GPS_EN, OUTPUT); - digitalWrite(PIN_GPS_EN, LOW); + #ifdef PIN_GPS_EN + pinMode(PIN_GPS_EN, OUTPUT); + digitalWrite(PIN_GPS_EN, LOW); + return; + #endif + + MESH_DEBUG_PRINTLN("Stop GPS is N/A on this board. Actual GPS state unchanged"); } void EnvironmentSensorManager::loop() { diff --git a/variants/lilygo_tbeam_SX1262/platformio.ini b/variants/lilygo_tbeam_SX1262/platformio.ini index 153fc6fac..b40fb7e14 100644 --- a/variants/lilygo_tbeam_SX1262/platformio.ini +++ b/variants/lilygo_tbeam_SX1262/platformio.ini @@ -4,32 +4,39 @@ board = ttgo-t-beam build_flags = ${esp32_base.build_flags} -I variants/lilygo_tbeam_SX1262 - -D LILYGO_TBEAM_SX1262 + -D TBEAM_SX1262 -D SX126X_DIO2_AS_RF_SWITCH=true -D SX126X_DIO3_TCXO_VOLTAGE=1.8 -D SX126X_CURRENT_LIMIT=140 -D SX126X_RX_BOOSTED_GAIN=1 -D RADIO_CLASS=CustomSX1262 -D WRAPPER_CLASS=CustomSX1262Wrapper + -D DISPLAY_CLASS=SSD1306Display -D LORA_TX_POWER=22 -D P_LORA_TX_LED=4 -D PIN_BOARD_SDA=21 -D PIN_BOARD_SCL=22 + -D PIN_GPS_RX=34 + -D PIN_GPS_TX=12 -D PIN_USER_BTN=38 + -D ENV_INCLUDE_GPS=1 build_src_filter = ${esp32_base.build_src_filter} +<../variants/lilygo_tbeam_SX1262> + + + + + + board_build.partitions = min_spiffs.csv ; get around 4mb flash limit lib_deps = ${esp32_base.lib_deps} lewisxhe/XPowersLib@^0.2.7 adafruit/Adafruit SSD1306 @ ^2.5.13 + stevemarple/MicroNMEA @ ^2.0.6 [env:Tbeam_SX1262_companion_radio_ble] extends = LilyGo_TBeam_SX1262 board_build.upload.maximum_ram_size=2000000 build_flags = ${LilyGo_TBeam_SX1262.build_flags} - -D DISPLAY_CLASS=SSD1306Display -D MAX_CONTACTS=100 -D MAX_GROUP_CHANNELS=8 -D BLE_PIN_CODE=123456 @@ -42,7 +49,6 @@ build_flags = ; -D MESH_DEBUG=1 build_src_filter = ${LilyGo_TBeam_SX1262.build_src_filter} + - + +<../examples/companion_radio> lib_deps = ${LilyGo_TBeam_SX1262.lib_deps} @@ -52,7 +58,6 @@ lib_deps = extends = LilyGo_TBeam_SX1262 build_flags = ${LilyGo_TBeam_SX1262.build_flags} - -D DISPLAY_CLASS=SSD1306Display -D ADVERT_NAME='"Tbeam SX1262 Repeater"' -D ADVERT_LAT=0.0 -D ADVERT_LON=0.0 @@ -61,7 +66,6 @@ build_flags = ; -D MESH_PACKET_LOGGING=1 ; -D MESH_DEBUG=1 build_src_filter = ${LilyGo_TBeam_SX1262.build_src_filter} - + +<../examples/simple_repeater> lib_deps = ${LilyGo_TBeam_SX1262.lib_deps} diff --git a/variants/lilygo_tbeam_SX1262/target.cpp b/variants/lilygo_tbeam_SX1262/target.cpp index 26ba27b59..fb05958b6 100644 --- a/variants/lilygo_tbeam_SX1262/target.cpp +++ b/variants/lilygo_tbeam_SX1262/target.cpp @@ -1,7 +1,7 @@ #include #include "target.h" -TBeamBoardSX1262 board; +TBeamBoard board; #if defined(P_LORA_SCLK) static SPIClass spi; @@ -14,7 +14,14 @@ WRAPPER_CLASS radio_driver(radio, board); ESP32RTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); -SensorManager sensors; + +#if ENV_INCLUDE_GPS + #include + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); +#else + EnvironmentSensorManager sensors; +#endif #ifdef DISPLAY_CLASS DISPLAY_CLASS display; diff --git a/variants/lilygo_tbeam_SX1262/target.h b/variants/lilygo_tbeam_SX1262/target.h index 3f4d77fa3..da4c5d5c4 100644 --- a/variants/lilygo_tbeam_SX1262/target.h +++ b/variants/lilygo_tbeam_SX1262/target.h @@ -3,18 +3,18 @@ #define RADIOLIB_STATIC_ONLY 1 #include #include -#include +#include #include #include -#include +#include #ifdef DISPLAY_CLASS #include #endif -extern TBeamBoardSX1262 board; +extern TBeamBoard board; extern WRAPPER_CLASS radio_driver; extern AutoDiscoverRTCClock rtc_clock; -extern SensorManager sensors; +extern EnvironmentSensorManager sensors; #ifdef DISPLAY_CLASS extern DISPLAY_CLASS display; diff --git a/variants/lilygo_tbeam_SX1276/platformio.ini b/variants/lilygo_tbeam_SX1276/platformio.ini new file mode 100644 index 000000000..9f9a9fffd --- /dev/null +++ b/variants/lilygo_tbeam_SX1276/platformio.ini @@ -0,0 +1,70 @@ +[LilyGo_TBeam_SX1276] +extends = esp32_base +board = ttgo-t-beam +build_flags = + ${esp32_base.build_flags} + -I variants/lilygo_tbeam_SX1276 + -D TBEAM_SX1276 + -D SX127X_CURRENT_LIMIT=120 + -D RADIO_CLASS=CustomSX1276 + -D WRAPPER_CLASS=CustomSX1276Wrapper + -D DISPLAY_CLASS=SSD1306Display + -D LORA_TX_POWER=20 + -D P_LORA_TX_LED=4 + -D PIN_BOARD_SDA=21 + -D PIN_BOARD_SCL=22 + -D PIN_GPS_RX=34 + -D PIN_GPS_TX=12 + -D PIN_USER_BTN=38 + -D ENV_INCLUDE_GPS=1 + ;-D ENV_INCLUDE_BME680 +build_src_filter = ${esp32_base.build_src_filter} + +<../variants/lilygo_tbeam_SX1276> + + + + + + +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 + stevemarple/MicroNMEA @ ^2.0.6 + boschsensortec/BSEC Software Library @ ^1.8.1492 + +[env:Tbeam_SX1276_companion_radio_ble] +extends = LilyGo_TBeam_SX1276 +board_build.upload.maximum_ram_size=2000000 +build_flags = + ${LilyGo_TBeam_SX1276.build_flags} + -D MAX_CONTACTS=100 + -D MAX_GROUP_CHANNELS=8 + -D BLE_PIN_CODE=123456 +; -D BLE_DEBUG_LOGGING=1 + -D OFFLINE_QUEUE_SIZE=256 +; -D RADIOLIB_DEBUG_BASIC=1 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${LilyGo_TBeam_SX1276.build_src_filter} + + + +<../examples/companion_radio> +lib_deps = + ${LilyGo_TBeam_SX1276.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:Tbeam_SX1276_repeater] +extends = LilyGo_TBeam_SX1276 +build_flags = + ${LilyGo_TBeam_SX1276.build_flags} + -D ADVERT_NAME='"Tbeam Repeater"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=8 + -D PERSISTANT_GPS=1 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${LilyGo_TBeam_SX1276.build_src_filter} + +<../examples/simple_repeater> +lib_deps = + ${LilyGo_TBeam_SX1276.lib_deps} + ${esp32_ota.lib_deps} \ No newline at end of file diff --git a/variants/lilygo_tbeam_SX1276/target.cpp b/variants/lilygo_tbeam_SX1276/target.cpp new file mode 100644 index 000000000..d340dedb2 --- /dev/null +++ b/variants/lilygo_tbeam_SX1276/target.cpp @@ -0,0 +1,75 @@ +#include +#include "target.h" + +TBeamBoard board; + +#if defined(P_LORA_SCLK) + static SPIClass spi; + RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi); +#else + RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1); +#endif + +WRAPPER_CLASS radio_driver(radio, board); + +ESP32RTCClock fallback_clock; +AutoDiscoverRTCClock rtc_clock(fallback_clock); + +#if ENV_INCLUDE_GPS + #include + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); +#else + EnvironmentSensorManager sensors; +#endif + +#ifdef DISPLAY_CLASS + DISPLAY_CLASS display; +#endif + +#ifndef LORA_CR + #define LORA_CR 5 +#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 + } + +#ifdef SX127X_CURRENT_LIMIT + radio.setCurrentLimit(SX127X_CURRENT_LIMIT); +#endif + + radio.setCRC(1); + + return true; // success +} + +uint32_t radio_get_rng_seed() { + return radio.random(0x7FFFFFFF); +} + +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { + radio.setFrequency(freq); + radio.setSpreadingFactor(sf); + radio.setBandwidth(bw); + radio.setCodingRate(cr); +} + +void radio_set_tx_power(uint8_t dbm) { + radio.setOutputPower(dbm); +} + +mesh::LocalIdentity radio_new_identity() { + RadioNoiseListener rng(radio); + return mesh::LocalIdentity(&rng); // create new random identity +} diff --git a/variants/lilygo_tbeam_SX1276/target.h b/variants/lilygo_tbeam_SX1276/target.h new file mode 100644 index 000000000..414352100 --- /dev/null +++ b/variants/lilygo_tbeam_SX1276/target.h @@ -0,0 +1,27 @@ +#pragma once + +#define RADIOLIB_STATIC_ONLY 1 +//#include +#include +#include +#include +#include +#include +#ifdef DISPLAY_CLASS + #include +#endif + +extern TBeamBoard board; +extern WRAPPER_CLASS radio_driver; +extern AutoDiscoverRTCClock rtc_clock; +extern EnvironmentSensorManager sensors; + +#ifdef DISPLAY_CLASS + extern DISPLAY_CLASS display; +#endif + +bool radio_init(); +uint32_t radio_get_rng_seed(); +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); +void radio_set_tx_power(uint8_t dbm); +mesh::LocalIdentity radio_new_identity(); diff --git a/variants/lilygo_tbeam_supreme_SX1262/platformio.ini b/variants/lilygo_tbeam_supreme_SX1262/platformio.ini index bcc517034..ee64a4d37 100644 --- a/variants/lilygo_tbeam_supreme_SX1262/platformio.ini +++ b/variants/lilygo_tbeam_supreme_SX1262/platformio.ini @@ -4,19 +4,28 @@ board = t_beams3_supreme ; LILYGO T-Beam Supreme ESP32S3 with SX1262 build_flags = ${esp32_base.build_flags} -I variants/lilygo_tbeam_supreme_SX1262 + -D TBEAM_SUPREME_SX1262 + -D SX126X_CURRENT_LIMIT=140 + -D SX126X_RX_BOOSTED_GAIN=1 + -D RADIO_CLASS=CustomSX1262 + -D WRAPPER_CLASS=CustomSX1262Wrapper + -D DISPLAY_CLASS=SH1106Display -D LORA_TX_POWER=22 -D P_LORA_TX_LED=6 -D PIN_BOARD_SDA=17 -D PIN_BOARD_SCL=18 + -D PIN_GPS_RX=9 + -D PIN_GPS_TX=8 + -D PIN_GPS_EN=7 -D PIN_USER_BTN=0 - -D RADIO_CLASS=CustomSX1262 - -D WRAPPER_CLASS=CustomSX1262Wrapper - -D DISPLAY_CLASS=SH1106Display - -D SX126X_RX_BOOSTED_GAIN=1 - -D SX126X_CURRENT_LIMIT=140 + -D TELEM_BME280_ADDRESS=0x77 + -D ENV_INCLUDE_GPS=1 + -D ENV_INCLUDE_BME280=1 build_src_filter = ${esp32_base.build_src_filter} +<../variants/lilygo_tbeam_supreme_SX1262> + + + + + board_build.partitions = min_spiffs.csv ; get around 4mb flash limit lib_deps = ${esp32_base.lib_deps} diff --git a/variants/lilygo_tbeam_supreme_SX1262/target.cpp b/variants/lilygo_tbeam_supreme_SX1262/target.cpp index 74639b4ed..68d543966 100644 --- a/variants/lilygo_tbeam_supreme_SX1262/target.cpp +++ b/variants/lilygo_tbeam_supreme_SX1262/target.cpp @@ -1,265 +1,33 @@ #include #include "target.h" -#include -TBeamS3SupremeBoard board; +TBeamBoard board; #ifdef DISPLAY_CLASS DISPLAY_CLASS display; #endif -bool pmuIntFlag; +static SPIClass spi; -#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 +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); ESP32RTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); -MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); -TbeamSupSensorManager sensors = TbeamSupSensorManager(nmea); - -static void setPMUIntFlag(){ - pmuIntFlag = true; -} - -#ifdef MESH_DEBUG -uint32_t deviceOnline = 0x00; -void scanDevices(TwoWire *w) -{ - uint8_t err, addr; - int nDevices = 0; - uint32_t start = 0; - - Serial.println("Scanning I2C for Devices"); - for (addr = 1; addr < 127; addr++) { - start = millis(); - w->beginTransmission(addr); delay(2); - err = w->endTransmission(); - if (err == 0) { - nDevices++; - switch (addr) { - case 0x77: - case 0x76: - Serial.println("\tFound BME280 Sensor"); - deviceOnline |= BME280_ONLINE; - break; - case 0x34: - Serial.println("\tFound AXP192/AXP2101 PMU"); - deviceOnline |= POWERMANAGE_ONLINE; - break; - case 0x3C: - Serial.println("\tFound SSD1306/SH1106 dispaly"); - deviceOnline |= DISPLAY_ONLINE; - break; - case 0x51: - Serial.println("\tFound PCF8563 RTC"); - deviceOnline |= PCF8563_ONLINE; - break; - case 0x1C: - Serial.println("\tFound QMC6310 MAG Sensor"); - deviceOnline |= QMC6310_ONLINE; - break; - default: - Serial.print("\tI2C device found at address 0x"); - if (addr < 16) { - Serial.print("0"); - } - Serial.print(addr, HEX); - Serial.println(" !"); - break; - } - - } else if (err == 4) { - Serial.print("Unknow error at address 0x"); - if (addr < 16) { - Serial.print("0"); - } - Serial.println(addr, HEX); - } - } - if (nDevices == 0) - Serial.println("No I2C devices found\n"); - - Serial.println("Scan for devices is complete."); - Serial.println("\n"); -} -void TBeamS3SupremeBoard::printPMU() -{ - Serial.print("isCharging:"); Serial.println(PMU.isCharging() ? "YES" : "NO"); - Serial.print("isDischarge:"); Serial.println(PMU.isDischarge() ? "YES" : "NO"); - Serial.print("isVbusIn:"); Serial.println(PMU.isVbusIn() ? "YES" : "NO"); - Serial.print("getBattVoltage:"); Serial.print(PMU.getBattVoltage()); Serial.println("mV"); - Serial.print("getVbusVoltage:"); Serial.print(PMU.getVbusVoltage()); Serial.println("mV"); - Serial.print("getSystemVoltage:"); Serial.print(PMU.getSystemVoltage()); Serial.println("mV"); - - // The battery percentage may be inaccurate at first use, the PMU will automatically - // learn the battery curve and will automatically calibrate the battery percentage - // after a charge and discharge cycle - if (PMU.isBatteryConnect()) { - Serial.print("getBatteryPercent:"); Serial.print(PMU.getBatteryPercent()); Serial.println("%"); - } - - Serial.println(); -} -void TbeamSupSensorManager::printBMEValues() { - Serial.print("Temperature = "); - Serial.print(bme.readTemperature()); - Serial.println(" *C"); - - Serial.print("Pressure = "); - - Serial.print(bme.readPressure() / 100.0F); - Serial.println(" hPa"); - - Serial.print("Approx. Altitude = "); - Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); - Serial.println(" m"); - - Serial.print("Humidity = "); - Serial.print(bme.readHumidity()); - Serial.println(" %"); - - Serial.println(); -} -#endif - -bool TBeamS3SupremeBoard::power_init() -{ - bool result = PMU.begin(PMU_WIRE_PORT, I2C_PMU_ADD, PIN_BOARD_SDA1, PIN_BOARD_SCL1); - if (result == false) { - MESH_DEBUG_PRINTLN("power is not online..."); while (1)delay(50); - } - MESH_DEBUG_PRINTLN("Setting charge led"); - PMU.setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG); - - // Set up PMU interrupts - MESH_DEBUG_PRINTLN("Setting up PMU interrupts"); - pinMode(PIN_PMU_IRQ, INPUT_PULLUP); - attachInterrupt(PIN_PMU_IRQ, setPMUIntFlag, FALLING); - - // GPS - MESH_DEBUG_PRINTLN("Setting and enabling a-ldo4 for GPS"); - PMU.setALDO4Voltage(3300); - PMU.enableALDO4(); // disable to save power - - // Lora - MESH_DEBUG_PRINTLN("Setting and enabling a-ldo3 for LoRa"); - PMU.setALDO3Voltage(3300); - PMU.enableALDO3(); - - // To avoid SPI bus issues during power up, reset OLED, sensor, and SD card supplies - // MESH_DEBUG_PRINTLN("Reset a-ldo1&2 and b-ldo1"); - // if (ESP_SLEEP_WAKEUP_UNDEFINED == esp_sleep_get_wakeup_cause()) - // { - // PMU.disableALDO1(); - // PMU.disableALDO2(); - // PMU.disableBLDO1(); - // delay(250); - // } - - // m.2 interface - MESH_DEBUG_PRINTLN("Setting and enabling dcdc3 for m.2 interface"); - PMU.setDC3Voltage(3300); // doesn't go anywhere in the schematic?? - PMU.enableDC3(); - - // QMC6310U - MESH_DEBUG_PRINTLN("Setting and enabling a-ldo2 for QMC"); - PMU.setALDO2Voltage(3300); - PMU.enableALDO2(); // disable to save power - - // BME280 and OLED - MESH_DEBUG_PRINTLN("Setting and enabling a-ldo1 for oled"); - PMU.setALDO1Voltage(3300); - PMU.enableALDO1(); - - // SD card - MESH_DEBUG_PRINTLN("Setting and enabling b-ldo2 for SD card"); - PMU.setBLDO1Voltage(3300); - PMU.enableBLDO1(); - - // Out to header pins - MESH_DEBUG_PRINTLN("Setting and enabling b-ldo2 for output to header"); - PMU.setBLDO2Voltage(3300); - PMU.enableBLDO2(); - - MESH_DEBUG_PRINTLN("Setting and enabling dcdc4 for output to header"); - PMU.setDC4Voltage(XPOWERS_AXP2101_DCDC4_VOL2_MAX); // 1.8V - PMU.enableDC4(); - - MESH_DEBUG_PRINTLN("Setting and enabling dcdc5 for output to header"); - PMU.setDC5Voltage(3300); - PMU.enableDC5(); - - // Unused power rails - MESH_DEBUG_PRINTLN("Disabling unused supplies dcdc2, dcdc5, dldo1 and dldo2"); - PMU.disableDC2(); - //PMU.disableDC5(); - PMU.disableDLDO1(); - PMU.disableDLDO2(); - - PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ); - - // Set charge current to 500mA - MESH_DEBUG_PRINTLN("Setting battery charge current limit and voltage"); - PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA); - PMU.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2); - PMU.clearIrqStatus(); - PMU.disableTSPinMeasure(); - - // enable battery voltage measurement - MESH_DEBUG_PRINTLN("Enabling battery measurement"); - PMU.enableBattVoltageMeasure(); - PMU.enableVbusVoltageMeasure(); - - // Reset and re-enable PMU interrupts - MESH_DEBUG_PRINTLN("Re-enable interrupts"); - PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ); - PMU.clearIrqStatus(); - PMU.enableIRQ( - XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | // Battery interrupts - XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | // VBUS interrupts - XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | // Power Key interrupts - XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ // Charging interrupts - ); -#ifdef MESH_DEBUG - scanDevices(&Wire); - scanDevices(&Wire1); - printPMU(); +#if ENV_INCLUDE_GPS + #include + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); +#else + EnvironmentSensorManager sensors; #endif - // Set the power key off press time - PMU.setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S); - return true; -} - -static bool readStringUntil(Stream& s, char dest[], size_t max_len, char term, unsigned int timeout_millis) { - unsigned long timeout = millis() + timeout_millis; - char *dp = dest; - while (millis() < timeout && dp - dest < max_len - 1) { - if (s.available()) { - char c = s.read(); - if (c == term) break; - *dp++ = c; // append to dest[] - } else { - delay(1); - } - } - *dp = 0; // null terminator - return millis() < timeout; // false, if timed out -} - bool radio_init() { fallback_clock.begin(); rtc_clock.begin(Wire1); return radio.std_init(&spi); -#endif } uint32_t radio_get_rng_seed() { @@ -277,123 +45,6 @@ void radio_set_tx_power(uint8_t dbm) { radio.setOutputPower(dbm); } -void TbeamSupSensorManager::start_gps() -{ - gps_active = true; - pinMode(P_GPS_WAKE, OUTPUT); - digitalWrite(P_GPS_WAKE, HIGH); -} - -void TbeamSupSensorManager::sleep_gps() { - gps_active = false; - pinMode(P_GPS_WAKE, OUTPUT); - digitalWrite(P_GPS_WAKE, LOW); -} - -bool TbeamSupSensorManager::begin() { - //init BME280 - if (! bme.begin(0x77, &Wire)) { - MESH_DEBUG_PRINTLN("Could not find a valid BME280 sensor"); - bme_active = false; - } - else - MESH_DEBUG_PRINTLN("BME280 found and init!"); - bme_active = true; - - // init GPS port - Serial1.begin(GPS_BAUD_RATE, SERIAL_8N1, P_GPS_RX, P_GPS_TX); - - MESH_DEBUG_PRINTLN("Sleeping GPS for initial state"); - sleep_gps(); - return true; -} - -bool TbeamSupSensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) { - if (requester_permissions & TELEM_PERM_LOCATION && gps_active) { // does requester have permission? - telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, node_altitude); - } - if (requester_permissions & TELEM_PERM_ENVIRONMENT && bme_active) { // does requester have permission? - telemetry.addTemperature(TELEM_CHANNEL_SELF, node_temp); - telemetry.addRelativeHumidity(TELEM_CHANNEL_SELF, node_hum); - telemetry.addBarometricPressure(TELEM_CHANNEL_SELF, node_pres); - //telemetry.addAltitude(TELEM_CHANNEL_SELF, node_alt); - } - return true; -} - -void TbeamSupSensorManager::loop() { - static long next_update = 0; - - _nmea->loop(); - - if (millis() > next_update) { - if (_nmea->isValid() && gps_active) { - node_lat = ((double)_nmea->getLatitude())/1000000.; - node_lon = ((double)_nmea->getLongitude())/1000000.; - node_altitude = ((double)_nmea->getAltitude()) / 1000.0; - MESH_DEBUG_PRINT("lat %f lon %f alt %f\r\n", node_lat, node_lon, node_altitude); - } - - //read BME280 values - if(bme_active){ - //node_alt = bme.readAltitude(SEALEVELPRESSURE_HPA); - node_temp = bme.readTemperature(); - node_hum = bme.readHumidity(); - node_pres = (bme.readPressure() / 100.0F); - - #ifdef MESH_DEBUG - // Serial.print("Temperature = "); - // Serial.print(node_temp); - // Serial.println(" *C"); - - // Serial.print("Humidity = "); - // Serial.print(node_hum); - // Serial.println(" %"); - - // Serial.print("Pressure = "); - // Serial.print(node_pres); - // Serial.println(" hPa"); - - // Serial.print("Approx. Altitude = "); - // Serial.print(node_alt); - // Serial.println(" m"); - #endif - } - - next_update = millis() + 1000; - } -} - -int TbeamSupSensorManager::getNumSettings() const { - return 1; -} - -const char* TbeamSupSensorManager::getSettingName(int i) const { - switch(i){ - case 0: return "gps"; - default: NULL; - } -} - -const char* TbeamSupSensorManager::getSettingValue(int i) const { - switch(i){ - case 0: return gps_active == true ? "1" : "0"; - default: NULL; - } -} - -bool TbeamSupSensorManager::setSettingValue(const char* name, const char* value) { - if (strcmp(name, "gps") == 0) { - if (strcmp(value, "0") == 0) { - sleep_gps(); - } else { - start_gps(); - } - return true; - } - return false; // not supported -} - mesh::LocalIdentity radio_new_identity() { RadioNoiseListener rng(radio); return mesh::LocalIdentity(&rng); // create new random identity diff --git a/variants/lilygo_tbeam_supreme_SX1262/target.h b/variants/lilygo_tbeam_supreme_SX1262/target.h index a3023750f..ea1138af1 100644 --- a/variants/lilygo_tbeam_supreme_SX1262/target.h +++ b/variants/lilygo_tbeam_supreme_SX1262/target.h @@ -3,66 +3,20 @@ #define RADIOLIB_STATIC_ONLY 1 #include #include -#include +#include #include #include -#include -#include -#include - -class TbeamSupSensorManager: public SensorManager { - bool gps_active = false; - bool bme_active = false; - LocationProvider * _nmea; - Adafruit_BME280 bme; - double node_temp, node_hum, node_pres; - - #define SEALEVELPRESSURE_HPA (1013.25) - - void start_gps(); - void sleep_gps(); - public: - TbeamSupSensorManager(LocationProvider &nmea): _nmea(&nmea) {node_temp = 0; node_hum = 0; node_pres = 0;} - bool begin() override; - bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override; - void loop() override; - int getNumSettings() const override; - const char* getSettingName(int i) const override; - const char* getSettingValue(int i) const override; - bool setSettingValue(const char* name, const char* value) override; - - #ifdef MESH_DEBUG - void printBMEValues(); - #endif - - }; - -extern TBeamS3SupremeBoard board; -extern WRAPPER_CLASS radio_driver; -extern AutoDiscoverRTCClock rtc_clock; -extern TbeamSupSensorManager sensors; +#include #ifdef DISPLAY_CLASS #include extern DISPLAY_CLASS display; #endif -enum { - POWERMANAGE_ONLINE = _BV(0), - DISPLAY_ONLINE = _BV(1), - RADIO_ONLINE = _BV(2), - GPS_ONLINE = _BV(3), - PSRAM_ONLINE = _BV(4), - SDCARD_ONLINE = _BV(5), - AXDL345_ONLINE = _BV(6), - BME280_ONLINE = _BV(7), - BMP280_ONLINE = _BV(8), - BME680_ONLINE = _BV(9), - QMC6310_ONLINE = _BV(10), - QMI8658_ONLINE = _BV(11), - PCF8563_ONLINE = _BV(12), - OSC32768_ONLINE = _BV(13), -}; +extern TBeamBoard board; +extern WRAPPER_CLASS radio_driver; +extern AutoDiscoverRTCClock rtc_clock; +extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed();