Просмотр исходного кода

Merge pull request #217 from AeroXuk/feature/rp2040_picow_dev

Support for Pi PicoW
ripplebiz 1 год назад
Родитель
Сommit
2ba3f42f30

+ 69 - 0
examples/companion_radio/main.cpp

@@ -3,6 +3,8 @@
 
 #if defined(NRF52_PLATFORM)
   #include <InternalFileSystem.h>
+#elif defined(RP2040_PLATFORM)
+  #include <LittleFS.h>
 #elif defined(ESP32)
   #include <SPIFFS.h>
 #endif
@@ -249,7 +251,11 @@ class MyMesh : public BaseChatMesh {
 
   void loadContacts() {
     if (_fs->exists("/contacts3")) {
+    #if defined(RP2040_PLATFORM)
+      File file = _fs->open("/contacts3", "r");
+    #else
       File file = _fs->open("/contacts3");
+    #endif
       if (file) {
         bool full = false;
         while (!full) {
@@ -284,6 +290,8 @@ class MyMesh : public BaseChatMesh {
 #if defined(NRF52_PLATFORM)
     File file = _fs->open("/contacts3", FILE_O_WRITE);
     if (file) { file.seek(0); file.truncate(); }
+#elif defined(RP2040_PLATFORM)
+    File file = _fs->open("/contacts3", "w");
 #else
     File file = _fs->open("/contacts3", "w", true);
 #endif
@@ -314,7 +322,11 @@ class MyMesh : public BaseChatMesh {
 
   void loadChannels() {
     if (_fs->exists("/channels2")) {
+    #if defined(RP2040_PLATFORM)
+    File file = _fs->open("/channels2", "r");
+    #else
       File file = _fs->open("/channels2");
+    #endif
       if (file) {
         bool full = false;
         uint8_t channel_idx = 0;
@@ -343,6 +355,8 @@ class MyMesh : public BaseChatMesh {
   #if defined(NRF52_PLATFORM)
     File file = _fs->open("/channels2", FILE_O_WRITE);
     if (file) { file.seek(0); file.truncate(); }
+  #elif defined(RP2040_PLATFORM)
+    File file = _fs->open("/channels2", "w");
   #else
     File file = _fs->open("/channels2", "w", true);
   #endif
@@ -373,7 +387,11 @@ class MyMesh : public BaseChatMesh {
     sprintf(path, "/bl/%s", fname);
 
     if (_fs->exists(path)) {
+    #if defined(RP2040_PLATFORM)
+      File f = _fs->open(path, "r");
+    #else
       File f = _fs->open(path);
+    #endif
       if (f) {
         int len = f.read(dest_buf, 255);  // currently MAX 255 byte blob len supported!!
         f.close();
@@ -394,6 +412,8 @@ class MyMesh : public BaseChatMesh {
   #if defined(NRF52_PLATFORM)
     File f = _fs->open(path, FILE_O_WRITE);
     if (f) { f.seek(0); f.truncate(); }
+  #elif defined(RP2040_PLATFORM)
+    File f = _fs->open(path, "w");
   #else
     File f = _fs->open(path, "w", true);
   #endif
@@ -752,7 +772,11 @@ public:
   }
 
   void loadPrefsInt(const char* filename) {
+#if defined(RP2040_PLATFORM)
+    File file = _fs->open(filename, "r");
+#else
     File file = _fs->open(filename);
+#endif
     if (file) {
       uint8_t pad[8];
 
@@ -850,6 +874,8 @@ public:
 #if defined(NRF52_PLATFORM)
     File file = _fs->open("/new_prefs", FILE_O_WRITE);
     if (file) { file.seek(0); file.truncate(); }
+#elif defined(RP2040_PLATFORM)
+    File file = _fs->open("/new_prefs", "w");
 #else
     File file = _fs->open("/new_prefs", "w", true);
 #endif
@@ -1444,6 +1470,24 @@ public:
     #include <helpers/ArduinoSerialInterface.h>
     ArduinoSerialInterface serial_interface;
   #endif
+#elif defined(RP2040_PLATFORM)
+  //#ifdef WIFI_SSID
+  //  #include <helpers/rp2040/SerialWifiInterface.h>
+  //  SerialWifiInterface serial_interface;
+  //  #ifndef TCP_PORT
+  //    #define TCP_PORT 5000
+  //  #endif
+  // #elif defined(BLE_PIN_CODE)
+  //   #include <helpers/rp2040/SerialBLEInterface.h>
+  //   SerialBLEInterface serial_interface;
+  #if defined(SERIAL_RX)
+    #include <helpers/ArduinoSerialInterface.h>
+    ArduinoSerialInterface serial_interface;
+    HardwareSerial companion_serial(1);
+  #else
+    #include <helpers/ArduinoSerialInterface.h>
+    ArduinoSerialInterface serial_interface;
+  #endif
 #elif defined(NRF52_PLATFORM)
   #ifdef BLE_PIN_CODE
     #include <helpers/nrf52/SerialBLEInterface.h>
@@ -1503,6 +1547,31 @@ void setup() {
   serial_interface.begin(Serial);
 #endif
   the_mesh.startInterface(serial_interface);
+#elif defined(RP2040_PLATFORM)
+  LittleFS.begin();
+  the_mesh.begin(LittleFS,
+    #ifdef HAS_UI
+        disp != NULL
+    #else
+        false
+    #endif
+  );
+
+  //#ifdef WIFI_SSID
+  //  WiFi.begin(WIFI_SSID, WIFI_PWD);
+  //  serial_interface.begin(TCP_PORT);
+  // #elif defined(BLE_PIN_CODE)
+  //   char dev_name[32+16];
+  //   sprintf(dev_name, "%s%s", BLE_NAME_PREFIX, the_mesh.getNodeName());
+  //   serial_interface.begin(dev_name, the_mesh.getBLEPin());
+  #if defined(SERIAL_RX)
+    companion_serial.setPins(SERIAL_RX, SERIAL_TX);
+    companion_serial.begin(115200);
+    serial_interface.begin(companion_serial);
+  #else
+    serial_interface.begin(Serial);
+  #endif
+    the_mesh.startInterface(serial_interface);
 #elif defined(ESP32)
   SPIFFS.begin(true);
   the_mesh.begin(SPIFFS,

+ 15 - 1
examples/simple_repeater/main.cpp

@@ -3,6 +3,8 @@
 
 #if defined(NRF52_PLATFORM)
   #include <InternalFileSystem.h>
+#elif defined(RP2040_PLATFORM)
+  #include <LittleFS.h>
 #elif defined(ESP32)
   #include <SPIFFS.h>
 #endif
@@ -180,6 +182,8 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
   File openAppend(const char* fname) {
   #if defined(NRF52_PLATFORM)
     return _fs->open(fname, FILE_O_WRITE);
+  #elif defined(RP2040_PLATFORM)
+    return _fs->open(fname, "a");
   #else
     return _fs->open(fname, "a", true);
   #endif
@@ -524,10 +528,12 @@ public:
   bool formatFileSystem() override {
 #if defined(NRF52_PLATFORM)
     return InternalFS.format();
+#elif defined(RP2040_PLATFORM)
+    return LittleFS.format();
 #elif defined(ESP32)
     return SPIFFS.format();
 #else
-  #error "need to implement file system erase"
+    #error "need to implement file system erase"
     return false;
 #endif
   }
@@ -563,7 +569,11 @@ public:
   }
 
   void dumpLogFile() override {
+#if defined(RP2040_PLATFORM)
+    File f = _fs->open(PACKET_LOG_FILE, "r");
+#else
     File f = _fs->open(PACKET_LOG_FILE);
+#endif
     if (f) {
       while (f.available()) {
         int c = f.read();
@@ -637,6 +647,10 @@ void setup() {
   SPIFFS.begin(true);
   fs = &SPIFFS;
   IdentityStore store(SPIFFS, "/identity");
+#elif defined(RP2040_PLATFORM)
+  LittleFS.begin();
+  fs = &LittleFS;
+  IdentityStore store(LittleFS, "/identity");
 #else
   #error "need to define filesystem"
 #endif

+ 14 - 0
examples/simple_room_server/main.cpp

@@ -3,6 +3,8 @@
 
 #if defined(NRF52_PLATFORM)
   #include <InternalFileSystem.h>
+#elif defined(RP2040_PLATFORM)
+  #include <LittleFS.h>
 #elif defined(ESP32)
   #include <SPIFFS.h>
 #endif
@@ -270,6 +272,8 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
   File openAppend(const char* fname) {
     #if defined(NRF52_PLATFORM)
       return _fs->open(fname, FILE_O_WRITE);
+    #elif defined(RP2040_PLATFORM)
+      return _fs->open(fname, "a");
     #else
       return _fs->open(fname, "a", true);
     #endif
@@ -725,6 +729,8 @@ public:
   bool formatFileSystem() override {
     #if defined(NRF52_PLATFORM)
       return InternalFS.format();
+    #elif defined(RP2040_PLATFORM)
+      return LittleFS.format();
     #elif defined(ESP32)
       return SPIFFS.format();
     #else
@@ -764,7 +770,11 @@ public:
   }
 
   void dumpLogFile() override {
+  #if defined(RP2040_PLATFORM)
+    File f = _fs->open(PACKET_LOG_FILE, "r");
+  #else
     File f = _fs->open(PACKET_LOG_FILE);
+  #endif
     if (f) {
       while (f.available()) {
         int c = f.read();
@@ -875,6 +885,10 @@ void setup() {
   InternalFS.begin();
   fs = &InternalFS;
   IdentityStore store(InternalFS, "");
+#elif defined(RP2040_PLATFORM)
+  LittleFS.begin();
+  fs = &LittleFS;
+  IdentityStore store(LittleFS, "/identity");
 #elif defined(ESP32)
   SPIFFS.begin(true);
   fs = &SPIFFS;

+ 17 - 0
examples/simple_secure_chat/main.cpp

@@ -3,6 +3,8 @@
 
 #if defined(NRF52_PLATFORM)
   #include <InternalFileSystem.h>
+#elif defined(RP2040_PLATFORM)
+  #include <LittleFS.h>
 #elif defined(ESP32)
   #include <SPIFFS.h>
 #endif
@@ -88,7 +90,11 @@ class MyMesh : public BaseChatMesh, ContactVisitor {
 
   void loadContacts() {
     if (_fs->exists("/contacts")) {
+    #if defined(RP2040_PLATFORM)
+      File file = _fs->open("/contacts", "r");
+    #else
       File file = _fs->open("/contacts");
+    #endif
       if (file) {
         bool full = false;
         while (!full) {
@@ -123,6 +129,8 @@ class MyMesh : public BaseChatMesh, ContactVisitor {
 #if defined(NRF52_PLATFORM)
     File file = _fs->open("/contacts", FILE_O_WRITE);
     if (file) { file.seek(0); file.truncate(); }
+#elif defined(RP2040_PLATFORM)
+    File file = _fs->open("/contacts", "w");
 #else
     File file = _fs->open("/contacts", "w", true);
 #endif
@@ -309,7 +317,11 @@ public:
 
     // load persisted prefs
     if (_fs->exists("/node_prefs")) {
+    #if defined(RP2040_PLATFORM)
+      File file = _fs->open("/node_prefs", "r");
+    #else
       File file = _fs->open("/node_prefs");
+    #endif
       if (file) {
         file.read((uint8_t *) &_prefs, sizeof(_prefs));
         file.close();
@@ -324,6 +336,8 @@ public:
 #if defined(NRF52_PLATFORM)
     File file = _fs->open("/node_prefs", FILE_O_WRITE);
     if (file) { file.seek(0); file.truncate(); }
+#elif defined(RP2040_PLATFORM)
+    File file = _fs->open("/node_prefs", "w");
 #else
     File file = _fs->open("/node_prefs", "w", true);
 #endif
@@ -545,6 +559,9 @@ void setup() {
 #if defined(NRF52_PLATFORM)
   InternalFS.begin();
   the_mesh.begin(InternalFS);
+#elif defined(RP2040_PLATFORM)
+  LittleFS.begin();
+  the_mesh.begin(LittleFS);
 #elif defined(ESP32)
   SPIFFS.begin(true);
   the_mesh.begin(SPIFFS);

+ 9 - 1
platformio.ini

@@ -47,6 +47,7 @@ lib_deps =
   file://arch/esp32/AsyncElegantOTA
 
 ; ----------------- NRF52 ---------------------
+
 [nrf52_base]
 extends = arduino_base
 platform = nordicnrf52
@@ -59,4 +60,11 @@ build_flags = ${nrf52_base.build_flags}
 lib_deps =
   ${nrf52_base.lib_deps}
   rweather/Crypto @ ^0.4.0
-  https://github.com/adafruit/Adafruit_nRF52_Arduino
+  https://github.com/adafruit/Adafruit_nRF52_Arduino
+
+; ----------------- RP2040 ---------------------
+
+[rp2040_base]
+extends = arduino_base
+build_flags = ${arduino_base.build_flags}
+  -D RP2040_PLATFORM

+ 6 - 0
src/helpers/CommonCLI.cpp

@@ -24,7 +24,11 @@ void CommonCLI::loadPrefs(FILESYSTEM* fs) {
 }
 
 void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
+#if defined(RP2040_PLATFORM)
+  File file = fs->open(filename, "r");
+#else
   File file = fs->open(filename);
+#endif
   if (file) {
     uint8_t pad[8];
 
@@ -72,6 +76,8 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
 #if defined(NRF52_PLATFORM)
   File file = fs->open("/com_prefs", FILE_O_WRITE);
   if (file) { file.seek(0); file.truncate(); }
+#elif defined(RP2040_PLATFORM)
+  File file = fs->open("/com_prefs", "w");
 #else
   File file = fs->open("/com_prefs", "w", true);
 #endif

+ 12 - 0
src/helpers/IdentityStore.cpp

@@ -5,7 +5,11 @@ bool IdentityStore::load(const char *name, mesh::LocalIdentity& id) {
   char filename[40];
   sprintf(filename, "%s/%s.id", _dir, name);
   if (_fs->exists(filename)) {
+#if defined(RP2040_PLATFORM)
+    File file = _fs->open(filename, "r");
+#else
     File file = _fs->open(filename);
+#endif
     if (file) {
       loaded = id.readFrom(file);
       file.close();
@@ -19,7 +23,11 @@ bool IdentityStore::load(const char *name, mesh::LocalIdentity& id, char display
   char filename[40];
   sprintf(filename, "%s/%s.id", _dir, name);
   if (_fs->exists(filename)) {
+#if defined(RP2040_PLATFORM)
+    File file = _fs->open(filename, "r");
+#else
     File file = _fs->open(filename);
+#endif
     if (file) {
       loaded = id.readFrom(file);
 
@@ -41,6 +49,8 @@ bool IdentityStore::save(const char *name, const mesh::LocalIdentity& id) {
 #if defined(NRF52_PLATFORM)
   File file = _fs->open(filename, FILE_O_WRITE);
   if (file) { file.seek(0); file.truncate(); }
+#elif defined(RP2040_PLATFORM)
+  File file = _fs->open(filename, "w");
 #else
   File file = _fs->open(filename, "w", true);
 #endif
@@ -61,6 +71,8 @@ bool IdentityStore::save(const char *name, const mesh::LocalIdentity& id, const
 #if defined(NRF52_PLATFORM)
   File file = _fs->open(filename, FILE_O_WRITE);
   if (file) { file.seek(0); file.truncate(); }
+#elif defined(RP2040_PLATFORM)
+  File file = _fs->open(filename, "w");
 #else
   File file = _fs->open(filename, "w", true);
 #endif

+ 1 - 1
src/helpers/IdentityStore.h

@@ -1,6 +1,6 @@
 #pragma once
 
-#if defined(ESP32)
+#if defined(ESP32) || defined(RP2040_PLATFORM)
   #include <FS.h>
   #define FILESYSTEM  fs::FS
 #elif defined(NRF52_PLATFORM)

+ 42 - 0
src/helpers/rp2040/PicoWBoard.cpp

@@ -0,0 +1,42 @@
+#include <Arduino.h>
+#include "PicoWBoard.h"
+
+//#include <bluefruit.h>
+#include <Wire.h>
+
+//static BLEDfu bledfu;
+
+static void connect_callback(uint16_t conn_handle) {
+  (void)conn_handle;
+  MESH_DEBUG_PRINTLN("BLE client connected");
+}
+
+static void disconnect_callback(uint16_t conn_handle, uint8_t reason) {
+  (void)conn_handle;
+  (void)reason;
+
+  MESH_DEBUG_PRINTLN("BLE client disconnected");
+}
+
+void PicoWBoard::begin() {
+  // for future use, sub-classes SHOULD call this from their begin()
+  startup_reason = BD_STARTUP_NORMAL;
+  pinMode(PIN_VBAT_READ, INPUT);
+#ifdef PIN_USER_BTN
+  pinMode(PIN_USER_BTN, INPUT_PULLUP);
+#endif
+
+#if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
+  Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL);
+#endif
+
+  Wire.begin();
+
+  //pinMode(SX126X_POWER_EN, OUTPUT);
+  //digitalWrite(SX126X_POWER_EN, HIGH);
+  delay(10);   // give sx1262 some time to power up
+}
+
+bool PicoWBoard::startOTAUpdate(const char* id, char reply[]) {
+  return false;
+}

+ 64 - 0
src/helpers/rp2040/PicoWBoard.h

@@ -0,0 +1,64 @@
+#pragma once
+
+#include <MeshCore.h>
+#include <Arduino.h>
+
+// LoRa radio module pins for PicoW
+#define  P_LORA_DIO_1   20
+#define  P_LORA_NSS     3
+#define  P_LORA_RESET   15
+#define  P_LORA_BUSY    2
+#define  P_LORA_SCLK    10
+#define  P_LORA_MISO    12
+#define  P_LORA_MOSI    11
+//#define  SX126X_POWER_EN  ??? // Not Sure
+
+#define SX126X_DIO2_AS_RF_SWITCH  true
+#define SX126X_DIO3_TCXO_VOLTAGE   1.8
+
+// built-ins
+#define  PIN_VBAT_READ    26
+#define  ADC_MULTIPLIER   (3.1 * 3.3 * 1000) // MT Uses 3.1
+#define  PIN_LED_BUILTIN  LED_BUILTIN
+
+class PicoWBoard : public mesh::MainBoard {
+protected:
+  uint8_t startup_reason;
+
+public:
+  void begin();
+  uint8_t getStartupReason() const override { return startup_reason; }
+
+  void onBeforeTransmit() override {
+    digitalWrite(LED_BUILTIN, HIGH);   // turn TX LED on
+  }
+
+  void onAfterTransmit() override {
+    digitalWrite(LED_BUILTIN, LOW);   // turn TX LED off
+  }
+
+  #define BATTERY_SAMPLES 8
+
+  uint16_t getBattMilliVolts() override {
+    analogReadResolution(12);
+
+    uint32_t raw = 0;
+    for (int i = 0; i < BATTERY_SAMPLES; i++) {
+      raw += analogRead(PIN_VBAT_READ);
+    }
+    raw = raw / BATTERY_SAMPLES;
+
+    return (ADC_MULTIPLIER * raw) / 4096;
+  }
+
+  const char* getManufacturerName() const override {
+    return "Pico W";
+  }
+
+  void reboot() override {
+    //NVIC_SystemReset();
+    rp2040.reboot();
+  }
+
+  bool startOTAUpdate(const char* id, char reply[]) override;
+};

+ 103 - 0
variants/picow/platformio.ini

@@ -0,0 +1,103 @@
+[picow]
+extends = rp2040_base
+platform = https://github.com/maxgerhardt/platform-raspberrypi.git
+board = rpipicow
+board_build.core = earlephilhower
+board_build.filesystem_size = 0.5m
+build_flags = ${rp2040_base.build_flags}
+  -I variants/picow
+;  -D PICOW
+;  -D HW_SPI1_DEVICE
+  -D SX126X_CURRENT_LIMIT=130
+  -D RADIO_CLASS=CustomSX1262
+  -D WRAPPER_CLASS=CustomSX1262Wrapper
+  -D LORA_TX_POWER=22
+  -D SX126X_RX_BOOSTED_GAIN=1
+build_src_filter = ${rp2040_base.build_src_filter}
+  +<helpers/rp2040/*.cpp>
+  +<../variants/picow>
+lib_deps = ${rp2040_base.lib_deps}
+
+[env:PicoW_Repeater]
+extends = picow
+build_flags = ${picow.build_flags}
+  -D ADVERT_NAME='"PicoW Repeater"'
+  -D ADVERT_LAT=0.0
+  -D ADVERT_LON=0.0
+  -D ADMIN_PASSWORD='"password"'
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+build_src_filter = ${picow.build_src_filter}
+  +<../examples/simple_repeater>
+
+[env:PicoW_room_server]
+extends = picow
+build_flags = ${picow.build_flags}
+  -D ADVERT_NAME='"Test Room"'
+  -D ADVERT_LAT=0.0
+  -D ADVERT_LON=0.0
+  -D ADMIN_PASSWORD='"password"'
+  -D ROOM_PASSWORD='"hello"'
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+build_src_filter = ${picow.build_src_filter}
+  +<../examples/simple_room_server>
+
+[env:PicoW_companion_radio_usb]
+extends = picow
+build_flags = ${picow.build_flags}
+  -D MAX_CONTACTS=100
+  -D MAX_GROUP_CHANNELS=8
+;  -D ENABLE_PRIVATE_KEY_IMPORT=1
+;  -D ENABLE_PRIVATE_KEY_EXPORT=1
+; NOTE: DO NOT ENABLE -->  -D MESH_PACKET_LOGGING=1
+; NOTE: DO NOT ENABLE -->  -D MESH_DEBUG=1
+build_src_filter = ${picow.build_src_filter}
+  +<../examples/companion_radio>
+lib_deps = ${picow.lib_deps}
+  densaugeo/base64 @ ~1.4.0
+
+; [env:PicoW_companion_radio_ble]
+; extends = picow
+; build_flags = ${picow.build_flags}
+;   -D MAX_CONTACTS=100
+;   -D MAX_GROUP_CHANNELS=8
+;   -D BLE_PIN_CODE=123456
+;   -D BLE_DEBUG_LOGGING=1
+; ;  -D ENABLE_PRIVATE_KEY_IMPORT=1
+; ;  -D ENABLE_PRIVATE_KEY_EXPORT=1
+; ;  -D MESH_PACKET_LOGGING=1
+; ;  -D MESH_DEBUG=1
+; build_src_filter = ${picow.build_src_filter}
+;   +<../examples/companion_radio>
+; lib_deps = ${picow.lib_deps}
+;   densaugeo/base64 @ ~1.4.0
+
+; [env:PicoW_companion_radio_wifi]
+; extends = picow
+; build_flags = ${picow.build_flags}
+;   -D MAX_CONTACTS=100
+;   -D MAX_GROUP_CHANNELS=8
+;   -D WIFI_DEBUG_LOGGING=1
+;   -D WIFI_SSID='"myssid"'
+;   -D WIFI_PWD='"mypwd"'
+; ;  -D ENABLE_PRIVATE_KEY_IMPORT=1
+; ;  -D ENABLE_PRIVATE_KEY_EXPORT=1
+; ;  -D MESH_PACKET_LOGGING=1
+; ;  -D MESH_DEBUG=1
+; build_src_filter = ${picow.build_src_filter}
+;   +<../examples/companion_radio>
+; lib_deps = ${picow.lib_deps}
+;   densaugeo/base64 @ ~1.4.0
+
+[env:PicoW_terminal_chat]
+extends = picow
+build_flags = ${picow.build_flags}
+  -D MAX_CONTACTS=100
+  -D MAX_GROUP_CHANNELS=1
+  -D MESH_PACKET_LOGGING=1
+  -D MESH_DEBUG=1
+build_src_filter = ${picow.build_src_filter}
+  +<../examples/simple_secure_chat/main.cpp>
+lib_deps = ${picow.lib_deps}
+  densaugeo/base64 @ ~1.4.0

+ 73 - 0
variants/picow/target.cpp

@@ -0,0 +1,73 @@
+#include <Arduino.h>
+#include "target.h"
+#include <helpers/ArduinoHelpers.h>
+
+PicoWBoard board;
+
+RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI1);
+
+WRAPPER_CLASS radio_driver(radio, board);
+
+VolatileRTCClock fallback_clock;
+AutoDiscoverRTCClock rtc_clock(fallback_clock);
+
+#ifndef LORA_CR
+  #define LORA_CR      5
+#endif
+
+bool radio_init() {
+  rtc_clock.begin(Wire);
+  
+#ifdef SX126X_DIO3_TCXO_VOLTAGE
+  float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
+#else
+  float tcxo = 1.6f;
+#endif
+
+  SPI1.setMISO(P_LORA_MISO);
+  //SPI1.setCS(P_LORA_NSS); // Setting CS results in freeze
+  SPI1.setSCK(P_LORA_SCLK);
+  SPI1.setMOSI(P_LORA_MOSI);
+
+  SPI1.begin();
+  int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo);
+  if (status != RADIOLIB_ERR_NONE) {
+    Serial.print("ERROR: radio init failed: ");
+    Serial.println(status);
+    return false;  // fail
+  }
+  
+  radio.setCRC(1);
+  
+#ifdef SX126X_CURRENT_LIMIT
+  radio.setCurrentLimit(SX126X_CURRENT_LIMIT);
+#endif
+#ifdef SX126X_DIO2_AS_RF_SWITCH
+  radio.setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH);
+#endif
+#ifdef SX126X_RX_BOOSTED_GAIN
+  radio.setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN);
+#endif
+
+  return true;  // success
+}
+
+uint32_t radio_get_rng_seed() {
+  return radio.random(0x7FFFFFFF);
+}
+
+void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
+  radio.setFrequency(freq);
+  radio.setSpreadingFactor(sf);
+  radio.setBandwidth(bw);
+  radio.setCodingRate(cr);
+}
+
+void radio_set_tx_power(uint8_t dbm) {
+  radio.setOutputPower(dbm);
+}
+
+mesh::LocalIdentity radio_new_identity() {
+  RadioNoiseListener rng(radio);
+  return mesh::LocalIdentity(&rng);  // create new random identity
+}

+ 18 - 0
variants/picow/target.h

@@ -0,0 +1,18 @@
+#pragma once
+
+#define RADIOLIB_STATIC_ONLY 1
+#include <RadioLib.h>
+#include <helpers/RadioLibWrappers.h>
+#include <helpers/rp2040/PicoWBoard.h>
+#include <helpers/CustomSX1262Wrapper.h>
+#include <helpers/AutoDiscoverRTCClock.h>
+
+extern PicoWBoard board;
+extern WRAPPER_CLASS radio_driver;
+extern AutoDiscoverRTCClock rtc_clock;
+
+bool radio_init();
+uint32_t radio_get_rng_seed();
+void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
+void radio_set_tx_power(uint8_t dbm);
+mesh::LocalIdentity radio_new_identity();