hub75 - post main merge fixes

This commit is contained in:
Will Tatam 2025-01-09 12:06:23 +00:00
commit d2f8f99683
16 changed files with 117 additions and 123 deletions

View File

@ -2,12 +2,7 @@
# [Choice] Python version: 3, 3.9, 3.8, 3.7, 3.6 # [Choice] Python version: 3, 3.9, 3.8, 3.7, 3.6
ARG VARIANT="3" ARG VARIANT="3"
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} FROM mcr.microsoft.com/devcontainers/python:0-${VARIANT}
# [Option] Install Node.js
ARG INSTALL_NODE="true"
ARG NODE_VERSION="lts/*"
RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image. # [Optional] If your pip requirements rarely change, uncomment this section to add them to the image.
# COPY requirements.txt /tmp/pip-tmp/ # COPY requirements.txt /tmp/pip-tmp/

View File

@ -5,10 +5,7 @@
"context": "..", "context": "..",
"args": { "args": {
// Update 'VARIANT' to pick a Python version: 3, 3.6, 3.7, 3.8, 3.9 // Update 'VARIANT' to pick a Python version: 3, 3.6, 3.7, 3.8, 3.9
"VARIANT": "3", "VARIANT": "3"
// Options
"INSTALL_NODE": "true",
"NODE_VERSION": "lts/*"
} }
}, },
@ -54,7 +51,7 @@
// "forwardPorts": [], // "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created. // Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "npm install", "postCreateCommand": "bash -i -c 'nvm install && npm ci'",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode" "remoteUser": "vscode"

View File

@ -38,6 +38,7 @@ jobs:
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version-file: '.nvmrc'
cache: 'npm' cache: 'npm'
- run: npm ci - run: npm ci
- name: Cache PlatformIO - name: Cache PlatformIO
@ -74,7 +75,7 @@ jobs:
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: '20.x' node-version-file: '.nvmrc'
cache: 'npm' cache: 'npm'
- run: npm ci - run: npm ci
- run: npm test - run: npm test

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
20.18

View File

@ -528,7 +528,7 @@ build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_DISABLE_BROWNOU
monitor_filters = esp32_exception_decoder monitor_filters = esp32_exception_decoder
lib_deps = lib_deps =
${esp32.lib_deps} ${esp32.lib_deps}
TFT_eSPI @ 2.5.33 ;; this is the last version that compiles with the WLED default framework - newer versions require platform = espressif32 @ ^6.3.2 TFT_eSPI @ 2.5.33 ;; this is the last version that compiles with the WLED default framework - newer versions require platform = espressif32 @ ^6.3.2
[env:esp32dev_hub75] [env:esp32dev_hub75]
@ -538,7 +538,7 @@ platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages} platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} build_flags = ${common.build_flags}
-D WLED_RELEASE_NAME=ESP32_hub75 -D WLED_RELEASE_NAME=\"ESP32_hub75\"
-D WLED_ENABLE_HUB75MATRIX -D NO_GFX -D NO_CIE1931 -D WLED_ENABLE_HUB75MATRIX -D NO_GFX -D NO_CIE1931
; -D ESP32_FORUM_PINOUT ;; enable for SmartMatrix default pins ; -D ESP32_FORUM_PINOUT ;; enable for SmartMatrix default pins
; -D WLED_DEBUG ; -D WLED_DEBUG

View File

