|
/*
|
|
|
|
Generic digital pin interface
|
|
|
|
Copyright (C) 2020 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <Arduino.h>
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
|
|
#include "../config/types.h"
|
|
|
|
class BasePin {
|
|
public:
|
|
|
|
// TODO: we always need to explicitly call the constructor from the child
|
|
// class, because we need to set the const `pin` member on construction
|
|
// - https://isocpp.org/wiki/faq/multiple-inheritance#virtual-inheritance-ctors
|
|
|
|
// TODO: vtable anchoring? same applies to every implemented ..._pin.h
|
|
// not a problem when using single-source aka unity build (build with `env ESPURNA_BUILD_SINGLE_SOURCE=1`)
|
|
//
|
|
// Some sources:
|
|
// - https://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers
|
|
// > If a class is defined in a header file and has a vtable (either it has virtual methods or it derives from classes with virtual methods),
|
|
// > it must always have at least one out-of-line virtual method in the class. Without this, the compiler will copy the vtable and RTTI into
|
|
// > every .o file that #includes the header, bloating .o file sizes and increasing link times.
|
|
// - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1263r0.pdf
|
|
// > This technique is unfortunate as it relies on detailed knowledge of how common toolchains work, and it may also require creating
|
|
// > a dummy virtual function.
|
|
|
|
virtual ~BasePin();
|
|
virtual String description() const;
|
|
|
|
virtual const char* id() const = 0;
|
|
virtual unsigned char pin() const = 0;
|
|
|
|
virtual void pinMode(int8_t mode) = 0;
|
|
virtual void digitalWrite(int8_t val) = 0;
|
|
virtual int digitalRead() = 0;
|
|
|
|
operator bool() const {
|
|
return GPIO_NONE != pin();
|
|
}
|
|
};
|
|
|
|
using BasePinPtr = std::unique_ptr<BasePin>;
|