mirror of
https://github.com/meshtastic/firmware.git
synced 2026-06-06 07:45:42 -04:00
Merge branch 'develop' into boot-status
This commit is contained in:
@@ -8,15 +8,15 @@ plugins:
|
||||
uri: https://github.com/trunk-io/plugins
|
||||
lint:
|
||||
enabled:
|
||||
- checkov@3.2.524
|
||||
- renovate@43.141.0
|
||||
- checkov@3.2.525
|
||||
- renovate@43.142.0
|
||||
- prettier@3.8.3
|
||||
- trufflehog@3.95.2
|
||||
- yamllint@1.38.0
|
||||
- bandit@1.9.4
|
||||
- trivy@0.70.0
|
||||
- taplo@0.10.0
|
||||
- ruff@0.15.11
|
||||
- ruff@0.15.12
|
||||
- isort@8.0.1
|
||||
- markdownlint@0.48.0
|
||||
- oxipng@10.1.1
|
||||
|
||||
@@ -31,5 +31,6 @@ basename=meshtasticd-$1-$VERSION
|
||||
pio pkg install --environment "$PIO_ENV" || platformioFailed
|
||||
pio run --environment "$PIO_ENV" || platformioFailed
|
||||
|
||||
cp "$BUILDDIR/meshtasticd" "$OUTDIR/meshtasticd_linux_$(uname -m)"
|
||||
os_name=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||
cp "$BUILDDIR/meshtasticd" "$OUTDIR/meshtasticd_${os_name}_$(uname -m)"
|
||||
cp bin/native-install.* $OUTDIR/
|
||||
|
||||
43
boards/heltec_v4_r8.json
Normal file
43
boards/heltec_v4_r8.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_16MB.csv",
|
||||
"memory_type": "qio_opi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=1",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"psram_type": "opi",
|
||||
"hwids": [["0x303A", "0x1001"]],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "heltec_v4_r8"
|
||||
},
|
||||
"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 r8 (16 MB FLASH, 8 MB PSRAM)",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 16777216,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://heltec.org/",
|
||||
"vendor": "heltec"
|
||||
}
|
||||
@@ -125,7 +125,7 @@ lib_deps =
|
||||
[device-ui_base]
|
||||
lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
||||
https://github.com/meshtastic/device-ui/archive/56e1da4e7d30abcd746a2092a30e422f8cf5fc2b.zip
|
||||
https://github.com/meshtastic/device-ui/archive/728932970996ec91bdb93cb6dae29c2cb70c66e2.zip
|
||||
|
||||
; Common libs for environmental measurements in telemetry module
|
||||
[environmental_base]
|
||||
|
||||
@@ -781,8 +781,10 @@ void Power::reboot()
|
||||
rp2040.reboot();
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
deInitApiServer();
|
||||
#ifdef __linux__
|
||||
if (aLinuxInputImpl)
|
||||
aLinuxInputImpl->deInit();
|
||||
#endif
|
||||
SPI.end();
|
||||
Wire.end();
|
||||
Serial1.end();
|
||||
@@ -1000,11 +1002,8 @@ int32_t Power::runOnce()
|
||||
powerFSM.trigger(EVENT_POWER_CONNECTED);
|
||||
}
|
||||
|
||||
#ifdef T_WATCH_S3
|
||||
/*
|
||||
In the T-Watch S3 this code fragment reacts to the short press of the button by switching the
|
||||
display on and off
|
||||
*/
|
||||
#ifdef PMU_POWER_BUTTON_IS_CANCEL
|
||||
// cancel action also turns the screen on and off.
|
||||
if (PMU->isPekeyShortPressIrq()) {
|
||||
LOG_INFO("Input: Corona Button Click");
|
||||
InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_CANCEL, .kbchar = 0, .touchX = 0, .touchY = 0};
|
||||
@@ -1027,13 +1026,6 @@ int32_t Power::runOnce()
|
||||
LOG_DEBUG("Battery removed");
|
||||
}
|
||||
*/
|
||||
#ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3?
|
||||
if (PMU->isPekeyLongPressIrq()) {
|
||||
LOG_DEBUG("PEK long button press");
|
||||
if (screen)
|
||||
screen->setOn(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
PMU->clearIrqStatus();
|
||||
}
|
||||
@@ -1102,7 +1094,7 @@ void Power::attachPowerInterrupts()
|
||||
if (PMU) {
|
||||
attachInterrupt(
|
||||
PMU_IRQ,
|
||||
[] {
|
||||
[]() {
|
||||
pmu_irq = true;
|
||||
power->setIntervalFromNow(0);
|
||||
runASAP = true;
|
||||
@@ -1405,19 +1397,16 @@ bool Power::axpChipInit()
|
||||
uint64_t pmuIrqMask = 0;
|
||||
|
||||
if (PMU->getChipModel() == XPOWERS_AXP192) {
|
||||
pmuIrqMask = XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_PKEY_SHORT_IRQ;
|
||||
pmuIrqMask = XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_VBUS_REMOVE_IRQ | XPOWERS_AXP192_PKEY_SHORT_IRQ;
|
||||
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
|
||||
pmuIrqMask = XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_PKEY_SHORT_IRQ;
|
||||
pmuIrqMask = XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | XPOWERS_AXP2101_PKEY_SHORT_IRQ;
|
||||
}
|
||||
|
||||
pinMode(PMU_IRQ, INPUT);
|
||||
|
||||
// we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_CHARGING_IRQ
|
||||
// because it occurs repeatedly while there is no battery also it could cause
|
||||
// inadvertent waking from light sleep just because the battery filled we
|
||||
// don't look for AXPXXX_BATT_REMOVED_IRQ because it occurs repeatedly while
|
||||
// no battery installed we don't look at AXPXXX_VBUS_REMOVED_IRQ because we
|
||||
// don't have anything hooked to vbus
|
||||
// We wake on IRQ, so only enable the IRQs that we care about.
|
||||
// we want USB plug and unplug to update the screen and LED status,
|
||||
// and short press on the power button to trigger the "cancel" action in the UI (which also turns the screen on and off).
|
||||
PMU->enableIRQ(pmuIrqMask);
|
||||
|
||||
PMU->clearIrqStatus();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "../freertosinc.h"
|
||||
#include "Print.h"
|
||||
#include "mesh/generated/meshtastic/mesh.pb.h"
|
||||
#include <Print.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -162,6 +162,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#elif defined(HELTEC_MESH_NODE_T096)
|
||||
#define NUM_PA_POINTS 22
|
||||
#define TX_GAIN_LORA 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 12, 11, 10, 9, 8, 7
|
||||
#elif defined(HELTEC_V4_R8)
|
||||
#define NUM_PA_POINTS 22
|
||||
#define TX_GAIN_LORA 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 11, 11, 10, 9, 8, 7
|
||||
#else
|
||||
// If a board enables USE_KCT8103L_PA but does not match a known variant and has
|
||||
// not already provided a PA curve, fail at compile time to avoid unsafe defaults.
|
||||
|
||||
@@ -70,20 +70,25 @@ bool GPSUpdateScheduling::isUpdateDue()
|
||||
// Have we been searching for a GPS position for too long?
|
||||
bool GPSUpdateScheduling::searchedTooLong()
|
||||
{
|
||||
constexpr uint32_t oneMinuteMs = 60UL * 1000UL;
|
||||
constexpr uint32_t maxSearchClampMs = 15UL * oneMinuteMs; // Hard cap: 15 minutes is always too long
|
||||
uint32_t elapsed = elapsedSearchMs();
|
||||
|
||||
// Anything over 15 minutes is too long, regardless of the broadcast interval.
|
||||
// TODO: Make a smarter algorithm that backs off the search dwell time when not getting a lock.
|
||||
if (elapsed > maxSearchClampMs)
|
||||
return true;
|
||||
|
||||
uint32_t minimumOrConfiguredSecs =
|
||||
Default::getConfiguredOrMinimumValue(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
||||
uint32_t maxSearchMs = Default::getConfiguredOrDefaultMs(minimumOrConfiguredSecs, default_broadcast_interval_secs);
|
||||
// If broadcast interval set to max, no such thing as "too long"
|
||||
if (maxSearchMs == UINT32_MAX)
|
||||
return false;
|
||||
|
||||
// If we've been searching longer than our position broadcast interval: that's too long
|
||||
else if (elapsedSearchMs() > maxSearchMs)
|
||||
if (elapsed > maxSearchMs)
|
||||
return true;
|
||||
|
||||
// Otherwise, not too long yet!
|
||||
else
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Updates the predicted time-to-get-lock, by exponentially smoothing the latest observation
|
||||
|
||||
@@ -422,7 +422,7 @@ static LGFX *tft = nullptr;
|
||||
|
||||
#elif defined(ST7789_CS)
|
||||
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
|
||||
#ifdef HELTEC_V4_TFT
|
||||
#if defined(HELTEC_V4_TFT) || defined(HELTEC_V4_R8_TFT)
|
||||
#include "chsc6x.h"
|
||||
#include "lgfx/v1/Touch.hpp"
|
||||
namespace lgfx
|
||||
@@ -444,7 +444,11 @@ class TOUCH_CHSC6X : public ITouch
|
||||
bool init(void) override
|
||||
{
|
||||
if (chsc6xTouch == nullptr) {
|
||||
#if (TOUCH_I2C_PORT == 1)
|
||||
chsc6xTouch = new chsc6x(&Wire1, TOUCH_SDA_PIN, TOUCH_SCL_PIN, TOUCH_INT_PIN, TOUCH_RST_PIN);
|
||||
#else
|
||||
chsc6xTouch = new chsc6x(&Wire, TOUCH_SDA_PIN, TOUCH_SCL_PIN, TOUCH_INT_PIN, TOUCH_RST_PIN);
|
||||
#endif
|
||||
}
|
||||
chsc6xTouch->chsc6x_init();
|
||||
return true;
|
||||
@@ -481,7 +485,7 @@ class LGFX : public lgfx::LGFX_Device
|
||||
#if HAS_TOUCHSCREEN
|
||||
#if defined(T_WATCH_S3) || defined(ELECROW)
|
||||
lgfx::Touch_FT5x06 _touch_instance;
|
||||
#elif defined(HELTEC_V4_TFT)
|
||||
#elif defined(HELTEC_V4_TFT) || defined(HELTEC_V4_R8_TFT)
|
||||
lgfx::TOUCH_CHSC6X _touch_instance;
|
||||
#else
|
||||
lgfx::Touch_GT911 _touch_instance;
|
||||
@@ -500,7 +504,11 @@ class LGFX : public lgfx::LGFX_Device
|
||||
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
|
||||
// 80MHz by an integer)
|
||||
cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving
|
||||
cfg.spi_3wire = false;
|
||||
#ifdef SPI_3_WIRE
|
||||
cfg.spi_3wire = SPI_3_WIRE;
|
||||
#else
|
||||
cfg.spi_3wire = true; // Set to true if reception is done on the MOSI pin
|
||||
#endif
|
||||
cfg.use_lock = true; // Set to true to use transaction locking
|
||||
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
|
||||
// SPI_DMA_CH_AUTO=auto setting)
|
||||
@@ -550,8 +558,11 @@ class LGFX : public lgfx::LGFX_Device
|
||||
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
|
||||
cfg.dlen_16bit =
|
||||
false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
|
||||
#if defined(HAS_SDCARD)
|
||||
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
|
||||
|
||||
#else
|
||||
cfg.bus_shared = false;
|
||||
#endif
|
||||
// Set the following only when the display is shifted with a driver with a variable number of pixels, such as the
|
||||
// ST7735 or ILI9163.
|
||||
// cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
|
||||
|
||||
@@ -390,8 +390,11 @@ void InputBroker::Init()
|
||||
seesawRotary = nullptr;
|
||||
}
|
||||
}
|
||||
#ifdef __linux__
|
||||
// Linux evdev keyboard input only — macOS has no <linux/input.h>.
|
||||
aLinuxInputImpl = new LinuxInputImpl();
|
||||
aLinuxInputImpl->init();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if !MESHTASTIC_EXCLUDE_INPUTBROKER && HAS_TRACKBALL
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
#if ARCH_PORTDUINO
|
||||
// Linux evdev keyboard input. Only compiled on Linux portduino targets;
|
||||
// macOS / non-Linux builds have no <linux/input.h> or epoll, and the
|
||||
// headless build doesn't need real keyboards anyway.
|
||||
#if ARCH_PORTDUINO && defined(__linux__)
|
||||
#include "InputBroker.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include <assert.h>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#ifdef ARCH_PORTDUINO
|
||||
// Linux evdev impl. Same Linux-only gating as LinuxInput.h.
|
||||
#if defined(ARCH_PORTDUINO) && defined(__linux__)
|
||||
#pragma once
|
||||
#include "LinuxInput.h"
|
||||
#include "main.h"
|
||||
|
||||
@@ -19,8 +19,12 @@ extern Adafruit_nRFCrypto nRFCrypto;
|
||||
#include <Arduino.h>
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
#include <random>
|
||||
#include <sys/random.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __linux__
|
||||
#include <sys/random.h> // getrandom()
|
||||
#else
|
||||
#include <stdlib.h> // arc4random_buf() on Darwin/BSD
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace HardwareRNG
|
||||
@@ -119,10 +123,16 @@ bool fill(uint8_t *buffer, size_t length, bool useRadioEntropy)
|
||||
filled = true;
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
// Prefer the host OS RNG first when running under Portduino.
|
||||
#ifdef __linux__
|
||||
ssize_t generated = ::getrandom(buffer, length, 0);
|
||||
if (generated == static_cast<ssize_t>(length)) {
|
||||
filled = true;
|
||||
}
|
||||
#else
|
||||
// arc4random_buf is available on Darwin/BSD and cannot fail.
|
||||
::arc4random_buf(buffer, length);
|
||||
filled = true;
|
||||
#endif
|
||||
|
||||
if (!filled) {
|
||||
fillWithRandomDevice(buffer, length);
|
||||
|
||||
@@ -6,8 +6,11 @@
|
||||
#include "configuration.h"
|
||||
#include "detect/LoRaRadioType.h"
|
||||
|
||||
// Sentinel marking the end of a modem preset array
|
||||
static constexpr meshtastic_Config_LoRaConfig_ModemPreset MODEM_PRESET_END =
|
||||
// Sentinel marking the end of a modem preset array. Declared `const` rather
|
||||
// than `constexpr` because the cast from 0xFF to the enum is out-of-range and
|
||||
// therefore not a valid constant expression on Clang 16+ (Apple Clang on
|
||||
// macOS). The value is only ever compared at runtime, so static-init is fine.
|
||||
static const meshtastic_Config_LoRaConfig_ModemPreset MODEM_PRESET_END =
|
||||
static_cast<meshtastic_Config_LoRaConfig_ModemPreset>(0xFF);
|
||||
|
||||
// Region profile: bundles the preset list with regulatory parameters shared across regions
|
||||
|
||||
@@ -688,7 +688,7 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
||||
strncpy(config.network.ntp_server, "meshtastic.pool.ntp.org", 32);
|
||||
|
||||
#if (defined(T_DECK) || defined(T_WATCH_S3) || defined(UNPHONE) || defined(PICOMPUTER_S3) || defined(SENSECAP_INDICATOR) || \
|
||||
defined(ELECROW_PANEL) || defined(HELTEC_V4_TFT)) && \
|
||||
defined(ELECROW_PANEL) || defined(HELTEC_V4_TFT) || defined(HELTEC_V4_R8_TFT)) && \
|
||||
HAS_TFT
|
||||
// switch BT off by default; use TFT programming mode or hotkey to enable
|
||||
config.bluetooth.enabled = false;
|
||||
|
||||
@@ -119,7 +119,7 @@ bool RadioLibInterface::canSendImmediately()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RadioLibInterface::receiveDetected(uint16_t irq, ulong syncWordHeaderValidFlag, ulong preambleDetectedFlag)
|
||||
bool RadioLibInterface::receiveDetected(uint16_t irq, unsigned long syncWordHeaderValidFlag, unsigned long preambleDetectedFlag)
|
||||
{
|
||||
bool detected = (irq & (syncWordHeaderValidFlag | preambleDetectedFlag));
|
||||
// Handle false detections
|
||||
|
||||
@@ -220,7 +220,7 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
protected:
|
||||
uint32_t activeReceiveStart = 0;
|
||||
|
||||
bool receiveDetected(uint16_t irq, ulong syncWordHeaderValidFlag, ulong preambleDetectedFlag);
|
||||
bool receiveDetected(uint16_t irq, unsigned long syncWordHeaderValidFlag, unsigned long preambleDetectedFlag);
|
||||
|
||||
/** Do any hardware setup needed on entry into send configuration for the radio.
|
||||
* Subclasses can customize, but must also call this base method */
|
||||
|
||||
@@ -736,9 +736,13 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
||||
// Also, we should set the time from the ISR and it should have msec level resolution
|
||||
p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone
|
||||
|
||||
// Store a copy of encrypted packet for MQTT
|
||||
// Store a copy of the encrypted packet for MQTT.
|
||||
// Local, not a class member: handleReceived re-enters itself when a module
|
||||
// reply broadcast goes through MeshService::sendToMesh -> Router::sendLocal,
|
||||
// and a member would be silently overwritten without release on the inner
|
||||
// call. Each invocation now owns its own copy (issue #9632, #10101, #8729).
|
||||
DEBUG_HEAP_BEFORE;
|
||||
p_encrypted = packetPool.allocCopy(*p);
|
||||
meshtastic_MeshPacket *p_encrypted = packetPool.allocCopy(*p);
|
||||
DEBUG_HEAP_AFTER("Router::handleReceived", p_encrypted);
|
||||
|
||||
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
||||
@@ -832,8 +836,7 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
||||
#endif
|
||||
}
|
||||
|
||||
packetPool.release(p_encrypted); // Release the encrypted packet
|
||||
p_encrypted = nullptr;
|
||||
packetPool.release(p_encrypted); // Release the encrypted packet (release() handles nullptr)
|
||||
}
|
||||
|
||||
void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
|
||||
|
||||
@@ -92,9 +92,6 @@ class Router : protected concurrency::OSThread, protected PacketHistory
|
||||
before us */
|
||||
uint32_t rxDupe = 0, txRelayCanceled = 0;
|
||||
|
||||
// pointer to the encrypted packet
|
||||
meshtastic_MeshPacket *p_encrypted = nullptr;
|
||||
|
||||
protected:
|
||||
friend class RoutingModule;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <assert.h>
|
||||
#include <utility>
|
||||
|
||||
#include <IPAddress.h>
|
||||
#include "IPAddress.h"
|
||||
#if defined(ARCH_PORTDUINO)
|
||||
#include <netinet/in.h>
|
||||
#elif !defined(ntohl)
|
||||
|
||||
@@ -9,13 +9,10 @@
|
||||
#include "PortduinoGlue.h"
|
||||
#include "SHA256.h"
|
||||
#include "api/ServerAPI.h"
|
||||
#include "linux/gpio/LinuxGPIOPin.h"
|
||||
#include "meshUtils.h"
|
||||
#include <ErriezCRC32.h>
|
||||
#include <Utility.h>
|
||||
#include <assert.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@@ -25,6 +22,12 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef PORTDUINO_LINUX_HARDWARE
|
||||
#include "linux/gpio/LinuxGPIOPin.h"
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#endif
|
||||
|
||||
#ifdef PORTDUINO_LINUX_HARDWARE
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
@@ -130,9 +133,9 @@ void getMacAddr(uint8_t *dmac)
|
||||
}
|
||||
} else if (portduino_config.mac_address.length() > 11) {
|
||||
MAC_from_string(portduino_config.mac_address, dmac);
|
||||
exit;
|
||||
return;
|
||||
} else {
|
||||
|
||||
#ifdef PORTDUINO_LINUX_HARDWARE
|
||||
struct hci_dev_info di = {0};
|
||||
di.dev_id = 0;
|
||||
bdaddr_t bdaddr;
|
||||
@@ -152,6 +155,11 @@ void getMacAddr(uint8_t *dmac)
|
||||
dmac[3] = di.bdaddr.b[2];
|
||||
dmac[4] = di.bdaddr.b[1];
|
||||
dmac[5] = di.bdaddr.b[0];
|
||||
#else
|
||||
// No BlueZ on non-Linux hosts (e.g. macOS). Leave dmac at its default;
|
||||
// the caller can override via the --hwid CLI flag or the YAML config.
|
||||
(void)dmac;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,10 +494,17 @@ void portduinoSetup()
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
char serial[9] = {0};
|
||||
ch341Hal->getSerialString(serial, 8);
|
||||
// Pass the full buffer size (9 = 8 chars + null) to getSerialString,
|
||||
// not 8. The function treats `len` as buffer size and reserves one
|
||||
// slot for the null terminator, so passing 8 produced a 7-char serial
|
||||
// and broke the `strlen(serial) == 8` check below — masked on Linux
|
||||
// by the BlueZ HCI MAC fallback in getMacAddr(), but on macOS (where
|
||||
// the BlueZ path is __linux__-guarded) it left mac_address empty and
|
||||
// meshtasticd refused to start.
|
||||
ch341Hal->getSerialString(serial, sizeof(serial));
|
||||
std::cout << "CH341 Serial " << serial << std::endl;
|
||||
char product_string[96] = {0};
|
||||
ch341Hal->getProductString(product_string, 95);
|
||||
ch341Hal->getProductString(product_string, sizeof(product_string));
|
||||
std::cout << "CH341 Product " << product_string << std::endl;
|
||||
if (strlen(serial) == 8 && portduino_config.mac_address.length() < 12) {
|
||||
std::cout << "Deriving MAC address from Serial and Product String" << std::endl;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "platform/portduino/PortduinoGlue.h"
|
||||
#include <RadioLib.h>
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <libpinedio-usb.h>
|
||||
#include <unistd.h>
|
||||
@@ -34,7 +35,7 @@ class Ch341Hal : public RadioLibHal
|
||||
: RadioLibHal(PI_INPUT, PI_OUTPUT, PI_LOW, PI_HIGH, PI_RISING, PI_FALLING)
|
||||
{
|
||||
if (serial != "") {
|
||||
strncpy(pinedio.serial_number, serial.c_str(), 8);
|
||||
std::strncpy(pinedio.serial_number, serial.c_str(), 8);
|
||||
pinedio_set_option(&pinedio, PINEDIO_OPTION_SEARCH_SERIAL, 1);
|
||||
}
|
||||
// LOG_INFO("USB Serial: %s", pinedio.serial_number);
|
||||
@@ -59,8 +60,11 @@ class Ch341Hal : public RadioLibHal
|
||||
|
||||
void getSerialString(char *_serial, size_t len)
|
||||
{
|
||||
len = len > 8 ? 8 : len;
|
||||
strncpy(_serial, pinedio.serial_number, len);
|
||||
if (len == 0)
|
||||
return;
|
||||
size_t bytesCopied = (len - 1) < 8 ? (len - 1) : 8;
|
||||
std::strncpy(_serial, pinedio.serial_number, bytesCopied);
|
||||
_serial[bytesCopied] = '\0';
|
||||
}
|
||||
|
||||
void getProductString(char *_product_string, size_t len)
|
||||
|
||||
@@ -35,9 +35,10 @@
|
||||
// code)
|
||||
#endif
|
||||
|
||||
// Leave undefined to disable our PMU IRQ handler. DO NOT ENABLE THIS because the pmuirq can cause sperious interrupts
|
||||
// and waking from light sleep
|
||||
// #define PMU_IRQ 35
|
||||
// Voiding more warranties.
|
||||
#define PMU_IRQ 35
|
||||
#define PMU_POWER_BUTTON_IS_CANCEL // maps a short click of the power button to a cancel action (turning off the screen)
|
||||
|
||||
#define HAS_AXP192
|
||||
#define GPS_UBLOX
|
||||
#define GPS_RX_PIN 34
|
||||
|
||||
@@ -89,8 +89,10 @@ build_flags =
|
||||
-D VIEW_240x320
|
||||
-D DISPLAY_SET_RESOLUTION
|
||||
-D DISPLAY_SIZE=240x320 ; portrait mode
|
||||
-D LGFX_SPI_3WIRE=true
|
||||
-D LGFX_PIN_SCK=17
|
||||
-D LGFX_PIN_MOSI=33
|
||||
-D LGFX_PIN_MISO=-1
|
||||
-D LGFX_PIN_DC=16
|
||||
-D LGFX_PIN_CS=15
|
||||
-D LGFX_PIN_BL=21
|
||||
@@ -123,7 +125,7 @@ build_flags =
|
||||
-D SCREEN_TRANSITION_FRAMERATE=30
|
||||
-D BRIGHTNESS_DEFAULT=130 ; Medium Low Brightness
|
||||
-D HAS_TOUCHSCREEN=1
|
||||
-D TOUCH_I2C_PORT=0
|
||||
-D TOUCH_I2C_PORT=1
|
||||
-D TOUCH_SLAVE_ADDRESS=0x2E
|
||||
-D SCREEN_TOUCH_INT=TOUCH_INT_PIN
|
||||
-D SCREEN_TOUCH_RST=TOUCH_RST_PIN
|
||||
|
||||
56
variants/esp32s3/heltec_v4_r8/pins_arduino.h
Normal file
56
variants/esp32s3/heltec_v4_r8/pins_arduino.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef Pins_Arduino_h
|
||||
#define Pins_Arduino_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define USB_VID 0x303a
|
||||
#define USB_PID 0x1001
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
static const uint8_t SDA = 17;
|
||||
static const uint8_t SCL = 18;
|
||||
|
||||
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;
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
||||
145
variants/esp32s3/heltec_v4_r8/platformio.ini
Normal file
145
variants/esp32s3/heltec_v4_r8/platformio.ini
Normal file
@@ -0,0 +1,145 @@
|
||||
[heltec_v4_r8_base]
|
||||
extends = esp32s3_base
|
||||
board = heltec_v4_r8
|
||||
board_check = true
|
||||
board_build.partitions = default_16MB.csv
|
||||
build_flags =
|
||||
${esp32s3_base.build_flags}
|
||||
-D HELTEC_V4_R8
|
||||
-D HAS_LORA_FEM=1
|
||||
-D BOARD_HAS_PSRAM
|
||||
-I variants/esp32s3/heltec_v4_r8
|
||||
-ULED_BUILTIN
|
||||
|
||||
[env:heltec-v4-r8-oled]
|
||||
custom_meshtastic_hw_model = 132
|
||||
custom_meshtastic_hw_model_slug = HELTEC_V4_R8
|
||||
custom_meshtastic_architecture = esp32-s3
|
||||
custom_meshtastic_actively_supported = true
|
||||
custom_meshtastic_support_level = 1
|
||||
custom_meshtastic_display_name = Heltec V4 R8
|
||||
custom_meshtastic_images = heltec_v4_r8.svg
|
||||
custom_meshtastic_tags = Heltec
|
||||
custom_meshtastic_requires_dfu = true
|
||||
custom_meshtastic_partition_scheme = 16MB
|
||||
|
||||
extends = heltec_v4_r8_base
|
||||
build_flags =
|
||||
${heltec_v4_r8_base.build_flags}
|
||||
-D HELTEC_V4_R8_OLED
|
||||
-D USE_SSD1306 ; Heltec_v4_R8 has an SSD1315 display (compatible with SSD1306 driver)
|
||||
-D LED_POWER=46
|
||||
-D RESET_OLED=21
|
||||
-D I2C_SDA=17
|
||||
-D I2C_SCL=18
|
||||
|
||||
[env:heltec-v4-r8-tft]
|
||||
custom_meshtastic_hw_model = 132
|
||||
custom_meshtastic_hw_model_slug = HELTEC_V4_R8
|
||||
custom_meshtastic_architecture = esp32-s3
|
||||
custom_meshtastic_actively_supported = true
|
||||
custom_meshtastic_support_level = 1
|
||||
custom_meshtastic_display_name = Heltec V4 R8 TFT
|
||||
custom_meshtastic_images = heltec_v4_r8_tft.svg
|
||||
custom_meshtastic_tags = Heltec
|
||||
custom_meshtastic_requires_dfu = true
|
||||
custom_meshtastic_partition_scheme = 16MB
|
||||
|
||||
extends = heltec_v4_r8_base
|
||||
build_flags =
|
||||
${heltec_v4_r8_base.build_flags} ;-Os
|
||||
-D HELTEC_V4_R8_TFT
|
||||
-D I2C_SDA=17
|
||||
-D I2C_SCL=18
|
||||
-D PIN_BUTTON2=46
|
||||
-D ALT_BUTTON_PIN=PIN_BUTTON2
|
||||
-D ALT_BUTTON_ACTIVE_LOW=false
|
||||
-D PIN_BUZZER=4
|
||||
-D USE_PIN_BUZZER=PIN_BUZZER
|
||||
-D CONFIG_ARDUHAL_LOG_COLORS
|
||||
-D RADIOLIB_DEBUG_SPI=0
|
||||
-D RADIOLIB_DEBUG_PROTOCOL=0
|
||||
-D RADIOLIB_DEBUG_BASIC=0
|
||||
-D RADIOLIB_VERBOSE_ASSERT=0
|
||||
-D RADIOLIB_SPI_PARANOID=0
|
||||
-D CONFIG_DISABLE_HAL_LOCKS=1
|
||||
-D INPUTDRIVER_BUTTON_TYPE=0
|
||||
-D HAS_SCREEN=1
|
||||
-D HAS_TFT=1
|
||||
-D RAM_SIZE=5120
|
||||
-D LV_LVGL_H_INCLUDE_SIMPLE
|
||||
-D LV_CONF_INCLUDE_SIMPLE
|
||||
-D LV_COMP_CONF_INCLUDE_SIMPLE
|
||||
-D LV_USE_SYSMON=0
|
||||
-D LV_USE_PROFILER=0
|
||||
-D LV_USE_PERF_MONITOR=0
|
||||
-D LV_USE_MEM_MONITOR=0
|
||||
-D LV_USE_LOG=0
|
||||
-D LV_BUILD_TEST=0
|
||||
-D USE_LOG_DEBUG
|
||||
-D LOG_DEBUG_INC=\"DebugConfiguration.h\"
|
||||
-D USE_PACKET_API
|
||||
-D LGFX_DRIVER=LGFX_HELTEC_V4_TFT
|
||||
-D GFX_DRIVER_INC=\"graphics/LGFX/LGFX_HELTEC_V4_TFT.h\"
|
||||
-D VIEW_240x320
|
||||
-D DISPLAY_SET_RESOLUTION
|
||||
-D DISPLAY_SIZE=240x320 ; portrait mode
|
||||
-D LGFX_SPI_3WIRE=false
|
||||
-D LGFX_PIN_SCK=16
|
||||
-D LGFX_PIN_MOSI=15
|
||||
-D LGFX_PIN_MISO=45
|
||||
-D LGFX_PIN_DC=48
|
||||
-D LGFX_PIN_CS=47
|
||||
-D LGFX_PIN_BL=44
|
||||
-D LGFX_PIN_RST=21
|
||||
-D CUSTOM_TOUCH_DRIVER
|
||||
-D TOUCH_SDA_PIN=I2C_SDA
|
||||
-D TOUCH_SCL_PIN=I2C_SCL
|
||||
-D TOUCH_INT_PIN=-1
|
||||
-D TOUCH_RST_PIN=-1
|
||||
;base UI
|
||||
-D TFT_CS=LGFX_PIN_CS
|
||||
-D ST7789_CS=TFT_CS
|
||||
-D ST7789_RS=LGFX_PIN_DC
|
||||
-D ST7789_SDA=LGFX_PIN_MOSI
|
||||
-D ST7789_SCK=LGFX_PIN_SCK
|
||||
-D ST7789_RESET=LGFX_PIN_RST
|
||||
-D ST7789_MISO=LGFX_PIN_MISO
|
||||
-D ST7789_BUSY=-1
|
||||
-D ST7789_BL=LGFX_PIN_BL
|
||||
-D ST7789_SPI_HOST=SPI3_HOST
|
||||
-D TFT_BL=ST7789_BL
|
||||
-D SPI_FREQUENCY=75000000
|
||||
-D SPI_READ_FREQUENCY=SPI_FREQUENCY
|
||||
-D SPI_3_WIRE=false
|
||||
-D TFT_HEIGHT=320
|
||||
-D TFT_WIDTH=240
|
||||
-D TFT_OFFSET_X=0
|
||||
-D TFT_OFFSET_Y=0
|
||||
-D TFT_OFFSET_ROTATION=0
|
||||
-D SCREEN_ROTATE
|
||||
-D SCREEN_TRANSITION_FRAMERATE=5
|
||||
-D BRIGHTNESS_DEFAULT=130 ; Medium Low Brightness
|
||||
-D HAS_TOUCHSCREEN=1
|
||||
-D TOUCH_I2C_PORT=0
|
||||
-D TOUCH_SLAVE_ADDRESS=0x2E
|
||||
-D SCREEN_TOUCH_INT=TOUCH_INT_PIN
|
||||
-D SCREEN_TOUCH_RST=TOUCH_RST_PIN
|
||||
|
||||
; Have SPI interface SD card slot
|
||||
-D HAS_SDCARD
|
||||
-D SDCARD_USE_SPI1
|
||||
-D SDCARD_USER_SPI_BEGIN
|
||||
-D SPI_MOSI=LGFX_PIN_MOSI
|
||||
-D SPI_SCK=LGFX_PIN_SCK
|
||||
-D SPI_MISO=LGFX_PIN_MISO
|
||||
-D SPI_CS=3
|
||||
-D SDCARD_CS=SPI_CS
|
||||
-D SD_SPI_FREQUENCY=SPI_FREQUENCY
|
||||
|
||||
lib_deps = ${heltec_v4_r8_base.lib_deps}
|
||||
${device-ui_base.lib_deps}
|
||||
# renovate: datasource=custom.pio depName=LovyanGFX packageName=lovyan03/library/LovyanGFX
|
||||
lovyan03/LovyanGFX@1.2.19
|
||||
# renovate: datasource=git-refs depName=Quency-D_chsc6x packageName=https://github.com/Quency-D/chsc6x gitBranch=master
|
||||
https://github.com/Quency-D/chsc6x/archive/3b2b6cebf3177b3e2c33d06e07909b0b10159516.zip
|
||||
72
variants/esp32s3/heltec_v4_r8/variant.h
Normal file
72
variants/esp32s3/heltec_v4_r8/variant.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#define VEXT_ENABLE 40 // active low, powers the oled display and the lora antenna boost
|
||||
#define VEXT_ON_VALUE LOW
|
||||
#define BUTTON_PIN 0
|
||||
|
||||
#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.035
|
||||
|
||||
#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
|
||||
|
||||
// Enable Traffic Management Module for Heltec V4
|
||||
#ifndef HAS_TRAFFIC_MANAGEMENT
|
||||
#define HAS_TRAFFIC_MANAGEMENT 1
|
||||
#endif
|
||||
#ifndef TRAFFIC_MANAGEMENT_CACHE_SIZE
|
||||
#define TRAFFIC_MANAGEMENT_CACHE_SIZE 2048
|
||||
#endif
|
||||
|
||||
// ---- KCT8103L RF FRONT END CONFIGURATION ----
|
||||
// The Heltec V4.3 uses a KCT8103L FEM chip with integrated PA and LNA
|
||||
// RF path: SX1262 -> Pi attenuator -> KCT8103L PA -> Antenna
|
||||
// Control logic (from KCT8103L datasheet):
|
||||
// Transmit PA: CSD=1, CTX=1, CPS=1
|
||||
// Receive LNA: CSD=1, CTX=0, CPS=X (21dB gain, 1.9dB NF)
|
||||
// Receive bypass: CSD=1, CTX=1, CPS=0
|
||||
// Shutdown: CSD=0, CTX=X, CPS=X
|
||||
// Pin mapping:
|
||||
// CPS (pin 5) -> SX1262 DIO2: TX/RX path select (automatic via SX126X_DIO2_AS_RF_SWITCH)
|
||||
// CSD (pin 4) -> GPIO2: Chip enable (HIGH=on, LOW=shutdown)
|
||||
// CTX (pin 6) -> GPIO5: Switch between Receive LNA Mode and Receive Bypass Mode. (HIGH=RX bypass, LOW=RX LNA)
|
||||
// VCC0/VCC1 -> Vfem via U3 LDO, controlled by GPIO7
|
||||
// KCT8103L FEM: TX/RX path switching is handled by DIO2 -> CPS pin (via SX126X_DIO2_AS_RF_SWITCH)
|
||||
|
||||
#define USE_KCT8103L_PA
|
||||
#define LORA_PA_POWER 7 // VFEM_Ctrl - KCT8103L LDO power enable
|
||||
#define LORA_KCT8103L_PA_CSD 2 // CSD - KCT8103L chip enable (HIGH=on)
|
||||
#define LORA_KCT8103L_PA_CTX 5 // CTX - Switch between Receive LNA Mode and Receive Bypass Mode. (HIGH=RX bypass, LOW=RX LNA)
|
||||
|
||||
#if HAS_TFT
|
||||
#define USE_TFTDISPLAY 1
|
||||
#endif
|
||||
/*
|
||||
* GPS pins
|
||||
*/
|
||||
#define GPS_L76K
|
||||
#define PIN_GPS_EN (42)
|
||||
#define GPS_EN_ACTIVE LOW
|
||||
#define PERIPHERAL_WARMUP_MS 1000 // Make sure I2C QuickLink has stable power before continuing
|
||||
#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
|
||||
@@ -42,6 +42,7 @@
|
||||
#define DAC_I2S_MCLK -1
|
||||
|
||||
#define HAS_AXP2101
|
||||
#define PMU_POWER_BUTTON_IS_CANCEL // maps a short click of the power button to a cancel action (turning off the screen)
|
||||
|
||||
// PCF8563 RTC Module
|
||||
#define PCF8563_RTC 0x51
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
#define LR11X0_DIO_AS_RF_SWITCH
|
||||
#endif
|
||||
|
||||
// Leave undefined to disable our PMU IRQ handler. DO NOT ENABLE THIS because the pmuirq can cause sperious interrupts
|
||||
// and waking from light sleep
|
||||
// #define PMU_IRQ 40
|
||||
// Voiding warrenties, we're gonna try the IRQ
|
||||
#define PMU_IRQ 40
|
||||
#define PMU_POWER_BUTTON_IS_CANCEL // maps a short click of the power button to a cancel action (turning off the screen)
|
||||
#define HAS_AXP2101
|
||||
|
||||
// PCF8563 RTC Module
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[portduino_base]
|
||||
platform =
|
||||
# renovate: datasource=git-refs depName=platform-native packageName=https://github.com/meshtastic/platform-native gitBranch=develop
|
||||
https://github.com/meshtastic/platform-native/archive/135b91e953db0b5f44d278f8ebd5b8d985fc03d8.zip
|
||||
https://github.com/meshtastic/platform-native/archive/4ea5e09ac7d51a593e12ec7c1ebb6cd06745ce53.zip
|
||||
framework = arduino
|
||||
|
||||
build_src_filter =
|
||||
@@ -37,25 +37,35 @@ lib_deps =
|
||||
# renovate: datasource=github-tags depName=Adafruit_BME680 packageName=adafruit/Adafruit_BME680
|
||||
https://github.com/adafruit/Adafruit_BME680/archive/refs/tags/2.0.6.zip
|
||||
|
||||
build_flags =
|
||||
; Cross-platform build flags shared between native (Linux) and native-macos builds.
|
||||
; Anything Linux-only (libbluetooth, libgpiod, libi2c, /sys/class/gpio,
|
||||
; PORTDUINO_LINUX_HARDWARE, glibc-style _FORTIFY_SOURCE) goes in `build_flags`
|
||||
; instead. UDP multicast also lives there because the firmware's
|
||||
; UdpMulticastHandler.h unconditionally `#include <WiFi.h>` on non-NRF52
|
||||
; targets, which requires the framework's bundled WiFi shim that we
|
||||
; lib_ignore on macOS.
|
||||
build_flags_common =
|
||||
${arduino_base.build_flags}
|
||||
-D ARCH_PORTDUINO
|
||||
-fPIC
|
||||
-D_FORTIFY_SOURCE=2
|
||||
-fstack-protector-all -Wstack-protector --param ssp-buffer-size=4
|
||||
-Isrc/platform/portduino
|
||||
-DRADIOLIB_EEPROM_UNSUPPORTED
|
||||
-DPORTDUINO_LINUX_HARDWARE
|
||||
-DHAS_UDP_MULTICAST=1
|
||||
-lpthread
|
||||
-lstdc++fs
|
||||
-lbluetooth
|
||||
-lgpiod
|
||||
-lyaml-cpp
|
||||
-li2c
|
||||
-luv
|
||||
-std=gnu17
|
||||
-std=gnu++17
|
||||
|
||||
build_flags =
|
||||
${portduino_base.build_flags_common}
|
||||
-DHAS_UDP_MULTICAST=1
|
||||
-D_FORTIFY_SOURCE=2
|
||||
-fstack-protector-all -Wstack-protector --param ssp-buffer-size=4
|
||||
-DPORTDUINO_LINUX_HARDWARE
|
||||
-lstdc++fs
|
||||
-lbluetooth
|
||||
-lgpiod
|
||||
-li2c
|
||||
lib_ignore =
|
||||
Adafruit NeoPixel
|
||||
Adafruit ST7735 and ST7789 Library
|
||||
|
||||
@@ -117,3 +117,92 @@ build_flags = -lgcov --coverage -fprofile-abs-path -fsanitize=address ${env:nati
|
||||
test_testing_command =
|
||||
${platformio.build_dir}/${this.__env__}/meshtasticd
|
||||
-s
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Native build for macOS (Darwin / arm64 + x86_64). Headless meshtasticd that
|
||||
; runs in SimRadio mode (`-s`) or against real LoRa hardware via a CH341
|
||||
; USB-SPI bridge. No BlueZ, libgpiod, or Linux I2C — those require Linux.
|
||||
;
|
||||
; Prerequisites (Homebrew):
|
||||
; brew install platformio yaml-cpp libuv openssl@3 libusb argp-standalone pkg-config
|
||||
;
|
||||
; The macOS-side patches now live upstream:
|
||||
; * meshtastic/platform-native — `String.h`-shadow shim, `-Wno-enum-constexpr-conversion`,
|
||||
; empty-variant-dir guard. Pulled via `portduino_base.platform` zip pin.
|
||||
; * meshtastic/framework-portduino — LinuxHardwareI2C macOS stubs, AsyncUDP
|
||||
; SOCK_NONBLOCK fallback, Common.h __APPLE__ guard, WiFiServer.cpp extern-C
|
||||
; fix, package.json URL refresh. Pulled by platform-native at its pinned commit.
|
||||
; This env therefore only carries the firmware-side build flags and src filter.
|
||||
;
|
||||
; Real LoRa hardware on macOS:
|
||||
; The same lib_dep `pine64/libch341-spi-userspace` used on Linux works on
|
||||
; macOS as-is — its `libusb_detach_kernel_driver()` call is `__linux__`-
|
||||
; guarded, but on macOS the kernel doesn't bind a driver to a CH341A SPI
|
||||
; bridge (PID 0x5512; bDeviceClass=0xff vendor-specific) by default, so
|
||||
; no detach is needed. Apple's bundled CH34x driver targets the CH340
|
||||
; *UART* variant (PID 0x7523) — different product. libusb opens the device
|
||||
; and claims interface 0 directly via IOUSBHostInterface.
|
||||
;
|
||||
; To use, point `meshtasticd` at any of the existing `bin/config.d/lora-*.yaml`
|
||||
; files that specify `spidev: ch341` — they're platform-agnostic. Example:
|
||||
; pio run -e native-macos
|
||||
; mkdir -p ~/.meshtasticd && cp bin/config-dist.yaml ~/.meshtasticd/config.yaml
|
||||
; # Edit ~/.meshtasticd/config.yaml: ConfigDirectory: ./config.d/
|
||||
; mkdir ~/.meshtasticd/config.d && cp bin/config.d/lora-meshstick-1262.yaml ~/.meshtasticd/config.d/
|
||||
; cd ~/.meshtasticd && /path/to/firmware/.pio/build/native-macos/meshtasticd
|
||||
;
|
||||
; The MAC address auto-derives from the CH341's USB serial + product string
|
||||
; (PortduinoGlue.cpp ~497-518); on Linux a BlueZ HCI socket is the fallback
|
||||
; when that path isn't taken, but BlueZ is `__linux__`-guarded so the
|
||||
; serial-derivation path is mandatory on macOS. Override with
|
||||
; `MACAddress: AA:BB:CC:DD:EE:FF` in config.yaml's `General:` section if
|
||||
; the device's serial isn't 8 hex chars.
|
||||
;
|
||||
; Diagnosing CH341 issues on macOS:
|
||||
; ioreg -p IOUSB -l -w 0 | grep -B2 -A30 0x5512
|
||||
; Children should be `IOUSBHostInterface`. If a vendor driver class
|
||||
; (e.g. `com.wch.CH34xVCPDriver` from a third-party WCH installer)
|
||||
; claims interface 0, libusb will fail with LIBUSB_ERROR_BUSY.
|
||||
; Workaround: `sudo kmutil unload -b <bundleID>`.
|
||||
; LIBUSB_DEBUG=4 .pio/build/native-macos/meshtasticd
|
||||
; Verbose libusb trace — useful when claim_interface fails.
|
||||
; ---------------------------------------------------------------------------
|
||||
[env:native-macos]
|
||||
extends = native_base
|
||||
; Apple's ld doesn't accept GNU ld's `-Wl,-Map,<file>` syntax (inherited from
|
||||
; the top-level platformio.ini). Strip it; the linker map isn't useful for
|
||||
; the macOS dev loop anyway, and Apple ld's equivalent (`-Wl,-map,<file>`)
|
||||
; uses different argument shape.
|
||||
build_unflags = -Wl,-Map,"${platformio.build_dir}"/output.map
|
||||
build_flags = ${portduino_base.build_flags_common}
|
||||
-I variants/native/portduino
|
||||
-I/opt/homebrew/include
|
||||
-I/opt/homebrew/opt/argp-standalone/include
|
||||
-I/opt/homebrew/opt/yaml-cpp/include
|
||||
-L/opt/homebrew/lib
|
||||
-L/opt/homebrew/opt/argp-standalone/lib
|
||||
-L/opt/homebrew/opt/yaml-cpp/lib
|
||||
-largp
|
||||
-DPORTDUINO_DARWIN
|
||||
; Headless build — variants/native/portduino/variant.h would otherwise
|
||||
; default HAS_SCREEN to 1 and pull in screen-renderer source that uses
|
||||
; VLA-with-initializer (a GNU/GCC extension Apple Clang rejects).
|
||||
; MESHTASTIC_EXCLUDE_SCREEN gates the optional `screen->setHeading(...)`-
|
||||
; style screen-driver hooks scattered through sensor sources.
|
||||
-DHAS_SCREEN=0
|
||||
-DMESHTASTIC_EXCLUDE_SCREEN=1
|
||||
!pkg-config --libs openssl --silence-errors || :
|
||||
; src/input/Linux*.{cpp,h} drive evdev (`<linux/input.h>`) which doesn't exist
|
||||
; on macOS. graphics/Panel_sdl.* and graphics/TFTDisplay.cpp pull LovyanGFX
|
||||
; (which we lib_ignore on macOS for the <malloc.h> issue). Neither is needed
|
||||
; for the headless build.
|
||||
build_src_filter = ${native_base.build_src_filter}
|
||||
-<input/LinuxInput.cpp>
|
||||
-<input/LinuxInputImpl.cpp>
|
||||
-<graphics/Panel_sdl.cpp>
|
||||
-<graphics/TFTDisplay.cpp>
|
||||
; LovyanGFX includes <malloc.h> (Linux-only) and is only needed by TFT
|
||||
; variants — not relevant for the headless macOS build.
|
||||
lib_ignore =
|
||||
${portduino_base.lib_ignore}
|
||||
LovyanGFX
|
||||
|
||||
@@ -7,7 +7,7 @@ extends = arduino_base
|
||||
platform_packages =
|
||||
; our custom Git version with C++17 support in platform.txt
|
||||
# TODO renovate
|
||||
platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino#cpp17-platform
|
||||
platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino#master
|
||||
; Don't renovate toolchain-gccarmnoneeabi
|
||||
platformio/toolchain-gccarmnoneeabi@~1.90301.0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user