Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 43 additions & 30 deletions wled00/bus_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ void BusNetwork::cleanup() {

// BusHub75Matrix "global" variables (static members)
MatrixPanel_I2S_DMA* BusHub75Matrix::activeDisplay = nullptr;
VirtualMatrixPanel* BusHub75Matrix::activeFourScanPanel = nullptr;
VirtualMatrixPanel* BusHub75Matrix::activevirtualDisp = nullptr;
HUB75_I2S_CFG BusHub75Matrix::activeMXconfig = HUB75_I2S_CFG();
uint8_t BusHub75Matrix::activeType = 0;
uint8_t BusHub75Matrix::instanceCount = 0;
Expand Down Expand Up @@ -571,7 +571,7 @@ uint8_t BusHub75Matrix::instanceCount = 0;

BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
MatrixPanel_I2S_DMA* display = nullptr;
VirtualMatrixPanel* fourScanPanel = nullptr;
VirtualMatrixPanel* virtualDisp = nullptr;
HUB75_I2S_CFG mxconfig;
size_t lastHeap = ESP.getFreeHeap();

Expand Down Expand Up @@ -664,6 +664,9 @@ BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWh
else if (numPixels <= MAX_PIXELS_4BIT) mxconfig.setPixelColorDepthBits(4); // 12bit
else mxconfig.setPixelColorDepthBits(3); // 9bit

rows = min(bc.pins[3], (uint8_t) 2); // TODO higher limit
cols = min(bc.pins[4], (uint8_t) 2); // TODO higher limit


#if defined(ARDUINO_ADAFRUIT_MATRIXPORTAL_ESP32S3) // MatrixPortal ESP32-S3

Expand Down Expand Up @@ -849,7 +852,7 @@ BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWh
delete activeDisplay;
//#endif
activeDisplay = nullptr;
activeFourScanPanel = nullptr;
activevirtualDisp = nullptr;
#if defined(CONFIG_IDF_TARGET_ESP32S3) // runtime reconfiguration is not working on -S3
USER_PRINTLN("\n\n****** MatrixPanel_I2S_DMA !KABOOM WARNING! Reboot needed to change driver options ***********\n");
errorFlag = ERR_REBOOT_NEEDED;
Expand All @@ -864,13 +867,13 @@ BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWh
newDisplay = true;
} else {
display = activeDisplay; // continue with existing matrix object
fourScanPanel = activeFourScanPanel;
virtualDisp = activevirtualDisp;
}

