From 5570b6bbc6542642735f774b95af56451ca87dda Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 22 Aug 2024 10:15:23 -0700 Subject: [PATCH] change GPS to use virtual GPIOs (for #4154) --- src/GpioLogic.cpp | 6 ++++++ src/GpioLogic.h | 2 +- src/gps/GPS.cpp | 27 +++++++++++++++++---------- src/gps/GPS.h | 11 +++++++++-- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/GpioLogic.cpp b/src/GpioLogic.cpp index d164615a7..c23c40a7f 100644 --- a/src/GpioLogic.cpp +++ b/src/GpioLogic.cpp @@ -10,6 +10,12 @@ void GpioVirtPin::set(bool value) } } +void GpioHwPin::set(bool value) +{ + pinMode(num, OUTPUT); + digitalWrite(num, value); +} + GpioTransformer::GpioTransformer(GpioPin *outPin) : outPin(outPin) {} void GpioTransformer::set(bool value) diff --git a/src/GpioLogic.h b/src/GpioLogic.h index 27e85d55b..c5a3cefa9 100644 --- a/src/GpioLogic.h +++ b/src/GpioLogic.h @@ -29,7 +29,7 @@ class GpioHwPin : public GpioPin public: explicit GpioHwPin(uint32_t num) : num(num) {} - void set(bool value) { digitalWrite(num, value); } + void set(bool value); }; class GpioTransformer; diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 7d7de8700..f7db1367a 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -2,6 +2,7 @@ #if !MESHTASTIC_EXCLUDE_GPS #include "Default.h" #include "GPS.h" +#include "GpioLogic.h" #include "NodeDB.h" #include "PowerMon.h" #include "RTC.h" @@ -875,16 +876,8 @@ void GPS::writePinEN(bool on) if (HW_VENDOR == meshtastic_HardwareModel_RAK4631 && (rotaryEncoderInterruptImpl1 || upDownInterruptImpl1)) return; - // Abort: if pin unset - if (!en_gpio) - return; - - // Determine new value for the pin - bool val = GPS_EN_ACTIVE ? on : !on; - // Write and log - pinMode(en_gpio, OUTPUT); - digitalWrite(en_gpio, val); + enablePin->set(on); #ifdef GPS_EXTRAVERBOSE LOG_DEBUG("Pin EN %s\n", val == HIGH ? "HIGH" : "LOW"); #endif @@ -1421,7 +1414,21 @@ GPS *GPS::createGps() GPS *new_gps = new GPS; new_gps->rx_gpio = _rx_gpio; new_gps->tx_gpio = _tx_gpio; - new_gps->en_gpio = _en_gpio; + + if (_en_gpio) { + GpioPin *p = new GpioHwPin(_en_gpio); + + if (!GPS_EN_ACTIVE) { // Need to invert the pin before hardware + auto virtPin = new GpioVirtPin(); + new GpioNotTransformer( + virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio + p = virtPin; + } + new_gps->enablePin = p; + } else { + // Just use a simulated pin + new_gps->enablePin = new GpioVirtPin(); + } #ifdef PIN_GPS_PPS // pulse per second diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 96171cba5..494bddae8 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -3,6 +3,7 @@ #if !MESHTASTIC_EXCLUDE_GPS #include "GPSStatus.h" +#include "GpioLogic.h" #include "Observer.h" #include "TinyGPS++.h" #include "concurrency/OSThread.h" @@ -73,7 +74,6 @@ class GPS : private concurrency::OSThread uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0; uint32_t rx_gpio = 0; uint32_t tx_gpio = 0; - uint32_t en_gpio = 0; int speedSelect = 0; int probeTries = 2; @@ -152,6 +152,13 @@ class GPS : private concurrency::OSThread meshtastic_Position p = meshtastic_Position_init_default; + /** This is normally bound to config.position.gps_en_gpio but some rare boards (like heltec tracker) need more advanced + * implementations. Those boards will set this public variable to a custom implementation. + * + * Normally set by GPS::createGPS() + */ + GpioPin *enablePin; + GPS() : concurrency::OSThread("GPS") {} virtual ~GPS(); @@ -303,4 +310,4 @@ class GPS : private concurrency::OSThread }; extern GPS *gps; -#endif // Exclude GPS +#endif // Exclude GPS \ No newline at end of file