mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-08-30 17:49:56 +02:00
Implemented a new pin mapper. First use case is Trinamic
This commit is contained in:
@@ -60,8 +60,6 @@ void TMC2130Stepper::switchCSpin(bool state) {
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR pinMode(uint8_t pin, uint8_t mode) {}
|
||||
|
||||
namespace Motors {
|
||||
uint8_t TrinamicDriver::get_next_index() {
|
||||
#ifdef TRINAMIC_DAISY_CHAIN
|
||||
|
101
Grbl_Esp32/src/PinMapper.cpp
Normal file
101
Grbl_Esp32/src/PinMapper.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "PinMapper.h"
|
||||
|
||||
#include "Assert.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// Pin mapping. Pretty straight forward, it's just a thing that
|
||||
|
||||
namespace {
|
||||
class Mapping {
|
||||
public:
|
||||
Pin* _mapping[256];
|
||||
|
||||
Mapping() {
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
_mapping[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Claim(Pin* pin) {
|
||||
// Let's not use 0. 1 is the first pin we'll allocate.
|
||||
for (int i = 1; i < 256; ++i) {
|
||||
if (_mapping[i] == nullptr) {
|
||||
_mapping[i] = pin;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Release(uint8_t idx) { _mapping[idx] = nullptr; }
|
||||
|
||||
static Mapping& instance() {
|
||||
static Mapping instance;
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
PinMapper::PinMapper() : _mappedId(0) {}
|
||||
|
||||
PinMapper::PinMapper(Pin& pin) {
|
||||
_mappedId = Mapping::instance().Claim(&pin);
|
||||
Assert(_mappedId != 0, "Cannot claim pin. We've reached the limit of 255 mapped pins.");
|
||||
}
|
||||
|
||||
PinMapper::PinMapper(PinMapper&& o) : _mappedId(0) {
|
||||
std::swap(_mappedId, o._mappedId);
|
||||
}
|
||||
|
||||
PinMapper& PinMapper::operator=(PinMapper&& o) {
|
||||
if (&o != this) {
|
||||
if (_mappedId != 0) {
|
||||
Mapping::instance().Release(_mappedId);
|
||||
_mappedId = 0;
|
||||
}
|
||||
std::swap(_mappedId, o._mappedId);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
PinMapper::~PinMapper() {
|
||||
if (_mappedId != 0) {
|
||||
Mapping::instance().Release(_mappedId);
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
thePin->write(val);
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR pinMode(uint8_t pin, uint8_t mode) {
|
||||
Pins::PinAttributes attr = Pins::PinAttributes::None;
|
||||
if ((mode & OUTPUT) == OUTPUT) {
|
||||
attr = attr | Pins::PinAttributes::Output;
|
||||
}
|
||||
if ((mode & INPUT) == INPUT) {
|
||||
attr = attr | Pins::PinAttributes::Input;
|
||||
}
|
||||
if ((mode & PULLUP) == PULLUP) {
|
||||
attr = attr | Pins::PinAttributes::PullUp;
|
||||
}
|
||||
if ((mode & PULLDOWN) == PULLDOWN) {
|
||||
attr = attr | Pins::PinAttributes::PullDown;
|
||||
}
|
||||
|
||||
auto thePin = Mapping::instance()._mapping[pin];
|
||||
if (thePin) {
|
||||
thePin->setAttr(attr);
|
||||
}
|
||||
}
|
||||
|
||||
int IRAM_ATTR digitalRead(uint8_t pin) {
|
||||
auto thePin = Mapping::instance()._mapping[pin];
|
||||
return (thePin) ? thePin->read() : 0;
|
||||
}
|
24
Grbl_Esp32/src/PinMapper.h
Normal file
24
Grbl_Esp32/src/PinMapper.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
// 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.
|
||||
|
||||
#include "Pin.h"
|
||||
|
||||
class PinMapper {
|
||||
uint8_t _mappedId;
|
||||
|
||||
public:
|
||||
PinMapper();
|
||||
PinMapper(Pin& pin);
|
||||
|
||||
PinMapper(const Pin& o) = delete;
|
||||
PinMapper& operator=(const Pin& o) = delete;
|
||||
|
||||
PinMapper(PinMapper&& o);
|
||||
PinMapper& operator=(PinMapper&& o);
|
||||
|
||||
inline uint8_t pinId() const { return _mappedId; }
|
||||
|
||||
~PinMapper();
|
||||
};
|
@@ -1,6 +1,7 @@
|
||||
#include "../TestFramework.h"
|
||||
|
||||
#include <src/Pin.h>
|
||||
#include <src/PinMapper.h>
|
||||
|
||||
#ifdef ESP32
|
||||
extern "C" void __pinMode(uint8_t pin, uint8_t mode);
|
||||
@@ -39,9 +40,9 @@ struct GPIONative {
|
||||
inline static bool read(int pin) { return SoftwareGPIO::instance().read(pin); }
|
||||
};
|
||||
|
||||
//void digitalWrite(uint8_t pin, uint8_t val);
|
||||
//void pinMode(uint8_t pin, uint8_t mode);
|
||||
//int digitalRead(uint8_t pin);
|
||||
void digitalWrite(uint8_t pin, uint8_t val);
|
||||
void pinMode(uint8_t pin, uint8_t mode);
|
||||
int digitalRead(uint8_t pin);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -176,68 +177,70 @@ namespace Pins {
|
||||
|
||||
Test(GPIO, ISRChangePin) { TestISR(1, 1, CHANGE); }
|
||||
|
||||
/*
|
||||
Test(GPIO, NativeForwardingInput) {
|
||||
GPIONative::initialize();
|
||||
|
||||
Pin gpio16 = Pin::create("gpio.16");
|
||||
Pin gpio17 = Pin::create("gpio.17");
|
||||
|
||||
pinMode(16, INPUT);
|
||||
PinMapper map1(gpio16);
|
||||
PinMapper map2(gpio17);
|
||||
|
||||
pinMode(map1.pinId(), INPUT);
|
||||
gpio17.setAttr(Pin::Attr::Output);
|
||||
|
||||
Assert(LOW == digitalRead(16));
|
||||
Assert(LOW == digitalRead(map1.pinId()));
|
||||
Assert(false == gpio17.read());
|
||||
Assert(false == GPIONative::read(16));
|
||||
Assert(false == GPIONative::read(17));
|
||||
|
||||
gpio17.on();
|
||||
|
||||
Assert(HIGH == digitalRead(16));
|
||||
Assert(HIGH == digitalRead(map1.pinId()));
|
||||
Assert(true == gpio17.read());
|
||||
Assert(true == GPIONative::read(16));
|
||||
Assert(true == GPIONative::read(17));
|
||||
|
||||
gpio17.off();
|
||||
|
||||
Assert(LOW == digitalRead(16));
|
||||
Assert(LOW == digitalRead(map1.pinId()));
|
||||
Assert(false == gpio17.read());
|
||||
Assert(false == GPIONative::read(16));
|
||||
Assert(false == GPIONative::read(17));
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
Test(GPIO, NativeForwardingOutput) {
|
||||
GPIONative::initialize();
|
||||
|
||||
Pin gpio16 = Pin::create("gpio.16");
|
||||
Pin gpio17 = Pin::create("gpio.17");
|
||||
|
||||
pinMode(16, OUTPUT);
|
||||
PinMapper map1(gpio16);
|
||||
PinMapper map2(gpio17);
|
||||
|
||||
pinMode(map1.pinId(), OUTPUT);
|
||||
gpio17.setAttr(Pin::Attr::Input);
|
||||
|
||||
digitalWrite(16, LOW);
|
||||
Assert(LOW == digitalRead(16));
|
||||
digitalWrite(map1.pinId(), LOW);
|
||||
Assert(LOW == digitalRead(map1.pinId()));
|
||||
Assert(false == gpio17.read());
|
||||
Assert(false == GPIONative::read(16));
|
||||
Assert(false == GPIONative::read(17));
|
||||
|
||||
digitalWrite(16, HIGH);
|
||||
digitalWrite(map1.pinId(), HIGH);
|
||||
|
||||
Assert(HIGH == digitalRead(16));
|
||||
Assert(HIGH == digitalRead(map1.pinId()));
|
||||
Assert(true == gpio17.read());
|
||||
Assert(true == GPIONative::read(16));
|
||||
Assert(true == GPIONative::read(17));
|
||||
|
||||
digitalWrite(16, LOW);
|
||||
digitalWrite(map1.pinId(), LOW);
|
||||
|
||||
Assert(LOW == digitalRead(16));
|
||||
Assert(LOW == digitalRead(map1.pinId()));
|
||||
Assert(false == gpio17.read());
|
||||
Assert(false == GPIONative::read(16));
|
||||
Assert(false == GPIONative::read(17));
|
||||
}
|
||||
*/
|
||||
|
||||
Test(GPIO, Name) {
|
||||
GPIONative::initialize();
|
||||
|
@@ -25,7 +25,8 @@ namespace Pins {
|
||||
AssertThrow(unassigned.detachInterrupt());
|
||||
|
||||
Assert(unassigned.capabilities().has(Pin::Capabilities::Void));
|
||||
Assert(unassigned.name().equals(""));
|
||||
auto name = unassigned.name();
|
||||
Assert(unassigned.name().equals("NO_PIN"));
|
||||
}
|
||||
|
||||
Test(Undefined, MultipleInstances) {
|
||||
|
@@ -46,6 +46,7 @@
|
||||
<ClInclude Include="Grbl_Esp32\src\Configuration\TokenKind.h" />
|
||||
<ClInclude Include="Grbl_Esp32\src\Logging.h" />
|
||||
<ClInclude Include="Grbl_Esp32\src\Pin.h" />
|
||||
<ClInclude Include="Grbl_Esp32\src\PinMapper.h" />
|
||||
<ClInclude Include="Grbl_Esp32\src\Pins\ErrorPinDetail.h" />
|
||||
<ClInclude Include="Grbl_Esp32\src\Pins\GPIOPinDetail.h" />
|
||||
<ClInclude Include="Grbl_Esp32\src\Pins\I2SOPinDetail.h" />
|
||||
@@ -69,6 +70,7 @@
|
||||
<ClCompile Include="Grbl_Esp32\src\Configuration\Tokenizer.cpp" />
|
||||
<ClCompile Include="Grbl_Esp32\src\Logging.cpp" />
|
||||
<ClCompile Include="Grbl_Esp32\src\Pin.cpp" />
|
||||
<ClCompile Include="Grbl_Esp32\src\PinMapper.cpp" />
|
||||
<ClCompile Include="Grbl_Esp32\src\Pins\ErrorPinDetail.cpp" />
|
||||
<ClCompile Include="Grbl_Esp32\src\Pins\GPIOPinDetail.cpp" />
|
||||
<ClCompile Include="Grbl_Esp32\src\Pins\I2SOPinDetail.cpp" />
|
||||
|
@@ -99,6 +99,9 @@
|
||||
<ClInclude Include="Grbl_Esp32\src\Logging.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Grbl_Esp32\src\PinMapper.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Grbl_Esp32\test\TestFrameworkTest.cpp">
|
||||
@@ -188,6 +191,9 @@
|
||||
<ClCompile Include="Grbl_Esp32\src\Logging.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Grbl_Esp32\src\PinMapper.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Grbl_Esp32\test\UnitTests.md">
|
||||
|
Reference in New Issue
Block a user