1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-08-30 17:49:56 +02:00

Added basic pin mapper to map Pin objects to Arduino API

This commit is contained in:
Stefan de Bruijn
2021-06-13 22:40:42 +02:00
parent 733b701860
commit db0ee2726a
2 changed files with 25 additions and 3 deletions

View File

@@ -4,8 +4,9 @@
#include <Arduino.h>
// Pin mapping. Pretty straight forward, it's just a thing that
// Pin mapping. Pretty straight forward, it's just a thing that stores pins in an array.
//
// The default behavior of a mapped pin is _undefined pin_, so it does nothing.
namespace {
class Mapping {
public:
@@ -37,18 +38,24 @@ namespace {
};
}
// See header file for more information.
PinMapper::PinMapper() : _mappedId(0) {}
PinMapper::PinMapper(Pin& pin) {
_mappedId = Mapping::instance().Claim(&pin);
// If you reach this assertion, you haven't been using the Pin class like you're supposed to.
Assert(_mappedId != 0, "Cannot claim pin. We've reached the limit of 255 mapped pins.");
}
// To aid return values and assignment
PinMapper::PinMapper(PinMapper&& o) : _mappedId(0) {
std::swap(_mappedId, o._mappedId);
}
PinMapper& PinMapper::operator=(PinMapper&& o) {
// Special case for `a=a`. If we release there, things go wrong.
if (&o != this) {
if (_mappedId != 0) {
Mapping::instance().Release(_mappedId);
@@ -59,6 +66,7 @@ PinMapper& PinMapper::operator=(PinMapper&& o) {
return *this;
}
// Clean up when we get destructed.
PinMapper::~PinMapper() {
if (_mappedId != 0) {
Mapping::instance().Release(_mappedId);
@@ -66,7 +74,6 @@ PinMapper::~PinMapper() {
}
// Arduino compatibility functions, which basically forward the call to the mapper:
void IRAM_ATTR digitalWrite(uint8_t pin, uint8_t val) {
auto thePin = Mapping::instance()._mapping[pin];
if (thePin) {

View File

@@ -2,6 +2,11 @@
// Pin mapper is a class that maps 'Pin' objects to Arduino digitalWrite / digitalRead / setMode. This
// can be useful for support of external libraries, while keeping all the things that Pin has to offer.
//
// It's designed to be easy to use. Basically just: `PinMapper myMap(pinToMap);`. It doesn't *own* the
// pin, it merely uses a pointer. Then, the external library can use `myMap.pinId()` as its pin number.
// Once the mapper goes out of scope (or is destructed if it's a field), the mapping is implicitly removed.
// Note that this is merely for external libraries that don't allow us to pass user data such as a void*...
#include "Pin.h"
@@ -9,16 +14,26 @@ class PinMapper {
uint8_t _mappedId;
public:
// Default constructor. Doesn't map anything
PinMapper();
// Constructor that maps a pin to some Arduino pin ID
PinMapper(Pin& pin);
// Let's not create copies, that will go wrong...
PinMapper(const Pin& o) = delete;
PinMapper& operator=(const Pin& o) = delete;
// For return values, we have to add some move semantics. This is just to
// support trivial assignment cases and return values. Normally: don't use it.
// All these constructors just pass along the id by swapping it. If a pinmapper
// goes out of scope, it is destructed.
PinMapper(PinMapper&& o);
PinMapper& operator=(PinMapper&& o);
// The ID of the pin, as used by digitalWrite, digitalRead and setMode.
inline uint8_t pinId() const { return _mappedId; }
// Destructor. Implicitly removes the mapping.
~PinMapper();
};