if (display == nullptr) {
USER_PRINTLN("****** MatrixPanel_I2S_DMA !KABOOM! driver allocation failed ***********");
activeDisplay = nullptr;
activeFourScanPanel = nullptr;
activevirtualDisp = nullptr;
USER_PRINT(F("heap usage: ")); USER_PRINTLN(int(lastHeap - ESP.getFreeHeap()));
return;
}
Expand Down Expand Up @@ -950,32 +953,42 @@ BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWh
switch(bc.type) {
case 105:
USER_PRINTLN("MatrixPanel_I2S_DMA FOUR_SCAN_32PX_HIGH - 32x32");
if (!fourScanPanel) fourScanPanel = new VirtualMatrixPanel((*display), 1, 1, 32, 32);
fourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH);
fourScanPanel->setRotation(0);
if (!virtualDisp) virtualDisp = new VirtualMatrixPanel((*display), 1, 1, 32, 32);
virtualDisp->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH);
virtualDisp->setRotation(0);
break;
case 106:
USER_PRINTLN("MatrixPanel_I2S_DMA FOUR_SCAN_32PX_HIGH - 64x32");
if (!fourScanPanel) fourScanPanel = new VirtualMatrixPanel((*display), 1, 1, 64, 32);
fourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH);
fourScanPanel->setRotation(0);
if (!virtualDisp) virtualDisp = new VirtualMatrixPanel((*display), 1, 1, 64, 32);
virtualDisp->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH);
virtualDisp->setRotation(0);
break;
case 107:
USER_PRINTLN("MatrixPanel_I2S_DMA FOUR_SCAN_64PX_HIGH");
if (!fourScanPanel) fourScanPanel = new VirtualMatrixPanel((*display), 1, 1, 64, 64);
fourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_64PX_HIGH);
fourScanPanel->setRotation(0);
if (!virtualDisp) virtualDisp = new VirtualMatrixPanel((*display), 1, 1, 64, 64);
virtualDisp->setPhysicalPanelScanRate(FOUR_SCAN_64PX_HIGH);
virtualDisp->setRotation(0);
break;
case 108: // untested
USER_PRINTLN("MatrixPanel_I2S_DMA 128x64 FOUR_SCAN_64PX_HIGH");
if (!fourScanPanel) fourScanPanel = new VirtualMatrixPanel((*display), 1, 1, 128, 64);
fourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_64PX_HIGH);
fourScanPanel->setRotation(0);
if (!virtualDisp) virtualDisp = new VirtualMatrixPanel((*display), 1, 1, 128, 64);
virtualDisp->setPhysicalPanelScanRate(FOUR_SCAN_64PX_HIGH);
virtualDisp->setRotation(0);
break;
default:
if(mxconfig.chain_length > 1 && rows >= 1 && cols >= 1) { // More than 1 panel, not just horizontal layout
// TODO: special case of 128x64 panels actually being 64x64 chain of two internally
USER_PRINTF("MatrixPanel_I2S_DMA VirtualMatrixPanel %ux%u - %ux%u\n", mxconfig.mx_width, mxconfig.mx_height, rows, cols);
virtualDisp = new VirtualMatrixPanel((*display), rows, cols, mxconfig.mx_width, mxconfig.mx_height, (PANEL_CHAIN_TYPE)bc.skipAmount);
Copy link
Collaborator Author

@netmindz netmindz Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

192x128 total was chain 6 - 2, 3, 64, 64, CHAIN_BOTTOM_RIGHT_UP (4)

}
else {
USER_PRINTLN("MatrixPanel_I2S_DMA PANEL_CHAIN_TYPE.CHAIN_NONE");
}
break;
}

if (_valid) {
_panelWidth = fourScanPanel ? fourScanPanel->width() : display->width(); // cache width - it will never change
_panelWidth = virtualDisp ? virtualDisp->width() : display->width(); // cache width - it will never change
}

