Skip to content

Commit 2e1c875

Browse files
committed
Fixes for over 65535 LEDs
1 parent 95cdf7e commit 2e1c875

21 files changed

+331
-857
lines changed

wled00/FX.cpp

Lines changed: 16 additions & 442 deletions
Large diffs are not rendered by default.

wled00/FX.h

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,9 @@ typedef enum mapping1D2D {
357357
// segment, 72 bytes
358358
typedef struct Segment {
359359
public:
360-
uint16_t start; // start index / start X coordinate 2D (left)
361-
uint16_t stop; // stop index / stop X coordinate 2D (right); segment is invalid if stop == 0
362-
uint16_t offset;
360+
uint32_t start; // start index / start X coordinate 2D (left)
361+
uint32_t stop; // stop index / stop X coordinate 2D (right); segment is invalid if stop == 0
362+
uint32_t offset;
363363
uint8_t speed;
364364
uint8_t intensity;
365365
uint8_t palette;
@@ -395,8 +395,8 @@ typedef struct Segment {
395395
bool check2 : 1; // checkmark 2
396396
bool check3 : 1; // checkmark 3
397397
};
398-
uint16_t startY; // start Y coodrinate 2D (top); there should be no more than 255 rows, but we cannot be sure.
399-
uint16_t stopY; // stop Y coordinate 2D (bottom); there should be no more than 255 rows, but we cannot be sure.
398+
uint32_t startY; // start Y coodrinate 2D (top); there should be no more than 255 rows, but we cannot be sure.
399+
uint32_t stopY; // stop Y coordinate 2D (bottom); there should be no more than 255 rows, but we cannot be sure.
400400
char *name = nullptr; // WLEDMM initialize to nullptr
401401

402402
// runtime data
@@ -435,7 +435,7 @@ typedef struct Segment {
435435
uint8_t _brightness = 255; // final pixel brightness - including transitions and segment opacity
436436
uint16_t _2dWidth = 0; // virtualWidth
437437
uint16_t _2dHeight = 0; // virtualHeight
438-
uint16_t _virtuallength = 0; // virtualLength
438+
uint32_t _virtuallength = 0; // virtualLength
439439

440440
void setPixelColorXY_slow(int x, int y, uint32_t c); // set relative pixel within segment with color - full slow version
441441
#else
@@ -482,7 +482,7 @@ typedef struct Segment {
482482

483483
public:
484484

485-
Segment(uint16_t sStart=0, uint16_t sStop=30) :
485+
Segment(uint32_t sStart=0, uint32_t sStop=30) :
486486
start(sStart),
487487
stop(sStop),
488488
offset(0),
@@ -522,7 +522,7 @@ typedef struct Segment {
522522
//refreshLightCapabilities();
523523
}
524524

525-
Segment(uint16_t sStartX, uint16_t sStopX, uint16_t sStartY, uint16_t sStopY) : Segment(sStartX, sStopX) {
525+
Segment(uint32_t sStartX, uint32_t sStopX, uint32_t sStartY, uint32_t sStopY) : Segment(sStartX, sStopX) {
526526
startY = sStartY;
527527
stopY = sStopY;
528528
}
@@ -570,10 +570,10 @@ typedef struct Segment {
570570
inline bool hasRGB(void) const { return _isRGB; }
571571
inline bool hasWhite(void) const { return _hasW; }
572572
inline bool isCCT(void) const { return _isCCT; }
573-
inline uint16_t width(void) const { return (stop > start) ? (stop - start) : 0; } // segment width in physical pixels (length if 1D)
574-
inline uint16_t height(void) const { return (stopY > startY) ? (stopY - startY) : 0; } // segment height (if 2D) in physical pixels // WLEDMM make sure its always > 0
573+
inline uint32_t width(void) const { return (stop > start) ? (stop - start) : 0; } // segment width in physical pixels (length if 1D)
574+
inline uint32_t height(void) const { return (stopY > startY) ? (stopY - startY) : 0; } // segment height (if 2D) in physical pixels // WLEDMM make sure its always > 0
575575
inline uint32_t length(void) const { return width() * height(); } // segment length (count) in physical pixels // WLEDMM fishy ... need to double-check if this is correct
576-
inline uint16_t groupLength(void) const { return max(1, grouping + spacing); } // WLEDMM length = 0 could lead to div/0 in virtualWidth() and virtualHeight()
576+
inline uint32_t groupLength(void) const { return max(1, grouping + spacing); } // WLEDMM length = 0 could lead to div/0 in virtualWidth() and virtualHeight()
577577
inline uint8_t getLightCapabilities(void) const { return _capabilities; }
578578

579579
static size_t getUsedSegmentData(void) { return _usedSegmentData; } // WLEDMM size_t
@@ -582,7 +582,7 @@ typedef struct Segment {
582582
void allocLeds(); //WLEDMM
583583
inline static const CRGBPalette16 &getCurrentPalette(void) { return Segment::_currentPalette; }
584584

585-
void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1);
585+
void setUp(uint32_t i1, uint32_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1);
586586
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
587587
void setCCT(uint16_t k);
588588
void setOpacity(uint8_t o);
@@ -636,11 +636,11 @@ typedef struct Segment {
636636
void setCurrentPalette(void);
637637

638638
// 1D strip
639-
uint16_t calc_virtualLength(void) const;
639+
uint32_t calc_virtualLength(void) const;
640640
#ifndef WLEDMM_FASTPATH
641-
inline uint16_t virtualLength(void) const {return calc_virtualLength();}
641+
inline uint32_t virtualLength(void) const {return calc_virtualLength();}
642642
#else
643-
inline uint16_t virtualLength(void) const {return _virtuallength;}
643+
inline uint32_t virtualLength(void) const {return _virtuallength;}
644644
#endif
645645
void setPixelColor(uint32_t n, uint32_t c); // set relative pixel within segment with color
646646
inline void setPixelColor(uint32_t n, byte r, byte g, byte b, byte w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } // automatically inline
@@ -694,15 +694,15 @@ typedef struct Segment {
694694
inline uint16_t virtualWidth() const { return(_2dWidth);} // WLEDMM get pre-calculated virtualWidth
695695
inline uint16_t virtualHeight() const { return(_2dHeight);} // WLEDMM get pre-calculated virtualHeight
696696

697-
uint16_t calc_virtualWidth() const {
698-
uint_fast16_t groupLen = groupLength();
699-
uint_fast16_t vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen;
697+
uint32_t calc_virtualWidth() const {
698+
uint_fast32_t groupLen = groupLength();
699+
uint_fast32_t vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen;
700700
if (mirror) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED
701701
return vWidth;
702702
}
703-
uint16_t calc_virtualHeight() const {
704-
uint_fast16_t groupLen = groupLength();
705-
uint_fast16_t vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen;
703+
uint32_t calc_virtualHeight() const {
704+
uint_fast32_t groupLen = groupLength();
705+
uint_fast32_t vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen;
706706
if (mirror_y) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED
707707
return vHeight;
708708
}
@@ -713,10 +713,16 @@ typedef struct Segment {
713713
void deletejMap(); //WLEDMM jMap
714714

715715
#ifndef WLED_DISABLE_2D
716-
[[gnu::hot]] inline uint16_t XY(uint_fast16_t x, uint_fast16_t y) const { // support function to get relative index within segment (for leds[]) // WLEDMM inline for speed
717-
uint_fast16_t width = max(uint16_t(1), virtualWidth()); // segment width in logical pixels -- softhack007 avoid div/0
718-
uint_fast16_t height = max(uint16_t(1), virtualHeight()); // segment height in logical pixels -- softhack007 avoid div/0
719-
return (x%width) + (y%height) * width;
716+
// [[gnu::hot]] inline uint32_t XY(uint_fast16_t x, uint_fast16_t y) const { // support function to get relative index within segment (for leds[]) // WLEDMM inline for speed
717+
// uint_fast16_t width = max(uint16_t(1), virtualWidth()); // segment width in logical pixels -- softhack007 avoid div/0
718+
// uint_fast16_t height = max(uint16_t(1), virtualHeight()); // segment height in logical pixels -- softhack007 avoid div/0
719+
// return (x%width) + (y%height) * width;
720+
// }
721+
722+
[[gnu::hot]] inline uint32_t XY(uint_fast16_t x, uint_fast16_t y) const {
723+
uint32_t width = max(uint16_t(1), virtualWidth());
724+
uint32_t height = max(uint16_t(1), virtualHeight());
725+
return (x % width) + (y % height) * width;
720726
}
721727

722728
#ifdef WLEDMM_FASTPATH
@@ -984,14 +990,16 @@ class WS2812FX { // 96 bytes
984990
uint16_t
985991
ablMilliampsMax,
986992
currentMilliamps,
993+
getFps() const;
994+
995+
uint32_t
987996
getLengthPhysical(void) const,
988997
getLengthPhysical2(void) const, // WLEDMM total length including HUB75, network busses excluded
989-
__attribute__((pure)) getLengthTotal(void) const, // will include virtual/nonexistent pixels in matrix //WLEDMM attribute added
990-
getFps() const;
998+
__attribute__((pure)) getLengthTotal(void) const; // will include virtual/nonexistent pixels in matrix //WLEDMM attribute added
991999

9921000
inline uint16_t getFrameTime(void) const { return _frametime; }
9931001
inline uint16_t getMinShowDelay(void) const { return MIN_SHOW_DELAY; }
994-
inline uint16_t getLength(void) const { return _length; } // 2D matrix may have less pixels than W*H
1002+
inline uint32_t getLength(void) const { return _length; } // 2D matrix may have less pixels than W*H
9951003
inline uint16_t getTransition(void) const { return _transitionDur; }
9961004

9971005
uint32_t

wled00/FX_2Dfcn.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ void WS2812FX::setUpMatrix() {
192192
void IRAM_ATTR __attribute__((hot)) WS2812FX::setPixelColorXY_fast(int x, int y, uint32_t col) //WLEDMM: IRAM_ATTR conditionally
193193
{
194194
uint_fast32_t index = y * Segment::maxWidth + x;
195+
195196
#ifndef WLEDMM_REMAP_AT_OUTPUT
196197
if (this->customMappingTable != nullptr && index < this->customMappingSize) {
197198
index = customMappingTable[index];
@@ -307,8 +308,8 @@ void IRAM_ATTR __attribute__((hot)) Segment::setPixelColorXY_fast(int x, int y,
307308
if (simpleSegment) return; // WLEDMM shortcut when no mirroring needed
308309

309310
// handle mirroring - minimum width/height is 1 !!!
310-
const int_fast16_t wid_ = max(1,stop - start);
311-
const int_fast16_t hei_ = max(1, stopY - startY);
311+
const int_fast32_t wid_ = max((uint32_t)1,stop - start);
312+
const int_fast32_t hei_ = max((uint32_t)1, stopY - startY);
312313
if (mirror) { //set the corresponding horizontally mirrored pixel
313314
if (transpose) strip.setPixelColorXY_fast(start + x, startY + hei_ - y - 1, scaled_col);
314315
else strip.setPixelColorXY_fast(start + wid_ - x - 1, startY + y, scaled_col);
@@ -369,9 +370,9 @@ void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col) //WLEDMM:
369370
return;
370371
}
371372

372-
const uint_fast16_t glen_ = groupLength(); // WLEDMM optimization
373-
const uint_fast16_t wid_ = max(uint16_t(1), width());
374-
const uint_fast16_t hei_ = max(uint16_t(1), height());
373+
const uint_fast32_t glen_ = groupLength(); // WLEDMM optimization
374+
const uint_fast32_t wid_ = max(uint32_t(1), width());
375+
const uint_fast32_t hei_ = max(uint32_t(1), height());
375376

376377
x *= glen_; // expand to physical pixels
377378
y *= glen_; // expand to physical pixels
@@ -380,7 +381,7 @@ void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col) //WLEDMM:
380381
const int grp_ = grouping; // WLEDMM optimization
381382
for (int j = 0; j < grp_; j++) { // groupping vertically
382383
for (int g = 0; g < grp_; g++) { // groupping horizontally
383-
uint_fast16_t xX = (x+g), yY = (y+j); //WLEDMM: use fast types
384+
uint_fast32_t xX = (x+g), yY = (y+j); //WLEDMM: use fast types
384385
if (xX >= wid_ || yY >= hei_) continue; // we have reached one dimension's end
385386

386387
strip.setPixelColorXY(start + xX, startY + yY, col);

wled00/FX_fcn.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ void Segment::handleTransition() {
499499
}
500500
}
501501

502-
void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y) {
502+
void Segment::setUp(uint32_t i1, uint32_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y) {
503503
//return if neither bounds nor grouping have changed
504504
bool boundsUnchanged = (start == i1 && stop == i2);
505505
#ifndef WLED_DISABLE_2D
@@ -518,7 +518,7 @@ void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t
518518
return;
519519
}
520520
if (i1 < Segment::maxWidth || (i1 >= Segment::maxWidth*Segment::maxHeight && i1 < strip.getLengthTotal())) start = i1; // Segment::maxWidth equals strip.getLengthTotal() for 1D
521-
stop = i2 > Segment::maxWidth*Segment::maxHeight ? min(i2,strip.getLengthTotal()) : (i2 > Segment::maxWidth ? Segment::maxWidth : max((uint16_t)1,i2)); // WLEDMM: use native min/max
521+
stop = i2 > Segment::maxWidth*Segment::maxHeight ? min(i2,strip.getLengthTotal()) : (i2 > Segment::maxWidth ? Segment::maxWidth : max((uint32_t)1,i2)); // WLEDMM: use native min/max
522522
startY = 0;
523523
stopY = 1;
524524
#ifndef WLED_DISABLE_2D
@@ -850,12 +850,12 @@ static int getPinwheelLength(int vW, int vH) {
850850
#endif
851851

852852
// 1D strip
853-
uint16_t Segment::calc_virtualLength() const {
853+
uint32_t Segment::calc_virtualLength() const {
854854
#ifndef WLED_DISABLE_2D
855855
if (is2D()) {
856-
uint16_t vW = calc_virtualWidth();
857-
uint16_t vH = calc_virtualHeight();
858-
uint16_t vLen = vW * vH; // use all pixels from segment
856+
uint32_t vW = calc_virtualWidth();
857+
uint32_t vH = calc_virtualHeight();
858+
uint32_t vLen = vW * vH; // use all pixels from segment
859859
switch (map1D2D) {
860860
case M12_pBar:
861861
vLen = vH;
@@ -891,8 +891,8 @@ uint16_t Segment::calc_virtualLength() const {
891891
return vLen;
892892
}
893893
#endif
894-
uint16_t groupLen = groupLength();
895-
uint16_t vLength = (length() + groupLen - 1) / groupLen;
894+
uint32_t groupLen = groupLength();
895+
uint32_t vLength = (length() + groupLen - 1) / groupLen;
896896
if (mirror && width() > 1) vLength = (vLength + 1) /2; // divide by 2 if mirror, leave at least a single LED // WLEDMM bugfix for pseudo 2d strips
897897
return vLength;
898898
}
@@ -1738,7 +1738,7 @@ void WS2812FX::finalizeInit(void)
17381738
_hasWhiteChannel |= bus->hasWhite();
17391739
//refresh is required to remain off if at least one of the strips requires the refresh.
17401740
_isOffRefreshRequired |= bus->isOffRefreshRequired();
1741-
uint16_t busEnd = bus->getStart() + bus->getLength();
1741+
uint32_t busEnd = bus->getStart() + bus->getLength();
17421742
if (busEnd > _length) _length = busEnd;
17431743
#ifdef ESP8266
17441744
if ((!IS_DIGITAL(bus->getType()) || IS_2PIN(bus->getType()))) continue;
@@ -2165,14 +2165,14 @@ uint8_t WS2812FX::getActiveSegmentsNum(void) const {
21652165
return c;
21662166
}
21672167

2168-
uint16_t WS2812FX::getLengthTotal(void) const { // WLEDMM fast int types
2169-
uint_fast16_t len = Segment::maxWidth * Segment::maxHeight; // will be _length for 1D (see finalizeInit()) but should cover whole matrix for 2D
2168+
uint32_t WS2812FX::getLengthTotal(void) const { // WLEDMM fast int types
2169+
uint_fast32_t len = Segment::maxWidth * Segment::maxHeight; // will be _length for 1D (see finalizeInit()) but should cover whole matrix for 2D
21702170
if (isMatrix && _length > len) len = _length; // for 2D with trailing strip
21712171
return len;
21722172
}
21732173

2174-
uint16_t WS2812FX::getLengthPhysical(void) const { // WLEDMM fast int types
2175-
uint_fast16_t len = 0;
2174+
uint32_t WS2812FX::getLengthPhysical(void) const { // WLEDMM fast int types
2175+
uint_fast32_t len = 0;
21762176
for (unsigned b = 0; b < busses.getNumBusses(); b++) { // WLEDMM use native (fast) types
21772177
Bus *bus = busses.getBus(b);
21782178
auto btype = bus->getType();
@@ -2183,8 +2183,8 @@ uint16_t WS2812FX::getLengthPhysical(void) const { // WLEDMM fast int types
21832183
}
21842184

21852185
//WLEDMM - getLengthPhysical plus plysical busses not supporting ABL (i.e. HUB75)
2186-
uint16_t WS2812FX::getLengthPhysical2(void) const {
2187-
uint_fast16_t len = 0;
2186+
uint32_t WS2812FX::getLengthPhysical2(void) const {
2187+
uint_fast32_t len = 0;
21882188
for (unsigned b = 0; b < busses.getNumBusses(); b++) {
21892189
Bus *bus = busses.getBus(b);
21902190
auto btype = bus->getType();

0 commit comments

Comments
 (0)