Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions wled00/FX_fcn.cpp
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -1178,17 +1178,42 @@ void WS2812FX::finalizeInit() {
digitalCount = 0;
#endif

DEBUG_PRINTF_P(PSTR("Heap before buses: %d\n"), getFreeHeapSize());
// create buses/outputs
unsigned mem = 0;
unsigned maxI2S = 0;
for (const auto &bus : busConfigs) {
mem += bus.memUsage(Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type) ? digitalCount++ : 0); // includes global buffer
if (mem <= MAX_LED_MEMORY) {
if (BusManager::add(bus) == -1) break;
unsigned memB = bus.memUsage(Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type) ? digitalCount++ : 0); // does not include DMA/RMT buffer
mem += memB;
// estimate maximum I2S memory usage (only relevant for digital non-2pin busses)
#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(ESP8266)
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S3)
const bool usesI2S = ((useParallelI2S && digitalCount <= 8) || (!useParallelI2S && digitalCount == 1));
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
const bool usesI2S = (useParallelI2S && digitalCount <= 8);
#else
const bool usesI2S = false;
#endif
if (Bus::isDigital(bus.type) && !Bus::is2Pin(bus.type) && usesI2S) {
#ifdef NPB_CONF_4STEP_CADENCE
constexpr unsigned stepFactor = 4; // 4 step cadence (4 bits per pixel bit)
#else
constexpr unsigned stepFactor = 3; // 3 step cadence (3 bits per pixel bit)
#endif
unsigned i2sCommonSize = stepFactor * bus.count * (3*Bus::hasRGB(bus.type)+Bus::hasWhite(bus.type)+Bus::hasCCT(bus.type)) * (Bus::is16bit(bus.type)+1);
if (i2sCommonSize > maxI2S) maxI2S = i2sCommonSize;
}
#endif
if (mem + maxI2S <= MAX_LED_MEMORY) {
BusManager::add(bus);
DEBUG_PRINTF_P(PSTR("Bus memory: %uB\n"), memB);
} else {
errorFlag = ERR_NORAM_PX; // alert UI
DEBUG_PRINTF_P(PSTR("Out of LED memory! Bus %d (%d) #%u not created."), (int)bus.type, (int)bus.count, digitalCount);
break;
}
}
DEBUG_PRINTF_P(PSTR("LED buffer size: %uB/%uB\n"), mem + maxI2S, BusManager::memUsage());
busConfigs.clear();
busConfigs.shrink_to_fit();

Expand Down
29 changes: 15 additions & 14 deletions wled00/bus_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ size_t BusDigital::getPins(uint8_t* pinArray) const {
}

size_t BusDigital::getBusSize() const {
return sizeof(BusDigital) + (isOk() ? PolyBus::getDataSize(_busPtr, _iType) : 0);
return sizeof(BusDigital) + (isOk() ? PolyBus::getDataSize(_busPtr, _iType) : 0); // does not include common I2S DMA buffer
}

void BusDigital::setColorOrder(uint8_t colorOrder) {
Expand Down Expand Up @@ -760,7 +760,8 @@ size_t BusConfig::memUsage(unsigned nr) const {
if (Bus::isVirtual(type)) {
return sizeof(BusNetwork) + (count * Bus::getNumberOfChannels(type));
} else if (Bus::isDigital(type)) {
return sizeof(BusDigital) + PolyBus::memUsage(count + skipAmount, PolyBus::getI(type, pins, nr)) /*+ doubleBuffer * (count + skipAmount) * Bus::getNumberOfChannels(type)*/;
// if any of digital buses uses I2S, there is additional common I2S DMA buffer not accounted for here
return sizeof(BusDigital) + PolyBus::memUsage(count + skipAmount, PolyBus::getI(type, pins, nr));
} else if (Bus::isOnOff(type)) {
return sizeof(BusOnOff);
} else {
Expand All @@ -776,23 +777,23 @@ size_t BusManager::memUsage() {
unsigned maxI2S = 0;
#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(ESP8266)
unsigned digitalCount = 0;
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
#define MAX_RMT 4
#else
#define MAX_RMT 8
#endif
#endif
for (const auto &bus : busses) {
unsigned busSize = bus->getBusSize();
size += bus->getBusSize();
#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(ESP8266)
if (bus->isDigital() && !bus->is2Pin()) digitalCount++;
if (PolyBus::isParallelI2S1Output() && digitalCount > MAX_RMT) {
unsigned i2sCommonSize = 3 * bus->getLength() * bus->getNumberOfChannels() * (bus->is16bit()+1);
if (i2sCommonSize > maxI2S) maxI2S = i2sCommonSize;
busSize -= i2sCommonSize;
if (bus->isDigital() && !bus->is2Pin()) {
digitalCount++;
if ((PolyBus::isParallelI2S1Output() && digitalCount <= 8) || (!PolyBus::isParallelI2S1Output() && digitalCount == 1)) {
#ifdef NPB_CONF_4STEP_CADENCE
constexpr unsigned stepFactor = 4; // 4 step cadence (4 bits per pixel bit)
#else
constexpr unsigned stepFactor = 3; // 3 step cadence (3 bits per pixel bit)
#endif
unsigned i2sCommonSize = stepFactor * bus->getLength() * bus->getNumberOfChannels() * (bus->is16bit()+1);
if (i2sCommonSize > maxI2S) maxI2S = i2sCommonSize;
}
}
#endif
size += busSize;
}
return size + maxI2S;
}
Expand Down
Loading