From 8c20fe5ec4ab85eba49e14157c418093ec589eaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 30 Dec 2022 21:44:51 +0100 Subject: [PATCH 01/12] Start working on RF95 attached to Raspberry Pi --- arch/portduino/portduino.ini | 1 + src/mesh/RF95Interface.cpp | 2 +- src/platform/portduino/PortduinoGlue.cpp | 26 ++++++++++++++++- variants/portduino/platformio.ini | 4 +-- variants/portduino/variant.h | 36 +++++++++++++++++++++++- 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini index cd962b671..f04e9016c 100644 --- a/arch/portduino/portduino.ini +++ b/arch/portduino/portduino.ini @@ -1,6 +1,7 @@ ; The Portduino based sim environment on top of any host OS, all hardware will be simulated [portduino_base] platform = https://github.com/meshtastic/platform-native.git#096b3c3e9c5c8e19d4c3b6cd803fffef2a9be4c5 +platform_packages = framework-portduino@https://github.com/caveman99/framework-portduino.git framework = arduino build_src_filter = ${env.build_src_filter} diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp index 4502d0810..8a0dfec51 100644 --- a/src/mesh/RF95Interface.cpp +++ b/src/mesh/RF95Interface.cpp @@ -14,7 +14,7 @@ RF95Interface::RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi) : RadioLibInterface(cs, irq, rst, RADIOLIB_NC, spi) { - // FIXME - we assume devices never get destroyed + LOG_WARN("RF95Interface(cs=%d, irq=%d, rst=%d)\n", cs, irq, rst); } /** Some boards require GPIO control of tx vs rx paths */ diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index b041391f8..332b40791 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -88,7 +88,31 @@ void portduinoSetup() { printf("Setting up Meshtastic on Portduino...\n"); -#ifdef PORTDUINO_LINUX_HARDWARE +#ifdef ARCH_RASPBERRY_PI + printf("using GPIOD Version: %s\n", gpiod_version_string()); + // We need to create SPI + SPI.begin(); + if(!spiChip->isSimulated()) { + printf("Connecting to RFM95 board...\n"); + loraIrq = new LinuxGPIOPin(LORA_DIO0, GPIOD_CHIP_LABEL, LORA_DIO0_LABEL, "loraIrq"); + loraIrq->setSilent(); + gpioBind(loraIrq); + +#if (RF95_NSS != RADIOLIB_NC) + auto loraCs = new LinuxGPIOPin(RF95_NSS, GPIOD_CHIP_LABEL, RF95_NSS_LABEL, "loraCs"); + loraCs->setSilent(); + gpioBind(loraCs); +#endif + + auto loraReset = new LinuxGPIOPin(LORA_RESET, GPIOD_CHIP_LABEL, LORA_RESET_LABEL, "loraReset"); + loraReset->setSilent(); + gpioBind(loraReset); + + } + else + + +#elif defined(PORTDUINO_LINUX_HARDWARE) SPI.begin(); // We need to create SPI bool usePineLora = !spiChip->isSimulated(); if(usePineLora) { diff --git a/variants/portduino/platformio.ini b/variants/portduino/platformio.ini index 5bbde2adf..13f298440 100644 --- a/variants/portduino/platformio.ini +++ b/variants/portduino/platformio.ini @@ -14,9 +14,9 @@ lib_deps = ${portduino_base.lib_deps} build_src_filter = ${portduino_base.build_src_filter} ; The Portduino based sim environment on top of a linux OS and touching linux hardware devices -[env:linux-arm] +[env:raspbian] extends = portduino_base -build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino +build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino -DARCH_RASPBERRY_PI -DRADIOLIB_DEBUG -DRADIOLIB_VERBOSE board = linux_arm lib_deps = ${portduino_base.lib_deps} build_src_filter = ${portduino_base.build_src_filter} diff --git a/variants/portduino/variant.h b/variants/portduino/variant.h index 76696b7af..d84c15d4a 100644 --- a/variants/portduino/variant.h +++ b/variants/portduino/variant.h @@ -1,3 +1,35 @@ +#if defined(ARCH_RASPBERRY_PI) + +#define GPIOD_CHIP_LABEL "pinctrl-bcm2711" + +#define USE_RF95 +#define USE_SX1262 + +#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 17 +#define LORA_RESET_LABEL "GPIO17" +#define LORA_DIO1 RADIOLIB_NC // SX1262 IRQ, called DIO0 on pinelora schematic, pin 7 on ch341f "ack" - FIXME, enable hwints in linux +#define LORA_DIO2 RADIOLIB_NC // SX1262 BUSY, actually connected to "DIO5" on pinelora schematic, pin 8 on ch341f "slct" +#define LORA_DIO3 RADIOLIB_NC // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled + +#ifdef USE_SX1262 +#define SX126X_CS RF95_NSS +#define SX126X_DIO1 LORA_DIO0 +#define SX126X_BUSY LORA_DIO2 +#define SX126X_RESET LORA_RESET +// HOPE RFM90 does not have a TCXO therefore not SX126X_E22 +#endif + +#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 // not found then probe for SX1262. Currently the RF95 code is disabled because I think the RF95 module won't need to ship. // #define USE_RF95 @@ -13,7 +45,7 @@ #define LORA_RESET 14 #define LORA_DIO1 33 // SX1262 IRQ, called DIO0 on pinelora schematic, pin 7 on ch341f "ack" - FIXME, enable hwints in linux #define LORA_DIO2 32 // SX1262 BUSY, actually connected to "DIO5" on pinelora schematic, pin 8 on ch341f "slct" -#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled +#define LORA_DIO3 RADIOLIB_NC // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled #ifdef USE_SX1262 #define SX126X_CS 20 // CS0 on pinelora schematic, hooked to gpio D0 on ch341f @@ -23,3 +55,5 @@ // HOPE RFM90 does not have a TCXO therefore not SX126X_E22 #endif +#endif + From e9a55fc296e029890cc0c7775cfdebf3d72396d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 2 Feb 2023 11:29:55 +0100 Subject: [PATCH 02/12] revert them trunk shite --- .trunk/configs/.flake8 | 3 --- .trunk/configs/.isort.cfg | 2 -- .trunk/trunk.yaml | 15 ++------------- .vscode/tasks.json | 30 ++++++++++++++---------------- 4 files changed, 16 insertions(+), 34 deletions(-) delete mode 100644 .trunk/configs/.flake8 delete mode 100644 .trunk/configs/.isort.cfg diff --git a/.trunk/configs/.flake8 b/.trunk/configs/.flake8 deleted file mode 100644 index 5ba6e2ffe..000000000 --- a/.trunk/configs/.flake8 +++ /dev/null @@ -1,3 +0,0 @@ -# Autoformatter friendly flake8 config (all formatting rules disabled) -[flake8] -extend-ignore = D1, D2, E1, E2, E3, E501, W1, W2, W3, W5 diff --git a/.trunk/configs/.isort.cfg b/.trunk/configs/.isort.cfg deleted file mode 100644 index b9fb3f3e8..000000000 --- a/.trunk/configs/.isort.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[settings] -profile=black diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index e854e883a..70acfd11b 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -1,6 +1,6 @@ version: 0.1 cli: - version: 1.4.1 + version: 1.3.1 plugins: sources: - id: trunk @@ -8,18 +8,8 @@ plugins: uri: https://github.com/trunk-io/plugins lint: enabled: - - oxipng@8.0.0 - - actionlint@1.6.23 - - markdownlint@0.33.0 - - shellcheck@0.9.0 - - shfmt@3.5.0 - - hadolint@2.12.0 - - isort@5.12.0 - - black@23.1.0 - - svgo@3.0.2 - - flake8@6.0.0 - git-diff-check - - gitleaks@8.15.3 + - gitleaks@8.15.2 - clang-format@14.0.0 - prettier@2.8.3 disabled: @@ -32,7 +22,6 @@ lint: - svgo@3.0.2 runtimes: enabled: - - python@3.10.8 - go@1.18.3 - node@18.12.1 actions: diff --git a/.vscode/tasks.json b/.vscode/tasks.json index b2340005e..cdb8f5114 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,17 +1,15 @@ { - "version": "2.0.0", - "tasks": [ - { - "type": "PlatformIO", - "task": "Build", - "problemMatcher": [ - "$platformio" - ], - "group": { - "kind": "build", - "isDefault": true - }, - "label": "PlatformIO: Build" - } - ] -} \ No newline at end of file + "version": "2.0.0", + "tasks": [ + { + "type": "PlatformIO", + "task": "Build", + "problemMatcher": ["$platformio"], + "group": { + "kind": "build", + "isDefault": true + }, + "label": "PlatformIO: Build" + } + ] +} From 945fd7a05c080464c842570dc918331a8eee0b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 2 Feb 2023 11:32:00 +0100 Subject: [PATCH 03/12] revert readprops change --- bin/readprops.py | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/bin/readprops.py b/bin/readprops.py index db8c8c011..c23092e41 100644 --- a/bin/readprops.py +++ b/bin/readprops.py @@ -1,7 +1,9 @@ -import configparser + + import subprocess -import sys +import configparser import traceback +import sys def readProps(prefsLoc): @@ -9,36 +11,27 @@ def readProps(prefsLoc): config = configparser.RawConfigParser() config.read(prefsLoc) - version = dict(config.items("VERSION")) - verObj = dict( - short="{}.{}.{}".format(version["major"], version["minor"], version["build"]), - long="unset", - ) + version = dict(config.items('VERSION')) + verObj = dict(short = "{}.{}.{}".format(version["major"], version["minor"], version["build"]), + long = "unset") # Try to find current build SHA if if the workspace is clean. This could fail if git is not installed try: - sha = ( - subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]) - .decode("utf-8") - .strip() - ) - isDirty = ( - subprocess.check_output(["git", "diff", "HEAD"]).decode("utf-8").strip() - ) + sha = subprocess.check_output( + ['git', 'rev-parse', '--short', 'HEAD']).decode("utf-8").strip() + isDirty = subprocess.check_output( + ['git', 'diff', 'HEAD']).decode("utf-8").strip() suffix = sha - # if isDirty: - # # short for 'dirty', we want to keep our verstrings source for protobuf reasons - # suffix = sha + "-d" - verObj["long"] = "{}.{}.{}.{}".format( - version["major"], version["minor"], version["build"], suffix - ) + if isDirty: + # short for 'dirty', we want to keep our verstrings source for protobuf reasons + suffix = sha + "-d" + verObj['long'] = "{}.{}.{}.{}".format( + version["major"], version["minor"], version["build"], suffix) except: # print("Unexpected error:", sys.exc_info()[0]) # traceback.print_exc() - verObj["long"] = verObj["short"] + verObj['long'] = verObj['short'] # print("firmware version " + verStr) return verObj - - # print("path is" + ','.join(sys.path)) From 56afed84df702524165d439313335ae4c323e9fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 2 Feb 2023 11:35:30 +0100 Subject: [PATCH 04/12] revert some more --- bin/readprops.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/readprops.py b/bin/readprops.py index c23092e41..ffa361541 100644 --- a/bin/readprops.py +++ b/bin/readprops.py @@ -22,9 +22,9 @@ def readProps(prefsLoc): isDirty = subprocess.check_output( ['git', 'diff', 'HEAD']).decode("utf-8").strip() suffix = sha - if isDirty: - # short for 'dirty', we want to keep our verstrings source for protobuf reasons - suffix = sha + "-d" + # if isDirty: + # # short for 'dirty', we want to keep our verstrings source for protobuf reasons + # suffix = sha + "-d" verObj['long'] = "{}.{}.{}.{}".format( version["major"], version["minor"], version["build"], suffix) except: From 06a1b079da9c6b3d51be1e4e3f2820acd1d70c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 2 Feb 2023 11:47:47 +0100 Subject: [PATCH 05/12] even more cleanup-ing and revert-ing --- .vscode/extensions.json | 6 +-- .vscode/settings.json | 82 ++--------------------------------------- 2 files changed, 5 insertions(+), 83 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 9a91518aa..4fc84fa78 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,10 +2,8 @@ // See http://go.microsoft.com/fwlink/?LinkId=827846 // for the documentation about the extensions.json format "recommendations": [ + "ms-vscode.cpptools", "platformio.platformio-ide", - "xaver.clang-format" + "trunk.io" ], - "unwantedRecommendations": [ - "ms-vscode.cpptools-extension-pack" - ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 21b7b97b7..3b489975b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,80 +1,4 @@ { - "files.associations": { - "type_traits": "cpp", - "array": "cpp", - "*.tcc": "cpp", - "cctype": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "fstream": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "iosfwd": "cpp", - "istream": "cpp", - "limits": "cpp", - "memory": "cpp", - "new": "cpp", - "ostream": "cpp", - "numeric": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "cinttypes": "cpp", - "utility": "cpp", - "typeinfo": "cpp", - "string": "cpp", - "*.xbm": "cpp", - "list": "cpp", - "atomic": "cpp", - "memory_resource": "cpp", - "optional": "cpp", - "string_view": "cpp", - "cassert": "cpp", - "iterator": "cpp", - "shared_mutex": "cpp", - "iostream": "cpp", - "esp_nimble_hci.h": "c", - "map": "cpp", - "random": "cpp", - "*.tpp": "cpp" - }, - "cSpell.words": [ - "Blox", - "EINK", - "HFSR", - "Meshtastic", - "NEMAGPS", - "NMEAGPS", - "RDEF", - "Ublox", - "bkpt", - "cfsr", - "descs", - "ocrypto", - "protobufs", - "wifi" - ], - "C_Cpp.dimInactiveRegions": true, - "cmake.configureOnOpen": true, - "protoc": { - "compile_on_save": false, - } -} \ No newline at end of file + "editor.formatOnSave": true, + "editor.defaultFormatter": "trunk.io" +} From d74cbdaa8b572897a4e25930e67c78b5428141a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 23 May 2023 21:55:12 +0200 Subject: [PATCH 06/12] update platform def --- arch/portduino/portduino.ini | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini index 31f5ee0dd..6d15e9178 100644 --- a/arch/portduino/portduino.ini +++ b/arch/portduino/portduino.ini @@ -1,7 +1,6 @@ ; The Portduino based sim environment on top of any host OS, all hardware will be simulated [portduino_base] -platform = https://github.com/meshtastic/platform-native.git#096b3c3e9c5c8e19d4c3b6cd803fffef2a9be4c5 -platform_packages = framework-portduino@https://github.com/caveman99/framework-portduino.git +platform = https://github.com/meshtastic/platform-native.git#489ff929dca0bb768256ba2de45f95815111490f framework = arduino build_src_filter = From 5075849ec01246204e9d143ff0040b8120326b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 28 Sep 2023 10:50:26 +0200 Subject: [PATCH 07/12] Add missing endif --- variants/portduino/variant.h | 1 + 1 file changed, 1 insertion(+) diff --git a/variants/portduino/variant.h b/variants/portduino/variant.h index 33437de9e..5ee92bacf 100644 --- a/variants/portduino/variant.h +++ b/variants/portduino/variant.h @@ -54,5 +54,6 @@ #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET #define SX126X_DIO2_AS_RF_SWITCH +#endif #endif From 8df16ad6a6a8833f3b152866dd1040ee9773858a Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 8 Nov 2023 14:36:12 -0600 Subject: [PATCH 08/12] Add ctime include to fix native compile --- src/gps/GPS.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index ce5b18af8..47ba067d2 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -8,6 +8,7 @@ #ifdef ARCH_PORTDUINO #include "meshUtils.h" +#include #endif #ifndef GPS_RESET_MODE From b1b5bafddab7a80ffd3f496cc32d1eef317dd269 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 15 Nov 2023 17:04:41 -0600 Subject: [PATCH 09/12] Add PiHal and get Waveshare SX1262 XXXM working --- arch/portduino/portduino.ini | 3 +- src/main.cpp | 21 ++- src/platform/portduino/PiHal.h | 159 +++++++++++++++++++++++ src/platform/portduino/PortduinoGlue.cpp | 17 ++- variants/portduino/variant.h | 30 ++--- 5 files changed, 207 insertions(+), 23 deletions(-) create mode 100644 src/platform/portduino/PiHal.h diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini index b39974853..312b52e9d 100644 --- a/arch/portduino/portduino.ini +++ b/arch/portduino/portduino.ini @@ -27,4 +27,5 @@ lib_deps = build_flags = ${arduino_base.build_flags} -fPIC - -Isrc/platform/portduino \ No newline at end of file + -Isrc/platform/portduino + -lpigpio \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a18ee4099..634ddeb25 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,6 +67,10 @@ NRF52Bluetooth *nrf52Bluetooth; #include "platform/portduino/SimRadio.h" #endif +#if defined(HAS_RADIO) && defined(ARCH_PORTDUINO) +#include "platform/portduino/PiHal.h" +#endif + #if HAS_BUTTON #include "ButtonThread.h" #endif @@ -662,7 +666,20 @@ void setup() digitalWrite(SX126X_ANT_SW, 1); #endif -#ifdef HW_SPI1_DEVICE +#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"); + } + } + +#elif HW_SPI1_DEVICE LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI1, spiSettings); #else // HW_SPI1_DEVICE LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); @@ -708,7 +725,7 @@ void setup() } #endif -#if defined(USE_SX1262) +#if defined(USE_SX1262) && !defined(ARCH_RASPBERRY_PI) if (!rIf) { rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); if (!rIf->init()) { diff --git a/src/platform/portduino/PiHal.h b/src/platform/portduino/PiHal.h new file mode 100644 index 000000000..9ffaa7fa0 --- /dev/null +++ b/src/platform/portduino/PiHal.h @@ -0,0 +1,159 @@ +#ifndef PI_HAL_H +#define PI_HAL_H + +// include RadioLib +#include + +// include the library for Raspberry GPIO pins +#include "pigpio.h" + +// create a new Raspberry Pi hardware abstraction layer +// using the pigpio library +// the HAL must inherit from the base RadioLibHal class +// and implement all of its virtual methods +class PiHal : public RadioLibHal +{ + public: + // default constructor - initializes the base HAL and any needed private members + PiHal(uint8_t spiChannel, uint32_t spiSpeed = 2000000) + : RadioLibHal(PI_INPUT, PI_OUTPUT, PI_LOW, PI_HIGH, RISING_EDGE, FALLING_EDGE), _spiChannel(spiChannel), + _spiSpeed(spiSpeed) + { + } + + void init() override + { + // first initialise pigpio library + gpioInitialise(); + + // now the SPI + spiBegin(); + + // Waveshare LoRaWAN Hat also needs pin 18 to be pulled high to enable the radio + // gpioSetMode(18, PI_OUTPUT); + // gpioWrite(18, PI_HIGH); + } + + void term() override + { + // stop the SPI + spiEnd(); + + // pull the enable pin low + // gpioSetMode(18, PI_OUTPUT); + // gpioWrite(18, PI_LOW); + + // finally, stop the pigpio library + gpioTerminate(); + } + + // GPIO-related methods (pinMode, digitalWrite etc.) should check + // RADIOLIB_NC as an alias for non-connected pins + void pinMode(uint32_t pin, uint32_t mode) override + { + if (pin == RADIOLIB_NC) { + return; + } + + gpioSetMode(pin, mode); + } + + void digitalWrite(uint32_t pin, uint32_t value) override + { + if (pin == RADIOLIB_NC) { + return; + } + + gpioWrite(pin, value); + } + + uint32_t digitalRead(uint32_t pin) override + { + if (pin == RADIOLIB_NC) { + return (0); + } + + return (gpioRead(pin)); + } + + void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override + { + LOG_DEBUG("Here to enable pin %d!\n", interruptNum); + if (interruptNum == RADIOLIB_NC) { + return; + } + if (gpioRead(interruptNum) == 1) { + interruptCb(); + } else { + gpioSetAlertFunc(interruptNum, (gpioISRFunc_t)interruptCb); + } + LOG_DEBUG("Pin enabled %d!\n", interruptNum); + } + + void detachInterrupt(uint32_t interruptNum) override + { + LOG_DEBUG("Here for pin %d!\n", interruptNum); + if (interruptNum == RADIOLIB_NC) { + return; + } + + gpioSetAlertFunc(interruptNum, NULL); + LOG_DEBUG("Finished\n"); + } + + void delay(unsigned long ms) override { gpioDelay(ms * 1000); } + + void delayMicroseconds(unsigned long us) override { gpioDelay(us); } + + unsigned long millis() override { return (gpioTick() / 1000); } + + unsigned long micros() override { return (gpioTick()); } + + long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override + { + if (pin == RADIOLIB_NC) { + return (0); + } + + this->pinMode(pin, PI_INPUT); + uint32_t start = this->micros(); + uint32_t curtick = this->micros(); + + while (this->digitalRead(pin) == state) { + if ((this->micros() - curtick) > timeout) { + return (0); + } + } + + return (this->micros() - start); + } + + void spiBegin() + { + if (_spiHandle < 0) { + _spiHandle = spiOpen(_spiChannel, _spiSpeed, 0); + } + } + + void spiBeginTransaction() {} + + void spiTransfer(uint8_t *out, size_t len, uint8_t *in) { spiXfer(_spiHandle, (char *)out, (char *)in, len); } + + void spiEndTransaction() {} + + void spiEnd() + { + if (_spiHandle >= 0) { + spiClose(_spiHandle); + _spiHandle = -1; + } + } + + private: + // the HAL can contain any additional private members + const unsigned int _spiSpeed; + const uint8_t _spiChannel; + int _spiHandle = -1; +}; + +#endif \ No newline at end of file diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index af38b61a0..3af65be38 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -7,8 +7,11 @@ #include #include +#ifdef ARCH_RASPBERRY_PI +#include "pigpio.h" +#else #include - +#endif // FIXME - move setBluetoothEnable into a HALPlatform class void setBluetoothEnable(bool on) @@ -89,12 +92,15 @@ void portduinoSetup() printf("Setting up Meshtastic on Portduino...\n"); #ifdef ARCH_RASPBERRY_PI - printf("using GPIOD Version: %s\n", gpiod_version_string()); + return; +/* + //printf("using GPIOD Version: %s\n", gpiod_version_string()); + gpioInitialise(); // We need to create SPI SPI.begin(); if (!spiChip->isSimulated()) { printf("Connecting to RFM95 board...\n"); - loraIrq = new LinuxGPIOPin(LORA_DIO0, GPIOD_CHIP_LABEL, LORA_DIO0_LABEL, "loraIrq"); + loraIrq = new LinuxGPIOPin(LORA_DIO0, "gpiochip0", LORA_DIO0_LABEL, "loraIrq"); loraIrq->setSilent(); gpioBind(loraIrq); @@ -151,7 +157,8 @@ void portduinoSetup() gpioBind(new SimGPIOPin(SX126X_RESET, "fakeLoraReset")); gpioBind(new SimGPIOPin(LORA_DIO1, "fakeLoraIrq")); } - +*/ +#endif // gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET"))); // gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent()); -} +} \ No newline at end of file diff --git a/variants/portduino/variant.h b/variants/portduino/variant.h index 5ee92bacf..2ce871ddc 100644 --- a/variants/portduino/variant.h +++ b/variants/portduino/variant.h @@ -1,10 +1,11 @@ #if defined(ARCH_RASPBERRY_PI) - +#define HAS_RADIO 1 #define GPIOD_CHIP_LABEL "pinctrl-bcm2711" -#define USE_RF95 +// define USE_RF95 #define USE_SX1262 - +#define SX126X_TXEN 6 +#define SX126X_DIO2_AS_RF_SWITCH #define NO_SCREEN #define RF95_SCK 11 @@ -12,19 +13,18 @@ #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 17 -#define LORA_RESET_LABEL "GPIO17" -#define LORA_DIO1 \ - RADIOLIB_NC // SX1262 IRQ, called DIO0 on pinelora schematic, pin 7 on ch341f "ack" - FIXME, enable hwints in linux -#define LORA_DIO2 RADIOLIB_NC // SX1262 BUSY, actually connected to "DIO5" on pinelora schematic, pin 8 on ch341f "slct" -#define LORA_DIO3 RADIOLIB_NC // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled +// #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 RF95_NSS -#define SX126X_DIO1 LORA_DIO0 -#define SX126X_BUSY LORA_DIO2 +#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 @@ -56,4 +56,4 @@ #define SX126X_DIO2_AS_RF_SWITCH #endif -#endif +#endif \ No newline at end of file From a144d5d6cc203fc78298a8a2139a33e9ce5f4cd6 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 15 Nov 2023 20:33:53 -0600 Subject: [PATCH 10/12] Clean up, fix reboot, minimize changes --- src/main.cpp | 27 ++++++++++++++++++---- src/main.h | 1 + src/mesh/NodeDB.cpp | 5 ++++ src/platform/portduino/PiHal.h | 4 ---- src/platform/portduino/PortduinoGlue.cpp | 29 ++++-------------------- src/shutdown.h | 2 ++ 6 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 634ddeb25..f36c7d132 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,8 +67,11 @@ NRF52Bluetooth *nrf52Bluetooth; #include "platform/portduino/SimRadio.h" #endif -#if defined(HAS_RADIO) && defined(ARCH_PORTDUINO) +#ifdef ARCH_RASPBERRY_PI #include "platform/portduino/PiHal.h" +#include +#include +#include #endif #if HAS_BUTTON @@ -132,12 +135,28 @@ std::pair nodeTelemetrySensorsMap[_meshtastic_TelemetrySenso Router *router = NULL; // Users of router don't care what sort of subclass implements that API +#ifdef ARCH_RASPBERRY_PI +void getPiMacAddr(uint8_t *dmac) +{ + std::fstream macIdentity; + macIdentity.open("/sys/kernel/debug/bluetooth/hci0/identity", std::ios::in); + std::string macLine; + getline(macIdentity, macLine); + macIdentity.close(); + + dmac[0] = strtol(macLine.substr(0, 2).c_str(), NULL, 16); + dmac[1] = strtol(macLine.substr(3, 2).c_str(), NULL, 16); + dmac[2] = strtol(macLine.substr(6, 2).c_str(), NULL, 16); + dmac[3] = strtol(macLine.substr(9, 2).c_str(), NULL, 16); + dmac[4] = strtol(macLine.substr(12, 2).c_str(), NULL, 16); + dmac[5] = strtol(macLine.substr(15, 2).c_str(), NULL, 16); +} +#endif + const char *getDeviceName() { uint8_t dmac[6]; - getMacAddr(dmac); - // Meshtastic_ab3c or Shortname_abcd static char name[20]; snprintf(name, sizeof(name), "%02x%02x", dmac[4], dmac[5]); @@ -679,7 +698,7 @@ void setup() } } -#elif HW_SPI1_DEVICE +#elif defined(HW_SPI1_DEVICE) LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI1, spiSettings); #else // HW_SPI1_DEVICE LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); diff --git a/src/main.h b/src/main.h index 3f0120406..5c9de1b81 100644 --- a/src/main.h +++ b/src/main.h @@ -56,6 +56,7 @@ extern graphics::Screen *screen; // Return a human readable string of the form "Meshtastic_ab13" const char *getDeviceName(); +void getPiMacAddr(uint8_t *dmac); extern uint32_t timeLastPowered; diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 2046c2cea..6d9fc2dea 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -421,7 +421,11 @@ void NodeDB::init() */ void NodeDB::pickNewNodeNum() { +#ifdef ARCH_RASPBERRY_PI + getPiMacAddr(ourMacAddr); // Make sure ourMacAddr is set +#else getMacAddr(ourMacAddr); // Make sure ourMacAddr is set +#endif // Pick an initial nodenum based on the macaddr NodeNum nodeNum = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5]; @@ -433,6 +437,7 @@ void NodeDB::pickNewNodeNum() LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, so trying for 0x%x\n", nodeNum, candidate); nodeNum = candidate; } + LOG_WARN("Using nodenum 0x%x \n", nodeNum); myNodeInfo.my_node_num = nodeNum; } diff --git a/src/platform/portduino/PiHal.h b/src/platform/portduino/PiHal.h index 9ffaa7fa0..f10040583 100644 --- a/src/platform/portduino/PiHal.h +++ b/src/platform/portduino/PiHal.h @@ -78,7 +78,6 @@ class PiHal : public RadioLibHal void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override { - LOG_DEBUG("Here to enable pin %d!\n", interruptNum); if (interruptNum == RADIOLIB_NC) { return; } @@ -87,18 +86,15 @@ class PiHal : public RadioLibHal } else { gpioSetAlertFunc(interruptNum, (gpioISRFunc_t)interruptCb); } - LOG_DEBUG("Pin enabled %d!\n", interruptNum); } void detachInterrupt(uint32_t interruptNum) override { - LOG_DEBUG("Here for pin %d!\n", interruptNum); if (interruptNum == RADIOLIB_NC) { return; } gpioSetAlertFunc(interruptNum, NULL); - LOG_DEBUG("Finished\n"); } void delay(unsigned long ms) override { gpioDelay(ms * 1000); } diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index 3af65be38..fb71a429b 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -7,13 +7,15 @@ #include #include + #ifdef ARCH_RASPBERRY_PI #include "pigpio.h" + #else #include #endif -// FIXME - move setBluetoothEnable into a HALPlatform class +// FIXME - move setBluetoothEnable into a HALPlatform class void setBluetoothEnable(bool on) { // not needed @@ -93,30 +95,9 @@ void portduinoSetup() #ifdef ARCH_RASPBERRY_PI return; -/* - //printf("using GPIOD Version: %s\n", gpiod_version_string()); - gpioInitialise(); - // We need to create SPI - SPI.begin(); - if (!spiChip->isSimulated()) { - printf("Connecting to RFM95 board...\n"); - loraIrq = new LinuxGPIOPin(LORA_DIO0, "gpiochip0", LORA_DIO0_LABEL, "loraIrq"); - loraIrq->setSilent(); - gpioBind(loraIrq); - -#if (RF95_NSS != RADIOLIB_NC) - auto loraCs = new LinuxGPIOPin(RF95_NSS, GPIOD_CHIP_LABEL, RF95_NSS_LABEL, "loraCs"); - loraCs->setSilent(); - gpioBind(loraCs); #endif - auto loraReset = new LinuxGPIOPin(LORA_RESET, GPIOD_CHIP_LABEL, LORA_RESET_LABEL, "loraReset"); - loraReset->setSilent(); - gpioBind(loraReset); - - } else - -#elif defined(PORTDUINO_LINUX_HARDWARE) +#ifdef defined(PORTDUINO_LINUX_HARDWARE) SPI.begin(); // We need to create SPI bool usePineLora = !spiChip->isSimulated(); if (usePineLora) { @@ -157,8 +138,6 @@ void portduinoSetup() gpioBind(new SimGPIOPin(SX126X_RESET, "fakeLoraReset")); gpioBind(new SimGPIOPin(LORA_DIO1, "fakeLoraIrq")); } -*/ -#endif // gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET"))); // gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent()); } \ No newline at end of file diff --git a/src/shutdown.h b/src/shutdown.h index 90fb19d0c..f36a7f8dd 100644 --- a/src/shutdown.h +++ b/src/shutdown.h @@ -14,6 +14,8 @@ void powerCommandsCheck() NVIC_SystemReset(); #elif defined(ARCH_RP2040) rp2040.reboot(); +#elif defined(ARCH_RASPBERRY_PI) + exit(EXIT_SUCCESS); #else rebootAtMsec = -1; LOG_WARN("FIXME implement reboot for this platform. Note that some settings require a restart to be applied.\n"); From 61f888e952d798e689827425ce9a2ebbe971165c Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 15 Nov 2023 21:01:17 -0600 Subject: [PATCH 11/12] Add missed ifdef --- src/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index f36c7d132..d5b3895d2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -156,7 +156,11 @@ void getPiMacAddr(uint8_t *dmac) const char *getDeviceName() { uint8_t dmac[6]; - +#ifdef ARCH_RASPBERRY_PI + getPiMacAddr(dmac); +#else + getMacAddr(dmac); +#endif // Meshtastic_ab3c or Shortname_abcd static char name[20]; snprintf(name, sizeof(name), "%02x%02x", dmac[4], dmac[5]); From e99ae64ece56e01f434ed32930c9e55c91ded6dc Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 15 Nov 2023 21:16:27 -0600 Subject: [PATCH 12/12] Add Pi library only to Raspbian --- arch/portduino/portduino.ini | 3 +-- variants/portduino/platformio.ini | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini index 312b52e9d..b39974853 100644 --- a/arch/portduino/portduino.ini +++ b/arch/portduino/portduino.ini @@ -27,5 +27,4 @@ lib_deps = build_flags = ${arduino_base.build_flags} -fPIC - -Isrc/platform/portduino - -lpigpio \ No newline at end of file + -Isrc/platform/portduino \ No newline at end of file diff --git a/variants/portduino/platformio.ini b/variants/portduino/platformio.ini index 13f298440..323609d0e 100644 --- a/variants/portduino/platformio.ini +++ b/variants/portduino/platformio.ini @@ -13,10 +13,10 @@ board = linux_hardware lib_deps = ${portduino_base.lib_deps} build_src_filter = ${portduino_base.build_src_filter} -; The Portduino based sim environment on top of a linux OS and touching linux hardware devices +; The Raspberry Pi actually has accessible SPI and GPIO, so we can support real hardware there. [env:raspbian] extends = portduino_base -build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino -DARCH_RASPBERRY_PI -DRADIOLIB_DEBUG -DRADIOLIB_VERBOSE +build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino -DARCH_RASPBERRY_PI -DRADIOLIB_DEBUG -lpigpio board = linux_arm lib_deps = ${portduino_base.lib_deps} -build_src_filter = ${portduino_base.build_src_filter} +build_src_filter = ${portduino_base.build_src_filter} \ No newline at end of file