USER_PRINT(F("MatrixPanel_I2S_DMA "));
Expand All @@ -993,7 +1006,7 @@ BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWh
// config is active, copy to global
activeType = bc.type;
activeDisplay = display;
activeFourScanPanel = fourScanPanel;
activevirtualDisp = virtualDisp;
if (newDisplay) memcpy(&activeMXconfig, &mxconfig, sizeof(mxconfig));
}
instanceCount++;
Expand All @@ -1018,19 +1031,19 @@ void __attribute__((hot)) BusHub75Matrix::setPixelColor(uint16_t pix, uint32_t c
else {
// no double buffer allocated --> directly draw pixel
MatrixPanel_I2S_DMA* display = BusHub75Matrix::activeDisplay;
VirtualMatrixPanel* fourScanPanel = BusHub75Matrix::activeFourScanPanel;
VirtualMatrixPanel* virtualDisp = BusHub75Matrix::activevirtualDisp;
#ifndef NO_CIE1931
c = unGamma24(c); // to use the driver linear brightness feature, we first need to undo WLED gamma correction
#endif
uint8_t r = R(c);
uint8_t g = G(c);
uint8_t b = B(c);

if(fourScanPanel != nullptr) {
if(virtualDisp != nullptr) {
int width = _panelWidth;
int x = pix % width;
int y = pix / width;
fourScanPanel->drawPixelRGB888(int16_t(x), int16_t(y), r, g, b);
virtualDisp->drawPixelRGB888(int16_t(x), int16_t(y), r, g, b);
} else {
int width = _panelWidth;
int x = pix % width;
Expand Down Expand Up @@ -1068,10 +1081,10 @@ void __attribute__((hot)) BusHub75Matrix::show(void) {

if (_ledBuffer) {
// write out buffered LEDs
VirtualMatrixPanel* fourScanPanel = BusHub75Matrix::activeFourScanPanel;
bool isFourScan = (fourScanPanel != nullptr);
//if (isFourScan) fourScanPanel->setRotation(0);
unsigned height = isFourScan ? fourScanPanel->height() : display->height();
VirtualMatrixPanel* virtualDisp = BusHub75Matrix::activevirtualDisp;
bool isVirtualDisp = (virtualDisp != nullptr);
//if (isVirtualDisp) virtualDisp->setRotation(0);
unsigned height = isVirtualDisp ? virtualDisp->height() : display->height();
unsigned width = _panelWidth;

// Cache pointers to LED array and bitmask array, to avoid repeated accesses
Expand All @@ -1095,7 +1108,7 @@ void __attribute__((hot)) BusHub75Matrix::show(void) {
uint8_t g = c.g;
uint8_t b = c.b;
#endif
if (isFourScan) fourScanPanel->drawPixelRGB888(int16_t(x), int16_t(y), r, g, b);
if (isVirtualDisp) virtualDisp->drawPixelRGB888(int16_t(x), int16_t(y), r, g, b);
else display->drawPixelRGB888(int16_t(x), int16_t(y), r, g, b);
}
pix ++;
Expand All @@ -1106,7 +1119,7 @@ void __attribute__((hot)) BusHub75Matrix::show(void) {

void BusHub75Matrix::cleanup() {
MatrixPanel_I2S_DMA* display = BusHub75Matrix::activeDisplay;
VirtualMatrixPanel* fourScanPanel = BusHub75Matrix::activeFourScanPanel;
VirtualMatrixPanel* virtualDisp = BusHub75Matrix::activevirtualDisp;
if (display) display->clearScreen();

#if !defined(CONFIG_IDF_TARGET_ESP32S3) // S3: don't stop, as we want to re-use the driver later
Expand All @@ -1119,11 +1132,11 @@ void BusHub75Matrix::cleanup() {

_valid = false;
deallocatePins();
//if (fourScanPanel != nullptr) delete fourScanPanel; // warning: deleting object of polymorphic class type 'VirtualMatrixPanel' which has non-virtual destructor might cause undefined behavior
//if (virtualDisp != nullptr) delete virtualDisp; // warning: deleting object of polymorphic class type 'VirtualMatrixPanel' which has non-virtual destructor might cause undefined behavior
#if !defined(CONFIG_IDF_TARGET_ESP32S3) // S3: don't delete, as we want to re-use the driver later
if (display) delete display;
activeDisplay = nullptr;
activeFourScanPanel = nullptr;
activevirtualDisp = nullptr;
USER_PRINTLN("HUB75 deleted.");
#else
USER_PRINTLN("HUB75 cleanup done.");
Expand Down
10 changes: 8 additions & 2 deletions wled00/bus_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,11 @@ class BusHub75Matrix : public Bus {

uint8_t getPins(uint8_t* pinArray) const override {
pinArray[0] = activeMXconfig.chain_length;
return 1;
pinArray[1] = -1;
pinArray[2] = -1;
pinArray[3] = rows;
pinArray[4] = cols;
Comment on lines +424 to +425
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no getters in the VirtualDisplay to read these values back out again, might do a PR at some stage to add that

return 5;
} // Fake value due to keep finaliseInit happy

void deallocatePins();
Expand All @@ -404,10 +408,12 @@ class BusHub75Matrix : public Bus {
unsigned _panelWidth = 0;
CRGB *_ledBuffer = nullptr;
byte *_ledsDirty = nullptr;
int rows = 0;
int cols = 0;
// C++ dirty trick: private static variables are actually _not_ part of the class (however only visibile to class instances).
// These variables persist when BusHub75Matrix gets deleted.
static MatrixPanel_I2S_DMA *activeDisplay; // active display object
static VirtualMatrixPanel *activeFourScanPanel; // active fourScan object
static VirtualMatrixPanel *activevirtualDisp; // active fourScan object
static HUB75_I2S_CFG activeMXconfig; // last used mxconfig
static uint8_t activeType; // last used type
static uint8_t instanceCount; // active instances - 0 or 1
Expand Down