#include "pin_manager.h" #include "wled.h" void PinManagerClass::deallocatePin(byte gpio) { if (!isPinOk(gpio, false)) return; byte by = gpio >> 3; byte bi = gpio - 8*by; bitWrite(pinAlloc[by], bi, false); } bool PinManagerClass::allocatePin(byte gpio, bool output) { if (!isPinOk(gpio, output)) return false; if (isPinAllocated(gpio)) { DEBUG_PRINT(F("Attempted duplicate allocation of pin ")); DEBUG_PRINTLN(gpio); return false; } byte by = gpio >> 3; byte bi = gpio - 8*by; bitWrite(pinAlloc[by], bi, true); return true; } bool PinManagerClass::isPinAllocated(byte gpio) { if (!isPinOk(gpio, false)) return true; byte by = gpio >> 3; byte bi = gpio - 8*by; return bitRead(pinAlloc[by], bi); } bool PinManagerClass::isPinOk(byte gpio, bool output) { if (gpio < 6) return true; if (gpio < 12) return false; //SPI flash pins #ifdef ESP8266 if (gpio < 17) return true; #else //ESP32 if (gpio < 34) return true; if (gpio < 40 && !output) return true; //34-39 input only #endif return false; } #ifdef ARDUINO_ARCH_ESP32 byte PinManagerClass::allocateLedc(byte channels) { if (channels > 16 || channels == 0) return 255; byte ca = 0; for (byte i = 0; i < 16; i++) { byte by = i >> 3; byte bi = i - 8*by; if (bitRead(ledcAlloc[by], bi)) { //found occupied pin ca = 0; } else { ca++; } if (ca >= channels) { //enough free channels byte in = (i + 1) - ca; for (byte j = 0; j < ca; j++) { byte b = in + j; byte by = b >> 3; byte bi = b - 8*by; bitWrite(ledcAlloc[by], bi, true); } return in; } } return 255; //not enough consecutive free LEDC channels } void PinManagerClass::deallocateLedc(byte pos, byte channels) { for (byte j = pos; j < pos + channels; j++) { if (j > 16) return; byte by = j >> 3; byte bi = j - 8*by; bitWrite(ledcAlloc[by], bi, false); } } #endif PinManagerClass pinManager = PinManagerClass();