Skip to content

Commit

Permalink
Pass Pin around instead of gpio_num_t
Browse files Browse the repository at this point in the history
  • Loading branch information
lptr committed Oct 26, 2024
1 parent 0c5b0c8 commit 6467f94
Show file tree
Hide file tree
Showing 28 changed files with 373 additions and 313 deletions.
2 changes: 1 addition & 1 deletion main/devices/Device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ class ConsoleProvider : public LogConsumer {
: logRecords(logRecords)
, recordedLevel(recordedLevel) {
Serial.begin(115200);
Serial1.begin(115200, SERIAL_8N1, pins::RXD0, pins::TXD0);
Serial1.begin(115200, SERIAL_8N1, pins::RXD0->getGpio(), pins::TXD0->getGpio());
#if Serial != Serial0
Serial0.begin(115200);
#endif
Expand Down
4 changes: 2 additions & 2 deletions main/devices/DeviceDefinition.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class DeviceConfiguration : public ConfigurationSection {
template <typename TDeviceConfiguration>
class DeviceDefinition {
public:
DeviceDefinition(gpio_num_t statusPin, gpio_num_t bootPin)
DeviceDefinition(PinPtr statusPin, PinPtr bootPin)
: statusLed("status", statusPin)
, bootPin(bootPin) {
}
Expand Down Expand Up @@ -99,7 +99,7 @@ class DeviceDefinition {
LedDriver statusLed;
PcntManager pcnt;
PwmManager pwm;
const gpio_num_t bootPin;
const PinPtr bootPin;

private:
ConfigurationFile<TDeviceConfiguration> configFile { FileSystem::get(), "/device-config.json" };
Expand Down
88 changes: 61 additions & 27 deletions main/devices/Pin.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include <exception>
#include <map>
#include <memory>
#include <optional>
#include <vector>

Expand All @@ -10,68 +12,100 @@

namespace farmhub::devices {

class Pin;
using PinPtr = std::shared_ptr<Pin>;

class Pin {
public:
static gpio_num_t registerPin(const String& name, gpio_num_t pin) {
GPIO_NUMBERS[name] = pin;
GPIO_NAMES[pin] = name;
static PinPtr registerPin(const String& name, gpio_num_t gpio) {
auto pin = std::make_shared<Pin>(name, gpio);
BY_GPIO[gpio] = pin;
BY_NAME[name] = pin;
return pin;
}

static gpio_num_t numberOf(const String& name) {
auto it = GPIO_NUMBERS.find(name);
if (it != GPIO_NUMBERS.end()) {
static PinPtr byName(const String& name) {
auto it = BY_NAME.find(name);
if (it != BY_NAME.end()) {
return it->second;
}
return GPIO_NUM_MAX;
throw std::runtime_error(String("Unknown pin: " + name).c_str());
}

static String nameOf(gpio_num_t pin) {
auto it = GPIO_NAMES.find(pin);
if (it == GPIO_NAMES.end()) {
static PinPtr byGpio(gpio_num_t pin) {
auto it = BY_GPIO.find(pin);
if (it == BY_GPIO.end()) {
String name = "GPIO_NUM_" + String(pin);
registerPin(name, pin);
return name;
return registerPin(name, pin);
} else {
return it->second;
}
}

static bool isRegistered(gpio_num_t pin) {
return GPIO_NAMES.find(pin) != GPIO_NAMES.end();
Pin(const String& name, gpio_num_t gpio)
: name(name)
, gpio(gpio) {
}

inline void pinMode(uint8_t mode) const {
::pinMode(gpio, mode);
}

inline void digitalWrite(uint8_t val) const {
::digitalWrite(gpio, val);
}

inline int digitalRead() const {
return ::digitalRead(gpio);
}

inline uint16_t analogRead() const {
return ::analogRead(gpio);
}

inline const String& getName() const {
return name;
}

inline gpio_num_t getGpio() const {
return gpio;
}

private:
bool useName;
const String name;
const gpio_num_t gpio;

static std::map<gpio_num_t, String> GPIO_NAMES;
static std::map<String, gpio_num_t> GPIO_NUMBERS;
static std::map<gpio_num_t, PinPtr> BY_GPIO;
static std::map<String, PinPtr> BY_NAME;
};

std::map<gpio_num_t, String> Pin::GPIO_NAMES;
std::map<String, gpio_num_t> Pin::GPIO_NUMBERS;
std::map<gpio_num_t, PinPtr> Pin::BY_GPIO;
std::map<String, PinPtr> Pin::BY_NAME;

} // namespace farmhub::devices

namespace ArduinoJson {

using farmhub::devices::Pin;
using farmhub::devices::PinPtr;

template <>
struct Converter<gpio_num_t> {
static void toJson(const gpio_num_t& src, JsonVariant dst) {
if (Pin::isRegistered(src)) {
dst.set(Pin::nameOf(src));
struct Converter<PinPtr> {
static void toJson(const PinPtr& src, JsonVariant dst) {
if (src == nullptr) {
dst.set(nullptr);
} else if (src->getName().startsWith("GPIO_NUM_")) {
dst.set(static_cast<int>(src->getGpio()));
} else {
dst.set(static_cast<int>(src));
dst.set(src->getName());
}
}

static gpio_num_t fromJson(JsonVariantConst src) {
static PinPtr fromJson(JsonVariantConst src) {
if (src.is<const char*>()) {
return Pin::numberOf(src.as<const char*>());
return Pin::byName(src.as<const char*>());
} else {
return static_cast<gpio_num_t>(src.as<int>());
return Pin::byGpio(static_cast<gpio_num_t>(src.as<int>()));
}
}

Expand Down
38 changes: 19 additions & 19 deletions main/devices/UglyDucklingMk4.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,25 @@ class Mk4Config
};

namespace pins {
static gpio_num_t BOOT = Pin::registerPin("BOOT", GPIO_NUM_0);
static gpio_num_t STATUS = Pin::registerPin("STATUS", GPIO_NUM_26);

static gpio_num_t SOIL_MOISTURE = Pin::registerPin("SOIL_MOISTURE", GPIO_NUM_6);
static gpio_num_t SOIL_TEMP = Pin::registerPin("SOIL_TEMP", GPIO_NUM_7);

static gpio_num_t VALVE_EN = Pin::registerPin("VALVE_EN", GPIO_NUM_10);
static gpio_num_t VALVE_PH = Pin::registerPin("VALVE_PH", GPIO_NUM_11);
static gpio_num_t VALVE_FAULT = Pin::registerPin("VALVE_FAULT", GPIO_NUM_12);
static gpio_num_t VALVE_SLEEP = Pin::registerPin("VALVE_SLEEP", GPIO_NUM_13);
static gpio_num_t VALVE_MODE1 = Pin::registerPin("VALVE_MODE1", GPIO_NUM_14);
static gpio_num_t VALVE_MODE2 = Pin::registerPin("VALVE_MODE2", GPIO_NUM_15);
static gpio_num_t VALVE_CURRENT = Pin::registerPin("VALVE_CURRENT", GPIO_NUM_16);
static gpio_num_t FLOW = Pin::registerPin("FLOW", GPIO_NUM_17);

static gpio_num_t SDA = Pin::registerPin("SDA", GPIO_NUM_8);
static gpio_num_t SCL = Pin::registerPin("SCL", GPIO_NUM_9);
static gpio_num_t RXD0 = Pin::registerPin("RXD0", GPIO_NUM_44);
static gpio_num_t TXD0 = Pin::registerPin("TXD0", GPIO_NUM_43);
static PinPtr BOOT = Pin::registerPin("BOOT", GPIO_NUM_0);
static PinPtr STATUS = Pin::registerPin("STATUS", GPIO_NUM_26);

static PinPtr SOIL_MOISTURE = Pin::registerPin("SOIL_MOISTURE", GPIO_NUM_6);
static PinPtr SOIL_TEMP = Pin::registerPin("SOIL_TEMP", GPIO_NUM_7);

static PinPtr VALVE_EN = Pin::registerPin("VALVE_EN", GPIO_NUM_10);
static PinPtr VALVE_PH = Pin::registerPin("VALVE_PH", GPIO_NUM_11);
static PinPtr VALVE_FAULT = Pin::registerPin("VALVE_FAULT", GPIO_NUM_12);
static PinPtr VALVE_SLEEP = Pin::registerPin("VALVE_SLEEP", GPIO_NUM_13);
static PinPtr VALVE_MODE1 = Pin::registerPin("VALVE_MODE1", GPIO_NUM_14);
static PinPtr VALVE_MODE2 = Pin::registerPin("VALVE_MODE2", GPIO_NUM_15);
static PinPtr VALVE_CURRENT = Pin::registerPin("VALVE_CURRENT", GPIO_NUM_16);
static PinPtr FLOW = Pin::registerPin("FLOW", GPIO_NUM_17);

static PinPtr SDA = Pin::registerPin("SDA", GPIO_NUM_8);
static PinPtr SCL = Pin::registerPin("SCL", GPIO_NUM_9);
static PinPtr RXD0 = Pin::registerPin("RXD0", GPIO_NUM_44);
static PinPtr TXD0 = Pin::registerPin("TXD0", GPIO_NUM_43);
} // namespace pins

class UglyDucklingMk4 : public DeviceDefinition<Mk4Config> {
Expand Down
80 changes: 40 additions & 40 deletions main/devices/UglyDucklingMk5.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,46 +33,46 @@ class Mk5Config
};

namespace pins {
static gpio_num_t BOOT = Pin::registerPin("BOOT", GPIO_NUM_0);
static gpio_num_t BATTERY = Pin::registerPin("BATTERY", GPIO_NUM_1);
static gpio_num_t STATUS = Pin::registerPin("STATUS", GPIO_NUM_2);
static gpio_num_t AIPROPI = Pin::registerPin("AIPROPI", GPIO_NUM_4);

static gpio_num_t IOA1 = Pin::registerPin("A1", GPIO_NUM_5);
static gpio_num_t IOA2 = Pin::registerPin("A2", GPIO_NUM_6);
static gpio_num_t BIPROPI = Pin::registerPin("BIPROPI", GPIO_NUM_7);
static gpio_num_t IOB1 = Pin::registerPin("B1", GPIO_NUM_15);
static gpio_num_t AIN1 = Pin::registerPin("AIN1", GPIO_NUM_16);
static gpio_num_t AIN2 = Pin::registerPin("AIN2", GPIO_NUM_17);
static gpio_num_t BIN1 = Pin::registerPin("BIN1", GPIO_NUM_18);
static gpio_num_t BIN2 = Pin::registerPin("BIN2", GPIO_NUM_8);

static gpio_num_t DMINUS = Pin::registerPin("D-", GPIO_NUM_19);
static gpio_num_t DPLUS = Pin::registerPin("D+", GPIO_NUM_20);

static gpio_num_t IOB2 = Pin::registerPin("B2", GPIO_NUM_9);

static gpio_num_t NSLEEP = Pin::registerPin("NSLEEP", GPIO_NUM_10);
static gpio_num_t NFault = Pin::registerPin("NFault", GPIO_NUM_11);
static gpio_num_t IOC4 = Pin::registerPin("C4", GPIO_NUM_12);
static gpio_num_t IOC3 = Pin::registerPin("C3", GPIO_NUM_13);
static gpio_num_t IOC2 = Pin::registerPin("C2", GPIO_NUM_14);
static gpio_num_t IOC1 = Pin::registerPin("C1", GPIO_NUM_21);
static gpio_num_t IOD4 = Pin::registerPin("D4", GPIO_NUM_47);
static gpio_num_t IOD3 = Pin::registerPin("D3", GPIO_NUM_48);

static gpio_num_t SDA = Pin::registerPin("SDA", GPIO_NUM_35);
static gpio_num_t SCL = Pin::registerPin("SCL", GPIO_NUM_36);

static gpio_num_t IOD1 = Pin::registerPin("D1", GPIO_NUM_37);
static gpio_num_t IOD2 = Pin::registerPin("D2", GPIO_NUM_38);

static gpio_num_t TCK = Pin::registerPin("TCK", GPIO_NUM_39);
static gpio_num_t TDO = Pin::registerPin("TDO", GPIO_NUM_40);
static gpio_num_t TDI = Pin::registerPin("TDI", GPIO_NUM_41);
static gpio_num_t TMS = Pin::registerPin("TMS", GPIO_NUM_42);
static gpio_num_t RXD0 = Pin::registerPin("RXD0", GPIO_NUM_44);
static gpio_num_t TXD0 = Pin::registerPin("TXD0", GPIO_NUM_43);
static PinPtr BOOT = Pin::registerPin("BOOT", GPIO_NUM_0);
static PinPtr BATTERY = Pin::registerPin("BATTERY", GPIO_NUM_1);
static PinPtr STATUS = Pin::registerPin("STATUS", GPIO_NUM_2);
static PinPtr AIPROPI = Pin::registerPin("AIPROPI", GPIO_NUM_4);

static PinPtr IOA1 = Pin::registerPin("A1", GPIO_NUM_5);
static PinPtr IOA2 = Pin::registerPin("A2", GPIO_NUM_6);
static PinPtr BIPROPI = Pin::registerPin("BIPROPI", GPIO_NUM_7);
static PinPtr IOB1 = Pin::registerPin("B1", GPIO_NUM_15);
static PinPtr AIN1 = Pin::registerPin("AIN1", GPIO_NUM_16);
static PinPtr AIN2 = Pin::registerPin("AIN2", GPIO_NUM_17);
static PinPtr BIN1 = Pin::registerPin("BIN1", GPIO_NUM_18);
static PinPtr BIN2 = Pin::registerPin("BIN2", GPIO_NUM_8);

static PinPtr DMINUS = Pin::registerPin("D-", GPIO_NUM_19);
static PinPtr DPLUS = Pin::registerPin("D+", GPIO_NUM_20);

static PinPtr IOB2 = Pin::registerPin("B2", GPIO_NUM_9);

static PinPtr NSLEEP = Pin::registerPin("NSLEEP", GPIO_NUM_10);
static PinPtr NFault = Pin::registerPin("NFault", GPIO_NUM_11);
static PinPtr IOC4 = Pin::registerPin("C4", GPIO_NUM_12);
static PinPtr IOC3 = Pin::registerPin("C3", GPIO_NUM_13);
static PinPtr IOC2 = Pin::registerPin("C2", GPIO_NUM_14);
static PinPtr IOC1 = Pin::registerPin("C1", GPIO_NUM_21);
static PinPtr IOD4 = Pin::registerPin("D4", GPIO_NUM_47);
static PinPtr IOD3 = Pin::registerPin("D3", GPIO_NUM_48);

static PinPtr SDA = Pin::registerPin("SDA", GPIO_NUM_35);
static PinPtr SCL = Pin::registerPin("SCL", GPIO_NUM_36);

static PinPtr IOD1 = Pin::registerPin("D1", GPIO_NUM_37);
static PinPtr IOD2 = Pin::registerPin("D2", GPIO_NUM_38);

static PinPtr TCK = Pin::registerPin("TCK", GPIO_NUM_39);
static PinPtr TDO = Pin::registerPin("TDO", GPIO_NUM_40);
static PinPtr TDI = Pin::registerPin("TDI", GPIO_NUM_41);
static PinPtr TMS = Pin::registerPin("TMS", GPIO_NUM_42);
static PinPtr RXD0 = Pin::registerPin("RXD0", GPIO_NUM_44);
static PinPtr TXD0 = Pin::registerPin("TXD0", GPIO_NUM_43);
} // namespace pins

class UglyDucklingMk5 : public DeviceDefinition<Mk5Config> {
Expand Down
84 changes: 42 additions & 42 deletions main/devices/UglyDucklingMk6.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,47 +27,47 @@ using namespace farmhub::peripherals::valve;
namespace farmhub::devices {

namespace pins {
static gpio_num_t BOOT = Pin::registerPin("BOOT", GPIO_NUM_0);
static gpio_num_t BATTERY = Pin::registerPin("BATTERY", GPIO_NUM_1);
static gpio_num_t STATUS = Pin::registerPin("STATUS", GPIO_NUM_2);
static gpio_num_t STATUS2 = Pin::registerPin("STATUS2", GPIO_NUM_4);

static gpio_num_t IOB1 = Pin::registerPin("B1", GPIO_NUM_5);
static gpio_num_t IOA1 = Pin::registerPin("A1", GPIO_NUM_6);
static gpio_num_t DIPROPI = Pin::registerPin("DIPROPI", GPIO_NUM_7);
static gpio_num_t IOA2 = Pin::registerPin("A2", GPIO_NUM_15);
static gpio_num_t AIN1 = Pin::registerPin("AIN1", GPIO_NUM_16);
static gpio_num_t AIN2 = Pin::registerPin("AIN2", GPIO_NUM_17);
static gpio_num_t BIN2 = Pin::registerPin("BIN2", GPIO_NUM_18);
static gpio_num_t BIN1 = Pin::registerPin("BIN1", GPIO_NUM_8);

static gpio_num_t DMINUS = Pin::registerPin("D-", GPIO_NUM_19);
static gpio_num_t DPLUS = Pin::registerPin("D+", GPIO_NUM_20);

static gpio_num_t LEDA_RED = Pin::registerPin("LEDA_RED", GPIO_NUM_46);
static gpio_num_t LEDA_GREEN = Pin::registerPin("LEDA_GREEN", GPIO_NUM_9);

static gpio_num_t NFault = Pin::registerPin("NFault", GPIO_NUM_11);
static gpio_num_t BTN1 = Pin::registerPin("BTN1", GPIO_NUM_12);
static gpio_num_t BTN2 = Pin::registerPin("BTN2", GPIO_NUM_13);
static gpio_num_t IOC4 = Pin::registerPin("C4", GPIO_NUM_14);
static gpio_num_t IOC3 = Pin::registerPin("C3", GPIO_NUM_21);
static gpio_num_t IOC2 = Pin::registerPin("C2", GPIO_NUM_47);
static gpio_num_t IOC1 = Pin::registerPin("C1", GPIO_NUM_48);
static gpio_num_t IOB2 = Pin::registerPin("B2", GPIO_NUM_45);

static gpio_num_t SDA = Pin::registerPin("SDA", GPIO_NUM_35);
static gpio_num_t SCL = Pin::registerPin("SCL", GPIO_NUM_36);

static gpio_num_t LEDB_GREEN = Pin::registerPin("LEDB_GREEN", GPIO_NUM_37);
static gpio_num_t LEDB_RED = Pin::registerPin("LEDB_RED", GPIO_NUM_38);

static gpio_num_t TCK = Pin::registerPin("TCK", GPIO_NUM_39);
static gpio_num_t TDO = Pin::registerPin("TDO", GPIO_NUM_40);
static gpio_num_t TDI = Pin::registerPin("TDI", GPIO_NUM_41);
static gpio_num_t TMS = Pin::registerPin("TMS", GPIO_NUM_42);
static gpio_num_t RXD0 = Pin::registerPin("RXD0", GPIO_NUM_44);
static gpio_num_t TXD0 = Pin::registerPin("TXD0", GPIO_NUM_43);
static PinPtr BOOT = Pin::registerPin("BOOT", GPIO_NUM_0);
static PinPtr BATTERY = Pin::registerPin("BATTERY", GPIO_NUM_1);
static PinPtr STATUS = Pin::registerPin("STATUS", GPIO_NUM_2);
static PinPtr STATUS2 = Pin::registerPin("STATUS2", GPIO_NUM_4);

static PinPtr IOB1 = Pin::registerPin("B1", GPIO_NUM_5);
static PinPtr IOA1 = Pin::registerPin("A1", GPIO_NUM_6);
static PinPtr DIPROPI = Pin::registerPin("DIPROPI", GPIO_NUM_7);
static PinPtr IOA2 = Pin::registerPin("A2", GPIO_NUM_15);
static PinPtr AIN1 = Pin::registerPin("AIN1", GPIO_NUM_16);
static PinPtr AIN2 = Pin::registerPin("AIN2", GPIO_NUM_17);
static PinPtr BIN2 = Pin::registerPin("BIN2", GPIO_NUM_18);
static PinPtr BIN1 = Pin::registerPin("BIN1", GPIO_NUM_8);

static PinPtr DMINUS = Pin::registerPin("D-", GPIO_NUM_19);
static PinPtr DPLUS = Pin::registerPin("D+", GPIO_NUM_20);

static PinPtr LEDA_RED = Pin::registerPin("LEDA_RED", GPIO_NUM_46);
static PinPtr LEDA_GREEN = Pin::registerPin("LEDA_GREEN", GPIO_NUM_9);

static PinPtr NFault = Pin::registerPin("NFault", GPIO_NUM_11);
static PinPtr BTN1 = Pin::registerPin("BTN1", GPIO_NUM_12);
static PinPtr BTN2 = Pin::registerPin("BTN2", GPIO_NUM_13);
static PinPtr IOC4 = Pin::registerPin("C4", GPIO_NUM_14);
static PinPtr IOC3 = Pin::registerPin("C3", GPIO_NUM_21);
static PinPtr IOC2 = Pin::registerPin("C2", GPIO_NUM_47);
static PinPtr IOC1 = Pin::registerPin("C1", GPIO_NUM_48);
static PinPtr IOB2 = Pin::registerPin("B2", GPIO_NUM_45);

static PinPtr SDA = Pin::registerPin("SDA", GPIO_NUM_35);
static PinPtr SCL = Pin::registerPin("SCL", GPIO_NUM_36);

static PinPtr LEDB_GREEN = Pin::registerPin("LEDB_GREEN", GPIO_NUM_37);
static PinPtr LEDB_RED = Pin::registerPin("LEDB_RED", GPIO_NUM_38);

static PinPtr TCK = Pin::registerPin("TCK", GPIO_NUM_39);
static PinPtr TDO = Pin::registerPin("TDO", GPIO_NUM_40);
static PinPtr TDI = Pin::registerPin("TDI", GPIO_NUM_41);
static PinPtr TMS = Pin::registerPin("TMS", GPIO_NUM_42);
static PinPtr RXD0 = Pin::registerPin("RXD0", GPIO_NUM_44);
static PinPtr TXD0 = Pin::registerPin("TXD0", GPIO_NUM_43);
} // namespace pins

class Mk6Config
Expand All @@ -81,7 +81,7 @@ class Mk6Config
* @brief The built-in motor driver's nSLEEP pin can be manually set by a jumper,
* but can be connected to a GPIO pin, too. Defaults to C2.
*/
Property<gpio_num_t> motorNSleepPin { this, "motorNSleepPin", pins::IOC2 };
Property<Pin> motorNSleepPin { this, "motorNSleepPin", pins::IOC2 };
};

class UglyDucklingMk6 : public DeviceDefinition<Mk6Config> {
Expand Down
Loading

0 comments on commit 6467f94

Please sign in to comment.