mirror of
https://github.com/Genaker/LoraSA.git
synced 2026-03-28 17:42:59 +01:00
1046 lines
28 KiB
C++
1046 lines
28 KiB
C++
/**
|
|
* @file boards.cpp
|
|
* @author Lewis He (lewishe@outlook.com)
|
|
* @license MIT
|
|
* @copyright Copyright (c) 2024 ShenZhen XinYuan Electronic Technology Co., Ltd
|
|
* @date 2024-04-24
|
|
* @last-update 2024-08-07
|
|
*
|
|
*/
|
|
|
|
#ifdef LILYGO
|
|
|
|
#include "LoRaBoards.h"
|
|
|
|
#include "LiLyGo.h"
|
|
|
|
// Implement stubs for functions that exist on Heltec, but not on LilyGo
|
|
void heltec_led(int led) {}
|
|
|
|
void heltec_deep_sleep(int sleep_seconds) {}
|
|
|
|
void heltec_delay(int millisec) { delay(millisec); }
|
|
|
|
DISPLAY_TYPE display = DISPLAY_INIT();
|
|
BOTH_TYPE both = BOTH_INIT();
|
|
|
|
HotButton button(BUTTON);
|
|
|
|
void heltec_loop()
|
|
{
|
|
#ifndef DT3_V1_6_SX1276
|
|
button.update();
|
|
#endif
|
|
}
|
|
|
|
void heltec_display_power(bool on)
|
|
{
|
|
#ifndef HELTEC_NO_DISPLAY_INSTANCE
|
|
if (on)
|
|
{
|
|
#ifdef HELTEC_WIRELESS_STICK
|
|
// They hooked the display to "external" power, and didn't tell anyone
|
|
heltec_ve(true);
|
|
delay(5);
|
|
#endif
|
|
pinMode(RST_OLED, OUTPUT);
|
|
digitalWrite(RST_OLED, HIGH);
|
|
delay(1);
|
|
digitalWrite(RST_OLED, LOW);
|
|
delay(20);
|
|
digitalWrite(RST_OLED, HIGH);
|
|
}
|
|
else
|
|
{
|
|
#ifdef HELTEC_WIRELESS_STICK
|
|
heltec_ve(false);
|
|
#else
|
|
display.displayOff();
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void heltec_setup()
|
|
{
|
|
Serial.begin(115200);
|
|
Serial.println("LILYGO BOARD");
|
|
|
|
#if defined(ARDUINO_ARCH_ESP32)
|
|
SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN);
|
|
#elif defined(ARDUINO_ARCH_STM32)
|
|
SPI.setMISO(RADIO_MISO_PIN);
|
|
SPI.setMOSI(RADIO_MOSI_PIN);
|
|
SPI.setSCLK(RADIO_SCLK_PIN);
|
|
SPI.begin();
|
|
#endif
|
|
|
|
#ifdef HELTEC
|
|
#ifndef ARDUINO_heltec_wifi_32_lora_V3
|
|
vspi->begin(SCK, MISO, MOSI, SS);
|
|
#endif
|
|
#endif
|
|
#ifndef HELTEC_NO_DISPLAY_INSTANCE
|
|
heltec_display_power(true);
|
|
display.init();
|
|
// display.setContrast(200);
|
|
display.flipScreenVertically();
|
|
#endif
|
|
}
|
|
|
|
#ifdef HELTEC
|
|
#ifndef ARDUINO_heltec_wifi_32_lora_V3
|
|
SPIClass vspi = new SPIClass(2);
|
|
#endif
|
|
#endif
|
|
|
|
RADIO_TYPE radio = RADIO_MODULE_INIT();
|
|
|
|
#if defined(HAS_SDCARD)
|
|
SPIClass SDCardSPI(HSPI);
|
|
#endif
|
|
|
|
#if defined(ARDUINO_ARCH_STM32)
|
|
HardwareSerial SerialGPS(GPS_RX_PIN, GPS_TX_PIN);
|
|
#endif
|
|
|
|
#if defined(ARDUINO_ARCH_ESP32)
|
|
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
|
#include "hal/gpio_hal.h"
|
|
#endif
|
|
#include "driver/gpio.h"
|
|
#endif // ARDUINO_ARCH_ESP32
|
|
|
|
DISPLAY_MODEL *u8g2 = NULL;
|
|
static DevInfo_t devInfo;
|
|
|
|
#ifdef HAS_GPS
|
|
static bool find_gps = false;
|
|
#endif
|
|
|
|
#ifdef HAS_PMU
|
|
XPowersLibInterface *PMU = NULL;
|
|
bool pmuInterrupt;
|
|
|
|
static void setPmuFlag() { pmuInterrupt = true; }
|
|
#endif
|
|
|
|
bool beginPower()
|
|
{
|
|
#ifdef HAS_PMU
|
|
if (!PMU)
|
|
{
|
|
PMU = new XPowersAXP2101(PMU_WIRE_PORT);
|
|
if (!PMU->init())
|
|
{
|
|
Serial.println("Warning: Failed to find AXP2101 power management");
|
|
delete PMU;
|
|
PMU = NULL;
|
|
}
|
|
else
|
|
{
|
|
Serial.println("AXP2101 PMU init succeeded, using AXP2101 PMU");
|
|
}
|
|
}
|
|
|
|
if (!PMU)
|
|
{
|
|
PMU = new XPowersAXP192(PMU_WIRE_PORT);
|
|
if (!PMU->init())
|
|
{
|
|
Serial.println("Warning: Failed to find AXP192 power management");
|
|
delete PMU;
|
|
PMU = NULL;
|
|
}
|
|
else
|
|
{
|
|
Serial.println("AXP192 PMU init succeeded, using AXP192 PMU");
|
|
}
|
|
}
|
|
|
|
if (!PMU)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
PMU->setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
|
|
|
|
pinMode(PMU_IRQ, INPUT_PULLUP);
|
|
attachInterrupt(PMU_IRQ, setPmuFlag, FALLING);
|
|
|
|
if (PMU->getChipModel() == XPOWERS_AXP192)
|
|
{
|
|
|
|
PMU->setProtectedChannel(XPOWERS_DCDC3);
|
|
|
|
// lora
|
|
PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
|
|
// gps
|
|
PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
|
|
// oled
|
|
PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
|
|
|
|
PMU->enablePowerOutput(XPOWERS_LDO2);
|
|
PMU->enablePowerOutput(XPOWERS_LDO3);
|
|
|
|
// protected oled power source
|
|
PMU->setProtectedChannel(XPOWERS_DCDC1);
|
|
// protected esp32 power source
|
|
PMU->setProtectedChannel(XPOWERS_DCDC3);
|
|
// enable oled power
|
|
PMU->enablePowerOutput(XPOWERS_DCDC1);
|
|
|
|
// disable not use channel
|
|
PMU->disablePowerOutput(XPOWERS_DCDC2);
|
|
|
|
PMU->disableIRQ(XPOWERS_AXP192_ALL_IRQ);
|
|
|
|
PMU->enableIRQ(XPOWERS_AXP192_VBUS_REMOVE_IRQ | XPOWERS_AXP192_VBUS_INSERT_IRQ |
|
|
XPOWERS_AXP192_BAT_CHG_DONE_IRQ |
|
|
XPOWERS_AXP192_BAT_CHG_START_IRQ | XPOWERS_AXP192_BAT_REMOVE_IRQ |
|
|
XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_PKEY_SHORT_IRQ);
|
|
}
|
|
else if (PMU->getChipModel() == XPOWERS_AXP2101)
|
|
{
|
|
|
|
#if defined(CONFIG_IDF_TARGET_ESP32)
|
|
// Unuse power channel
|
|
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);
|
|
|
|
// GNSS RTC PowerVDD 3300mV
|
|
PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_VBACKUP);
|
|
|
|
// ESP32 VDD 3300mV
|
|
// ! No need to set, automatically open , Don't close it
|
|
// PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
|
|
// PMU->setProtectedChannel(XPOWERS_DCDC1);
|
|
PMU->setProtectedChannel(XPOWERS_DCDC1);
|
|
|
|
// LoRa VDD 3300mV
|
|
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
|
|
|
// GNSS VDD 3300mV
|
|
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_ALDO3);
|
|
|
|
#endif /*CONFIG_IDF_TARGET_ESP32*/
|
|
|
|
#if defined(T_BEAM_S3_SUPREME)
|
|
|
|
// t-beam m.2 inface
|
|
// gps
|
|
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_ALDO4);
|
|
|
|
// lora
|
|
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_ALDO3);
|
|
|
|
// In order to avoid bus occupation, during initialization, the SD card and QMC
|
|
// sensor are powered off and restarted
|
|
if (ESP_SLEEP_WAKEUP_UNDEFINED == esp_sleep_get_wakeup_cause())
|
|
{
|
|
Serial.println("Power off and restart ALDO BLDO..");
|
|
PMU->disablePowerOutput(XPOWERS_ALDO1);
|
|
PMU->disablePowerOutput(XPOWERS_ALDO2);
|
|
PMU->disablePowerOutput(XPOWERS_BLDO1);
|
|
delay(250);
|
|
}
|
|
|
|
// Sensor
|
|
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_ALDO1);
|
|
|
|
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
|
|
|
// Sdcard
|
|
|
|
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_BLDO1);
|
|
|
|
PMU->setPowerChannelVoltage(XPOWERS_BLDO2, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_BLDO2);
|
|
|
|
// face m.2
|
|
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_DCDC3);
|
|
|
|
PMU->setPowerChannelVoltage(XPOWERS_DCDC4, XPOWERS_AXP2101_DCDC4_VOL2_MAX);
|
|
PMU->enablePowerOutput(XPOWERS_DCDC4);
|
|
|
|
PMU->setPowerChannelVoltage(XPOWERS_DCDC5, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_DCDC5);
|
|
|
|
// not use channel
|
|
PMU->disablePowerOutput(XPOWERS_DCDC2);
|
|
// PMU->disablePowerOutput(XPOWERS_DCDC4);
|
|
// PMU->disablePowerOutput(XPOWERS_DCDC5);
|
|
PMU->disablePowerOutput(XPOWERS_DLDO1);
|
|
PMU->disablePowerOutput(XPOWERS_DLDO2);
|
|
PMU->disablePowerOutput(XPOWERS_VBACKUP);
|
|
|
|
#elif defined(T_BEAM_S3_BPF)
|
|
|
|
// gps
|
|
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_ALDO4);
|
|
|
|
// Sdcard
|
|
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
|
|
|
// Extern Power source
|
|
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_DCDC3);
|
|
|
|
PMU->setPowerChannelVoltage(XPOWERS_DCDC5, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_DCDC5);
|
|
|
|
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
|
|
PMU->enablePowerOutput(XPOWERS_ALDO1);
|
|
|
|
// not use channel
|
|
PMU->disablePowerOutput(XPOWERS_BLDO1);
|
|
PMU->disablePowerOutput(XPOWERS_BLDO2);
|
|
PMU->disablePowerOutput(XPOWERS_DCDC4);
|
|
PMU->disablePowerOutput(XPOWERS_DCDC2);
|
|
PMU->disablePowerOutput(XPOWERS_DCDC4);
|
|
PMU->disablePowerOutput(XPOWERS_DCDC5);
|
|
PMU->disablePowerOutput(XPOWERS_DLDO1);
|
|
PMU->disablePowerOutput(XPOWERS_DLDO2);
|
|
PMU->disablePowerOutput(XPOWERS_VBACKUP);
|
|
|
|
#endif
|
|
|
|
// Set constant current charge current limit
|
|
PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA);
|
|
|
|
// Set charge cut-off voltage
|
|
PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
|
|
|
|
// Disable all interrupts
|
|
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
|
// Clear all interrupt flags
|
|
PMU->clearIrqStatus();
|
|
// Enable the required interrupt function
|
|
PMU->enableIRQ(
|
|
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | // BATTERY
|
|
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | // VBUS
|
|
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | // POWER KEY
|
|
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ // CHARGE
|
|
// XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ | XPOWERS_AXP2101_PKEY_POSITIVE_IRQ |
|
|
// //POWER KEY
|
|
);
|
|
}
|
|
|
|
PMU->enableSystemVoltageMeasure();
|
|
PMU->enableVbusVoltageMeasure();
|
|
PMU->enableBattVoltageMeasure();
|
|
|
|
Serial.printf("=========================================\n");
|
|
if (PMU->isChannelAvailable(XPOWERS_DCDC1))
|
|
{
|
|
Serial.printf("DC1 : %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_DCDC2))
|
|
{
|
|
Serial.printf("DC2 : %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_DCDC3))
|
|
{
|
|
Serial.printf("DC3 : %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_DCDC4))
|
|
{
|
|
Serial.printf("DC4 : %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_DCDC5))
|
|
{
|
|
Serial.printf("DC5 : %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_DCDC5) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_DCDC5));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_LDO2))
|
|
{
|
|
Serial.printf("LDO2 : %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_LDO2));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_LDO3))
|
|
{
|
|
Serial.printf("LDO3 : %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_LDO3));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_ALDO1))
|
|
{
|
|
Serial.printf("ALDO1: %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_ALDO2))
|
|
{
|
|
Serial.printf("ALDO2: %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_ALDO3))
|
|
{
|
|
Serial.printf("ALDO3: %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_ALDO4))
|
|
{
|
|
Serial.printf("ALDO4: %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_BLDO1))
|
|
{
|
|
Serial.printf("BLDO1: %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
|
|
}
|
|
if (PMU->isChannelAvailable(XPOWERS_BLDO2))
|
|
{
|
|
Serial.printf("BLDO2: %s Voltage: %04u mV \n",
|
|
PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-",
|
|
PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
|
|
}
|
|
Serial.printf("=========================================\n");
|
|
|
|
// Set the time of pressing the button to turn off
|
|
PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
|
|
uint8_t opt = PMU->getPowerKeyPressOffTime();
|
|
Serial.print("PowerKeyPressOffTime:");
|
|
switch (opt)
|
|
{
|
|
case XPOWERS_POWEROFF_4S:
|
|
Serial.println("4 Second");
|
|
break;
|
|
case XPOWERS_POWEROFF_6S:
|
|
Serial.println("6 Second");
|
|
break;
|
|
case XPOWERS_POWEROFF_8S:
|
|
Serial.println("8 Second");
|
|
break;
|
|
case XPOWERS_POWEROFF_10S:
|
|
Serial.println("10 Second");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
void disablePeripherals()
|
|
{
|
|
|
|
#ifdef HAS_PMU
|
|
if (!PMU)
|
|
return;
|
|
#if defined(T_BEAM_S3_BPF)
|
|
PMU->disablePowerOutput(XPOWERS_ALDO4); // gps
|
|
PMU->disablePowerOutput(XPOWERS_ALDO2); // Sdcard
|
|
PMU->disablePowerOutput(XPOWERS_DCDC3); // Extern Power source
|
|
PMU->disablePowerOutput(XPOWERS_DCDC5);
|
|
PMU->disablePowerOutput(XPOWERS_ALDO1);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
void loopPMU()
|
|
{
|
|
#ifdef HAS_PMU
|
|
if (!PMU)
|
|
{
|
|
return;
|
|
}
|
|
if (!pmuInterrupt)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pmuInterrupt = false;
|
|
// Get PMU Interrupt Status Register
|
|
uint32_t status = PMU->getIrqStatus();
|
|
Serial.print("STATUS => HEX:");
|
|
Serial.print(status, HEX);
|
|
Serial.print(" BIN:");
|
|
Serial.println(status, BIN);
|
|
|
|
if (PMU->isVbusInsertIrq())
|
|
{
|
|
Serial.println("isVbusInsert");
|
|
}
|
|
if (PMU->isVbusRemoveIrq())
|
|
{
|
|
Serial.println("isVbusRemove");
|
|
}
|
|
if (PMU->isBatInsertIrq())
|
|
{
|
|
Serial.println("isBatInsert");
|
|
}
|
|
if (PMU->isBatRemoveIrq())
|
|
{
|
|
Serial.println("isBatRemove");
|
|
}
|
|
if (PMU->isPekeyShortPressIrq())
|
|
{
|
|
Serial.println("isPekeyShortPress");
|
|
}
|
|
if (PMU->isPekeyLongPressIrq())
|
|
{
|
|
Serial.println("isPekeyLongPress");
|
|
}
|
|
if (PMU->isBatChagerDoneIrq())
|
|
{
|
|
Serial.println("isBatChagerDone");
|
|
}
|
|
if (PMU->isBatChagerStartIrq())
|
|
{
|
|
Serial.println("isBatChagerStart");
|
|
}
|
|
// Clear PMU Interrupt Status Register
|
|
PMU->clearIrqStatus();
|
|
#endif
|
|
}
|
|
|
|
bool beginDisplay()
|
|
{
|
|
Wire.beginTransmission(DISPLAY_ADDR);
|
|
if (Wire.endTransmission() == 0)
|
|
{
|
|
Serial.printf("Find Display model at 0x%X address\n", DISPLAY_ADDR);
|
|
u8g2 = new DISPLAY_MODEL(U8G2_R0, U8X8_PIN_NONE);
|
|
u8g2->begin();
|
|
u8g2->clearBuffer();
|
|
u8g2->setFont(u8g2_font_inb19_mr);
|
|
u8g2->drawStr(0, 30, "LilyGo");
|
|
u8g2->drawHLine(2, 35, 47);
|
|
u8g2->drawHLine(3, 36, 47);
|
|
u8g2->drawVLine(45, 32, 12);
|
|
u8g2->drawVLine(46, 33, 12);
|
|
u8g2->setFont(u8g2_font_inb19_mf);
|
|
u8g2->drawStr(58, 60, "LoRa");
|
|
u8g2->sendBuffer();
|
|
u8g2->setFont(u8g2_font_fur11_tf);
|
|
delay(3000);
|
|
return true;
|
|
}
|
|
|
|
Serial.printf("Warning: Failed to find Display at 0x%0X address\n", DISPLAY_ADDR);
|
|
return false;
|
|
}
|
|
|
|
bool beginSDCard()
|
|
{
|
|
#ifdef SDCARD_CS
|
|
if (SD.begin(SDCARD_CS, SDCardSPI))
|
|
{
|
|
uint32_t cardSize = SD.cardSize() / (1024 * 1024);
|
|
Serial.print("Sd Card init succeeded, The current available capacity is ");
|
|
Serial.print(cardSize / 1024.0);
|
|
Serial.println(" GB");
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
Serial.println("Warning: Failed to init Sd Card");
|
|
}
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
void beginWiFi()
|
|
{
|
|
if (!WiFi.softAP(BOARD_VARIANT_NAME))
|
|
{
|
|
log_e("Soft AP creation failed.");
|
|
}
|
|
IPAddress myIP = WiFi.softAPIP();
|
|
Serial.print("AP IP address: ");
|
|
Serial.println(myIP);
|
|
}
|
|
|
|
void printWakeupReason()
|
|
{
|
|
#ifdef ESP32
|
|
Serial.print("Reset reason:");
|
|
esp_sleep_wakeup_cause_t wakeup_reason;
|
|
wakeup_reason = esp_sleep_get_wakeup_cause();
|
|
switch (wakeup_reason)
|
|
{
|
|
case ESP_SLEEP_WAKEUP_UNDEFINED:
|
|
Serial.println(
|
|
" In case of deep sleep, reset was not caused by exit from deep sleep");
|
|
break;
|
|
case ESP_SLEEP_WAKEUP_ALL:
|
|
break;
|
|
case ESP_SLEEP_WAKEUP_EXT0:
|
|
Serial.println("Wakeup caused by external signal using RTC_IO");
|
|
break;
|
|
case ESP_SLEEP_WAKEUP_EXT1:
|
|
Serial.println("Wakeup caused by external signal using RTC_CNTL");
|
|
break;
|
|
case ESP_SLEEP_WAKEUP_TIMER:
|
|
Serial.println("Wakeup caused by timer");
|
|
break;
|
|
case ESP_SLEEP_WAKEUP_TOUCHPAD:
|
|
Serial.println("Wakeup caused by touchpad");
|
|
break;
|
|
case ESP_SLEEP_WAKEUP_ULP:
|
|
Serial.println("Wakeup caused by ULP program");
|
|
break;
|
|
default:
|
|
Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason);
|
|
break;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void getChipInfo()
|
|
{
|
|
#if defined(ARDUINO_ARCH_ESP32)
|
|
|
|
Serial.println("-----------------------------------");
|
|
|
|
printWakeupReason();
|
|
|
|
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
|
|
|
if (psramFound())
|
|
{
|
|
uint32_t psram = ESP.getPsramSize();
|
|
devInfo.psramSize = psram / 1024.0 / 1024.0;
|
|
Serial.printf("PSRAM is enable! PSRAM: %.2fMB\n", devInfo.psramSize);
|
|
}
|
|
else
|
|
{
|
|
Serial.println("PSRAM is disable!");
|
|
devInfo.psramSize = 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
Serial.print("Flash:");
|
|
devInfo.flashSize = ESP.getFlashChipSize() / 1024.0 / 1024.0;
|
|
devInfo.flashSpeed = ESP.getFlashChipSpeed() / 1000 / 1000;
|
|
devInfo.chipModel = ESP.getChipModel();
|
|
devInfo.chipModelRev = ESP.getChipRevision();
|
|
devInfo.chipFreq = ESP.getCpuFreqMHz();
|
|
|
|
Serial.print(devInfo.flashSize);
|
|
Serial.println(" MB");
|
|
Serial.print("Flash speed:");
|
|
Serial.print(devInfo.flashSpeed);
|
|
Serial.println(" M");
|
|
Serial.print("Model:");
|
|
|
|
Serial.println(devInfo.chipModel);
|
|
Serial.print("Chip Revision:");
|
|
Serial.println(devInfo.chipModelRev);
|
|
Serial.print("Freq:");
|
|
Serial.print(devInfo.chipFreq);
|
|
Serial.println(" MHZ");
|
|
Serial.print("SDK Ver:");
|
|
Serial.println(ESP.getSdkVersion());
|
|
Serial.print("DATE:");
|
|
Serial.println(__DATE__);
|
|
Serial.print("TIME:");
|
|
Serial.println(__TIME__);
|
|
|
|
Serial.print("EFUSE MAC: ");
|
|
Serial.print(ESP.getEfuseMac(), HEX);
|
|
Serial.println();
|
|
|
|
Serial.println("-----------------------------------");
|
|
|
|
#elif defined(ARDUINO_ARCH_STM32)
|
|
uint32_t uid[3];
|
|
|
|
uid[0] = HAL_GetUIDw0();
|
|
uid[1] = HAL_GetUIDw1();
|
|
uid[2] = HAL_GetUIDw2();
|
|
Serial.print("STM UID: 0X");
|
|
Serial.print(uid[0], HEX);
|
|
Serial.print(uid[1], HEX);
|
|
Serial.print(uid[2], HEX);
|
|
Serial.println();
|
|
#endif
|
|
}
|
|
|
|
void setupBoards(bool disable_u8g2)
|
|
{
|
|
Serial.begin(115200);
|
|
|
|
// while (!Serial);
|
|
|
|
Serial.println("setupBoards");
|
|
|
|
getChipInfo();
|
|
|
|
#if defined(ARDUINO_ARCH_ESP32)
|
|
SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN);
|
|
#elif defined(ARDUINO_ARCH_STM32)
|
|
SPI.setMISO(RADIO_MISO_PIN);
|
|
SPI.setMOSI(RADIO_MOSI_PIN);
|
|
SPI.setSCLK(RADIO_SCLK_PIN);
|
|
SPI.begin();
|
|
#endif
|
|
|
|
#ifdef HAS_SDCARD
|
|
SDCardSPI.begin(SDCARD_SCLK, SDCARD_MISO, SDCARD_MOSI);
|
|
#endif
|
|
|
|
#ifdef I2C_SDA
|
|
Wire.begin(I2C_SDA, I2C_SCL);
|
|
scanDevices(&Wire);
|
|
#endif
|
|
|
|
#ifdef I2C1_SDA
|
|
Wire1.begin(I2C1_SDA, I2C1_SCL);
|
|
#endif
|
|
|
|
#ifdef HAS_GPS
|
|
#if defined(ARDUINO_ARCH_ESP32)
|
|
SerialGPS.begin(GPS_BAUD_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
|
|
#elif defined(ARDUINO_ARCH_STM32)
|
|
SerialGPS.setRx(GPS_RX_PIN);
|
|
SerialGPS.setTx(GPS_TX_PIN);
|
|
SerialGPS.begin(GPS_BAUD_RATE);
|
|
#endif // ARDUINO_ARCH_
|
|
#endif // HAS_GPS
|
|
|
|
#if OLED_RST
|
|
pinMode(OLED_RST, OUTPUT);
|
|
digitalWrite(OLED_RST, HIGH);
|
|
delay(20);
|
|
digitalWrite(OLED_RST, LOW);
|
|
delay(20);
|
|
digitalWrite(OLED_RST, HIGH);
|
|
delay(20);
|
|
#endif
|
|
|
|
#ifdef BOARD_LED
|
|
/*
|
|
* T-Beam LED defaults to low level as turn on,
|
|
* so it needs to be forced to pull up
|
|
* * * * */
|
|
#if LED_ON == LOW
|
|
#if defined(ARDUINO_ARCH_ESP32)
|
|
gpio_hold_dis((gpio_num_t)BOARD_LED);
|
|
#endif // ARDUINO_ARCH_ESP32
|
|
#endif
|
|
|
|
pinMode(BOARD_LED, OUTPUT);
|
|
digitalWrite(BOARD_LED, LED_ON);
|
|
#endif
|
|
|
|
#ifdef GPS_EN_PIN
|
|
pinMode(GPS_EN_PIN, OUTPUT);
|
|
digitalWrite(GPS_EN_PIN, HIGH);
|
|
#endif
|
|
|
|
#ifdef GPS_RST_PIN
|
|
pinMode(GPS_RST_PIN, OUTPUT);
|
|
digitalWrite(GPS_RST_PIN, HIGH);
|
|
#endif
|
|
|
|
#if defined(ARDUINO_ARCH_STM32)
|
|
SerialGPS.println("@GSR");
|
|
delay(300);
|
|
SerialGPS.println("@GSR");
|
|
delay(300);
|
|
SerialGPS.println("@GSR");
|
|
delay(300);
|
|
SerialGPS.println("@GSR");
|
|
delay(300);
|
|
SerialGPS.println("@GSR");
|
|
delay(300);
|
|
#endif
|
|
|
|
#ifdef RADIO_LDO_EN
|
|
pinMode(RADIO_LDO_EN, OUTPUT);
|
|
digitalWrite(RADIO_LDO_EN, HIGH);
|
|
#endif
|
|
|
|
beginPower();
|
|
|
|
bool sdReady;
|
|
|
|
#ifndef DISABLE_SDCARD
|
|
for (int i = 0; i < 5 && !(sdReady = beginSDCard()); i++)
|
|
{
|
|
Serial.println("SD card failed or not found");
|
|
delay(1000);
|
|
}
|
|
#endif
|
|
|
|
if (sdReady)
|
|
{
|
|
char *card_type = "UNKNOWN";
|
|
sdcard_type_t t = SD.cardType();
|
|
|
|
if (t == sdcard_type_t::CARD_MMC)
|
|
{
|
|
card_type = "MMC";
|
|
}
|
|
else if (t == sdcard_type_t::CARD_SD)
|
|
{
|
|
card_type = "SD";
|
|
}
|
|
else if (t == sdcard_type_t::CARD_SDHC)
|
|
{
|
|
card_type = "SDHC";
|
|
}
|
|
|
|
Serial.printf("SD card %s is ready.\n", card_type);
|
|
}
|
|
|
|
if (!disable_u8g2)
|
|
{
|
|
beginDisplay();
|
|
}
|
|
|
|
beginWiFi();
|
|
|
|
#ifdef HAS_GPS
|
|
#ifdef T_BEAM_S3_BPF
|
|
find_gps = beginGPS();
|
|
#endif
|
|
#endif
|
|
|
|
Serial.println("init done . ");
|
|
}
|
|
|
|
void printResult(bool radio_online)
|
|
{
|
|
Serial.print("Radio : ");
|
|
Serial.println((radio_online) ? "+" : "-");
|
|
|
|
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
|
|
|
Serial.print("PSRAM : ");
|
|
Serial.println((psramFound()) ? "+" : "-");
|
|
|
|
Serial.print("Display : ");
|
|
Serial.println((u8g2) ? "+" : "-");
|
|
|
|
#ifdef HAS_SDCARD
|
|
Serial.print("Sd Card : ");
|
|
Serial.println((SD.cardSize() != 0) ? "+" : "-");
|
|
#endif
|
|
|
|
#ifdef HAS_PMU
|
|
Serial.print("Power : ");
|
|
Serial.println((PMU) ? "+" : "-");
|
|
#endif
|
|
|
|
#ifdef HAS_GPS
|
|
#ifdef T_BEAM_S3_BPF
|
|
Serial.print("GPS : ");
|
|
Serial.println((find_gps) ? "+" : "-");
|
|
#endif
|
|
#endif
|
|
|
|
if (u8g2)
|
|
{
|
|
|
|
u8g2->clearBuffer();
|
|
u8g2->setFont(u8g2_font_NokiaLargeBold_tf);
|
|
uint16_t str_w = u8g2->getStrWidth(BOARD_VARIANT_NAME);
|
|
u8g2->drawStr((u8g2->getWidth() - str_w) / 2, 16, BOARD_VARIANT_NAME);
|
|
u8g2->drawHLine(5, 21, u8g2->getWidth() - 5);
|
|
|
|
u8g2->drawStr(0, 38, "Disp:");
|
|
u8g2->drawStr(45, 38, (u8g2) ? "+" : "-");
|
|
|
|
#ifdef HAS_SDCARD
|
|
u8g2->drawStr(0, 54, "SD :");
|
|
u8g2->drawStr(45, 54, (SD.cardSize() != 0) ? "+" : "-");
|
|
#endif
|
|
|
|
u8g2->drawStr(62, 38, "Radio:");
|
|
u8g2->drawStr(120, 38, (radio_online) ? "+" : "-");
|
|
|
|
#ifdef HAS_PMU
|
|
u8g2->drawStr(62, 54, "Power:");
|
|
u8g2->drawStr(120, 54, (PMU) ? "+" : "-");
|
|
#endif
|
|
|
|
u8g2->sendBuffer();
|
|
|
|
delay(2000);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static uint8_t ledState = LOW;
|
|
static const uint32_t debounceDelay = 50;
|
|
static uint32_t lastDebounceTime = 0;
|
|
|
|
void flashLed()
|
|
{
|
|
#ifdef BOARD_LED
|
|
if ((millis() - lastDebounceTime) > debounceDelay)
|
|
{
|
|
ledState = !ledState;
|
|
if (ledState)
|
|
{
|
|
digitalWrite(BOARD_LED, LED_ON);
|
|
}
|
|
else
|
|
{
|
|
digitalWrite(BOARD_LED, !LED_ON);
|
|
}
|
|
lastDebounceTime = millis();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void scanDevices(TwoWire *w)
|
|
{
|
|
uint8_t err, addr;
|
|
int nDevices = 0;
|
|
uint32_t start = 0;
|
|
|
|
Serial.println("I2C Devices scanning");
|
|
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("\tFind BMX280 Sensor!");
|
|
break;
|
|
case 0x34:
|
|
Serial.println("\tFind AXP192/AXP2101 PMU!");
|
|
break;
|
|
case 0x3C:
|
|
Serial.println("\tFind SSD1306/SH1106 dispaly!");
|
|
break;
|
|
case 0x51:
|
|
Serial.println("\tFind PCF8563 RTC!");
|
|
break;
|
|
case 0x1C:
|
|
Serial.println("\tFind QMC6310 MAG Sensor!");
|
|
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 devices done.");
|
|
Serial.println("\n");
|
|
}
|
|
|
|
#ifdef HAS_GPS
|
|
bool beginGPS()
|
|
{
|
|
SerialGPS.begin(GPS_BAUD_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
|
|
bool result = false;
|
|
uint32_t startTimeout;
|
|
for (int i = 0; i < 3; ++i)
|
|
{
|
|
SerialGPS.write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
|
delay(5);
|
|
// Get version information
|
|
startTimeout = millis() + 3000;
|
|
Serial.print("Try to init L76K . Wait stop .");
|
|
while (SerialGPS.available())
|
|
{
|
|
Serial.print(".");
|
|
SerialGPS.readString();
|
|
if (millis() > startTimeout)
|
|
{
|
|
Serial.println("Wait L76K stop NMEA timeout!");
|
|
return false;
|
|
}
|
|
};
|
|
Serial.println();
|
|
SerialGPS.flush();
|
|
delay(200);
|
|
|
|
SerialGPS.write("$PCAS06,0*1B\r\n");
|
|
startTimeout = millis() + 500;
|
|
String ver = "";
|
|
while (!SerialGPS.available())
|
|
{
|
|
if (millis() > startTimeout)
|
|
{
|
|
Serial.println("Get L76K timeout!");
|
|
return false;
|
|
}
|
|
}
|
|
SerialGPS.setTimeout(10);
|
|
ver = SerialGPS.readStringUntil('\n');
|
|
if (ver.startsWith("$GPTXT,01,01,02"))
|
|
{
|
|
Serial.println("L76K GNSS init succeeded, using L76K GNSS Module\n");
|
|
result = true;
|
|
break;
|
|
}
|
|
delay(500);
|
|
}
|
|
// Initialize the L76K Chip, use GPS + GLONASS
|
|
SerialGPS.write("$PCAS04,5*1C\r\n");
|
|
delay(250);
|
|
// only ask for RMC and GGA
|
|
SerialGPS.write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
|
|
delay(250);
|
|
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
|
|
SerialGPS.write("$PCAS11,3*1E\r\n");
|
|
return result;
|
|
}
|
|
#endif
|
|
#endif // #ifdef LILYGO
|