Compare commits

..
481 changed files with 5302 additions and 18992 deletions
+1 -1
View File
@@ -100,7 +100,7 @@ runs:
id: version id: version
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
with: with:
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }} name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }}
overwrite: true overwrite: true
+2
View File
@@ -8,6 +8,8 @@ runs:
uses: actions/checkout@v6 uses: actions/checkout@v6
with: with:
submodules: recursive submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Install dependencies - name: Install dependencies
shell: bash shell: bash
+27 -164
View File
@@ -4,11 +4,11 @@ This document provides context and guidelines for AI assistants working with the
## Project Overview ## Project Overview
Meshtastic is an open-source LoRa mesh networking project for long-range, low-power communication without relying on internet or cellular infrastructure. The firmware enables text messaging, location sharing, and telemetry over a decentralized mesh network. The project uses **C++17** as its language standard across all platforms. Meshtastic is an open-source LoRa mesh networking project for long-range, low-power communication without relying on internet or cellular infrastructure. The firmware enables text messaging, location sharing, and telemetry over a decentralized mesh network.
### Supported Hardware Platforms ### Supported Hardware Platforms
- **ESP32** (ESP32, ESP32-S3, ESP32-C3, ESP32-C6) - Most common platform - **ESP32** (ESP32, ESP32-S3, ESP32-C3) - Most common platform
- **nRF52** (nRF52840, nRF52833) - Low power Nordic chips - **nRF52** (nRF52840, nRF52833) - Low power Nordic chips
- **RP2040/RP2350** - Raspberry Pi Pico variants - **RP2040/RP2350** - Raspberry Pi Pico variants
- **STM32WL** - STM32 with integrated LoRa - **STM32WL** - STM32 with integrated LoRa
@@ -80,46 +80,21 @@ firmware/
│ │ ├── NodeDB.* # Node database management │ │ ├── NodeDB.* # Node database management
│ │ ├── Router.* # Packet routing │ │ ├── Router.* # Packet routing
│ │ ├── Channels.* # Channel management │ │ ├── Channels.* # Channel management
│ │ ├── CryptoEngine.* # AES-CCM encryption
│ │ ├── *Interface.* # Radio interface implementations │ │ ├── *Interface.* # Radio interface implementations
│ │ ├── api/ # WiFi/Ethernet server APIs (ServerAPI, PacketAPI)
│ │ ├── http/ # HTTP server (WebServer, ContentHandler)
│ │ ├── wifi/ # WiFi support (WiFiAPClient)
│ │ ├── eth/ # Ethernet support (ethClient)
│ │ ├── udp/ # UDP multicast
│ │ ├── compression/ # Message compression (unishox2)
│ │ └── generated/ # Protobuf generated code │ │ └── generated/ # Protobuf generated code
│ ├── modules/ # Feature modules (Position, Telemetry, etc.) │ ├── modules/ # Feature modules (Position, Telemetry, etc.)
│ │ └── Telemetry/ # Telemetry subsystem
│ │ └── Sensor/ # 50+ I2C sensor drivers
│ ├── gps/ # GPS handling │ ├── gps/ # GPS handling
│ ├── graphics/ # Display drivers and UI │ ├── graphics/ # Display drivers and UI
│ │ └── niche/ # Specialized UIs (InkHUD e-ink framework) │ ├── platform/ # Platform-specific code
│ ├── platform/ # Platform-specific code (esp32, nrf52, rp2xx0, stm32wl, portduino) │ ├── input/ # Input device handling
│ ├── input/ # Input device handling (InputBroker, keyboards, buttons) │ └── concurrency/ # Threading utilities
│ ├── detect/ # I2C hardware auto-detection (80+ device types)
│ ├── motion/ # Accelerometer drivers (BMA423, BMI270, MPU6050, etc.)
│ ├── mqtt/ # MQTT bridge client
│ ├── power/ # Power HAL
│ ├── nimble/ # BLE via NimBLE
│ ├── buzz/ # Audio/notification (buzzer, RTTTL)
│ ├── serialization/ # JSON serialization, COBS encoding
│ ├── watchdog/ # Hardware watchdog thread
│ ├── concurrency/ # Threading utilities (OSThread, Lock)
│ ├── PowerFSM.* # Power finite state machine
│ └── Observer.h # Observer/Observable event pattern
├── variants/ # Hardware variant definitions ├── variants/ # Hardware variant definitions
│ ├── esp32/ # ESP32 variants │ ├── esp32/ # ESP32 variants
│ ├── esp32s3/ # ESP32-S3 variants │ ├── esp32s3/ # ESP32-S3 variants
│ ├── esp32c3/ # ESP32-C3 variants │ ├── nrf52/ # nRF52 variants
│ ├── esp32c6/ # ESP32-C6 variants │ └── rp2xxx/ # RP2040/RP2350 variants
│ ├── nrf52840/ # nRF52 variants
│ ├── rp2040/ # RP2040/RP2350 variants
│ ├── stm32/ # STM32WL variants
│ └── native/ # Linux/Portduino variants
├── protobufs/ # Protocol buffer definitions ├── protobufs/ # Protocol buffer definitions
├── boards/ # Custom PlatformIO board definitions ├── boards/ # Custom PlatformIO board definitions
├── test/ # Unit tests (12 test suites)
└── bin/ # Build and utility scripts └── bin/ # Build and utility scripts
``` ```
@@ -130,7 +105,6 @@ firmware/
- Follow existing code style - run `trunk fmt` before commits - Follow existing code style - run `trunk fmt` before commits
- Prefer `LOG_DEBUG`, `LOG_INFO`, `LOG_WARN`, `LOG_ERROR` for logging - Prefer `LOG_DEBUG`, `LOG_INFO`, `LOG_WARN`, `LOG_ERROR` for logging
- Use `assert()` for invariants that should never fail - Use `assert()` for invariants that should never fail
- C++17 features are available (`std::optional`, structured bindings, `if constexpr`, etc.)
### Naming Conventions ### Naming Conventions
@@ -144,151 +118,70 @@ firmware/
#### Module System #### Module System
Modules use a three-tier class hierarchy: Modules inherit from `MeshModule` or `ProtobufModule<T>` and implement:
1. **`MeshModule`** - Base class. Implement `wantPacket()` and `handleReceived()`. Returns `ProcessMessage::STOP` or `ProcessMessage::CONTINUE`. - `handleReceivedProtobuf()` - Process incoming packets
2. **`SinglePortModule`** - Handles a single portnum. Simplified `wantPacket()` that checks `decoded.portnum`. - `allocReply()` - Generate response packets
3. **`ProtobufModule<T>`** - Template for protobuf-based modules. Handles encoding/decoding automatically. - `runOnce()` - Periodic task execution (returns next run interval in ms)
Most modules also inherit from **`OSThread`** for periodic tasks (the "mixin" pattern):
```cpp ```cpp
class MyModule : public ProtobufModule<meshtastic_MyMessage>, private concurrency::OSThread class MyModule : public ProtobufModule<meshtastic_MyMessage>
{ {
public:
MyModule();
protected: protected:
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_MyMessage *msg) override; virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_MyMessage *msg) override;
virtual meshtastic_MeshPacket *allocReply() override; // Generate response packets virtual int32_t runOnce() override;
virtual int32_t runOnce() override; // Periodic task (returns next interval in ms)
virtual bool alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtastic_MyMessage *msg); // Modify in-flight
virtual bool wantUIFrame(); // Request a UI display frame
}; };
``` ```
Modules are registered in `src/modules/Modules.cpp` guarded by `MESHTASTIC_EXCLUDE_*` flags.
#### Observer/Observable Pattern
Event-driven communication between subsystems uses `src/Observer.h`:
```cpp
// Observable emits events
Observable<const meshtastic::Status *> newStatus;
newStatus.notifyObservers(&status);
// Observer receives events via callback
CallbackObserver<MyClass, const meshtastic::Status *> statusObserver =
CallbackObserver<MyClass, const meshtastic::Status *>(this, &MyClass::handleStatusUpdate);
```
#### Configuration Access #### Configuration Access
- `config.*` - Device configuration (LoRa, position, power, etc.) - `config.*` - Device configuration (LoRa, position, power, etc.)
- `moduleConfig.*` - Module-specific configuration - `moduleConfig.*` - Module-specific configuration
- `channels.*` - Channel configuration and management - `channels.*` - Channel configuration and management
- `owner` - Device owner info
- `myNodeInfo` - Local node info
#### Default Values #### Default Values
Use the `Default` class helpers in `src/mesh/Default.h`: Use the `Default` class helpers in `src/mesh/Default.h`:
- `Default::getConfiguredOrDefaultMs(configured, default)` - Returns ms, using default if configured is 0 - `Default::getConfiguredOrDefaultMs(configured, default)` - Returns ms, using default if configured is 0
- `Default::getConfiguredOrDefault(configured, default)` - Generic configured/default getter
- `Default::getConfiguredOrMinimumValue(configured, min)` - Enforces minimum values - `Default::getConfiguredOrMinimumValue(configured, min)` - Enforces minimum values
- `Default::getConfiguredOrDefaultMsScaled(configured, default, numNodes)` - Scales based on network size - `Default::getConfiguredOrDefaultMsScaled(configured, default, numNodes)` - Scales based on network size
#### Thread Safety #### Thread Safety
- Use `concurrency::Lock` and `concurrency::LockGuard` for mutex protection - Use `concurrency::Lock` for mutex protection
- Radio SPI access uses `SPILock` - Radio SPI access uses `SPILock`
- Prefer `OSThread` for background tasks - Prefer `OSThread` for background tasks
### Hardware Detection
`src/detect/ScanI2C` automatically enumerates 80+ I2C device types at boot including displays, sensors, RTCs, keyboards, PMUs, and touch controllers. This drives automatic initialization of the correct drivers.
### Graphics/UI System
Multiple display driver families in `src/graphics/`:
- **OLED**: SSD1306, SH1106, ST7567
- **TFT**: TFTDisplay (LovyanGFX-based)
- **E-Ink**: EInkDisplay2, EInkDynamicDisplay, EInkParallelDisplay
**InkHUD** (`src/graphics/niche/InkHUD/`) is an event-driven e-ink UI framework:
- Applet-based architecture — modular display tiles
- Read-only, static display optimized for minimal refreshes and low power
- Configured per-variant via `nicheGraphics.h`
- Separate PlatformIO config: `src/graphics/niche/InkHUD/PlatformioConfig.ini`
### Input System
`src/input/InputBroker` is the centralized input event dispatcher. Supports multiple input sources: buttons, keyboards (BBQ10, Cardputer, TCA8418), touch screens, rotary encoders, and matrix keyboards.
### Power Management
`src/PowerFSM.*` implements a finite state machine with states: `stateON`, `statePOWER`, `stateSERIAL`, `stateDARK`. Key events: `EVENT_PRESS`, `EVENT_WAKE_TIMER`, `EVENT_LOW_BATTERY`, `EVENT_RECEIVED_MSG`, `EVENT_SHUTDOWN`. Conditionally excluded with `MESHTASTIC_EXCLUDE_POWER_FSM` (falls back to `FakeFsm`).
### Motion Sensors
`src/motion/AccelerometerThread` provides background motion monitoring with automatic screen wake and double-tap button press detection. Supports 10+ accelerometer/gyroscope chips (BMA423, BMI270, MPU6050, LIS3DH, LSM6DS3, STK8XXX, QMA6100P, ICM20948, BMX160).
### Telemetry Sensor Library
`src/modules/Telemetry/Sensor/` contains 50+ I2C sensor drivers organized by category:
- **Power monitoring**: INA219/226/260/3221, MAX17048
- **Environmental**: BME280/680, SCD4X (CO₂), SEN5X (particulate)
- **Humidity/Temperature**: SHT3X/4X, AHT10, MCP9808, MLX90614
- **Light**: BH1750, TSL2561/2591, VEML7700, LTR390UV, OPT3001
- **Air quality**: PMSA003I, SFA30
- **Specialized**: CGRadSens (radiation), NAU7802 (weight scale)
### API/Networking
`src/mesh/api/` provides a template-based `ServerAPI` for client communication over WiFi (`WiFiServerAPI`) and Ethernet (`ethServerAPI`). Default port: **4403**. HTTP server in `src/mesh/http/`. JSON serialization in `src/serialization/MeshPacketSerializer`.
### Hardware Variants ### Hardware Variants
Each hardware variant has: Each hardware variant has:
- `variant.h` - Pin definitions and hardware capabilities - `variant.h` - Pin definitions and hardware capabilities
- `platformio.ini` - Build configuration - `platformio.ini` - Build configuration
- Optional: `pins_arduino.h`, `rfswitch.h`, `nicheGraphics.h` (for InkHUD variants) - Optional: `pins_arduino.h`, `rfswitch.h`
Key defines in variant.h: Key defines in variant.h:
```cpp ```cpp
#define USE_SX1262 // Radio chip selection #define USE_SX1262 // Radio chip selection
#define HAS_GPS 1 // Hardware capabilities #define HAS_GPS 1 // Hardware capabilities
#define HAS_SCREEN 1 // Display present
#define LORA_CS 36 // Pin assignments #define LORA_CS 36 // Pin assignments
#define SX126X_DIO1 14 // Radio-specific pins #define SX126X_DIO1 14 // Radio-specific pins
``` ```
### Protobuf Messages ### Protobuf Messages
- Defined in `protobufs/meshtastic/*.proto` (~32 proto files) - Defined in `protobufs/meshtastic/*.proto`
- Generated code in `src/mesh/generated/meshtastic/` - Generated code in `src/mesh/generated/`
- Regenerate with `bin/regen-protos.sh` - Regenerate with `bin/regen-protos.sh`
- Message types prefixed with `meshtastic_` - Message types prefixed with `meshtastic_`
- Nanopb `.options` files control field sizes and encoding
### Conditional Compilation ### Conditional Compilation
```cpp ```cpp
#if !MESHTASTIC_EXCLUDE_GPS // Feature exclusion #if !MESHTASTIC_EXCLUDE_GPS // Feature exclusion
#if !MESHTASTIC_EXCLUDE_WIFI // Network feature exclusion
#if !MESHTASTIC_EXCLUDE_BLUETOOTH // BLE exclusion
#if !MESHTASTIC_EXCLUDE_POWER_FSM // Power FSM exclusion
#ifdef ARCH_ESP32 // Architecture-specific #ifdef ARCH_ESP32 // Architecture-specific
#ifdef ARCH_NRF52 // Nordic platform
#ifdef ARCH_RP2040 // Raspberry Pi Pico
#ifdef ARCH_PORTDUINO // Linux native
#if defined(USE_SX1262) // Radio-specific #if defined(USE_SX1262) // Radio-specific
#ifdef HAS_SCREEN // Hardware capability #ifdef HAS_SCREEN // Hardware capability
#if USERPREFS_EVENT_MODE // User preferences #if USERPREFS_EVENT_MODE // User preferences
@@ -299,7 +192,7 @@ Key defines in variant.h:
Uses **PlatformIO** with custom scripts: Uses **PlatformIO** with custom scripts:
- `bin/platformio-pre.py` - Pre-build script - `bin/platformio-pre.py` - Pre-build script
- `bin/platformio-custom.py` - Custom build logic, manifest generation - `bin/platformio-custom.py` - Custom build logic
Build commands: Build commands:
@@ -309,38 +202,21 @@ pio run -e tbeam -t upload # Build and upload
pio run -e native # Build native/Linux version pio run -e native # Build native/Linux version
``` ```
### Build Manifest
`bin/platformio-custom.py` emits a build manifest with metadata:
- `hasMui`, `hasInkHud` - UI capability flags (overridable via `custom_meshtastic_has_mui`, `custom_meshtastic_has_ink_hud`)
- Architecture normalization (e.g., `esp32s3` → `esp32-s3` for API compatibility)
## Common Tasks ## Common Tasks
### Adding a New Module ### Adding a New Module
1. Create `src/modules/MyModule.cpp` and `.h` 1. Create `src/modules/MyModule.cpp` and `.h`
2. Inherit from appropriate base class (`MeshModule`, `SinglePortModule`, or `ProtobufModule<T>`) 2. Inherit from appropriate base class
3. Mix in `concurrency::OSThread` if periodic work is needed 3. Register in `src/modules/Modules.cpp`
4. Register in `src/modules/Modules.cpp` guarded by `#if !MESHTASTIC_EXCLUDE_MYMODULE` 4. Add protobuf messages if needed in `protobufs/`
5. Add protobuf messages if needed in `protobufs/meshtastic/`
6. Add test suite in `test/test_mymodule/` if applicable
### Adding a New Hardware Variant ### Adding a New Hardware Variant
1. Create directory under `variants/<arch>/<name>/` 1. Create directory under `variants/<arch>/<name>/`
2. Add `variant.h` with pin definitions and hardware capability defines 2. Add `variant.h` with pin definitions
3. Add `platformio.ini` with build config — use `extends` to reference common base (e.g., `esp32s3_base`) 3. Add `platformio.ini` with build config
4. Set `custom_meshtastic_support_level = 1` (PR builds) or `2` (merge builds) 4. Reference common configs with `extends`
5. For e-ink displays, add `nicheGraphics.h` for InkHUD configuration
### Adding a New Telemetry Sensor
1. Create driver in `src/modules/Telemetry/Sensor/` following existing sensor pattern
2. Register I2C address in `src/detect/ScanI2C` for auto-detection
3. Integrate with the appropriate telemetry module (Environment, Health, Power, AirQuality)
4. Add proto fields in `protobufs/meshtastic/telemetry.proto` if new data types are needed
### Modifying Configuration Defaults ### Modifying Configuration Defaults
@@ -429,22 +305,9 @@ Most workflows can be triggered manually via `workflow_dispatch` for testing.
## Testing ## Testing
Unit tests in `test/` directory with 12 test suites: - Unit tests in `test/` directory
- Run with `pio test -e native`
- `test_crypto/` - Cryptography - Use `bin/test-simulator.sh` for simulation testing
- `test_mqtt/` - MQTT integration
- `test_radio/` - Radio interface
- `test_mesh_module/` - Module framework
- `test_meshpacket_serializer/` - Packet serialization
- `test_transmit_history/` - Retransmission tracking
- `test_atak/` - ATAK integration
- `test_default/` - Default configuration
- `test_http_content_handler/` - HTTP handling
- `test_serial/` - Serial communication
Run with: `pio test -e native`
Simulation testing: `bin/test-simulator.sh`
## Resources ## Resources
-138
View File
@@ -1,138 +0,0 @@
# New Meshtastic Module
Guide for developing a new Meshtastic firmware module.
## Module Hierarchy
Choose the appropriate base class:
1. **`MeshModule`** — Raw base class. Override `wantPacket()` and `handleReceived()`. Returns `ProcessMessage::STOP` or `ProcessMessage::CONTINUE`.
2. **`SinglePortModule`** — Handles a single `meshtastic_PortNum`. Constructor takes `(name, portNum)`. Simplified `wantPacket()` checking `decoded.portnum`. Use `allocDataPacket()` to create outgoing packets.
3. **`ProtobufModule<T>`** — Template for protobuf-encoded modules. Constructor takes `(name, portNum, fields)`. Override `handleReceivedProtobuf()`. Use `allocDataProtobuf(payload)` to create outgoing packets.
Most modules also mix in `concurrency::OSThread` for periodic background tasks.
## Implementation Pattern
```cpp
// src/modules/MyModule.h
#pragma once
#include "ProtobufModule.h"
#include "concurrency/OSThread.h"
class MyModule : public ProtobufModule<meshtastic_MyMessage>, private concurrency::OSThread
{
public:
MyModule();
protected:
// Process incoming protobuf packet. Return true to stop further processing.
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_MyMessage *msg) override;
// Generate response packet (optional)
virtual meshtastic_MeshPacket *allocReply() override;
// Periodic task — return next run interval in ms, or disable()
virtual int32_t runOnce() override;
// Modify packet in-flight before delivery (optional)
virtual bool alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtastic_MyMessage *msg);
// Request a UI display frame (optional)
virtual bool wantUIFrame();
};
```
## Registration
Register in `src/modules/Modules.cpp` inside `setupModules()`:
```cpp
#if !MESHTASTIC_EXCLUDE_MYMODULE
new MyModule();
#endif
```
If other code needs to reference the module instance:
```cpp
#if !MESHTASTIC_EXCLUDE_MYMODULE
myModule = new MyModule();
#endif
```
And declare the global in the header:
```cpp
extern MyModule *myModule;
```
Some modules also conditionally instantiate based on `moduleConfig`:
```cpp
#if !MESHTASTIC_EXCLUDE_MYMODULE
if (moduleConfig.has_my_module && moduleConfig.my_module.enabled) {
new MyModule();
}
#endif
```
## Conditional Compilation
Add a `MESHTASTIC_EXCLUDE_MYMODULE` guard. This allows the module to be excluded from constrained builds. The flag name must follow the pattern: `MESHTASTIC_EXCLUDE_` + uppercase module name.
## Protobuf Messages (if needed)
1. Define messages in `protobufs/meshtastic/` (e.g., `mymodule.proto`)
2. Add a `.options` file for nanopb field size constraints
3. Regenerate with `bin/regen-protos.sh`
4. Generated code appears in `src/mesh/generated/meshtastic/`
5. Assign a `meshtastic_PortNum` if the module uses a new port number
## Timing and Defaults
Use `Default` class helpers for configurable intervals:
```cpp
int32_t MyModule::runOnce()
{
uint32_t interval = Default::getConfiguredOrDefaultMs(moduleConfig.my_module.update_interval,
default_my_module_interval);
// ... do work ...
return interval;
}
```
On public/default channels, enforce minimums with `Default::getConfiguredOrMinimumValue()`.
## Observer Pattern
Subscribe to system events:
```cpp
CallbackObserver<MyModule, const meshtastic::Status *> statusObserver =
CallbackObserver<MyModule, const meshtastic::Status *>(this, &MyModule::handleStatusUpdate);
```
## Testing
Add test suite in `test/test_mymodule/`:
```
test/
└── test_mymodule/
└── test_main.cpp
```
Run with: `pio test -e native`
## Checklist
- [ ] Header and implementation files in `src/modules/`
- [ ] Inherit from appropriate base class (MeshModule / SinglePortModule / ProtobufModule)
- [ ] Mix in OSThread if periodic work is needed
- [ ] Register in `src/modules/Modules.cpp` with `MESHTASTIC_EXCLUDE_` guard
- [ ] Add protobuf definitions if needed (`protobufs/meshtastic/`)
- [ ] Use `Default::getConfiguredOrDefaultMs()` for timing
- [ ] Respect bandwidth limits on public channels
- [ ] Add test suite in `test/`
-149
View File
@@ -1,149 +0,0 @@
# New Telemetry Sensor
Guide for adding a new I2C telemetry sensor driver to Meshtastic firmware.
## Overview
Telemetry sensors live in `src/modules/Telemetry/Sensor/`. There are 50+ existing drivers organized by measurement type. Each sensor integrates with one of the telemetry modules:
- **EnvironmentTelemetryModule** — Temperature, humidity, pressure, gas, light
- **AirQualityTelemetryModule** — Particulate matter, VOCs
- **PowerTelemetryModule** — Voltage, current, power monitoring
- **HealthTelemetryModule** — Heart rate, SpO2, body temperature
## Sensor Driver Pattern
Each sensor has a `.h` and `.cpp` file pair following this pattern:
```cpp
// src/modules/Telemetry/Sensor/MySensor.h
#pragma once
#include "TelemetrySensor.h"
#include <MySensorLibrary.h> // Arduino/PlatformIO library
class MySensor : virtual public TelemetrySensor
{
private:
MySensorLibrary sensor;
public:
MySensor() : TelemetrySensor(meshtastic_TelemetrySensorType_MY_SENSOR, "MySensor") {}
// Initialize sensor hardware. Return true on success.
virtual void setup() override;
// Read sensor data into the telemetry protobuf. Return true on success.
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
```
```cpp
// src/modules/Telemetry/Sensor/MySensor.cpp
#include "MySensor.h"
#include "TelemetrySensor.h"
void MySensor::setup()
{
sensor.begin();
// Configure sensor parameters...
}
bool MySensor::getMetrics(meshtastic_Telemetry *measurement)
{
// Read from hardware
float value = sensor.readValue();
// Populate the appropriate protobuf variant
measurement->variant.environment_metrics.temperature = value;
// ... other fields ...
return true;
}
```
## I2C Address Registration
Register the sensor's I2C address(es) in `src/detect/ScanI2C` so it's auto-detected at boot:
1. Add a `DeviceType` enum entry in `src/detect/ScanI2C.h`
2. Add the I2C address mapping in `src/detect/ScanI2CTwoWire.cpp`
The scan runs at boot and populates a device map that telemetry modules use to decide which sensors to initialize.
## Protobuf Fields
If the sensor provides data not covered by existing telemetry fields:
1. Add fields to the appropriate message in `protobufs/meshtastic/telemetry.proto`:
- `EnvironmentMetrics` — Environmental measurements
- `AirQualityMetrics` — Air quality data
- `PowerMetrics` — Power/energy data
- `HealthMetrics` — Health/biometric data
2. Add a `.options` constraint if needed (field sizes for nanopb)
3. Regenerate: `bin/regen-protos.sh`
## Sensor Type Enum
Add the sensor to `meshtastic_TelemetrySensorType` enum in `protobufs/meshtastic/telemetry.proto`:
```protobuf
enum TelemetrySensorType {
// ... existing entries ...
MY_SENSOR = XX;
}
```
## Integration with Telemetry Module
Wire the sensor into the appropriate telemetry module. For environment sensors, this is typically in `src/modules/Telemetry/EnvironmentTelemetry.cpp`:
1. Include the sensor header
2. Add initialization in `setupSensor()` guarded by detection results
3. Call `getMetrics()` in the measurement collection path
Example pattern from existing sensors:
```cpp
#include "Sensor/MySensor.h"
MySensor mySensor;
// In setup:
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MY_SENSOR].first > 0) {
mySensor.setup();
}
// In measurement collection:
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MY_SENSOR].first > 0) {
mySensor.getMetrics(&measurement);
}
```
## Library Dependencies
If the sensor needs an external library, add it to the `lib_deps` in the relevant base platformio.ini configs:
```ini
lib_deps =
${env.lib_deps}
mysensorlibrary@^1.0.0
```
Or use a conditional dependency if it's platform-specific.
## Unit Conversions
If the sensor reports values in non-standard units, use `src/modules/Telemetry/UnitConversions.h` for conversion helpers (e.g., Celsius ↔ Fahrenheit, hPa ↔ inHg).
## Checklist
- [ ] Create `src/modules/Telemetry/Sensor/MySensor.h` and `.cpp`
- [ ] Inherit from `TelemetrySensor` base class
- [ ] Implement `setup()` and `getMetrics()` methods
- [ ] Add `meshtastic_TelemetrySensorType` enum entry in `telemetry.proto`
- [ ] Add I2C address to `src/detect/ScanI2C` for auto-detection
- [ ] Add protobuf fields in `telemetry.proto` if new data types needed
- [ ] Regenerate protos: `bin/regen-protos.sh`
- [ ] Wire into the appropriate telemetry module (Environment/AirQuality/Power/Health)
- [ ] Add library dependency if external library required
- [ ] Test on hardware or native build
-178
View File
@@ -1,178 +0,0 @@
# New Hardware Variant
Guide for adding a new Meshtastic hardware variant to the firmware.
## Directory Structure
Create under `variants/<arch>/<name>/`:
```
variants/
├── esp32/ # ESP32
├── esp32s3/ # ESP32-S3
├── esp32c3/ # ESP32-C3
├── esp32c6/ # ESP32-C6
├── nrf52840/ # nRF52840
├── rp2040/ # RP2040/RP2350
├── stm32/ # STM32WL
└── native/ # Linux/Portduino
```
Each variant needs at minimum:
- `variant.h` — Pin definitions and hardware capabilities
- `platformio.ini` — Build configuration
Optional files:
- `pins_arduino.h` — Arduino pin mapping overrides
- `rfswitch.h` — RF switch control for multi-band radios
- `nicheGraphics.h` — InkHUD e-ink configuration
## variant.h Template
```cpp
// Pin definitions
#define I2C_SDA 21
#define I2C_SCL 22
// LoRa radio
#define USE_SX1262 // Radio chip: USE_SX1262, USE_SX1268, USE_SX1280, USE_RF95, USE_LLCC68, USE_LR1110, USE_LR1120, USE_LR1121
#define LORA_CS 18
#define LORA_SCK 5
#define LORA_MOSI 27
#define LORA_MISO 19
#define LORA_DIO1 33 // SX126x: DIO1, SX128x: DIO1, RF95: IRQ
#define LORA_RESET 23
#define LORA_BUSY 32 // SX126x/SX128x only
#define SX126X_DIO2_AS_RF_SWITCH // Common for SX1262 boards
// GPS
#define HAS_GPS 1
#define GPS_RX_PIN 34
#define GPS_TX_PIN 12
// #define PIN_GPS_EN 47 // Optional GPS enable pin
// #define GPS_BAUDRATE 9600 // Override default 9600
// Display
#define HAS_SCREEN 1
// #define USE_SSD1306 // OLED type
// #define USE_SH1106 // Alternative OLED
// #define USE_ST7789 // TFT type
// #define SCREEN_WIDTH 128
// #define SCREEN_HEIGHT 64
// LEDs
#define LED_PIN 2 // Status LED (optional)
// #define HAS_NEOPIXEL 1 // WS2812 support
// Buttons
#define BUTTON_PIN 38
// #define BUTTON_PIN_ALT 0 // Secondary button
// Power management
// #define HAS_AXP192 1 // AXP192 PMU (T-Beam v1.0)
// #define HAS_AXP2101 1 // AXP2101 PMU (T-Beam v1.2+)
// #define BATTERY_PIN 35 // ADC battery voltage pin
// #define ADC_MULTIPLIER 2.0 // Voltage divider ratio
// Optional I2C devices
// #define HAS_RTC 1 // Real-time clock
// #define HAS_TELEMETRY 1 // Enable telemetry sensor support
// #define HAS_SENSOR 1 // I2C sensors present
```
## platformio.ini Template
```ini
[env:my_variant]
extends = esp32s3_base ; Use architecture-specific base
board = esp32-s3-devkitc-1 ; PlatformIO board definition (or custom in boards/)
board_level = extra ; Build level: extra, or omit for default
custom_meshtastic_support_level = 1 ; 1 = PR builds, 2 = merge builds only
build_flags =
${esp32s3_base.build_flags}
-D MY_VARIANT_SPECIFIC_FLAG=1
-I variants/esp32s3/my_variant ; Include path for variant.h
upload_speed = 921600
```
### Common Base Configs
- `esp32_base` / `esp32-common.ini` — ESP32
- `esp32s3_base` — ESP32-S3
- `esp32c3_base` — ESP32-C3
- `esp32c6_base` — ESP32-C6
- `nrf52840_base` / `nrf52.ini` — nRF52840
- `rp2040_base` — RP2040/RP2350
### Support Levels
- `custom_meshtastic_support_level = 1` — Built on every PR (actively supported)
- `custom_meshtastic_support_level = 2` — Built only on merge to main branches
- `board_level = extra` — Only built on full releases
## Build Manifest Metadata
`bin/platformio-custom.py` emits UI capability flags in the build manifest:
- `custom_meshtastic_has_mui = true/false` — Override MUI detection
- `custom_meshtastic_has_ink_hud = true/false` — Override InkHUD detection
- Architecture names are normalized (e.g., `esp32s3` → `esp32-s3`)
## InkHUD E-Ink Variants
For e-ink display variants using the InkHUD framework, add `nicheGraphics.h`:
```cpp
// nicheGraphics.h — InkHUD configuration for this variant
#define INKHUD // Enable InkHUD
// Configure display, applets, and refresh behavior per device
```
InkHUD has its own PlatformIO config: `src/graphics/niche/InkHUD/PlatformioConfig.ini`
## I2C Device Detection
If the variant has I2C devices, ensure `src/detect/ScanI2C` will detect them. The auto-detection system handles 80+ device types including displays, sensors, RTCs, keyboards, PMUs, and touch controllers at boot.
## Custom Board Definitions
If the PlatformIO board doesn't exist, create a custom board JSON in `boards/`:
```json
{
"build": {
"arduino": { "ldscript": "esp32s3_out.ld" },
"core": "esp32",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": ["wifi", "bluetooth"],
"frameworks": ["arduino", "espidf"],
"name": "My Custom Board",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608
},
"url": "https://example.com",
"vendor": "MyVendor"
}
```
## Checklist
- [ ] Create `variants/<arch>/<name>/variant.h` with pin definitions
- [ ] Create `variants/<arch>/<name>/platformio.ini` extending correct base
- [ ] Set `custom_meshtastic_support_level` (1 or 2)
- [ ] Verify radio chip define matches hardware (`USE_SX1262`, etc.)
- [ ] Set hardware capability flags (`HAS_GPS`, `HAS_SCREEN`, etc.)
- [ ] Add custom board JSON in `boards/` if needed
- [ ] Test build: `pio run -e my_variant`
- [ ] For e-ink: add `nicheGraphics.h` with InkHUD config
+3 -3
View File
@@ -4,16 +4,16 @@
- Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first - Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first
to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback
is appreciated." This will allow other devs to potentially save you time by not accidentally duplicating work etc... is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
- Please do not check in files that don't have real changes - Please do not check in files that don't have real changes
- Please do not reformat lines that you didn't have to change the code on - Please do not reformat lines that you didn't have to change the code on
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (In beta for windows, WSL2 for the Linux version), - We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (In beta for windows, WSL2 for the linux version),
because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines. because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines.
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description. - If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
- If your other co-developers have comments on your PR please tweak as needed. - If your other co-developers have comments on your PR please tweak as needed.
- Please also enable "Allow edits by maintainers". - Please also enable "Allow edits by maintainers".
- Please do not submit untested code. - Please do not submit untested code.
- If you do not have the affected hardware to test your code changes adequately against regressions, please indicate this, so that contributors and community members can help test your changes. - If you do not have the affected hardware to test your code changes adequately against regressions, please indicate this, so that contributors and commnunity members can help test your changes.
- If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord - If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord
## 🤝 Attestations ## 🤝 Attestations
+7 -5
View File
@@ -16,7 +16,8 @@ on:
type: string type: string
permissions: permissions:
contents: read contents: write
packages: write
jobs: jobs:
build-debian-src: build-debian-src:
@@ -27,6 +28,8 @@ jobs:
with: with:
submodules: recursive submodules: recursive
path: meshtasticd path: meshtasticd
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Install deps - name: Install deps
shell: bash shell: bash
@@ -39,8 +42,7 @@ jobs:
sudo mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control sudo mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
- name: Import GPG key - name: Import GPG key
if: github.event_name != 'pull_request' && github.event_name != 'pull_request_target' uses: crazy-max/ghaction-import-gpg@v6
uses: crazy-max/ghaction-import-gpg@v7
with: with:
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
id: gpg id: gpg
@@ -58,11 +60,11 @@ jobs:
run: debian/ci_pack_sdeb.sh run: debian/ci_pack_sdeb.sh
env: env:
SERIES: ${{ inputs.series }} SERIES: ${{ inputs.series }}
GPG_KEY_ID: ${{ steps.gpg.outputs.keyid || '' }} GPG_KEY_ID: ${{ steps.gpg.outputs.keyid }}
PKG_VERSION: ${{ steps.version.outputs.deb }} PKG_VERSION: ${{ steps.version.outputs.deb }}
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
with: with:
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
overwrite: true overwrite: true
+4 -2
View File
@@ -26,6 +26,8 @@ jobs:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
with: with:
submodules: recursive submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Build ${{ inputs.platform }} - name: Build ${{ inputs.platform }}
id: build id: build
@@ -109,7 +111,7 @@ jobs:
echo "</details>" >> $GITHUB_STEP_SUMMARY echo "</details>" >> $GITHUB_STEP_SUMMARY
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
id: upload-firmware id: upload-firmware
with: with:
name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }} name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}
@@ -125,7 +127,7 @@ jobs:
release/device-*.bat release/device-*.bat
- name: Store manifests as an artifact - name: Store manifests as an artifact
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
id: upload-manifest id: upload-manifest
with: with:
name: manifest-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }} name: manifest-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}
+30 -44
View File
@@ -4,14 +4,9 @@ on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
# trunk-ignore(checkov/CKV_GHA_7) # trunk-ignore(checkov/CKV_GHA_7)
target:
type: string
required: false
description: Choose the target board, e.g. nrf52_promicro_diy_tcxo. If blank, will find available targets.
arch: arch:
type: choice type: choice
options: options:
- all
- esp32 - esp32
- esp32s3 - esp32s3
- esp32c3 - esp32c3
@@ -20,18 +15,32 @@ on:
- rp2040 - rp2040
- rp2350 - rp2350
- stm32 - stm32
description: Choose an arch to limit the search, or 'all' to search all architectures. target:
default: all type: string
required: false
description: Choose the target board, e.g. nrf52_promicro_diy_tcxo. If blank, will find available targets.
# find-target:
# type: boolean
# default: true
# description: 'Find the available targets'
permissions: read-all permissions: read-all
jobs: jobs:
find-targets: find-targets:
if: ${{ inputs.target == '' }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
arch: arch:
- all - esp32
- esp32s3
- esp32c3
- esp32c6
- nrf52840
- rp2040
- rp2350
- stm32
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
@@ -42,37 +51,14 @@ jobs:
- run: pip install -U platformio - run: pip install -U platformio
- name: Generate matrix - name: Generate matrix
id: jsonStep id: jsonStep
env:
BUILDTARGET: ${{ inputs.target }}
MATRIXARCH: ${{ inputs.arch }}
run: | run: |
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} --level extra) TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} --level extra)
if [ "$BUILDTARGET" = "" ]; then echo "Name: $GITHUB_REF_NAME" >> $GITHUB_STEP_SUMMARY
echo "Name: $GITHUB_REF_NAME" >> $GITHUB_STEP_SUMMARY echo "Base: $GITHUB_BASE_REF" >> $GITHUB_STEP_SUMMARY
echo "Base: $GITHUB_BASE_REF" >> $GITHUB_STEP_SUMMARY echo "Arch: ${{matrix.arch}}" >> $GITHUB_STEP_SUMMARY
echo "Arch: $MATRIXARCH" >> $GITHUB_STEP_SUMMARY echo "Ref: $GITHUB_REF" >> $GITHUB_STEP_SUMMARY
echo "Ref: $GITHUB_REF" >> $GITHUB_STEP_SUMMARY echo "Targets:" >> $GITHUB_STEP_SUMMARY
echo "## 🎯 The following target boards are available to build:" >> $GITHUB_STEP_SUMMARY echo $TARGETS | jq -r 'sort_by(.board) |.[] | "- " + .board' >> $GITHUB_STEP_SUMMARY
echo "| Platform | Board |" >> $GITHUB_STEP_SUMMARY
echo "| -------- | ----- |" >> $GITHUB_STEP_SUMMARY
echo $TARGETS | jq -r 'sort_by(.board) | sort_by(.platform) |.[] | "| " + .platform + " | " + .board + " |" ' >> $GITHUB_STEP_SUMMARY
else
echo "We build this one:" >> $GITHUB_STEP_SUMMARY
ARCH=$(echo "$TARGETS" | jq --arg BUILDTARGET "$BUILDTARGET" -r '.[] | select(.board==$BUILDTARGET) | .platform')
echo "| Platform | Board |" >> $GITHUB_STEP_SUMMARY
echo "| -------- | ----- |" >> $GITHUB_STEP_SUMMARY
echo "| $ARCH | "$BUILDTARGET" |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ "$ARCH" == "" ]]; then
echo "## ❌ Error: Target "$BUILDTARGET" not found!" >> $GITHUB_STEP_SUMMARY
else
echo "## ✅ Target "$BUILDTARGET" found, proceeding to build." >> $GITHUB_STEP_SUMMARY
fi
echo "You may need to refresh this page to make the built firmware appear below." >> $GITHUB_STEP_SUMMARY
echo "arch=$ARCH" >> $GITHUB_OUTPUT
fi
outputs:
arch: ${{ steps.jsonStep.outputs.arch }}
version: version:
if: ${{ inputs.target != '' }} if: ${{ inputs.target != '' }}
@@ -92,16 +78,16 @@ jobs:
build: build:
if: ${{ inputs.target != '' && inputs.arch != 'native' }} if: ${{ inputs.target != '' && inputs.arch != 'native' }}
needs: [version, find-targets] needs: [version]
uses: ./.github/workflows/build_firmware.yml uses: ./.github/workflows/build_firmware.yml
with: with:
version: ${{ needs.version.outputs.long }} version: ${{ needs.version.outputs.long }}
pio_env: ${{ inputs.target }} pio_env: ${{ inputs.target }}
platform: ${{ needs.find-targets.outputs.arch }} platform: ${{ inputs.arch }}
gather-artifacts: gather-artifacts:
permissions: permissions:
contents: read contents: write
pull-requests: write pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [version, build] needs: [version, build]
@@ -112,7 +98,7 @@ jobs:
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v8 - uses: actions/download-artifact@v7
with: with:
path: ./ path: ./
pattern: firmware-*-* pattern: firmware-*-*
@@ -125,7 +111,7 @@ jobs:
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
- name: Repackage in single firmware zip - name: Repackage in single firmware zip
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
with: with:
name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }} name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }}
overwrite: true overwrite: true
@@ -141,7 +127,7 @@ jobs:
./Meshtastic_nRF52_factory_erase*.uf2 ./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30 retention-days: 30
- uses: actions/download-artifact@v8 - uses: actions/download-artifact@v7
with: with:
pattern: firmware-*-${{ needs.version.outputs.long }} pattern: firmware-*-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -160,7 +146,7 @@ jobs:
run: zip -j -9 -r ./firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip ./output run: zip -j -9 -r ./firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip ./output
- name: Repackage in single elfs zip - name: Repackage in single elfs zip
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
with: with:
name: debug-elfs-${{inputs.target}}-${{ needs.version.outputs.long }}.zip name: debug-elfs-${{inputs.target}}-${{ needs.version.outputs.long }}.zip
overwrite: true overwrite: true
+3 -3
View File
@@ -5,7 +5,7 @@ on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: branches:
- develop # Default branch, same as 'cron' above - master
paths: paths:
- debian/** - debian/**
- "*.rpkg" - "*.rpkg"
@@ -16,7 +16,7 @@ on:
- .github/workflows/hook_copr.yml - .github/workflows/hook_copr.yml
permissions: permissions:
contents: read contents: write
packages: write packages: write
jobs: jobs:
@@ -35,8 +35,8 @@ jobs:
series: series:
- jammy # 22.04 LTS - jammy # 22.04 LTS
- noble # 24.04 LTS - noble # 24.04 LTS
- plucky # 25.04
- questing # 25.10 - questing # 25.10
- resolute # 26.04 LTS
uses: ./.github/workflows/package_ppa.yml uses: ./.github/workflows/package_ppa.yml
with: with:
ppa_repo: ppa:meshtastic/daily ppa_repo: ppa:meshtastic/daily
+14 -23
View File
@@ -37,7 +37,7 @@ on:
value: ${{ jobs.docker-build.outputs.digest }} value: ${{ jobs.docker-build.outputs.digest }}
permissions: permissions:
contents: read contents: write
packages: write packages: write
jobs: jobs:
@@ -50,41 +50,35 @@ jobs:
uses: actions/checkout@v6 uses: actions/checkout@v6
with: with:
submodules: recursive submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Get release version string - name: Get release version string
run: | run: |
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version id: version
- name: Set up QEMU - name: Docker login
uses: docker/setup-qemu-action@v4 if: ${{ inputs.push }}
uses: docker/login-action@v3
with: with:
cache-image: true username: meshtastic
password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Docker setup - name: Docker setup
uses: docker/setup-buildx-action@v4 uses: docker/setup-buildx-action@v3
with:
# Add Google/Amazon DockerHub mirrors to buildkit config
# https://docs.docker.com/build/ci/github-actions/configure-builder/#registry-mirror
buildkitd-config-inline: |
[registry."docker.io"]
mirrors = ["mirror.gcr.io", "public.ecr.aws"]
- name: Sanitize platform string - name: Sanitize platform string
id: sanitize_platform id: sanitize_platform
# Replace slashes with underscores # Replace slashes with underscores
run: echo "cleaned_platform=${{ inputs.platform }}" | sed 's/\//_/g' >> $GITHUB_OUTPUT run: echo "cleaned_platform=${{ inputs.platform }}" | sed 's/\//_/g' >> $GITHUB_OUTPUT
- name: Docker login
if: ${{ inputs.push }}
uses: docker/login-action@v4
with:
username: meshtastic
password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
- name: Docker tag - name: Docker tag
id: meta id: meta
uses: docker/metadata-action@v6 uses: docker/metadata-action@v5
with: with:
images: meshtastic/meshtasticd images: meshtastic/meshtasticd
tags: | tags: |
@@ -92,7 +86,7 @@ jobs:
flavor: latest=false flavor: latest=false
- name: Docker build and push - name: Docker build and push
uses: docker/build-push-action@v7 uses: docker/build-push-action@v6
id: docker_variant id: docker_variant
with: with:
context: . context: .
@@ -103,6 +97,3 @@ jobs:
platforms: ${{ inputs.platform }} platforms: ${{ inputs.platform }}
build-args: | build-args: |
PIO_ENV=${{ inputs.pio_env }} PIO_ENV=${{ inputs.pio_env }}
# Cache image layers in GitHub Actions cache to speed up subsequent builds.
cache-from: type=gha
cache-to: type=gha,mode=max
+6 -4
View File
@@ -12,7 +12,7 @@ on:
type: string type: string
permissions: permissions:
contents: read contents: write
packages: write packages: write
jobs: jobs:
@@ -86,6 +86,8 @@ jobs:
uses: actions/checkout@v6 uses: actions/checkout@v6
with: with:
submodules: recursive submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Get release version string - name: Get release version string
run: | run: |
@@ -137,14 +139,14 @@ jobs:
id: tags id: tags
- name: Docker login - name: Docker login
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
username: meshtastic username: meshtastic
password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }} password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
- name: Docker meta (Debian) - name: Docker meta (Debian)
id: meta_debian id: meta_debian
uses: docker/metadata-action@v6 uses: docker/metadata-action@v5
with: with:
images: meshtastic/meshtasticd images: meshtastic/meshtasticd
tags: | tags: |
@@ -165,7 +167,7 @@ jobs:
- name: Docker meta (Alpine) - name: Docker meta (Alpine)
id: meta_alpine id: meta_alpine
uses: docker/metadata-action@v6 uses: docker/metadata-action@v5
with: with:
images: meshtastic/meshtasticd images: meshtastic/meshtasticd
tags: | tags: |
+4 -1
View File
@@ -11,7 +11,8 @@ on:
type: string type: string
permissions: permissions:
contents: read contents: write
packages: write
jobs: jobs:
build-copr-hook: build-copr-hook:
@@ -21,6 +22,8 @@ jobs:
uses: actions/checkout@v6 uses: actions/checkout@v6
with: with:
submodules: recursive submodules: recursive
ref: ${{ github.ref }}
repository: ${{ github.repository }}
- name: Trigger COPR build - name: Trigger COPR build
uses: vidplace7/copr-build@main uses: vidplace7/copr-build@main
+38 -36
View File
@@ -15,7 +15,8 @@ on:
- "**.md" - "**.md"
- version.properties - version.properties
pull_request: # Note: This is different from "pull_request". Need to specify ref when doing checkouts.
pull_request_target:
branches: branches:
- master - master
- develop - develop
@@ -28,8 +29,6 @@ on:
workflow_dispatch: workflow_dispatch:
permissions: read-all
jobs: jobs:
setup: setup:
strategy: strategy:
@@ -89,12 +88,15 @@ jobs:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
with: with:
submodules: recursive submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Check ${{ matrix.check.board }} - name: Check ${{ matrix.check.board }}
uses: meshtastic/gh-action-firmware@main uses: meshtastic/gh-action-firmware@main
with: with:
pio_platform: ${{ matrix.check.platform }} pio_platform: ${{ matrix.check.platform }}
pio_env: ${{ matrix.check.board }} pio_env: ${{ matrix.check.board }}
pio_target: check pio_target: check
pio_opts: --fail-on-defect=low
build: build:
needs: [setup, version] needs: [setup, version]
@@ -125,16 +127,9 @@ jobs:
test-native: test-native:
if: ${{ !contains(github.ref_name, 'event/') && github.repository == 'meshtastic/firmware' }} if: ${{ !contains(github.ref_name, 'event/') && github.repository == 'meshtastic/firmware' }}
permissions: # Needed for dorny/test-reporter.
contents: read
actions: read
checks: write
uses: ./.github/workflows/test_native.yml uses: ./.github/workflows/test_native.yml
docker: docker:
permissions: # Needed for pushing to GHCR.
contents: read
packages: write
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -159,6 +154,9 @@ jobs:
gather-artifacts: gather-artifacts:
# trunk-ignore(checkov/CKV2_GHA_1) # trunk-ignore(checkov/CKV2_GHA_1)
if: github.repository == 'meshtastic/firmware' if: github.repository == 'meshtastic/firmware'
permissions:
contents: write
pull-requests: write
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -176,8 +174,11 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v6 uses: actions/checkout@v6
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v8 - uses: actions/download-artifact@v7
with: with:
path: ./ path: ./
pattern: firmware-${{matrix.arch}}-* pattern: firmware-${{matrix.arch}}-*
@@ -187,7 +188,7 @@ jobs:
run: ls -R run: ls -R
- name: Repackage in single firmware zip - name: Repackage in single firmware zip
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
with: with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
overwrite: true overwrite: true
@@ -205,7 +206,7 @@ jobs:
./Meshtastic_nRF52_factory_erase*.uf2 ./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30 retention-days: 30
- uses: actions/download-artifact@v8 - uses: actions/download-artifact@v7
with: with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -224,13 +225,20 @@ jobs:
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
- name: Repackage in single elfs zip - name: Repackage in single elfs zip
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
with: with:
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }} name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
overwrite: true overwrite: true
path: ./*.elf path: ./*.elf
retention-days: 30 retention-days: 30
- uses: scruplelesswizard/comment-artifact@main
if: ${{ github.event_name == 'pull_request' }}
with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
description: "Download firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip. This artifact will be available for 90 days from creation"
github-token: ${{ secrets.GITHUB_TOKEN }}
shame: shame:
if: github.repository == 'meshtastic/firmware' if: github.repository == 'meshtastic/firmware'
continue-on-error: true continue-on-error: true
@@ -238,44 +246,42 @@ jobs:
needs: [build] needs: [build]
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request_target'
with: with:
filter: blob:none # means we download all the git history but none of the commit (except ones with checkout like the head) filter: blob:none # means we download all the git history but none of the commit (except ones with checkout like the head)
fetch-depth: 0 fetch-depth: 0
- name: Download the current manifests - name: Download the current manifests
uses: actions/download-artifact@v8 uses: actions/download-artifact@v7
with: with:
path: ./manifests-new/ path: ./manifests-new/
pattern: manifest-* pattern: manifest-*
merge-multiple: true merge-multiple: true
- name: Upload combined manifests for later commit and global stats crunching. - name: Upload combined manifests for later commit and global stats crunching.
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
id: upload-manifest id: upload-manifest
with: with:
name: manifests-${{ github.sha }} name: manifests-${{ github.sha }}
overwrite: true overwrite: true
path: manifests-new/*.mt.json path: manifests-new/*.mt.json
- name: Find the merge base - name: Find the merge base
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request_target'
run: echo "MERGE_BASE=$(git merge-base "origin/$base" "$head")" >> $GITHUB_ENV run: echo "MERGE_BASE=$(git merge-base "origin/$base" "$head")" >> $GITHUB_ENV
env: env:
base: ${{ github.base_ref }} base: ${{ github.base_ref }}
head: ${{ github.sha }} head: ${{ github.sha }}
# Currently broken (for-loop through EVERY artifact -- rate limiting) # Currently broken (for-loop through EVERY artifact -- rate limiting)
# - name: Download the old manifests # - name: Download the old manifests
# if: github.event_name == 'pull_request' # if: github.event_name == 'pull_request_target'
# run: gh run download -R "$repo" --name "manifests-$merge_base" --dir manifest-old/ # run: gh run download -R "$repo" --name "manifests-$merge_base" --dir manifest-old/
# env: # env:
# GH_TOKEN: ${{ github.token }} # GH_TOKEN: ${{ github.token }}
# merge_base: ${{ env.MERGE_BASE }} # merge_base: ${{ env.MERGE_BASE }}
# repo: ${{ github.repository }} # repo: ${{ github.repository }}
# - name: Do scan and post comment # - name: Do scan and post comment
# if: github.event_name == 'pull_request' # if: github.event_name == 'pull_request_target'
# run: python3 bin/shame.py ${{ github.event.pull_request.number }} manifests-old/ manifests-new/ # run: python3 bin/shame.py ${{ github.event.pull_request.number }} manifests-old/ manifests-new/
release-artifacts: release-artifacts:
permissions: # Needed for 'gh release upload'.
contents: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'meshtastic/firmware' }} if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'meshtastic/firmware' }}
outputs: outputs:
@@ -301,17 +307,15 @@ jobs:
id: release_notes id: release_notes
run: | run: |
chmod +x ./bin/generate_release_notes.py chmod +x ./bin/generate_release_notes.py
NOTES=$(./bin/generate_release_notes.py ${{ needs.version.outputs.long }} --compare-ref HEAD 2>release_notes.log) NOTES=$(./bin/generate_release_notes.py ${{ needs.version.outputs.long }})
echo "notes<<EOF" >> $GITHUB_OUTPUT echo "notes<<EOF" >> $GITHUB_OUTPUT
echo "$NOTES" >> $GITHUB_OUTPUT echo "$NOTES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT
echo "### Release note range" >> $GITHUB_STEP_SUMMARY
cat release_notes.log >> $GITHUB_STEP_SUMMARY
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create release - name: Create release
uses: softprops/action-gh-release@v3 uses: softprops/action-gh-release@v2
id: create_release id: create_release
with: with:
draft: true draft: true
@@ -321,14 +325,14 @@ jobs:
body: ${{ steps.release_notes.outputs.notes }} body: ${{ steps.release_notes.outputs.notes }}
- name: Download source deb - name: Download source deb
uses: actions/download-artifact@v8 uses: actions/download-artifact@v7
with: with:
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
merge-multiple: true merge-multiple: true
path: ./output/debian-src path: ./output/debian-src
- name: Download `native-tft` pio deps - name: Download `native-tft` pio deps
uses: actions/download-artifact@v8 uses: actions/download-artifact@v7
with: with:
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }} pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -352,7 +356,7 @@ jobs:
}' > firmware-${{ needs.version.outputs.long }}.json }' > firmware-${{ needs.version.outputs.long }}.json
- name: Save Release manifest artifact - name: Save Release manifest artifact
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
with: with:
name: manifest-${{ needs.version.outputs.long }} name: manifest-${{ needs.version.outputs.long }}
overwrite: true overwrite: true
@@ -369,8 +373,6 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
release-firmware: release-firmware:
permissions: # Needed for 'gh release upload'.
contents: write
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -395,7 +397,7 @@ jobs:
with: with:
python-version: 3.x python-version: 3.x
- uses: actions/download-artifact@v8 - uses: actions/download-artifact@v7
with: with:
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -412,7 +414,7 @@ jobs:
- name: Zip firmware - name: Zip firmware
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
- uses: actions/download-artifact@v8 - uses: actions/download-artifact@v7
with: with:
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }} name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -453,14 +455,14 @@ jobs:
python-version: 3.x python-version: 3.x
- name: Get firmware artifacts - name: Get firmware artifacts
uses: actions/download-artifact@v8 uses: actions/download-artifact@v7
with: with:
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }} pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
path: ./publish path: ./publish
- name: Get manifest artifact - name: Get manifest artifact
uses: actions/download-artifact@v8 uses: actions/download-artifact@v7
with: with:
pattern: manifest-${{ needs.version.outputs.long }} pattern: manifest-${{ needs.version.outputs.long }}
path: ./publish path: ./publish
@@ -468,7 +470,7 @@ jobs:
- name: Generate release notes - name: Generate release notes
run: | run: |
chmod +x ./bin/generate_release_notes.py chmod +x ./bin/generate_release_notes.py
./bin/generate_release_notes.py ${{ needs.version.outputs.long }} --compare-ref HEAD > ./publish/release_notes.md ./bin/generate_release_notes.py ${{ needs.version.outputs.long }} > ./publish/release_notes.md
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+371
View File
@@ -0,0 +1,371 @@
name: Merge Queue
# Not sure how concurrency works in merge_queue, removing for now.
# concurrency:
# group: merge-queue-${{ github.head_ref || github.run_id }}
# cancel-in-progress: true
on:
# Merge group is a special trigger that is used to trigger the workflow when a merge group is created.
merge_group:
jobs:
setup:
strategy:
fail-fast: true
matrix:
arch:
- all
- check
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.x
cache: pip
- run: pip install -U platformio
- name: Generate matrix
id: jsonStep
run: |
if [[ "$GITHUB_HEAD_REF" == "" ]]; then
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
else
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} --level pr)
fi
echo "Name: $GITHUB_REF_NAME Base: $GITHUB_BASE_REF Ref: $GITHUB_REF"
echo "${{matrix.arch}}=$TARGETS" >> $GITHUB_OUTPUT
outputs:
all: ${{ steps.jsonStep.outputs.all }}
check: ${{ steps.jsonStep.outputs.check }}
version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Get release version string
run: |
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
id: version
env:
BUILD_LOCATION: local
outputs:
long: ${{ steps.version.outputs.long }}
deb: ${{ steps.version.outputs.deb }}
check:
needs: setup
strategy:
fail-fast: true
matrix:
check: ${{ fromJson(needs.setup.outputs.check) }}
runs-on: ubuntu-latest
if: ${{ github.event_name != 'workflow_dispatch' }}
steps:
- uses: actions/checkout@v6
- name: Build base
id: base
uses: ./.github/actions/setup-base
- name: Check ${{ matrix.check.board }}
run: bin/check-all.sh ${{ matrix.check.board }}
build:
needs: [setup, version]
strategy:
matrix:
build: ${{ fromJson(needs.setup.outputs.all) }}
uses: ./.github/workflows/build_firmware.yml
with:
version: ${{ needs.version.outputs.long }}
pio_env: ${{ matrix.build.board }}
platform: ${{ matrix.build.platform }}
build-debian-src:
if: github.repository == 'meshtastic/firmware'
uses: ./.github/workflows/build_debian_src.yml
with:
series: UNRELEASED
build_location: local
secrets: inherit
package-pio-deps-native-tft:
if: ${{ github.event_name == 'workflow_dispatch' }}
uses: ./.github/workflows/package_pio_deps.yml
with:
pio_env: native-tft
secrets: inherit
test-native:
if: ${{ !contains(github.ref_name, 'event/') }}
uses: ./.github/workflows/test_native.yml
docker:
strategy:
fail-fast: false
matrix:
distro: [debian, alpine]
platform: [linux/amd64, linux/arm64, linux/arm/v7]
pio_env: [native, native-tft]
exclude:
- distro: alpine
platform: linux/arm/v7
- pio_env: native-tft
platform: linux/arm64
- pio_env: native-tft
platform: linux/arm/v7
uses: ./.github/workflows/docker_build.yml
with:
distro: ${{ matrix.distro }}
platform: ${{ matrix.platform }}
runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
pio_env: ${{ matrix.pio_env }}
push: false
gather-artifacts:
# trunk-ignore(checkov/CKV2_GHA_1)
permissions:
contents: write
pull-requests: write
strategy:
fail-fast: false
matrix:
arch:
- esp32
- esp32s3
- esp32c3
- esp32c6
- nrf52840
- rp2040
- rp2350
- stm32
runs-on: ubuntu-latest
needs: [version, build]
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v7
with:
path: ./
pattern: firmware-${{matrix.arch}}-*
merge-multiple: true
- name: Display structure of downloaded files
run: ls -R
- name: Move files up
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
- name: Repackage in single firmware zip
uses: actions/upload-artifact@v6
with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
overwrite: true
path: |
./firmware-*.bin
./firmware-*.uf2
./firmware-*.hex
./firmware-*.zip
./device-*.sh
./device-*.bat
./littlefs-*.bin
./bleota*bin
./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30
- uses: actions/download-artifact@v7
with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true
path: ./output
# For diagnostics
- name: Show artifacts
run: ls -lR
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh || true
chmod +x ./output/device-update.sh || true
- name: Zip firmware
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
- name: Repackage in single elfs zip
uses: actions/upload-artifact@v6
with:
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
overwrite: true
path: ./*.elf
retention-days: 30
- uses: scruplelesswizard/comment-artifact@main
if: ${{ github.event_name == 'pull_request' }}
with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
description: "Download firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip. This artifact will be available for 90 days from creation"
github-token: ${{ secrets.GITHUB_TOKEN }}
release-artifacts:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }}
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
needs:
- version
- gather-artifacts
- build-debian-src
- package-pio-deps-native-tft
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Create release
uses: softprops/action-gh-release@v2
id: create_release
with:
draft: true
prerelease: true
name: Meshtastic Firmware ${{ needs.version.outputs.long }} Alpha
tag_name: v${{ needs.version.outputs.long }}
body: |
Autogenerated by github action, developer should edit as required before publishing...
- name: Download source deb
uses: actions/download-artifact@v7
with:
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
merge-multiple: true
path: ./output/debian-src
- name: Download `native-tft` pio deps
uses: actions/download-artifact@v7
with:
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
merge-multiple: true
path: ./output/pio-deps-native-tft
- name: Zip Linux sources
working-directory: output
run: |
zip -j -9 -r ./meshtasticd-${{ needs.version.outputs.deb }}-src.zip ./debian-src
zip -9 -r ./platformio-deps-native-tft-${{ needs.version.outputs.long }}.zip ./pio-deps-native-tft
# For diagnostics
- name: Display structure of downloaded files
run: ls -lR
- name: Add Linux sources to GtiHub Release
# Only run when targeting master branch with workflow_dispatch
if: ${{ github.ref_name == 'master' }}
run: |
gh release upload v${{ needs.version.outputs.long }} ./output/meshtasticd-${{ needs.version.outputs.deb }}-src.zip
gh release upload v${{ needs.version.outputs.long }} ./output/platformio-deps-native-tft-${{ needs.version.outputs.long }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
release-firmware:
strategy:
fail-fast: false
matrix:
arch:
- esp32
- esp32s3
- esp32c3
- esp32c6
- nrf52840
- rp2040
- rp2350
- stm32
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [release-artifacts, version]
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: 3.x
- uses: actions/download-artifact@v7
with:
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true
path: ./output
- name: Display structure of downloaded files
run: ls -lR
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh || true
chmod +x ./output/device-update.sh || true
- name: Zip firmware
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
- uses: actions/download-artifact@v7
with:
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true
path: ./elfs
- name: Zip debug elfs
run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./elfs
# For diagnostics
- name: Display structure of downloaded files
run: ls -lR
- name: Add bins and debug elfs to GitHub Release
# Only run when targeting master branch with workflow_dispatch
if: ${{ github.ref_name == 'master' }}
run: |
gh release upload v${{ needs.version.outputs.long }} ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip
gh release upload v${{ needs.version.outputs.long }} ./debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-firmware:
runs-on: ubuntu-24.04
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [release-firmware, version]
env:
targets: |-
esp32,esp32s3,esp32c3,esp32c6,nrf52840,rp2040,rp2350,stm32
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: 3.x
- uses: actions/download-artifact@v7
with:
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
merge-multiple: true
path: ./publish
- name: Publish firmware to meshtastic.github.io
uses: peaceiris/actions-gh-pages@v4
env:
# On event/* branches, use the event name as the destination prefix
DEST_PREFIX: ${{ contains(github.ref_name, 'event/') && format('{0}/', github.ref_name) || '' }}
with:
deploy_key: ${{ secrets.DIST_PAGES_DEPLOY_KEY }}
external_repository: meshtastic/meshtastic.github.io
publish_branch: master
publish_dir: ./publish
destination_dir: ${{ env.DEST_PREFIX }}firmware-${{ needs.version.outputs.long }}
keep_files: true
user_name: github-actions[bot]
user_email: github-actions[bot]@users.noreply.github.com
commit_message: ${{ needs.version.outputs.long }}
enable_jekyll: true
+5 -5
View File
@@ -38,7 +38,7 @@ jobs:
- name: Apply quality label if needed - name: Apply quality label if needed
if: steps.quality.outputs.response != '' && steps.quality.outputs.response != 'ok' if: steps.quality.outputs.response != '' && steps.quality.outputs.response != 'ok'
uses: actions/github-script@v9 uses: actions/github-script@v8
env: env:
QUALITY_LABEL: ${{ steps.quality.outputs.response }} QUALITY_LABEL: ${{ steps.quality.outputs.response }}
with: with:
@@ -80,7 +80,7 @@ jobs:
# ───────────────────────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────────────────────
- name: Determine if completeness check should be skipped - name: Determine if completeness check should be skipped
if: steps.quality.outputs.response == 'ok' || steps.quality.outputs.response == '' if: steps.quality.outputs.response == 'ok' || steps.quality.outputs.response == ''
uses: actions/github-script@v9 uses: actions/github-script@v8
id: check-skip id: check-skip
with: with:
script: | script: |
@@ -134,7 +134,7 @@ jobs:
- name: Process analysis result - name: Process analysis result
if: (steps.quality.outputs.response == 'ok' || steps.quality.outputs.response == '') && steps.check-skip.outputs.should_skip != 'true' && steps.analysis.outputs.response != '' if: (steps.quality.outputs.response == 'ok' || steps.quality.outputs.response == '') && steps.check-skip.outputs.should_skip != 'true' && steps.analysis.outputs.response != ''
uses: actions/github-script@v9 uses: actions/github-script@v8
id: process id: process
env: env:
AI_RESPONSE: ${{ steps.analysis.outputs.response }} AI_RESPONSE: ${{ steps.analysis.outputs.response }}
@@ -174,7 +174,7 @@ jobs:
- name: Apply triage label - name: Apply triage label
if: steps.process.outputs.label != '' && steps.process.outputs.label != 'none' if: steps.process.outputs.label != '' && steps.process.outputs.label != 'none'
uses: actions/github-script@v9 uses: actions/github-script@v8
env: env:
LABEL_NAME: ${{ steps.process.outputs.label }} LABEL_NAME: ${{ steps.process.outputs.label }}
with: with:
@@ -200,7 +200,7 @@ jobs:
- name: Comment on issue - name: Comment on issue
if: steps.process.outputs.should_comment == 'true' if: steps.process.outputs.should_comment == 'true'
uses: actions/github-script@v9 uses: actions/github-script@v8
env: env:
COMMENT_BODY: ${{ steps.process.outputs.comment_body }} COMMENT_BODY: ${{ steps.process.outputs.comment_body }}
with: with:
+3 -3
View File
@@ -22,7 +22,7 @@ jobs:
# Step 1: Check if PR already has automation/type labels (skip if so) # Step 1: Check if PR already has automation/type labels (skip if so)
# ───────────────────────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────────────────────
- name: Check existing labels - name: Check existing labels
uses: actions/github-script@v9 uses: actions/github-script@v8
id: check-labels id: check-labels
with: with:
script: | script: |
@@ -58,7 +58,7 @@ jobs:
- name: Apply quality label if needed - name: Apply quality label if needed
if: steps.check-labels.outputs.skip_all != 'true' && steps.quality.outputs.response != '' && steps.quality.outputs.response != 'ok' if: steps.check-labels.outputs.skip_all != 'true' && steps.quality.outputs.response != '' && steps.quality.outputs.response != 'ok'
uses: actions/github-script@v9 uses: actions/github-script@v8
id: quality-label id: quality-label
env: env:
QUALITY_LABEL: ${{ steps.quality.outputs.response }} QUALITY_LABEL: ${{ steps.quality.outputs.response }}
@@ -113,7 +113,7 @@ jobs:
- name: Apply type label - name: Apply type label
if: steps.check-labels.outputs.skip_all != 'true' && steps.check-labels.outputs.has_type_label != 'true' && steps.classify.outputs.response != '' if: steps.check-labels.outputs.skip_all != 'true' && steps.check-labels.outputs.has_type_label != 'true' && steps.classify.outputs.response != ''
uses: actions/github-script@v9 uses: actions/github-script@v8
env: env:
TYPE_LABEL: ${{ steps.classify.outputs.response }} TYPE_LABEL: ${{ steps.classify.outputs.response }}
with: with:
+3 -2
View File
@@ -18,7 +18,8 @@ on:
type: string type: string
permissions: permissions:
contents: read contents: write
packages: write
jobs: jobs:
build-debian-src: build-debian-src:
@@ -57,7 +58,7 @@ jobs:
id: version id: version
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v8 uses: actions/download-artifact@v7
with: with:
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
merge-multiple: true merge-multiple: true
+5 -12
View File
@@ -16,7 +16,8 @@ on:
type: string type: string
permissions: permissions:
contents: read contents: write
packages: write
jobs: jobs:
pkg-pio-libdeps: pkg-pio-libdeps:
@@ -26,6 +27,8 @@ jobs:
uses: actions/checkout@v6 uses: actions/checkout@v6
with: with:
submodules: recursive submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v6 uses: actions/setup-python@v6
@@ -51,19 +54,9 @@ jobs:
PLATFORMIO_LIBDEPS_DIR: pio/libdeps PLATFORMIO_LIBDEPS_DIR: pio/libdeps
PLATFORMIO_PACKAGES_DIR: pio/packages PLATFORMIO_PACKAGES_DIR: pio/packages
PLATFORMIO_CORE_DIR: pio/core PLATFORMIO_CORE_DIR: pio/core
PLATFORMIO_SETTING_ENABLE_TELEMETRY: 0
PLATFORMIO_SETTING_CHECK_PLATFORMIO_INTERVAL: 3650
PLATFORMIO_SETTING_CHECK_PRUNE_SYSTEM_THRESHOLD: 10240
- name: Mangle platformio cache
# Add "1" to epoch-timestamps of all downloads in the cache.
# This is a hack to prevent internet access at build-time.
run: |
cp pio/core/.cache/downloads/usage.db pio/core/.cache/downloads/usage.db.bak
jq -c 'with_entries(.value |= (. | tostring + "1" | tonumber))' pio/core/.cache/downloads/usage.db.bak > pio/core/.cache/downloads/usage.db
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
with: with:
name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }} name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }}
overwrite: true overwrite: true
+10 -45
View File
@@ -5,8 +5,6 @@ on:
secrets: secrets:
PPA_GPG_PRIVATE_KEY: PPA_GPG_PRIVATE_KEY:
required: true required: true
PPA_SFTP_PRIVATE_KEY:
required: true
inputs: inputs:
ppa_repo: ppa_repo:
description: Meshtastic PPA to target description: Meshtastic PPA to target
@@ -18,7 +16,8 @@ on:
type: string type: string
permissions: permissions:
contents: read contents: write
packages: write
jobs: jobs:
build-debian-src: build-debian-src:
@@ -29,7 +28,6 @@ jobs:
build_location: ppa build_location: ppa
package-ppa: package-ppa:
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
needs: build-debian-src needs: build-debian-src
steps: steps:
@@ -38,15 +36,17 @@ jobs:
with: with:
submodules: recursive submodules: recursive
path: meshtasticd path: meshtasticd
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Install deps - name: Install deps
shell: bash shell: bash
run: | run: |
sudo apt-get update -y --fix-missing sudo apt-get update -y --fix-missing
sudo apt-get install -y dput openssh-client sudo apt-get install -y dput
- name: Import GPG key - name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v7 uses: crazy-max/ghaction-import-gpg@v6
with: with:
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
id: gpg id: gpg
@@ -60,7 +60,7 @@ jobs:
id: version id: version
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v8 uses: actions/download-artifact@v7
with: with:
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
merge-multiple: true merge-multiple: true
@@ -68,42 +68,7 @@ jobs:
- name: Display structure of downloaded files - name: Display structure of downloaded files
run: ls -lah run: ls -lah
- name: Trust Launchpad's SSH key - name: Publish with dput
if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
run: | run: |
mkdir -p ~/.ssh dput ${{ inputs.ppa_repo }} meshtasticd_${{ steps.version.outputs.deb }}~${{ inputs.series }}_source.changes
ssh-keyscan -H ppa.launchpad.net >> ~/.ssh/known_hosts
- name: Setup dput config
env:
ppa_login: meshtasticorg
run: |
sudo tee /etc/meshtastic-dput.cf >/dev/null <<EOF
[ppa]
fqdn = ppa.launchpad.net
method = ftp
incoming = ~%(ppa)s
login = anonymous
[ssh-ppa]
fqdn = ppa.launchpad.net
method = sftp
incoming = ~%(ssh-ppa)s
login = ${ppa_login}
EOF
- name: Import SSH key
uses: webfactory/ssh-agent@v0.10.0
with:
ssh-private-key: ${{ secrets.PPA_SFTP_PRIVATE_KEY }}
id: ssh
- name: Publish with dput (sftp)
timeout-minutes: 30 # dput is terrible, sometimes runs 'forever'
env:
up_ppa_repo: ${{ inputs.ppa_repo }}
up_series: ${{ inputs.series }}
up_version: ${{ steps.version.outputs.deb }}
run: >
dput -c /etc/meshtastic-dput.cf
ssh-${up_ppa_repo}
meshtasticd_${up_version}~${up_series}_source.changes
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check for PR labels - name: Check for PR labels
uses: actions/github-script@v9 uses: actions/github-script@v8
with: with:
script: | script: |
const labels = context.payload.pull_request.labels.map(label => label.name); const labels = context.payload.pull_request.labels.map(label => label.name);
+2 -2
View File
@@ -50,7 +50,7 @@ jobs:
- name: Download test artifacts - name: Download test artifacts
if: needs.native-tests.result != 'skipped' if: needs.native-tests.result != 'skipped'
uses: actions/download-artifact@v8 uses: actions/download-artifact@v7
with: with:
name: platformio-test-report-${{ steps.version.outputs.long }} name: platformio-test-report-${{ steps.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -177,7 +177,7 @@ jobs:
- name: Comment test results on PR - name: Comment test results on PR
if: github.event_name == 'pull_request' && needs.native-tests.result != 'skipped' if: github.event_name == 'pull_request' && needs.native-tests.result != 'skipped'
uses: actions/github-script@v9 uses: actions/github-script@v8
with: with:
script: | script: |
const fs = require('fs'); const fs = require('fs');
+1 -1
View File
@@ -23,8 +23,8 @@ jobs:
series: series:
- jammy # 22.04 LTS - jammy # 22.04 LTS
- noble # 24.04 LTS - noble # 24.04 LTS
- plucky # 25.04
- questing # 25.10 - questing # 25.10
- resolute # 26.04 LTS
uses: ./.github/workflows/package_ppa.yml uses: ./.github/workflows/package_ppa.yml
with: with:
ppa_repo: |- ppa_repo: |-
+1 -1
View File
@@ -33,7 +33,7 @@ jobs:
# step 3 # step 3
- name: save report as pipeline artifact - name: save report as pipeline artifact
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
with: with:
name: report.sarif name: report.sarif
overwrite: true overwrite: true
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
steps: steps:
- name: Stale PR+Issues - name: Stale PR+Issues
uses: actions/stale@v10.2.0 uses: actions/stale@v10.1.1
with: with:
days-before-stale: 45 days-before-stale: 45
stale-issue-message: This issue has not had any comment or update in the last month. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days. stale-issue-message: This issue has not had any comment or update in the last month. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days.
+14 -7
View File
@@ -16,6 +16,8 @@ jobs:
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
with: with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
submodules: recursive submodules: recursive
- name: Setup native build - name: Setup native build
@@ -57,7 +59,7 @@ jobs:
id: version id: version
- name: Save coverage information - name: Save coverage information
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
if: always() # run this step even if previous step failed if: always() # run this step even if previous step failed
with: with:
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }} name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }}
@@ -70,6 +72,8 @@ jobs:
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
with: with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
submodules: recursive submodules: recursive
- name: Setup native build - name: Setup native build
@@ -90,7 +94,7 @@ jobs:
- name: Save test results - name: Save test results
if: always() # run this step even if previous step failed if: always() # run this step even if previous step failed
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
with: with:
name: platformio-test-report-${{ steps.version.outputs.long }} name: platformio-test-report-${{ steps.version.outputs.long }}
overwrite: true overwrite: true
@@ -104,7 +108,7 @@ jobs:
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative. sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
- name: Save coverage information - name: Save coverage information
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
if: always() # run this step even if previous step failed if: always() # run this step even if previous step failed
with: with:
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }} name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }}
@@ -124,26 +128,29 @@ jobs:
if: always() if: always()
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Get release version string - name: Get release version string
run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT run: echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version id: version
- name: Download test artifacts - name: Download test artifacts
uses: actions/download-artifact@v8 uses: actions/download-artifact@v7
with: with:
name: platformio-test-report-${{ steps.version.outputs.long }} name: platformio-test-report-${{ steps.version.outputs.long }}
merge-multiple: true merge-multiple: true
- name: Test Report - name: Test Report
uses: dorny/test-reporter@v3.0.0 uses: dorny/test-reporter@v2.5.0
with: with:
name: PlatformIO Tests name: PlatformIO Tests
path: testreport.xml path: testreport.xml
reporter: java-junit reporter: java-junit
- name: Download coverage artifacts - name: Download coverage artifacts
uses: actions/download-artifact@v8 uses: actions/download-artifact@v7
with: with:
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }} pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }}
path: code-coverage-report path: code-coverage-report
@@ -156,7 +163,7 @@ jobs:
genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report
- name: Save Code Coverage Report - name: Save Code Coverage Report
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v6
with: with:
name: code-coverage-report-${{ steps.version.outputs.long }} name: code-coverage-report-${{ steps.version.outputs.long }}
path: code-coverage-report path: code-coverage-report
+1 -1
View File
@@ -52,7 +52,7 @@ jobs:
node-version: 24 node-version: 24
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v6 uses: pnpm/action-setup@v4
with: with:
version: latest version: latest
+1 -1
View File
@@ -6,7 +6,7 @@ permissions: read-all
jobs: jobs:
update-protobufs: update-protobufs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: # Needed for peter-evans/create-pull-request. permissions:
contents: write contents: write
pull-requests: write pull-requests: write
steps: steps:
+13 -13
View File
@@ -4,31 +4,31 @@ cli:
plugins: plugins:
sources: sources:
- id: trunk - id: trunk
ref: v1.7.6 ref: v1.7.4
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- checkov@3.2.517 - checkov@3.2.501
- renovate@43.110.9 - renovate@43.10.3
- prettier@3.8.1 - prettier@3.8.1
- trufflehog@3.94.3 - trufflehog@3.93.3
- yamllint@1.38.0 - yamllint@1.38.0
- bandit@1.9.4 - bandit@1.9.3
- trivy@0.69.3 - trivy@0.69.1
- taplo@0.10.0 - taplo@0.10.0
- ruff@0.15.9 - ruff@0.15.1
- isort@8.0.1 - isort@7.0.0
- markdownlint@0.48.0 - markdownlint@0.47.0
- oxipng@10.1.0 - oxipng@10.1.0
- svgo@4.0.1 - svgo@4.0.0
- actionlint@1.7.12 - actionlint@1.7.10
- flake8@7.3.0 - flake8@7.3.0
- hadolint@2.14.0 - hadolint@2.14.0
- shfmt@3.6.0 - shfmt@3.6.0
- shellcheck@0.11.0 - shellcheck@0.11.0
- black@26.3.1 - black@26.1.0
- git-diff-check - git-diff-check
- gitleaks@8.30.1 - gitleaks@8.30.0
- clang-format@16.0.3 - clang-format@16.0.3
ignore: ignore:
- linters: [ALL] - linters: [ALL]
-26
View File
@@ -1,26 +0,0 @@
# Lightweight container for running native PlatformIO tests on non-Linux hosts
FROM python:3.14-slim-trixie
ENV DEBIAN_FRONTEND=noninteractive
ENV PIP_ROOT_USER_ACTION=ignore
# hadolint ignore=DL3008
RUN apt-get update && apt-get install --no-install-recommends -y \
g++ git ca-certificates pkg-config \
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev libuv1-dev \
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev \
libx11-dev libinput-dev libxkbcommon-x11-dev libsqlite3-dev libsdl2-dev \
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
&& pip install --no-cache-dir platformio==6.1.19 \
&& useradd --create-home --shell /usr/sbin/nologin meshtastic
WORKDIR /firmware
RUN chown -R meshtastic:meshtastic /firmware
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD platformio --version || exit 1
USER meshtastic
# Run tests by default; override with docker run args for specific filters
CMD ["platformio", "test", "-e", "coverage", "-v"]
+1 -1
View File
@@ -23,4 +23,4 @@ for BOARD in $BOARDS; do
CHECK="${CHECK} -e ${BOARD}" CHECK="${CHECK} -e ${BOARD}"
done done
pio check --flags "-DAPP_VERSION=${APP_VERSION} --suppressions-list=suppressions.txt --inline-suppr" $CHECK --skip-packages --pattern="src/" --fail-on-defect=low --fail-on-defect=medium --fail-on-defect=high pio check --flags "-DAPP_VERSION=${APP_VERSION} --suppressions-list=suppressions.txt --inline-suppr" $CHECK --skip-packages --pattern="src/" --fail-on-defect=medium --fail-on-defect=high
-2
View File
@@ -187,7 +187,6 @@ Logging:
LogLevel: info # debug, info, warn, error LogLevel: info # debug, info, warn, error
# TraceFile: /var/log/meshtasticd.json # TraceFile: /var/log/meshtasticd.json
# JSONFile: /packets.json # File location for JSON output of decoded packets # JSONFile: /packets.json # File location for JSON output of decoded packets
# JSONFileRotate: 60 # Rotate JSON file every N minutes, or 0 for no rotation
# JSONFilter: position # filter for packets to save to JSON file # JSONFilter: position # filter for packets to save to JSON file
# AsciiLogs: true # default if not specified is !isatty() on stdout # AsciiLogs: true # default if not specified is !isatty() on stdout
@@ -215,4 +214,3 @@ General:
AvailableDirectory: /etc/meshtasticd/available.d/ AvailableDirectory: /etc/meshtasticd/available.d/
# MACAddress: AA:BB:CC:DD:EE:FF # MACAddress: AA:BB:CC:DD:EE:FF
# MACAddressSource: eth0 # MACAddressSource: eth0
# APIPort: 4403
@@ -1,9 +1,3 @@
Meta:
name: BananaPi-BPI-R4-sx1262
support: community
compatible:
- bananapi_bpi-r4 # OpenWrt target
Lora: Lora:
Module: sx1262 # BananaPi-BPI-R4 SPI via 26p GPIO Header Module: sx1262 # BananaPi-BPI-R4 SPI via 26p GPIO Header
## CS: 28 ## CS: 28
@@ -1,10 +1,4 @@
## https://www.mikroe.com/lr-iot-click ## https://www.mikroe.com/lr-iot-click
Meta:
name: OpenWRT One mikroBUS LR-IOT-CLICK
support: community
compatible:
- openwrt_one # OpenWrt target
Lora: Lora:
Module: lr1110 # OpenWRT ONE mikroBUS with LR-IOT-CLICK Module: lr1110 # OpenWRT ONE mikroBUS with LR-IOT-CLICK
# CS: 25 # CS: 25
@@ -1,9 +1,3 @@
Meta:
name: OpenWRT One mikroBUS sx1262
support: community
compatible:
- openwrt_one # OpenWrt target
Lora: Lora:
Module: sx1262 Module: sx1262
IRQ: 10 IRQ: 10
-28
View File
@@ -1,28 +0,0 @@
# meshtasticd configuration files
This directory contains YAML configuration files for meshtasticd. Each file describes a specific hardware configuration, including the LoRa module and pin assignments. These configurations are used by meshtasticd to correctly interface with the hardware.
## Metadata structure
Each configuration file includes a `Meta` section that provides information about the configuration.
This configuration is consumed by configuration-selection tools.
```yaml
Meta:
name: MeshAdv-Pi E22-900M30S # A unique identifier for this configuration.
support: community # community, official, or deprecated; determined by Meshtastic Leads.
compatible: # A list of compatible products or platforms.
- raspberry-pi
```
`name`: A unique identifier for the configuration, typically reflecting the hardware it supports.
`support`: Indicates the level of support for this configuration. It can be one of the following:
- `community`: Supported by the Meshtastic community. Meshtastic Members may not possess, or have not tested this configuration.
- `official`: Fully supported by Meshtastic. Meshtastic Members have tested and verified this configuration.
- `deprecated`: No longer recommended for deployment by Meshtastic.
`compatible`: A list of compatible products or platforms that can use this configuration.
This will vary depending on the intended use case / platform.
Multiple compatible entries can be included. E.g. Armbian `BOARD` value or OpenWrt `TARGET` value.
These tags can be consumed by different configuration-selection tools, filtering based upon their platform/etc.
-6
View File
@@ -1,9 +1,3 @@
Meta:
name: Waveshare 1.44inch LCD HAT
support: community
compatible:
- raspberry-pi
### Waveshare 1.44inch LCD HAT ### Waveshare 1.44inch LCD HAT
Display: Display:
Panel: ST7735S Panel: ST7735S
-6
View File
@@ -1,9 +1,3 @@
Meta:
name: Waveshare 2.8inch LCD HAT
support: community
compatible:
- raspberry-pi
Display: Display:
### Waveshare 2.8inch RPi LCD ### Waveshare 2.8inch RPi LCD
@@ -1,30 +0,0 @@
---
Lora:
## Ebyte E80-900M22S
## This is a bit experimental
##
##
Module: lr1121
gpiochip: 1 # subtract 32 from the gpio numbers
DIO3_TCXO_VOLTAGE: 1.8
CS: 16 #pin6 / GPIO48 1C0
IRQ: 23 #pin17 / GPIO55 1C7
Busy: 22 #pin16 / GPIO54 1C6
Reset: 25 #pin13 / GPIO57 1D1
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
spiSpeed: 2000000
rfswitch_table:
pins: [DIO5, DIO6, DIO7]
MODE_STBY: [LOW, LOW, LOW]
MODE_RX: [LOW, HIGH, LOW]
MODE_TX: [HIGH, HIGH, LOW]
MODE_TX_HP: [HIGH, LOW, LOW]
MODE_TX_HF: [LOW, LOW, LOW]
MODE_GNSS: [LOW, LOW, HIGH]
MODE_WIFI: [LOW, LOW, LOW]
General:
MACAddressSource: eth0
@@ -1,46 +0,0 @@
---
Lora:
## Ebyte E80-900M22S
## This is a bit experimental
##
##
Module: lr1121
gpiochip: 1 # subtract 32 from the gpio numbers
DIO3_TCXO_VOLTAGE: 1.8
CS: 16 #pin6 / GPIO48 1C0
IRQ: 23 #pin17 / GPIO55 1C7
Busy: 22 #pin16 / GPIO54 1C6
Reset: 25 #pin13 / GPIO57 1D1
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
spiSpeed: 2000000
rfswitch_table:
pins:
- DIO5
- DIO6
MODE_STBY:
- LOW
- LOW
MODE_RX:
- HIGH
- LOW
MODE_TX:
- HIGH
- HIGH
MODE_TX_HP:
- LOW
- HIGH
MODE_TX_HF:
- LOW
- LOW
MODE_GNSS:
- LOW
- LOW
MODE_WIFI:
- LOW
- LOW
General:
MACAddressSource: eth0
@@ -1,10 +1,4 @@
--- ---
Meta:
name: Femtofox Ebyte E80-900M22S with TCXO
support: community
compatible:
- luckfox-pico-mini # Armbian
Lora: Lora:
## Ebyte E80-900M22S ## Ebyte E80-900M22S
## This is a bit experimental ## This is a bit experimental
@@ -18,5 +12,9 @@ Lora:
Busy: 22 #pin16 / GPIO54 1C6 Busy: 22 #pin16 / GPIO54 1C6
Reset: 25 #pin13 / GPIO57 1D1 Reset: 25 #pin13 / GPIO57 1D1
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19) spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
spiSpeed: 2000000 spiSpeed: 2000000
General:
MACAddressSource: eth0
@@ -1,10 +1,4 @@
--- ---
Meta:
name: Femtofox SX1262 TCXO
support: community
compatible:
- luckfox-pico-mini # Armbian
Lora: Lora:
## Ebyte E22-900M30S, E22-900M22S with or without external RF switching setup ## Ebyte E22-900M30S, E22-900M22S with or without external RF switching setup
## HT-RA62 (Has internal switching, but whatever) ## HT-RA62 (Has internal switching, but whatever)
@@ -22,3 +16,6 @@ Lora:
# TXen: bridge to DIO2 on E22 module # TXen: bridge to DIO2 on E22 module
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19) spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
spiSpeed: 2000000 spiSpeed: 2000000
General:
MACAddressSource: eth0
@@ -1,10 +1,4 @@
--- ---
Meta:
name: Femtofox SX1262 XTAL
support: community
compatible:
- luckfox-pico-mini # Armbian
Lora: Lora:
## Ebyte E22-900MM22S with no external RF switching setup ## Ebyte E22-900MM22S with no external RF switching setup
## Waveshare SX126X XXXM, AI Thinker RA-01SH ## Waveshare SX126X XXXM, AI Thinker RA-01SH
@@ -22,3 +16,6 @@ Lora:
# TXen: bridge to DIO2 on E22 module # TXen: bridge to DIO2 on E22 module
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19) spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
spiSpeed: 2000000 spiSpeed: 2000000
General:
MACAddressSource: eth0
@@ -1,30 +0,0 @@
---
Lora:
## Ebyte E80-900M22S
## This is a bit experimental
##
##
Module: lr1121
gpiochip: 1 # subtract 32 from the gpio numbers
DIO3_TCXO_VOLTAGE: 1.8
CS: 16 #pin6 / GPIO48 1C0
IRQ: 23 #pin17 / GPIO55 1C7
Busy: 22 #pin16 / GPIO54 1C6
Reset: 25 #pin13 / GPIO57 1D1
spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19)
spiSpeed: 2000000
rfswitch_table:
pins: [DIO5, DIO6, DIO7]
MODE_STBY: [LOW, LOW, LOW]
MODE_RX: [LOW, LOW, LOW]
MODE_TX: [LOW, HIGH, LOW]
MODE_TX_HP: [HIGH, LOW, LOW]
# MODE_TX_HF: []
# MODE_GNSS: []
MODE_WIFI: [LOW, LOW, LOW]
General:
MACAddressSource: eth0
-6
View File
@@ -1,9 +1,3 @@
Meta:
name: Adafruit RFM9x
support: deprecated
compatible:
- raspberry-pi
Lora: Lora:
Module: RF95 # Adafruit RFM9x Module: RF95 # Adafruit RFM9x
Reset: 25 Reset: 25
-6
View File
@@ -1,11 +1,5 @@
# MeshAdv-Pi E22-900M30S # MeshAdv-Pi E22-900M30S
# https://github.com/chrismyers2000/MeshAdv-Pi-Hat # https://github.com/chrismyers2000/MeshAdv-Pi-Hat
Meta:
name: MeshAdv-Pi E22-900M30S
support: community
compatible:
- raspberry-pi
Lora: Lora:
Module: sx1262 Module: sx1262
CS: 21 CS: 21
@@ -1,11 +1,5 @@
# MeshAdv Mini E22-900M22S # MeshAdv Mini E22-900M22S
# https://github.com/chrismyers2000/MeshAdv-Mini # https://github.com/chrismyers2000/MeshAdv-Mini
Meta:
name: MeshAdv Mini E22-900M22S
support: community
compatible:
- raspberry-pi
Lora: Lora:
Module: sx1262 # Ebyte E22-900M22S Module: sx1262 # Ebyte E22-900M22S
CS: 8 CS: 8
+1 -10
View File
@@ -1,20 +1,11 @@
Meta:
name: RAK6421 + RAK13300 Slot 1
support: official
compatible:
- raspberry-pi
Lora: Lora:
### RAK13300 in Slot 1 ### RAK13300in Slot 1
Module: sx1262 Module: sx1262
IRQ: 22 #IO6 IRQ: 22 #IO6
Reset: 16 # IO4 Reset: 16 # IO4
Busy: 24 # IO5 Busy: 24 # IO5
# Ant_sw: 13 # IO3 # Ant_sw: 13 # IO3
Enable_Pins:
- 12
- 13
DIO3_TCXO_VOLTAGE: true DIO3_TCXO_VOLTAGE: true
DIO2_AS_RF_SWITCH: true DIO2_AS_RF_SWITCH: true
spidev: spidev0.0 spidev: spidev0.0
+1 -10
View File
@@ -1,17 +1,8 @@
Meta:
name: RAK6421 + RAK13300 Slot 2
support: official
compatible:
- raspberry-pi
Lora: Lora:
### RAK13300 in Slot 2 pins ### RAK13300in Slot 2 pins
IRQ: 18 #IO6 IRQ: 18 #IO6
Reset: 24 # IO4 Reset: 24 # IO4
Busy: 19 # IO5 Busy: 19 # IO5
# Ant_sw: 23 # IO3 # Ant_sw: 23 # IO3
Enable_Pins:
- 26
- 23
spidev: spidev0.1 spidev: spidev0.1
# CS: 7 # CS: 7
@@ -1,22 +0,0 @@
Meta:
name: RAK6421 + RAK13302 Slot 1
support: official
compatible:
- raspberry-pi
Lora:
### RAK13302 in Slot 1
Module: sx1262
IRQ: 22 #IO6
Reset: 16 # IO4
Busy: 24 # IO5
# Ant_sw: 13 # IO3
Enable_Pins:
- 12
- 13
DIO3_TCXO_VOLTAGE: true
DIO2_AS_RF_SWITCH: true
spidev: spidev0.0
# CS: 8
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
@@ -1,18 +0,0 @@
Meta:
name: RAK6421 + RAK13302 Slot 2
support: official
compatible:
- raspberry-pi
Lora:
### RAK13302 in Slot 2 pins
IRQ: 18 #IO6
Reset: 24 # IO4
Busy: 19 # IO5
# Ant_sw: 23 # IO3
Enable_Pins:
- 26
- 23
spidev: spidev0.1
# CS: 7
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
@@ -1,39 +0,0 @@
# MeshAdv-Pi E22-900M30S
# https://github.com/chrismyers2000/MeshAdv-Pi-Hat
Meta:
name: MeshAdv-Pi E22-900M30S
support: community
compatible:
- ebyte-ecb41-pge # Armbian
Lora:
Module: sx1262
CS: # GPIO0_A1 (physical 40)
pin: 1
gpiochip: 0
line: 1
IRQ: # GPIO0_A3 (physical 36)
pin: 3
gpiochip: 0
line: 3
Busy: # GPIO0_A0 (physical 38)
pin: 0
gpiochip: 0
line: 0
Reset: # GPIO0_B4 (physical 12)
pin: 12
gpiochip: 0
line: 12
TXen: # GPIO1_D1 (physical 33)
pin: 57
gpiochip: 1
line: 25
RXen: # GPIO1_B3 (physical 32)
pin: 43
gpiochip: 1
line: 11
DIO3_TCXO_VOLTAGE: true
# Only for E22-900M33S:
# Limit the output power to 8 dBm
# SX126X_MAX_POWER: 8
spidev: spidev0.0
@@ -1,33 +0,0 @@
# MeshAdv Mini E22-900M22S
# https://github.com/chrismyers2000/MeshAdv-Mini
Meta:
name: MeshAdv Mini E22-900M22S
support: community
compatible:
- ebyte-ecb41-pge # Armbian
Lora:
Module: sx1262 # Ebyte E22-900M22S
CS: # GPIO0_B6 (physical 24, SPI1_CSN0)
pin: 14
gpiochip: 0
line: 14
IRQ: # GPIO0_A3 (physical 36)
pin: 3
gpiochip: 0
line: 3
Busy: # GPIO0_A0 (physical 38)
pin: 0
gpiochip: 0
line: 0
Reset: # GPIO1_C3 (physical 18)
pin: 51
gpiochip: 1
line: 19
RXen: # GPIO1_B3 (physical 32)
pin: 43
gpiochip: 1
line: 11
DIO2_AS_RF_SWITCH: true
DIO3_TCXO_VOLTAGE: true
spidev: spidev0.0
@@ -1,38 +0,0 @@
Meta:
name: RAK6421 + RAK13300 Slot 1
support: community # Promote when tested
compatible:
- ebyte-ecb41-pge # Armbian
Lora:
Module: sx1262
IRQ: # GPIO0_A5 (IO6, physical 15)
pin: 5
gpiochip: 0
line: 5
Reset: # GPIO0_A3 (IO4, physical 36)
pin: 3
gpiochip: 0
line: 3
Busy: # GPIO1_C3 (IO5, physical 18)
pin: 51
gpiochip: 1
line: 19
# Ant_sw: # GPIO1_C2 (IO3, physical 16)
# pin: 50
# gpiochip: 1
# line: 18
Enable_Pins:
- pin: 43 # GPIO1_B3 (physical 32)
gpiochip: 1
line: 11
- pin: 57 # GPIO1_D1 (physical 33)
gpiochip: 1
line: 25
DIO3_TCXO_VOLTAGE: true
DIO2_AS_RF_SWITCH: true
spidev: spidev0.0
# CS: # GPIO0_B6 (SPI1_CSN0, physical 24)
# pin: 14
# gpiochip: 0
# line: 14
@@ -1,36 +0,0 @@
Meta:
name: RAK6421 + RAK13300 Slot 2
support: community # Promote when tested
compatible:
- ebyte-ecb41-pge # Armbian
Lora:
Module: sx1262
IRQ: # GPIO0_B4 (IO6, physical 12)
pin: 12
gpiochip: 0
line: 12
Reset: # GPIO1_C3 (IO4, physical 18)
pin: 51
gpiochip: 1
line: 19
Busy: # GPIO0_B3 (IO5, physical 35)
pin: 11
gpiochip: 0
line: 11
# Ant_sw: # GPIO1_C2 (IO3, physical 16)
# pin: 50
# gpiochip: 1
# line: 18
Enable_Pins:
- pin: 2 # GPIO0_A2 (physical 37)
gpiochip: 0
line: 2
- pin: 50 # GPIO1_C2 (physical 16)
gpiochip: 1
line: 18
spidev: spidev0.1
# CS: # GPIO0_A7 (SPI1_CSN1, physical 26)
# pin: 7
# gpiochip: 0
# line: 7
@@ -1,39 +0,0 @@
Meta:
name: RAK6421 + RAK13302 Slot 1
support: community # Promote when tested
compatible:
- ebyte-ecb41-pge # Armbian
Lora:
Module: sx1262
IRQ: # GPIO0_A5 (IO6, physical 15)
pin: 5
gpiochip: 0
line: 5
Reset: # GPIO0_A3 (IO4, physical 36)
pin: 3
gpiochip: 0
line: 3
Busy: # GPIO1_C3 (IO5, physical 18)
pin: 51
gpiochip: 1
line: 19
# Ant_sw: # GPIO1_C2 (IO3, physical 16)
# pin: 50
# gpiochip: 1
# line: 18
Enable_Pins:
- pin: 43 # GPIO1_B3 (physical 32)
gpiochip: 1
line: 11
- pin: 57 # GPIO1_D1 (physical 33)
gpiochip: 1
line: 25
DIO3_TCXO_VOLTAGE: true
DIO2_AS_RF_SWITCH: true
spidev: spidev0.0
# CS: # GPIO0_B6 (SPI1_CSN0, physical 24)
# pin: 14
# gpiochip: 0
# line: 14
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
@@ -1,37 +0,0 @@
Meta:
name: RAK6421 + RAK13302 Slot 2
support: community # Promote when tested
compatible:
- ebyte-ecb41-pge # Armbian
Lora:
Module: sx1262
IRQ: # GPIO0_B4 (IO6, physical 12)
pin: 12
gpiochip: 0
line: 12
Reset: # GPIO1_C3 (IO4, physical 18)
pin: 51
gpiochip: 1
line: 19
Busy: # GPIO0_B3 (IO5, physical 35)
pin: 11
gpiochip: 0
line: 11
# Ant_sw: # GPIO1_C2 (IO3, physical 16)
# pin: 50
# gpiochip: 1
# line: 18
Enable_Pins:
- pin: 2 # GPIO0_A2 (physical 37)
gpiochip: 0
line: 2
- pin: 50 # GPIO1_C2 (physical 16)
gpiochip: 1
line: 18
spidev: spidev0.1
# CS: # GPIO0_A7 (SPI1_CSN1, physical 26)
# pin: 7
# gpiochip: 0
# line: 7
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
@@ -1,30 +0,0 @@
Meta:
name: Waveshare SX1262
support: deprecated
compatible:
- ebyte-ecb41-pge # Armbian
Lora:
Module: sx1262 # Waveshare SX126X XXXM
DIO2_AS_RF_SWITCH: true
CS: # GPIO0_A1 (physical 40)
pin: 1
gpiochip: 0
line: 1
IRQ: # GPIO0_A3 (physical 36)
pin: 3
gpiochip: 0
line: 3
Busy: # GPIO0_A0 (physical 38)
pin: 0
gpiochip: 0
line: 0
Reset: # GPIO0_B4 (physical 12)
pin: 12
gpiochip: 0
line: 12
SX126X_ANT_SW: # GPIO1_B2 (physical 31)
pin: 42
gpiochip: 1
line: 10
spidev: spidev0.0
+2 -12
View File
@@ -1,21 +1,11 @@
Meta:
name: RAK6421 + RAK13300 Slot 1 (Autoconf default)
support: official
compatible:
- raspberry-pi
Lora: Lora:
### RAK13300 in Slot 1 ### RAK13300in Slot 1
Module: sx1262 Module: sx1262
IRQ: 22 #IO6 IRQ: 22 #IO6
Reset: 16 # IO4 Reset: 16 # IO4
Busy: 24 # IO5 Busy: 24 # IO5
Enable_Pins: # Ant_sw: 13 # IO3
- 12
- 13
DIO3_TCXO_VOLTAGE: true DIO3_TCXO_VOLTAGE: true
DIO2_AS_RF_SWITCH: true DIO2_AS_RF_SWITCH: true
spidev: spidev0.0 spidev: spidev0.0
# GPIO_DETECT_PA: 13
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
@@ -1,31 +0,0 @@
# For use with Armbian luckfox-pico-max
# Waveshare LoRa HAT for Raspberry Pi Pico
# https://www.waveshare.com/wiki/Pico-LoRa-SX1262
Meta:
name: luckfox-pico-max-ws-raspberry-pi-pico-hat
support: community
compatible:
- luckfox-pico-max # Armbian
Lora:
Module: sx1262
DIO2_AS_RF_SWITCH: true
DIO3_TCXO_VOLTAGE: true
spidev: spidev0.0
Busy: # GPIO1_C7 / GP2
pin: 55
gpiochip: 1
line: 23
CS: # GPIO1_C6 / GP3
pin: 54
gpiochip: 1
line: 22
Reset: # GPIO1_D1 / GP15
pin: 57
gpiochip: 1
line: 25
IRQ: # GPIO2_A2 / GP20
pin: 66
gpiochip: 2
line: 2
@@ -1,9 +1,3 @@
Meta:
name: Luckfox Lyra PicoCalc Wio LoRa SX1262
support: official
compatible:
- luckfox-lyra-plus # Armbian
Lora: Lora:
Module: sx1262 Module: sx1262
DIO2_AS_RF_SWITCH: true DIO2_AS_RF_SWITCH: true
-23
View File
@@ -1,23 +0,0 @@
# For use with Armbian luckfox-lyra-ultra-w
# Enable overlay 'luckfox-lyra-ultra-w-spi0-cs0-spidev' with armbian-config
# https://github.com/wehooper4/Meshtastic-Hardware/tree/main/Luckfox%20Ultra%20Hat
# 1 Watt Lyra Ultra hat
Meta:
name: wehooper4 Luckfox Ultra 1W
support: community
compatible:
- luckfox-pico-ultra # Armbian
- luckfox-lyra-ultra # Armbian
Lora:
Module: sx1262
DIO2_AS_RF_SWITCH: true
DIO3_TCXO_VOLTAGE: true
CS: 10
IRQ: 5
Busy: 11
Reset: 9
RXen: 14
spidev: spidev0.0 #pins are (CS=10, CLK=8, MOSI=6, MISO=7)
spiSpeed: 2000000
-24
View File
@@ -1,24 +0,0 @@
# For use with Armbian luckfox-lyra-ultra-w
# Enable overlay 'luckfox-lyra-ultra-w-spi0-cs0-spidev' with armbian-config
# https://github.com/wehooper4/Meshtastic-Hardware/tree/main/Luckfox%20Ultra%20Hat
# 2 Watt Lyra Ultra hat
Meta:
name: wehooper4 Luckfox Ultra 2W
support: community
compatible:
- luckfox-pico-ultra # Armbian
- luckfox-lyra-ultra # Armbian
Lora:
Module: sx1262
DIO2_AS_RF_SWITCH: true
DIO3_TCXO_VOLTAGE: true
SX126X_MAX_POWER: 8
CS: 10
IRQ: 5
Busy: 11
Reset: 9
RXen: 14
spidev: spidev0.0 #pins are (CS=10, CLK=8, MOSI=6, MISO=7)
spiSpeed: 2000000
@@ -1,31 +0,0 @@
# For use with Armbian luckfox-lyra // luckfox-lyra-plus
# Enable overlay 'luckfox-lyra-plus-spi0-cs0_rmio13-spidev' with armbian-config
# Waveshare LoRa HAT for Raspberry Pi Pico
# https://www.waveshare.com/wiki/Pico-LoRa-SX1262
Meta:
name: Waveshare LoRa HAT for Raspberry Pi Pico
support: community
compatible:
- luckfox-lyra-plus # Armbian
Lora:
Module: sx1262
DIO2_AS_RF_SWITCH: true
DIO3_TCXO_VOLTAGE: true
spidev: spidev0.0
CS: # GPIO0_B5
pin: 13
gpiochip: 0
line: 13
IRQ: # GPIO1_C2
pin: 50
gpiochip: 1
line: 18
Busy: # GPIO0_B4
pin: 12
gpiochip: 0
line: 12
Reset: # GPIO0_A2
pin: 2
gpiochip: 0
line: 2
@@ -1,39 +0,0 @@
# MeshAdv-Pi E22-900M30S
# https://github.com/chrismyers2000/MeshAdv-Pi-Hat
Meta:
name: MeshAdv-Pi E22-900M30S
support: community
compatible:
- luckfox-lyra-zero-w # Armbian
Lora:
Module: sx1262
CS: # GPIO0_C2 (physical 40)
pin: 18
gpiochip: 0
line: 18
IRQ: # GPIO1_D1 (physical 36)
pin: 57
gpiochip: 1
line: 25
Busy: # GPIO0_C1 (physical 38)
pin: 17
gpiochip: 0
line: 17
Reset: # GPIO0_B6 (physical 12)
pin: 14
gpiochip: 0
line: 14
TXen: # GPIO1_C2 (physical 33)
pin: 50
gpiochip: 1
line: 18
RXen: # GPIO1_D2 (physical 32)
pin: 58
gpiochip: 1
line: 26
DIO3_TCXO_VOLTAGE: true
# Only for E22-900M33S:
# Limit the output power to 8 dBm
# SX126X_MAX_POWER: 8
spidev: spidev0.0
@@ -1,33 +0,0 @@
# MeshAdv Mini E22-900M22S
# https://github.com/chrismyers2000/MeshAdv-Mini
Meta:
name: MeshAdv Mini E22-900M22S
support: community
compatible:
- luckfox-lyra-zero-w # Armbian
Lora:
Module: sx1262 # Ebyte E22-900M22S
CS: # GPIO0_B2_d (phys 24, RPi CE0)
pin: 10
gpiochip: 0
line: 10
IRQ: # GPIO1_D1_d (phys 36, RPi GPIO16)
pin: 57
gpiochip: 1
line: 25
Busy: # GPIO0_C1_d (phys 38, RPi GPIO20)
pin: 17
gpiochip: 0
line: 17
Reset: # GPIO0_B4_d (phys 18, RPi GPIO24)
pin: 12
gpiochip: 0
line: 12
RXen: # GPIO1_D2_d (phys 32, RPi GPIO12)
pin: 58
gpiochip: 1
line: 26
DIO2_AS_RF_SWITCH: true
DIO3_TCXO_VOLTAGE: true
spidev: spidev0.0
@@ -1,38 +0,0 @@
Meta:
name: RAK6421 + RAK13300 Slot 1
support: community # Promote when tested
compatible:
- luckfox-lyra-zero-w # Armbian
Lora:
Module: sx1262
IRQ: # GPIO0_A5 (IO6)
pin: 5
gpiochip: 0
line: 5
Reset: # GPIO1_D1 (IO4)
pin: 57
gpiochip: 1
line: 25
Busy: # GPIO0_B4 (IO5)
pin: 12
gpiochip: 0
line: 12
# Ant_sw: # GPIO1_C2 (IO3)
# pin: 50
# gpiochip: 1
# line: 18
Enable_Pins:
- pin: 58 # GPIO1_D2
gpiochip: 1
line: 26
- pin: 50 # GPIO1_C2
gpiochip: 1
line: 18
DIO3_TCXO_VOLTAGE: true
DIO2_AS_RF_SWITCH: true
spidev: spidev0.0
# CS: # GPIO0_B2
# pin: 10
# gpiochip: 0
# line: 10
@@ -1,36 +0,0 @@
Meta:
name: RAK6421 + RAK13300 Slot 2
support: community # Promote when tested
compatible:
- luckfox-lyra-zero-w # Armbian
Lora:
Module: sx1262
IRQ: # GPIO0_B6 (IO6)
pin: 14
gpiochip: 0
line: 14
Reset: # GPIO0_B4 (IO4)
pin: 12
gpiochip: 0
line: 12
Busy: # GPIO1_C0 (IO5)
pin: 48
gpiochip: 1
line: 16
# Ant_sw: # GPIO0_B5 (IO3)
# pin: 13
# gpiochip: 0
# line: 13
Enable_Pins:
- pin: 51 # GPIO1_C3
gpiochip: 1
line: 19
- pin: 13 # GPIO0_B5
gpiochip: 0
line: 13
spidev: spidev0.1
# CS: # GPIO0_B1
# pin: 9
# gpiochip: 0
# line: 9
@@ -1,39 +0,0 @@
Meta:
name: RAK6421 + RAK13300 Slot 1
support: community # Promote when tested
compatible:
- luckfox-lyra-zero-w # Armbian
Lora:
Module: sx1262
IRQ: # GPIO0_A5 (IO6)
pin: 5
gpiochip: 0
line: 5
Reset: # GPIO1_D1 (IO4)
pin: 57
gpiochip: 1
line: 25
Busy: # GPIO0_B4 (IO5)
pin: 12
gpiochip: 0
line: 12
# Ant_sw: # GPIO1_C2 (IO3)
# pin: 50
# gpiochip: 1
# line: 18
Enable_Pins:
- pin: 58 # GPIO1_D2
gpiochip: 1
line: 26
- pin: 50 # GPIO1_C2
gpiochip: 1
line: 18
DIO3_TCXO_VOLTAGE: true
DIO2_AS_RF_SWITCH: true
spidev: spidev0.0
# CS: # GPIO0_B2
# pin: 10
# gpiochip: 0
# line: 10
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
@@ -1,37 +0,0 @@
Meta:
name: RAK6421 + RAK13300 Slot 2
support: community # Promote when tested
compatible:
- luckfox-lyra-zero-w # Armbian
Lora:
Module: sx1262
IRQ: # GPIO0_B6 (IO6)
pin: 14
gpiochip: 0
line: 14
Reset: # GPIO0_B4 (IO4)
pin: 12
gpiochip: 0
line: 12
Busy: # GPIO1_C0 (IO5)
pin: 48
gpiochip: 1
line: 16
# Ant_sw: # GPIO0_B5 (IO3)
# pin: 13
# gpiochip: 0
# line: 13
Enable_Pins:
- pin: 51 # GPIO1_C3
gpiochip: 1
line: 19
- pin: 13 # GPIO0_B5
gpiochip: 0
line: 13
spidev: spidev0.1
# CS: # GPIO0_B1
# pin: 9
# gpiochip: 0
# line: 9
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
@@ -1,30 +0,0 @@
Meta:
name: Waveshare SX1262
support: deprecated
compatible:
- luckfox-lyra-zero-w # Armbian
Lora:
Module: sx1262 # Waveshare SX126X XXXM
DIO2_AS_RF_SWITCH: true
CS: # GPIO0_C2 (physical 40)
pin: 18
gpiochip: 0
line: 18
IRQ: # GPIO1_D1 (physical 36)
pin: 57
gpiochip: 1
line: 25
Busy: # GPIO0_C1 (physical 38)
pin: 17
gpiochip: 0
line: 17
Reset: # GPIO0_B6 (physical 12)
pin: 14
gpiochip: 0
line: 14
SX126X_ANT_SW: # GPIO1_B3 (physical 31)
pin: 43
gpiochip: 1
line: 11
spidev: spidev0.0
-6
View File
@@ -1,9 +1,3 @@
Meta:
name: Lora Meshstick SX1262
support: official
compatible:
- usb
Lora: Lora:
Module: sx1262 Module: sx1262
CS: 0 CS: 0
@@ -1,41 +0,0 @@
# !! WARNING: Hats on the OK3506 board are installed "backwards" (facing outwards)
# MeshAdv-Pi E22-900M30S
# https://github.com/chrismyers2000/MeshAdv-Pi-Hat
Meta:
name: MeshAdv-Pi E22-900M30S
support: community
compatible:
- forlinx-ok3506-s12 # Armbian
Lora:
Module: sx1262
CS: # GPIO0_B0 (physical 40)
pin: 8
gpiochip: 0
line: 8
IRQ: # GPIO3_B0 (physical 36)
pin: 104
gpiochip: 3
line: 8
Busy: # GPIO0_B1 (physical 38)
pin: 9
gpiochip: 0
line: 9
Reset: # GPIO0_B6 (physical 12)
pin: 14
gpiochip: 0
line: 14
TXen: # GPIO0_A3 (physical 33)
pin: 3
gpiochip: 0
line: 3
RXen: # GPIO0_A2 (physical 32)
pin: 2
gpiochip: 0
line: 2
DIO3_TCXO_VOLTAGE: true
# Only for E22-900M33S:
# Limit the output power to 8 dBm
# SX126X_MAX_POWER: 8
spidev: spidev0.0
@@ -1,35 +0,0 @@
# !! WARNING: Hats on the OK3506 board are installed "backwards" (facing outwards)
# MeshAdv Mini E22-900M22S
# https://github.com/chrismyers2000/MeshAdv-Mini
Meta:
name: MeshAdv Mini E22-900M22S
support: community
compatible:
- forlinx-ok3506-s12 # Armbian
Lora:
Module: sx1262 # Ebyte E22-900M22S
CS: # GPIO0_C3 (physical 24, SPI0_CSN0)
pin: 19
gpiochip: 0
line: 19
IRQ: # GPIO3_B0 (physical 36)
pin: 104
gpiochip: 3
line: 8
Busy: # GPIO0_B1 (physical 38)
pin: 9
gpiochip: 0
line: 9
Reset: # GPIO3_A6 (physical 18)
pin: 102
gpiochip: 3
line: 6
RXen: # GPIO0_A2 (physical 32)
pin: 2
gpiochip: 0
line: 2
DIO2_AS_RF_SWITCH: true
DIO3_TCXO_VOLTAGE: true
spidev: spidev0.0
@@ -1,40 +0,0 @@
# !! WARNING: Hats on the OK3506 board are installed "backwards" (facing outwards)
Meta:
name: RAK6421 + RAK13300 Slot 1
support: community # Promote when tested
compatible:
- forlinx-ok3506-s12 # Armbian
Lora:
Module: sx1262
IRQ: # GPIO3_B5 (IO6, physical 15)
pin: 109
gpiochip: 3
line: 13
Reset: # GPIO3_B0 (IO4, physical 36)
pin: 104
gpiochip: 3
line: 8
Busy: # GPIO3_A6 (IO5, physical 18)
pin: 102
gpiochip: 3
line: 6
# Ant_sw: # GPIO0_A3 (IO3, physical 33)
# pin: 3
# gpiochip: 0
# line: 3
Enable_Pins:
- pin: 2 # GPIO0_A2 (physical 32)
gpiochip: 0
line: 2
- pin: 3 # GPIO0_A3 (physical 33)
gpiochip: 0
line: 3
DIO3_TCXO_VOLTAGE: true
DIO2_AS_RF_SWITCH: true
spidev: spidev0.0
# CS: # GPIO0_C3 (SPI0_CSN0, physical 24)
# pin: 19
# gpiochip: 0
# line: 19
@@ -1,38 +0,0 @@
# !! WARNING: Hats on the OK3506 board are installed "backwards" (facing outwards)
Meta:
name: RAK6421 + RAK13300 Slot 2
support: community # Promote when tested
compatible:
- forlinx-ok3506-s12 # Armbian
Lora:
Module: sx1262
IRQ: # GPIO0_B6 (IO6, physical 12)
pin: 14
gpiochip: 0
line: 14
Reset: # GPIO3_A6 (IO4, physical 18)
pin: 102
gpiochip: 3
line: 6
Busy: # GPIO0_B2 (IO5, physical 35)
pin: 10
gpiochip: 0
line: 10
# Ant_sw: # GPIO3_A7 (IO3, physical 16)
# pin: 103
# gpiochip: 3
# line: 7
Enable_Pins:
- pin: 106 # GPIO3_B2 (physical 37)
gpiochip: 3
line: 10
- pin: 103 # GPIO3_A7 (physical 16)
gpiochip: 3
line: 7
spidev: spidev0.1
# CS: # GPIO0_B7 (SPI0_CSN1, physical 26)
# pin: 15
# gpiochip: 0
# line: 15
@@ -1,41 +0,0 @@
# !! WARNING: Hats on the OK3506 board are installed "backwards" (facing outwards)
Meta:
name: RAK6421 + RAK13302 Slot 1
support: community # Promote when tested
compatible:
- forlinx-ok3506-s12 # Armbian
Lora:
Module: sx1262
IRQ: # GPIO3_B5 (IO6, physical 15)
pin: 109
gpiochip: 3
line: 13
Reset: # GPIO3_B0 (IO4, physical 36)
pin: 104
gpiochip: 3
line: 8
Busy: # GPIO3_A6 (IO5, physical 18)
pin: 102
gpiochip: 3
line: 6
# Ant_sw: # GPIO0_A3 (IO3, physical 33)
# pin: 3
# gpiochip: 0
# line: 3
Enable_Pins:
- pin: 2 # GPIO0_A2 (physical 32)
gpiochip: 0
line: 2
- pin: 3 # GPIO0_A3 (physical 33)
gpiochip: 0
line: 3
DIO3_TCXO_VOLTAGE: true
DIO2_AS_RF_SWITCH: true
spidev: spidev0.0
# CS: # GPIO0_C3 (SPI0_CSN0, physical 24)
# pin: 19
# gpiochip: 0
# line: 19
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
@@ -1,39 +0,0 @@
# !! WARNING: Hats on the OK3506 board are installed "backwards" (facing outwards)
Meta:
name: RAK6421 + RAK13302 Slot 2
support: community # Promote when tested
compatible:
- forlinx-ok3506-s12 # Armbian
Lora:
Module: sx1262
IRQ: # GPIO0_B6 (IO6, physical 12)
pin: 14
gpiochip: 0
line: 14
Reset: # GPIO3_A6 (IO4, physical 18)
pin: 102
gpiochip: 3
line: 6
Busy: # GPIO0_B2 (IO5, physical 35)
pin: 10
gpiochip: 0
line: 10
# Ant_sw: # GPIO3_A7 (IO3, physical 16)
# pin: 103
# gpiochip: 3
# line: 7
Enable_Pins:
- pin: 106 # GPIO3_B2 (physical 37)
gpiochip: 3
line: 10
- pin: 103 # GPIO3_A7 (physical 16)
gpiochip: 3
line: 7
spidev: spidev0.1
# CS: # GPIO0_B7 (SPI0_CSN1, physical 26)
# pin: 15
# gpiochip: 0
# line: 15
TX_GAIN_LORA: [9, 9, 10, 11, 9, 8, 9, 10, 10, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 10, 9, 8]
@@ -1,32 +0,0 @@
# !! WARNING: Hats on the OK3506 board are installed "backwards" (facing outwards)
Meta:
name: Waveshare SX1262
support: deprecated
compatible:
- forlinx-ok3506-s12 # Armbian
Lora:
Module: sx1262 # Waveshare SX126X XXXM
DIO2_AS_RF_SWITCH: true
CS: # GPIO0_B0 (physical 40)
pin: 8
gpiochip: 0
line: 8
IRQ: # GPIO3_B0 (physical 36)
pin: 104
gpiochip: 3
line: 8
Busy: # GPIO0_B1 (physical 38)
pin: 9
gpiochip: 0
line: 9
Reset: # GPIO0_B6 (physical 12)
pin: 14
gpiochip: 0
line: 14
SX126X_ANT_SW: # GPIO3_B3 (physical 31)
pin: 107
gpiochip: 3
line: 11
spidev: spidev0.0
-6
View File
@@ -1,9 +1,3 @@
Meta:
name: Lora Meshstick SX1262
support: community
compatible:
- usb
Lora: Lora:
Module: lr1121 Module: lr1121
CS: 0 CS: 0
@@ -1,9 +1,3 @@
Meta:
name: Pinedio USB SX1262
support: deprecated
compatible:
- usb
Lora: Lora:
Module: sx1262 Module: sx1262
CS: 0 CS: 0
@@ -1,9 +1,3 @@
Meta:
name: raxda-rock2f-starter-edition-hat
support: community
compatible:
- rock-2f # Armbian
Lora: Lora:
### Raxda Rock 2F running Armbian Linux 6.1.99-vendor-rk35xx ### Raxda Rock 2F running Armbian Linux 6.1.99-vendor-rk35xx
@@ -1,11 +1,5 @@
# https://www.waveshare.com/core1262-868m.htm # https://www.waveshare.com/core1262-868m.htm
# https://github.com/markbirss/lora-starter-edition-sx1262-i2c # https://github.com/markbirss/lora-starter-edition-sx1262-i2c
Meta:
name: lora-starter-edition-sx1262-i2c
support: community
compatible:
- raspberry-pi
Lora: Lora:
Module: sx1262 # Starter Edition SX1262 I2C Raspberry Pi HAT Module: sx1262 # Starter Edition SX1262 I2C Raspberry Pi HAT
DIO2_AS_RF_SWITCH: true DIO2_AS_RF_SWITCH: true
@@ -1,9 +1,3 @@
Meta:
name: meshstick-1262
support: official
compatible:
- usb
Lora: Lora:
Module: sx1262 Module: sx1262
CS: 0 CS: 0
-6
View File
@@ -1,9 +1,3 @@
Meta:
name: meshtoad-e22
support: official
compatible:
- usb
Lora: Lora:
Module: sx1262 Module: sx1262
CS: 0 CS: 0
+2 -7
View File
@@ -1,9 +1,3 @@
Meta:
name: umesh-1262-30dbm
support: community
compatible:
- clockwork-uconsole
Lora: Lora:
Module: sx1262 Module: sx1262
CS: 0 CS: 0
@@ -19,7 +13,8 @@ Lora:
# USB_Serialnum: 12345678 # USB_Serialnum: 12345678
SX126X_MAX_POWER: 22 SX126X_MAX_POWER: 22
# Reduce output power to improve EMI # Reduce output power to improve EMI
TX_GAIN_LORA: [12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 8, 8, 7] NUM_PA_POINTS: 22
TX_GAIN_LORA: 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 8, 8, 7
# Note: This module integrates an additional PA to achieve higher output power. # Note: This module integrates an additional PA to achieve higher output power.
# The 'power' parameter here does not represent the actual RF output. # The 'power' parameter here does not represent the actual RF output.
# TX_GAIN_LORA defines the gain offset applied at each SX1262 input power step (1–22 dBm). # TX_GAIN_LORA defines the gain offset applied at each SX1262 input power step (1–22 dBm).
+2 -7
View File
@@ -1,9 +1,3 @@
Meta:
name: umesh-1268-30dbm
support: community
compatible:
- clockwork-uconsole
Lora: Lora:
Module: sx1268 Module: sx1268
CS: 0 CS: 0
@@ -19,7 +13,8 @@ Lora:
# USB_Serialnum: 12345678 # USB_Serialnum: 12345678
SX126X_MAX_POWER: 22 SX126X_MAX_POWER: 22
# Reduce output power to improve EMI # Reduce output power to improve EMI
TX_GAIN_LORA: [12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 8, 8, 7] NUM_PA_POINTS: 22
TX_GAIN_LORA: 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 8, 8, 7
# Note: This module integrates an additional PA to achieve higher output power. # Note: This module integrates an additional PA to achieve higher output power.
# The 'power' parameter here does not represent the actual RF output. # The 'power' parameter here does not represent the actual RF output.
# TX_GAIN_LORA defines the gain offset applied at each SX1262 input power step (1–22 dBm). # TX_GAIN_LORA defines the gain offset applied at each SX1262 input power step (1–22 dBm).
-6
View File
@@ -1,9 +1,3 @@
Meta:
name: Waveshare SX1262
support: deprecated
compatible:
- raspberry-pi
Lora: Lora:
Module: sx1262 # Waveshare SX126X XXXM Module: sx1262 # Waveshare SX126X XXXM
DIO2_AS_RF_SWITCH: true DIO2_AS_RF_SWITCH: true
@@ -1,12 +1,5 @@
# https://www.waveshare.com/pico-lora-sx1262-868m.htm # https://www.waveshare.com/pico-lora-sx1262-868m.htm
# https://github.com/markbirss/lora-ws-raspberry-pi-pico-to-rpi-adapter # https://github.com/markbirss/lora-ws-raspberry-pi-pico-to-rpi-adapter
Meta:
name: ws-raspberry-pico-to-rpi-adapter
support: community
compatible:
- raspberry-pi
Lora: Lora:
Module: sx1262 # Waveshare Raspberry Pi Pico to Raspberry Pi HAT Adapter Module: sx1262 # Waveshare Raspberry Pi Pico to Raspberry Pi HAT Adapter
DIO2_AS_RF_SWITCH: true DIO2_AS_RF_SWITCH: true
@@ -15,12 +15,6 @@
# 5 CS 24 # 5 CS 24
# 26 DIO1/IRQ 26 # 26 DIO1/IRQ 26
Meta:
name: ws-raspberry-pico-to-orangepi-03
support: community
compatible:
- orange-pi-zero-3 # Armbian
Lora: Lora:
Module: sx1262 # Waveshare Raspberry Pico Lora module Module: sx1262 # Waveshare Raspberry Pico Lora module
DIO2_AS_RF_SWITCH: true DIO2_AS_RF_SWITCH: true
+1 -1
View File
@@ -43,7 +43,7 @@ for pio_env in pio_envs:
env = { env = {
"ci": {"board": pio_env, "platform": env_platform}, "ci": {"board": pio_env, "platform": env_platform},
"board_level": cfg.get(f"env:{pio_env}", "board_level", default=None), "board_level": cfg.get(f"env:{pio_env}", "board_level", default=None),
"board_check": cfg.get(f"env:{pio_env}", "board_check", default="false").strip().lower() == "true", "board_check": bool(cfg.get(f"env:{pio_env}", "board_check", default=False)),
} }
all_envs.append(env) all_envs.append(env)
+29 -54
View File
@@ -1,31 +1,25 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Generate release notes from the actual release commit range.""" """
Generate release notes from merged PRs on develop and master branches.
Categorizes PRs into Enhancements and Bug Fixes/Maintenance sections.
"""
import argparse
import json
import re
import subprocess import subprocess
import re
import json
import sys import sys
from datetime import datetime
def get_last_release_tag(compare_ref, exclude_tag=None): def get_last_release_tag():
"""Get the most recent version tag merged into compare_ref.""" """Get the most recent release tag."""
result = subprocess.run( result = subprocess.run(
["git", "tag", "--merged", compare_ref, "--sort=-version:refname", "v*"], ["git", "describe", "--tags", "--abbrev=0"],
capture_output=True, capture_output=True,
text=True, text=True,
check=True, check=True,
) )
return result.stdout.strip()
for line in result.stdout.splitlines():
candidate = line.strip()
if not candidate:
continue
if exclude_tag and candidate == exclude_tag:
continue
return candidate
raise subprocess.CalledProcessError(result.returncode, result.args, output=result.stdout, stderr=result.stderr)
def get_tag_date(tag): def get_tag_date(tag):
@@ -39,18 +33,18 @@ def get_tag_date(tag):
return result.stdout.strip() return result.stdout.strip()
def get_merged_prs_in_range(tag, compare_ref): def get_merged_prs_since_tag(tag, branch):
"""Get all merged PRs in the git range between tag and compare_ref.""" """Get all merged PRs since the given tag on the specified branch."""
# Get commits since tag on the branch - look for PR numbers in parentheses
result = subprocess.run( result = subprocess.run(
[ [
"git", "git",
"log", "log",
f"{tag}..{compare_ref}", f"{tag}..origin/{branch}",
"--oneline", "--oneline",
], ],
capture_output=True, capture_output=True,
text=True, text=True,
check=True,
) )
prs = [] prs = []
@@ -71,25 +65,6 @@ def get_merged_prs_in_range(tag, compare_ref):
return prs return prs
def parse_args():
"""Parse CLI arguments."""
parser = argparse.ArgumentParser(
description="Generate release notes from the actual release commit range."
)
parser.add_argument("new_version", help="Version that will be tagged for this release")
parser.add_argument(
"--base-tag",
dest="base_tag",
help="Existing version tag to diff from. Defaults to the latest version tag merged into the compare ref.",
)
parser.add_argument(
"--compare-ref",
default="HEAD",
help="Git ref to diff to. Defaults to HEAD.",
)
return parser.parse_args()
def get_pr_details(pr_number): def get_pr_details(pr_number):
"""Get PR details from GitHub API via gh CLI.""" """Get PR details from GitHub API via gh CLI."""
try: try:
@@ -293,28 +268,28 @@ def get_new_contributors(pr_details_list, tag, repo="meshtastic/firmware"):
def main(): def main():
args = parse_args() if len(sys.argv) < 2:
new_version = args.new_version print("Usage: generate_release_notes.py <new_version>", file=sys.stderr)
compare_ref = args.compare_ref sys.exit(1)
current_tag = f"v{new_version}"
new_version = sys.argv[1]
# Get last release tag # Get last release tag
try: try:
last_tag = args.base_tag or get_last_release_tag(compare_ref, exclude_tag=current_tag) last_tag = get_last_release_tag()
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
print("Error: Could not find last release tag", file=sys.stderr) print("Error: Could not find last release tag", file=sys.stderr)
sys.exit(1) sys.exit(1)
print( # Collect PRs from both branches
f"Resolved release note range: {last_tag}..{compare_ref}", all_pr_numbers = set()
file=sys.stderr,
)
try: for branch in ["develop", "master"]:
all_pr_numbers = set(get_merged_prs_in_range(last_tag, compare_ref)) try:
except subprocess.CalledProcessError as e: prs = get_merged_prs_since_tag(last_tag, branch)
print(f"Error: Could not get PRs for range {last_tag}..{compare_ref}: {e}", file=sys.stderr) all_pr_numbers.update(prs)
sys.exit(1) except Exception as e:
print(f"Warning: Could not get PRs from {branch}: {e}", file=sys.stderr)
# Get details for all PRs # Get details for all PRs
enhancements = [] enhancements = []
@@ -87,15 +87,6 @@
</screenshots> </screenshots>
<releases> <releases>
<release version="2.7.23" date="2026-04-14">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.23</url>
</release>
<release version="2.7.22" date="2026-04-06">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.22</url>
</release>
<release version="2.7.21" date="2026-03-11">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.21</url>
</release>
<release version="2.7.20" date="2026-02-11"> <release version="2.7.20" date="2026-02-11">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.20</url> <url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.20</url>
</release> </release>
-44
View File
@@ -1,44 +0,0 @@
#!/usr/bin/env bash
# Run native PlatformIO tests inside Docker (for macOS / non-Linux hosts).
#
# Usage:
# ./bin/test-native-docker.sh # run all native tests
# ./bin/test-native-docker.sh -f test_transmit_history # run specific test filter
# ./bin/test-native-docker.sh --rebuild # force rebuild the image
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
IMAGE_NAME="meshtastic-native-test"
REBUILD=false
EXTRA_ARGS=()
for arg in "$@"; do
if [[ "$arg" == "--rebuild" ]]; then
REBUILD=true
else
EXTRA_ARGS+=("$arg")
fi
done
if $REBUILD || ! docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then
echo "Building test image (first run may take a few minutes)..."
docker build -t "$IMAGE_NAME" -f "$ROOT_DIR/Dockerfile.test" "$ROOT_DIR"
fi
# Disable BUILD_EPOCH to avoid full rebuilds between test runs (matches CI)
sed_cmd='s/-DBUILD_EPOCH=$UNIX_TIME/#-DBUILD_EPOCH=$UNIX_TIME/'
# Default: run all tests. Pass extra args (e.g. -f test_transmit_history) through.
if [[ ${#EXTRA_ARGS[@]} -eq 0 ]]; then
CMD=("platformio" "test" "-e" "coverage" "-v")
else
CMD=("platformio" "test" "-e" "coverage" "-v" "${EXTRA_ARGS[@]}")
fi
exec docker run --rm \
-v "$ROOT_DIR:/src:ro" \
"$IMAGE_NAME" \
bash -c "rm -rf /tmp/fw-test && cp -a /src /tmp/fw-test && cd /tmp/fw-test && sed -i '${sed_cmd}' platformio.ini && ${CMD[*]}"
-54
View File
@@ -1,54 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x4405"],
["0x239A", "0x0029"],
["0x239A", "0x002A"],
["0x2886", "0x1667"]
],
"usb_product": "HT-n5262G",
"mcu": "nrf52840",
"variant": "heltec_mesh_node_t096",
"variants_dir": "variants",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino"],
"name": "Heltec nrf (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://heltec.org/",
"vendor": "Heltec"
}
-40
View File
@@ -1,40 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default.csv"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_ESP32S3_DEV",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": ["wifi"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "LilyGo Mini-Epaper-S3 (4 MB Flash, 2MB PSRAM)",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.lilygo.cc",
"vendor": "LilyGo"
}
-38
View File
@@ -1,38 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi",
"partitions": "default_16MB.csv"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=0",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "LilyGo T5-ePaper-S3",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 921600
},
"url": "https://lilygo.cc/products/t5-e-paper-s3-pro",
"vendor": "LILYGO"
}
-29
View File
@@ -1,29 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": "-DARDUINO_T_Beam",
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "tbeam"
},
"connectivity": ["wifi", "bluetooth", "can", "ethernet"],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "TTGO T-Beam (PSRAM Disabled)",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 1310720,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://github.com/LilyGO/TTGO-T-Beam",
"vendor": "TTGO"
}
+1 -1
View File
@@ -12,6 +12,6 @@ Ex:
- `logo_320x480.png` - `logo_320x480.png`
- `logo_320x240.png` - `logo_320x240.png`
This file is copied to `data/boot/logo.png` before filesystem image compilation. This file is copied to `data/boot/logo.png` before filesytem image compilation.
For additional examples see the [`event/defcon33` branch](https://github.com/meshtastic/firmware/tree/event/defcon33). For additional examples see the [`event/defcon33` branch](https://github.com/meshtastic/firmware/tree/event/defcon33).

Some files were not shown because too many files have changed in this diff Show More