-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
HUB75 bugfixes for 4-scan and chained panels + new "Seengreat" pinout #5662
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
base: main
Are you sure you want to change the base?
Changes from 7 commits
834a902
f1a99ce
c530e13
1ee4c61
22fead8
32412c9
53cbb15
939c254
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 |
|---|---|---|
|
|
@@ -802,10 +802,11 @@ BusHub75Matrix::BusHub75Matrix(const BusConfig &bc) : Bus(bc.type, bc.start, bc. | |
| _hasRgb = true; | ||
| _hasWhite = false; | ||
| virtualDisp = nullptr; // todo: this should be solved properly, can cause memory leak (if omitted here, nothing seems to work) | ||
| _isVirtual = false; | ||
| // aliases for easier reading | ||
| uint8_t panelWidth = bc.pins[0]; | ||
| uint8_t panelHeight = bc.pins[1]; | ||
| uint8_t chainLength = bc.pins[2]; | ||
| unsigned panelWidth = bc.pins[0]; | ||
| unsigned panelHeight = bc.pins[1]; | ||
| unsigned chainLength = bc.pins[2]; | ||
| _rows = bc.pins[3]; | ||
| _cols = bc.pins[4]; | ||
|
|
||
|
|
@@ -822,7 +823,7 @@ BusHub75Matrix::BusHub75Matrix(const BusConfig &bc) : Bus(bc.type, bc.start, bc. | |
|
|
||
| mxconfig.clkphase = bc.reversed; | ||
| // allow chain length up to 4, limit to prevent bad data from preventing boot due to low memory | ||
| mxconfig.chain_length = max((uint8_t) 1, min(chainLength, (uint8_t) 4)); | ||
| mxconfig.chain_length = max(1U, min(chainLength, 4U)); | ||
|
|
||
| if (mxconfig.mx_height >= 64 && (mxconfig.chain_length > 1)) { | ||
| #if defined(BOARD_HAS_PSRAM) // limitation to one panel only applies to boards without PSRAM | ||
|
|
@@ -835,12 +836,12 @@ BusHub75Matrix::BusHub75Matrix(const BusConfig &bc) : Bus(bc.type, bc.start, bc. | |
| } | ||
|
|
||
| if (bc.type == TYPE_HUB75MATRIX_HS) { | ||
| mxconfig.mx_width = min((uint8_t) 64, panelWidth); // TODO: UI limit is 128, this limits to 64 | ||
| mxconfig.mx_height = min((uint8_t) 64, panelHeight); | ||
| mxconfig.mx_width = min(128U, panelWidth); // UI limit is 128 | ||
| mxconfig.mx_height = min(64U, panelHeight); | ||
| } else if (bc.type == TYPE_HUB75MATRIX_QS) { | ||
| _isVirtual = true; | ||
| mxconfig.mx_width = min((uint8_t) 64, panelWidth) * 2; | ||
| mxconfig.mx_height = min((uint8_t) 64, panelHeight) / 2; | ||
| mxconfig.mx_width = min(128U, panelWidth) * 2; | ||
| mxconfig.mx_height = min(64U, panelHeight) / 2; | ||
| mxconfig.driver = HUB75_I2S_CFG::FM6124; // use FM6124 for "outdoor" 4-scan panels - workaround until we can make the driver user-configurable | ||
| } else { | ||
| DEBUGBUS_PRINTLN("Unknown type"); | ||
|
|
@@ -887,6 +888,12 @@ BusHub75Matrix::BusHub75Matrix(const BusConfig &bc) : Bus(bc.type, bc.start, bc. | |
| // HUB75_I2S_CFG::i2s_pins _pins={R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, LAT_PIN, OE_PIN, CLK_PIN}; | ||
| mxconfig.gpio = {4, 5, 6, 7, 15, 16, 18, 8, 3, 42, 9, 40, 2, 41}; | ||
|
|
||
| #elif defined(SEENGREAT_V2_PINOUT) | ||
| DEBUGBUS_PRINTLN("MatrixPanel_I2S_DMA - S3 devKit-C with PSRAM, SEENGREAT_V2 pinout"); | ||
| mxconfig.gpio = { 18, 8, 17, // R1_PIN, G1_PIN, B1_PIN, | ||
| 16, 1, 15, // R2_PIN, G2_PIN, B2_PIN, | ||
| 7, 48, 6, 47, 2, // A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, | ||
| 21, 4, 5 }; //LAT_PIN, OE_PIN,CLK_PIN | ||
| #else | ||
| DEBUGBUS_PRINTLN("MatrixPanel_I2S_DMA - S3 with PSRAM"); | ||
| // HUB75_I2S_CFG::i2s_pins _pins={R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, LAT_PIN, OE_PIN, CLK_PIN}; | ||
|
|
@@ -1011,15 +1018,15 @@ BusHub75Matrix::BusHub75Matrix(const BusConfig &bc) : Bus(bc.type, bc.start, bc. | |
| // chained panels with cols and rows define need the virtual display driver, so do quarter-scan panels | ||
| if (chainLength > 1 && (_rows > 1 || _cols > 1) || bc.type == TYPE_HUB75MATRIX_QS) { | ||
| _isVirtual = true; | ||
| chainType = CHAIN_BOTTOM_LEFT_UP; // TODO: is there any need to support other chaining types? | ||
| DEBUGBUS_PRINTF_P(PSTR("Using virtual matrix: %ux%u panels of %ux%u pixels\n"), _cols, _rows, mxconfig.mx_width, mxconfig.mx_height); | ||
| if (chainLength > 1 && (_rows > 1 || _cols > 1)) chainType = CHAIN_TOP_RIGHT_DOWN; // we need to use a _DOWN chainType, otherwise the display is upside-down | ||
|
Collaborator
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. the condition is a duplicate, better to change the initial condition also what effect does chainType have? CHAIN_BOTTOM_LEFT_UP works fine on my chained panel.
Member
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. The chain type is typically used for multiple physical panels and is a common technique of physically instal panels upside down to keep cables shorter, see the driver docs for details. I've yet to see a true 128 wide panel myself, the ones I've seen have been two 64x64 mounted side by side, so you need a chain length of 2 per panel, but that could get tricky once you then try and use multiple physical panels to get both halves of the panel the right way up
Member
Author
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.
This should - normally - only be relevant when you have chained panels. Similar our 2D setup, chained panels can be connected from top down, left to right or even "sepentine" to save wire length. For my 4-scan panel, CHAIN_BOTTOM_LEFT_UP always results in 180° rotated display where everything is upside-down, even without chaining panels. TOP_RIGHT_DOWN is the only one where I still had the "correct" orientation. I've compared to CHAIN_NONE and to 2-scan mode, just to be sure I'm not holding the panel wrongly. |
||
| DEBUGBUS_PRINTF_P(PSTR("Using virtual matrix: %ux%u panels of %ux%u pixels\n"), _cols, _rows, mxconfig.mx_width/2, mxconfig.mx_height*2); | ||
| } | ||
| else { | ||
| _isVirtual = false; | ||
| } | ||
|
|
||
| if (_isVirtual) { | ||
| virtualDisp = new VirtualMatrixPanel((*display), _rows, _cols, mxconfig.mx_width, mxconfig.mx_height, chainType); | ||
| virtualDisp = new VirtualMatrixPanel((*display), _rows, _cols, mxconfig.mx_width/2, mxconfig.mx_height*2, chainType); | ||
| virtualDisp->setRotation(0); | ||
| if (bc.type == TYPE_HUB75MATRIX_QS) { | ||
| switch(panelHeight) { | ||
|
|
@@ -1090,7 +1097,7 @@ void IRAM_ATTR BusHub75Matrix::setPixelColor(unsigned pix, uint32_t c) { | |
| uint32_t BusHub75Matrix::getPixelColor(unsigned pix) const { | ||
| if (!_valid) return IS_BLACK; // note: no need to check pix >= _len as that is checked in containsPixel() | ||
| if (_ledBuffer) | ||
| return uint32_t(_ledBuffer[pix]); | ||
| return uint32_t(_ledBuffer[pix]) & 0x00FFFFFF; // FastLED 32bit is RGBA, we need RGBW | ||
| else | ||
| return getBitFromArray(_ledsDirty, pix) ? IS_DARKGREY: IS_BLACK; // just a hack - we only know if the pixel is black or not | ||
| } | ||
|
|
@@ -1155,8 +1162,8 @@ std::vector<LEDType> BusHub75Matrix::getLEDTypes() { | |
|
|
||
| size_t BusHub75Matrix::getPins(uint8_t* pinArray) const { | ||
| if (pinArray) { | ||
| pinArray[0] = mxconfig.mx_width; | ||
| pinArray[1] = mxconfig.mx_height; | ||
| pinArray[0] = _isVirtual ? mxconfig.mx_width /2 : mxconfig.mx_width; | ||
|
Member
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. Originally I was tracking QS virtual panels separately from regular use of virtual panels, we possibly need to use separate flag not the isVirtual |
||
| pinArray[1] = _isVirtual ? mxconfig.mx_height *2 : mxconfig.mx_height; | ||
| pinArray[2] = mxconfig.chain_length; | ||
| pinArray[3] = _rows; | ||
| pinArray[4] = _cols; | ||
|
|
||
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.
Probably worth adding the S3 check to that define
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.
More to come - the board has a second pinout for esp32 classic, and it even comes in "V1" and "V2" pinout variants. 4 new printouts in total 😅