@ -2032,7 +2032,7 @@ uint16_t mode_palette() {
const mathType sourceX = xtSinTheta + ytCosTheta + centerX; const mathType sourceX = xtSinTheta + ytCosTheta + centerX;
// The computation was scaled just right so that the result should always be in range [0, maxXOut], but enforce this anyway // The computation was scaled just right so that the result should always be in range [0, maxXOut], but enforce this anyway
// to account for imprecision. Then scale it so that the range is [0, 255], which we can use with the palette. // to account for imprecision. Then scale it so that the range is [0, 255], which we can use with the palette.
int colorIndex = (std::min(std::max(sourceX, mathType(0)), maxXOut * sInt16Scale) * 255) / (sInt16Scale * maxXOut); int colorIndex = (std::min(std::max(sourceX, mathType(0)), maxXOut * sInt16Scale) * wideMathType(255)) / (sInt16Scale * maxXOut);
// inputSize determines by how much we want to scale the palette: // inputSize determines by how much we want to scale the palette:
// values < 128 display a fraction of a palette, // values < 128 display a fraction of a palette,
// values > 128 display multiple palettes. // values > 128 display multiple palettes.

View File

@ -1011,7 +1011,7 @@ BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWh
} }
} }
void __attribute__((hot)) BusHub75Matrix::setPixelColor(uint16_t pix, uint32_t c) { void __attribute__((hot)) BusHub75Matrix::setPixelColor(unsigned pix, uint32_t c) {
if (!_valid || pix >= _len) return; if (!_valid || pix >= _len) return;
// if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT // if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
@ -1045,7 +1045,7 @@ void __attribute__((hot)) BusHub75Matrix::setPixelColor(uint16_t pix, uint32_t c
} }
} }
uint32_t BusHub75Matrix::getPixelColor(uint16_t pix) const { uint32_t BusHub75Matrix::getPixelColor(unsigned pix) const {
if (!_valid || pix >= _len) return IS_BLACK; if (!_valid || pix >= _len) return IS_BLACK;
if (_ledBuffer) if (_ledBuffer)
return uint32_t(_ledBuffer[pix].scale8(_bri)) & 0x00FFFFFF; // scale8() is needed to mimic NeoPixelBus, which returns scaled-down colours return uint32_t(_ledBuffer[pix].scale8(_bri)) & 0x00FFFFFF; // scale8() is needed to mimic NeoPixelBus, which returns scaled-down colours

View File

@ -328,8 +328,8 @@ class BusNetwork : public Bus {
class BusHub75Matrix : public Bus { class BusHub75Matrix : public Bus {
public: public:
BusHub75Matrix(BusConfig &bc); BusHub75Matrix(BusConfig &bc);
void setPixelColor(uint16_t pix, uint32_t c) override; void setPixelColor(unsigned pix, uint32_t c) override;
uint32_t getPixelColor(uint16_t pix) const override; uint32_t getPixelColor(unsigned pix) const override;
void show() override; void show() override;
void setBrightness(uint8_t b) override; void setBrightness(uint8_t b) override;
uint8_t getPins(uint8_t* pinArray) const override; uint8_t getPins(uint8_t* pinArray) const override;
@ -344,7 +344,7 @@ class BusHub75Matrix : public Bus {
private: private:
MatrixPanel_I2S_DMA *display = nullptr; MatrixPanel_I2S_DMA *display = nullptr;
VirtualMatrixPanel *fourScanPanel = nullptr; VirtualMatrixPanel *virtualDisp = nullptr;
HUB75_I2S_CFG mxconfig; HUB75_I2S_CFG mxconfig;
unsigned _panelWidth = 0; unsigned _panelWidth = 0;
CRGB *_ledBuffer = nullptr; CRGB *_ledBuffer = nullptr;

View File

@ -29,7 +29,7 @@ void shortPressAction(uint8_t b)
#ifndef WLED_DISABLE_MQTT #ifndef WLED_DISABLE_MQTT
// publish MQTT message // publish MQTT message
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) { if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
char subuf[64]; char subuf[MQTT_MAX_TOPIC_LEN + 32];
sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b); sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
mqtt->publish(subuf, 0, false, "short"); mqtt->publish(subuf, 0, false, "short");
} }
@ -62,7 +62,7 @@ void longPressAction(uint8_t b)
#ifndef WLED_DISABLE_MQTT #ifndef WLED_DISABLE_MQTT
// publish MQTT message // publish MQTT message
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) { if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
char subuf[64]; char subuf[MQTT_MAX_TOPIC_LEN + 32];
sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b); sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
mqtt->publish(subuf, 0, false, "long"); mqtt->publish(subuf, 0, false, "long");
} }
@ -83,7 +83,7 @@ void doublePressAction(uint8_t b)
#ifndef WLED_DISABLE_MQTT #ifndef WLED_DISABLE_MQTT
// publish MQTT message // publish MQTT message
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) { if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
char subuf[64]; char subuf[MQTT_MAX_TOPIC_LEN + 32];
sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b); sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
mqtt->publish(subuf, 0, false, "double"); mqtt->publish(subuf, 0, false, "double");
} }
@ -151,7 +151,7 @@ void handleSwitch(uint8_t b)
#ifndef WLED_DISABLE_MQTT #ifndef WLED_DISABLE_MQTT
// publish MQTT message // publish MQTT message
if (buttonPublishMqtt && WLED_MQTT_CONNECTED) { if (buttonPublishMqtt && WLED_MQTT_CONNECTED) {
char subuf[64]; char subuf[MQTT_MAX_TOPIC_LEN + 32];
if (buttonType[b] == BTN_TYPE_PIR_SENSOR) sprintf_P(subuf, PSTR("%s/motion/%d"), mqttDeviceTopic, (int)b); if (buttonType[b] == BTN_TYPE_PIR_SENSOR) sprintf_P(subuf, PSTR("%s/motion/%d"), mqttDeviceTopic, (int)b);
else sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b); else sprintf_P(subuf, _mqtt_topic_button, mqttDeviceTopic, (int)b);
mqtt->publish(subuf, 0, false, !buttonPressedBefore[b] ? "off" : "on"); mqtt->publish(subuf, 0, false, !buttonPressedBefore[b] ? "off" : "on");

View File

@ -417,36 +417,33 @@ class Usermod {
#endif #endif
}; };
class UsermodManager { namespace UsermodManager {
private: extern byte numMods;
static Usermod* ums[WLED_MAX_USERMODS];
static byte numMods;
public: void loop();
static void loop(); void handleOverlayDraw();
static void handleOverlayDraw(); bool handleButton(uint8_t b);
static bool handleButton(uint8_t b); bool getUMData(um_data_t **um_data, uint8_t mod_id = USERMOD_ID_RESERVED); // USERMOD_ID_RESERVED will poll all usermods
static bool getUMData(um_data_t **um_data, uint8_t mod_id = USERMOD_ID_RESERVED); // USERMOD_ID_RESERVED will poll all usermods void setup();
static void setup(); void connected();
static void connected(); void appendConfigData(Print&);
static void appendConfigData(Print&); void addToJsonState(JsonObject& obj);
static void addToJsonState(JsonObject& obj); void addToJsonInfo(JsonObject& obj);
static void addToJsonInfo(JsonObject& obj); void readFromJsonState(JsonObject& obj);
static void readFromJsonState(JsonObject& obj); void addToConfig(JsonObject& obj);
static void addToConfig(JsonObject& obj); bool readFromConfig(JsonObject& obj);
static bool readFromConfig(JsonObject& obj);
#ifndef WLED_DISABLE_MQTT #ifndef WLED_DISABLE_MQTT
static void onMqttConnect(bool sessionPresent); void onMqttConnect(bool sessionPresent);
static bool onMqttMessage(char* topic, char* payload); bool onMqttMessage(char* topic, char* payload);
#endif #endif
#ifndef WLED_DISABLE_ESPNOW #ifndef WLED_DISABLE_ESPNOW
static bool onEspNowMessage(uint8_t* sender, uint8_t* payload, uint8_t len); bool onEspNowMessage(uint8_t* sender, uint8_t* payload, uint8_t len);
#endif #endif
static void onUpdateBegin(bool); void onUpdateBegin(bool);
static void onStateChange(uint8_t); void onStateChange(uint8_t);
static bool add(Usermod* um); bool add(Usermod* um);
static Usermod* lookup(uint16_t mod_id); Usermod* lookup(uint16_t mod_id);
static inline byte getModCount() {return numMods;}; inline byte getModCount() {return numMods;};
}; };
//usermods_list.cpp //usermods_list.cpp

