ESP32-HUB75-MatrixPanel-DMA
ESP32-HUB75-MatrixPanel-DMA copied to clipboard
NO_GFX/Adafruit_GFX: m_cfg struct seems to be "wrong" when calling "allocateDMAmemory", causing a crash
Hi!
I have a very strange problem when using the lib with Adafruit_GFX.
When using the lib with NO_GFX, it does not occur and the lib/panel works as expected.
- Latest master
- https://github.com/martinberlin/Adafruit-GFX-Library-ESP-IDF
- ESP32-S3
- PlatformIO 6.6.0
- ESP-IDF 5.2.1
- P5 64x32 1/8 scan (works with VirtualMatrixPanel)
When compiling without NO_GFX (so with Adafruit_GFX), I get a "division by zero" exception after calling "begin()":
`HUB75_I2S_CFG mxconfig(PANEL_RES_X * 2, PANEL_RES_Y / 2); // for 1/8-scan, double the actual width and half the actual height mxconfig.driver = mxconfig.FM6124; mxconfig.setPixelColorDepthBits(8); dma_display = new MatrixPanel_I2S_DMA(mxconfig);
dma_display->begin();
dma_display->setBrightness8(5); virtualDisp = new VirtualMatrixPanel((*dma_display), 1, 1, PANEL_RES_X, PANEL_RES_Y); virtualDisp->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH);`
I (634) begin(): Using GPIO 4 for R1_PIN I (634) begin(): Using GPIO 5 for G1_PIN I (644) begin(): Using GPIO 6 for B1_PIN I (644) begin(): Using GPIO 7 for R2_PIN I (654) begin(): Using GPIO 15 for G2_PIN I (654) begin(): Using GPIO 16 for B2_PIN I (664) begin(): Using GPIO 18 for A_PIN I (664) begin(): Using GPIO 8 for B_PIN I (664) begin(): Using GPIO 3 for C_PIN I (674) begin(): Using GPIO 42 for D_PIN I (674) begin(): Using GPIO -1 for E_PIN I (684) begin(): Using GPIO 40 for LAT_PIN I (684) begin(): Using GPIO 2 for OE_PIN I (694) begin(): Using GPIO 41 for CLK_PIN I (694) LEDdrivers: MatrixPanel_I2S_DMA - initializing FM6124 driver... I (704) gpio: GPIO[4]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (714) gpio: GPIO[7]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (724) gpio: GPIO[5]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (734) gpio: GPIO[15]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (744) gpio: GPIO[6]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (754) gpio: GPIO[16]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (764) gpio: GPIO[41]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (764) gpio: GPIO[40]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (774) gpio: GPIO[2]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 E (784) begin(): chain_length: 1 E (794) begin(): clkphase: 1 E (794) begin(): double_buff: 0 E (794) begin(): driver: 1 E (804) begin(): i2sspeed: 15000000 E (804) begin(): latch_blanking: 2 E (814) begin(): min_refresh_rate: 60 E (814) begin(): mx_height: 16 E (814) begin(): mx_width: 128 E (824) begin(): getPixelColorDepthBits: 8 I (824) I2S-DMA: Free heap: 294080 I (834) I2S-DMA: Free SPIRAM: 0 E (834) I2S-DMA: chain_length: 0 E (834) I2S-DMA: clkphase: 0 E (844) I2S-DMA: double_buff: 0 E (844) I2S-DMA: driver: 0 E (854) I2S-DMA: i2sspeed: 1 E (854) I2S-DMA: latch_blanking: 128 E (854) I2S-DMA: min_refresh_rate: 16 E (864) I2S-DMA: mx_height: 0 E (864) I2S-DMA: mx_width: 0 E (864) I2S-DMA: getPixelColorDepthBits: 0 I (874) I2S-DMA: allocating rowBitStructs with pixel_color_depth_bits of 0 E (884) I2S-DMA: m_cfg.mx_height: 0 E (884) I2S-DMA: ROWS_PER_FRAME: 0 I (894) I2S-DMA: Allocating 0 bytes memory for DMA BCM framebuffer(s). I (894) I2S-DMA: Minimum visual refresh rate (scan rate from panel top to bottom) requested: 16 Hz Guru Meditation Error: Core 0 panic'ed (IntegerDivideByZero). Exception was unhandled. Core 0 register dump: PC : 0x4202146e PS : 0x00060330 A0 : 0x82003179 A1 : 0x3fca1e90
A2 : 0x3fcb09d0 A3 : 0x3b9aca00 A4 : 0x00000000 A5 : 0x00000000 A6 : 0x00000000 A7 : 0x00000000 A8 : 0x00000000 A9 : 0x00000000
A10 : 0x00000000 A11 : 0x000000e8 A12 : 0x00000000 A13 : 0x00008000 A14 : 0x3c0604fc A15 : 0x00000010 SAR : 0x00000001 EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x400556d5 LEND : 0x400556e5 LCOUNT : 0xfffffffd
Backtrace: 0x4202146b:0x3fca1e90 0x42003176:0x3fca1ee0 0x4200385b:0x3fca1f00 0x4037f078:0x3fca1fc0 0x40381df9:0x3fca1ff0
I added a lot of Log-Outputs, tracing the HUB75_I2S_CFG information through the calls: It looks like "begin()" itself ist still using the "right" cfg-data, but once "allocateDMAmemory" is called, somehow the wrong HUB75_I2S_CFG struct is accessed. When comparing the function definition of "allocateDMAmemory()" with "configureDMA(const HUB75_I2S_CFG &opts)", "shiftDriver(const HUB75_I2S_CFG &opts)", "fm6124init(const HUB75_I2S_CFG &_cfg)" etc., it strikes me that all other have the dependency injection giving the HUB75_I2S_CFG as an argument. Still, if I hand this over as an argument, it fails as ROWS_PER_FRAME seems to be calculated once upon construction, which still is zero.
Any help would be highly appreciated!
Greetings,
You build your project from zero in Platform.io, or import from Arduino IDE Project? If you did so, check your board selection, I imagine You build a simple basic example, as the blink and upload to your board, right? Test, if all works fine, re-install (uninstall, then install again) the Adafruit GFX Library. Check also, y if Platform.io is updated y vs code...
Thanks for your reply!
Can you please explain how the board selection might affect above setup?
Do you think a working "blink" example will give some more insights - as stated the "NO_GFX" version is already working with the panel as well.
The Adafruit GFX lib is included as a GIT submodule and up-to-date.
I don't think it is directly related to the specific Adafruit_GFX lib, it is more related to the was how the MatrixPanel_I2S_DMA is implemented and how the CFG-struct gets thrown around:
Log with "NO_GFX" (working):
E (441) CFG constructor: min_refresh_rate: 60 E (451) CFG constructor: getPixelColorDepthBits: 8 E (451) CFG constructor: CFG-STRUCT ADDRESS: 3fca1f7c E (461) Freelap: min_refresh_rate: 60 E (461) Freelap: getPixelColorDepthBits: 8 E (471) Freelap: CFG-STRUCT ADDRESS: 3fca1f7c E (471) CFG constructor: min_refresh_rate: 60 E (481) CFG constructor: getPixelColorDepthBits: 8 E (481) CFG constructor: CFG-STRUCT ADDRESS: 3fcb0a18 E (491) arg to setCfg: min_refresh_rate: 60 E (491) arg to setCfg: getPixelColorDepthBits: 8 E (501) arg to setCfg: CFG-STRUCT ADDRESS: 3fcb0a18 E (501) m_cfg after setCfg: min_refresh_rate: 60 E (511) m_cfg after setCfg: getPixelColorDepthBits: 8 E (521) m_cfg after setCfg: CFG-STRUCT ADDRESS: 3fcb0a18 E (521) Freelap: min_refresh_rate: 60 E (531) Freelap: getPixelColorDepthBits: 8 E (531) Freelap: CFG-STRUCT ADDRESS: 3fcb0a18 I (541) begin(): Using GPIO 4 for R1_PIN I (541) begin(): Using GPIO 5 for G1_PIN I (551) begin(): Using GPIO 6 for B1_PIN I (551) begin(): Using GPIO 7 for R2_PIN I (551) begin(): Using GPIO 15 for G2_PIN I (561) begin(): Using GPIO 16 for B2_PIN I (561) begin(): Using GPIO 18 for A_PIN I (571) begin(): Using GPIO 8 for B_PIN I (571) begin(): Using GPIO 3 for C_PIN I (581) begin(): Using GPIO -1 for D_PIN I (581) begin(): Using GPIO -1 for E_PIN I (591) begin(): Using GPIO 40 for LAT_PIN I (591) begin(): Using GPIO 2 for OE_PIN I (601) begin(): Using GPIO 41 for CLK_PIN I (601) LEDdrivers: MatrixPanel_I2S_DMA - initializing FM6124 driver... I (611) gpio: GPIO[4]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (621) gpio: GPIO[7]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (631) gpio: GPIO[5]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (641) gpio: GPIO[15]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (641) gpio: GPIO[6]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (651) gpio: GPIO[16]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (661) gpio: GPIO[41]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (671) gpio: GPIO[40]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (681) gpio: GPIO[2]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 E (691) begin(): min_refresh_rate: 60 E (691) begin(): getPixelColorDepthBits: 8 E (701) begin(): CFG-STRUCT ADDRESS: 3fcb0a18 I (701) I2S-DMA: Free heap: 294112 I (711) I2S-DMA: Free SPIRAM: 0 E (711) allocateDMAmemory: min_refresh_rate: 60 E (721) allocateDMAmemory: getPixelColorDepthBits: 8 E (721) allocateDMAmemory: CFG-STRUCT ADDRESS: 3fcb0a18 I (731) I2S-DMA: allocating rowBitStructs with pixel_color_depth_bits of 8 E (741) allocateDMAmemory: ROWS_PER_FRAME: 8 I (741) I2S-DMA: Allocating 16384 bytes memory for DMA BCM framebuffer(s). I (751) I2S-DMA: Minimum visual refresh rate (scan rate from panel top to bottom) requested: 60 Hz W (761) I2S-DMA: lsbMsbTransitionBit of 0 gives 57 Hz refresh rate. W (771) I2S-DMA: lsbMsbTransitionBit of 1 gives 114 Hz refresh rate. W (771) I2S-DMA: lsbMsbTransitionBit of 1 used to achieve refresh rate of 60 Hz. Percieved colour depth to the eye may be reduced. I (791) I2S-DMA: DMA has pixel_color_depth_bits of 7 I (791) I2S-DMA: Recalculated number of DMA descriptors per row: 64 I (801) I2S-DMA: 512 DMA descriptors linked to buffer data. I (811) S3: Clock divider is 12 I (811) I2S-DMA: DMA setup completed I (4011) main_task: Returned from app_main()
Note once the CFG-struct gets handed over to the constructor of "MatrixPanel_I2S_DMA" its address stays the same (3fcb0a18).
Non-working version (without NO_GFX):
E (443) CFG constructor: min_refresh_rate: 60 E (443) CFG constructor: getPixelColorDepthBits: 8 E (453) CFG constructor: CFG-STRUCT ADDRESS: 3fca1f7c E (453) Freelap: min_refresh_rate: 60 E (463) Freelap: getPixelColorDepthBits: 8 E (463) Freelap: CFG-STRUCT ADDRESS: 3fca1f7c E (473) CFG constructor: min_refresh_rate: 60 E (473) CFG constructor: getPixelColorDepthBits: 8 E (483) CFG constructor: CFG-STRUCT ADDRESS: 3fcb0a38 E (483) arg to setCfg: min_refresh_rate: 60 E (493) arg to setCfg: getPixelColorDepthBits: 8 E (493) arg to setCfg: CFG-STRUCT ADDRESS: 3fcb0a38 E (503) m_cfg after setCfg: min_refresh_rate: 60 E (513) m_cfg after setCfg: getPixelColorDepthBits: 8 E (513) m_cfg after setCfg: CFG-STRUCT ADDRESS: 3fcb0a38 E (523) Freelap: min_refresh_rate: 60 E (523) Freelap: getPixelColorDepthBits: 8 E (533) Freelap: CFG-STRUCT ADDRESS: 3fcb0a38 I (533) begin(): Using GPIO 4 for R1_PIN I (543) begin(): Using GPIO 5 for G1_PIN I (543) begin(): Using GPIO 6 for B1_PIN I (553) begin(): Using GPIO 7 for R2_PIN I (553) begin(): Using GPIO 15 for G2_PIN I (553) begin(): Using GPIO 16 for B2_PIN I (563) begin(): Using GPIO 18 for A_PIN I (563) begin(): Using GPIO 8 for B_PIN I (573) begin(): Using GPIO 3 for C_PIN I (573) begin(): Using GPIO -1 for D_PIN I (583) begin(): Using GPIO -1 for E_PIN I (583) begin(): Using GPIO 40 for LAT_PIN I (593) begin(): Using GPIO 2 for OE_PIN I (593) begin(): Using GPIO 41 for CLK_PIN I (603) LEDdrivers: MatrixPanel_I2S_DMA - initializing FM6124 driver... I (603) gpio: GPIO[4]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (613) gpio: GPIO[7]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (623) gpio: GPIO[5]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (633) gpio: GPIO[15]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (643) gpio: GPIO[6]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (653) gpio: GPIO[16]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (663) gpio: GPIO[41]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (673) gpio: GPIO[40]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 I (683) gpio: GPIO[2]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 E (693) begin(): min_refresh_rate: 60 E (693) begin(): getPixelColorDepthBits: 8 E (703) begin(): CFG-STRUCT ADDRESS: 3fcb0a38 I (703) I2S-DMA: Free heap: 294080 I (703) I2S-DMA: Free SPIRAM: 0 E (713) allocateDMAmemory: min_refresh_rate: 16 E (713) allocateDMAmemory: getPixelColorDepthBits: 0 E (723) allocateDMAmemory: CFG-STRUCT ADDRESS: 3fcb0a18 I (733) I2S-DMA: allocating rowBitStructs with pixel_color_depth_bits of 0 E (733) allocateDMAmemory: ROWS_PER_FRAME: 0 I (743) I2S-DMA: Allocating 0 bytes memory for DMA BCM framebuffer(s). I (753) I2S-DMA: Minimum visual refresh rate (scan rate from panel top to bottom) requested: 16 Hz Guru Meditation Error: Core 0 panic'ed (IntegerDivideByZero). Exception was unhandled. Core 0 register dump: PC : 0x42020fa2 PS : 0x00060330 A0 : 0x82002f69 A1 : 0x3fca1ea0 A2 : 0x3fcb09d0 A3 : 0x3b9aca00 A4 : 0x00000000 A5 : 0x3fcb0a40
A6 : 0x00000000 A7 : 0x00000000 A8 : 0x00000000 A9 : 0x00000000 A10 : 0x00000000 A11 : 0x000000e8 A12 : 0x00000000 A13 : 0x00008000
Please observe the address of the CFG-struct: everything is fine until "allocateDMAmemory" grabs it from the "wrong" address (in this case 3fcb0a18 (but 3fcb0a38 would be correct).
I somehow think "allocateDMAmemory" does not know the correct offset as the inheritance from the "Adafruit_GFX" class offsets some variables of the derived class...