Skip to content

Commit 1f4d5b8

Browse files
authored
Merge pull request #108 from netmindz/ESP32-HUB75-MatrixPanel-DMA
Hub75 output
2 parents 77576f6 + f1a494f commit 1f4d5b8

File tree

8 files changed

+371
-14
lines changed

8 files changed

+371
-14
lines changed

platformio.ini

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ default_envs =
9090
esp01_1MB_S
9191
esp32_16MB_M_eth
9292
athom_music_esp32_4MB_M
93+
adafruit_matrixportal_esp32s3
9394

9495
; Go to MoonModules environments for environments
9596

@@ -336,11 +337,15 @@ build_flagsV4 = -g
336337
-D CONFIG_ASYNC_TCP_USE_WDT=0
337338
-D CONFIG_ASYNC_TCP_TASK_STACK_SIZE=9472 ;; WLEDMM increase stack by 1.25Kb, as audioreactive needs bigger SETTINGS_STACK_BUF_SIZE
338339
; -DARDUINO_USB_CDC_ON_BOOT=0 ;; mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
340+
-D NO_GFX ; Disable the use of Adafruit_GFX by the HUB75 driver
341+
339342
;;; V4.4.x libraries (without LOROL_LITTLEFS; with newer NeoPixelBus)
340343
lib_depsV4 =
341344
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 ;; WLEDMM this must be first in the list, otherwise Aircoookie/ESPAsyncWebServer pulls in an older version of AsyncTCP !!
342345
makuna/NeoPixelBus @ 2.7.5
343346
${env.lib_deps}
347+
https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA.git @ 3.0.10
348+
344349

345350
;; WLEDMM end
346351

@@ -1504,11 +1509,12 @@ build_flags = ${esp32_4MB_V4_S_base.esp32_build_flags}
15041509
; -D WLED_DEBUG
15051510
; -D SR_DEBUG
15061511
; -D MIC_LOGGER
1512+
-D WLED_ENABLE_HUB75MATRIX
1513+
15071514
lib_deps = ${esp32_4MB_V4_S_base.esp32_lib_deps}
15081515
lib_ignore = IRremoteESP8266 ; use with WLED_DISABLE_INFRARED for faster compilation
1509-
; RAM: [=== ] 25.1% (used 82176 bytes from 327680 bytes)
1510-
; Flash: [========= ] 93.8% (used 1474893 bytes from 1572864 bytes)
1511-
1516+
; RAM: [=== ] 27.7% (used 90664 bytes from 327680 bytes)
1517+
; Flash: [==========] 95.1% (used 1495497 bytes from 1572864 bytes)
15121518
; compiled with ESP-IDF 4.4.1
15131519
[env:esp32_4MB_V4_M]
15141520
extends = esp32_4MB_V4_M_base
@@ -2276,3 +2282,26 @@ lib_deps = ${esp32_4MB_V4_S_base.esp32_lib_deps}
22762282
; RAM: [=== ] 25.4% (used 83144 bytes from 327680 bytes)
22772283
; Flash: [==========] 96.4% (used 1516029 bytes from 1572864 bytes)
22782284
;
2285+
2286+
2287+
[env:adafruit_matrixportal_esp32s3]
2288+
platform = espressif32 ; latest
2289+
board = adafruit_matrixportal_esp32s3
2290+
extends = esp32_4MB_V4_S_base
2291+
build_unflags = ${env:esp32S3_8MB_M.build_unflags} ;; use the same as "normal" S3 buildenv
2292+
build_flags = ${common.build_flags} ${esp32s3.build_flags} -Wno-misleading-indentation -Wno-format-truncation
2293+
${common_mm.build_flags_S}
2294+
-D WLED_RELEASE_NAME=matrixportal_esp32s3
2295+
-DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=1 ;; for Hardware-CDC USB mode
2296+
-D WLED_DISABLE_ADALIGHT ;; disables serial protocols - recommended for Hardware-CDC USB (Serial RX will receive junk commands when RX pin is unconnected, unless its pulled down by resistor)
2297+
${common_mm.animartrix_build_flags}
2298+
${common_mm.build_disable_sync_interfaces}
2299+
-D LOLIN_WIFI_FIX ;; try this in case Wifi does not work
2300+
-D WLED_WATCHDOG_TIMEOUT=0 -D CONFIG_ASYNC_TCP_USE_WDT=0
2301+
-D WLED_USE_PSRAM -DBOARD_HAS_PSRAM ; tells WLED that PSRAM shall be used
2302+
-D WLED_ENABLE_HUB75MATRIX -D NO_GFX ;-D SPIRAM_FRAMEBUFFER
2303+
-D DEFAULT_LED_TYPE=101
2304+
lib_deps = ${esp32_4MB_V4_S_base.esp32_lib_deps}
2305+
${common_mm.animartrix_lib_deps}
2306+
lib_ignore = IRremoteESP8266 ; use with WLED_DISABLE_INFRARED for faster compilation
2307+
monitor_filters = esp32_exception_decoder

