mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-09-11 09:04:53 +00:00
154 lines
3.8 KiB
C++
154 lines
3.8 KiB
C++
#include "GPIO_Direct_Access.h"
|
|
|
|
#include <Arduino.h>
|
|
|
|
#if defined(ARDUINO_ARCH_ESP8266)
|
|
# ifndef CORE_POST_3_0_0
|
|
# define IRAM_ATTR ICACHE_RAM_ATTR
|
|
# endif // ifndef CORE_POST_3_0_0
|
|
#endif // if defined(ARDUINO_ARCH_ESP8266)
|
|
|
|
|
|
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
|
|
|
IO_REG_TYPE DIRECT_pinRead(IO_REG_TYPE pin)
|
|
{
|
|
# ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
// ESP8266 GPIO 16 doesn't have direct access
|
|
if (pin == 16) { return digitalRead(pin); }
|
|
# endif // ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
return DIRECT_READ(reg, PIN_TO_BITMASK(pin));
|
|
}
|
|
|
|
void DIRECT_pinWrite(IO_REG_TYPE pin, bool pinstate)
|
|
{
|
|
# ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
// ESP8266 GPIO 16 doesn't have direct access
|
|
if (pin == 16) {
|
|
digitalWrite(pin, pinstate);
|
|
return;
|
|
}
|
|
if (pinstate) { DIRECT_WRITE_HIGH(reg, PIN_TO_BITMASK(pin)); }
|
|
else { DIRECT_WRITE_LOW(reg, PIN_TO_BITMASK(pin)); }
|
|
#else
|
|
directWrite(pin, pinstate ? 1u : 0u);
|
|
# endif // ifdef ARDUINO_ARCH_ESP8266
|
|
}
|
|
|
|
void DIRECT_PINMODE_OUTPUT(IO_REG_TYPE pin)
|
|
{
|
|
# ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
// ESP8266 GPIO 16 doesn't have direct access
|
|
if (pin == 16) {
|
|
pinMode(pin, OUTPUT);
|
|
return;
|
|
}
|
|
GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO
|
|
GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED)
|
|
# endif // ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
DIRECT_MODE_OUTPUT(reg, PIN_TO_BITMASK(pin));
|
|
}
|
|
|
|
void DIRECT_PINMODE_INPUT(IO_REG_TYPE pin)
|
|
{
|
|
# ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
// ESP8266 GPIO 16 doesn't have direct access
|
|
if (pin == 16) {
|
|
pinMode(pin, INPUT);
|
|
return;
|
|
}
|
|
# endif // ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
DIRECT_MODE_INPUT(reg, PIN_TO_BITMASK(pin));
|
|
}
|
|
|
|
IO_REG_TYPE IRAM_ATTR DIRECT_pinRead_ISR(IO_REG_TYPE pin)
|
|
{
|
|
# ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
// ESP8266 GPIO 16 doesn't have direct access
|
|
if (pin == 16) { return digitalRead(pin); }
|
|
# endif // ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
return DIRECT_READ(reg, PIN_TO_BITMASK(pin));
|
|
}
|
|
|
|
void IRAM_ATTR DIRECT_pinWrite_ISR(IO_REG_TYPE pin, bool pinstate)
|
|
{
|
|
# ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
// ESP8266 GPIO 16 doesn't have direct access
|
|
if (pin == 16) {
|
|
digitalWrite(pin, pinstate);
|
|
return;
|
|
}
|
|
# endif // ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
if (pinstate) { DIRECT_WRITE_HIGH(reg, PIN_TO_BITMASK(pin)); }
|
|
else { DIRECT_WRITE_LOW(reg, PIN_TO_BITMASK(pin)); }
|
|
}
|
|
|
|
void IRAM_ATTR DIRECT_PINMODE_OUTPUT_ISR(IO_REG_TYPE pin)
|
|
{
|
|
# ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
// ESP8266 GPIO 16 doesn't have direct access
|
|
if (pin == 16) {
|
|
pinMode(pin, OUTPUT);
|
|
return;
|
|
}
|
|
GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO
|
|
GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED)
|
|
|
|
# endif // ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
DIRECT_MODE_OUTPUT(reg, PIN_TO_BITMASK(pin));
|
|
}
|
|
|
|
void IRAM_ATTR DIRECT_PINMODE_INPUT_ISR(IO_REG_TYPE pin)
|
|
{
|
|
# ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
// ESP8266 GPIO 16 doesn't have direct access
|
|
if (pin == 16) {
|
|
pinMode(pin, INPUT);
|
|
return;
|
|
}
|
|
# endif // ifdef ARDUINO_ARCH_ESP8266
|
|
|
|
DIRECT_MODE_INPUT(reg, PIN_TO_BITMASK(pin));
|
|
}
|
|
|
|
int32_t IRAM_ATTR DIRECT_measureWaitForPinState_ISR(
|
|
IO_REG_TYPE gpio_pin_rx,
|
|
uint32_t start_usec,
|
|
int32_t timeout_usec,
|
|
bool newState)
|
|
{
|
|
int32_t passed{};
|
|
|
|
do {
|
|
passed = (int32_t) ((uint32_t)micros() - start_usec);
|
|
} while (passed < timeout_usec &&
|
|
(!DIRECT_pinRead_ISR(gpio_pin_rx) == newState)); // Using '!' to do a quick cast to bool
|
|
|
|
if ((passed > timeout_usec) ||
|
|
(!DIRECT_pinRead_ISR(gpio_pin_rx) == newState)) {
|
|
return -1;
|
|
}
|
|
|
|
// N.B. we allow the situation where passed == timeout_usec
|
|
// and pin might have reached the state we're waiting for.
|
|
// This way we don't need to average for time before reading pin state and after.
|
|
return passed;
|
|
|
|
}
|
|
|
|
#endif // if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
|