Repository navigation
Added support for LSC Smart connect led strips #5177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -186,11 +186,17 @@ BusDigital::BusDigital(const BusConfig &bc, uint8_t nr) | |||||||||||||
| _hasWhite = hasWhite(bc.type); | ||||||||||||||
| _hasCCT = hasCCT(bc.type); | ||||||||||||||
| uint16_t lenToCreate = bc.count; | ||||||||||||||
| if (bc.type == TYPE_SM16703_DUAL) lenToCreate = (bc.count + _skip) * 2; // two SM16703 chips per logical pixel (including skip) | ||||||||||||||
| if (bc.type == TYPE_WS2812_1CH_X3) lenToCreate = NUM_ICS_WS2812_1CH_3X(bc.count); // only needs a third of "RGB" LEDs for NeoPixelBus | ||||||||||||||
| _busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr); | ||||||||||||||
| if (bc.type == TYPE_SM16703_DUAL) { | ||||||||||||||
| _busPtr = PolyBus::create(_iType, _pins, lenToCreate, nr); // lenToCreate already includes skip * 2 | ||||||||||||||
| } else { | ||||||||||||||
| _busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr); | ||||||||||||||
| } | ||||||||||||||
| _valid = (_busPtr != nullptr) && bc.count > 0; | ||||||||||||||
| // fix for wled#4759 | ||||||||||||||
| if (_valid) for (unsigned i = 0; i < _skip; i++) { | ||||||||||||||
| unsigned skipHW = (bc.type == TYPE_SM16703_DUAL) ? _skip * 2 : _skip; | ||||||||||||||
| if (_valid) for (unsigned i = 0; i < skipHW; i++) { | ||||||||||||||
| PolyBus::setPixelColor(_busPtr, _iType, i, 0, COL_ORDER_GRB); // set sacrificial pixels to black (CO does not matter here) | ||||||||||||||
| } | ||||||||||||||
| DEBUGBUS_PRINTF_P(PSTR("Bus: %successfully inited #%u (len:%u, type:%u (RGB:%d, W:%d, CCT:%d), pins:%u,%u [itype:%u] mA=%d/%d)\n"), | ||||||||||||||
|
|
@@ -293,6 +299,45 @@ void IRAM_ATTR BusDigital::setPixelColor(unsigned pix, uint32_t c) { | |||||||||||||
| if (Bus::_cct >= 1900) c = colorBalanceFromKelvin(Bus::_cct, c); //color correction from CCT | ||||||||||||||
| c = color_fade(c, _bri, true); // apply brightness | ||||||||||||||
|
|
||||||||||||||
| if (_type == TYPE_SM16703_DUAL) { | ||||||||||||||
| // logical pixel uses two SM16703 chips: first RGB, second WW/CW (B unused) | ||||||||||||||
| uint8_t r = R(c), g = G(c), b = B(c); | ||||||||||||||
| uint8_t ww = 0, cw = 0; | ||||||||||||||
| if (hasCCT()) Bus::calculateCCT(c, ww, cw); | ||||||||||||||
|
|
||||||||||||||
| if (BusManager::_useABL) { | ||||||||||||||
| if (_milliAmpsPerLed < 255) { | ||||||||||||||
| _colorSum += r + g + b + ww + cw; // include both chips' channels for ABL | ||||||||||||||
| } else { | ||||||||||||||
| // wacky model not expected; fall back to max RGB | ||||||||||||||
| uint8_t maxRgb = (r > g) ? ((r > b) ? r : b) : ((g > b) ? g : b); | ||||||||||||||
| _colorSum += maxRgb; | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+308
to
+315
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use a 5-channel ABL divisor for this type.
🤖 Prompt for AI Agents |
||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| unsigned logicalPix = pix; | ||||||||||||||
| if (_reversed) logicalPix = _len - pix - 1; | ||||||||||||||
| logicalPix += _skip; | ||||||||||||||
| unsigned firstIdx = logicalPix * 2; | ||||||||||||||
| unsigned secondIdx = firstIdx + 1; | ||||||||||||||
|
|
||||||||||||||
| // bounds safeguard (should not trigger if lenToCreate set correctly) | ||||||||||||||
| unsigned hwLen = (_len + _skip) * 2; | ||||||||||||||
| if (secondIdx >= hwLen) return; | ||||||||||||||
|
|
||||||||||||||
| const uint8_t coFirst = _colorOrderMap.getPixelColorOrder(logicalPix + _start, _colorOrder); | ||||||||||||||
| PolyBus::setPixelColor(_busPtr, _iType, firstIdx, c, coFirst, 0); | ||||||||||||||
|
|
||||||||||||||
| // Second chip: R=WW, G=CW by default; respect WW/CW swap flag (upper nibble of color order) | ||||||||||||||
| const uint8_t coSecond = _colorOrderMap.getPixelColorOrder(logicalPix + _start, _colorOrder); | ||||||||||||||
| bool swapWhites = true; // hardware wiring has WW/CW reversed relative to CCT | ||||||||||||||
| if ((coSecond >> 4) & 0x01) swapWhites = !swapWhites; // UI swap toggles | ||||||||||||||
| if (swapWhites) { uint8_t tmp = ww; ww = cw; cw = tmp; } | ||||||||||||||
| uint32_t wwCwColor = RGBW32(ww, cw, 0, 0); | ||||||||||||||
| PolyBus::setPixelColor(_busPtr, _iType, secondIdx, wwCwColor, COL_ORDER_GRB, 0); | ||||||||||||||
| return; | ||||||||||||||
|
Comment on lines
+331
to
+338
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential issue with WW/CW swap detection. The swap logic on line 334 checks
If the intent is to respect the WW/CW swap setting from the UI, the condition should check for value 4 specifically: - bool swapWhites = true; // hardware wiring has WW/CW reversed relative to CCT
- if ((coSecond >> 4) & 0x01) swapWhites = !swapWhites; // UI swap toggles
+ bool swapWhites = true; // hardware wiring has WW/CW reversed relative to CCT
+ if ((coSecond >> 4) == 4) swapWhites = !swapWhites; // UI WW/CW swap togglesPlease verify this matches the intended behavior for the LSC Smart Connect strips. 🤖 Prompt for AI Agents
Comment on lines
+302
to
+338
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mirror this 2:1 mapping in readback and ABL repaint paths. This new path writes one logical pixel to two hardware indices, but 🤖 Prompt for AI Agents |
||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if (BusManager::_useABL) { | ||||||||||||||
| // if using ABL, sum all color channels to estimate current and limit brightness in show() | ||||||||||||||
| uint8_t r = R(c), g = G(c), b = B(c); | ||||||||||||||
|
|
@@ -370,6 +415,7 @@ void BusDigital::setColorOrder(uint8_t colorOrder) { | |||||||||||||
| std::vector<LEDType> BusDigital::getLEDTypes() { | ||||||||||||||
| return { | ||||||||||||||
| {TYPE_WS2812_RGB, "D", PSTR("WS281x")}, | ||||||||||||||
| {TYPE_SM16703_DUAL, "D", PSTR("SM16703 RGB+CCT (2x)")}, | ||||||||||||||
| {TYPE_SK6812_RGBW, "D", PSTR("SK6812/WS2814 RGBW")}, | ||||||||||||||
| {TYPE_TM1814, "D", PSTR("TM1814")}, | ||||||||||||||
| {TYPE_WS2811_400KHZ, "D", PSTR("400kHz")}, | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update memory accounting for the doubled hardware length.
This constructor now allocates
(count + skip) * 2pixels forTYPE_SM16703_DUAL, but the existingBusConfig::memUsage()/BusManager::memUsage()paths still size the bus from logical pixels. That underestimates RAM/DMA usage for this type and can make initialization heuristics overly optimistic.🤖 Prompt for AI Agents