mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-08 14:12:05 +00:00
YAML based config for PI / Portduino (#2943)
* Add configuration via /etc/meshtastic/config.yaml * Move example config, support more locations * Fix config check * Use access() to check for config file presence * Throw an error and exit on radio init fail * Adds error check for reading Bluetooth MAC * Settle on meshtasticd, add install script * Shell fixes * Fine. I'll put it back and then disable you * Get wrekt, shellchekt * Firat attempt at adding raspbian CI build * Tickle the workflow * Beatings will continue til morale improves * Permissions are overrated --------- Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
This commit is contained in:
parent
9d4af1146e
commit
46bd6ca7ba
30
.github/workflows/build_raspbian.yml
vendored
Normal file
30
.github/workflows/build_raspbian.yml
vendored
Normal file
@ -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
|
@ -1,7 +1,10 @@
|
|||||||
enable=all
|
enable=all
|
||||||
source-path=SCRIPTDIR
|
source-path=SCRIPTDIR
|
||||||
disable=SC2154
|
disable=SC2154
|
||||||
|
disable=SC2248
|
||||||
|
disable=SC2250
|
||||||
|
|
||||||
# If you're having issues with shellcheck following source, disable the errors via:
|
# If you're having issues with shellcheck following source, disable the errors via:
|
||||||
# disable=SC1090
|
# disable=SC1090
|
||||||
# disable=SC1091
|
# disable=SC1091
|
||||||
|
#
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
VERSION=`bin/buildinfo.py long`
|
VERSION=$(bin/buildinfo.py long)
|
||||||
SHORT_VERSION=`bin/buildinfo.py short`
|
SHORT_VERSION=$(bin/buildinfo.py short)
|
||||||
|
|
||||||
OUTDIR=release/
|
OUTDIR=release/
|
||||||
|
|
||||||
@ -15,9 +15,13 @@ rm -r $OUTDIR/* || true
|
|||||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
# 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
|
if command -v raspi-config &>/dev/null; then
|
||||||
cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64
|
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-install.* $OUTDIR
|
||||||
cp bin/device-update.* $OUTDIR
|
cp bin/device-update.* $OUTDIR
|
||||||
|
|
||||||
|
26
bin/config-dist.yaml
Normal file
26
bin/config-dist.yaml
Normal file
@ -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
|
9
bin/meshtasticd.service
Normal file
9
bin/meshtasticd.service
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[unit]
|
||||||
|
description=Meshtastic Native Daemon
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/sbin/meshtasticd
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
10
bin/native-install.sh
Executable file
10
bin/native-install.sh
Executable file
@ -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
|
@ -57,8 +57,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define REQUIRE_RADIO true // If true, we will fail to start if the radio is not found
|
#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
|
/// Convert a preprocessor name into a quoted string
|
||||||
#define xstr(s) str(s)
|
#define xstr(s) ystr(s)
|
||||||
#define str(s) #s
|
#define ystr(s) #s
|
||||||
|
|
||||||
/// Convert a preprocessor name into a quoted string and if that string is empty use "unset"
|
/// 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")
|
#define optstr(s) (xstr(s)[0] ? xstr(s) : "unset")
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
|
|
||||||
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32)
|
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32)
|
||||||
HardwareSerial *GPS::_serial_gps = &Serial1;
|
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
|
#else
|
||||||
HardwareSerial *GPS::_serial_gps = NULL;
|
HardwareSerial *GPS::_serial_gps = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
36
src/main.cpp
36
src/main.cpp
@ -69,6 +69,7 @@ NRF52Bluetooth *nrf52Bluetooth;
|
|||||||
|
|
||||||
#ifdef ARCH_RASPBERRY_PI
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
#include "platform/portduino/PiHal.h"
|
#include "platform/portduino/PiHal.h"
|
||||||
|
#include "platform/portduino/PortduinoGlue.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -690,15 +691,32 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ARCH_RASPBERRY_PI
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
PiHal *RadioLibHAL = new PiHal(1);
|
if (settingsMap[use_sx1262]) {
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, 21, 16, 18, 20);
|
PiHal *RadioLibHAL = new PiHal(1);
|
||||||
if (!rIf->init()) {
|
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[sx126x_cs], settingsMap[sx126x_dio1],
|
||||||
LOG_WARN("Failed to find SX1262 radio\n");
|
settingsMap[sx126x_reset], settingsMap[sx126x_busy]);
|
||||||
delete rIf;
|
if (!rIf->init()) {
|
||||||
rIf = NULL;
|
LOG_ERROR("Failed to find SX1262 radio\n");
|
||||||
} else {
|
delete rIf;
|
||||||
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n");
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "mesh/NodeDB.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
|
// 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)
|
// specified (may be dangerous if using external PA and SX126x power config forgotten)
|
||||||
@ -74,6 +77,12 @@ template <typename T> bool SX126xInterface<T>::init()
|
|||||||
#ifdef SX126X_DIO2_AS_RF_SWITCH
|
#ifdef SX126X_DIO2_AS_RF_SWITCH
|
||||||
LOG_DEBUG("Setting DIO2 as RF switch\n");
|
LOG_DEBUG("Setting DIO2 as RF switch\n");
|
||||||
bool dio2AsRfSwitch = true;
|
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
|
#else
|
||||||
LOG_DEBUG("Setting DIO2 as not RF switch\n");
|
LOG_DEBUG("Setting DIO2 as not RF switch\n");
|
||||||
bool dio2AsRfSwitch = false;
|
bool dio2AsRfSwitch = false;
|
||||||
|
@ -9,7 +9,14 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#ifdef ARCH_RASPBERRY_PI
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
#include "PortduinoGlue.h"
|
||||||
#include "pigpio.h"
|
#include "pigpio.h"
|
||||||
|
#include "yaml-cpp/yaml.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
std::map<int, int> settingsMap;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include <linux/gpio/LinuxGPIOPin.h>
|
#include <linux/gpio/LinuxGPIOPin.h>
|
||||||
@ -27,7 +34,7 @@ void cpuDeepSleep(uint32_t msecs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
|
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
|
||||||
|
#ifndef ARCH_RASPBERRY_PI
|
||||||
/** a simulated pin for busted IRQ hardware
|
/** a simulated pin for busted IRQ hardware
|
||||||
* Porduino helper class to do this i2c based polling:
|
* Porduino helper class to do this i2c based polling:
|
||||||
*/
|
*/
|
||||||
@ -54,7 +61,7 @@ class PolledIrqPin : public GPIOPin
|
|||||||
};
|
};
|
||||||
|
|
||||||
static GPIOPin *loraIrq;
|
static GPIOPin *loraIrq;
|
||||||
|
#endif
|
||||||
int TCPPort = 4403;
|
int TCPPort = 4403;
|
||||||
|
|
||||||
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||||
@ -94,6 +101,48 @@ void portduinoSetup()
|
|||||||
printf("Setting up Meshtastic on Portduino...\n");
|
printf("Setting up Meshtastic on Portduino...\n");
|
||||||
|
|
||||||
#ifdef ARCH_RASPBERRY_PI
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
YAML::Node yamlConfig;
|
||||||
|
|
||||||
|
if (access("config.yaml", R_OK) == 0) {
|
||||||
|
try {
|
||||||
|
yamlConfig = YAML::LoadFile("config.yaml");
|
||||||
|
} catch (YAML::Exception e) {
|
||||||
|
std::cout << "*** Exception " << e.what() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
} else if (access("/etc/meshtasticd/config.yaml", R_OK) == 0) {
|
||||||
|
try {
|
||||||
|
yamlConfig = YAML::LoadFile("/etc/meshtasticd/config.yaml");
|
||||||
|
} catch (YAML::Exception e) {
|
||||||
|
std::cout << "*** Exception " << e.what() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::cout << "No 'config.yaml' found, exiting." << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
settingsMap[use_sx1262] = yamlConfig["USE_SX1262"].as<bool>(false);
|
||||||
|
settingsMap[sx126x_dio2_as_rf_switch] = yamlConfig["SX126X_DIO2_AS_RF_SWITCH"].as<bool>(false);
|
||||||
|
settingsMap[sx126x_cs] = yamlConfig["SX126X_CS"].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[sx126x_dio1] = yamlConfig["SX126X_DIO1"].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[sx126x_busy] = yamlConfig["SX126X_BUSY"].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[sx126x_reset] = yamlConfig["SX126X_RESET"].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[use_rf95] = yamlConfig["USE_RF95"].as<bool>(false);
|
||||||
|
settingsMap[rf95_nss] = yamlConfig["RF95_NSS"].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[rf95_irq] = yamlConfig["RF95_IRQ"].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[rf95_reset] = yamlConfig["RF95_RESET"].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[rf95_dio1] = yamlConfig["RF95_DIO1"].as<int>(RADIOLIB_NC);
|
||||||
|
|
||||||
|
} catch (YAML::Exception e) {
|
||||||
|
std::cout << "*** Exception " << e.what() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (access("/sys/kernel/debug/bluetooth/hci0/identity", R_OK) != 0) {
|
||||||
|
std::cout << "Cannot read Bluetooth MAC Address. Please run as root" << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -121,7 +170,7 @@ void portduinoSetup()
|
|||||||
gpioBind(loraCs);
|
gpioBind(loraCs);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef ARCH_RASPBERRY_PI
|
||||||
{
|
{
|
||||||
// Set the random seed equal to TCPPort to have a different seed per instance
|
// Set the random seed equal to TCPPort to have a different seed per instance
|
||||||
randomSeed(TCPPort);
|
randomSeed(TCPPort);
|
||||||
@ -140,4 +189,5 @@ void portduinoSetup()
|
|||||||
}
|
}
|
||||||
// gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET")));
|
// gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET")));
|
||||||
// gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent());
|
// gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent());
|
||||||
|
#endif
|
||||||
}
|
}
|
21
src/platform/portduino/PortduinoGlue.h
Normal file
21
src/platform/portduino/PortduinoGlue.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
extern std::map<int, int> settingsMap;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
use_sx1262,
|
||||||
|
sx126x_cs,
|
||||||
|
sx126x_dio1,
|
||||||
|
sx126x_busy,
|
||||||
|
sx126x_reset,
|
||||||
|
sx126x_dio2_as_rf_switch,
|
||||||
|
use_rf95,
|
||||||
|
rf95_nss,
|
||||||
|
rf95_irq,
|
||||||
|
rf95_reset,
|
||||||
|
rf95_dio1
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -16,7 +16,7 @@ build_src_filter = ${portduino_base.build_src_filter}
|
|||||||
; The Raspberry Pi actually has accessible SPI and GPIO, so we can support real hardware there.
|
; The Raspberry Pi actually has accessible SPI and GPIO, so we can support real hardware there.
|
||||||
[env:raspbian]
|
[env:raspbian]
|
||||||
extends = portduino_base
|
extends = portduino_base
|
||||||
build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino -DARCH_RASPBERRY_PI -DRADIOLIB_DEBUG -lpigpio
|
build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino -DARCH_RASPBERRY_PI -DRADIOLIB_DEBUG -lpigpio -lyaml-cpp
|
||||||
board = linux_arm
|
board = linux_arm
|
||||||
lib_deps = ${portduino_base.lib_deps}
|
lib_deps = ${portduino_base.lib_deps}
|
||||||
build_src_filter = ${portduino_base.build_src_filter}
|
build_src_filter = ${portduino_base.build_src_filter}
|
@ -1,34 +1,6 @@
|
|||||||
#if defined(ARCH_RASPBERRY_PI)
|
#if defined(ARCH_RASPBERRY_PI)
|
||||||
#define HAS_RADIO 1
|
|
||||||
#define GPIOD_CHIP_LABEL "pinctrl-bcm2711"
|
|
||||||
|
|
||||||
// define USE_RF95
|
|
||||||
#define USE_SX1262
|
|
||||||
#define SX126X_TXEN 6
|
|
||||||
#define SX126X_DIO2_AS_RF_SWITCH
|
|
||||||
#define NO_SCREEN
|
#define NO_SCREEN
|
||||||
|
|
||||||
#define RF95_SCK 11
|
|
||||||
#define RF95_MISO 9
|
|
||||||
#define RF95_MOSI 10
|
|
||||||
#define RF95_NSS RADIOLIB_NC
|
|
||||||
|
|
||||||
// #define LORA_DIO0 4 // a No connect on the SX1262 module
|
|
||||||
// #define LORA_DIO0_LABEL "GPIO_GCLK"
|
|
||||||
#define LORA_RESET 18
|
|
||||||
#define LORA_RESET_LABEL "GPIO18"
|
|
||||||
#define LORA_DIO1 16 // SX1262 IRQ, called DIO0 on pinelora schematic, pin 7 on ch341f "ack" - FIXME, enable hwints in linux
|
|
||||||
// #define LORA_DIO2 20 // SX1262 BUSY, actually connected to "DIO5" on pinelora schematic, pin 8 on ch341f "slct"
|
|
||||||
// #define LORA_DIO3 6 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
|
|
||||||
|
|
||||||
#ifdef USE_SX1262
|
|
||||||
#define SX126X_CS 21
|
|
||||||
#define SX126X_DIO1 16
|
|
||||||
#define SX126X_BUSY 20
|
|
||||||
#define SX126X_RESET LORA_RESET
|
|
||||||
// HOPE RFM90 does not have a TCXO therefore not SX126X_E22
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else // Pine64 mode.
|
#else // Pine64 mode.
|
||||||
|
|
||||||
// Pine64 uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
|
// Pine64 uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
|
||||||
|
Loading…
Reference in New Issue
Block a user