diff --git a/.github/workflows/build_raspbian.yml b/.github/workflows/build_raspbian.yml
new file mode 100644
index 0000000000..1860e90980
--- /dev/null
+++ b/.github/workflows/build_raspbian.yml
@@ -0,0 +1,30 @@
+name: Build Raspbian
+
+on: workflow_call
+
+permissions:
+ contents: write
+ packages: write
+
+jobs:
+ build-raspbian:
+ runs-on: [self-hosted, linux, ARM64]
+ steps:
+ - uses: actions/checkout@v3
+ - name: Build base
+ id: base
+ uses: ./.github/actions/setup-base
+
+ - name: Build Raspbian
+ run: bin/build-native.sh
+
+ - name: Get release version string
+ run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
+ id: version
+
+ - name: Store binaries as an artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: firmware-native-${{ steps.version.outputs.version }}.zip
+ path: |
+ release/meshtasticd_linux_arm64
diff --git a/.trunk/configs/.shellcheckrc b/.trunk/configs/.shellcheckrc
index 8c7b1ada8a..b2e8a14cc6 100644
--- a/.trunk/configs/.shellcheckrc
+++ b/.trunk/configs/.shellcheckrc
@@ -1,7 +1,10 @@
enable=all
source-path=SCRIPTDIR
disable=SC2154
+disable=SC2248
+disable=SC2250
# If you're having issues with shellcheck following source, disable the errors via:
# disable=SC1090
# disable=SC1091
+#
\ No newline at end of file
diff --git a/bin/build-native.sh b/bin/build-native.sh
index 8bc262860e..64c5adb504 100755
--- a/bin/build-native.sh
+++ b/bin/build-native.sh
@@ -2,8 +2,8 @@
set -e
-VERSION=`bin/buildinfo.py long`
-SHORT_VERSION=`bin/buildinfo.py short`
+VERSION=$(bin/buildinfo.py long)
+SHORT_VERSION=$(bin/buildinfo.py short)
OUTDIR=release/
@@ -13,11 +13,15 @@ mkdir -p $OUTDIR/
rm -r $OUTDIR/* || true
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
-platformio pkg update
+platformio pkg update
-pio run --environment native
-cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64
+if command -v raspi-config &>/dev/null; then
+ pio run --environment raspbian
+ cp .pio/build/raspbian/program $OUTDIR/meshtasticd_linux_arm64
+else
+ pio run --environment native
+ cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64
+fi
cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR
-
diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml
new file mode 100644
index 0000000000..2a3abac6ff
--- /dev/null
+++ b/bin/config-dist.yaml
@@ -0,0 +1,26 @@
+# Define your devices here.
+# Use Broadcom pin numbering
+
+#Waveshare SX126X XXXM
+
+#USE_SX1262: true
+#SX126X_DIO2_AS_RF_SWITCH: true
+#SX126X_CS: 21
+#SX126X_DIO1: 16
+#SX126X_BUSY: 20
+#SX126X_RESET: 18
+
+#Waveshare SX1302 LISTEN ONLY AT THIS TIME!
+
+#USE_SX1262: true
+#SX126X_CS: 7
+#SX126X_DIO1: 17
+#SX126X_RESET: 22
+
+#Adafruit RFM9x
+
+#USE_RF95: true
+#RF95_RESET: 25
+#RF95_NSS: 7
+#RF95_IRQ: 22
+#RF95_DIO1: 23
diff --git a/bin/meshtasticd.service b/bin/meshtasticd.service
new file mode 100644
index 0000000000..4ed1bfd8fa
--- /dev/null
+++ b/bin/meshtasticd.service
@@ -0,0 +1,9 @@
+[unit]
+description=Meshtastic Native Daemon
+
+[Service]
+Type=simple
+ExecStart=/usr/sbin/meshtasticd
+
+[Install]
+WantedBy=multi-user.target
diff --git a/bin/native-install.sh b/bin/native-install.sh
new file mode 100755
index 0000000000..d1d0c8707b
--- /dev/null
+++ b/bin/native-install.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+cp release/meshtasticd_linux_arm64 /usr/sbin/meshtasticd
+mkdir /etc/meshtasticd
+if [[ -f "/etc/meshtasticd/config.yaml" ]]; then
+ cp bin/config-dist.yaml /etc/meshtasticd/config-upgrade.yaml
+else
+ cp bin/config-dist.yaml /etc/meshtasticd/config.yaml
+fi
+cp bin/meshtasticd.service /usr/lib/systemd/system/meshtasticd.service
diff --git a/src/configuration.h b/src/configuration.h
index 199880c6be..cb7ee218be 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -57,8 +57,8 @@ along with this program. If not, see .
#define REQUIRE_RADIO true // If true, we will fail to start if the radio is not found
/// Convert a preprocessor name into a quoted string
-#define xstr(s) str(s)
-#define str(s) #s
+#define xstr(s) ystr(s)
+#define ystr(s) #s
/// Convert a preprocessor name into a quoted string and if that string is empty use "unset"
#define optstr(s) (xstr(s)[0] ? xstr(s) : "unset")
@@ -209,4 +209,4 @@ along with this program. If not, see .
#ifndef HW_VENDOR
#error HW_VENDOR must be defined
-#endif
+#endif
\ No newline at end of file
diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp
index 47ba067d2a..af622e3d8b 100644
--- a/src/gps/GPS.cpp
+++ b/src/gps/GPS.cpp
@@ -17,6 +17,9 @@
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32)
HardwareSerial *GPS::_serial_gps = &Serial1;
+#elif defined(ARCH_RASPBERRY_PI)
+// need a translation layer to make _serial_gps work with pigpio https://abyz.me.uk/rpi/pigpio/cif.html#serOpen
+HardwareSerial *GPS::_serial_gps = NULL;
#else
HardwareSerial *GPS::_serial_gps = NULL;
#endif
diff --git a/src/main.cpp b/src/main.cpp
index d5b3895d2e..5c3151fc07 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -69,6 +69,7 @@ NRF52Bluetooth *nrf52Bluetooth;
#ifdef ARCH_RASPBERRY_PI
#include "platform/portduino/PiHal.h"
+#include "platform/portduino/PortduinoGlue.h"
#include
#include
#include
@@ -690,15 +691,32 @@ void setup()
#endif
#ifdef ARCH_RASPBERRY_PI
- PiHal *RadioLibHAL = new PiHal(1);
- if (!rIf) {
- rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, 21, 16, 18, 20);
- if (!rIf->init()) {
- LOG_WARN("Failed to find SX1262 radio\n");
- delete rIf;
- rIf = NULL;
- } else {
- LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n");
+ if (settingsMap[use_sx1262]) {
+ if (!rIf) {
+ PiHal *RadioLibHAL = new PiHal(1);
+ rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[sx126x_cs], settingsMap[sx126x_dio1],
+ settingsMap[sx126x_reset], settingsMap[sx126x_busy]);
+ if (!rIf->init()) {
+ LOG_ERROR("Failed to find SX1262 radio\n");
+ delete rIf;
+ exit(EXIT_FAILURE);
+ } else {
+ LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n");
+ }
+ }
+ } else if (settingsMap[use_rf95]) {
+ if (!rIf) {
+ PiHal *RadioLibHAL = new PiHal(1);
+ rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[rf95_nss], settingsMap[rf95_irq],
+ settingsMap[rf95_reset], settingsMap[rf95_dio1]);
+ if (!rIf->init()) {
+ LOG_ERROR("Failed to find RF95 radio\n");
+ delete rIf;
+ rIf = NULL;
+ exit(EXIT_FAILURE);
+ } else {
+ LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n");
+ }
}
}
diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp
index 9801079171..ba3f2bc2a8 100644
--- a/src/mesh/SX126xInterface.cpp
+++ b/src/mesh/SX126xInterface.cpp
@@ -2,6 +2,9 @@
#include "configuration.h"
#include "error.h"
#include "mesh/NodeDB.h"
+#ifdef ARCH_RASPBERRY_PI
+#include "PortduinoGlue.h"
+#endif
// Particular boards might define a different max power based on what their hardware can do, default to max power output if not
// specified (may be dangerous if using external PA and SX126x power config forgotten)
@@ -74,6 +77,12 @@ template bool SX126xInterface::init()
#ifdef SX126X_DIO2_AS_RF_SWITCH
LOG_DEBUG("Setting DIO2 as RF switch\n");
bool dio2AsRfSwitch = true;
+#elif defined(ARCH_RASPBERRY_PI)
+ bool dio2AsRfSwitch = false;
+ if (settingsMap[sx126x_dio2_as_rf_switch]) {
+ LOG_DEBUG("Setting DIO2 as RF switch\n");
+ dio2AsRfSwitch = true;
+ }
#else
LOG_DEBUG("Setting DIO2 as not RF switch\n");
bool dio2AsRfSwitch = false;
@@ -318,4 +327,4 @@ template bool SX126xInterface::sleep()
#endif
return true;
-}
+}
\ No newline at end of file
diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp
index fb71a429b2..b3c2dc5f2e 100644
--- a/src/platform/portduino/PortduinoGlue.cpp
+++ b/src/platform/portduino/PortduinoGlue.cpp
@@ -9,7 +9,14 @@
#include
#ifdef ARCH_RASPBERRY_PI
+#include "PortduinoGlue.h"
#include "pigpio.h"
+#include "yaml-cpp/yaml.h"
+#include
+#include