1
0
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:
Stefan de Bruijn
2021-06-13 22:30:16 +02:00
parent 2f0e7e716e
commit 733b701860
7 changed files with 156 additions and 21 deletions

View File

@@ -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

View 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;
}

View 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();
};

View File

@@ -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();

View File

@@ -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) {

View File

@@ -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" />

View File

@@ -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">