Skip to content

Problem with panels of over 32768 pixels size #755

Open
@rigorka

Description

@rigorka

I know I'm kinda on my own with the panels of this size, but still - any advice on where to look at would be much appreciated.
Here's the deal: I have a lot of 32x32 px 1/8 panels (simple SHIFTREG driver), ESP32S3 with 8Mb PSRAM, and I'm trying to create a fairly big screen. I don't need much of a color depth, so I set that to 3.

It works great up to the size of 3x10 panels (30720 pixels). Any size bigger than that, such as 4x8 panels (32768 px) produces random garbage on the panels. The memory size should not be an issue: at 3 bpp color it only allocates about 96kB even with the double buffering enabled.

What worries me, is this weird 32768 px threshold. It is almost as if signed int is used somewhere instead of unsigned int. But where?...

UPD: "Single line" configurations up to 1 row of 31 panels (31744 pixels) work great, but 1 row of 32 panels (32768 pixels) breaks.

Activity

added
not an issue with libraryThis library works as expected, but something else is the root cause, such as AdaFruitGFX
on Feb 12, 2025
mrcodetastic

mrcodetastic commented on Feb 17, 2025

@mrcodetastic
Owner

It would be hard to know without looking at a logic level capture.

rigorka

rigorka commented on Feb 17, 2025

@rigorka
Author

It would be hard to know without looking at a logic level capture.

I can get that by connecting the HUB75 output to oscilloscope. Which of the HUB75 signals are you interested in?

Lukaswnd

Lukaswnd commented on Feb 18, 2025

@Lukaswnd
Contributor

This is interesting, back in December 2023 I managed to run 45056 pixels, 22 Panels each 64x32.
Which version are you using? Latest Commit from Git, latest Git Release, latest from Pio registry or Arduino Registry.
One of the last commits changed the resolution in the Virtual Display from int16_t to uint16_t. Since the problem also occurs in single line configuration I doubt that is the issue.
Did you try to increase latch_blanking on some (cheap and poorly produced) boards it helps to keep long chains stable.
Can you make some pictures?
Edit: You are not using the external DMA buffer, right? This is not fast enough for such long chains even with low color depth?

board707

board707 commented on Feb 18, 2025

@board707
Contributor

One of the last commits changed the Panel Solution in the Virtual Display from int16_t to uint16_t. Since the problem also occurs in single line configuration I doubt that is the issue.

Changing the matrix dimensions from int16 to uint should have increased the number of available points rather than decreased it :) However, I am more inclined to think that this has nothing to do with the problem.
If you suspect this, you can always return to the previous type of numbers, one line was corrected

rigorka

rigorka commented on Feb 18, 2025

@rigorka
Author

Thanks you for taking time to respond, here are some clarifications:

Which version are you using? Latest Commit from Git, latest Git Release, latest from Pio registry or Arduino Registry.

Latest Commit from Git

One of the last commits changed the resolution in the Virtual Display from int16_t to uint16_t. Since the problem also occurs in single line configuration I doubt that is the issue.

Yep, this does not change things much as this affects merely the X res, which was quite far from int16_t maximum anyway.

Did you try to increase latch_blanking on some (cheap and poorly produced) boards it helps to keep long chains stable.

Yep, all the way up to four, with no changes.

Can you make some pictures?

This is what the end of the "healthy" 31-panel chain looks like (I don't have all the panels at home, so that's just the end of the chain):
Image