View File

@ -7,6 +7,10 @@
#ifndef WLED_DISABLE_MQTT #ifndef WLED_DISABLE_MQTT
#define MQTT_KEEP_ALIVE_TIME 60 // contact the MQTT broker every 60 seconds #define MQTT_KEEP_ALIVE_TIME 60 // contact the MQTT broker every 60 seconds
#if MQTT_MAX_TOPIC_LEN > 32
#warning "MQTT topics length > 32 is not recommended for compatibility with usermods!"
#endif
static void parseMQTTBriPayload(char* payload) static void parseMQTTBriPayload(char* payload)
{ {
if (strstr(payload, "ON") || strstr(payload, "on") || strstr(payload, "true")) {bri = briLast; stateUpdated(CALL_MODE_DIRECT_CHANGE);} if (strstr(payload, "ON") || strstr(payload, "on") || strstr(payload, "true")) {bri = briLast; stateUpdated(CALL_MODE_DIRECT_CHANGE);}
@ -23,24 +27,24 @@ static void parseMQTTBriPayload(char* payload)
static void onMqttConnect(bool sessionPresent) static void onMqttConnect(bool sessionPresent)
{ {
//(re)subscribe to required topics //(re)subscribe to required topics
char subuf[38]; char subuf[MQTT_MAX_TOPIC_LEN + 6];
if (mqttDeviceTopic[0] != 0) { if (mqttDeviceTopic[0] != 0) {
strlcpy(subuf, mqttDeviceTopic, 33); strlcpy(subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1);
mqtt->subscribe(subuf, 0); mqtt->subscribe(subuf, 0);
strcat_P(subuf, PSTR("/col")); strcat_P(subuf, PSTR("/col"));
mqtt->subscribe(subuf, 0); mqtt->subscribe(subuf, 0);
strlcpy(subuf, mqttDeviceTopic, 33); strlcpy(subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1);
strcat_P(subuf, PSTR("/api")); strcat_P(subuf, PSTR("/api"));
mqtt->subscribe(subuf, 0); mqtt->subscribe(subuf, 0);
} }
if (mqttGroupTopic[0] != 0) { if (mqttGroupTopic[0] != 0) {
strlcpy(subuf, mqttGroupTopic, 33); strlcpy(subuf, mqttGroupTopic, MQTT_MAX_TOPIC_LEN + 1);
mqtt->subscribe(subuf, 0); mqtt->subscribe(subuf, 0);
strcat_P(subuf, PSTR("/col")); strcat_P(subuf, PSTR("/col"));
mqtt->subscribe(subuf, 0); mqtt->subscribe(subuf, 0);
strlcpy(subuf, mqttGroupTopic, 33); strlcpy(subuf, mqttGroupTopic, MQTT_MAX_TOPIC_LEN + 1);
strcat_P(subuf, PSTR("/api")); strcat_P(subuf, PSTR("/api"));
mqtt->subscribe(subuf, 0); mqtt->subscribe(subuf, 0);
} }
@ -158,19 +162,19 @@ void publishMqtt()
#ifndef USERMOD_SMARTNEST #ifndef USERMOD_SMARTNEST
char s[10]; char s[10];
char subuf[48]; char subuf[MQTT_MAX_TOPIC_LEN + 16];
sprintf_P(s, PSTR("%u"), bri); sprintf_P(s, PSTR("%u"), bri);
strlcpy(subuf, mqttDeviceTopic, 33); strlcpy(subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1);
strcat_P(subuf, PSTR("/g")); strcat_P(subuf, PSTR("/g"));
mqtt->publish(subuf, 0, retainMqttMsg, s); // optionally retain message (#2263) mqtt->publish(subuf, 0, retainMqttMsg, s); // optionally retain message (#2263)
sprintf_P(s, PSTR("#%06X"), (col[3] << 24) | (col[0] << 16) | (col[1] << 8) | (col[2])); sprintf_P(s, PSTR("#%06X"), (col[3] << 24) | (col[0] << 16) | (col[1] << 8) | (col[2]));
strlcpy(subuf, mqttDeviceTopic, 33); strlcpy(subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1);
strcat_P(subuf, PSTR("/c")); strcat_P(subuf, PSTR("/c"));
mqtt->publish(subuf, 0, retainMqttMsg, s); // optionally retain message (#2263) mqtt->publish(subuf, 0, retainMqttMsg, s); // optionally retain message (#2263)
strlcpy(subuf, mqttDeviceTopic, 33); strlcpy(subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1);
strcat_P(subuf, PSTR("/status")); strcat_P(subuf, PSTR("/status"));
mqtt->publish(subuf, 0, true, "online"); // retain message for a LWT mqtt->publish(subuf, 0, true, "online"); // retain message for a LWT
@ -178,7 +182,7 @@ void publishMqtt()
DynamicBuffer buf(1024); DynamicBuffer buf(1024);
bufferPrint pbuf(buf.data(), buf.size()); bufferPrint pbuf(buf.data(), buf.size());
XML_response(pbuf); XML_response(pbuf);
strlcpy(subuf, mqttDeviceTopic, 33); strlcpy(subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1);
strcat_P(subuf, PSTR("/v")); strcat_P(subuf, PSTR("/v"));
mqtt->publish(subuf, 0, retainMqttMsg, buf.data(), pbuf.size()); // optionally retain message (#2263) mqtt->publish(subuf, 0, retainMqttMsg, buf.data(), pbuf.size()); // optionally retain message (#2263)
#endif #endif
@ -211,7 +215,7 @@ bool initMqtt()
if (mqttUser[0] && mqttPass[0]) mqtt->setCredentials(mqttUser, mqttPass); if (mqttUser[0] && mqttPass[0]) mqtt->setCredentials(mqttUser, mqttPass);
#ifndef USERMOD_SMARTNEST #ifndef USERMOD_SMARTNEST
strlcpy(mqttStatusTopic, mqttDeviceTopic, 33); strlcpy(mqttStatusTopic, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1);
strcat_P(mqttStatusTopic, PSTR("/status")); strcat_P(mqttStatusTopic, PSTR("/status"));
mqtt->setWill(mqttStatusTopic, 0, true, "offline"); // LWT message mqtt->setWill(mqttStatusTopic, 0, true, "offline"); // LWT message
#endif #endif

View File

@ -13,6 +13,16 @@
#endif #endif
#endif #endif
// Pin management state variables
#ifdef ESP8266
static uint32_t pinAlloc = 0UL; // 1 bit per pin, we use first 17bits
#else
static uint64_t pinAlloc = 0ULL; // 1 bit per pin, we use 50 bits on ESP32-S3
static uint16_t ledcAlloc = 0; // up to 16 LEDC channels (WLED_MAX_ANALOG_CHANNELS)
#endif
static uint8_t i2cAllocCount = 0; // allow multiple allocation of I2C bus pins but keep track of allocations
static uint8_t spiAllocCount = 0; // allow multiple allocation of SPI bus pins but keep track of allocations
static PinOwner ownerTag[WLED_NUM_PINS] = { PinOwner::None };
/// Actual allocation/deallocation routines /// Actual allocation/deallocation routines
bool PinManager::deallocatePin(byte gpio, PinOwner tag) bool PinManager::deallocatePin(byte gpio, PinOwner tag)
@ -296,13 +306,3 @@ void PinManager::deallocateLedc(byte pos, byte channels)
} }
} }
#endif #endif
#ifdef ESP8266
uint32_t PinManager::pinAlloc = 0UL;
#else
uint64_t PinManager::pinAlloc = 0ULL;
uint16_t PinManager::ledcAlloc = 0;
#endif
uint8_t PinManager::i2cAllocCount = 0;
uint8_t PinManager::spiAllocCount = 0;
PinOwner PinManager::ownerTag[WLED_NUM_PINS] = { PinOwner::None };

