Skip to content

Commit d13b8c8

Browse files
committed
Move LED_BUILTIN handling to BusManager class
- reduce max panels
1 parent 0af3063 commit d13b8c8

File tree

6 files changed

+99
-58
lines changed

6 files changed

+99
-58
lines changed

wled00/FX.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,7 @@ class WS2812FX { // 96 bytes
862862
isMatrix;
863863

864864
#ifndef WLED_DISABLE_2D
865-
#define WLED_MAX_PANELS 64
865+
#define WLED_MAX_PANELS 18
866866
uint8_t
867867
panels;
868868

wled00/bus_manager.cpp

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -270,12 +270,6 @@ bool BusDigital::canShow() {
270270

271271
void BusDigital::setBrightness(uint8_t b) {
272272
if (_bri == b) return;
273-
//Fix for turning off onboard LED breaking bus
274-
#ifdef LED_BUILTIN
275-
if (_bri == 0) { // && b > 0, covered by guard if above
276-
if (_pins[0] == LED_BUILTIN || _pins[1] == LED_BUILTIN) reinit();
277-
}
278-
#endif
279273
Bus::setBrightness(b);
280274
PolyBus::setBrightness(_busPtr, _iType, b);
281275
}
@@ -707,6 +701,7 @@ int BusManager::add(BusConfig &bc) {
707701
}
708702

709703
void BusManager::useParallelOutput(void) {
704+
_parallelOutputs = 8; // hardcoded since we use NPB I2S x8 methods
710705
PolyBus::setParallelI2S1Output();
711706
}
712707

@@ -717,9 +712,81 @@ void BusManager::removeAll() {
717712
while (!canAllShow()) yield();
718713
for (unsigned i = 0; i < numBusses; i++) delete busses[i];
719714
numBusses = 0;
715+
_parallelOutputs = 1;
720716
PolyBus::setParallelI2S1Output(false);
721717
}
722718

719+
#ifdef ESP32_DATA_IDLE_HIGH
720+
// #2478
721+
// If enabled, RMT idle level is set to HIGH when off
722+
// to prevent leakage current when using an N-channel MOSFET to toggle LED power
723+
void BusManager::esp32RMTInvertIdle() {
724+
bool idle_out;
725+
unsigned rmt = 0;
726+
for (unsigned u = 0; u < numBusses(); u++) {
727+
#if defined(CONFIG_IDF_TARGET_ESP32C3) // 2 RMT, only has 1 I2S but NPB does not support it ATM
728+
if (u > 1) return;
729+
rmt = u;
730+
#elif defined(CONFIG_IDF_TARGET_ESP32S2) // 4 RMT, only has 1 I2S bus, supported in NPB
731+
if (u > 3) return;
732+
rmt = u;
733+
#elif defined(CONFIG_IDF_TARGET_ESP32S3) // 4 RMT, has 2 I2S but NPB does not support them ATM
734+
if (u > 3) return;
735+
rmt = u;
736+
#else
737+
if (u < _parallelOutputs) continue;
738+
if (u >= _parallelOutputs + 8) return; // only 8 RMT channels
739+
rmt = u - _parallelOutputs;
740+
#endif
741+
if (busses[u]->getLength()==0 || !IS_DIGITAL(busses[u]->getType()) || IS_2PIN(busses[u]->getType())) continue;
742+
//assumes that bus number to rmt channel mapping stays 1:1
743+
rmt_channel_t ch = static_cast<rmt_channel_t>(rmt);
744+
rmt_idle_level_t lvl;
745+
rmt_get_idle_level(ch, &idle_out, &lvl);
746+
if (lvl == RMT_IDLE_LEVEL_HIGH) lvl = RMT_IDLE_LEVEL_LOW;
747+
else if (lvl == RMT_IDLE_LEVEL_LOW) lvl = RMT_IDLE_LEVEL_HIGH;
748+
else continue;
749+
rmt_set_idle_level(ch, idle_out, lvl);
750+
}
751+
}
752+
#endif
753+
754+
void BusManager::on() {
755+
#ifdef ESP8266
756+
//Fix for turning off onboard LED breaking bus
757+
if (pinManager.getPinOwner(LED_BUILTIN) == PinOwner::BusDigital) {
758+
for (unsigned i = 0; i < numBusses; i++) {
759+
uint8_t pins[2] = {255,255};
760+
if (IS_DIGITAL(busses[i]->getType()) && busses[i]->getPins(pins)) {
761+
if (pins[0] == LED_BUILTIN || pins[1] == LED_BUILTIN) {
762+
BusDigital *bus = static_cast<BusDigital*>(busses[i]);
763+
bus->reinit();
764+
break;
765+
}
766+
}
767+
}
768+
}
769+
#endif
770+
#ifdef ESP32_DATA_IDLE_HIGH
771+
esp32RMTInvertIdle();
772+
#endif
773+
}
774+
775+
void BusManager::off() {
776+
#ifdef ESP8266
777+
// turn off built-in LED if strip is turned off
778+
// this will break digital bus so will need to be re-initialised on On
779+
if (pinManager.getPinOwner(LED_BUILTIN) == PinOwner::BusDigital) {
780+
for (unsigned i = 0; i < numBusses; i++) if (busses[i]->isOffRefreshRequired()) return;
781+
pinMode(LED_BUILTIN, OUTPUT);
782+
digitalWrite(LED_BUILTIN, HIGH);
783+
}
784+
#endif
785+
#ifdef ESP32_DATA_IDLE_HIGH
786+
esp32RMTInvertIdle();
787+
#endif
788+
}
789+
723790
void BusManager::show() {
724791
_milliAmpsUsed = 0;
725792
for (unsigned i = 0; i < numBusses; i++) {
@@ -799,4 +866,5 @@ uint8_t BusManager::numBusses = 0;
799866
Bus* BusManager::busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES];
800867
ColorOrderMap BusManager::colorOrderMap = {};
801868
uint16_t BusManager::_milliAmpsUsed = 0;
802-
uint16_t BusManager::_milliAmpsMax = ABL_MILLIAMPS_DEFAULT;
869+
uint16_t BusManager::_milliAmpsMax = ABL_MILLIAMPS_DEFAULT;
870+
uint8_t BusManager::_parallelOutputs = 1;

wled00/bus_manager.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,9 @@ class BusManager {
364364
//do not call this method from system context (network callback)
365365
static void removeAll();
366366

367+
static void on(void);
368+
static void off(void);
369+
367370
static void show();
368371
static bool canAllShow();
369372
static void setStatusPixel(uint32_t c);
@@ -391,7 +394,11 @@ class BusManager {
391394
static ColorOrderMap colorOrderMap;
392395
static uint16_t _milliAmpsUsed;
393396
static uint16_t _milliAmpsMax;
397+
static uint8_t _parallelOutputs;
394398

399+
#ifdef ESP32_DATA_IDLE_HIGH
400+
static void esp32RMTInvertIdle();
401+
#endif
395402
static uint8_t getNumVirtualBusses() {
396403
int j = 0;
397404
for (int i=0; i<numBusses; i++) if (busses[i]->getType() >= TYPE_NET_DDP_RGB && busses[i]->getType() < 96) j++;

wled00/button.cpp

Lines changed: 12 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -358,69 +358,35 @@ void handleButton()
358358
}
359359
}
360360

361-
// If enabled, RMT idle level is set to HIGH when off
362-
// to prevent leakage current when using an N-channel MOSFET to toggle LED power
363-
#ifdef ESP32_DATA_IDLE_HIGH
364-
void esp32RMTInvertIdle()
365-
{
366-
bool idle_out;
367-
for (uint8_t u = 0; u < BusManager::getNumBusses(); u++)
368-
{
369-
if (u > 7) return; // only 8 RMT channels, TODO: ESP32 variants have less RMT channels
370-
Bus *bus = BusManager::getBus(u);
371-
if (!bus || bus->getLength()==0 || !IS_DIGITAL(bus->getType()) || IS_2PIN(bus->getType())) continue;
372-
//assumes that bus number to rmt channel mapping stays 1:1
373-
rmt_channel_t ch = static_cast<rmt_channel_t>(u);
374-
rmt_idle_level_t lvl;
375-
rmt_get_idle_level(ch, &idle_out, &lvl);
376-
if (lvl == RMT_IDLE_LEVEL_HIGH) lvl = RMT_IDLE_LEVEL_LOW;
377-
else if (lvl == RMT_IDLE_LEVEL_LOW) lvl = RMT_IDLE_LEVEL_HIGH;
378-
else continue;
379-
rmt_set_idle_level(ch, idle_out, lvl);
380-
}
381-
}
382-
#endif
383-
361+
// handleIO() happens *after* handleTransitions() (see wled.cpp) which may change bri/briT but *before* strip.service()
362+
// where actual LED painting occurrs
363+
// this is important for relay control and in the event of turning off on-board LED
384364
void handleIO()
385365
{
386366
handleButton();
387367

388-
//set relay when LEDs turn on
389-
if (strip.getBrightness())
390-
{
368+
// if we want to control on-board LED (ESP8266) or relay we have to do it here as the final show() may not happen until
369+
// next loop() cycle
370+
if (strip.getBrightness()) {
391371
lastOnTime = millis();
392-
if (offMode)
393-
{
394-
#ifdef ESP32_DATA_IDLE_HIGH
395-
esp32RMTInvertIdle();
396-
#endif
372+
if (offMode) {
373+
BusManager::on();
397374
if (rlyPin>=0) {
398375
pinMode(rlyPin, rlyOpenDrain ? OUTPUT_OPEN_DRAIN : OUTPUT);
399376
digitalWrite(rlyPin, rlyMde);
400377
}
401378
offMode = false;
402379
}
403-
} else if (millis() - lastOnTime > 600)
404-
{
380+
} else if (millis() - lastOnTime > 600 && !strip.needsUpdate()) {
381+
// for turning LED or relay off we need to wait until strip no longer needs updates (strip.trigger())
405382
if (!offMode) {
406-
#ifdef ESP8266
407-
// turn off built-in LED if strip is turned off
408-
// this will break digital bus so will need to be re-initialised on On
409-
PinOwner ledPinOwner = pinManager.getPinOwner(LED_BUILTIN);
410-
if (!strip.isOffRefreshRequired() && (ledPinOwner == PinOwner::None || ledPinOwner == PinOwner::BusDigital)) {
411-
pinMode(LED_BUILTIN, OUTPUT);
412-
digitalWrite(LED_BUILTIN, HIGH);
413-
}
414-
#endif
415-
#ifdef ESP32_DATA_IDLE_HIGH
416-
esp32RMTInvertIdle();
417-
#endif
383+
BusManager::off();
418384
if (rlyPin>=0) {
419385
pinMode(rlyPin, rlyOpenDrain ? OUTPUT_OPEN_DRAIN : OUTPUT);
420386
digitalWrite(rlyPin, !rlyMde);
421387
}
388+
offMode = true;
422389
}
423-
offMode = true;
424390
}
425391
}
426392

wled00/const.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,9 @@
192192
#define CALL_MODE_INIT 0 //no updates on init, can be used to disable updates
193193
#define CALL_MODE_DIRECT_CHANGE 1
194194
#define CALL_MODE_BUTTON 2 //default button actions applied to selected segments
195-
#define CALL_MODE_NOTIFICATION 3
196-
#define CALL_MODE_NIGHTLIGHT 4
197-
#define CALL_MODE_NO_NOTIFY 5
195+
#define CALL_MODE_NOTIFICATION 3 //caused by incoming notification (UDP or DMX preset)
196+
#define CALL_MODE_NIGHTLIGHT 4 //nightlight progress
197+
#define CALL_MODE_NO_NOTIFY 5 //change state but do not send notifications (UDP)
198198
#define CALL_MODE_FX_CHANGED 6 //no longer used
199199
#define CALL_MODE_HUE 7
200200
#define CALL_MODE_PRESET_CYCLE 8 //no longer used

wled00/led.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ void handleTransitions()
195195
applyFinalBri();
196196
return;
197197
}
198-
if (tper - tperLast < 0.004f) return;
198+
if (tper - tperLast < 0.004f) return; // less than 1 bit change (1/255)
199199
tperLast = tper;
200200
briT = briOld + ((bri - briOld) * tper);
201201

0 commit comments

Comments
 (0)