1818#endif
1919#include " const.h"
2020#include " pin_manager.h"
21- #include " bus_wrapper.h"
2221#include " bus_manager.h"
22+ #include " bus_wrapper.h"
2323
2424extern bool cctICused;
25+ extern bool useParallelI2S;
2526
2627// colors.cpp
2728uint32_t colorBalanceFromKelvin (uint16_t kelvin, uint32_t rgb);
@@ -121,7 +122,7 @@ uint8_t *Bus::allocateData(size_t size) {
121122}
122123
123124
124- BusDigital::BusDigital (BusConfig &bc, uint8_t nr, const ColorOrderMap &com)
125+ BusDigital::BusDigital (const BusConfig &bc, uint8_t nr, const ColorOrderMap &com)
125126: Bus(bc.type, bc.start, bc.autoWhite, bc.count, bc.reversed, (bc.refreshReq || bc.type == TYPE_TM1814))
126127, _skip(bc.skipAmount) // sacrificial pixels
127128, _colorOrder(bc.colorOrder)
@@ -220,7 +221,7 @@ void BusDigital::show() {
220221 if (!_valid) return ;
221222
222223 uint8_t cctWW = 0 , cctCW = 0 ;
223- unsigned newBri = estimateCurrentAndLimitBri (); // will fill _milliAmpsTotal
224+ unsigned newBri = estimateCurrentAndLimitBri (); // will fill _milliAmpsTotal (TODO: could use PolyBus::CalcTotalMilliAmpere())
224225 if (newBri < _bri) PolyBus::setBrightness (_busPtr, _iType, newBri); // limit brightness to stay within current limits
225226
226227 if (_data) {
@@ -246,6 +247,7 @@ void BusDigital::show() {
246247 // TODO: there is an issue if CCT is calculated from RGB value (_cct==-1), we cannot do that with double buffer
247248 Bus::_cct = _data[offset+channels-1 ];
248249 Bus::calculateCCT (c, cctWW, cctCW);
250+ if (_type == TYPE_WS2812_WWA) c = RGBW32 (cctWW, cctCW, 0 , W (c)); // may need swapping
249251 }
250252 unsigned pix = i;
251253 if (_reversed) pix = _len - pix -1 ;
@@ -331,8 +333,8 @@ void IRAM_ATTR BusDigital::setPixelColor(unsigned pix, uint32_t c) {
331333 uint8_t cctWW = 0 , cctCW = 0 ;
332334 Bus::calculateCCT (c, cctWW, cctCW);
333335 wwcw = (cctCW<<8 ) | cctWW;
336+ if (_type == TYPE_WS2812_WWA) c = RGBW32 (cctWW, cctCW, 0 , W (c)); // may need swapping
334337 }
335-
336338 PolyBus::setPixelColor (_busPtr, _iType, pix, c, co, wwcw);
337339 }
338340}
@@ -364,16 +366,24 @@ uint32_t IRAM_ATTR BusDigital::getPixelColor(unsigned pix) const {
364366 case 2 : c = RGBW32 (b, b, b, b); break ;
365367 }
366368 }
369+ if (_type == TYPE_WS2812_WWA) {
370+ uint8_t w = R (c) | G (c);
371+ c = RGBW32 (w, w, 0 , w);
372+ }
367373 return c;
368374 }
369375}
370376
371- uint8_t BusDigital::getPins (uint8_t * pinArray) const {
377+ unsigned BusDigital::getPins (uint8_t * pinArray) const {
372378 unsigned numPins = is2Pin (_type) + 1 ;
373379 if (pinArray) for (unsigned i = 0 ; i < numPins; i++) pinArray[i] = _pins[i];
374380 return numPins;
375381}
376382
383+ unsigned BusDigital::getBufferSize () const {
384+ return isOk () ? PolyBus::getDataSize (_busPtr, _iType) : 0 ;
385+ }
386+
377387void BusDigital::setColorOrder (uint8_t colorOrder) {
378388 // upper nibble contains W swap information
379389 if ((colorOrder & 0x0F ) > 5 ) return ;
@@ -397,7 +407,7 @@ std::vector<LEDType> BusDigital::getLEDTypes() {
397407 {TYPE_SM16825, " D" , PSTR (" SM16825 RGBCW" )},
398408 {TYPE_WS2812_1CH_X3, " D" , PSTR (" WS2811 White" )},
399409 // {TYPE_WS2812_2CH_X3, "D", PSTR("WS2811 CCT")}, // not implemented
400- // {TYPE_WS2812_WWA, "D", PSTR("WS2811 WWA")}, // not implemented
410+ {TYPE_WS2812_WWA, " D" , PSTR (" WS2811 WWA" )}, // amber ignored
401411 {TYPE_WS2801, " 2P" , PSTR (" WS2801" )},
402412 {TYPE_APA102, " 2P" , PSTR (" APA102" )},
403413 {TYPE_LPD8806, " 2P" , PSTR (" LPD8806" )},
@@ -418,8 +428,9 @@ void BusDigital::cleanup() {
418428 _valid = false ;
419429 _busPtr = nullptr ;
420430 if (_data != nullptr ) freeData ();
421- PinManager::deallocatePin (_pins[1 ], PinOwner::BusDigital);
422- PinManager::deallocatePin (_pins[0 ], PinOwner::BusDigital);
431+ PinManager::deallocateMultiplePins (_pins, 2 , PinOwner::BusDigital);
432+ // PinManager::deallocatePin(_pins[1], PinOwner::BusDigital);
433+ // PinManager::deallocatePin(_pins[0], PinOwner::BusDigital);
423434}
424435
425436
@@ -448,7 +459,7 @@ void BusDigital::cleanup() {
448459 #endif
449460#endif
450461
451- BusPwm::BusPwm (BusConfig &bc)
462+ BusPwm::BusPwm (const BusConfig &bc)
452463: Bus(bc.type, bc.start, bc.autoWhite, 1 , bc.reversed, bc.refreshReq) // hijack Off refresh flag to indicate usage of dithering
453464{
454465 if (!isPWM (bc.type )) return ;
@@ -610,7 +621,7 @@ void BusPwm::show() {
610621 }
611622}
612623
613- uint8_t BusPwm::getPins (uint8_t * pinArray) const {
624+ unsigned BusPwm::getPins (uint8_t * pinArray) const {
614625 if (!_valid) return 0 ;
615626 unsigned numPins = numPWMPins (_type);
616627 if (pinArray) for (unsigned i = 0 ; i < numPins; i++) pinArray[i] = _pins[i];
@@ -646,7 +657,7 @@ void BusPwm::deallocatePins() {
646657}
647658
648659
649- BusOnOff::BusOnOff (BusConfig &bc)
660+ BusOnOff::BusOnOff (const BusConfig &bc)
650661: Bus(bc.type, bc.start, bc.autoWhite, 1 , bc.reversed)
651662, _onoffdata(0 )
652663{
@@ -686,7 +697,7 @@ void BusOnOff::show() {
686697 digitalWrite (_pin, _reversed ? !(bool )_data[0 ] : (bool )_data[0 ]);
687698}
688699
689- uint8_t BusOnOff::getPins (uint8_t * pinArray) const {
700+ unsigned BusOnOff::getPins (uint8_t * pinArray) const {
690701 if (!_valid) return 0 ;
691702 if (pinArray) pinArray[0 ] = _pin;
692703 return 1 ;
@@ -699,7 +710,7 @@ std::vector<LEDType> BusOnOff::getLEDTypes() {
699710 };
700711}
701712
702- BusNetwork::BusNetwork (BusConfig &bc)
713+ BusNetwork::BusNetwork (const BusConfig &bc)
703714: Bus(bc.type, bc.start, bc.autoWhite, bc.count)
704715, _broadcastLock(false )
705716{
@@ -750,7 +761,7 @@ void BusNetwork::show() {
750761 _broadcastLock = false ;
751762}
752763
753- uint8_t BusNetwork::getPins (uint8_t * pinArray) const {
764+ unsigned BusNetwork::getPins (uint8_t * pinArray) const {
754765 if (pinArray) for (unsigned i = 0 ; i < 4 ; i++) pinArray[i] = _client[i];
755766 return 4 ;
756767}
@@ -778,7 +789,7 @@ void BusNetwork::cleanup() {
778789
779790
780791// utility to get the approx. memory usage of a given BusConfig
781- uint32_t BusManager::memUsage (BusConfig &bc) {
792+ uint32_t BusManager::memUsage (const BusConfig &bc) {
782793 if (Bus::isOnOff (bc.type ) || Bus::isPWM (bc.type )) return OUTPUT_MAX_PINS;
783794
784795 unsigned len = bc.count + bc.skipAmount ;
@@ -791,19 +802,23 @@ uint32_t BusManager::memUsage(BusConfig &bc) {
791802 multiplier = 5 ;
792803 }
793804 #else // ESP32 RMT uses double buffer, parallel I2S uses 8x buffer (3 times)
794- multiplier = PolyBus::isParallelI2S1Output () ? 24 : 2 ;
805+ #ifndef CONFIG_IDF_TARGET_ESP32C3
806+ multiplier = useParallelI2S ? 24 : 2 ;
807+ #else
808+ multiplier = 2 ;
809+ #endif
795810 #endif
796811 }
797812 return (len * multiplier + bc.doubleBuffer * (bc.count + bc.skipAmount )) * channels;
798813}
799814
800- uint32_t BusManager::memUsage ( unsigned maxChannels, unsigned maxCount, unsigned minBuses ) {
801- // ESP32 RMT uses double buffer, parallel I2S uses 8x buffer (3 times)
802- unsigned multiplier = PolyBus::isParallelI2S1Output () ? 3 : 2 ;
803- return (maxChannels * maxCount * minBuses * multiplier) ;
815+ unsigned BusManager::getTotalBuffers ( ) {
816+ unsigned size = 0 ;
817+ for ( unsigned i= 0 ; i<numBusses; i++) size += busses[i]-> getBufferSize () ;
818+ return size ;
804819}
805820
806- int BusManager::add (BusConfig &bc) {
821+ int BusManager::add (const BusConfig &bc) {
807822 if (getNumBusses () - getNumVirtualBusses () >= WLED_MAX_BUSSES) return -1 ;
808823 if (Bus::isVirtual (bc.type )) {
809824 busses[numBusses] = new BusNetwork (bc);
@@ -843,18 +858,20 @@ String BusManager::getLEDTypesJSONString() {
843858}
844859
845860void BusManager::useParallelOutput () {
846- _parallelOutputs = 8 ; // hardcoded since we use NPB I2S x8 methods
847861 PolyBus::setParallelI2S1Output ();
848862}
849863
864+ bool BusManager::hasParallelOutput () {
865+ return PolyBus::isParallelI2S1Output ();
866+ }
867+
850868// do not call this method from system context (network callback)
851869void BusManager::removeAll () {
852870 DEBUG_PRINTLN (F (" Removing all." ));
853871 // prevents crashes due to deleting busses while in use.
854872 while (!canAllShow ()) yield ();
855873 for (unsigned i = 0 ; i < numBusses; i++) delete busses[i];
856874 numBusses = 0 ;
857- _parallelOutputs = 1 ;
858875 PolyBus::setParallelI2S1Output (false );
859876}
860877
@@ -876,9 +893,10 @@ void BusManager::esp32RMTInvertIdle() {
876893 if (u > 3 ) return ;
877894 rmt = u;
878895 #else
879- if (u < _parallelOutputs) continue ;
880- if (u >= _parallelOutputs + 8 ) return ; // only 8 RMT channels
881- rmt = u - _parallelOutputs;
896+ unsigned numI2S = 1 + PolyBus::isParallelI2S1Output ()*7 ;
897+ if (u < numI2S) continue ;
898+ if (u >= numI2S + 8 ) return ; // only 8 RMT channels
899+ rmt = u - numI2S;
882900 #endif
883901 if (busses[u]->getLength ()==0 || !busses[u]->isDigital () || busses[u]->is2Pin ()) continue ;
884902 // assumes that bus number to rmt channel mapping stays 1:1
@@ -994,7 +1012,7 @@ uint16_t BusManager::getTotalLength() {
9941012 return len;
9951013}
9961014
997- bool PolyBus::useParallelI2S = false ;
1015+ bool PolyBus::_useParallelI2S = false ;
9981016
9991017// Bus static member definition
10001018int16_t Bus::_cct = -1 ;
@@ -1008,4 +1026,3 @@ Bus* BusManager::busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES];
10081026ColorOrderMap BusManager::colorOrderMap = {};
10091027uint16_t BusManager::_milliAmpsUsed = 0 ;
10101028uint16_t BusManager::_milliAmpsMax = ABL_MILLIAMPS_DEFAULT;
1011- uint8_t BusManager::_parallelOutputs = 1 ;
0 commit comments