View File

@ -9,6 +9,12 @@
#endif #endif
#include "const.h" // for USERMOD_* values #include "const.h" // for USERMOD_* values
#ifdef ESP8266
#define WLED_NUM_PINS (GPIO_PIN_COUNT+1) // somehow they forgot GPIO 16 (0-16==17)
#else
#define WLED_NUM_PINS (GPIO_PIN_COUNT)
#endif
typedef struct PinManagerPinType { typedef struct PinManagerPinType {
int8_t pin; int8_t pin;
bool isOutput; bool isOutput;
@ -71,55 +77,46 @@ enum struct PinOwner : uint8_t {
}; };
static_assert(0u == static_cast<uint8_t>(PinOwner::None), "PinOwner::None must be zero, so default array initialization works as expected"); static_assert(0u == static_cast<uint8_t>(PinOwner::None), "PinOwner::None must be zero, so default array initialization works as expected");
class PinManager { namespace PinManager {
private: // De-allocates a single pin
#ifdef ESP8266 bool deallocatePin(byte gpio, PinOwner tag);
#define WLED_NUM_PINS (GPIO_PIN_COUNT+1) // somehow they forgot GPIO 16 (0-16==17) // De-allocates multiple pins but only if all can be deallocated (PinOwner has to be specified)
static uint32_t pinAlloc; // 1 bit per pin, we use first 17bits bool deallocateMultiplePins(const uint8_t *pinArray, byte arrayElementCount, PinOwner tag);
#else bool deallocateMultiplePins(const managed_pin_type *pinArray, byte arrayElementCount, PinOwner tag);
#define WLED_NUM_PINS (GPIO_PIN_COUNT) // Allocates a single pin, with an owner tag.
static uint64_t pinAlloc; // 1 bit per pin, we use 50 bits on ESP32-S3 // De-allocation requires the same owner tag (or override)
static uint16_t ledcAlloc; // up to 16 LEDC channels (WLED_MAX_ANALOG_CHANNELS) bool allocatePin(byte gpio, bool output, PinOwner tag);
#endif // Allocates all the pins, or allocates none of the pins, with owner tag.
static uint8_t i2cAllocCount; // allow multiple allocation of I2C bus pins but keep track of allocations // Provided to simplify error condition handling in clients
static uint8_t spiAllocCount; // allow multiple allocation of SPI bus pins but keep track of allocations // using more than one pin, such as I2C, SPI, rotary encoders,
static PinOwner ownerTag[WLED_NUM_PINS]; // ethernet, etc..
bool allocateMultiplePins(const managed_pin_type * mptArray, byte arrayElementCount, PinOwner tag );
[[deprecated("Replaced by three-parameter allocatePin(gpio, output, ownerTag), for improved debugging")]]
inline bool allocatePin(byte gpio, bool output = true) { return allocatePin(gpio, output, PinOwner::None); }
[[deprecated("Replaced by two-parameter deallocatePin(gpio, ownerTag), for improved debugging")]]
inline void deallocatePin(byte gpio) { deallocatePin(gpio, PinOwner::None); }
public:
// De-allocates a single pin
static bool deallocatePin(byte gpio, PinOwner tag);
// De-allocates multiple pins but only if all can be deallocated (PinOwner has to be specified) // De-allocates multiple pins but only if all can be deallocated (PinOwner has to be specified)
static bool deallocateMultiplePins(const uint8_t *pinArray, byte arrayElementCount, PinOwner tag); bool deallocateMultiplePins(const uint8_t *pinArray, byte arrayElementCount, PinOwner tag);
static bool deallocateMultiplePins(const managed_pin_type *pinArray, byte arrayElementCount, PinOwner tag); bool deallocateMultiplePins(const managed_pin_type *pinArray, byte arrayElementCount, PinOwner tag);
// Allocates a single pin, with an owner tag.
// De-allocation requires the same owner tag (or override) bool allocateMultiplePins(const managed_pin_type * mptArray, byte arrayElementCount, PinOwner tag );
static bool allocatePin(byte gpio, bool output, PinOwner tag); bool allocateMultiplePins(const int8_t * mptArray, byte arrayElementCount, PinOwner tag, boolean output);
// 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..
static bool allocateMultiplePins(const managed_pin_type * mptArray, byte arrayElementCount, PinOwner tag );
static bool allocateMultiplePins(const int8_t * mptArray, byte arrayElementCount, PinOwner tag, boolean output);
// will return true for reserved pins
bool isPinAllocated(byte gpio, PinOwner tag = PinOwner::None);
// will return false for reserved pins
bool isPinOk(byte gpio, bool output = true);
bool isReadOnlyPin(byte gpio);
[[deprecated("Replaced by three-parameter allocatePin(gpio, output, ownerTag), for improved debugging")]] PinOwner getPinOwner(byte gpio);
static inline bool allocatePin(byte gpio, bool output = true) { return allocatePin(gpio, output, PinOwner::None); }
[[deprecated("Replaced by two-parameter deallocatePin(gpio, ownerTag), for improved debugging")]]
static inline void deallocatePin(byte gpio) { deallocatePin(gpio, PinOwner::None); }
// will return true for reserved pins #ifdef ARDUINO_ARCH_ESP32
static bool isPinAllocated(byte gpio, PinOwner tag = PinOwner::None); byte allocateLedc(byte channels);
// will return false for reserved pins void deallocateLedc(byte pos, byte channels);
static bool isPinOk(byte gpio, bool output = true); #endif
static bool isReadOnlyPin(byte gpio);
static PinOwner getPinOwner(byte gpio);
#ifdef ARDUINO_ARCH_ESP32
static byte allocateLedc(byte channels);
static void deallocateLedc(byte pos, byte channels);
#endif
}; };
//extern PinManager pinManager; //extern PinManager pinManager;

View File

@ -3,6 +3,9 @@
* Registration and management utility for v2 usermods * Registration and management utility for v2 usermods
*/ */
static Usermod* ums[WLED_MAX_USERMODS] = {nullptr};
byte UsermodManager::numMods = 0;
//Usermod Manager internals //Usermod Manager internals
void UsermodManager::setup() { for (unsigned i = 0; i < numMods; i++) ums[i]->setup(); } void UsermodManager::setup() { for (unsigned i = 0; i < numMods; i++) ums[i]->setup(); }
void UsermodManager::connected() { for (unsigned i = 0; i < numMods; i++) ums[i]->connected(); } void UsermodManager::connected() { for (unsigned i = 0; i < numMods; i++) ums[i]->connected(); }
@ -69,8 +72,6 @@ bool UsermodManager::add(Usermod* um)
return true; return true;
} }
Usermod* UsermodManager::ums[WLED_MAX_USERMODS] = {nullptr};
byte UsermodManager::numMods = 0;
/* Usermod v2 interface shim for oappend */ /* Usermod v2 interface shim for oappend */
Print* Usermod::oappend_shim = nullptr; Print* Usermod::oappend_shim = nullptr;

