From 0d74735fe6d6af1f82c025ddb4f47177b80eb0d8 Mon Sep 17 00:00:00 2001 From: LegoManACM <41910060+LegoManACM@users.noreply.github.com> Date: Mon, 11 May 2026 23:27:01 -0700 Subject: [PATCH] Created Dragino Pico Board Def Currently just LoRa over usb --- variants/pico_dragino_sx1276/WaveshareBoard.h | 61 +++++++++++++++++++ variants/pico_dragino_sx1276/platformio.ini | 58 ++++++++++++++++++ variants/pico_dragino_sx1276/target.cpp | 56 +++++++++++++++++ variants/pico_dragino_sx1276/target.h | 20 ++++++ 4 files changed, 195 insertions(+) create mode 100644 variants/pico_dragino_sx1276/WaveshareBoard.h create mode 100644 variants/pico_dragino_sx1276/platformio.ini create mode 100644 variants/pico_dragino_sx1276/target.cpp create mode 100644 variants/pico_dragino_sx1276/target.h diff --git a/variants/pico_dragino_sx1276/WaveshareBoard.h b/variants/pico_dragino_sx1276/WaveshareBoard.h new file mode 100644 index 000000000..694b8bd12 --- /dev/null +++ b/variants/pico_dragino_sx1276/WaveshareBoard.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +// LoRa radio module pins for Waveshare RP2040-LoRa-HF/LF +// https://files.waveshare.com/wiki/RP2040-LoRa/Rp2040-lora-sch.pdf + +/* + * This board has no built-in way to read battery voltage. + * Nevertheless it's very easy to make it work, you only require two 1% resistors. + * + * BAT+ -----+ + * | + * VSYS --+ -/\/\/\/\- --+ + * 200k | + * +-- GPIO28 + * | + * GND --+ -/\/\/\/\- --+ + * | 100k + * BAT- -----+ + */ +#define PIN_VBAT_READ 28 +#define BATTERY_SAMPLES 8 +#define ADC_MULTIPLIER (3.0f * 3.3f * 1000) + +class WaveshareBoard : public mesh::MainBoard { +protected: + uint8_t startup_reason; + +public: + void begin(); + uint8_t getStartupReason() const override { return startup_reason; } + +#ifdef P_LORA_TX_LED + void onBeforeTransmit() override { digitalWrite(P_LORA_TX_LED, HIGH); } + void onAfterTransmit() override { digitalWrite(P_LORA_TX_LED, LOW); } +#endif + + uint16_t getBattMilliVolts() override { +#if defined(PIN_VBAT_READ) && defined(ADC_MULTIPLIER) + 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; +#else + return 0; +#endif + } + + const char *getManufacturerName() const override { return "Waveshare RP2040-LoRa"; } + + void reboot() override { rp2040.reboot(); } + + bool startOTAUpdate(const char *id, char reply[]) override; +}; diff --git a/variants/pico_dragino_sx1276/platformio.ini b/variants/pico_dragino_sx1276/platformio.ini new file mode 100644 index 000000000..e9f8d861a --- /dev/null +++ b/variants/pico_dragino_sx1276/platformio.ini @@ -0,0 +1,58 @@ +[pico_dragino_sx1276] +extends = rp2040_base +board = pico +build_flags = + ${rp2040_base.build_flags} + -I variants/pico_dragino_sx1276 + -I variants/waveshare_rp2040_lora + -D RADIO_CLASS=CustomSX1276 + -D WRAPPER_CLASS=CustomSX1276Wrapper + -D SX127X_CURRENT_LIMIT=120 + -D LORA_TX_POWER=17 + -D LORA_FREQ=915.0 + -D P_LORA_DIO_0=6 + -D P_LORA_DIO_1=7 + -D P_LORA_RST=8 + -D P_LORA_SCLK=18 + -D P_LORA_MISO=16 + -D P_LORA_MOSI=19 + -D P_LORA_NSS=17 + -D PIN_GPS_RX=9 + -D PIN_GPS_TX=8 + -D ENV_INCLUDE_GPS=1 +build_src_filter = ${rp2040_base.build_src_filter} + +<../variants/pico_dragino_sx1276> + +<../variants/waveshare_rp2040_lora/WaveshareBoard.cpp> +lib_deps = + ${rp2040_base.lib_deps} + stevemarple/MicroNMEA @ ^2.0.6 + +[env:pico_dragino_companion_radio_usb] +extends = pico_dragino_sx1276 +build_flags = + ${pico_dragino_sx1276.build_flags} + -D MAX_CONTACTS=100 + -D MAX_GROUP_CHANNELS=8 +build_src_filter = ${pico_dragino_sx1276.build_src_filter} + +<../examples/companion_radio/*.cpp> +lib_deps = + ${pico_dragino_sx1276.lib_deps} + densaugeo/base64 @ ~1.4.0 +lib_ignore = + BLE + WiFi + +[env:pico_dragino_repeater] +extends = pico_dragino_sx1276 +build_flags = + ${pico_dragino_sx1276.build_flags} + -D ADVERT_NAME='"Pico Repeater"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 + -D PERSISTANT_GPS=1 +build_src_filter = ${pico_dragino_sx1276.build_src_filter} + +<../examples/simple_repeater> +lib_deps = + ${pico_dragino_sx1276.lib_deps} \ No newline at end of file diff --git a/variants/pico_dragino_sx1276/target.cpp b/variants/pico_dragino_sx1276/target.cpp new file mode 100644 index 000000000..39e636e63 --- /dev/null +++ b/variants/pico_dragino_sx1276/target.cpp @@ -0,0 +1,56 @@ +#include "target.h" + +#include +#include + +WaveshareBoard board; + +RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RST, P_LORA_DIO_1, SPI); +WRAPPER_CLASS radio_driver(radio, board); + +VolatileRTCClock fallback_clock; +AutoDiscoverRTCClock rtc_clock(fallback_clock); +SensorManager sensors; + +bool radio_init() { + Serial.begin(115200); + delay(3000); + Serial.println("Starting up..."); + + rtc_clock.begin(Wire); + Serial.println("RTC done"); + + pinMode(P_LORA_RST, OUTPUT); + digitalWrite(P_LORA_RST, LOW); + delay(10); + digitalWrite(P_LORA_RST, HIGH); + delay(10); + Serial.println("Reset done"); + + SPI.begin(); + Serial.println("SPI done"); + + bool result = radio.std_init(NULL); + Serial.println(result ? "Radio OK" : "Radio FAILED"); + return result; +} + +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(int8_t dbm) { + radio.setOutputPower(dbm); +} + +mesh::LocalIdentity radio_new_identity() { + RadioNoiseListener rng(radio); + return mesh::LocalIdentity(&rng); +} \ No newline at end of file diff --git a/variants/pico_dragino_sx1276/target.h b/variants/pico_dragino_sx1276/target.h new file mode 100644 index 000000000..18702442e --- /dev/null +++ b/variants/pico_dragino_sx1276/target.h @@ -0,0 +1,20 @@ +#pragma once + +#define RADIOLIB_STATIC_ONLY 1 +#include +#include +#include +#include +#include +#include + +extern WaveshareBoard board; +extern WRAPPER_CLASS radio_driver; +extern AutoDiscoverRTCClock rtc_clock; +extern SensorManager sensors; + +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(int8_t dbm); +mesh::LocalIdentity radio_new_identity(); \ No newline at end of file