Showing results for 
Search instead for 
Did you mean: 

Touch-GFX-Sample with ILI9341-SPI wanted (dead or alive ;-)

Associate II


I'm now spent about three weeks with trying to set up a custom board with the M7-Core of a STM32H745BIT6 to work with an ILI9341-controlled display via SPI.

Interfacing the ILI and writing a bitmap to the display even with 50Mhz SPI Clock (with and without DMA) works perfectly. (=> handling the ILI itself is not the problem)

The online documentation for Tgfx 4.16 doesn't help me to run the system like it should. The Sniplets from the ST7789-Example in there for the L496-Disco-Boads seems to cover an older version of Tgfx cause there are used other (older?) C++methods)

Cause in CubeMX there is a very small hint, that for some reasons H745 is not supported (yet?), I also tried it with a H743-Nucleo Board but also without any success.

The Tgfx included example for the ILI9341-Shield (X-NUCLEO-GFX01M1) for the Nucleo-G071-Add-On Board is not really usable, cause the SPI-Communication is made on MCU-Register-Level (seems very different to H7) and it uses a partial framebuffer and external SPI-Flash but doesn't use FreeRTOS.

I checked a lot of things in my CubeIDE1.6.1 generated project including watching the semaphores „frame_buffer_sem“ and „vsync_sem“ => they never seems to change there status / never been taken? The methods in teh os-wrapper seems to never called....

Due to this, my additional code-lines to transmit data to the ILI in the files where I have to place it (follwing the documentation) never seems to run.

So my first 3 Questions:

  1. Does anybody has a hint for me where I can go on?
  2. Does anybody could share an example based on or closely to my configuration?
  • STM32H745BITG (using M7 Core)
  • No external Flash
  • ILI93241 4-lines SPI RGB 565
  • One complete Framebuffer in internal RAMFreeRTOS

3. Can I anywhere find better examples/explanations to do it by myself?

If it would be helpful I could share a similar project based on a H745- or H743-Nucleo so that it would be easier to „try at home“….

In my live I read a lot of explanations, some good and a much more bad, but that what Tgfx offers here is one of the worst I ever got. It doesn’t help me anything to get to the goal. I cannot believe, that it is so difficult to describe the few steps to set up a custom driver. Surely I understand, that ST/Tgfx cannot write exacly how to connect all display-controllers on the market, but hey…

 ….this is only „SPI“ – it only uses few functions to set a window and transfer a certain ammount of bytes. Thats all !! ?? Why you don't explain where to place the necessary commands.

This leads me to my fourth question:

4.    What is the the intention of ST/TouchGFX to supply such kind of documentation?

(Is this cause Tgfx want to sell additional individually made ready-to-use display-drivers or does ST wants that users only use exact the same MCU-&-Display-Types that are sold as Disco-/Eval-Baords?)

P.S.: I know, that 745 also offers LTDC or 747 even DSI, but the hardware is like it is, so I have to work with 745 and SPI

I also know, that external RAM/Flash would be better, but for my application it will do.

Thanks for your answers…

Best regards

Associate III

Hello. How about this?

The repository contains a TouchGFX project using ILI9341 with a partial framebuffer strategy and a Nucleo board. The project does not use FreeRTOS.

I think we have to pay attention to the code generated by CubeMX. The partial framebuffer strategy code generated by CubeMX will have to be manually modified even in the newest CubeMX version.


That projects are not created in the latest touchgfx version, so you have to check the following documentation at the same time.

From the point of view of transferring data to ILI9341, it is important to write your custom code in TouchGFXHAL::flushframebuffer.

If you want to update all the region of LCD, you need to send all the framebuffer data in TouchGFXHAL::flushframebuffer, otherwise you must select the transmit data from Rect in TouchGFXHAL::flushframebuffer.

Associate II

Thank's four your reply,

yes, I found this example and got it easily running on a Nucelo 64-F411 Board. No Problem.

But transfering the ILI-specific Files to the CubeIDE-generated H745-Nucleo-Project and adding the necessary lines (as discribed in the documentation) does not run.

I tried it with and without FreeRTOS, with partial and single complete framebuffer.

It ended in comparing the files (also the Tgfx - generated ones) line by line. Yes, there are small differences between them - in Comments and some parts which are quotet not to be relevant for this setup (no RTOS, partial buffer). Comparing both also with the documentation shows additional differences...

No chance...

As a second attempt I took the complete ILI-Files and the complete TGFX-Files from Kotetsuy's example and inserted this in a freshly startet "nearly naked" CubeIDE-H745-project (= only the CMSIS, Startup and HAL-Files for the basic peripheral and IO (TIM,SPI, RCC, etc) but without activating Tgfs in there.

Also no success.


In a complete new set up I put my working code for transfering data to the ILI into TouchGFXHAL::flushframebuffer - but this code never runs !?? (setted Breakpoints in this code-lines are never reached) (...tried this with my custom board H745BIT6, Nucleo-H745 and Nucleo H743 - all the same => doesn't work)

SPI Communication in gereneral works - for checking this I set some pixels directly after the init of the ILI.

But after reaching the touchgfx_taskEntry there is no more activity seen on the SPI. Monitoring the SPI with a logic analyzer shows complete silence. :(

I try to upload my code for a H745-Nucleo (and eventually fpr the H743) this evening.


additional tipps are welcome...

Thanks so long...

Chief II

Show how you generate vsync events. Too your screen refresh code...

Associate II

Concerning to the link to Kotetsuy's example posted by qq3g7bad I remembered me wrong about the name - sorry for this confusion. I also found the projects from Kotetsuy, but I started with another project - the one from PeraZver / Helentronica. cause this F411-Nucleo-Board I had already here at my site.

I opended PeraZvers .ioc-File in CubeIDE 1.6.1 to generate the missing code-parts and also the Touch-GFX-File to generate the GUI-Files.

First there were two errors in TouchGFXGeneratedHAL.cpp where I had to correct DisplayDriverTransmitBlock into touchgfxDisplayDriverTransmitBlock.

Then the build ran through without any issues and after flashing the Board the application works and shows the ADC-Value in the graph-window. The location of the zero-line can be moved via the slider => works all perfect.

Then I set up new H743-project with everything as close as possible to PeraZvers project. The main difference is that I had to use SPI3 instead of SPI2 for the Touchscreen.

I copied the driver-files from PeraZvers. In all Tgfx-Files generated by Tgfx itself I copied the code snipplets from the corresponding files from PeraZvers.

The build was completed without issue, but when reaching the MX_TouchGFX_Process() the application run into a hardfault.

After adding the line


it shows, that in detail it is a busfault.

I attached my project - but due to the large size, I deleted the Middlewares-Folder. To recover it you have to open H743ili9341tgfx.touchgfx wiht Tgfx-Desginer via by dubble-click directly in the CubeIDE Project explorer.

Still confusing...

The vsync-event is created by the TIM2-Timer - exactly like it is in the example from PeraZver

Thank you for sharing your project. It looks almost fine to me except for only one thing.

In my case using STM32H730 with ILI9341, I fixed flushFrameBuffer() and startNewTransfer() in TouchGFXHAL or TouchGFXGeneratedHAL. I think it is due to the difference of TouchGFX version. When I use Version 4.13.0, my code which is similar to your code runs successfully. But when I update TouchGFX version to 4.16.1, the same code causes failure.

So, I suggest you comment out these region, flushFrameBuffer() and startNewTransfer() in TouchGFXHAL or TouchGFXGeneratedHAL. If it is going to be fine, the problem is there. I fixed my code with reference to TouchGFX official tutorial I wrote in previous message.


I think the code you have to change is TouchGFXHAL.cpp/hpp, not TouchGFXGeneratedHAL.cpp/hpp. Because when you generate new code by CubeMX, your code written in TouchGFXGeneratedHAL.cpp/hpp is overwritten. That is tragedy for us...

Chief II

Maybe good or only one , that i see is project generated from TouchGFX for H747 DSI. Then compare and change DSI/LTDC parts to SPI.

When you generate TouchGFX read Boardconfig.cpp in target folder usw...

Associate II

Thanks for all the ideas so far..

I hope that I understood the suggestion from qq3g7bad right - I commented out evereything between the curly braces of flushFrameBuffer() & startNewTransfer() in TouchGFXHAL and TouchGFXGeneratedHAL.

…but it still ends up in a Hardfault/Busfault.

By stepping-trough / stepping-in it goes the following way:

MX_TouchGFX_Process(); // in main.c


touchgfx_taskEntry(); // in app_touchgfx.c


hal.backPorchExited(); // in TouchGFXConfiguration.cpp


(...some step in between here are not quoted..)


swapFrameBuffers(); // in HAL.hpp

then the next line in HAL.hpp is


stepping into or over this tick(); leads to the Hardfault/Busfault.

I also tried to set up the project with Tgfx 4.13. There seems to be diffences in the code (names of functions methods and variables), but the result ist he same: Hardfault

The idea to start from the H747 DSI-example I already had, but for the H747-Disco & H747Eval boards Tgfx 4.15 & 4.16.1 creates another project structure. without any .ioc-file. It is possible to open the foder-structure in CubeIDE, but it seems, that all the files are not handled like CubeIDE shoudl do it with .c/.cpp/.h/.hhh-files. Yes, maybe this all can be corrected by hand - but... :( I have non of the boards, so I cannot try to flash it directly out of Tgfx)

Creating projctes with Tgfx for other Disco-Boards (F429, F469 & F746) works fine for importing the Code into CubeIDE and also flashing the Boards directly out of Tgfxy.

Funny thing: a breakpoint which I sat at the equivalent tick(); (which causes the Hardfault in my H743) in a Tgfx-generated project running on a F469 Disco is never been triggered. The function  virtual void backPorchExited() is never called.. !?

Ideas and hints are still welcome - I will report when having success or other faults 😉

Thank you all

I also think about to switch to STemWIN - does anybody have a working ILI9341-SPI-driver for this framework which he would share?

Chief II
Associate II

I am facing this issue in my account and want to fix this issue also I need some help about touchgfxsample because I never faced issue in it before.