View File

@ -482,10 +482,10 @@ WLED_GLOBAL unsigned long lastMqttReconnectAttempt _INIT(0); // used for other
#endif #endif
WLED_GLOBAL AsyncMqttClient *mqtt _INIT(NULL); WLED_GLOBAL AsyncMqttClient *mqtt _INIT(NULL);
WLED_GLOBAL bool mqttEnabled _INIT(false); WLED_GLOBAL bool mqttEnabled _INIT(false);
WLED_GLOBAL char mqttStatusTopic[40] _INIT(""); // this must be global because of async handlers WLED_GLOBAL char mqttStatusTopic[MQTT_MAX_TOPIC_LEN + 8] _INIT(""); // this must be global because of async handlers
WLED_GLOBAL char mqttDeviceTopic[MQTT_MAX_TOPIC_LEN+1] _INIT(""); // main MQTT topic (individual per device, default is wled/mac) WLED_GLOBAL char mqttDeviceTopic[MQTT_MAX_TOPIC_LEN + 1] _INIT(""); // main MQTT topic (individual per device, default is wled/mac)
WLED_GLOBAL char mqttGroupTopic[MQTT_MAX_TOPIC_LEN+1] _INIT("wled/all"); // second MQTT topic (for example to group devices) WLED_GLOBAL char mqttGroupTopic[MQTT_MAX_TOPIC_LEN + 1] _INIT("wled/all"); // second MQTT topic (for example to group devices)
WLED_GLOBAL char mqttServer[MQTT_MAX_SERVER_LEN+1] _INIT(""); // both domains and IPs should work (no SSL) WLED_GLOBAL char mqttServer[MQTT_MAX_SERVER_LEN + 1] _INIT(""); // both domains and IPs should work (no SSL)
WLED_GLOBAL char mqttUser[41] _INIT(""); // optional: username for MQTT auth WLED_GLOBAL char mqttUser[41] _INIT(""); // optional: username for MQTT auth
WLED_GLOBAL char mqttPass[65] _INIT(""); // optional: password for MQTT auth WLED_GLOBAL char mqttPass[65] _INIT(""); // optional: password for MQTT auth
WLED_GLOBAL char mqttClientID[41] _INIT(""); // override the client ID WLED_GLOBAL char mqttClientID[41] _INIT(""); // override the client ID
@ -895,9 +895,6 @@ WLED_GLOBAL uint32_t ledMaps _INIT(0); // bitfield representation of available l
WLED_GLOBAL uint16_t ledMaps _INIT(0); // bitfield representation of available ledmaps WLED_GLOBAL uint16_t ledMaps _INIT(0); // bitfield representation of available ledmaps
#endif #endif
// Usermod manager
WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager());
// global I2C SDA pin (used for usermods) // global I2C SDA pin (used for usermods)
#ifndef I2CSDAPIN #ifndef I2CSDAPIN
WLED_GLOBAL int8_t i2c_sda _INIT(-1); WLED_GLOBAL int8_t i2c_sda _INIT(-1);

4
wled00/wled_eeprom.cpp Executable file → Normal file
View File

@ -2,6 +2,10 @@
#include <EEPROM.h> #include <EEPROM.h>
#include "wled.h" #include "wled.h"
#if defined(WLED_ENABLE_MQTT) && MQTT_MAX_TOPIC_LEN < 32
#error "MQTT topics length < 32 is not supported by the EEPROM module!"
#endif
/* /*
* DEPRECATED, do not use for new settings * DEPRECATED, do not use for new settings
* Only used to restore config from pre-0.11 installations using the deEEP() methods * Only used to restore config from pre-0.11 installations using the deEEP() methods