And this are the examples of what "broken" 32-chain looks like (the shapes are fairly random at each reboot, sometimes the screen is just black. The chain responds to setBrightness call, but all other GFX calls such as drawPixel and clearScreen do nothing:

Image

Image

Edit: You are not using the external DMA buffer, right? This is not fast enough for such long chains even with low color depth?

I'm not, but nothing changes if I do - the results are pretty much the same: chain of 31 panels work, chain of 32 does not

These are the library log output with 32 panels (when it does not work):

[   381][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:423] begin(): [begin()] Using GPIO 46 for R1_PIN
[   389][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:424] begin(): [begin()] Using GPIO 38 for G1_PIN
[   398][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:425] begin(): [begin()] Using GPIO 4 for B1_PIN
[   406][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:426] begin(): [begin()] Using GPIO 16 for R2_PIN
[   414][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:427] begin(): [begin()] Using GPIO 15 for G2_PIN
[   423][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:428] begin(): [begin()] Using GPIO 39 for B2_PIN
[   431][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:429] begin(): [begin()] Using GPIO 18 for A_PIN
[   439][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:430] begin(): [begin()] Using GPIO 8 for B_PIN
[   448][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:431] begin(): [begin()] Using GPIO 45 for C_PIN
[   456][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:432] begin(): [begin()] Using GPIO 21 for D_PIN
[   464][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:433] begin(): [begin()] Using GPIO 17 for E_PIN
[   473][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:434] begin(): [begin()] Using GPIO 48 for LAT_PIN
[   481][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:435] begin(): [begin()] Using GPIO 2 for OE_PIN
[   489][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:436] begin(): [begin()] Using GPIO 41 for CLK_PIN
[   498][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:38] allocateDMAmemory(): [I2S-DMA] Free heap: 319608
[   507][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:39] allocateDMAmemory(): [I2S-DMA] Free SPIRAM: 8386295
[   516][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:43] allocateDMAmemory(): [I2S-DMA] allocating rowBitStructs with pixel_color_depth_bits of 3
[   529][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:70] allocateDMAmemory(): [I2S-DMA] Allocating 196608 bytes memory for DMA BCM framebuffer(s).
[   541][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:78] allocateDMAmemory(): [I2S-DMA] Minimum visual refresh rate (scan rate from panel top to bottom) requested: 20 Hz
[   556][W][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:96] allocateDMAmemory(): [I2S-DMA] lsbMsbTransitionBit of 0 gives 69 Hz refresh rate.
[   567][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:112] allocateDMAmemory(): [I2S-DMA] DMA has pixel_color_depth_bits of 3
[   578][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:126] allocateDMAmemory(): [I2S-DMA] Recalculated number of DMA descriptors per row: 4
[   590][W][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:133] allocateDMAmemory(): [I2S-DMA] rowBits struct is too large to fit in one DMA transfer payload, splitting required. Adding 2 DMA descriptors

[   607][I][gdma_lcd_parallel16.cpp:324] enable_double_dma_desc(): [S3] Enabled support for secondary DMA buffer.
[   617][D][gdma_lcd_parallel16.cpp:334] allocate_dma_desc_memory(): [S3] Allocating 576 bytes memory for DMA descriptors.
[   642][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   655][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   668][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   682][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   695][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   709][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   722][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   736][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   749][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   763][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   776][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   789][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   803][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   816][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   830][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   843][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   857][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   870][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   883][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   897][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   910][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   924][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   937][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   951][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   964][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   977][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   991][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1004][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1018][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1031][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1045][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1058][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1071][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1085][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1098][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1112][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1125][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1139][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1152][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1166][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1179][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1192][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1206][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1219][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1233][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1246][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1260][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1273][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1286][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1300][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1313][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1327][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1340][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1354][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1367][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1380][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1394][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1407][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1421][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1434][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1448][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1461][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1475][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1488][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1501][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1515][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1528][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1542][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1555][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1569][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1582][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1595][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1609][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1622][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1636][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1649][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1663][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1676][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1689][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1703][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1716][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1730][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1743][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1757][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1770][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1784][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1797][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1810][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1824][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1837][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1851][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1864][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1878][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1891][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1904][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1918][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[  1931][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:264] configureDMA(): [I2S-DMA] 48 DMA descriptors linked to buffer data.
[  1943][I][gdma_lcd_parallel16.cpp:155] init(): [S3] Clock divider is 16
[  1950][D][gdma_lcd_parallel16.cpp:156] init(): [S3] Resulting output clock frequency: 10000000 Mhz
[  1970][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:305] configureDMA(): [I2S-DMA] DMA setup completed

And this is the log with 31 panels, when things do work okay:

[   381][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:423] begin(): [begin()] Using GPIO 46 for R1_PIN
[   389][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:424] begin(): [begin()] Using GPIO 38 for G1_PIN
[   398][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:425] begin(): [begin()] Using GPIO 4 for B1_PIN
[   406][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:426] begin(): [begin()] Using GPIO 16 for R2_PIN
[   414][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:427] begin(): [begin()] Using GPIO 15 for G2_PIN
[   423][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:428] begin(): [begin()] Using GPIO 39 for B2_PIN
[   431][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:429] begin(): [begin()] Using GPIO 18 for A_PIN
[   440][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:430] begin(): [begin()] Using GPIO 8 for B_PIN
[   448][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:431] begin(): [begin()] Using GPIO 45 for C_PIN
[   456][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:432] begin(): [begin()] Using GPIO 21 for D_PIN
[   464][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:433] begin(): [begin()] Using GPIO 17 for E_PIN
[   473][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:434] begin(): [begin()] Using GPIO 48 for LAT_PIN
[   481][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:435] begin(): [begin()] Using GPIO 2 for OE_PIN
[   489][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:436] begin(): [begin()] Using GPIO 41 for CLK_PIN
[   498][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:38] allocateDMAmemory(): [I2S-DMA] Free heap: 319608
[   507][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:39] allocateDMAmemory(): [I2S-DMA] Free SPIRAM: 8386295
[   516][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:43] allocateDMAmemory(): [I2S-DMA] allocating rowBitStructs with pixel_color_depth_bits of 3
[   529][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:70] allocateDMAmemory(): [I2S-DMA] Allocating 190464 bytes memory for DMA BCM framebuffer(s).
[   541][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:78] allocateDMAmemory(): [I2S-DMA] Minimum visual refresh rate (scan rate from panel top to bottom) requested: 20 Hz
[   556][W][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:96] allocateDMAmemory(): [I2S-DMA] lsbMsbTransitionBit of 0 gives 72 Hz refresh rate.
[   567][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:112] allocateDMAmemory(): [I2S-DMA] DMA has pixel_color_depth_bits of 3
[   578][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:126] allocateDMAmemory(): [I2S-DMA] Recalculated number of DMA descriptors per row: 4
[   590][W][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:133] allocateDMAmemory(): [I2S-DMA] rowBits struct is too large to fit in one DMA transfer payload, splitting required. Adding 2 DMA descriptors

[   607][I][gdma_lcd_parallel16.cpp:324] enable_double_dma_desc(): [S3] Enabled support for secondary DMA buffer.
[   617][D][gdma_lcd_parallel16.cpp:334] allocate_dma_desc_memory(): [S3] Allocating 576 bytes memory for DMA descriptors.
[   641][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   655][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   668][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   682][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   695][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   708][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   722][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   735][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   749][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   762][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   776][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   789][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   802][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   816][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   829][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   843][W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!
[   856][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:264] configureDMA(): [I2S-DMA] 48 DMA descriptors linked to buffer data.
[   868][I][gdma_lcd_parallel16.cpp:155] init(): [S3] Clock divider is 16
[   875][D][gdma_lcd_parallel16.cpp:156] init(): [S3] Resulting output clock frequency: 10000000 Mhz
[   895][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:305] configureDMA(): [I2S-DMA] DMA setup completed
Lukaswnd

Lukaswnd commented on Feb 19, 2025

@Lukaswnd
Contributor

Interesting, that the issues are with the Panels clsesed to the esp. This defently indictes a issuse with this library, probably numerical.

what I found so far it might be a problem with the DMA descriptors. Can someone please confirm or deny this:
This are 1/8 Panels 32 Pixels heigh and 32 pixel wide, so the Virtual display Maps it to a 16 pixel heigh and 64 pixel long Panel internally. So in a chain of 32 there would be 64*32 = 2048 Pixels in a row. Since the DMA Descriptor uses uint16_t as storage and output type there are 4096 bytes. for each color depth for each row.
In configureDMA the libraries tries to allocate one discriptor for all color depths seperated by row. This defenetly 'fails' (results in log [W][gdma_lcd_parallel16.cpp:369] create_dma_desc_link(): [S3] Creating DMA descriptor which links to payload with size greater than MAX_DMA_LEN!), because there is a max length for each descriptor on the s3 which is 4096-4. So it allocates one discriptor for each colordepth in each row, which also 'fails' because it would need 4 more bytes.

But this would only explain the last 4 pixels each row on the 32nd Panel, which are on the 1/8 Panels the following pixels. In lines 9-16 and 25-32 the pixels 29-32 (indexing starting at [1/1]). I marked them green. Judging by the logs start your panel count at 1, not 0, right? Otherwise it would explain the wrong panel 32 and onwards.

Image

By 'fail' I mean that it just allocates 4092 bytes and ignores the rest of the data.
Allocation wise this would be managable to change. Maybe I find time to make a prototype on Friday.
Would changing the descriptors effect anything else but the DMA output? Like setting a pixel, color, oe and latch is all done to the datastructs, right?
And I guess we will see if changing the DMA Descriptor mid line would have any visual glitches

Lukaswnd

Lukaswnd commented on Feb 19, 2025

@Lukaswnd
Contributor

Oh wait, the Image I edited is Panel 31, but you get which pixel should be wrong.

But I don't get why the ouput on Panel 31 would be wrong by my explanation.

rigorka

rigorka commented on Feb 19, 2025

@rigorka
Author

Indeed, in my panel labeling debug code the panel count is 1..31.

What I also can not explain is why all GFX operations after the first one produce no effect at all in "faulty" case of 32 panels:
my application on S3 works normally, its network API responds fine, I can call VirtualMatrixPanel->clearScreen(), VirtualMatrixPanel->drawPixel() etc without any memory-related errors, but these calls do not produce any result.

This seems especially strange for clearScreen() which just calls updateMatrixDMABuffer(0, 0, 0); internally, and I see no reason at all for that to produce no effect.

mrcodetastic

mrcodetastic commented on Feb 22, 2025

@mrcodetastic
Owner

Interesting, that the issues are with the Panels closest to the esp. This definitely indicates an issue with this library, probably numerical.

what I found so far it might be a problem with the DMA descriptors. Can someone please confirm or deny this: This are 1/8 Panels 32 Pixels heigh and 32 pixel wide, so the Virtual display Maps it to a 16 pixel heigh and 64 pixel long Panel internally. So in a chain of 32 there would be 64*32 = 2048 Pixels in a row. Since the DMA Descriptor uses uint16_t as storage and output type there are 4096 bytes. for each color depth for each row.

It's times like this I realise this library really is a labour of love for me 😂.

You're on the money. The first data to get clocked out is the co-ordinates (0,0), the last data is the panel closest to the ESP.

With these ESP's getting ever more powerful, it seems with a long chain of 'four scan' (2xwidth, .5xheight) panels it's possible to easily blast the 4069-byte DMA descriptor payload limit with 32 panels 😂. As all each 'colour depth' loop is a long chain of output data, with each iteration of truncated data, the offset x will get worse I suspect.

Let me look and see what I can do.

added
bugSomething isn't working
and removed
not an issue with libraryThis library works as expected, but something else is the root cause, such as AdaFruitGFX
on Feb 22, 2025
mrcodetastic

mrcodetastic commented on Feb 22, 2025

@mrcodetastic
Owner

This seems especially strange for clearScreen() which just calls updateMatrixDMABuffer(0, 0, 0); internally, and I see no reason at all for that to produce no effect.

This I don't understand. I'm hoping there's some strange side-effect of the DMA payload limit being exceeded.

added a commit that references this issue on Feb 24, 2025
mrcodetastic

mrcodetastic commented on Feb 24, 2025

@mrcodetastic
Owner

I made some changes which I think might fix the issue.

rigorka

rigorka commented on Feb 25, 2025

@rigorka
Author

Thank you for your efforts, but unfortunately I'm out of luck trying to test the new version so far. The same config (one chain, 31 panels) which used to work before now spits the following log and dies (as in S3 becomes completely unresponsive, none of my app code is being executed after the library initialization). Furthermore, reducing the panel chain size to modest 4 panels changes nothing - S3 still hangs immediately after library init. Rolling the lib back to previous version fixes the issue immediately.

[   236][I][esp32-hal-psram.c:96] psramInit(): PSRAM enabled
[   381][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:435] begin(): [begin()] Using GPIO 46 for R1_PIN
[   390][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:436] begin(): [begin()] Using GPIO 38 for G1_PIN
[   398][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:437] begin(): [begin()] Using GPIO 4 for B1_PIN
[   406][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:438] begin(): [begin()] Using GPIO 16 for R2_PIN
[   415][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:439] begin(): [begin()] Using GPIO 15 for G2_PIN
[   423][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:440] begin(): [begin()] Using GPIO 39 for B2_PIN
[   431][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:441] begin(): [begin()] Using GPIO 18 for A_PIN
[   440][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:442] begin(): [begin()] Using GPIO 8 for B_PIN
[   448][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:443] begin(): [begin()] Using GPIO 45 for C_PIN
[   456][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:444] begin(): [begin()] Using GPIO 21 for D_PIN
[   465][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:445] begin(): [begin()] Using GPIO 17 for E_PIN
[   473][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:446] begin(): [begin()] Using GPIO 48 for LAT_PIN
[   481][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:447] begin(): [begin()] Using GPIO 2 for OE_PIN
[   490][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:448] begin(): [begin()] Using GPIO 41 for CLK_PIN
[   498][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:43] setupDMA(): [I2S-DMA] Free heap: 320104
[   506][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:44] setupDMA(): [I2S-DMA] Free SPIRAM: 8386295
[   515][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:71] setupDMA(): [I2S-DMA] Allocating 190464 bytes memory for DMA BCM framebuffer(s).
[   527][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:85] setupDMA(): [I2S-DMA] Minimum visual refresh rate (scan rate from panel top to bottom) requested: 20 Hz
[   540][W][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:105] setupDMA(): [I2S-DMA] lsbMsbTransitionBit of 0 gives 84 Hz refresh rate.
[   552][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:121] setupDMA(): [I2S-DMA] DMA has pixel_color_depth_bits of 3
[   561][I][gdma_lcd_parallel16.cpp:324] enable_double_dma_desc(): [S3] Enabled support for secondary DMA buffer.
[   571][D][gdma_lcd_parallel16.cpp:334] allocate_dma_desc_memory(): [S3] Allocating 576 bytes memory for DMA descriptors.
[   582][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   596][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   610][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   624][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   637][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   651][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   665][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   679][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   693][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   706][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   720][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   734][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   748][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   762][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   775][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   789][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   803][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   817][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   830][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   844][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   858][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   872][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   886][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   899][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   913][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   927][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   941][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   955][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   968][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   982][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[   996][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1010][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1023][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1037][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1051][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1065][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1079][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1092][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1106][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1120][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1134][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1148][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1161][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1175][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1189][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1203][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1217][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1230][E][gdma_lcd_parallel16.cpp:397] create_dma_desc_link(): [S3] Attempted to create more DMA descriptors than allocated. Expecting max 48 descriptors.
[  1244][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:260] setupDMA(): [I2S-DMA] 96 DMA descriptors linked to buffer data vs 48 required.
[  1256][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:302] setupDMA(): [I2S-DMA] DMA setup completed
mrcodetastic

mrcodetastic commented on Mar 2, 2025

@mrcodetastic
Owner

Can you post a simple application with the code so I can repeat this issue on my end? I want to fix this issue.

rigorka

rigorka commented on Mar 5, 2025

@rigorka
Author

Can you post a simple application with the code so I can repeat this issue on my end? I want to fix this issue.

Thank you for your willingness to pursue this further. I'm away on a trip from 1st to 21st march without (thankfully!) my panels and controllers, but will make sure to prepare a super simple app allowing to reproduce the problem and will send it to you late march as soon as I'm back and can test it on a real controller.

mrcodetastic

mrcodetastic commented on Mar 16, 2025

@mrcodetastic
Owner

Thank you for your willingness to pursue this further. I'm away on a trip from 1st to 21st march

No problems. I introduced new bugs trying to solve for this edge-case, but I think I've fixed everything now. Whilst I don't have a S3 connected to 32 panels, I can now at least get this output if I run a test sketch, which indicates to me all is now working fine.

[   908][I][ESP32-HUB75-MatrixPanel-I2S-DMA.h:459] begin(): [begin()] HUB75 effective display resolution of width: 2048px height: 8px.
[   920][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:43] setupDMA(): [I2S-DMA] Free heap: 350908
[   928][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:44] setupDMA(): [I2S-DMA] Free SPIRAM: 0
[   936][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:71] setupDMA(): [I2S-DMA] Allocating 262144 bytes memory for DMA BCM framebuffer(s).
[   948][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:85] setupDMA(): [I2S-DMA] Minimum visual refresh rate (scan rate from panel top to bottom) requested: 60 Hz
[   961][W][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:105] setupDMA(): [I2S-DMA] lsbMsbTransitionBit of 0 gives 7 Hz refresh rate.
[   972][W][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:105] setupDMA(): [I2S-DMA] lsbMsbTransitionBit of 1 gives 13 Hz refresh rate.
[   983][W][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:105] setupDMA(): [I2S-DMA] lsbMsbTransitionBit of 2 gives 25 Hz refresh rate.
[   994][W][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:105] setupDMA(): [I2S-DMA] lsbMsbTransitionBit of 3 gives 42 Hz refresh rate.
[  1005][W][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:105] setupDMA(): [I2S-DMA] lsbMsbTransitionBit of 4 gives 65 Hz refresh rate.
[  1016][W][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:118] setupDMA(): [I2S-DMA] lsbMsbTransitionBit of 4 used to achieve refresh rate of 60 Hz. Percieved colour depth to the eye may be reduced.
[  1033][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:121] setupDMA(): [I2S-DMA] DMA frame buffer color depths: 8
[  1042][V][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:139] setupDMA(): [I2S-DMA] dma_descs_per_row_1cdepth: 2
[  1051][V][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:140] setupDMA(): [I2S-DMA] last_dma_desc_bytes_1cdepth: 4
[  1061][V][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:141] setupDMA(): [I2S-DMA] dma_descs_per_row_all_cdepths: 9
[  1070][V][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:142] setupDMA(): [I2S-DMA] last_dma_desc_bytes_all_cdepths: 32
[  1080][V][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:158] setupDMA(): [I2S-DMA] DMA descriptors per row: 23
[  1089][V][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:159] setupDMA(): [I2S-DMA] DMA descriptors required per buffer: 92
[  1099][I][gdma_lcd_parallel16.cpp:287] enable_double_dma_desc(): [S3] Enabled support for secondary DMA buffer.
[  1109][D][gdma_lcd_parallel16.cpp:297] allocate_dma_desc_memory(): [S3] Allocating 1104 bytes memory for DMA descriptors.
[  1120][V][gdma_lcd_parallel16.cpp:372] create_dma_desc_link(): [S3] Creating last _dmadesc_a descriptor which loops back to _dmadesc_a[0]!
[  1132][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:234] setupDMA(): [I2S-DMA] Created 92 DMA descriptors for buffer 0.
[  1142][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:234] setupDMA(): [I2S-DMA] Created 92 DMA descriptors for buffer 1.
[  1152][I][ESP32-HUB75-MatrixPanel-I2S-DMA.cpp:306] setupDMA(): [I2S-DMA] DMA setup completed
[  1173][V][ESP32-HUB75-MatrixPanel-I2S-DMA.h:476] begin(): [being()] Completed resetbuffers()
[  1173][V][ESP32-HUB75-MatrixPanel-I2S-DMA.h:479] begin(): [being()] Completed flipDMABuffer()
[  1180][I][gdma_lcd_parallel16.cpp:148] init(): [S3] Clock divider is 16
[  1185][D][gdma_lcd_parallel16.cpp:149] init(): [S3] Resulting output clock frequency: 10000000 Mhz
[  1195][V][ESP32-HUB75-MatrixPanel-I2S-DMA.h:483] begin(): [being()] Completed dma_bus.init()
[  1203][V][ESP32-HUB75-MatrixPanel-I2S-DMA.h:486] begin(): [being()] Completed dma_bus.dma_transfer_start()
=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   388812 B ( 379.7 KB)
  Free Bytes        :    85716 B (  83.7 KB)
  Allocated Bytes   :   297584 B ( 290.6 KB)
  Minimum Free Bytes:    85588 B (  83.6 KB)
  Largest Free Block:    31732 B (  31.0 KB)
------------------------------------------
GPIO Info:
------------------------------------------
  GPIO : BUS_TYPE[bus/unit][chan]
  --------------------------------------
    19 : USB_DM
    20 : USB_DP
    43 : UART_TX[0]
    44 : UART_RX[0]
============ After Setup End =============
green
red
green
red
green
red

Sketch:

#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>

#define PANEL_RES_X 64      // Number of pixels wide of each INDIVIDUAL panel module. 
#define PANEL_RES_Y 8     // Number of pixels tall of each INDIVIDUAL panel module.
#define PANEL_CHAIN 32      // Total number of panels chained one to another
 
//MatrixPanel_I2S_DMA dma_display;
MatrixPanel_I2S_DMA *dma_display = nullptr;

void setup() {
  Serial.begin(115200);

  // Module configuration
  HUB75_I2S_CFG mxconfig(
    PANEL_RES_X,   // module width
    PANEL_RES_Y,   // module height
    PANEL_CHAIN    // Chain length
  );

  mxconfig.double_buff = true;

  // Display Setup
  dma_display = new MatrixPanel_I2S_DMA(mxconfig);
  dma_display->begin();
  dma_display->clearScreen();

}

bool temp_value = 1;
void loop() {

  temp_value = !temp_value;
  if (temp_value) {
   dma_display->fillScreenRGB888(128,0,0);
    Serial.println("red");
  }
  else {
    dma_display->fillScreenRGB888(0,128,0);
    Serial.println("green");
  }
  
  dma_display->flipDMABuffer();
  delay(500);
}
airCoder2

airCoder2 commented on Apr 1, 2025

@airCoder2

It works great up to the size of 3x10 panels (30720 pixels). Any size bigger than that, such as 4x8 panels (32768 px) produces random garbage on the panels. The memory size should not be an issue: at 3 bpp color it only allocates about 96kB even with the double buffering enabled.

Could you explain how you got the 96kB? According to my calculations, it should take about 24kB.

ashthespy

ashthespy commented on Apr 7, 2025

@ashthespy

Hi!
The refactoring of getColourDepthSize and getDataPtr missed the parts for SPIRAM_DMA_BUFFER

Will this (rather naive) diff be sufficient? I am not sure where getColorDepthSize needs the full row and where it doesn't.

diff --git a/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp b/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp
index 86acc0f..117369a 100644
--- a/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp
+++ b/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp
@@ -629,7 +629,7 @@ void MatrixPanel_I2S_DMA::clearFrameBuffer(bool _buff_id)
     } while (colouridx);

 #if defined(SPIRAM_DMA_BUFFER)
-    Cache_WriteBack_Addr((uint32_t)row, fb->rowBits[row_idx]->getColorDepthSize());
+    Cache_WriteBack_Addr((uint32_t)row, fb->rowBits[row_idx]->getColorDepthSize(false));
 #endif

   } while (row_idx);
@@ -752,9 +752,9 @@ void MatrixPanel_I2S_DMA::setBrightnessOE(uint8_t brt, const int _buff_id)

 // switch pointer to a row for a specific colour index
 #if defined(SPIRAM_DMA_BUFFER)
-    ESP32_I2S_DMA_STORAGE_TYPE *row_hack = fb->rowBits[row_idx]->getDataPtr(0, _buff_id);
+    ESP32_I2S_DMA_STORAGE_TYPE *row_hack = fb->rowBits[row_idx]->getDataPtr(0);
     //Cache_WriteBack_Addr((uint32_t)row_hack, sizeof(ESP32_I2S_DMA_STORAGE_TYPE) * ((fb->rowBits[row_idx]->width * fb->rowBits[row_idx]->colour_depth) - 1));
-    Cache_WriteBack_Addr((uint32_t)row_hack, fb->rowBits[row_idx]->getColorDepthSize());
+    Cache_WriteBack_Addr((uint32_t)row_hack, fb->rowBits[row_idx]->getColorDepthSize(true));
 #endif
   } while (row_idx);
 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

      Participants

      @rigorka@mrcodetastic@ashthespy@Lukaswnd@board707

      Issue actions

        Problem with panels of over 32768 pixels size · Issue #755 · mrcodetastic/ESP32-HUB75-MatrixPanel-DMA