Change GPIO input to polling (#484)

* add code to attach timer isr

* call timer ISR every 100 ms

* implement gpio input logic

* do not attach ISR for general input PINs

* add debounce code

* execute lock actions on GPIO input

* only register timer ISR if input PINs are configured

* remove gpio2go lib
This commit is contained in:
Jan-Ole Schümann
2024-10-13 23:01:04 +07:00
committed by GitHub
parent 3f0ef34c9e
commit fed5f95490
12 changed files with 166 additions and 582 deletions

View File

@@ -47,9 +47,6 @@ set(SRCFILES
../lib/nuki_ble/src/NukiUtils.cpp
../lib/nuki_ble/src/NukiLockUtils.cpp
../lib/nuki_ble/src/NukiOpenerUtils.cpp
../lib/gpio2go/src/Gpio2Go.cpp
../lib/gpio2go/src/InterruptMode.h
../lib/gpio2go/src/PinMode.h
../lib/BleScanner/src/BleInterfaces.h
../lib/BleScanner/src/BleScanner.cpp
../lib/MqttLogger/src/MqttLogger.cpp

View File

@@ -1,58 +0,0 @@
cmake_minimum_required(VERSION 3.0.0)
if(NOT ARDUINO_BOARD)
set(ARDUINO_BOARD "ESP32 Dev Module [esp32.esp32]")
endif()
project(gpio2go CXX)
# ARDUHAL_LOG_LEVEL_NONE, define ARDUHAL_LOG_LEVEL_ERROR, define ARDUHAL_LOG_LEVEL_WARN, define ARDUHAL_LOG_LEVEL_INFO,
# define ARDUHAL_LOG_LEVEL_DEBUG, define ARDUHAL_LOG_LEVEL_VERBOSE
set(LOG_LEVEL ARDUHAL_LOG_LEVEL_NONE)
#add_compile_definitions(DEBUG_SENSE_NUKI)
#add_compile_definitions(DEBUG_NUKI_COMMAND)
#add_compile_definitions(DEBUG_NUKI_CONNECT)
#add_compile_definitions(DEBUG_NUKI_COMMUNICATION)
#add_compile_definitions(DEBUG_NUKI_HEX_DATA)
#add_compile_definitions(DEBUG_NUKI_READABLE_DATA)
add_compile_definitions(ESP_PLATFORM)
add_compile_definitions(ESP32)
add_compile_definitions(ARDUINO_ARCH_ESP32)
include_directories(${PROJECT_NAME}
PRIVATE
src
)
set(SRCFILES
src/PinMode.h
src/Gpio2Go.cpp
src/InterruptMode.h
)
file(GLOB_RECURSE SRCFILESREC
)
add_executable(${PROJECT_NAME}
main.cpp
${SRCFILES}
${SRCFILESREC}
)
target_compile_definitions(${PROJECT_NAME}
PRIVATE
ARDUHAL_LOG_LEVEL=${LOG_LEVEL}
CORE_DEBUG_LEVEL=${LOG_LEVEL}
)
target_link_arduino_libraries(${PROJECT_NAME}
PRIVATE
core
)
target_enable_arduino_upload(${PROJECT_NAME})

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2023 Jan-Ole Schümann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1 +0,0 @@
# gpio2go

View File

@@ -1,38 +0,0 @@
#include "Arduino.h"
#include "Gpio2Go.h"
#define INPUT_PIN 21
bool hasMessage = false;
String message;
void inputCb(const int & pin)
{
message = "";
message.concat("Input, Pin ");
message.concat(pin);
message.concat(" ");
message.concat(", state ");
message.concat(digitalRead(INPUT_PIN) ? "High" : "Low");
hasMessage = true;
}
void setup()
{
Serial.begin(115200);
delay(1100);
Serial.println(F("Started"));
Gpio2Go::configurePin(INPUT_PIN, PinMode::InputPullup, InterruptMode::Change, 200);
Gpio2Go::subscribe(inputCb);
}
void loop()
{
delay(100);
if(hasMessage)
{
hasMessage = false;
Serial.println(message);
}
}

View File

@@ -1,242 +0,0 @@
#include "Gpio2Go.h"
#include <stdexcept>
void Gpio2Go::configurePin(int pin, PinMode pin_Mode, InterruptMode interrupt_Mode, uint16_t timeoutAfterTriggerMS)
{
timeoutDurations[pin - GPIO2GO_NR_FIRST_PIN] = timeoutAfterTriggerMS;
switch(pin_Mode)
{
case PinMode::InputPullup:
pinMode(pin, INPUT_PULLUP);
attachIsr(pin, interrupt_Mode);
break;
case PinMode::InputPullDown:
pinMode(pin, INPUT_PULLDOWN);
attachIsr(pin, interrupt_Mode);
break;
case PinMode::Output:
pinMode(pin, OUTPUT);
break;
}
}
void Gpio2Go::subscribe(std::function<void(const int &)> callback)
{
subscriptions.push_back(callback);
}
unsigned long Gpio2Go::getLastTriggeredMillis(const int &pin)
{
if(pin >= GPIO2GO_NR_FIRST_PIN && pin <= (GPIO2GO_NR_OF_PINS + GPIO2GO_NR_FIRST_PIN))
{
return lastTriggeredTimestamps[pin - GPIO2GO_NR_FIRST_PIN];
}
return -1;
}
void Gpio2Go::attachIsr(int pin, InterruptMode interruptMode)
{
switch(pin)
{
case 2:
attachInterrupt(2, isrGpio2, resolveInterruptMode(interruptMode));
break;
case 4:
attachInterrupt(4, isrGpio4, resolveInterruptMode(interruptMode));
break;
case 5:
attachInterrupt(5, isrGpio5, resolveInterruptMode(interruptMode));
break;
case 13:
attachInterrupt(13, isrGpio13, resolveInterruptMode(interruptMode));
break;
case 14:
attachInterrupt(14, isrGpio14, resolveInterruptMode(interruptMode));
break;
case 15:
attachInterrupt(15, isrGpio15, resolveInterruptMode(interruptMode));
break;
case 16:
attachInterrupt(16, isrGpio16, resolveInterruptMode(interruptMode));
break;
case 17:
attachInterrupt(17, isrGpio17, resolveInterruptMode(interruptMode));
break;
case 18:
attachInterrupt(18, isrGpio18, resolveInterruptMode(interruptMode));
break;
case 19:
attachInterrupt(19, isrGpio19, resolveInterruptMode(interruptMode));
break;
case 20:
attachInterrupt(20, isrGpio20, resolveInterruptMode(interruptMode));
break;
case 21:
attachInterrupt(21, isrGpio21, resolveInterruptMode(interruptMode));
break;
case 22:
attachInterrupt(22, isrGpio22, resolveInterruptMode(interruptMode));
break;
case 23:
attachInterrupt(23, isrGpio23, resolveInterruptMode(interruptMode));
break;
case 24:
attachInterrupt(24, isrGpio24, resolveInterruptMode(interruptMode));
break;
case 25:
attachInterrupt(25, isrGpio25, resolveInterruptMode(interruptMode));
break;
case 26:
attachInterrupt(26, isrGpio26, resolveInterruptMode(interruptMode));
break;
case 27:
attachInterrupt(27, isrGpio27, resolveInterruptMode(interruptMode));
break;
case 32:
attachInterrupt(32, isrGpio32, resolveInterruptMode(interruptMode));
break;
case 33:
attachInterrupt(33, isrGpio33, resolveInterruptMode(interruptMode));
break;
default:
throw std::runtime_error("Gpio2Go: Unsupported pin.");
}
}
int Gpio2Go::resolveInterruptMode(InterruptMode interruptMode)
{
switch(interruptMode)
{
case InterruptMode::Rising:
return RISING;
case InterruptMode::Falling:
return FALLING;
case InterruptMode::Change:
return CHANGE;
case InterruptMode::OnLow:
return ONLOW;
case InterruptMode::OnHigh:
return ONHIGH;
default:
throw std::runtime_error("Gpio2Go: Unsupported interrupt mode.");
}
}
void Gpio2Go::isrHandler(int pin)
{
unsigned long timeout = lastTriggeredTimestamps[pin - GPIO2GO_NR_FIRST_PIN];
if(timeoutDurations[pin - GPIO2GO_NR_FIRST_PIN] != 0 && (millis() - timeout) < timeoutDurations[pin - GPIO2GO_NR_FIRST_PIN]) return;
lastTriggeredTimestamps[pin - GPIO2GO_NR_FIRST_PIN] = millis();
bool state = digitalRead(pin) == HIGH;
for(const auto& callback : subscriptions)
{
callback(pin);
}
}
void Gpio2Go::isrGpio2()
{
isrHandler(2);
}
void Gpio2Go::isrGpio4()
{
isrHandler(4);
}
void Gpio2Go::isrGpio5()
{
isrHandler(5);
}
void Gpio2Go::isrGpio13()
{
isrHandler(13);
}
void Gpio2Go::isrGpio14()
{
isrHandler(14);
}
void Gpio2Go::isrGpio15()
{
isrHandler(15);
}
void Gpio2Go::isrGpio16()
{
isrHandler(16);
}
void Gpio2Go::isrGpio17()
{
isrHandler(17);
}
void Gpio2Go::isrGpio18()
{
isrHandler(18);
}
void Gpio2Go::isrGpio19()
{
isrHandler(19);
}
void Gpio2Go::isrGpio20()
{
isrHandler(20);
}
void Gpio2Go::isrGpio21()
{
isrHandler(21);
}
void Gpio2Go::isrGpio22()
{
isrHandler(22);
}
void Gpio2Go::isrGpio23()
{
isrHandler(23);
}
void Gpio2Go::isrGpio24()
{
isrHandler(24);
}
void Gpio2Go::isrGpio25()
{
isrHandler(25);
}
void Gpio2Go::isrGpio26()
{
isrHandler(26);
}
void Gpio2Go::isrGpio27()
{
isrHandler(27);
}
void Gpio2Go::isrGpio32()
{
isrHandler(32);
}
void Gpio2Go::isrGpio33()
{
isrHandler(33);
}
unsigned long Gpio2Go::lastTriggeredTimestamps[] = {0};
uint16_t Gpio2Go::timeoutDurations[] = {0};
std::vector<std::function<void(const int&)>> Gpio2Go::subscriptions;

View File

@@ -1,49 +0,0 @@
#pragma once
#include <Arduino.h>
#include <vector>
#include "esp_attr.h"
#include "PinMode.h"
#include "InterruptMode.h"
#define GPIO2GO_NR_OF_PINS 31
#define GPIO2GO_NR_FIRST_PIN 2
class Gpio2Go
{
public:
static void configurePin(int pin, PinMode pin_Mode, InterruptMode interrupt_Mode, uint16_t timeoutAfterTriggerMS);
static void subscribe(std::function<void(const int&)> callback);
unsigned long getLastTriggeredMillis(const int& pin);
private:
static void attachIsr(int pin, InterruptMode interruptMode);
static int resolveInterruptMode(InterruptMode interruptMode);
static void IRAM_ATTR isrHandler(int pin);
static void IRAM_ATTR isrGpio2();
static void IRAM_ATTR isrGpio4();
static void IRAM_ATTR isrGpio5();
static void IRAM_ATTR isrGpio13();
static void IRAM_ATTR isrGpio14();
static void IRAM_ATTR isrGpio15();
static void IRAM_ATTR isrGpio16();
static void IRAM_ATTR isrGpio17();
static void IRAM_ATTR isrGpio18();
static void IRAM_ATTR isrGpio19();
static void IRAM_ATTR isrGpio20();
static void IRAM_ATTR isrGpio21();
static void IRAM_ATTR isrGpio22();
static void IRAM_ATTR isrGpio23();
static void IRAM_ATTR isrGpio24();
static void IRAM_ATTR isrGpio25();
static void IRAM_ATTR isrGpio26();
static void IRAM_ATTR isrGpio27();
static void IRAM_ATTR isrGpio32();
static void IRAM_ATTR isrGpio33();
static unsigned long DRAM_ATTR lastTriggeredTimestamps[GPIO2GO_NR_OF_PINS];
static uint16_t DRAM_ATTR timeoutDurations[GPIO2GO_NR_OF_PINS];
static std::vector<std::function<void(const int&)>> DRAM_ATTR subscriptions;
};

View File

@@ -1,10 +0,0 @@
#pragma once
enum class InterruptMode
{
Rising = 0x01,
Falling = 0x02,
Change = 0x03,
OnLow = 0x04,
OnHigh = 0x05
};

View File

@@ -1,20 +0,0 @@
#pragma once
enum class PinMode
{
Output = 0x03,
InputPullup = 0x05,
InputPullDown = 0x09
};
//#define INPUT 0x01
//// Changed OUTPUT from 0x02 to behave the same as Arduino pinMode(pin,OUTPUT)
//// where you can read the state of pin even when it is set as OUTPUT
//#define OUTPUT 0x03
//#define PULLUP 0x04
//#define INPUT_PULLUP 0x05
//#define PULLDOWN 0x08
//#define INPUT_PULLDOWN 0x09
//#define OPEN_DRAIN 0x10
//#define OUTPUT_OPEN_DRAIN 0x12
//#define ANALOG 0xC0

View File

@@ -4,7 +4,7 @@
#define NUKI_HUB_VERSION "9.01"
#define NUKI_HUB_BUILD "unknownbuildnr"
#define NUKI_HUB_DATE "2024-09-01"
#define NUKI_HUB_DATE "2024-10-13"
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"

View File

@@ -5,13 +5,11 @@
#include "Logger.h"
#include "PreferencesKeys.h"
#include "RestartReason.h"
#include "Gpio2Go.h"
#include "networkDevices/LAN8720Definitions.h"
#include "networkDevices/DM9051Definitions.h"
#include "networkDevices/W5500Definitions.h"
Gpio* Gpio::_inst = nullptr;
int64_t Gpio::_debounceTs = 0;
const uint Gpio::_debounceTime = GPIO_DEBOUNCE_TIME;
Gpio::Gpio(Preferences* preferences)
@@ -28,8 +26,101 @@ Gpio::Gpio(Preferences* preferences)
_inst->init();
}
bool Gpio::isTriggered(const PinEntry& entry)
{
const int threshold = 3;
int state = digitalRead(entry.pin);
if(entry.role == PinRole::GeneralInputPullDown)
{
state = 1 - state;
}
if(state == LOW)
{
if (_triggerCount[entry.pin] >= 0)
{
_triggerCount[entry.pin]++;
}
if (_triggerCount[entry.pin] >= threshold)
{
_triggerCount[entry.pin] = -1;
return true;
}
}
else
{
if (_triggerCount[entry.pin] < 0)
{
_triggerCount[entry.pin]--;
if(_triggerCount[entry.pin] <= -threshold)
{
_triggerCount[entry.pin] = 0;
}
}
}
return false;
}
void Gpio::onTimer()
{
for(const auto& entry : _inst->_pinConfiguration)
{
switch(entry.role)
{
case PinRole::InputLock:
case PinRole::InputUnlock:
case PinRole::InputUnlatch:
case PinRole::InputLockNgo:
case PinRole::InputLockNgoUnlatch:
case PinRole::InputElectricStrikeActuation:
case PinRole::InputActivateRTO:
case PinRole::InputActivateCM:
case PinRole::InputDeactivateRtoCm:
case PinRole::InputDeactivateRTO:
case PinRole::InputDeactivateCM:
case PinRole::GeneralInputPullDown:
case PinRole::GeneralInputPullUp:
if(isTriggered(entry))
{
_inst->notify(getGpioAction(entry.role), entry.pin);
}
break;
case PinRole::OutputHighLocked:
case PinRole::OutputHighUnlocked:
case PinRole::OutputHighMotorBlocked:
case PinRole::OutputHighRtoActive:
case PinRole::OutputHighCmActive:
case PinRole::OutputHighRtoOrCmActive:
case PinRole::GeneralOutput:
case PinRole::Ethernet:
// ignore. This case should not occur since pins are configured as output
default:
break;
}
}
}
void Gpio::isrOnTimer()
{
_inst->onTimer();
}
void Gpio::init()
{
_inst->_triggerCount.reserve(_inst->availablePins().size());
for(int i=0; i<_inst->availablePins().size(); i++)
{
_inst->_triggerCount.push_back(0);
}
bool hasInputPin = false;
for(const auto& entry : _inst->_pinConfiguration)
{
const auto it = std::find(_inst->availablePins().begin(), _inst->availablePins().end(), entry.pin);
@@ -42,48 +133,23 @@ void Gpio::init()
switch(entry.role)
{
case PinRole::InputLock:
pinMode(entry.pin, INPUT_PULLUP);
attachInterrupt(entry.pin, isrLock, FALLING);
break;
case PinRole::InputUnlock:
pinMode(entry.pin, INPUT_PULLUP);
attachInterrupt(entry.pin, isrUnlock, FALLING);
break;
case PinRole::InputUnlatch:
pinMode(entry.pin, INPUT_PULLUP);
attachInterrupt(entry.pin, isrUnlatch, FALLING);
break;
case PinRole::InputLockNgo:
pinMode(entry.pin, INPUT_PULLUP);
attachInterrupt(entry.pin, isrLockNgo, FALLING);
break;
case PinRole::InputLockNgoUnlatch:
pinMode(entry.pin, INPUT_PULLUP);
attachInterrupt(entry.pin, isrLockNgoUnlatch, FALLING);
break;
case PinRole::InputElectricStrikeActuation:
pinMode(entry.pin, INPUT_PULLUP);
attachInterrupt(entry.pin, isrElectricStrikeActuation, FALLING);
break;
case PinRole::InputActivateRTO:
pinMode(entry.pin, INPUT_PULLUP);
attachInterrupt(entry.pin, isrActivateRTO, FALLING);
break;
case PinRole::InputActivateCM:
pinMode(entry.pin, INPUT_PULLUP);
attachInterrupt(entry.pin, isrActivateCM, FALLING);
break;
case PinRole::InputDeactivateRtoCm:
pinMode(entry.pin, INPUT_PULLUP);
attachInterrupt(entry.pin, isrDeactivateRtoCm, FALLING);
break;
case PinRole::InputDeactivateRTO:
pinMode(entry.pin, INPUT_PULLUP);
attachInterrupt(entry.pin, isrDeactivateRTO, FALLING);
break;
case PinRole::InputDeactivateCM:
case PinRole::GeneralInputPullUp:
pinMode(entry.pin, INPUT_PULLUP);
attachInterrupt(entry.pin, isrDeactivateCM, FALLING);
hasInputPin = true;
break;
case PinRole::GeneralInputPullDown:
pinMode(entry.pin, INPUT_PULLDOWN);
hasInputPin = true;
break;
case PinRole::OutputHighLocked:
case PinRole::OutputHighUnlocked:
@@ -94,19 +160,17 @@ void Gpio::init()
case PinRole::GeneralOutput:
pinMode(entry.pin, OUTPUT);
break;
case PinRole::GeneralInputPullDown:
Gpio2Go::configurePin(entry.pin, PinMode::InputPullDown, InterruptMode::Change, 300);
break;
case PinRole::GeneralInputPullUp:
Gpio2Go::configurePin(entry.pin, PinMode::InputPullup, InterruptMode::Change, 300);
break;
case PinRole::Ethernet:
break;
default:
break;
}
}
Gpio2Go::subscribe(Gpio::inputCallback);
if(hasInputPin)
{
_inst->timer = timerBegin(1000000);
timerAttachInterrupt(_inst->timer, isrOnTimer);
timerAlarm(_inst->timer, 100000, true, 0);
}
}
@@ -318,7 +382,7 @@ const PinRole Gpio::getPinRole(const int &pin) const
return PinRole::Disabled;
}
String Gpio::getRoleDescription(PinRole role) const
String Gpio::getRoleDescription(const PinRole& role) const
{
switch(role)
{
@@ -371,6 +435,53 @@ String Gpio::getRoleDescription(PinRole role) const
}
}
GpioAction Gpio::getGpioAction(const PinRole &role) const
{
switch(role)
{
case PinRole::Disabled:
return GpioAction::None;
case PinRole::InputLock:
return GpioAction::Lock;
case PinRole::InputUnlock:
return GpioAction::Unlock;
case PinRole::InputUnlatch:
return GpioAction::Unlatch;
case PinRole::InputLockNgo:
return GpioAction::LockNgo;
case PinRole::InputLockNgoUnlatch:
return GpioAction::LockNgoUnlatch;
case PinRole::InputElectricStrikeActuation:
return GpioAction::ElectricStrikeActuation;
case PinRole::InputActivateRTO:
return GpioAction::ActivateRTO;
case PinRole::InputActivateCM:
return GpioAction::ActivateCM;
case PinRole::InputDeactivateRtoCm:
return GpioAction::DeactivateRtoCm;
case PinRole::InputDeactivateRTO:
return GpioAction::DeactivateRTO;
case PinRole::InputDeactivateCM:
return GpioAction::DeactivateCM;
case PinRole::GeneralInputPullDown:
case PinRole::GeneralInputPullUp:
return GpioAction::GeneralInput;
case PinRole::GeneralOutput:
case PinRole::Ethernet:
case PinRole::OutputHighLocked:
case PinRole::OutputHighUnlocked:
case PinRole::OutputHighMotorBlocked:
case PinRole::OutputHighRtoActive:
case PinRole::OutputHighCmActive:
case PinRole::OutputHighRtoOrCmActive:
default:
return GpioAction::None;
}}
void Gpio::getConfigurationText(String& text, const std::vector<PinEntry>& pinConfiguration, const String& linebreak) const
{
for(const auto& entry : pinConfiguration)
@@ -403,93 +514,11 @@ void Gpio::notify(const GpioAction &action, const int& pin)
}
}
void Gpio::inputCallback(const int &pin)
{
_inst->notify(GpioAction::GeneralInput, pin);
}
void Gpio::addCallback(std::function<void(const GpioAction&, const int&)> callback)
{
_callbacks.push_back(callback);
}
void Gpio::isrLock()
{
if((esp_timer_get_time() / 1000) < _debounceTs) return;
_inst->notify(GpioAction::Lock, -1);
_debounceTs = (esp_timer_get_time() / 1000) + _debounceTime;
}
void Gpio::isrUnlock()
{
if((esp_timer_get_time() / 1000) < _debounceTs) return;
_inst->notify(GpioAction::Unlock, -1);
_debounceTs = (esp_timer_get_time() / 1000) + _debounceTime;
}
void Gpio::isrUnlatch()
{
if((esp_timer_get_time() / 1000) < _debounceTs) return;
_inst->notify(GpioAction::Unlatch, -1);
_debounceTs = (esp_timer_get_time() / 1000) + _debounceTime;
}
void Gpio::isrLockNgo()
{
if((esp_timer_get_time() / 1000) < _debounceTs) return;
_inst->notify(GpioAction::LockNgo, -1);
_debounceTs = (esp_timer_get_time() / 1000) + _debounceTime;
}
void Gpio::isrLockNgoUnlatch()
{
if((esp_timer_get_time() / 1000) < _debounceTs) return;
_inst->notify(GpioAction::LockNgoUnlatch, -1);
_debounceTs = (esp_timer_get_time() / 1000) + _debounceTime;
}
void Gpio::isrElectricStrikeActuation()
{
if((esp_timer_get_time() / 1000) < _debounceTs) return;
_inst->notify(GpioAction::ElectricStrikeActuation, -1);
_debounceTs = (esp_timer_get_time() / 1000) + _debounceTime;
}
void Gpio::isrActivateRTO()
{
if((esp_timer_get_time() / 1000) < _debounceTs) return;
_inst->notify(GpioAction::ActivateRTO, -1);
_debounceTs = (esp_timer_get_time() / 1000) + _debounceTime;
}
void Gpio::isrActivateCM()
{
if((esp_timer_get_time() / 1000) < _debounceTs) return;
_inst->notify(GpioAction::ActivateCM, -1);
_debounceTs = (esp_timer_get_time() / 1000) + _debounceTime;
}
void Gpio::isrDeactivateRtoCm()
{
if((esp_timer_get_time() / 1000) < _debounceTs) return;
_inst->notify(GpioAction::DeactivateRtoCm, -1);
_debounceTs = (esp_timer_get_time() / 1000) + _debounceTime;
}
void Gpio::isrDeactivateRTO()
{
if((esp_timer_get_time() / 1000) < _debounceTs) return;
_inst->notify(GpioAction::DeactivateRTO, -1);
_debounceTs = (esp_timer_get_time() / 1000) + _debounceTime;
}
void Gpio::isrDeactivateCM()
{
if((esp_timer_get_time() / 1000) < _debounceTs) return;
_inst->notify(GpioAction::DeactivateCM, -1);
_debounceTs = (esp_timer_get_time() / 1000) + _debounceTime;
}
void Gpio::setPinOutput(const uint8_t& pin, const uint8_t& state)
{
digitalWrite(pin, state);
@@ -523,3 +552,4 @@ void Gpio::migrateObsoleteSetting()
restartEsp(RestartReason::GpioConfigurationUpdated);
}

