Merge branch 'master' into dev
This commit is contained in:
commit
916ad0a58e
@ -8,12 +8,15 @@
|
|||||||
# Please uncomment one of the lines below to select your board(s)
|
# Please uncomment one of the lines below to select your board(s)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
# Travis CI binaries (comment this out with a ';' when building for your own board)
|
# Travis CI binaries (use `platformio_override.ini` when building for your own board; see `platformio_override.ini.sample` for an example)
|
||||||
;default_envs = travis_esp8266, travis_esp32
|
; default_envs = travis_esp8266, travis_esp32
|
||||||
|
|
||||||
# Release binaries
|
# Release binaries
|
||||||
default_envs = nodemcuv2, esp01_1m_full, esp32dev, esp32_eth
|
default_envs = nodemcuv2, esp01_1m_full, esp32dev, esp32_eth
|
||||||
|
|
||||||
|
# Build everything
|
||||||
|
; default_envs = esp32dev, esp8285_4CH_MagicHome, esp8285_4CH_H801, codm-controller-0.6-rev2, codm-controller-0.6, esp32s2_saola, d1_mini_5CH_Shojo_PCB, d1_mini, sp501e, travis_esp8266, travis_esp32, nodemcuv2, esp32_eth, anavi_miracle_controller, esp07, esp01_1m_full, m5atom, h803wf, d1_mini_ota, heltec_wifi_kit_8, esp8285_5CH_H801, d1_mini_debug, wemos_shield_esp32, elekstube_ips
|
||||||
|
|
||||||
# Single binaries (uncomment your board)
|
# Single binaries (uncomment your board)
|
||||||
; default_envs = elekstube_ips
|
; default_envs = elekstube_ips
|
||||||
; default_envs = nodemcuv2
|
; default_envs = nodemcuv2
|
||||||
@ -399,7 +402,7 @@ build_flags = ${common.build_flags_esp32}
|
|||||||
-D TEMPERATURE_PIN=23
|
-D TEMPERATURE_PIN=23
|
||||||
lib_deps = ${esp32.lib_deps}
|
lib_deps = ${esp32.lib_deps}
|
||||||
OneWire@~2.3.5
|
OneWire@~2.3.5
|
||||||
U8g2@~2.28.11
|
olikraus/U8g2 @ ^2.28.8
|
||||||
|
|
||||||
[env:m5atom]
|
[env:m5atom]
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
@ -482,4 +485,6 @@ build_flags = ${common.build_flags_esp32} -D WLED_DISABLE_BROWNOUT_DET -D WLED_D
|
|||||||
-D SPI_FREQUENCY=40000000
|
-D SPI_FREQUENCY=40000000
|
||||||
-D USER_SETUP_LOADED
|
-D USER_SETUP_LOADED
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
lib_deps = ${esp32.lib_deps} TFT_eSPI
|
lib_deps =
|
||||||
|
${esp32.lib_deps}
|
||||||
|
TFT_eSPI @ ^2.3.70
|
||||||
|
@ -306,22 +306,26 @@ class Animated_Staircase : public Usermod {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void setup() {
|
void setup() {
|
||||||
|
// standardize invalid pin numbers to -1
|
||||||
|
if (topPIRorTriggerPin < 0) topPIRorTriggerPin = -1;
|
||||||
|
if (topEchoPin < 0) topEchoPin = -1;
|
||||||
|
if (bottomPIRorTriggerPin < 0) bottomPIRorTriggerPin = -1;
|
||||||
|
if (bottomEchoPin < 0) bottomEchoPin = -1;
|
||||||
// allocate pins
|
// allocate pins
|
||||||
if (topPIRorTriggerPin >= 0) {
|
PinManagerPinType pins[4] = {
|
||||||
if (!pinManager.allocatePin(topPIRorTriggerPin,useUSSensorTop))
|
{ topPIRorTriggerPin, useUSSensorTop },
|
||||||
|
{ topEchoPin, false },
|
||||||
|
{ bottomPIRorTriggerPin, useUSSensorBottom },
|
||||||
|
{ bottomEchoPin, false },
|
||||||
|
};
|
||||||
|
// NOTE: this *WILL* return TRUE if all the pins are set to -1.
|
||||||
|
// this is *BY DESIGN*.
|
||||||
|
if (!pinManager.allocateMultiplePins(pins, 4, PinOwner::UM_AnimatedStaircase)) {
|
||||||
topPIRorTriggerPin = -1;
|
topPIRorTriggerPin = -1;
|
||||||
}
|
|
||||||
if (topEchoPin >= 0) {
|
|
||||||
if (!pinManager.allocatePin(topEchoPin,false))
|
|
||||||
topEchoPin = -1;
|
topEchoPin = -1;
|
||||||
}
|
|
||||||
if (bottomPIRorTriggerPin >= 0) {
|
|
||||||
if (!pinManager.allocatePin(bottomPIRorTriggerPin,useUSSensorBottom))
|
|
||||||
bottomPIRorTriggerPin = -1;
|
bottomPIRorTriggerPin = -1;
|
||||||
}
|
|
||||||
if (bottomEchoPin >= 0) {
|
|
||||||
if (!pinManager.allocatePin(bottomEchoPin,false))
|
|
||||||
bottomEchoPin = -1;
|
bottomEchoPin = -1;
|
||||||
|
enabled = false;
|
||||||
}
|
}
|
||||||
enable(enabled);
|
enable(enabled);
|
||||||
initDone = true;
|
initDone = true;
|
||||||
@ -484,10 +488,10 @@ class Animated_Staircase : public Usermod {
|
|||||||
(oldBottomAPin != bottomPIRorTriggerPin) ||
|
(oldBottomAPin != bottomPIRorTriggerPin) ||
|
||||||
(oldBottomBPin != bottomEchoPin)) {
|
(oldBottomBPin != bottomEchoPin)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
pinManager.deallocatePin(oldTopAPin);
|
pinManager.deallocatePin(oldTopAPin, PinOwner::UM_AnimatedStaircase);
|
||||||
pinManager.deallocatePin(oldTopBPin);
|
pinManager.deallocatePin(oldTopBPin, PinOwner::UM_AnimatedStaircase);
|
||||||
pinManager.deallocatePin(oldBottomAPin);
|
pinManager.deallocatePin(oldBottomAPin, PinOwner::UM_AnimatedStaircase);
|
||||||
pinManager.deallocatePin(oldBottomBPin);
|
pinManager.deallocatePin(oldBottomBPin, PinOwner::UM_AnimatedStaircase);
|
||||||
}
|
}
|
||||||
if (changed) setup();
|
if (changed) setup();
|
||||||
}
|
}
|
||||||
|
@ -58,12 +58,12 @@ public:
|
|||||||
void setMinutesTens() { setDigit(MINUTES_TENS); }
|
void setMinutesTens() { setDigit(MINUTES_TENS); }
|
||||||
void setHoursOnes() { setDigit(HOURS_ONES); }
|
void setHoursOnes() { setDigit(HOURS_ONES); }
|
||||||
void setHoursTens() { setDigit(HOURS_TENS); }
|
void setHoursTens() { setDigit(HOURS_TENS); }
|
||||||
bool isSecondsOnes() { return (digits_map&SECONDS_ONES_MAP > 0); }
|
bool isSecondsOnes() { return ((digits_map & SECONDS_ONES_MAP) > 0); }
|
||||||
bool isSecondsTens() { return (digits_map&SECONDS_TENS_MAP > 0); }
|
bool isSecondsTens() { return ((digits_map & SECONDS_TENS_MAP) > 0); }
|
||||||
bool isMinutesOnes() { return (digits_map&MINUTES_ONES_MAP > 0); }
|
bool isMinutesOnes() { return ((digits_map & MINUTES_ONES_MAP) > 0); }
|
||||||
bool isMinutesTens() { return (digits_map&MINUTES_TENS_MAP > 0); }
|
bool isMinutesTens() { return ((digits_map & MINUTES_TENS_MAP) > 0); }
|
||||||
bool isHoursOnes() { return (digits_map&HOURS_ONES_MAP > 0); }
|
bool isHoursOnes() { return ((digits_map & HOURS_ONES_MAP) > 0); }
|
||||||
bool isHoursTens() { return (digits_map&HOURS_TENS_MAP > 0); }
|
bool isHoursTens() { return ((digits_map & HOURS_TENS_MAP) > 0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,12 +201,14 @@ public:
|
|||||||
{
|
{
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
// pin retrieved from cfg.json (readFromConfig()) prior to running setup()
|
// pin retrieved from cfg.json (readFromConfig()) prior to running setup()
|
||||||
if (PIRsensorPin >= 0 && pinManager.allocatePin(PIRsensorPin,false)) {
|
if (PIRsensorPin >= 0 && pinManager.allocatePin(PIRsensorPin, false, PinOwner::UM_PIR)) {
|
||||||
// PIR Sensor mode INPUT_PULLUP
|
// PIR Sensor mode INPUT_PULLUP
|
||||||
pinMode(PIRsensorPin, INPUT_PULLUP);
|
pinMode(PIRsensorPin, INPUT_PULLUP);
|
||||||
sensorPinState = digitalRead(PIRsensorPin);
|
sensorPinState = digitalRead(PIRsensorPin);
|
||||||
} else {
|
} else {
|
||||||
if (PIRsensorPin >= 0) DEBUG_PRINTLN(F("PIRSensorSwitch pin allocation failed."));
|
if (PIRsensorPin >= 0) {
|
||||||
|
DEBUG_PRINTLN(F("PIRSensorSwitch pin allocation failed."));
|
||||||
|
}
|
||||||
PIRsensorPin = -1; // allocation failed
|
PIRsensorPin = -1; // allocation failed
|
||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
}
|
||||||
@ -367,8 +369,8 @@ public:
|
|||||||
if (oldPin != PIRsensorPin && oldPin >= 0) {
|
if (oldPin != PIRsensorPin && oldPin >= 0) {
|
||||||
// if we are changing pin in settings page
|
// if we are changing pin in settings page
|
||||||
// deallocate old pin
|
// deallocate old pin
|
||||||
pinManager.deallocatePin(oldPin);
|
pinManager.deallocatePin(oldPin, PinOwner::UM_PIR);
|
||||||
if (pinManager.allocatePin(PIRsensorPin,false)) {
|
if (pinManager.allocatePin(PIRsensorPin, false, PinOwner::UM_PIR)) {
|
||||||
pinMode(PIRsensorPin, INPUT_PULLUP);
|
pinMode(PIRsensorPin, INPUT_PULLUP);
|
||||||
} else {
|
} else {
|
||||||
// allocation failed
|
// allocation failed
|
||||||
|
@ -117,14 +117,19 @@ class UsermodTemperature : public Usermod {
|
|||||||
// config says we are enabled
|
// config says we are enabled
|
||||||
DEBUG_PRINTLN(F("Allocating temperature pin..."));
|
DEBUG_PRINTLN(F("Allocating temperature pin..."));
|
||||||
// pin retrieved from cfg.json (readFromConfig()) prior to running setup()
|
// pin retrieved from cfg.json (readFromConfig()) prior to running setup()
|
||||||
if (temperaturePin >= 0 && pinManager.allocatePin(temperaturePin)) {
|
if (temperaturePin >= 0 && pinManager.allocatePin(temperaturePin, true, PinOwner::UM_Temperature)) {
|
||||||
oneWire = new OneWire(temperaturePin);
|
oneWire = new OneWire(temperaturePin);
|
||||||
if (!oneWire->reset())
|
if (!oneWire->reset()) {
|
||||||
sensorFound = false; // resetting 1-Wire bus yielded an error
|
sensorFound = false; // resetting 1-Wire bus yielded an error
|
||||||
else
|
|
||||||
while ((sensorFound=findSensor()) && retries--) delay(25); // try to find sensor
|
|
||||||
} else {
|
} else {
|
||||||
if (temperaturePin >= 0) DEBUG_PRINTLN(F("Temperature pin allocation failed."));
|
while ((sensorFound=findSensor()) && retries--) {
|
||||||
|
delay(25); // try to find sensor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (temperaturePin >= 0) {
|
||||||
|
DEBUG_PRINTLN(F("Temperature pin allocation failed."));
|
||||||
|
}
|
||||||
temperaturePin = -1; // allocation failed
|
temperaturePin = -1; // allocation failed
|
||||||
sensorFound = false;
|
sensorFound = false;
|
||||||
}
|
}
|
||||||
@ -275,7 +280,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
DEBUG_PRINTLN(F("Re-init temperature."));
|
DEBUG_PRINTLN(F("Re-init temperature."));
|
||||||
// deallocate pin and release memory
|
// deallocate pin and release memory
|
||||||
delete oneWire;
|
delete oneWire;
|
||||||
pinManager.deallocatePin(temperaturePin);
|
pinManager.deallocatePin(temperaturePin, PinOwner::UM_Temperature);
|
||||||
temperaturePin = newTemperaturePin;
|
temperaturePin = newTemperaturePin;
|
||||||
// initialise
|
// initialise
|
||||||
setup();
|
setup();
|
||||||
|
@ -258,7 +258,7 @@ class MultiRelay : public Usermod {
|
|||||||
// pins retrieved from cfg.json (readFromConfig()) prior to running setup()
|
// pins retrieved from cfg.json (readFromConfig()) prior to running setup()
|
||||||
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
||||||
if (_relay[i].pin<0) continue;
|
if (_relay[i].pin<0) continue;
|
||||||
if (!pinManager.allocatePin(_relay[i].pin,true)) {
|
if (!pinManager.allocatePin(_relay[i].pin,true, PinOwner::UM_MultiRelay)) {
|
||||||
_relay[i].pin = -1; // allocation failed
|
_relay[i].pin = -1; // allocation failed
|
||||||
} else {
|
} else {
|
||||||
switchRelay(i, _relay[i].state = (bool)bri);
|
switchRelay(i, _relay[i].state = (bool)bri);
|
||||||
@ -381,12 +381,14 @@ class MultiRelay : public Usermod {
|
|||||||
// deallocate all pins 1st
|
// deallocate all pins 1st
|
||||||
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++)
|
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++)
|
||||||
if (oldPin[i]>=0) {
|
if (oldPin[i]>=0) {
|
||||||
pinManager.deallocatePin(oldPin[i]);
|
pinManager.deallocatePin(oldPin[i], PinOwner::UM_MultiRelay);
|
||||||
}
|
}
|
||||||
// allocate new pins
|
// allocate new pins
|
||||||
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
||||||
if (_relay[i].pin>=0 && pinManager.allocatePin(_relay[i].pin,true)) {
|
if (_relay[i].pin>=0 && pinManager.allocatePin(_relay[i].pin, true, PinOwner::UM_MultiRelay)) {
|
||||||
if (!_relay[i].external) switchRelay(i, _relay[i].state = (bool)bri);
|
if (!_relay[i].external) {
|
||||||
|
switchRelay(i, _relay[i].state = (bool)bri);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_relay[i].pin = -1;
|
_relay[i].pin = -1;
|
||||||
}
|
}
|
||||||
|
@ -39,13 +39,10 @@ class RgbRotaryEncoderUsermod : public Usermod
|
|||||||
|
|
||||||
void initRotaryEncoder()
|
void initRotaryEncoder()
|
||||||
{
|
{
|
||||||
if (!pinManager.allocatePin(eaIo, false)) {
|
PinManagerPinType pins[2] = { { eaIo, false }, { ebIo, false } };
|
||||||
|
if (!pinManager.allocateMultiplePins(pins, 2, UM_RGBRotaryEncoder)) {
|
||||||
eaIo = -1;
|
eaIo = -1;
|
||||||
}
|
|
||||||
if (!pinManager.allocatePin(ebIo, false)) {
|
|
||||||
ebIo = -1;
|
ebIo = -1;
|
||||||
}
|
|
||||||
if (eaIo == -1 || ebIo == -1) {
|
|
||||||
cleanup();
|
cleanup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -111,10 +108,12 @@ class RgbRotaryEncoderUsermod : public Usermod
|
|||||||
{
|
{
|
||||||
// Only deallocate pins if we allocated them ;)
|
// Only deallocate pins if we allocated them ;)
|
||||||
if (eaIo != -1) {
|
if (eaIo != -1) {
|
||||||
pinManager.deallocatePin(eaIo);
|
pinManager.deallocatePin(eaIo, PinOwner::UM_RGBRotaryEncoder);
|
||||||
|
eaIo = -1;
|
||||||
}
|
}
|
||||||
if (ebIo != -1) {
|
if (ebIo != -1) {
|
||||||
pinManager.deallocatePin(ebIo);
|
pinManager.deallocatePin(ebIo, PinOwner::UM_RGBRotaryEncoder);
|
||||||
|
ebIo = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete rotaryEncoder;
|
delete rotaryEncoder;
|
||||||
@ -304,8 +303,8 @@ class RgbRotaryEncoderUsermod : public Usermod
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (eaIo != oldEaIo || ebIo != oldEbIo || stepsPerClick != oldStepsPerClick || incrementPerClick != oldIncrementPerClick) {
|
if (eaIo != oldEaIo || ebIo != oldEbIo || stepsPerClick != oldStepsPerClick || incrementPerClick != oldIncrementPerClick) {
|
||||||
pinManager.deallocatePin(oldEaIo);
|
pinManager.deallocatePin(oldEaIo, PinOwner::UM_RGBRotaryEncoder);
|
||||||
pinManager.deallocatePin(oldEbIo);
|
pinManager.deallocatePin(oldEbIo, PinOwner::UM_RGBRotaryEncoder);
|
||||||
|
|
||||||
delete rotaryEncoder;
|
delete rotaryEncoder;
|
||||||
initRotaryEncoder();
|
initRotaryEncoder();
|
||||||
|
@ -168,14 +168,12 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
// network here
|
// network here
|
||||||
void setup() {
|
void setup() {
|
||||||
if (type == NONE) return;
|
if (type == NONE) return;
|
||||||
bool allocated = false;
|
|
||||||
byte i;
|
|
||||||
if (type == SSD1306_SPI || type == SSD1306_SPI64) {
|
if (type == SSD1306_SPI || type == SSD1306_SPI64) {
|
||||||
for (i=0; i<5; i++) if (!pinManager.allocatePin(ioPin[i])) { allocated=true; break; }
|
PinManagerPinType pins[5] = { { ioPin[0], true }, { ioPin[1], true}, { ioPin[2], true }, { ioPin[3], true}, { ioPin[4], true }};
|
||||||
if (i<5 && allocated) { for (byte i=0; i<5; i++) pinManager.deallocatePin(ioPin[i]); type=NONE; return; }
|
if (!pinManager.allocateMultiplePins(pins, 5, PinOwner::UM_FourLineDisplay)) { type=NONE; return; }
|
||||||
} else {
|
} else {
|
||||||
for (i=0; i<2; i++) if (!pinManager.allocatePin(ioPin[i])) { allocated=true; break; }
|
PinManagerPinType pins[2] = { { ioPin[0], true }, { ioPin[1], true} };
|
||||||
if (i<2 && allocated) { for (byte i=0; i<5; i++) pinManager.deallocatePin(ioPin[i]); type=NONE; return; }
|
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::UM_FourLineDisplay)) { type=NONE; return; }
|
||||||
}
|
}
|
||||||
DEBUG_PRINTLN(F("Allocating display."));
|
DEBUG_PRINTLN(F("Allocating display."));
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -240,18 +238,17 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
u8x8 = nullptr;
|
u8x8 = nullptr;
|
||||||
type = NONE;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
initDone = true;
|
if (nullptr == u8x8) {
|
||||||
if (u8x8 != nullptr) {
|
|
||||||
DEBUG_PRINTLN(F("Starting display."));
|
|
||||||
(static_cast<U8X8*>(u8x8))->begin();
|
|
||||||
} else {
|
|
||||||
DEBUG_PRINTLN(F("Display init failed."));
|
DEBUG_PRINTLN(F("Display init failed."));
|
||||||
|
for (byte i=0; i<5 && ioPin[i]>=0; i++) pinManager.deallocatePin(ioPin[i], PinOwner::UM_FourLineDisplay);
|
||||||
type = NONE;
|
type = NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initDone = true;
|
||||||
|
DEBUG_PRINTLN(F("Starting display."));
|
||||||
|
u8x8->begin();
|
||||||
setFlipMode(flip);
|
setFlipMode(flip);
|
||||||
setContrast(contrast); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255
|
setContrast(contrast); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255
|
||||||
setPowerSave(0);
|
setPowerSave(0);
|
||||||
@ -277,40 +274,40 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
*/
|
*/
|
||||||
void setFlipMode(uint8_t mode) {
|
void setFlipMode(uint8_t mode) {
|
||||||
if (type==NONE) return;
|
if (type==NONE) return;
|
||||||
(static_cast<U8X8*>(u8x8))->setFlipMode(mode);
|
u8x8->setFlipMode(mode);
|
||||||
}
|
}
|
||||||
void setContrast(uint8_t contrast) {
|
void setContrast(uint8_t contrast) {
|
||||||
if (type==NONE) return;
|
if (type==NONE) return;
|
||||||
(static_cast<U8X8*>(u8x8))->setContrast(contrast);
|
u8x8->setContrast(contrast);
|
||||||
}
|
}
|
||||||
void drawString(uint8_t col, uint8_t row, const char *string, bool ignoreLH=false) {
|
void drawString(uint8_t col, uint8_t row, const char *string, bool ignoreLH=false) {
|
||||||
if (type==NONE) return;
|
if (type==NONE) return;
|
||||||
(static_cast<U8X8*>(u8x8))->setFont(u8x8_font_chroma48medium8_r);
|
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
||||||
if (!ignoreLH && lineHeight==2) (static_cast<U8X8*>(u8x8))->draw1x2String(col, row, string);
|
if (!ignoreLH && lineHeight==2) u8x8->draw1x2String(col, row, string);
|
||||||
else (static_cast<U8X8*>(u8x8))->drawString(col, row, string);
|
else u8x8->drawString(col, row, string);
|
||||||
}
|
}
|
||||||
void draw2x2String(uint8_t col, uint8_t row, const char *string) {
|
void draw2x2String(uint8_t col, uint8_t row, const char *string) {
|
||||||
if (type==NONE) return;
|
if (type==NONE) return;
|
||||||
(static_cast<U8X8*>(u8x8))->setFont(u8x8_font_chroma48medium8_r);
|
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
||||||
(static_cast<U8X8*>(u8x8))->draw2x2String(col, row, string);
|
u8x8->draw2x2String(col, row, string);
|
||||||
}
|
}
|
||||||
void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font, bool ignoreLH=false) {
|
void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font, bool ignoreLH=false) {
|
||||||
if (type==NONE) return;
|
if (type==NONE) return;
|
||||||
(static_cast<U8X8*>(u8x8))->setFont(font);
|
u8x8->setFont(font);
|
||||||
if (!ignoreLH && lineHeight==2) (static_cast<U8X8*>(u8x8))->draw1x2Glyph(col, row, glyph);
|
if (!ignoreLH && lineHeight==2) u8x8->draw1x2Glyph(col, row, glyph);
|
||||||
else (static_cast<U8X8*>(u8x8))->drawGlyph(col, row, glyph);
|
else u8x8->drawGlyph(col, row, glyph);
|
||||||
}
|
}
|
||||||
uint8_t getCols() {
|
uint8_t getCols() {
|
||||||
if (type==NONE) return 0;
|
if (type==NONE) return 0;
|
||||||
return (static_cast<U8X8*>(u8x8))->getCols();
|
return u8x8->getCols();
|
||||||
}
|
}
|
||||||
void clear() {
|
void clear() {
|
||||||
if (type==NONE) return;
|
if (type==NONE) return;
|
||||||
(static_cast<U8X8*>(u8x8))->clear();
|
u8x8->clear();
|
||||||
}
|
}
|
||||||
void setPowerSave(uint8_t save) {
|
void setPowerSave(uint8_t save) {
|
||||||
if (type==NONE) return;
|
if (type==NONE) return;
|
||||||
(static_cast<U8X8*>(u8x8))->setPowerSave(save);
|
u8x8->setPowerSave(save);
|
||||||
}
|
}
|
||||||
|
|
||||||
void center(String &line, uint8_t width) {
|
void center(String &line, uint8_t width) {
|
||||||
@ -725,9 +722,9 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
bool pinsChanged = false;
|
bool pinsChanged = false;
|
||||||
for (byte i=0; i<5; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; }
|
for (byte i=0; i<5; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; }
|
||||||
if (pinsChanged || type!=newType) {
|
if (pinsChanged || type!=newType) {
|
||||||
if (type != NONE) delete (static_cast<U8X8*>(u8x8));
|
if (type != NONE) delete u8x8;
|
||||||
for (byte i=0; i<5; i++) {
|
for (byte i=0; i<5; i++) {
|
||||||
if (ioPin[i]>=0) pinManager.deallocatePin(ioPin[i]);
|
if (ioPin[i]>=0) pinManager.deallocatePin(ioPin[i], PinOwner::UM_FourLineDisplay);
|
||||||
ioPin[i] = newPin[i];
|
ioPin[i] = newPin[i];
|
||||||
}
|
}
|
||||||
if (ioPin[0]<0 || ioPin[1]<0) { // data & clock must be > -1
|
if (ioPin[0]<0 || ioPin[1]<0) { // data & clock must be > -1
|
||||||
|
@ -76,7 +76,7 @@ private:
|
|||||||
unsigned char Enc_B;
|
unsigned char Enc_B;
|
||||||
unsigned char Enc_A_prev = 0;
|
unsigned char Enc_A_prev = 0;
|
||||||
|
|
||||||
bool currentEffectAndPaleeteInitialized = false;
|
bool currentEffectAndPaletteInitialized = false;
|
||||||
uint8_t effectCurrentIndex = 0;
|
uint8_t effectCurrentIndex = 0;
|
||||||
uint8_t effectPaletteIndex = 0;
|
uint8_t effectPaletteIndex = 0;
|
||||||
|
|
||||||
@ -97,9 +97,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
if (!pinManager.allocatePin(pinA)) { enabled = false; return;}
|
PinManagerPinType pins[3] = { { pinA, false }, { pinB, false }, { pinC, false } };
|
||||||
if (!pinManager.allocatePin(pinB)) { pinManager.deallocatePin(pinA); enabled = false; return; }
|
if (!pinManager.allocateMultiplePins(pins, 3, PinOwner::UM_RotaryEncoderUI)) {
|
||||||
if (!pinManager.allocatePin(pinC)) { pinManager.deallocatePin(pinA); pinManager.deallocatePin(pinB); enabled = false; return; }
|
// BUG: configuring this usermod with conflicting pins
|
||||||
|
// will cause it to de-allocate pins it does not own
|
||||||
|
// (at second config)
|
||||||
|
// This is the exact type of bug solved by pinManager
|
||||||
|
// tracking the owner tags....
|
||||||
|
pinA = pinB = pinC = -1;
|
||||||
|
enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pinMode(pinA, INPUT_PULLUP);
|
pinMode(pinA, INPUT_PULLUP);
|
||||||
pinMode(pinB, INPUT_PULLUP);
|
pinMode(pinB, INPUT_PULLUP);
|
||||||
@ -152,7 +160,7 @@ public:
|
|||||||
// Initialize effectCurrentIndex and effectPaletteIndex to
|
// Initialize effectCurrentIndex and effectPaletteIndex to
|
||||||
// current state. We do it here as (at least) effectCurrent
|
// current state. We do it here as (at least) effectCurrent
|
||||||
// is not yet initialized when setup is called.
|
// is not yet initialized when setup is called.
|
||||||
if (!currentEffectAndPaleeteInitialized) {
|
if (!currentEffectAndPaletteInitialized) {
|
||||||
findCurrentEffectAndPalette();
|
findCurrentEffectAndPalette();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +256,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void findCurrentEffectAndPalette() {
|
void findCurrentEffectAndPalette() {
|
||||||
currentEffectAndPaleeteInitialized = true;
|
currentEffectAndPaletteInitialized = true;
|
||||||
for (uint8_t i = 0; i < strip.getModeCount(); i++) {
|
for (uint8_t i = 0; i < strip.getModeCount(); i++) {
|
||||||
//byte value = modes_alpha_indexes[i];
|
//byte value = modes_alpha_indexes[i];
|
||||||
if (modes_alpha_indexes[i] == effectCurrent) {
|
if (modes_alpha_indexes[i] == effectCurrent) {
|
||||||
@ -455,9 +463,9 @@ public:
|
|||||||
DEBUG_PRINTLN(F(" config (re)loaded."));
|
DEBUG_PRINTLN(F(" config (re)loaded."));
|
||||||
// changing parameters from settings page
|
// changing parameters from settings page
|
||||||
if (pinA!=newDTpin || pinB!=newCLKpin || pinC!=newSWpin) {
|
if (pinA!=newDTpin || pinB!=newCLKpin || pinC!=newSWpin) {
|
||||||
pinManager.deallocatePin(pinA);
|
pinManager.deallocatePin(pinA, PinOwner::UM_RotaryEncoderUI);
|
||||||
pinManager.deallocatePin(pinB);
|
pinManager.deallocatePin(pinB, PinOwner::UM_RotaryEncoderUI);
|
||||||
pinManager.deallocatePin(pinC);
|
pinManager.deallocatePin(pinC, PinOwner::UM_RotaryEncoderUI);
|
||||||
pinA = newDTpin;
|
pinA = newDTpin;
|
||||||
pinB = newCLKpin;
|
pinB = newCLKpin;
|
||||||
pinC = newSWpin;
|
pinC = newSWpin;
|
||||||
|
@ -916,7 +916,9 @@ const char JSON_palette_names[] PROGMEM = R"=====([
|
|||||||
"Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64",
|
"Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64",
|
||||||
"Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn",
|
"Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn",
|
||||||
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura",
|
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura",
|
||||||
"Aurora","Atlantica","C9 2","C9 New","Temperature","Aurora 2"
|
"Aurora","Atlantica","C9 2","C9 New","Temperature","Aurora 2","Retro Clown","Candy","Toxy Reaf","Fairy Reaf",
|
||||||
|
"Semi Blue","Pink Candy","Red Reaf","Aqua Flash","Yelblu Hot","Lite Light","Red Flash","Blink Red","Red Shift","Red Tide",
|
||||||
|
"Candy2"
|
||||||
])=====";
|
])=====";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -125,10 +125,10 @@ class BusDigital : public Bus {
|
|||||||
public:
|
public:
|
||||||
BusDigital(BusConfig &bc, uint8_t nr) : Bus(bc.type, bc.start) {
|
BusDigital(BusConfig &bc, uint8_t nr) : Bus(bc.type, bc.start) {
|
||||||
if (!IS_DIGITAL(bc.type) || !bc.count) return;
|
if (!IS_DIGITAL(bc.type) || !bc.count) return;
|
||||||
if (!pinManager.allocatePin(bc.pins[0])) return;
|
if (!pinManager.allocatePin(bc.pins[0], true, PinOwner::BusDigital)) return;
|
||||||
_pins[0] = bc.pins[0];
|
_pins[0] = bc.pins[0];
|
||||||
if (IS_2PIN(bc.type)) {
|
if (IS_2PIN(bc.type)) {
|
||||||
if (!pinManager.allocatePin(bc.pins[1])) {
|
if (!pinManager.allocatePin(bc.pins[1], true, PinOwner::BusDigital)) {
|
||||||
cleanup(); return;
|
cleanup(); return;
|
||||||
}
|
}
|
||||||
_pins[1] = bc.pins[1];
|
_pins[1] = bc.pins[1];
|
||||||
@ -208,11 +208,11 @@ class BusDigital : public Bus {
|
|||||||
|
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
PolyBus::cleanup(_busPtr, _iType);
|
PolyBus::cleanup(_busPtr, _iType);
|
||||||
pinManager.deallocatePin(_pins[0]);
|
|
||||||
pinManager.deallocatePin(_pins[1]);
|
|
||||||
_iType = I_NONE;
|
_iType = I_NONE;
|
||||||
_valid = false;
|
_valid = false;
|
||||||
_busPtr = nullptr;
|
_busPtr = nullptr;
|
||||||
|
pinManager.deallocatePin(_pins[1], PinOwner::BusDigital);
|
||||||
|
pinManager.deallocatePin(_pins[0], PinOwner::BusDigital);
|
||||||
}
|
}
|
||||||
|
|
||||||
~BusDigital() {
|
~BusDigital() {
|
||||||
@ -249,7 +249,7 @@ class BusPwm : public Bus {
|
|||||||
|
|
||||||
for (uint8_t i = 0; i < numPins; i++) {
|
for (uint8_t i = 0; i < numPins; i++) {
|
||||||
uint8_t currentPin = bc.pins[i];
|
uint8_t currentPin = bc.pins[i];
|
||||||
if (!pinManager.allocatePin(currentPin)) {
|
if (!pinManager.allocatePin(currentPin, true, PinOwner::BusPwm)) {
|
||||||
deallocatePins(); return;
|
deallocatePins(); return;
|
||||||
}
|
}
|
||||||
_pins[i] = currentPin; // store only after allocatePin() succeeds
|
_pins[i] = currentPin; // store only after allocatePin() succeeds
|
||||||
@ -339,7 +339,7 @@ class BusPwm : public Bus {
|
|||||||
void deallocatePins() {
|
void deallocatePins() {
|
||||||
uint8_t numPins = NUM_PWM_PINS(_type);
|
uint8_t numPins = NUM_PWM_PINS(_type);
|
||||||
for (uint8_t i = 0; i < numPins; i++) {
|
for (uint8_t i = 0; i < numPins; i++) {
|
||||||
pinManager.deallocatePin(_pins[i]);
|
pinManager.deallocatePin(_pins[i], PinOwner::BusPwm);
|
||||||
if (!pinManager.isPinOk(_pins[i])) continue;
|
if (!pinManager.isPinOk(_pins[i])) continue;
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
digitalWrite(_pins[i], LOW); //turn off PWM interrupt
|
digitalWrite(_pins[i], LOW); //turn off PWM interrupt
|
||||||
|
@ -19,6 +19,13 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
|
|
||||||
//long vid = doc[F("vid")]; // 2010020
|
//long vid = doc[F("vid")]; // 2010020
|
||||||
|
|
||||||
|
#ifdef WLED_USE_ETHERNET
|
||||||
|
JsonObject ethernet = doc[F("eth")];
|
||||||
|
CJSON(ethernetType, ethernet["type"]);
|
||||||
|
// NOTE: Ethernet configuration takes priority over other use of pins
|
||||||
|
WLED::instance().initEthernet();
|
||||||
|
#endif
|
||||||
|
|
||||||
JsonObject id = doc["id"];
|
JsonObject id = doc["id"];
|
||||||
getStringFromJson(cmDNS, id[F("mdns")], 33);
|
getStringFromJson(cmDNS, id[F("mdns")], 33);
|
||||||
getStringFromJson(serverDescription, id[F("name")], 33);
|
getStringFromJson(serverDescription, id[F("name")], 33);
|
||||||
@ -93,7 +100,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
|
|
||||||
JsonObject hw = doc[F("hw")];
|
JsonObject hw = doc[F("hw")];
|
||||||
|
|
||||||
// initialize LED pins and lengths prior to other HW
|
// initialize LED pins and lengths prior to other HW (except for ethernet)
|
||||||
JsonObject hw_led = hw[F("led")];
|
JsonObject hw_led = hw[F("led")];
|
||||||
|
|
||||||
CJSON(ledCount, hw_led[F("total")]);
|
CJSON(ledCount, hw_led[F("total")]);
|
||||||
@ -162,7 +169,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
for (JsonObject btn : hw_btn_ins) {
|
for (JsonObject btn : hw_btn_ins) {
|
||||||
CJSON(buttonType[s], btn["type"]);
|
CJSON(buttonType[s], btn["type"]);
|
||||||
int8_t pin = btn["pin"][0] | -1;
|
int8_t pin = btn["pin"][0] | -1;
|
||||||
if (pin > -1 && pinManager.allocatePin(pin,false)) {
|
if (pin > -1 && pinManager.allocatePin(pin, false, PinOwner::Button)) {
|
||||||
btnPin[s] = pin;
|
btnPin[s] = pin;
|
||||||
pinMode(btnPin[s], INPUT_PULLUP);
|
pinMode(btnPin[s], INPUT_PULLUP);
|
||||||
} else {
|
} else {
|
||||||
@ -186,8 +193,10 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
// new install/missing configuration (button 0 has defaults)
|
// new install/missing configuration (button 0 has defaults)
|
||||||
if (fromFS) {
|
if (fromFS) {
|
||||||
// relies upon only being called once with fromFS == true, which is currently true.
|
// relies upon only being called once with fromFS == true, which is currently true.
|
||||||
uint8_t s=0;
|
uint8_t s = 0;
|
||||||
if (pinManager.allocatePin(btnPin[0],false)) s++; // do not clear button 0 if pin successfully allocated
|
if (pinManager.allocatePin(btnPin[0], false, PinOwner::Button)) { // initialized to #define value BTNPIN, or zero if not defined(!)
|
||||||
|
++s; // do not clear default button if allocated successfully
|
||||||
|
}
|
||||||
for (; s<WLED_MAX_BUTTONS; s++) {
|
for (; s<WLED_MAX_BUTTONS; s++) {
|
||||||
btnPin[s] = -1;
|
btnPin[s] = -1;
|
||||||
buttonType[s] = BTN_TYPE_NONE;
|
buttonType[s] = BTN_TYPE_NONE;
|
||||||
@ -202,7 +211,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
|
|
||||||
int hw_ir_pin = hw["ir"]["pin"] | -2; // 4
|
int hw_ir_pin = hw["ir"]["pin"] | -2; // 4
|
||||||
if (hw_ir_pin > -2) {
|
if (hw_ir_pin > -2) {
|
||||||
if (pinManager.allocatePin(hw_ir_pin,false)) {
|
if (pinManager.allocatePin(hw_ir_pin, false, PinOwner::IR)) {
|
||||||
irPin = hw_ir_pin;
|
irPin = hw_ir_pin;
|
||||||
} else {
|
} else {
|
||||||
irPin = -1;
|
irPin = -1;
|
||||||
@ -213,7 +222,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
JsonObject relay = hw[F("relay")];
|
JsonObject relay = hw[F("relay")];
|
||||||
int hw_relay_pin = relay["pin"] | -2;
|
int hw_relay_pin = relay["pin"] | -2;
|
||||||
if (hw_relay_pin > -2) {
|
if (hw_relay_pin > -2) {
|
||||||
if (pinManager.allocatePin(hw_relay_pin,true)) {
|
if (pinManager.allocatePin(hw_relay_pin,true, PinOwner::Relay)) {
|
||||||
rlyPin = hw_relay_pin;
|
rlyPin = hw_relay_pin;
|
||||||
pinMode(rlyPin, OUTPUT);
|
pinMode(rlyPin, OUTPUT);
|
||||||
} else {
|
} else {
|
||||||
@ -469,6 +478,8 @@ void deserializeConfigFromFS() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: This routine deserializes *and* applies the configuration
|
||||||
|
// Therefore, must also initialize ethernet from this function
|
||||||
deserializeConfig(doc.as<JsonObject>(), true);
|
deserializeConfig(doc.as<JsonObject>(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@
|
|||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#define LEDPIN 2 // GPIO2 (D4) on Wemod D1 mini compatible boards
|
#define LEDPIN 2 // GPIO2 (D4) on Wemod D1 mini compatible boards
|
||||||
#else
|
#else
|
||||||
#define LEDPIN 16 // alligns with GPIO2 (D4) on Wemos D1 mini32 compatible boards
|
#define LEDPIN 16 // aligns with GPIO2 (D4) on Wemos D1 mini32 compatible boards
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -359,7 +359,7 @@ void _drawOverlayCronixie()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else // WLED_DISABLE_CRONIXIE
|
#else // WLED_DISABLE_CRONIXIE
|
||||||
byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) {return 0;}
|
byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) { return 0; }
|
||||||
void setCronixie() {}
|
void setCronixie() {}
|
||||||
void _overlayCronixie() {}
|
void _overlayCronixie() {}
|
||||||
void _drawOverlayCronixie() {}
|
void _drawOverlayCronixie() {}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#ifndef PalettesWLED_h
|
#ifndef PalettesWLED_h
|
||||||
#define PalettesWLED_h
|
#define PalettesWLED_h
|
||||||
|
|
||||||
#define GRADIENT_PALETTE_COUNT 43
|
#define GRADIENT_PALETTE_COUNT 58
|
||||||
|
|
||||||
const byte ib_jul01_gp[] PROGMEM = {
|
const byte ib_jul01_gp[] PROGMEM = {
|
||||||
0, 194, 1, 1,
|
0, 194, 1, 1,
|
||||||
@ -631,7 +631,7 @@ const byte temperature_gp[] PROGMEM = {
|
|||||||
240, 80, 3, 3,
|
240, 80, 3, 3,
|
||||||
255, 80, 3, 3};
|
255, 80, 3, 3};
|
||||||
|
|
||||||
const byte Aurora2[] PROGMEM = {
|
const byte Aurora2_gp[] PROGMEM = {
|
||||||
0, 17, 177, 13, //Greenish
|
0, 17, 177, 13, //Greenish
|
||||||
64, 121, 242, 5, //Greenish
|
64, 121, 242, 5, //Greenish
|
||||||
128, 25, 173, 121, //Turquoise
|
128, 25, 173, 121, //Turquoise
|
||||||
@ -639,6 +639,213 @@ const byte temperature_gp[] PROGMEM = {
|
|||||||
255, 171, 101, 221 //Purple
|
255, 171, 101, 221 //Purple
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Gradient palette "bhw1_01_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw1/tn/bhw1_01.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 12 bytes of program space.
|
||||||
|
|
||||||
|
const byte retro_clown_gp[] PROGMEM = {
|
||||||
|
0, 227,101, 3,
|
||||||
|
117, 194, 18, 19,
|
||||||
|
255, 92, 8,192};
|
||||||
|
|
||||||
|
// Gradient palette "bhw1_04_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw1/tn/bhw1_04.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 20 bytes of program space.
|
||||||
|
|
||||||
|
const byte candy_gp[] PROGMEM = {
|
||||||
|
0, 229,227, 1,
|
||||||
|
15, 227,101, 3,
|
||||||
|
142, 40, 1, 80,
|
||||||
|
198, 17, 1, 79,
|
||||||
|
255, 0, 0, 45};
|
||||||
|
|
||||||
|
// Gradient palette "bhw1_05_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw1/tn/bhw1_05.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 8 bytes of program space.
|
||||||
|
|
||||||
|
const byte toxy_reaf_gp[] PROGMEM = {
|
||||||
|
0, 1,221, 53,
|
||||||
|
255, 73, 3,178};
|
||||||
|
|
||||||
|
// Gradient palette "bhw1_06_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw1/tn/bhw1_06.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 16 bytes of program space.
|
||||||
|
|
||||||
|
const byte fairy_reaf_gp[] PROGMEM = {
|
||||||
|
0, 184, 1,128,
|
||||||
|
160, 1,193,182,
|
||||||
|
219, 153,227,190,
|
||||||
|
255, 255,255,255};
|
||||||
|
|
||||||
|
// Gradient palette "bhw1_14_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw1/tn/bhw1_14.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 36 bytes of program space.
|
||||||
|
|
||||||
|
const byte semi_blue_gp[] PROGMEM = {
|
||||||
|
0, 0, 0, 0,
|
||||||
|
12, 1, 1, 3,
|
||||||
|
53, 8, 1, 22,
|
||||||
|
80, 4, 6, 89,
|
||||||
|
119, 2, 25,216,
|
||||||
|
145, 7, 10, 99,
|
||||||
|
186, 15, 2, 31,
|
||||||
|
233, 2, 1, 5,
|
||||||
|
255, 0, 0, 0};
|
||||||
|
|
||||||
|
// Gradient palette "bhw1_three_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw1/tn/bhw1_three.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 32 bytes of program space.
|
||||||
|
|
||||||
|
const byte pink_candy_gp[] PROGMEM = {
|
||||||
|
0, 255,255,255,
|
||||||
|
45, 7, 12,255,
|
||||||
|
112, 227, 1,127,
|
||||||
|
112, 227, 1,127,
|
||||||
|
140, 255,255,255,
|
||||||
|
155, 227, 1,127,
|
||||||
|
196, 45, 1, 99,
|
||||||
|
255, 255,255,255};
|
||||||
|
|
||||||
|
// Gradient palette "bhw1_w00t_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw1/tn/bhw1_w00t.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 16 bytes of program space.
|
||||||
|
|
||||||
|
const byte red_reaf_gp[] PROGMEM = {
|
||||||
|
0, 3, 13, 43,
|
||||||
|
104, 78,141,240,
|
||||||
|
188, 255, 0, 0,
|
||||||
|
255, 28, 1, 1};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "bhw2_23_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw2/tn/bhw2_23.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Red & Flash in SR
|
||||||
|
// Size: 28 bytes of program space.
|
||||||
|
|
||||||
|
const byte aqua_flash_gp[] PROGMEM = {
|
||||||
|
0, 0, 0, 0,
|
||||||
|
66, 57,227,233,
|
||||||
|
96, 255,255, 8,
|
||||||
|
124, 255,255,255,
|
||||||
|
153, 255,255, 8,
|
||||||
|
188, 57,227,233,
|
||||||
|
255, 0, 0, 0};
|
||||||
|
|
||||||
|
// Gradient palette "bhw2_xc_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw2/tn/bhw2_xc.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// YBlue in SR
|
||||||
|
// Size: 28 bytes of program space.
|
||||||
|
|
||||||
|
const byte yelblu_hot_gp[] PROGMEM = {
|
||||||
|
0, 4, 2, 9,
|
||||||
|
58, 16, 0, 47,
|
||||||
|
122, 24, 0, 16,
|
||||||
|
158, 144, 9, 1,
|
||||||
|
183, 179, 45, 1,
|
||||||
|
219, 220,114, 2,
|
||||||
|
255, 234,237, 1};
|
||||||
|
|
||||||
|
// Gradient palette "bhw2_45_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw2/tn/bhw2_45.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 24 bytes of program space.
|
||||||
|
|
||||||
|
const byte lite_light_gp[] PROGMEM = {
|
||||||
|
0, 0, 0, 0,
|
||||||
|
9, 1, 1, 1,
|
||||||
|
40, 5, 5, 6,
|
||||||
|
66, 5, 5, 6,
|
||||||
|
101, 10, 1, 12,
|
||||||
|
255, 0, 0, 0};
|
||||||
|
|
||||||
|
// Gradient palette "bhw2_22_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw2/tn/bhw2_22.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Pink Plasma in SR
|
||||||
|
// Size: 20 bytes of program space.
|
||||||
|
|
||||||
|
const byte red_flash_gp[] PROGMEM = {
|
||||||
|
0, 0, 0, 0,
|
||||||
|
99, 227, 1, 1,
|
||||||
|
130, 249,199, 95,
|
||||||
|
155, 227, 1, 1,
|
||||||
|
255, 0, 0, 0};
|
||||||
|
|
||||||
|
// Gradient palette "bhw3_40_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw3/tn/bhw3_40.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 32 bytes of program space.
|
||||||
|
|
||||||
|
const byte blink_red_gp[] PROGMEM = {
|
||||||
|
0, 1, 1, 1,
|
||||||
|
43, 4, 1, 11,
|
||||||
|
76, 10, 1, 3,
|
||||||
|
109, 161, 4, 29,
|
||||||
|
127, 255, 86,123,
|
||||||
|
165, 125, 16,160,
|
||||||
|
204, 35, 13,223,
|
||||||
|
255, 18, 2, 18};
|
||||||
|
|
||||||
|
// Gradient palette "bhw3_52_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw3/tn/bhw3_52.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Yellow2Blue in SR
|
||||||
|
// Size: 28 bytes of program space.
|
||||||
|
|
||||||
|
const byte red_shift_gp[] PROGMEM = {
|
||||||
|
0, 31, 1, 27,
|
||||||
|
45, 34, 1, 16,
|
||||||
|
99, 137, 5, 9,
|
||||||
|
132, 213,128, 10,
|
||||||
|
175, 199, 22, 1,
|
||||||
|
201, 199, 9, 6,
|
||||||
|
255, 1, 0, 1};
|
||||||
|
|
||||||
|
// Gradient palette "bhw4_097_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw4/tn/bhw4_097.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Yellow2Red in SR
|
||||||
|
// Size: 44 bytes of program space.
|
||||||
|
|
||||||
|
const byte red_tide_gp[] PROGMEM = {
|
||||||
|
0, 247, 5, 0,
|
||||||
|
28, 255, 67, 1,
|
||||||
|
43, 234, 88, 11,
|
||||||
|
58, 234,176, 51,
|
||||||
|
84, 229, 28, 1,
|
||||||
|
114, 113, 12, 1,
|
||||||
|
140, 255,225, 44,
|
||||||
|
168, 113, 12, 1,
|
||||||
|
196, 244,209, 88,
|
||||||
|
216, 255, 28, 1,
|
||||||
|
255, 53, 1, 1};
|
||||||
|
|
||||||
|
// Gradient palette "bhw4_017_gp", originally from
|
||||||
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw4/tn/bhw4_017.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 40 bytes of program space.
|
||||||
|
|
||||||
|
const byte candy2_gp[] PROGMEM = {
|
||||||
|
0, 39, 33, 34,
|
||||||
|
25, 4, 6, 15,
|
||||||
|
48, 49, 29, 22,
|
||||||
|
73, 224,173, 1,
|
||||||
|
89, 177, 35, 5,
|
||||||
|
130, 4, 6, 15,
|
||||||
|
163, 255,114, 6,
|
||||||
|
186, 224,173, 1,
|
||||||
|
211, 39, 33, 34,
|
||||||
|
255, 1, 1, 1};
|
||||||
|
|
||||||
// Single array of defined cpt-city color palettes.
|
// Single array of defined cpt-city color palettes.
|
||||||
// This will let us programmatically choose one based on
|
// This will let us programmatically choose one based on
|
||||||
// a number, rather than having to activate each explicitly
|
// a number, rather than having to activate each explicitly
|
||||||
@ -686,7 +893,22 @@ const byte* const gGradientPalettes[] PROGMEM = {
|
|||||||
C9_2_gp, //52-39 C9 2
|
C9_2_gp, //52-39 C9 2
|
||||||
C9_new_gp, //53-40 C9 New
|
C9_new_gp, //53-40 C9 New
|
||||||
temperature_gp, //54-41 Temperature
|
temperature_gp, //54-41 Temperature
|
||||||
Aurora2 //55-42 Aurora 2
|
Aurora2_gp, //55-42 Aurora 2
|
||||||
|
retro_clown_gp, //56-43 Retro Clown
|
||||||
|
candy_gp, //57-44 Candy
|
||||||
|
toxy_reaf_gp, //58-45 Toxy Reaf
|
||||||
|
fairy_reaf_gp, //59-46 Fairy Reaf
|
||||||
|
semi_blue_gp, //60-47 Semi Blue
|
||||||
|
pink_candy_gp, //61-48 Pink Candy
|
||||||
|
red_reaf_gp, //62-49 Red Reaf
|
||||||
|
aqua_flash_gp, //63-50 Aqua Flash
|
||||||
|
yelblu_hot_gp, //64-51 Yelblu Hot
|
||||||
|
lite_light_gp, //65-52 Lite Light
|
||||||
|
red_flash_gp, //66-53 Red Flash
|
||||||
|
blink_red_gp, //67-54 Blink Red
|
||||||
|
red_shift_gp, //68-55 Red Shift
|
||||||
|
red_tide_gp, //69-56 Red Tide
|
||||||
|
candy2_gp //70-57 Candy2
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,35 +1,110 @@
|
|||||||
#include "pin_manager.h"
|
#include "pin_manager.h"
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
|
||||||
void PinManagerClass::deallocatePin(byte gpio)
|
static void DebugPrintOwnerTag(PinOwner tag)
|
||||||
{
|
{
|
||||||
if (!isPinOk(gpio, false)) return;
|
uint32_t q = static_cast<uint8_t>(tag);
|
||||||
|
if (q) {
|
||||||
|
DEBUG_PRINTF("0x%02x (%d)", q, q);
|
||||||
|
} else {
|
||||||
|
DEBUG_PRINT(F("(no owner)"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Actual allocation/deallocation routines
|
||||||
|
bool PinManagerClass::deallocatePin(byte gpio, PinOwner tag)
|
||||||
|
{
|
||||||
|
if (gpio == 0xFF) return true; // explicitly allow clients to free -1 as a no-op
|
||||||
|
if (!isPinOk(gpio, false)) return false; // but return false for any other invalid pin
|
||||||
|
|
||||||
|
// if a non-zero ownerTag, only allow de-allocation if the owner's tag is provided
|
||||||
|
if ((ownerTag[gpio] != PinOwner::None) && (ownerTag[gpio] != tag)) {
|
||||||
|
DEBUG_PRINT(F("PIN DEALLOC: IO "));
|
||||||
|
DEBUG_PRINT(gpio);
|
||||||
|
DEBUG_PRINT(F(" allocated by "));
|
||||||
|
DebugPrintOwnerTag(ownerTag[gpio]);
|
||||||
|
DEBUG_PRINT(F(", but attempted de-allocation by "));
|
||||||
|
DebugPrintOwnerTag(tag);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
byte by = gpio >> 3;
|
byte by = gpio >> 3;
|
||||||
byte bi = gpio - 8*by;
|
byte bi = gpio - 8*by;
|
||||||
bitWrite(pinAlloc[by], bi, false);
|
bitWrite(pinAlloc[by], bi, false);
|
||||||
|
ownerTag[gpio] = PinOwner::None;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, byte arrayElementCount, PinOwner tag)
|
||||||
|
{
|
||||||
|
bool shouldFail = false;
|
||||||
|
// first verify the pins are OK and not already allocated
|
||||||
|
for (int i = 0; i < arrayElementCount; i++) {
|
||||||
|
byte gpio = mptArray[i].pin;
|
||||||
|
if (gpio == 0xFF) {
|
||||||
|
// explicit support for io -1 as a no-op (no allocation of pin),
|
||||||
|
// as this can greatly simplify configuration arrays
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isPinOk(gpio, mptArray[i].isOutput)) {
|
||||||
|
DEBUG_PRINT(F("PIN ALLOC: Invalid pin attempted to be allocated: "));
|
||||||
|
DEBUG_PRINT(gpio);
|
||||||
|
DEBUG_PRINTLN(F(""));
|
||||||
|
shouldFail = true;
|
||||||
|
}
|
||||||
|
if (isPinAllocated(gpio)) {
|
||||||
|
DEBUG_PRINT(F("PIN ALLOC: FAIL: IO "));
|
||||||
|
DEBUG_PRINT(gpio);
|
||||||
|
DEBUG_PRINT(F(" already allocated by "));
|
||||||
|
DebugPrintOwnerTag(ownerTag[gpio]);
|
||||||
|
DEBUG_PRINTLN(F(""));
|
||||||
|
shouldFail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shouldFail) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool PinManagerClass::allocatePin(byte gpio, bool output)
|
// all pins are available .. track each one
|
||||||
|
for (int i = 0; i < arrayElementCount; i++) {
|
||||||
|
byte gpio = mptArray[i].pin;
|
||||||
|
if (gpio == 0xFF) {
|
||||||
|
// allow callers to include -1 value as non-requested pin
|
||||||
|
// as this can greatly simplify configuration arrays
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
byte by = gpio >> 3;
|
||||||
|
byte bi = gpio - 8*by;
|
||||||
|
bitWrite(pinAlloc[by], bi, true);
|
||||||
|
ownerTag[gpio] = tag;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool PinManagerClass::allocatePin(byte gpio, bool output, PinOwner tag)
|
||||||
{
|
{
|
||||||
if (!isPinOk(gpio, output)) return false;
|
if (!isPinOk(gpio, output)) return false;
|
||||||
if (isPinAllocated(gpio)) {
|
if (isPinAllocated(gpio)) {
|
||||||
DEBUG_PRINT(F("Attempted duplicate allocation of pin "));
|
DEBUG_PRINT(F("PIN ALLOC: Pin "));
|
||||||
DEBUG_PRINTLN(gpio);
|
DEBUG_PRINT(gpio);
|
||||||
|
DEBUG_PRINT(F(" already allocated by "));
|
||||||
|
DebugPrintOwnerTag(ownerTag[gpio]);
|
||||||
|
DEBUG_PRINTLN(F(""));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte by = gpio >> 3;
|
byte by = gpio >> 3;
|
||||||
byte bi = gpio - 8*by;
|
byte bi = gpio - 8*by;
|
||||||
bitWrite(pinAlloc[by], bi, true);
|
bitWrite(pinAlloc[by], bi, true);
|
||||||
|
ownerTag[gpio] = tag;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PinManagerClass::isPinAllocated(byte gpio)
|
// if tag is set to PinOwner::None, checks for ANY owner of the pin.
|
||||||
|
// if tag is set to any other value, checks if that tag is the current owner of the pin.
|
||||||
|
bool PinManagerClass::isPinAllocated(byte gpio, PinOwner tag)
|
||||||
{
|
{
|
||||||
if (!isPinOk(gpio, false)) return true;
|
if (!isPinOk(gpio, false)) return true;
|
||||||
|
if ((tag != PinOwner::None) && (ownerTag[gpio] != tag)) return false;
|
||||||
byte by = gpio >> 3;
|
byte by = gpio >> 3;
|
||||||
byte bi = gpio - 8*by;
|
byte bi = gpio - 8*by;
|
||||||
return bitRead(pinAlloc[by], bi);
|
return bitRead(pinAlloc[by], bi);
|
||||||
|
@ -4,21 +4,92 @@
|
|||||||
* Registers pins so there is no attempt for two interfaces to use the same pin
|
* Registers pins so there is no attempt for two interfaces to use the same pin
|
||||||
*/
|
*/
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include "const.h" // for USERMOD_* values
|
||||||
|
|
||||||
|
typedef struct PinManagerPinType {
|
||||||
|
int8_t pin;
|
||||||
|
uint8_t isOutput;
|
||||||
|
} managed_pin_type;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allows PinManager to "lock" an allocation to a specific
|
||||||
|
* owner, so someone else doesn't accidentally de-allocate
|
||||||
|
* a pin it hasn't allocated. Also enhances debugging.
|
||||||
|
*
|
||||||
|
* RAM Cost:
|
||||||
|
* 17 bytes on ESP8266
|
||||||
|
* 40 bytes on ESP32
|
||||||
|
*/
|
||||||
|
enum struct PinOwner : uint8_t {
|
||||||
|
None = 0, // default == legacy == unspecified owner
|
||||||
|
// High bit is set for all built-in pin owners
|
||||||
|
Ethernet = 0x81,
|
||||||
|
BusDigital = 0x82,
|
||||||
|
BusDigital2 = 0x83,
|
||||||
|
BusPwm = 0x84, // 'BusP' == PWM output using BusPwm
|
||||||
|
Button = 0x85, // 'Butn' == button from configuration
|
||||||
|
IR = 0x86, // 'IR' == IR receiver pin from configuration
|
||||||
|
Relay = 0x87, // 'Rly' == Relay pin from configuration
|
||||||
|
SPI_RAM = 0x88, // 'SpiR' == SPI RAM
|
||||||
|
DebugOut = 0x89, // 'Dbg' == debug output always IO1
|
||||||
|
DMX = 0x8A, // 'DMX' == hard-coded to IO2
|
||||||
|
// Use UserMod IDs from const.h here
|
||||||
|
UM_Unspecified = USERMOD_ID_UNSPECIFIED, // 0x01
|
||||||
|
UM_RGBRotaryEncoder = USERMOD_ID_UNSPECIFIED, // 0x01 // No define in const.h for this user module -- consider adding?
|
||||||
|
UM_Example = USERMOD_ID_EXAMPLE, // 0x02 // Usermod "usermod_v2_example.h"
|
||||||
|
UM_Temperature = USERMOD_ID_TEMPERATURE, // 0x03 // Usermod "usermod_temperature.h"
|
||||||
|
// #define USERMOD_ID_FIXNETSERVICES // 0x04 // Usermod "usermod_Fix_unreachable_netservices.h" -- Does not allocate pins
|
||||||
|
UM_PIR = USERMOD_ID_PIRSWITCH, // 0x05 // Usermod "usermod_PIR_sensor_switch.h"
|
||||||
|
// #define USERMOD_ID_IMU // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Uses "standard" I2C pins ... TODO -- enable shared I2C bus use
|
||||||
|
UM_FourLineDisplay = USERMOD_ID_FOUR_LINE_DISP, // 0x07 // Usermod "usermod_v2_four_line_display.h
|
||||||
|
UM_RotaryEncoderUI = USERMOD_ID_ROTARY_ENC_UI, // 0x08 // Usermod "usermod_v2_rotary_encoder_ui.h"
|
||||||
|
// #define USERMOD_ID_AUTO_SAVE // 0x09 // Usermod "usermod_v2_auto_save.h" -- Does not allocate pins
|
||||||
|
// #define USERMOD_ID_DHT // 0x0A // Usermod "usermod_dht.h" -- Statically allocates pins, not compatible with pinManager?
|
||||||
|
// #define USERMOD_ID_MODE_SORT // 0x0B // Usermod "usermod_v2_mode_sort.h" -- Does not allocate pins
|
||||||
|
// #define USERMOD_ID_VL53L0X // 0x0C // Usermod "usermod_vl53l0x_gestures.h" -- Uses "standard" I2C pins ... TODO -- enable shared I2C bus use
|
||||||
|
UM_MultiRelay = USERMOD_ID_MULTI_RELAY, // 0x0D // Usermod "usermod_multi_relay.h"
|
||||||
|
UM_AnimatedStaircase = USERMOD_ID_ANIMATED_STAIRCASE, // 0x0E // Usermod "Animated_Staircase.h"
|
||||||
|
// #define USERMOD_ID_RTC // 0x0F // Usermod "usermod_rtc.h" -- Uses "standard" I2C pins ... TODO -- enable shared I2C bus use
|
||||||
|
// #define USERMOD_ID_ELEKSTUBE_IPS // 0x10 // Usermod "usermod_elekstube_ips.h" -- Uses quite a few pins ... see Hardware.h and User_Setup.h
|
||||||
|
// #define USERMOD_ID_SN_PHOTORESISTOR // 0x11 // Usermod "usermod_sn_photoresistor.h" -- Uses hard-coded pin (PHOTORESISTOR_PIN == A0), but could be easily updated to use pinManager
|
||||||
|
};
|
||||||
|
static_assert(0u == static_cast<uint8_t>(PinOwner::None), "PinOwner::None must be zero, so default array initialization works as expected");
|
||||||
|
|
||||||
class PinManagerClass {
|
class PinManagerClass {
|
||||||
private:
|
private:
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
uint8_t pinAlloc[3] = {0x00, 0x00, 0x00}; //24bit, 1 bit per pin, we use first 17bits
|
uint8_t pinAlloc[3] = {0x00, 0x00, 0x00}; //24bit, 1 bit per pin, we use first 17bits
|
||||||
|
PinOwner ownerTag[17] = { PinOwner::None };
|
||||||
#else
|
#else
|
||||||
uint8_t pinAlloc[5] = {0x00, 0x00, 0x00, 0x00, 0x00}; //40bit, 1 bit per pin, we use all bits
|
uint8_t pinAlloc[5] = {0x00, 0x00, 0x00, 0x00, 0x00}; //40bit, 1 bit per pin, we use all bits
|
||||||
uint8_t ledcAlloc[2] = {0x00, 0x00}; //16 LEDC channels
|
uint8_t ledcAlloc[2] = {0x00, 0x00}; //16 LEDC channels
|
||||||
|
PinOwner ownerTag[40] = { PinOwner::None };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void deallocatePin(byte gpio);
|
// De-allocates a single pin
|
||||||
bool allocatePin(byte gpio, bool output = true);
|
bool deallocatePin(byte gpio, PinOwner tag);
|
||||||
bool isPinAllocated(byte gpio);
|
// Allocates a single pin, with an owner tag.
|
||||||
|
// De-allocation requires the same owner tag (or override)
|
||||||
|
bool allocatePin(byte gpio, bool output, PinOwner tag);
|
||||||
|
// Allocates all the pins, or allocates none of the pins, with owner tag.
|
||||||
|
// Provided to simplify error condition handling in clients
|
||||||
|
// using more than one pin, such as I2C, SPI, rotary encoders,
|
||||||
|
// ethernet, etc..
|
||||||
|
bool allocateMultiplePins(const managed_pin_type * mptArray, byte arrayElementCount, PinOwner tag );
|
||||||
|
|
||||||
|
#if !defined(ESP8266) // ESP8266 compiler doesn't understand deprecated attribute
|
||||||
|
[[deprecated("Replaced by three-parameter allocatePin(gpio, output, ownerTag), for improved debugging")]]
|
||||||
|
#endif
|
||||||
|
inline bool allocatePin(byte gpio, bool output = true) { return allocatePin(gpio, output, PinOwner::None); }
|
||||||
|
#if !defined(ESP8266) // ESP8266 compiler doesn't understand deprecated attribute
|
||||||
|
[[deprecated("Replaced by three-parameter deallocatePin(gpio, output, ownerTag), for improved debugging")]]
|
||||||
|
#endif
|
||||||
|
inline void deallocatePin(byte gpio) { deallocatePin(gpio, PinOwner::None); }
|
||||||
|
|
||||||
|
bool isPinAllocated(byte gpio, PinOwner tag = PinOwner::None);
|
||||||
bool isPinOk(byte gpio, bool output = true);
|
bool isPinOk(byte gpio, bool output = true);
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
byte allocateLedc(byte channels);
|
byte allocateLedc(byte channels);
|
||||||
void deallocateLedc(byte pos, byte channels);
|
void deallocateLedc(byte pos, byte channels);
|
||||||
|
@ -54,6 +54,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
|
|
||||||
#ifdef WLED_USE_ETHERNET
|
#ifdef WLED_USE_ETHERNET
|
||||||
ethernetType = request->arg(F("ETH")).toInt();
|
ethernetType = request->arg(F("ETH")).toInt();
|
||||||
|
WLED::instance().initEthernet();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char k[3]; k[2] = 0;
|
char k[3]; k[2] = 0;
|
||||||
@ -77,11 +78,17 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
{
|
{
|
||||||
int t = 0;
|
int t = 0;
|
||||||
|
|
||||||
if (rlyPin>=0 && pinManager.isPinAllocated(rlyPin)) pinManager.deallocatePin(rlyPin);
|
if (rlyPin>=0 && pinManager.isPinAllocated(rlyPin, PinOwner::Relay)) {
|
||||||
if (irPin>=0 && pinManager.isPinAllocated(irPin)) pinManager.deallocatePin(irPin);
|
pinManager.deallocatePin(rlyPin, PinOwner::Relay);
|
||||||
for (uint8_t s=0; s<WLED_MAX_BUTTONS; s++)
|
}
|
||||||
if (btnPin[s]>=0 && pinManager.isPinAllocated(btnPin[s]))
|
if (irPin>=0 && pinManager.isPinAllocated(irPin, PinOwner::IR)) {
|
||||||
pinManager.deallocatePin(btnPin[s]);
|
pinManager.deallocatePin(irPin, PinOwner::IR);
|
||||||
|
}
|
||||||
|
for (uint8_t s=0; s<WLED_MAX_BUTTONS; s++) {
|
||||||
|
if (btnPin[s]>=0 && pinManager.isPinAllocated(btnPin[s], PinOwner::Button)) {
|
||||||
|
pinManager.deallocatePin(btnPin[s], PinOwner::Button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t colorOrder, type, skip;
|
uint8_t colorOrder, type, skip;
|
||||||
uint16_t length, start;
|
uint16_t length, start;
|
||||||
@ -126,7 +133,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
|
|
||||||
// upate other pins
|
// upate other pins
|
||||||
int hw_ir_pin = request->arg(F("IR")).toInt();
|
int hw_ir_pin = request->arg(F("IR")).toInt();
|
||||||
if (pinManager.allocatePin(hw_ir_pin,false)) {
|
if (pinManager.allocatePin(hw_ir_pin,false, PinOwner::IR)) {
|
||||||
irPin = hw_ir_pin;
|
irPin = hw_ir_pin;
|
||||||
} else {
|
} else {
|
||||||
irPin = -1;
|
irPin = -1;
|
||||||
@ -134,7 +141,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
irEnabled = request->arg(F("IT")).toInt();
|
irEnabled = request->arg(F("IT")).toInt();
|
||||||
|
|
||||||
int hw_rly_pin = request->arg(F("RL")).toInt();
|
int hw_rly_pin = request->arg(F("RL")).toInt();
|
||||||
if (pinManager.allocatePin(hw_rly_pin,true)) {
|
if (pinManager.allocatePin(hw_rly_pin,true, PinOwner::Relay)) {
|
||||||
rlyPin = hw_rly_pin;
|
rlyPin = hw_rly_pin;
|
||||||
} else {
|
} else {
|
||||||
rlyPin = -1;
|
rlyPin = -1;
|
||||||
@ -145,7 +152,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
char bt[4] = "BT"; bt[2] = 48+i; bt[3] = 0; // button pin
|
char bt[4] = "BT"; bt[2] = 48+i; bt[3] = 0; // button pin
|
||||||
char be[4] = "BE"; be[2] = 48+i; be[3] = 0; // button type
|
char be[4] = "BE"; be[2] = 48+i; be[3] = 0; // button type
|
||||||
int hw_btn_pin = request->arg(bt).toInt();
|
int hw_btn_pin = request->arg(bt).toInt();
|
||||||
if (pinManager.allocatePin(hw_btn_pin,false)) {
|
if (pinManager.allocatePin(hw_btn_pin,false,PinOwner::Button)) {
|
||||||
btnPin[i] = hw_btn_pin;
|
btnPin[i] = hw_btn_pin;
|
||||||
pinMode(btnPin[i], INPUT_PULLUP);
|
pinMode(btnPin[i], INPUT_PULLUP);
|
||||||
buttonType[i] = request->arg(be).toInt();
|
buttonType[i] = request->arg(be).toInt();
|
||||||
|
145
wled00/wled.cpp
145
wled00/wled.cpp
@ -177,6 +177,11 @@ void WiFiEvent(WiFiEvent_t event)
|
|||||||
break;
|
break;
|
||||||
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
||||||
DEBUG_PRINT(F("ETH Disconnected"));
|
DEBUG_PRINT(F("ETH Disconnected"));
|
||||||
|
// This doesn't really affect ethernet per se,
|
||||||
|
// as it's only configured once. Rather, it
|
||||||
|
// may be necessary to reconnect the WiFi when
|
||||||
|
// ethernet disconnects, as a way to provide
|
||||||
|
// alternative access to the device.
|
||||||
forceReconnect = true;
|
forceReconnect = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@ -352,8 +357,9 @@ void WLED::setup()
|
|||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
||||||
if (psramFound()) {
|
if (psramFound()) {
|
||||||
pinManager.allocatePin(16); // GPIO16 reserved for SPI RAM
|
// GPIO16/GPIO17 reserved for SPI RAM
|
||||||
pinManager.allocatePin(17); // GPIO17 reserved for SPI RAM
|
managed_pin_type pins[2] = { {16, true}, {17, true} };
|
||||||
|
pinManager.allocateMultiplePins(pins, 2, PinOwner::SPI_RAM);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -361,10 +367,10 @@ void WLED::setup()
|
|||||||
//DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap());
|
//DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap());
|
||||||
|
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
pinManager.allocatePin(1,true); // GPIO1 reserved for debug output
|
pinManager.allocatePin(1, true, PinOwner::DebugOut); // GPIO1 reserved for debug output
|
||||||
#endif
|
#endif
|
||||||
#ifdef WLED_USE_DMX //reserve GPIO2 as hardcoded DMX pin
|
#ifdef WLED_USE_DMX //reserve GPIO2 as hardcoded DMX pin
|
||||||
pinManager.allocatePin(2);
|
pinManager.allocatePin(2, true, PinOwner::DMX);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (uint8_t i=1; i<WLED_MAX_BUTTONS; i++) btnPin[i] = -1;
|
for (uint8_t i=1; i<WLED_MAX_BUTTONS; i++) btnPin[i] = -1;
|
||||||
@ -509,80 +515,105 @@ void WLED::initAP(bool resetAP)
|
|||||||
apActive = true;
|
apActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WLED::initConnection()
|
bool WLED::initEthernet()
|
||||||
{
|
{
|
||||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
|
||||||
ws.onEvent(wsEvent);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
|
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
|
||||||
// Only initialize ethernet board if not NONE
|
|
||||||
if (ethernetType != WLED_ETH_NONE && ethernetType < WLED_NUM_ETH_TYPES) {
|
static bool successfullyConfiguredEthernet = false;
|
||||||
|
|
||||||
|
if (successfullyConfiguredEthernet) {
|
||||||
|
// DEBUG_PRINTLN(F("initE: ETH already successfully configured, ignoring"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ethernetType == WLED_ETH_NONE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ethernetType >= WLED_NUM_ETH_TYPES) {
|
||||||
|
DEBUG_PRINT(F("initE: Ignoring attempt for invalid ethernetType ")); DEBUG_PRINTLN(ethernetType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_PRINT(F("initE: Attempting ETH config: ")); DEBUG_PRINTLN(ethernetType);
|
||||||
|
|
||||||
|
// Ethernet initialization should only succeed once -- else reboot required
|
||||||
ethernet_settings es = ethernetBoards[ethernetType];
|
ethernet_settings es = ethernetBoards[ethernetType];
|
||||||
// Use PinManager to ensure pins are available for
|
managed_pin_type pinsToAllocate[10] = {
|
||||||
// ethernet AND to prevent other uses of these pins.
|
// first six pins are non-configurable
|
||||||
bool s = true;
|
esp32_nonconfigurable_ethernet_pins[0],
|
||||||
byte pinsAllocated[4] { 255, 255, 255, 255 };
|
esp32_nonconfigurable_ethernet_pins[1],
|
||||||
|
esp32_nonconfigurable_ethernet_pins[2],
|
||||||
if (s && (s = pinManager.allocatePin((byte)es.eth_power))) {
|
esp32_nonconfigurable_ethernet_pins[3],
|
||||||
pinsAllocated[0] = (byte)es.eth_power;
|
esp32_nonconfigurable_ethernet_pins[4],
|
||||||
}
|
esp32_nonconfigurable_ethernet_pins[5],
|
||||||
if (s && (s = pinManager.allocatePin((byte)es.eth_mdc))) {
|
{ (int8_t)es.eth_mdc, true }, // [6] = MDC is output and mandatory
|
||||||
pinsAllocated[1] = (byte)es.eth_mdc;
|
{ (int8_t)es.eth_mdio, true }, // [7] = MDIO is bidirectional and mandatory
|
||||||
}
|
{ (int8_t)es.eth_power, true }, // [8] = optional pin, not all boards use
|
||||||
if (s && (s = pinManager.allocatePin((byte)es.eth_mdio))) {
|
{ ((int8_t)0xFE), false }, // [9] = replaced with eth_clk_mode, mandatory
|
||||||
pinsAllocated[2] = (byte)es.eth_mdio;
|
};
|
||||||
}
|
// update the clock pin....
|
||||||
switch(es.eth_clk_mode) {
|
if (es.eth_clk_mode == ETH_CLOCK_GPIO0_IN) {
|
||||||
case ETH_CLOCK_GPIO0_IN:
|
pinsToAllocate[9].pin = 0;
|
||||||
s = pinManager.allocatePin(0, false);
|
pinsToAllocate[9].isOutput = false;
|
||||||
pinsAllocated[3] = 0;
|
} else if (es.eth_clk_mode == ETH_CLOCK_GPIO0_OUT) {
|
||||||
break;
|
pinsToAllocate[9].pin = 0;
|
||||||
case ETH_CLOCK_GPIO0_OUT:
|
pinsToAllocate[9].isOutput = true;
|
||||||
s = pinManager.allocatePin(0);
|
} else if (es.eth_clk_mode == ETH_CLOCK_GPIO16_OUT) {
|
||||||
pinsAllocated[3] = 0;
|
pinsToAllocate[9].pin = 16;
|
||||||
break;
|
pinsToAllocate[9].isOutput = true;
|
||||||
case ETH_CLOCK_GPIO16_OUT:
|
} else if (es.eth_clk_mode == ETH_CLOCK_GPIO17_OUT) {
|
||||||
s = pinManager.allocatePin(16);
|
pinsToAllocate[9].pin = 17;
|
||||||
pinsAllocated[3] = 16;
|
pinsToAllocate[9].isOutput = true;
|
||||||
break;
|
} else {
|
||||||
case ETH_CLOCK_GPIO17_OUT:
|
DEBUG_PRINT(F("initE: Failing due to invalid eth_clk_mode ("));
|
||||||
s = pinManager.allocatePin(17);
|
DEBUG_PRINT(es.eth_clk_mode);
|
||||||
pinsAllocated[3] = 17;
|
DEBUG_PRINTLN(F(")"));
|
||||||
break;
|
return false;
|
||||||
default:
|
|
||||||
s = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s) {
|
if (!pinManager.allocateMultiplePins(pinsToAllocate, 10, PinOwner::Ethernet)) {
|
||||||
s = ETH.begin(
|
DEBUG_PRINTLN(F("initE: Failed to allocate ethernet pins"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ETH.begin(
|
||||||
(uint8_t) es.eth_address,
|
(uint8_t) es.eth_address,
|
||||||
(int) es.eth_power,
|
(int) es.eth_power,
|
||||||
(int) es.eth_mdc,
|
(int) es.eth_mdc,
|
||||||
(int) es.eth_mdio,
|
(int) es.eth_mdio,
|
||||||
(eth_phy_type_t) es.eth_type,
|
(eth_phy_type_t) es.eth_type,
|
||||||
(eth_clock_mode_t) es.eth_clk_mode
|
(eth_clock_mode_t) es.eth_clk_mode
|
||||||
);
|
)) {
|
||||||
|
DEBUG_PRINTLN(F("initC: ETH.begin() failed"));
|
||||||
|
// de-allocate the allocated pins
|
||||||
|
for (managed_pin_type mpt : pinsToAllocate) {
|
||||||
|
pinManager.deallocatePin(mpt.pin, PinOwner::Ethernet);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s) {
|
successfullyConfiguredEthernet = true;
|
||||||
DEBUG_PRINTLN(F("Ethernet init failed"));
|
DEBUG_PRINTLN(F("initC: *** Ethernet successfully configured! ***"));
|
||||||
// de-allocate only those pins allocated before the failure
|
return true;
|
||||||
for (byte p : pinsAllocated) {
|
#else
|
||||||
pinManager.deallocatePin(p);
|
return false; // Ethernet not enabled for build
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WLED::initConnection()
|
||||||
|
{
|
||||||
|
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||||
|
ws.onEvent(wsEvent);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
WiFi.disconnect(true); // close old connections
|
WiFi.disconnect(true); // close old connections
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
WiFi.setPhyMode(WIFI_PHY_MODE_11N);
|
WiFi.setPhyMode(WIFI_PHY_MODE_11N);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (staticIP[0] != 0 && staticGateway[0] != 0) {
|
if (staticIP[0] != 0 && staticGateway[0] != 0) {
|
||||||
WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8, 8, 8, 8));
|
WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(1, 1, 1, 1));
|
||||||
} else {
|
} else {
|
||||||
WiFi.config(0U, 0U, 0U);
|
WiFi.config(0U, 0U, 0U);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2108251
|
#define VERSION 2108261
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
@ -599,13 +599,6 @@ WLED_GLOBAL bool doInitBusses _INIT(false);
|
|||||||
// Usermod manager
|
// Usermod manager
|
||||||
WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager());
|
WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager());
|
||||||
|
|
||||||
// Status LED
|
|
||||||
#if STATUSLED
|
|
||||||
WLED_GLOBAL unsigned long ledStatusLastMillis _INIT(0);
|
|
||||||
WLED_GLOBAL unsigned short ledStatusType _INIT(0); // current status type - corresponds to number of blinks per second
|
|
||||||
WLED_GLOBAL bool ledStatusState _INIT(0); // the current LED state
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// enable additional debug output
|
// enable additional debug output
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
#ifndef ESP8266
|
#ifndef ESP8266
|
||||||
@ -668,6 +661,7 @@ public:
|
|||||||
|
|
||||||
void beginStrip();
|
void beginStrip();
|
||||||
void handleConnection();
|
void handleConnection();
|
||||||
|
bool initEthernet(); // result is informational
|
||||||
void initAP(bool resetAP = false);
|
void initAP(bool resetAP = false);
|
||||||
void initConnection();
|
void initConnection();
|
||||||
void initInterfaces();
|
void initInterfaces();
|
||||||
|
@ -2,7 +2,32 @@
|
|||||||
#define WLED_ETHERNET_H
|
#define WLED_ETHERNET_H
|
||||||
|
|
||||||
#ifdef WLED_USE_ETHERNET
|
#ifdef WLED_USE_ETHERNET
|
||||||
// settings for various ethernet boards
|
#include "pin_manager.h"
|
||||||
|
|
||||||
|
// The following six pins are neither configurable nor
|
||||||
|
// can they be re-assigned through IOMUX / GPIO matrix.
|
||||||
|
// See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-ethernet-kit-v1.1.html#ip101gri-phy-interface
|
||||||
|
const managed_pin_type esp32_nonconfigurable_ethernet_pins[6] = {
|
||||||
|
{ 21, true }, // RMII EMAC TX EN == When high, clocks the data on TXD0 and TXD1 to transmitter
|
||||||
|
{ 19, true }, // RMII EMAC TXD0 == First bit of transmitted data
|
||||||
|
{ 22, true }, // RMII EMAC TXD1 == Second bit of transmitted data
|
||||||
|
{ 25, false }, // RMII EMAC RXD0 == First bit of received data
|
||||||
|
{ 26, false }, // RMII EMAC RXD1 == Second bit of received data
|
||||||
|
{ 27, true }, // RMII EMAC CRS_DV == Carrier Sense and RX Data Valid
|
||||||
|
};
|
||||||
|
|
||||||
|
// For ESP32, the remaining five pins are at least somewhat configurable.
|
||||||
|
// eth_address is in range [0..31], indicates which PHY (MAC?) address should be allocated to the interface
|
||||||
|
// eth_power is an output GPIO pin used to enable/disable the ethernet port (and/or external oscillator)
|
||||||
|
// eth_mdc is an output GPIO pin used to provide the clock for the management data
|
||||||
|
// eth_mdio is an input/output GPIO pin used to transfer management data
|
||||||
|
// eth_type is the physical ethernet module's type (ETH_PHY_LAN8720, ETH_PHY_TLK110)
|
||||||
|
// eth_clk_mode defines the GPIO pin and GPIO mode for the clock signal
|
||||||
|
// However, there are really only four configurable options on ESP32:
|
||||||
|
// ETH_CLOCK_GPIO0_IN == External oscillator, clock input via GPIO0
|
||||||
|
// ETH_CLOCK_GPIO0_OUT == ESP32 provides 50MHz clock output via GPIO0
|
||||||
|
// ETH_CLOCK_GPIO16_OUT == ESP32 provides 50MHz clock output via GPIO16
|
||||||
|
// ETH_CLOCK_GPIO17_OUT == ESP32 provides 50MHz clock output via GPIO17
|
||||||
typedef struct EthernetSettings {
|
typedef struct EthernetSettings {
|
||||||
uint8_t eth_address;
|
uint8_t eth_address;
|
||||||
int eth_power;
|
int eth_power;
|
||||||
|
Loading…
Reference in New Issue
Block a user