mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-22 10:42:49 +00:00
Merge remote-tracking branch 'upstream/develop' into multi-message-Storage
This commit is contained in:
2
.github/workflows/pr_enforce_labels.yml
vendored
2
.github/workflows/pr_enforce_labels.yml
vendored
@@ -10,7 +10,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-label:
|
check-label:
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check for PR labels
|
- name: Check for PR labels
|
||||||
uses: actions/github-script@v8
|
uses: actions/github-script@v8
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ plugins:
|
|||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- checkov@3.2.471
|
- checkov@3.2.471
|
||||||
- renovate@41.115.6
|
- renovate@41.118.1
|
||||||
- prettier@3.6.2
|
- prettier@3.6.2
|
||||||
- trufflehog@3.90.6
|
- trufflehog@3.90.8
|
||||||
- yamllint@1.37.1
|
- yamllint@1.37.1
|
||||||
- bandit@1.8.6
|
- bandit@1.8.6
|
||||||
- trivy@0.66.0
|
- trivy@0.66.0
|
||||||
- taplo@0.10.0
|
- taplo@0.10.0
|
||||||
- ruff@0.13.0
|
- ruff@0.13.1
|
||||||
- isort@6.0.1
|
- isort@6.0.1
|
||||||
- markdownlint@0.45.0
|
- markdownlint@0.45.0
|
||||||
- oxipng@9.1.5
|
- oxipng@9.1.5
|
||||||
@@ -26,7 +26,7 @@ lint:
|
|||||||
- hadolint@2.13.1
|
- hadolint@2.13.1
|
||||||
- shfmt@3.6.0
|
- shfmt@3.6.0
|
||||||
- shellcheck@0.11.0
|
- shellcheck@0.11.0
|
||||||
- black@25.1.0
|
- black@25.9.0
|
||||||
- git-diff-check
|
- git-diff-check
|
||||||
- gitleaks@8.28.0
|
- gitleaks@8.28.0
|
||||||
- clang-format@16.0.3
|
- clang-format@16.0.3
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
[portduino_base]
|
[portduino_base]
|
||||||
platform =
|
platform =
|
||||||
# renovate: datasource=git-refs depName=platform-native packageName=https://github.com/meshtastic/platform-native gitBranch=develop
|
# renovate: datasource=git-refs depName=platform-native packageName=https://github.com/meshtastic/platform-native gitBranch=develop
|
||||||
https://github.com/meshtastic/platform-native/archive/c490bcd019e0658404088a61b96e653c9da22c45.zip
|
https://github.com/meshtastic/platform-native/archive/d3f6e339534233c7217818867368767590ce549e.zip
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
|
|||||||
43
boards/heltec_v4.json
Normal file
43
boards/heltec_v4.json
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"ldscript": "esp32s3_out.ld",
|
||||||
|
"partitions": "default_16MB.csv",
|
||||||
|
"memory_type": "qio_qspi"
|
||||||
|
},
|
||||||
|
"core": "esp32",
|
||||||
|
"extra_flags": [
|
||||||
|
"-DBOARD_HAS_PSRAM",
|
||||||
|
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||||
|
"-DARDUINO_USB_MODE=0",
|
||||||
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
|
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||||
|
],
|
||||||
|
"f_cpu": "240000000L",
|
||||||
|
"f_flash": "80000000L",
|
||||||
|
"flash_mode": "qio",
|
||||||
|
"psram_type": "qspi",
|
||||||
|
"hwids": [["0x303A", "0x1001"]],
|
||||||
|
"mcu": "esp32s3",
|
||||||
|
"variant": "heltec_v4"
|
||||||
|
},
|
||||||
|
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||||
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": ["esp-builtin"],
|
||||||
|
"openocd_target": "esp32s3.cfg"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino", "espidf"],
|
||||||
|
"name": "heltec_wifi_lora_32 v4 (16 MB FLASH, 2 MB PSRAM)",
|
||||||
|
"upload": {
|
||||||
|
"flash_size": "16MB",
|
||||||
|
"maximum_ram_size": 2097152,
|
||||||
|
"maximum_size": 16777216,
|
||||||
|
"use_1200bps_touch": true,
|
||||||
|
"wait_for_upload_port": true,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"speed": 921600
|
||||||
|
},
|
||||||
|
"url": "https://heltec.org/",
|
||||||
|
"vendor": "heltec"
|
||||||
|
}
|
||||||
@@ -114,7 +114,7 @@ lib_deps =
|
|||||||
[radiolib_base]
|
[radiolib_base]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
# renovate: datasource=custom.pio depName=RadioLib packageName=jgromes/library/RadioLib
|
# renovate: datasource=custom.pio depName=RadioLib packageName=jgromes/library/RadioLib
|
||||||
jgromes/RadioLib@7.2.1
|
jgromes/RadioLib@7.3.0
|
||||||
|
|
||||||
[device-ui_base]
|
[device-ui_base]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
|
|||||||
@@ -85,6 +85,11 @@ extern uint16_t TFT_MESH;
|
|||||||
#include "platform/portduino/PortduinoGlue.h"
|
#include "platform/portduino/PortduinoGlue.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(T_LORA_PAGER)
|
||||||
|
// KB backlight control
|
||||||
|
#include "input/cardKbI2cImpl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace meshtastic; /** @todo remove */
|
using namespace meshtastic; /** @todo remove */
|
||||||
|
|
||||||
namespace graphics
|
namespace graphics
|
||||||
@@ -660,6 +665,19 @@ void Screen::setup()
|
|||||||
MeshModule::observeUIEvents(&uiFrameEventObserver);
|
MeshModule::observeUIEvents(&uiFrameEventObserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Screen::setOn(bool on, FrameCallback einkScreensaver)
|
||||||
|
{
|
||||||
|
#if defined(T_LORA_PAGER)
|
||||||
|
if (cardKbI2cImpl)
|
||||||
|
cardKbI2cImpl->toggleBacklight(on);
|
||||||
|
#endif
|
||||||
|
if (!on)
|
||||||
|
// We handle off commands immediately, because they might be called because the CPU is shutting down
|
||||||
|
handleSetOn(false, einkScreensaver);
|
||||||
|
else
|
||||||
|
enqueueCmd(ScreenCmd{.cmd = Cmd::SET_ON});
|
||||||
|
}
|
||||||
|
|
||||||
void Screen::forceDisplay(bool forceUiUpdate)
|
void Screen::forceDisplay(bool forceUiUpdate)
|
||||||
{
|
{
|
||||||
// Nasty hack to force epaper updates for 'key' frames. FIXME, cleanup.
|
// Nasty hack to force epaper updates for 'key' frames. FIXME, cleanup.
|
||||||
|
|||||||
@@ -259,15 +259,7 @@ class Screen : public concurrency::OSThread
|
|||||||
void setup();
|
void setup();
|
||||||
|
|
||||||
/// Turns the screen on/off. Optionally, pass a custom screensaver frame for E-Ink
|
/// Turns the screen on/off. Optionally, pass a custom screensaver frame for E-Ink
|
||||||
void setOn(bool on, FrameCallback einkScreensaver = NULL)
|
void setOn(bool on, FrameCallback einkScreensaver = NULL);
|
||||||
{
|
|
||||||
if (!on)
|
|
||||||
// We handle off commands immediately, because they might be called because the CPU is shutting down
|
|
||||||
handleSetOn(false, einkScreensaver);
|
|
||||||
else
|
|
||||||
enqueueCmd(ScreenCmd{.cmd = Cmd::SET_ON});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the display for the unit going to the lowest power mode possible. Most screens will just
|
* Prepare the display for the unit going to the lowest power mode possible. Most screens will just
|
||||||
* poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code
|
* poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code
|
||||||
|
|||||||
@@ -33,19 +33,21 @@ uint8_t test_count = 0;
|
|||||||
|
|
||||||
void menuHandler::loraMenu()
|
void menuHandler::loraMenu()
|
||||||
{
|
{
|
||||||
static const char *optionsArray[] = {"Back", "Region Picker", "Device Role"};
|
static const char *optionsArray[] = {"Back", "Device Role", "Radio Preset", "LoRa Region"};
|
||||||
enum optionsNumbers { Back = 0, lora_picker = 1, device_role_picker = 2 };
|
enum optionsNumbers { Back = 0, device_role_picker = 1, radio_preset_picker = 2, lora_picker = 3 };
|
||||||
BannerOverlayOptions bannerOptions;
|
BannerOverlayOptions bannerOptions;
|
||||||
bannerOptions.message = "LoRa Actions";
|
bannerOptions.message = "LoRa Actions";
|
||||||
bannerOptions.optionsArrayPtr = optionsArray;
|
bannerOptions.optionsArrayPtr = optionsArray;
|
||||||
bannerOptions.optionsCount = 3;
|
bannerOptions.optionsCount = 4;
|
||||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||||
if (selected == Back) {
|
if (selected == Back) {
|
||||||
// No action
|
// No action
|
||||||
} else if (selected == lora_picker) {
|
|
||||||
menuHandler::menuQueue = menuHandler::lora_picker;
|
|
||||||
} else if (selected == device_role_picker) {
|
} else if (selected == device_role_picker) {
|
||||||
menuHandler::menuQueue = menuHandler::device_role_picker;
|
menuHandler::menuQueue = menuHandler::device_role_picker;
|
||||||
|
} else if (selected == radio_preset_picker) {
|
||||||
|
menuHandler::menuQueue = menuHandler::radio_preset_picker;
|
||||||
|
} else if (selected == lora_picker) {
|
||||||
|
menuHandler::menuQueue = menuHandler::lora_picker;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
screen->showOverlayBanner(bannerOptions);
|
screen->showOverlayBanner(bannerOptions);
|
||||||
@@ -182,6 +184,53 @@ void menuHandler::DeviceRolePicker()
|
|||||||
screen->showOverlayBanner(bannerOptions);
|
screen->showOverlayBanner(bannerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void menuHandler::RadioPresetPicker()
|
||||||
|
{
|
||||||
|
static const char *optionsArray[] = {"Back", "LongSlow", "LongModerate", "LongFast", "MediumSlow",
|
||||||
|
"MediumFast", "ShortSlow", "ShortFast", "ShortTurbo"};
|
||||||
|
enum optionsNumbers {
|
||||||
|
Back = 0,
|
||||||
|
radiopreset_LongSlow = 1,
|
||||||
|
radiopreset_LongModerate = 2,
|
||||||
|
radiopreset_LongFast = 3,
|
||||||
|
radiopreset_MediumSlow = 4,
|
||||||
|
radiopreset_MediumFast = 5,
|
||||||
|
radiopreset_ShortSlow = 6,
|
||||||
|
radiopreset_ShortFast = 7,
|
||||||
|
radiopreset_ShortTurbo = 8
|
||||||
|
};
|
||||||
|
BannerOverlayOptions bannerOptions;
|
||||||
|
bannerOptions.message = "Radio Preset";
|
||||||
|
bannerOptions.optionsArrayPtr = optionsArray;
|
||||||
|
bannerOptions.optionsCount = 9;
|
||||||
|
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||||
|
if (selected == Back) {
|
||||||
|
menuHandler::menuQueue = menuHandler::lora_Menu;
|
||||||
|
screen->runNow();
|
||||||
|
return;
|
||||||
|
} else if (selected == radiopreset_LongSlow) {
|
||||||
|
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW;
|
||||||
|
} else if (selected == radiopreset_LongModerate) {
|
||||||
|
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE;
|
||||||
|
} else if (selected == radiopreset_LongFast) {
|
||||||
|
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
|
||||||
|
} else if (selected == radiopreset_MediumSlow) {
|
||||||
|
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW;
|
||||||
|
} else if (selected == radiopreset_MediumFast) {
|
||||||
|
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST;
|
||||||
|
} else if (selected == radiopreset_ShortSlow) {
|
||||||
|
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW;
|
||||||
|
} else if (selected == radiopreset_ShortFast) {
|
||||||
|
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST;
|
||||||
|
} else if (selected == radiopreset_ShortTurbo) {
|
||||||
|
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO;
|
||||||
|
}
|
||||||
|
service->reloadConfig(SEGMENT_CONFIG);
|
||||||
|
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
|
||||||
|
};
|
||||||
|
screen->showOverlayBanner(bannerOptions);
|
||||||
|
}
|
||||||
|
|
||||||
void menuHandler::TwelveHourPicker()
|
void menuHandler::TwelveHourPicker()
|
||||||
{
|
{
|
||||||
static const char *optionsArray[] = {"Back", "12-hour", "24-hour"};
|
static const char *optionsArray[] = {"Back", "12-hour", "24-hour"};
|
||||||
@@ -1667,6 +1716,9 @@ void menuHandler::handleMenuSwitch(OLEDDisplay *display)
|
|||||||
case device_role_picker:
|
case device_role_picker:
|
||||||
DeviceRolePicker();
|
DeviceRolePicker();
|
||||||
break;
|
break;
|
||||||
|
case radio_preset_picker:
|
||||||
|
RadioPresetPicker();
|
||||||
|
break;
|
||||||
case no_timeout_lora_picker:
|
case no_timeout_lora_picker:
|
||||||
LoraRegionPicker(0);
|
LoraRegionPicker(0);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class menuHandler
|
|||||||
lora_Menu,
|
lora_Menu,
|
||||||
lora_picker,
|
lora_picker,
|
||||||
device_role_picker,
|
device_role_picker,
|
||||||
|
radio_preset_picker,
|
||||||
no_timeout_lora_picker,
|
no_timeout_lora_picker,
|
||||||
TZ_picker,
|
TZ_picker,
|
||||||
twelve_hour_picker,
|
twelve_hour_picker,
|
||||||
@@ -52,6 +53,7 @@ class menuHandler
|
|||||||
static void LoraRegionPicker(uint32_t duration = 30000);
|
static void LoraRegionPicker(uint32_t duration = 30000);
|
||||||
static void loraMenu();
|
static void loraMenu();
|
||||||
static void DeviceRolePicker();
|
static void DeviceRolePicker();
|
||||||
|
static void RadioPresetPicker();
|
||||||
static void handleMenuSwitch(OLEDDisplay *display);
|
static void handleMenuSwitch(OLEDDisplay *display);
|
||||||
static void showConfirmationBanner(const char *message, std::function<void()> onConfirm);
|
static void showConfirmationBanner(const char *message, std::function<void()> onConfirm);
|
||||||
static void clockMenu();
|
static void clockMenu();
|
||||||
|
|||||||
@@ -287,9 +287,7 @@ const uint8_t digital_icon_clock[] PROGMEM = {0b00111100, 0b01000010, 0b10000101
|
|||||||
#define analog_icon_clock_height 8
|
#define analog_icon_clock_height 8
|
||||||
const uint8_t analog_icon_clock[] PROGMEM = {0b11111111, 0b01000010, 0b00100100, 0b00011000,
|
const uint8_t analog_icon_clock[] PROGMEM = {0b11111111, 0b01000010, 0b00100100, 0b00011000,
|
||||||
0b00100100, 0b01000010, 0b01000010, 0b11111111};
|
0b00100100, 0b01000010, 0b01000010, 0b11111111};
|
||||||
#ifdef M5STACK_UNITC6L
|
|
||||||
#include "img/icon_small.xbm"
|
|
||||||
#else
|
|
||||||
#define chirpy_width 38
|
#define chirpy_width 38
|
||||||
#define chirpy_height 50
|
#define chirpy_height 50
|
||||||
const uint8_t chirpy[] = {
|
const uint8_t chirpy[] = {
|
||||||
@@ -362,6 +360,9 @@ const uint8_t chirpy_hirez[] = {
|
|||||||
#define chirpy_small_image_height 8
|
#define chirpy_small_image_height 8
|
||||||
const uint8_t chirpy_small[] = {0x7f, 0x41, 0x55, 0x55, 0x55, 0x55, 0x41, 0x7f};
|
const uint8_t chirpy_small[] = {0x7f, 0x41, 0x55, 0x55, 0x55, 0x55, 0x41, 0x7f};
|
||||||
|
|
||||||
|
#ifdef M5STACK_UNITC6L
|
||||||
|
#include "img/icon_small.xbm"
|
||||||
|
#else
|
||||||
#include "img/icon.xbm"
|
#include "img/icon.xbm"
|
||||||
#endif
|
#endif
|
||||||
static_assert(sizeof(icon_bits) >= 0, "Silence unused variable warning");
|
static_assert(sizeof(icon_bits) >= 0, "Silence unused variable warning");
|
||||||
@@ -27,7 +27,7 @@ void RotaryEncoderInterruptBase::init(
|
|||||||
|
|
||||||
if (!isRAK || pinPress != 0) {
|
if (!isRAK || pinPress != 0) {
|
||||||
pinMode(pinPress, INPUT_PULLUP);
|
pinMode(pinPress, INPUT_PULLUP);
|
||||||
attachInterrupt(pinPress, onIntPress, RISING);
|
attachInterrupt(pinPress, onIntPress, CHANGE);
|
||||||
}
|
}
|
||||||
if (!isRAK || this->_pinA != 0) {
|
if (!isRAK || this->_pinA != 0) {
|
||||||
pinMode(this->_pinA, INPUT_PULLUP);
|
pinMode(this->_pinA, INPUT_PULLUP);
|
||||||
|
|||||||
@@ -200,6 +200,11 @@ uint8_t TCA8418KeyboardBase::flush()
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TCA8418KeyboardBase::clearInt()
|
||||||
|
{
|
||||||
|
writeRegister(TCA8418_REG_INT_STAT, 3);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t TCA8418KeyboardBase::digitalRead(uint8_t pinnum) const
|
uint8_t TCA8418KeyboardBase::digitalRead(uint8_t pinnum) const
|
||||||
{
|
{
|
||||||
if (pinnum > TCA8418_COL9)
|
if (pinnum > TCA8418_COL9)
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ class TCA8418KeyboardBase
|
|||||||
virtual void begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr = TCA8418_KB_ADDR);
|
virtual void begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr = TCA8418_KB_ADDR);
|
||||||
|
|
||||||
virtual void reset(void);
|
virtual void reset(void);
|
||||||
|
void clearInt(void);
|
||||||
|
|
||||||
virtual void trigger(void);
|
virtual void trigger(void);
|
||||||
|
|
||||||
virtual void setBacklight(bool on);
|
virtual void setBacklight(bool on);
|
||||||
|
|||||||
@@ -105,7 +105,14 @@ void TLoraPagerKeyboard::trigger()
|
|||||||
|
|
||||||
void TLoraPagerKeyboard::setBacklight(bool on)
|
void TLoraPagerKeyboard::setBacklight(bool on)
|
||||||
{
|
{
|
||||||
toggleBacklight(!on);
|
uint32_t _brightness = 0;
|
||||||
|
if (on)
|
||||||
|
_brightness = brightness;
|
||||||
|
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||||
|
ledcWrite(KB_BL_PIN, _brightness);
|
||||||
|
#else
|
||||||
|
ledcWrite(LEDC_BACKLIGHT_CHANNEL, _brightness);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLoraPagerKeyboard::pressed(uint8_t key)
|
void TLoraPagerKeyboard::pressed(uint8_t key)
|
||||||
@@ -192,7 +199,6 @@ void TLoraPagerKeyboard::hapticFeedback()
|
|||||||
// toggle brightness of the backlight in three steps
|
// toggle brightness of the backlight in three steps
|
||||||
void TLoraPagerKeyboard::toggleBacklight(bool off)
|
void TLoraPagerKeyboard::toggleBacklight(bool off)
|
||||||
{
|
{
|
||||||
static uint32_t brightness = 0;
|
|
||||||
if (off) {
|
if (off) {
|
||||||
brightness = 0;
|
brightness = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -206,11 +212,7 @@ void TLoraPagerKeyboard::toggleBacklight(bool off)
|
|||||||
}
|
}
|
||||||
LOG_DEBUG("Toggle backlight: %d", brightness);
|
LOG_DEBUG("Toggle backlight: %d", brightness);
|
||||||
|
|
||||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
setBacklight(true);
|
||||||
ledcWrite(KB_BL_PIN, brightness);
|
|
||||||
#else
|
|
||||||
ledcWrite(LEDC_BACKLIGHT_CHANNEL, brightness);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLoraPagerKeyboard::updateModifierFlag(uint8_t key)
|
void TLoraPagerKeyboard::updateModifierFlag(uint8_t key)
|
||||||
|
|||||||
@@ -26,4 +26,5 @@ class TLoraPagerKeyboard : public TCA8418KeyboardBase
|
|||||||
uint32_t last_tap;
|
uint32_t last_tap;
|
||||||
uint8_t char_idx;
|
uint8_t char_idx;
|
||||||
int32_t tap_interval;
|
int32_t tap_interval;
|
||||||
|
uint32_t brightness = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -333,6 +333,7 @@ int32_t KbI2cBase::runOnce()
|
|||||||
}
|
}
|
||||||
TCAKeyboard.trigger();
|
TCAKeyboard.trigger();
|
||||||
}
|
}
|
||||||
|
TCAKeyboard.clearInt();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x02: {
|
case 0x02: {
|
||||||
@@ -519,4 +520,11 @@ int32_t KbI2cBase::runOnce()
|
|||||||
LOG_WARN("Unknown kb_model 0x%02x", kb_model);
|
LOG_WARN("Unknown kb_model 0x%02x", kb_model);
|
||||||
}
|
}
|
||||||
return 300;
|
return 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KbI2cBase::toggleBacklight(bool on)
|
||||||
|
{
|
||||||
|
#if defined(T_LORA_PAGER)
|
||||||
|
TCAKeyboard.setBacklight(on);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OST
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit KbI2cBase(const char *name);
|
explicit KbI2cBase(const char *name);
|
||||||
|
void toggleBacklight(bool on);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int32_t runOnce() override;
|
virtual int32_t runOnce() override;
|
||||||
|
|||||||
@@ -369,6 +369,7 @@ void setup()
|
|||||||
digitalWrite(SDCARD_CS, HIGH);
|
digitalWrite(SDCARD_CS, HIGH);
|
||||||
pinMode(TFT_CS, OUTPUT);
|
pinMode(TFT_CS, OUTPUT);
|
||||||
digitalWrite(TFT_CS, HIGH);
|
digitalWrite(TFT_CS, HIGH);
|
||||||
|
pinMode(KB_INT, INPUT_PULLUP);
|
||||||
// io expander
|
// io expander
|
||||||
io.begin(Wire, XL9555_SLAVE_ADDRESS0, SDA, SCL);
|
io.begin(Wire, XL9555_SLAVE_ADDRESS0, SDA, SCL);
|
||||||
io.pinMode(EXPANDS_DRV_EN, OUTPUT);
|
io.pinMode(EXPANDS_DRV_EN, OUTPUT);
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ NodeDB::NodeDB()
|
|||||||
|
|
||||||
int saveWhat = 0;
|
int saveWhat = 0;
|
||||||
// Get device unique id
|
// Get device unique id
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||||
uint32_t unique_id[4];
|
uint32_t unique_id[4];
|
||||||
// ESP32 factory burns a unique id in efuse for S2+ series and evidently C3+ series
|
// ESP32 factory burns a unique id in efuse for S2+ series and evidently C3+ series
|
||||||
// This is used for HMACs in the esp-rainmaker AIOT platform and seems to be a good choice for us
|
// This is used for HMACs in the esp-rainmaker AIOT platform and seems to be a good choice for us
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
if (config_nonce == SPECIAL_NONCE_ONLY_NODES) {
|
if (config_nonce == SPECIAL_NONCE_ONLY_NODES) {
|
||||||
// If client only wants node info, jump directly to sending nodes
|
// If client only wants node info, jump directly to sending nodes
|
||||||
state = STATE_SEND_OTHER_NODEINFOS;
|
state = STATE_SEND_OTHER_NODEINFOS;
|
||||||
|
onNowHasData(0);
|
||||||
} else {
|
} else {
|
||||||
state = STATE_SEND_METADATA;
|
state = STATE_SEND_METADATA;
|
||||||
}
|
}
|
||||||
@@ -423,6 +424,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
state = STATE_SEND_FILEMANIFEST;
|
state = STATE_SEND_FILEMANIFEST;
|
||||||
} else {
|
} else {
|
||||||
state = STATE_SEND_OTHER_NODEINFOS;
|
state = STATE_SEND_OTHER_NODEINFOS;
|
||||||
|
onNowHasData(0);
|
||||||
}
|
}
|
||||||
config_state = 0;
|
config_state = 0;
|
||||||
}
|
}
|
||||||
@@ -588,6 +590,7 @@ bool PhoneAPI::available()
|
|||||||
nodeInfoForPhone.snr = isUs ? 0 : nodeInfoForPhone.snr;
|
nodeInfoForPhone.snr = isUs ? 0 : nodeInfoForPhone.snr;
|
||||||
nodeInfoForPhone.via_mqtt = isUs ? false : nodeInfoForPhone.via_mqtt;
|
nodeInfoForPhone.via_mqtt = isUs ? false : nodeInfoForPhone.via_mqtt;
|
||||||
nodeInfoForPhone.is_favorite = nodeInfoForPhone.is_favorite || isUs; // Our node is always a favorite
|
nodeInfoForPhone.is_favorite = nodeInfoForPhone.is_favorite || isUs; // Our node is always a favorite
|
||||||
|
onNowHasData(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true; // Always say we have something, because we might need to advance our state machine
|
return true; // Always say we have something, because we might need to advance our state machine
|
||||||
|
|||||||
@@ -52,6 +52,16 @@ template <typename T> bool SX126xInterface<T>::init()
|
|||||||
pinMode(SX126X_POWER_EN, OUTPUT);
|
pinMode(SX126X_POWER_EN, OUTPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HELTEC_V4
|
||||||
|
pinMode(LORA_PA_POWER, OUTPUT);
|
||||||
|
digitalWrite(LORA_PA_POWER, HIGH);
|
||||||
|
|
||||||
|
pinMode(LORA_PA_EN, OUTPUT);
|
||||||
|
digitalWrite(LORA_PA_EN, LOW);
|
||||||
|
pinMode(LORA_PA_TX_EN, OUTPUT);
|
||||||
|
digitalWrite(LORA_PA_TX_EN, LOW);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
tcxoVoltage = (float)portduino_config.dio3_tcxo_voltage / 1000;
|
tcxoVoltage = (float)portduino_config.dio3_tcxo_voltage / 1000;
|
||||||
if (portduino_config.lora_sx126x_ant_sw_pin.pin != RADIOLIB_NC) {
|
if (portduino_config.lora_sx126x_ant_sw_pin.pin != RADIOLIB_NC) {
|
||||||
@@ -63,7 +73,7 @@ template <typename T> bool SX126xInterface<T>::init()
|
|||||||
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage");
|
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage");
|
||||||
else
|
else
|
||||||
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V", tcxoVoltage);
|
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V", tcxoVoltage);
|
||||||
|
setTransmitEnable(false);
|
||||||
// FIXME: May want to set depending on a definition, currently all SX126x variant files use the DC-DC regulator option
|
// FIXME: May want to set depending on a definition, currently all SX126x variant files use the DC-DC regulator option
|
||||||
bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
|
bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
|
||||||
|
|
||||||
@@ -259,6 +269,7 @@ template <typename T> void SX126xInterface<T>::addReceiveMetadata(meshtastic_Mes
|
|||||||
*/
|
*/
|
||||||
template <typename T> void SX126xInterface<T>::configHardwareForSend()
|
template <typename T> void SX126xInterface<T>::configHardwareForSend()
|
||||||
{
|
{
|
||||||
|
setTransmitEnable(true);
|
||||||
RadioLibInterface::configHardwareForSend();
|
RadioLibInterface::configHardwareForSend();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,6 +282,7 @@ template <typename T> void SX126xInterface<T>::startReceive()
|
|||||||
sleep();
|
sleep();
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
setTransmitEnable(false);
|
||||||
setStandby();
|
setStandby();
|
||||||
|
|
||||||
// We use a 16 bit preamble so this should save some power by letting radio sit in standby mostly.
|
// We use a 16 bit preamble so this should save some power by letting radio sit in standby mostly.
|
||||||
@@ -298,7 +310,7 @@ template <typename T> bool SX126xInterface<T>::isChannelActive()
|
|||||||
.irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS,
|
.irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS,
|
||||||
.irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK}};
|
.irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK}};
|
||||||
int16_t result;
|
int16_t result;
|
||||||
|
setTransmitEnable(false);
|
||||||
setStandby();
|
setStandby();
|
||||||
result = lora.scanChannel(cfg);
|
result = lora.scanChannel(cfg);
|
||||||
if (result == RADIOLIB_LORA_DETECTED)
|
if (result == RADIOLIB_LORA_DETECTED)
|
||||||
@@ -337,6 +349,26 @@ template <typename T> bool SX126xInterface<T>::sleep()
|
|||||||
digitalWrite(SX126X_POWER_EN, LOW);
|
digitalWrite(SX126X_POWER_EN, LOW);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HELTEC_V4
|
||||||
|
/*
|
||||||
|
* Do not switch the power on and off frequently.
|
||||||
|
* After turning off LORA_PA_EN, the power consumption has dropped to the uA level.
|
||||||
|
* // digitalWrite(LORA_PA_POWER, LOW);
|
||||||
|
*/
|
||||||
|
digitalWrite(LORA_PA_EN, LOW);
|
||||||
|
digitalWrite(LORA_PA_TX_EN, LOW);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Some boards require GPIO control of tx vs rx paths */
|
||||||
|
template <typename T> void SX126xInterface<T>::setTransmitEnable(bool txon)
|
||||||
|
{
|
||||||
|
#ifdef HELTEC_V4
|
||||||
|
digitalWrite(LORA_PA_POWER, HIGH);
|
||||||
|
digitalWrite(LORA_PA_EN, HIGH);
|
||||||
|
digitalWrite(LORA_PA_TX_EN, txon ? 1 : 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -71,5 +71,9 @@ template <class T> class SX126xInterface : public RadioLibInterface
|
|||||||
virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) override;
|
virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) override;
|
||||||
|
|
||||||
virtual void setStandby() override;
|
virtual void setStandby() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Some boards require GPIO control of tx vs rx paths */
|
||||||
|
void setTransmitEnable(bool txon);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@@ -293,9 +293,7 @@ void setupModules()
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
|
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
|
||||||
if (moduleConfig.has_external_notification && moduleConfig.external_notification.enabled) {
|
externalNotificationModule = new ExternalNotificationModule();
|
||||||
externalNotificationModule = new ExternalNotificationModule();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#if !MESHTASTIC_EXCLUDE_RANGETEST && !MESHTASTIC_EXCLUDE_GPS
|
#if !MESHTASTIC_EXCLUDE_RANGETEST && !MESHTASTIC_EXCLUDE_GPS
|
||||||
if (moduleConfig.has_range_test && moduleConfig.range_test.enabled)
|
if (moduleConfig.has_range_test && moduleConfig.range_test.enabled)
|
||||||
|
|||||||
@@ -174,11 +174,11 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
|||||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||||
display->setFont(FONT_MEDIUM);
|
display->setFont(FONT_MEDIUM);
|
||||||
display->drawString(x_offset + x, y_offset + y, "Bluetooth");
|
display->drawString(x_offset + x, y_offset + y, "Bluetooth");
|
||||||
|
#if !defined(M5STACK_UNITC6L)
|
||||||
display->setFont(FONT_SMALL);
|
display->setFont(FONT_SMALL);
|
||||||
y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM - 4 : y_offset + FONT_HEIGHT_MEDIUM + 5;
|
y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM - 4 : y_offset + FONT_HEIGHT_MEDIUM + 5;
|
||||||
display->drawString(x_offset + x, y_offset + y, "Enter this code");
|
display->drawString(x_offset + x, y_offset + y, "Enter this code");
|
||||||
|
#endif
|
||||||
display->setFont(FONT_LARGE);
|
display->setFont(FONT_LARGE);
|
||||||
char pin[8];
|
char pin[8];
|
||||||
snprintf(pin, sizeof(pin), "%.3s %.3s", btPIN, btPIN + 3);
|
snprintf(pin, sizeof(pin), "%.3s %.3s", btPIN, btPIN + 3);
|
||||||
|
|||||||
@@ -197,6 +197,8 @@
|
|||||||
#define HW_VENDOR meshtastic_HardwareModel_T_DECK_PRO
|
#define HW_VENDOR meshtastic_HardwareModel_T_DECK_PRO
|
||||||
#elif defined(T_LORA_PAGER)
|
#elif defined(T_LORA_PAGER)
|
||||||
#define HW_VENDOR meshtastic_HardwareModel_T_LORA_PAGER
|
#define HW_VENDOR meshtastic_HardwareModel_T_LORA_PAGER
|
||||||
|
#elif defined(HELTEC_V4)
|
||||||
|
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_V4
|
||||||
#elif defined(M5STACK_UNITC6L)
|
#elif defined(M5STACK_UNITC6L)
|
||||||
#define HW_VENDOR meshtastic_HardwareModel_M5STACK_C6L
|
#define HW_VENDOR meshtastic_HardwareModel_M5STACK_C6L
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -411,12 +411,16 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
|||||||
// assert(uart_set_wakeup_threshold(UART_NUM_0, 3) == ESP_OK);
|
// assert(uart_set_wakeup_threshold(UART_NUM_0, 3) == ESP_OK);
|
||||||
// assert(esp_sleep_enable_uart_wakeup(0) == ESP_OK);
|
// assert(esp_sleep_enable_uart_wakeup(0) == ESP_OK);
|
||||||
#endif
|
#endif
|
||||||
#ifdef BUTTON_PIN
|
#ifdef ROTARY_PRESS
|
||||||
// The enableLoraInterrupt() method is using ext0_wakeup, so we are forced to use GPIO wakeup
|
// The enableLoraInterrupt() method is using ext0_wakeup, so we are forced to use GPIO wakeup
|
||||||
|
gpio_wakeup_enable((gpio_num_t)ROTARY_PRESS, GPIO_INTR_LOW_LEVEL);
|
||||||
|
#endif
|
||||||
|
#ifdef KB_INT
|
||||||
|
gpio_wakeup_enable((gpio_num_t)KB_INT, GPIO_INTR_LOW_LEVEL);
|
||||||
|
#endif
|
||||||
|
#ifdef BUTTON_PIN
|
||||||
gpio_num_t pin = (gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
|
gpio_num_t pin = (gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
|
||||||
|
|
||||||
gpio_wakeup_enable(pin, GPIO_INTR_LOW_LEVEL);
|
gpio_wakeup_enable(pin, GPIO_INTR_LOW_LEVEL);
|
||||||
esp_sleep_enable_gpio_wakeup();
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef INPUTDRIVER_ENCODER_BTN
|
#ifdef INPUTDRIVER_ENCODER_BTN
|
||||||
gpio_wakeup_enable((gpio_num_t)INPUTDRIVER_ENCODER_BTN, GPIO_INTR_LOW_LEVEL);
|
gpio_wakeup_enable((gpio_num_t)INPUTDRIVER_ENCODER_BTN, GPIO_INTR_LOW_LEVEL);
|
||||||
@@ -450,7 +454,12 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
|||||||
// commented out because it's not that crucial;
|
// commented out because it's not that crucial;
|
||||||
// if it sporadically happens the node will go into light sleep during the next round
|
// if it sporadically happens the node will go into light sleep during the next round
|
||||||
// assert(res == ESP_OK);
|
// assert(res == ESP_OK);
|
||||||
|
#ifdef ROTARY_PRESS
|
||||||
|
gpio_wakeup_disable((gpio_num_t)ROTARY_PRESS);
|
||||||
|
#endif
|
||||||
|
#ifdef KB_INT
|
||||||
|
gpio_wakeup_disable((gpio_num_t)KB_INT);
|
||||||
|
#endif
|
||||||
#ifdef BUTTON_PIN
|
#ifdef BUTTON_PIN
|
||||||
// Disable wake-on-button interrupt. Re-attach normal button-interrupts
|
// Disable wake-on-button interrupt. Re-attach normal button-interrupts
|
||||||
gpio_wakeup_disable(pin);
|
gpio_wakeup_disable(pin);
|
||||||
@@ -545,6 +554,12 @@ void enableLoraInterrupt()
|
|||||||
gpio_pullup_en((gpio_num_t)LORA_CS);
|
gpio_pullup_en((gpio_num_t)LORA_CS);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HELTEC_V4
|
||||||
|
gpio_pullup_en((gpio_num_t)LORA_PA_POWER);
|
||||||
|
gpio_pullup_en((gpio_num_t)LORA_PA_EN);
|
||||||
|
gpio_pulldown_en((gpio_num_t)LORA_PA_TX_EN);
|
||||||
|
#endif
|
||||||
|
|
||||||
LOG_INFO("setup LORA_DIO1 (GPIO%02d) with wakeup by gpio interrupt", LORA_DIO1);
|
LOG_INFO("setup LORA_DIO1 (GPIO%02d) with wakeup by gpio interrupt", LORA_DIO1);
|
||||||
gpio_wakeup_enable((gpio_num_t)LORA_DIO1, GPIO_INTR_HIGH_LEVEL);
|
gpio_wakeup_enable((gpio_num_t)LORA_DIO1, GPIO_INTR_HIGH_LEVEL);
|
||||||
|
|
||||||
|
|||||||
70
variants/esp32s3/heltec_v4/pins_arduino.h
Normal file
70
variants/esp32s3/heltec_v4/pins_arduino.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#ifndef Pins_Arduino_h
|
||||||
|
#define Pins_Arduino_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define USB_VID 0x303a
|
||||||
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
|
static const uint8_t LED_BUILTIN = 35;
|
||||||
|
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||||
|
#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN
|
||||||
|
|
||||||
|
static const uint8_t TX = 43;
|
||||||
|
static const uint8_t RX = 44;
|
||||||
|
|
||||||
|
static const uint8_t SDA = 3;
|
||||||
|
static const uint8_t SCL = 4;
|
||||||
|
|
||||||
|
static const uint8_t SS = 8;
|
||||||
|
static const uint8_t MOSI = 10;
|
||||||
|
static const uint8_t MISO = 11;
|
||||||
|
static const uint8_t SCK = 9;
|
||||||
|
|
||||||
|
static const uint8_t A0 = 1;
|
||||||
|
static const uint8_t A1 = 2;
|
||||||
|
static const uint8_t A2 = 3;
|
||||||
|
static const uint8_t A3 = 4;
|
||||||
|
static const uint8_t A4 = 5;
|
||||||
|
static const uint8_t A5 = 6;
|
||||||
|
static const uint8_t A6 = 7;
|
||||||
|
static const uint8_t A7 = 8;
|
||||||
|
static const uint8_t A8 = 9;
|
||||||
|
static const uint8_t A9 = 10;
|
||||||
|
static const uint8_t A10 = 11;
|
||||||
|
static const uint8_t A11 = 12;
|
||||||
|
static const uint8_t A12 = 13;
|
||||||
|
static const uint8_t A13 = 14;
|
||||||
|
static const uint8_t A14 = 15;
|
||||||
|
static const uint8_t A15 = 16;
|
||||||
|
static const uint8_t A16 = 17;
|
||||||
|
static const uint8_t A17 = 18;
|
||||||
|
static const uint8_t A18 = 19;
|
||||||
|
static const uint8_t A19 = 20;
|
||||||
|
|
||||||
|
static const uint8_t T1 = 1;
|
||||||
|
static const uint8_t T2 = 2;
|
||||||
|
static const uint8_t T3 = 3;
|
||||||
|
static const uint8_t T4 = 4;
|
||||||
|
static const uint8_t T5 = 5;
|
||||||
|
static const uint8_t T6 = 6;
|
||||||
|
static const uint8_t T7 = 7;
|
||||||
|
static const uint8_t T8 = 8;
|
||||||
|
static const uint8_t T9 = 9;
|
||||||
|
static const uint8_t T10 = 10;
|
||||||
|
static const uint8_t T11 = 11;
|
||||||
|
static const uint8_t T12 = 12;
|
||||||
|
static const uint8_t T13 = 13;
|
||||||
|
static const uint8_t T14 = 14;
|
||||||
|
|
||||||
|
static const uint8_t Vext = 36;
|
||||||
|
static const uint8_t LED = 35;
|
||||||
|
static const uint8_t RST_OLED = 21;
|
||||||
|
static const uint8_t SCL_OLED = 18;
|
||||||
|
static const uint8_t SDA_OLED = 17;
|
||||||
|
|
||||||
|
static const uint8_t RST_LoRa = 12;
|
||||||
|
static const uint8_t BUSY_LoRa = 13;
|
||||||
|
static const uint8_t DIO0 = 14;
|
||||||
|
|
||||||
|
#endif /* Pins_Arduino_h */
|
||||||
10
variants/esp32s3/heltec_v4/platformio.ini
Normal file
10
variants/esp32s3/heltec_v4/platformio.ini
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[env:heltec-v4]
|
||||||
|
extends = esp32s3_base
|
||||||
|
board = heltec_v4
|
||||||
|
board_check = true
|
||||||
|
build_flags =
|
||||||
|
${esp32s3_base.build_flags}
|
||||||
|
-D HELTEC_V4
|
||||||
|
-I variants/esp32s3/heltec_v4
|
||||||
|
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||||
|
-D SX126X_MAX_POWER=11
|
||||||
58
variants/esp32s3/heltec_v4/variant.h
Normal file
58
variants/esp32s3/heltec_v4/variant.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#define LED_PIN 35
|
||||||
|
|
||||||
|
#define USE_SSD1306 // Heltec_v4 has an SSD1315 display (compatible with SSD1306 driver)
|
||||||
|
|
||||||
|
#define RESET_OLED 21
|
||||||
|
#define I2C_SDA 17 // I2C pins for this board
|
||||||
|
#define I2C_SCL 18
|
||||||
|
|
||||||
|
#define VEXT_ENABLE 36 // active low, powers the oled display and the lora antenna boost
|
||||||
|
#define BUTTON_PIN 0
|
||||||
|
|
||||||
|
#define ADC_CTRL 37
|
||||||
|
#define ADC_CTRL_ENABLED HIGH
|
||||||
|
#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||||
|
#define ADC_CHANNEL ADC1_GPIO1_CHANNEL
|
||||||
|
#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider
|
||||||
|
#define ADC_MULTIPLIER 4.9 * 1.045
|
||||||
|
|
||||||
|
#define USE_SX1262
|
||||||
|
|
||||||
|
#define LORA_DIO0 -1 // a No connect on the SX1262 module
|
||||||
|
#define LORA_RESET 12
|
||||||
|
#define LORA_DIO1 14 // SX1262 IRQ
|
||||||
|
#define LORA_DIO2 13 // SX1262 BUSY
|
||||||
|
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TCXO is enabled
|
||||||
|
|
||||||
|
#define LORA_SCK 9
|
||||||
|
#define LORA_MISO 11
|
||||||
|
#define LORA_MOSI 10
|
||||||
|
#define LORA_CS 8
|
||||||
|
|
||||||
|
#define SX126X_CS LORA_CS
|
||||||
|
#define SX126X_DIO1 LORA_DIO1
|
||||||
|
#define SX126X_BUSY LORA_DIO2
|
||||||
|
#define SX126X_RESET LORA_RESET
|
||||||
|
|
||||||
|
#define SX126X_DIO2_AS_RF_SWITCH
|
||||||
|
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||||
|
|
||||||
|
#define LORA_PA_POWER 7 // power en
|
||||||
|
#define LORA_PA_EN 2
|
||||||
|
#define LORA_PA_TX_EN 46 // enable tx
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPS pins
|
||||||
|
*/
|
||||||
|
#define GPS_L76K
|
||||||
|
#define PIN_GPS_RESET (42) // An output to reset L76K GPS. As per datasheet, low for > 100ms will reset the L76K
|
||||||
|
#define GPS_RESET_MODE LOW
|
||||||
|
#define PIN_GPS_EN (34)
|
||||||
|
#define GPS_EN_ACTIVE LOW
|
||||||
|
#define PERIPHERAL_WARMUP_MS 1000 // Make sure I2C QuickLink has stable power before continuing
|
||||||
|
#define PIN_GPS_STANDBY (40) // An output to wake GPS, low means allow sleep, high means force wake
|
||||||
|
#define PIN_GPS_PPS (41)
|
||||||
|
// Seems to be missing on this new board
|
||||||
|
#define GPS_TX_PIN (38) // This is for bits going TOWARDS the CPU
|
||||||
|
#define GPS_RX_PIN (39) // This is for bits going TOWARDS the GPS
|
||||||
|
#define GPS_THREAD_INTERVAL 50
|
||||||
@@ -16,3 +16,11 @@ lib_deps =
|
|||||||
debug_tool = jlink
|
debug_tool = jlink
|
||||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||||
;upload_protocol = jlink
|
;upload_protocol = jlink
|
||||||
|
|
||||||
|
; Seeed Xiao BLE but with GPS undefined, and therefore i2c active
|
||||||
|
[env:seeed_xiao_nrf52840_kit_i2c]
|
||||||
|
extends = env:seeed_xiao_nrf52840_kit
|
||||||
|
board_level = extra
|
||||||
|
build_flags = ${env:seeed_xiao_nrf52840_kit.build_flags}
|
||||||
|
-DSEEED_XIAO_NRF52840_KIT
|
||||||
|
build_unflags = -DGPS_L76K
|
||||||
|
|||||||
Reference in New Issue
Block a user