forked from meshtastic/firmware
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
for meshtastic#4154 and meshtastic#4136 add concept of dependent gpio…
…s... Which is currently only tested with the LED but eventually will be used for shared GPIO/screen power rail enable and LED forcing (which is a sanity check in the power stress testing)
- Loading branch information
1 parent
469ae0f
commit db68c88
Showing
9 changed files
with
261 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#include "GpioLogic.h" | ||
#include <assert.h> | ||
|
||
void GpioVirtPin::set(bool value) | ||
{ | ||
if (value != this->value) { | ||
this->value = value ? PinState::On : PinState::Off; | ||
if (dependentPin) | ||
dependentPin->update(); | ||
} | ||
} | ||
|
||
GpioLogicPin::GpioLogicPin(GpioPin *outPin) : outPin(outPin) {} | ||
|
||
void GpioLogicPin::set(bool value) | ||
{ | ||
outPin->set(value); | ||
} | ||
|
||
GpioNotPin::GpioNotPin(GpioVirtPin *inPin, GpioPin *outPin) : GpioLogicPin(outPin), inPin(inPin) | ||
{ | ||
assert(!inPin->dependentPin); // We only allow one dependent pin | ||
inPin->dependentPin = this; | ||
update(); | ||
} | ||
void GpioNotPin::set(bool value) | ||
{ | ||
outPin->set(value); | ||
} | ||
|
||
/** | ||
* Update the output pin based on the current state of the input pin. | ||
*/ | ||
void GpioNotPin::update() | ||
{ | ||
auto p = inPin->get(); | ||
if (p == GpioVirtPin::PinState::Unset) | ||
return; // Not yet fully initialized | ||
|
||
set(!p); | ||
} | ||
|
||
GpioBinaryLogicPin::GpioBinaryLogicPin(GpioVirtPin *inPin1, GpioVirtPin *inPin2, GpioPin *outPin, Operation operation) | ||
: GpioLogicPin(outPin), inPin1(inPin1), inPin2(inPin2), operation(operation) | ||
{ | ||
assert(!inPin1->dependentPin); // We only allow one dependent pin | ||
inPin1->dependentPin = this; | ||
assert(!inPin2->dependentPin); // We only allow one dependent pin | ||
inPin2->dependentPin = this; | ||
update(); | ||
} | ||
|
||
void GpioBinaryLogicPin::update() | ||
{ | ||
auto p1 = inPin1->get(), p2 = inPin2->get(); | ||
GpioVirtPin::PinState newValue = GpioVirtPin::PinState::Unset; | ||
|
||
if (p1 == GpioVirtPin::PinState::Unset) | ||
newValue = p2; // Not yet fully initialized | ||
else if (p2 == GpioVirtPin::PinState::Unset) | ||
newValue = p1; // Not yet fully initialized | ||
|
||
// If we've already found our value just use it, otherwise need to do the operation | ||
if (newValue == GpioVirtPin::PinState::Unset) { | ||
switch (operation) { | ||
case And: | ||
newValue = (GpioVirtPin::PinState)(p1 && p2); | ||
break; | ||
case Or: | ||
newValue = (GpioVirtPin::PinState)(p1 || p2); | ||
break; | ||
case Xor: | ||
newValue = (GpioVirtPin::PinState)(p1 != p2); | ||
break; | ||
default: | ||
assert(false); | ||
} | ||
} | ||
set(newValue); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#pragma once | ||
|
||
#include "configuration.h" | ||
|
||
/**This is a set of classes to mediate access to GPIOs in a structured way. Most usage of GPIOs do not | ||
require these classes! But if your hardware has a GPIO that is 'shared' between multiple devices (i.e. a shared power enable) | ||
then using these classes might be able to let you cleanly turn on that enable when either dependent device is needed. | ||
Note: these classes are intended to be 99% inline for the common case so should have minimal impact on flash or RAM | ||
requirements. | ||
*/ | ||
|
||
/** | ||
* A logical GPIO pin (not necessary raw hardware). | ||
*/ | ||
class GpioPin | ||
{ | ||
public: | ||
virtual void set(bool value) = 0; | ||
}; | ||
|
||
/** | ||
* A physical GPIO hw pin. | ||
*/ | ||
class GpioHwPin : public GpioPin | ||
{ | ||
uint32_t num; | ||
|
||
public: | ||
explicit GpioHwPin(uint32_t num) : num(num) {} | ||
|
||
void set(bool value) { digitalWrite(num, value); } | ||
}; | ||
|
||
class GpioLogicPin; | ||
class GpioNotPin; | ||
class GpioBinaryLogicPin; | ||
|
||
/** | ||
* A virtual GPIO pin. | ||
*/ | ||
class GpioVirtPin : public GpioPin | ||
{ | ||
friend class GpioBinaryLogicPin; | ||
friend class GpioNotPin; | ||
|
||
public: | ||
enum PinState { On = true, Off = false, Unset = 2 }; | ||
|
||
void set(bool value); | ||
PinState get() const { return value; } | ||
|
||
private: | ||
PinState value = PinState::Unset; | ||
GpioLogicPin *dependentPin = NULL; | ||
}; | ||
|
||
#include <assert.h> | ||
|
||
/** | ||
* A logical GPIO pin baseclass, notably: the set method is not public (because it always is calculated by a subclass) | ||
*/ | ||
class GpioLogicPin | ||
{ | ||
public: | ||
/** | ||
* Update the output pin based on the current state of the input pin. | ||
*/ | ||
virtual void update() = 0; | ||
|
||
protected: | ||
GpioLogicPin(GpioPin *outPin); | ||
|
||
void set(bool value); | ||
|
||
private: | ||
GpioPin *outPin; | ||
}; | ||
|
||
/** | ||
* A logical GPIO pin that performs a unary NOT operation on a virtual pin. | ||
*/ | ||
class GpioNotPin : public GpioLogicPin | ||
{ | ||
public: | ||
GpioNotPin(GpioVirtPin *inPin, GpioPin *outPin); | ||
void set(bool value); | ||
|
||
protected: | ||
friend class GpioVirtPin; | ||
|
||
/** | ||
* Update the output pin based on the current state of the input pin. | ||
*/ | ||
void update(); | ||
|
||
private: | ||
GpioVirtPin *inPin; | ||
GpioPin *outPin; | ||
}; | ||
|
||
/** | ||
* A logical GPIO pin that combines multiple virtual pins to drive a real physical pin | ||
*/ | ||
class GpioBinaryLogicPin : public GpioLogicPin | ||
{ | ||
|
||
public: | ||
enum Operation { And, Or, Xor }; | ||
|
||
GpioBinaryLogicPin(GpioVirtPin *inPin1, GpioVirtPin *inPin2, GpioPin *outPin, Operation operation); | ||
|
||
protected: | ||
friend class GpioVirtPin; | ||
|
||
/** | ||
* Update the output pin based on the current state of the input pins. | ||
*/ | ||
void update(); | ||
|
||
private: | ||
GpioVirtPin *inPin1; | ||
GpioVirtPin *inPin2; | ||
Operation operation; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#include "Led.h" | ||
|
||
GpioVirtPin ledForceOn, ledBlink; | ||
|
||
#if defined(LED_PIN) | ||
|
||
// Most boards have a GPIO for LED control | ||
GpioHwPin ledRawHwPin(LED_PIN); | ||
|
||
#elif defined(HAS_PMU) | ||
|
||
/** | ||
* A GPIO controlled by the PMU | ||
*/ | ||
class GpioPmuPin : public GpioPin | ||
{ | ||
public: | ||
void set(bool value) | ||
{ | ||
if (pmu_found && PMU) { | ||
// blink the axp led | ||
PMU->setChargingLedMode(ledOn ? XPOWERS_CHG_LED_ON : XPOWERS_CHG_LED_OFF); | ||
} | ||
} | ||
} ledRawHwPin; | ||
|
||
#else | ||
GpioVirtPin ledRawHwPin; // Dummy pin for no hardware | ||
#endif | ||
|
||
#if LED_INVERTED | ||
GpioPin ledHwPin = GpioNotPin(&ledRawHwPin); | ||
#else | ||
GpioPin &ledHwPin = ledRawHwPin; | ||
#endif | ||
|
||
static GpioBinaryLogicPin ledForcer(&ledForceOn, &ledBlink, &ledHwPin, GpioBinaryLogicPin::Or); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include "GpioLogic.h" | ||
#include "configuration.h" | ||
|
||
/** | ||
* ledForceOn and ledForceOff both override the normal ledBlinker behavior (which is controlled by main) | ||
*/ | ||
extern GpioVirtPin ledForceOn, ledBlink; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters