2024-11-06 07:42 AM - edited 2024-11-07 04:11 AM
I have a custom board, which uses STM32H747IXH6 and MB1166 LCD screen from the related discovery board. I am trying to get TouchGFX up and running on this custom setup, but in my PCB design, I missed out the dedicated TE pin in the connector (I'm following the RaspberryPi DSI convention of DSI CLK, Data Lanes and I2C only). I can initialise the display, but I cannot get my TouchGFX application running. The process at the moment is as follows:
Init DSI Host
Reset the LCD display
Config DSI PLL
Config Host Timeouts
Config PHY Timers
Config LPCommand
Config AdaptedCommand Mode
Invert clock and data pins (to correct for PCB error)
Register busIO for OTM8009A
Init OTM8009A (as per Discovery examples)
Config Flow Control
Force RX Low Power
Init LTDC
Active low VSYNC and HSYNC polarity
803x483 total width and height (800x480 + porches)
Format RGB888
Double frame buffer
Start address 0xD0000000
Init FMC (IS42S32800J)
Init as Bank 2
Init TouchGFX
Start TouchGFX Thread
Now when TouchGFX starts, taskEntry sits at OSWrappers::waitForVSync(); I assume that this VSync should be called from HAL_DSI_TearingEffectCallback in TouchGFXHAL, but this callback never fires. It appears a tearing effect is requested earlier in taskEntry by LCD_ReqTear, which in the discovery code writes OTM8009A_CMD_TEEON to the LCD driver. I have modified LCD_ReqTear to send OTM8009A_CMD_WRTESCN with a param of 533 (0x2,0x15) instead, as per the CMDMode_TearingEffect example, but the TearingEffectCallback is still not triggered.
What am I missing here? I can't attach the full project for confidentiality reasons, but I'm happy to share main.c and TouchGFXHAL.cpp
I'm aware also that TearingEffectCallback and EndOfRefreshCallback still contain code that assumes the display is split in two (as per both the examples I have borrowed from), I wouldn't have thought this was the issue however, as neither of these callbacks ever fire.
Edit
I have updated taskEntry to enable the DSI interrupts and call a DSI_Refresh before the first wait for Vsync, but the callbacks still don't fire. Examining the SFRs shows that the DSI transfer hangs on BUSY (DSI_WISR), so presumably the callback doesn't fire due to the refresh never finishing. What could be preventing the transfer from occurring?
2024-11-14 04:30 AM
I did have enableMCULoadCalculation(true) set, but I have now removed it, along with mcuInstr.init() and setMCUInstrumentation(&mcuInstr). Unfortunately, this doesn't change anything.
2024-11-14 04:34 AM
One difference from STM32H747DISCO is that I am using the IS42S32800J SRAM chip instead of the IS32S32160D on the DISCO board. I have half as much memory at 256Mb instead of 512, but the access parameters are all the same (except for one fewer address line). This is compensated for in the FMC init, so I wouldn't think it would cause a problem.
2024-11-14 04:50 AM
I did not see this post when typing my previous answer.
You can try to disable DCache and see if TouchGFX can complete its loop.
It can also be an issue with unaligned access.
Are you running your own project or a modified standard project?
I would try to get the standard project to compile and run without worrying about the screen first.
If you comment out the DSI init and all the "extern C"-code in TouchGFXHAL, I believe it would run if you just call
2024-11-14 05:00 AM
This is the stack from the point that the task locks up
Without access to the HAL source, I can't probe this any further
2024-11-14 06:26 AM
It looks like the OS thread hangs when it is set to delay.
Have you set up your OS according to Real Time Operating System | TouchGFX Documentation?
There is a thread delay in the draw loop for some refresh strategies. Do you have an implementation of
2024-11-14 06:58 AM
I don't have an implementation of getTFTCurrentLine() in TouchGFXHAL, no.
I have tried going from an example - just the blankUI example in TouchGFX designer for the STM32H747I-DISCO. I have had to make the following modifications to get it up and running:
- Change DSI timings so OTM8009AInit() works correctly
- Change LCD reset pin to PE6
- Remove external flash from linker script (hardware implementation is incorrect)
-Disabled touch controller init
-20ms timer calling touchgfx_signalVSyncTimer();
The touchgfx task starts and cycles as expected, with flushframebuffer being called. BUT, because there is no TE pin, the tearing effect callback never gets called and the below code never executes - I'm back at square 1! What should trigger this code instead of the Tearing Effect?
2024-11-14 08:10 AM
Sorted! I got it working with the example and then copied the TouchGFXHAL code to my custom project. The colours are wrong, but we're off to a good start!
2024-11-15 01:47 AM
Good to hear!
As I said, you would probably be better off with two frame buffers, and you should definitely find a way to get a TE signal, but I guess you will just have to experiment a bit with the registers on the board. I would suggest enabling everything related to TE and seeing if you get something. You will get tearing regardless of your frame buffer strategy unless you can get the display and the MCU in sync.
Trying to initialize the display in video mode is also an option, then it will be synced by the LTDC V-blank signal.
The display on MB1166 is actually a portrait mode display, which is the reason for the "split" screen code. I would suggest initializing it as such, setting the LTDC and framebuffers to 480x800 and running a rotated UI in TouchGFX if you discard the split screen code.