View File

@@ -43,7 +43,8 @@ enum class GpioAction
DeactivateRtoCm,
DeactivateRTO,
DeactivateCM,
GeneralInput
GeneralInput,
None
};
struct PinEntry
@@ -70,7 +71,8 @@ public:
const std::vector<int> getDisabledPins() const;
const PinRole getPinRole(const int& pin) const;
String getRoleDescription(PinRole role) const;
String getRoleDescription(const PinRole& role) const;
void getConfigurationText(String& text, const std::vector<PinEntry>& pinConfiguration, const String& linebreak = "\n") const;
const std::vector<PinRole>& getAllRoles() const;
@@ -79,7 +81,9 @@ public:
private:
void IRAM_ATTR notify(const GpioAction& action, const int& pin);
static void inputCallback(const int & pin);
void IRAM_ATTR onTimer();
bool IRAM_ATTR isTriggered(const PinEntry& pinEntry);
GpioAction IRAM_ATTR getGpioAction(const PinRole& role) const;
#if defined(CONFIG_IDF_TARGET_ESP32C3)
//Based on https://docs.espressif.com/projects/esp-idf/en/stable/esp32c3/api-reference/peripherals/gpio.html and https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
@@ -125,22 +129,14 @@ private:
std::vector<PinEntry> _pinConfiguration;
static const uint _debounceTime;
static void IRAM_ATTR isrLock();
static void IRAM_ATTR isrUnlock();
static void IRAM_ATTR isrUnlatch();
static void IRAM_ATTR isrLockNgo();
static void IRAM_ATTR isrLockNgoUnlatch();
static void IRAM_ATTR isrElectricStrikeActuation();
static void IRAM_ATTR isrActivateRTO();
static void IRAM_ATTR isrActivateCM();
static void IRAM_ATTR isrDeactivateRtoCm();
static void IRAM_ATTR isrDeactivateRTO();
static void IRAM_ATTR isrDeactivateCM();
static void IRAM_ATTR isrOnTimer();
std::vector<std::function<void(const GpioAction&, const int&)>> _callbacks;
static Gpio* _inst;
static int64_t _debounceTs;
std::vector<int8_t> _triggerCount;
hw_timer_t* timer = nullptr;
Preferences* _preferences = nullptr;
};