diff --git a/platformio.ini b/platformio.ini index 6ae4c79091..03a810fca7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -309,6 +309,7 @@ build_flags = -g ; -D WLEDMM_TWOPATH ;; use I2S1 as the second bus --> ~15% faster on "V3" builds - may flicker a bit more ; -D WLEDMM_SLOWPATH ;; don't use I2S for LED bus ; -DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3 + -D WLED_ENABLE_I2SCLOCKLESS default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv ;; WLED standard for 4MB flash: 1.4MB firmware, 1MB filesystem ;default_partitions = tools/WLED_ESP32_4MB_256KB_FS.csv ;; WLEDMM alternative for 4MB flash: 1.8MB firmware, 256KB filesystem (esptool erase_flash needed before changing) @@ -326,6 +327,7 @@ lib_deps = https://github.com/softhack007/LITTLEFS-threadsafe.git#master makuna/NeoPixelBus @ 2.7.5 ;; makuna/NeoPixelBus @ 2.7.9 ;; experimental + ${common_mm.I2SClockless_libs} ${env.lib_deps} ;; Compatibility with upstream --> you should prefer using ${common_mm.build_flags_S} and ${common_mm.lib_deps_S} @@ -363,6 +365,7 @@ lib_depsV4 = makuna/NeoPixelBus @ 2.7.5 ;; makuna/NeoPixelBus @ 2.7.9 ;; experimental ${common_mm.HUB75_lib_deps} + ${common_mm.I2SClockless_libs} ${env.lib_deps} @@ -456,12 +459,14 @@ build_flags = -g -D CONFIG_ASYNC_TCP_TASK_STACK_SIZE=9472 ;; WLEDMM increase stack by 1.25Kb, as audioreactive needs bigger SETTINGS_STACK_BUF_SIZE -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_DFU_ON_BOOT=0 -DCO + -D WLED_ENABLE_I2SCLOCKLESS ;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry: ;; ARDUINO_USB_MODE, ARDUINO_USB_CDC_ON_BOOT lib_deps = https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 makuna/NeoPixelBus @ 2.7.5 ;; makuna/NeoPixelBus @ 2.7.9 ;; experimental + https://github.com/netmindz/I2SClockLessLedDriveresp32s3#67341fc ;; WLED-compat ${env.lib_deps} @@ -1018,7 +1023,7 @@ build_disable_sync_interfaces = -D WLED_DISABLE_ADALIGHT ;; WLEDMM this board does not have a serial-to-USB chip. Better to disable serial protocols, to avoid crashes (see upstream #3128) -D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only -AR_build_flags = -D USERMOD_AUDIOREACTIVE -D UM_AUDIOREACTIVE_USE_NEW_FFT ;; WLEDMM audioreactive usermod, licensed under GPLv3 +AR_build_flags = ;; -D USERMOD_AUDIOREACTIVE -D UM_AUDIOREACTIVE_USE_NEW_FFT ;; WLEDMM audioreactive usermod, licensed under GPLv3 AR_lib_deps = https://github.com/softhack007/arduinoFFT.git#develop @ 1.9.2 ;; used for USERMOD_AUDIOREACTIVE - optimized version, 10% faster on -S2/-C3 animartrix_build_flags = -D USERMOD_ANIMARTRIX ;; WLEDMM usermod: CC BY-NC 3.0 licensed effects by Stefan Petrick @@ -1035,6 +1040,8 @@ HUB75_build_flags = HUB75_lib_deps = https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA.git @ 3.0.10 HUB75_lib_ignore = ESP32 HUB75 LED MATRIX PANEL DMA Display ;; to remove the HUB75 lib dependancy (saves a few bytes) +I2SClockless_libs = https://github.com/hpwit/I2SClocklessLedDriver#333754b + NetDebug_build_flags = ;; WLEDMM: only setting WLED_DEBUG_HOST is enough, ip and port can be defined in sync settings as well -D WLED_DEBUG_HOST='"192.168.x.x"' ;; to send debug messages over network to host 192.168.x.y - FQDN is also possible @@ -1049,7 +1056,7 @@ build_flags_S = ; -D WLED_DISABLE_2D ;; un-comment to build a firmware without 2D matrix support ; -D WLED_USE_CIE_BRIGHTNESS_TABLE ;; experimental: use different color / brightness lookup table ${common_mm.AR_build_flags} ; use latest (upstream) FFTLib, instead of older library modified by blazoncek. Slightly faster, more accurate, needs 2KB RAM extra - -D USERMOD_AUTO_PLAYLIST + ; -D USERMOD_AUTO_PLAYLIST ; -D USERMOD_ARTIFX ;; WLEDMM usermod - temporarily moved into "_M", due to problems in "_S" when compiling with -O2 -D WLEDMM_FASTPATH ;; WLEDMM experimental option. Reduces audio lag (latency), and allows for faster LED framerates. May break compatibility with previous versions. ; -D WLED_DEBUG_HEAP ;; WLEDMM enable heap debugging @@ -1163,6 +1170,7 @@ build_flags = ${common.build_flags} ${common_mm.build_flags_S} ${common_mm.build ;-Wstack-usage=2732 ;; warn if a function needs more that 30% of availeable stack ("stack usage might be unbounded", "stack usage is 2824 bytes") ;-Wsuggest-attribute=const -Wsuggest-attribute=pure ;; ask compiler for hints on attributes ${common_mm.DMXin_build_flags} + lib_deps = ${common_mm.lib_deps_S} ;; do not include ${esp32.lib_depsV4} here !!!! ${common_mm.DMXin_lib_deps} esp32_build_flags = ${esp32.build_flagsV4} ${esp32_4MB_V4_S_base.build_flags} ;; this is for esp32 only, including specific "V4" flags diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index fff5ecb384..38fbdc624a 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -482,7 +482,63 @@ void BusNetwork::cleanup() { if (_data != nullptr) free(_data); _data = nullptr; } +// *************************************************************************** +#ifdef WLED_ENABLE_I2SCLOCKLESS + +BusI2SClocklessLedDriver::BusI2SClocklessLedDriver(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) { + USER_PRINTF("Construct BusI2SClocklessLedDriver\n"); + _valid = false; + if (!pinManager.allocatePin(bc.pins[0], true, PinOwner::BusDigital)) return; + _pins[0] = bc.pins[0]; + _pins[1] = bc.pins[1]; // TODO: remove once the UI knows we don't need clock pin + USER_PRINTF("initled using pin %d for %d LEDs\n", _pins[0], bc.count); + switch(bc.colorOrder) { + case 0: color = ORDER_GRB; break; + case 1: color = ORDER_RGB; break; + case 2: color = ORDER_BGR; break; + } + + #ifdef CONFIG_IDF_TARGET_ESP32S3 + USER_PRINTLN("no color order support for I2SClockLessLedDriveresp32s3"); + driver.initled((uint8_t*)leds, _pins, 1, bc.count); + #else + driver.initled((uint8_t*)leds, _pins, 1, bc.count, color); + #endif + + _len = bc.count; + _valid = true; + } +void BusI2SClocklessLedDriver::setPixelColor(uint16_t pix, uint32_t c) { + if(_valid) { + #ifdef CONFIG_IDF_TARGET_ESP32S3 + // TODO - use this.color to use the right ordering + this->leds[pix] = CRGB(R(c), G(c), B(c)); + #else + this->driver.setPixel(pix, R(c), G(c), B(c)); + #endif + } +} + +void BusI2SClocklessLedDriver::show() { + if(_valid) driver.showPixels(); +} + +void BusI2SClocklessLedDriver::setBrightness(uint8_t b, bool immediate) { + if(_valid) driver.setBrightness(b); +} + +uint8_t BusI2SClocklessLedDriver::getPins(uint8_t* pinArray) { + pinArray[0] = _pins[0]; + pinArray[1] = _pins[1]; + return 2; +} + +void BusI2SClocklessLedDriver::cleanup() { + pinManager.deallocatePin(_pins[0], PinOwner::BusDigital); +} + +#endif // *************************************************************************** #ifdef WLED_ENABLE_HUB75MATRIX @@ -742,6 +798,10 @@ int BusManager::add(BusConfig &bc) { } else if (bc.type >= TYPE_HUB75MATRIX && bc.type <= (TYPE_HUB75MATRIX + 10)) { DEBUG_PRINTLN("BusManager::add - Adding BusHub75Matrix"); busses[numBusses] = new BusHub75Matrix(bc); +#endif +#ifdef WLED_ENABLE_I2SCLOCKLESS + } else if (bc.type == TYPE_I2SCL) { + busses[numBusses] = new BusI2SClocklessLedDriver(bc); #endif } else if (IS_DIGITAL(bc.type)) { busses[numBusses] = new BusDigital(bc, numBusses, colorOrderMap); diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 0bfd3e04de..a9ebb2ca39 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -5,6 +5,16 @@ #include #include #endif + +#ifdef WLED_ENABLE_I2SCLOCKLESS +#ifdef CONFIG_IDF_TARGET_ESP32S3 +#include "I2SClockLessLedDriveresp32s3.h" +#include +#else +#include "I2SClocklessLedDriver.h" +#endif +#endif + /* * Class for addressing various light types */ @@ -333,6 +343,47 @@ class BusNetwork : public Bus { byte *_data; }; +#ifdef WLED_ENABLE_I2SCLOCKLESS + +class BusI2SClocklessLedDriver : public Bus { + public: + BusI2SClocklessLedDriver(BusConfig &bc); + + uint16_t getMaxPixels() override { return 1024; }; // TODO: dynamic + bool hasRGB() { return true; } + bool hasWhite() { return false; } + + void setPixelColor(uint16_t pix, uint32_t c); + void setBrightness(uint8_t b, bool immediate); + + void show(); + + void cleanup(); + + uint8_t getPins(uint8_t* pinArray); + + uint16_t getLength() { + return _len; + } + + ~BusI2SClocklessLedDriver() { + cleanup(); + } + + private: + #ifdef CONFIG_IDF_TARGET_ESP32S3 + CRGB leds[1024]; // TODO: dynamic + I2SClocklessLedDriveresp32S3 driver; + #else + uint8_t leds[1024*3]; // TODO: dynamic + I2SClocklessLedDriver driver; + #endif + colorarrangment color; + int _pins[2] = {0,0}; +}; + +#endif + #ifdef WLED_ENABLE_HUB75MATRIX class BusHub75Matrix : public Bus { public: diff --git a/wled00/const.h b/wled00/const.h index 7857a1d33d..4e55dbdfe3 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -245,6 +245,8 @@ #define TYPE_P9813 53 #define TYPE_LPD6803 54 +#define TYPE_I2SCL 61 + #define TYPE_HUB75MATRIX 100 // 100 - 110 //Network types (master broadcast) (80-95) diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index e1979fdcaf..bef5b08e60 100644 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -375,6 +375,7 @@ \ \ \ +\ '}