From 8a9cc727a8d73b9b9e0b1754d483954151abcb40 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 28 Aug 2024 09:59:42 -0700 Subject: [PATCH] for #4154 use a binary gpio transformer to manage vext on heltec-tracker (saves power) --- src/GpioLogic.cpp | 16 +++++++++++++++- src/GpioLogic.h | 30 +++++++++++++++++++++++------- src/gps/GPS.cpp | 11 +++++------ src/gps/GPS.h | 2 +- src/graphics/TFTDisplay.cpp | 4 ++++ src/graphics/TFTDisplay.h | 4 +++- 6 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/GpioLogic.cpp b/src/GpioLogic.cpp index c23c40a7f..cbe26fc60 100644 --- a/src/GpioLogic.cpp +++ b/src/GpioLogic.cpp @@ -12,6 +12,7 @@ void GpioVirtPin::set(bool value) void GpioHwPin::set(bool value) { + // if (num == 3) LOG_DEBUG("Setting pin %d to %d\n", num, value); pinMode(num, OUTPUT); digitalWrite(num, value); } @@ -23,7 +24,7 @@ void GpioTransformer::set(bool value) outPin->set(value); } -GpioNotTransformer::GpioNotTransformer(GpioVirtPin *inPin, GpioPin *outPin) : GpioTransformer(outPin), inPin(inPin) +GpioUnaryTransformer::GpioUnaryTransformer(GpioVirtPin *inPin, GpioPin *outPin) : GpioTransformer(outPin), inPin(inPin) { assert(!inPin->dependentPin); // We only allow one dependent pin inPin->dependentPin = this; @@ -33,6 +34,18 @@ GpioNotTransformer::GpioNotTransformer(GpioVirtPin *inPin, GpioPin *outPin) : Gp // update(); } +/** + * Update the output pin based on the current state of the input pin. + */ +void GpioUnaryTransformer::update() +{ + auto p = inPin->get(); + if (p == GpioVirtPin::PinState::Unset) + return; // Not yet fully initialized + + set(p); +} + /** * Update the output pin based on the current state of the input pin. */ @@ -75,6 +88,7 @@ void GpioBinaryTransformer::update() newValue = (GpioVirtPin::PinState)(p1 && p2); break; case Or: + // LOG_DEBUG("Doing GPIO OR\n"); newValue = (GpioVirtPin::PinState)(p1 || p2); break; case Xor: diff --git a/src/GpioLogic.h b/src/GpioLogic.h index c5a3cefa9..947d49625 100644 --- a/src/GpioLogic.h +++ b/src/GpioLogic.h @@ -42,7 +42,7 @@ class GpioBinaryTransformer; class GpioVirtPin : public GpioPin { friend class GpioBinaryTransformer; - friend class GpioNotTransformer; + friend class GpioUnaryTransformer; public: enum PinState { On = true, Off = false, Unset = 2 }; @@ -79,12 +79,31 @@ class GpioTransformer }; /** - * A transformer that performs a unary NOT operation from an input. + * A transformer that just drives a hw pin based on a virtual pin. */ -class GpioNotTransformer : public GpioTransformer +class GpioUnaryTransformer : public GpioTransformer { public: - GpioNotTransformer(GpioVirtPin *inPin, GpioPin *outPin); + GpioUnaryTransformer(GpioVirtPin *inPin, GpioPin *outPin); + + protected: + friend class GpioVirtPin; + + /** + * Update the output pin based on the current state of the input pin. + */ + virtual void update(); + + GpioVirtPin *inPin; +}; + +/** + * A transformer that performs a unary NOT operation from an input. + */ +class GpioNotTransformer : public GpioUnaryTransformer +{ + public: + GpioNotTransformer(GpioVirtPin *inPin, GpioPin *outPin) : GpioUnaryTransformer(inPin, outPin) {} protected: friend class GpioVirtPin; @@ -93,9 +112,6 @@ class GpioNotTransformer : public GpioTransformer * Update the output pin based on the current state of the input pin. */ void update(); - - private: - GpioVirtPin *inPin; }; /** diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index f7db1367a..12ef34c52 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -1415,19 +1415,18 @@ GPS *GPS::createGps() new_gps->rx_gpio = _rx_gpio; new_gps->tx_gpio = _tx_gpio; + GpioVirtPin *virtPin = new GpioVirtPin(); + new_gps->enablePin = virtPin; // Always at least populate a virtual pin 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; + } else { + new GpioUnaryTransformer( + virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio } - new_gps->enablePin = p; - } else { - // Just use a simulated pin - new_gps->enablePin = new GpioVirtPin(); } #ifdef PIN_GPS_PPS diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 494bddae8..befa4eef0 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -157,7 +157,7 @@ class GPS : private concurrency::OSThread * * Normally set by GPS::createGPS() */ - GpioPin *enablePin; + GpioVirtPin *enablePin; GPS() : concurrency::OSThread("GPS") {} diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index f6bd6513a..1dc4569db 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -25,6 +25,8 @@ extern SX1509 gpioExtender; #define TFT_INVERT true #endif +GpioPin *TFTDisplay::backlightEnable; + class LGFX : public lgfx::LGFX_Device { lgfx::Panel_ST7735S _panel_instance; @@ -584,6 +586,7 @@ void TFTDisplay::sendCommand(uint8_t com) // handle display on/off directly switch (com) { case DISPLAYON: { + // LOG_DEBUG("Display on\n"); backlightEnable->set(true); #if ARCH_PORTDUINO display(true); @@ -607,6 +610,7 @@ void TFTDisplay::sendCommand(uint8_t com) break; } case DISPLAYOFF: { + // LOG_DEBUG("Display off\n"); backlightEnable->set(false); #if ARCH_PORTDUINO tft->clear(); diff --git a/src/graphics/TFTDisplay.h b/src/graphics/TFTDisplay.h index 595984fbc..38cd53ebb 100644 --- a/src/graphics/TFTDisplay.h +++ b/src/graphics/TFTDisplay.h @@ -43,8 +43,10 @@ class TFTDisplay : public OLEDDisplay /** * This is normally managed entirely by TFTDisplay, but some rare applications (heltec tracker) might need to replace the * default GPIO behavior with something a bit more complex. + * + * We (cruftily) make it static so that variant.cpp can access it without needing a ptr to the TFTDisplay instance. */ - GpioPin *backlightEnable; + static GpioPin *backlightEnable; protected: // the header size of the buffer used, e.g. for the SPI command header