wled00/bus_manager.cpp

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,232 @@ void BusNetwork::cleanup() {
458458
_data = nullptr;
459459
}
460460

461+
// ***************************************************************************
462+
463+
#ifdef WLED_ENABLE_HUB75MATRIX
464+
465+
BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
466+
467+
mxconfig.double_buff = false; // <------------- Turn on double buffer
468+
469+
470+
fourScanPanel = nullptr;
471+
472+
switch(bc.type) {
473+
case 101:
474+
mxconfig.mx_width = 32;
475+
mxconfig.mx_height = 32;
476+
break;
477+
case 102:
478+
mxconfig.mx_width = 64;
479+
mxconfig.mx_height = 32;
480+
break;
481+
case 103:
482+
mxconfig.mx_width = 64;
483+
mxconfig.mx_height = 64;
484+
break;
485+
case 105:
486+
mxconfig.mx_width = 32 * 2;
487+
mxconfig.mx_height = 32 / 2;
488+
break;
489+
case 106:
490+
mxconfig.mx_width = 64 * 2;
491+
mxconfig.mx_height = 64 / 2;
492+
break;
493+
}
494+
495+
mxconfig.chain_length = max((u_int8_t) 1, min(bc.pins[0], (u_int8_t) 4)); // prevent bad data preventing boot due to low memory
496+
497+
if(mxconfig.mx_width >= 64 && (bc.pins[0] > 1)) {
498+
USER_PRINT("WARNING, only single panel can be used of 64 pixel boards due to memory")
499+
mxconfig.chain_length = 1;
500+
}
501+
502+
// mxconfig.driver = HUB75_I2S_CFG::SHIFTREG;
503+
504+
#if defined(ARDUINO_ADAFRUIT_MATRIXPORTAL_ESP32S3) // MatrixPortal ESP32-S3
505+
506+
// https://www.adafruit.com/product/5778
507+
508+
USER_PRINTLN("MatrixPanel_I2S_DMA - Matrix Portal S3 config");
509+
510+
mxconfig.gpio.r1 = 42;
511+
mxconfig.gpio.g1 = 41;
512+
mxconfig.gpio.b1 = 40;
513+
mxconfig.gpio.r2 = 38;
514+
mxconfig.gpio.g2 = 39;
515+
mxconfig.gpio.b2 = 37;
516+
517+
mxconfig.gpio.lat = 47;
518+
mxconfig.gpio.oe = 14;
519+
mxconfig.gpio.clk = 2;
520+
521+
mxconfig.gpio.a = 45;
522+
mxconfig.gpio.b = 36;
523+
mxconfig.gpio.c = 48;
524+
mxconfig.gpio.d = 35;
525+
mxconfig.gpio.e = 21;
526+
527+
#elif defined(ESP32_FORUM_PINOUT) // Common format for boards designed for SmartMatrix
528+
529+
USER_PRINTLN("MatrixPanel_I2S_DMA - ESP32_FORUM_PINOUT");
530+
531+
/*
532+
ESP32 with SmartMatrix's default pinout - ESP32_FORUM_PINOUT
533+
534+
https://github.com/pixelmatix/SmartMatrix/blob/teensylc/src/MatrixHardware_ESP32_V0.h
535+
536+
Can use a board like https://github.com/rorosaurus/esp32-hub75-driver
537+
*/
538+
539+
mxconfig.gpio.r1 = 2;
540+
mxconfig.gpio.g1 = 15;
541+
mxconfig.gpio.b1 = 4;
542+
mxconfig.gpio.r2 = 16;
543+
mxconfig.gpio.g2 = 27;
544+
mxconfig.gpio.b2 = 17;
545+
546+
mxconfig.gpio.lat = 26;
547+
mxconfig.gpio.oe = 25;
548+
mxconfig.gpio.clk = 22;
549+
550+
mxconfig.gpio.a = 5;
551+
mxconfig.gpio.b = 18;
552+
mxconfig.gpio.c = 19;
553+
mxconfig.gpio.d = 21;
554+
mxconfig.gpio.e = 12;
555+
556+
#else
557+
USER_PRINTLN("MatrixPanel_I2S_DMA - Default pins");
558+
/*
559+
https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA?tab=readme-ov-file
560+
561+
Boards
562+
563+
https://esp32trinity.com/
564+
https://www.electrodragon.com/product/rgb-matrix-panel-drive-interface-board-for-esp32-dma/
565+
566+
*/
567+
mxconfig.gpio.r1 = 25;
568+
mxconfig.gpio.g1 = 26;
569+
mxconfig.gpio.b1 = 27;
570+
mxconfig.gpio.r2 = 14;
571+
mxconfig.gpio.g2 = 12;
572+
mxconfig.gpio.b2 = 13;
573+
574+
mxconfig.gpio.lat = 4;
575+
mxconfig.gpio.oe = 15;
576+
mxconfig.gpio.clk = 16;
577+
578+
mxconfig.gpio.a = 23;
579+
mxconfig.gpio.b = 19;
580+
mxconfig.gpio.c = 5;
581+
mxconfig.gpio.d = 17;
582+
mxconfig.gpio.e = 18;
583+
584+
#endif
585+
586+
587+
USER_PRINTF("MatrixPanel_I2S_DMA config - %ux%u length: %u\n", mxconfig.mx_width, mxconfig.mx_height, mxconfig.chain_length);
588+
589+
// OK, now we can create our matrix object
590+
display = new MatrixPanel_I2S_DMA(mxconfig);
591+
592+
this->_len = (display->width() * display->height());
593+
594+
pinManager.allocatePin(mxconfig.gpio.r1, true, PinOwner::HUB75);
595+
pinManager.allocatePin(mxconfig.gpio.g1, true, PinOwner::HUB75);
596+
pinManager.allocatePin(mxconfig.gpio.b1, true, PinOwner::HUB75);
597+
pinManager.allocatePin(mxconfig.gpio.r2, true, PinOwner::HUB75);
598+
pinManager.allocatePin(mxconfig.gpio.g2, true, PinOwner::HUB75);
599+
pinManager.allocatePin(mxconfig.gpio.b2, true, PinOwner::HUB75);
600+
601+
pinManager.allocatePin(mxconfig.gpio.lat, true, PinOwner::HUB75);
602+
pinManager.allocatePin(mxconfig.gpio.oe, true, PinOwner::HUB75);
603+
pinManager.allocatePin(mxconfig.gpio.clk, true, PinOwner::HUB75);
604+
605+
pinManager.allocatePin(mxconfig.gpio.a, true, PinOwner::HUB75);
606+
pinManager.allocatePin(mxconfig.gpio.b, true, PinOwner::HUB75);
607+
pinManager.allocatePin(mxconfig.gpio.c, true, PinOwner::HUB75);
608+
pinManager.allocatePin(mxconfig.gpio.d, true, PinOwner::HUB75);
609+
pinManager.allocatePin(mxconfig.gpio.e, true, PinOwner::HUB75);
610+
611+
// display->setLatBlanking(4);
612+
613+
USER_PRINTLN("MatrixPanel_I2S_DMA created");
614+
// let's adjust default brightness
615+
display->setBrightness8(25); // range is 0-255, 0 - 0%, 255 - 100%
616+
617+
// Allocate memory and start DMA display
618+
if( not display->begin() ) {
619+
USER_PRINTLN("****** MatrixPanel_I2S_DMA !KABOOM! I2S memory allocation failed ***********");
620+
return;
621+
}
622+
else {
623+
_valid = true;
624+
}
625+
626+
switch(bc.type) {
627+
case 105:
628+
USER_PRINTLN("MatrixPanel_I2S_DMA FOUR_SCAN_32PX_HIGH");
629+
fourScanPanel = new VirtualMatrixPanel((*display), 1, 1, 32, 32);
630+
fourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH);
631+
fourScanPanel->setRotation(0);
632+
break;
633+
case 106:
634+
USER_PRINTLN("MatrixPanel_I2S_DMA FOUR_SCAN_64PX_HIGH");
635+
fourScanPanel = new VirtualMatrixPanel((*display), 1, 1, 64, 64);
636+
fourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_64PX_HIGH);
637+
fourScanPanel->setRotation(0);
638+
break;
639+
}
640+
641+
642+
USER_PRINTLN("MatrixPanel_I2S_DMA started");
643+
}
644+
645+
void BusHub75Matrix::setPixelColor(uint16_t pix, uint32_t c) {
646+
r = R(c);
647+
g = G(c);
648+
b = B(c);
649+
if(fourScanPanel != nullptr) {
650+
x = pix % fourScanPanel->width();
651+
y = floor(pix / fourScanPanel->width());
652+
fourScanPanel->drawPixelRGB888(x, y, r, g, b);
653+
}
654+
else {
655+
x = pix % display->width();
656+
y = floor(pix / display->width());
657+
display->drawPixelRGB888(x, y, r, g, b);
658+
}
659+
}
660+
661+
void BusHub75Matrix::setBrightness(uint8_t b, bool immediate) {
662+
this->display->setBrightness(b);
663+
}
664+
665+
void BusHub75Matrix::deallocatePins() {
666+
667+
pinManager.deallocatePin(mxconfig.gpio.r1, PinOwner::HUB75);
668+
pinManager.deallocatePin(mxconfig.gpio.g1, PinOwner::HUB75);
669+
pinManager.deallocatePin(mxconfig.gpio.b1, PinOwner::HUB75);
670+
pinManager.deallocatePin(mxconfig.gpio.r2, PinOwner::HUB75);
671+
pinManager.deallocatePin(mxconfig.gpio.g2, PinOwner::HUB75);
672+
pinManager.deallocatePin(mxconfig.gpio.b2, PinOwner::HUB75);
673+
674+
pinManager.deallocatePin(mxconfig.gpio.lat, PinOwner::HUB75);
675+
pinManager.deallocatePin(mxconfig.gpio.oe, PinOwner::HUB75);
676+
pinManager.deallocatePin(mxconfig.gpio.clk, PinOwner::HUB75);
677+
678+
pinManager.deallocatePin(mxconfig.gpio.a, PinOwner::HUB75);
679+
pinManager.deallocatePin(mxconfig.gpio.b, PinOwner::HUB75);
680+
pinManager.deallocatePin(mxconfig.gpio.c, PinOwner::HUB75);
681+
pinManager.deallocatePin(mxconfig.gpio.d, PinOwner::HUB75);
682+
pinManager.deallocatePin(mxconfig.gpio.e, PinOwner::HUB75);
683+
684+
}
685+
#endif
686+
// ***************************************************************************
461687

462688
//utility to get the approx. memory usage of a given BusConfig
463689
uint32_t BusManager::memUsage(BusConfig &bc) {
@@ -483,8 +709,14 @@ uint32_t BusManager::memUsage(BusConfig &bc) {
483709

484710
int BusManager::add(BusConfig &bc) {
485711
if (getNumBusses() - getNumVirtualBusses() >= WLED_MAX_BUSSES) return -1;
712+
USER_PRINTF("BusManager::add(bc.type=%u)\n", bc.type);
486713
if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) {
487714
busses[numBusses] = new BusNetwork(bc);
715+
#ifdef WLED_ENABLE_HUB75MATRIX
716+
} else if (bc.type >= TYPE_HUB75MATRIX && bc.type <= (TYPE_HUB75MATRIX + 10)) {
717+
USER_PRINTLN("BusManager::add - Adding BusHub75Matrix");
718+
busses[numBusses] = new BusHub75Matrix(bc);
719+
#endif
488720
} else if (IS_DIGITAL(bc.type)) {
489721
busses[numBusses] = new BusDigital(bc, numBusses, colorOrderMap);
490722
} else if (bc.type == TYPE_ONOFF) {

0 commit comments

Comments
 (0)