2019-12-06 03:10 AM
Hi all,
we have a STM32F103 MCU with an Epson TFT controller with an internal framebuffer. This framebuffer is attached via FSMC bus and memory-mapped at 0x68000000. We already have an application that draws graphics successfully to our display (using Atollic TrueStudio 9). Now we are evaluating touchGFX as an abstraction layer to create the GUI. What we have achieved so far:
Most important steps we are doing in pseudo-code:
init_our_hardware();
NoDMA dma;
LCD16bpp display;
NoTouchController tc
touchgfx_init() {
HAL& hal = touchgfx_generic_init<STM32F103HAL>(dma, display, tc, 320, 240, 0, 0);
hal.setFrameBufferStartAddress((uint16_t*)frameBuf0, 16, false, false);
hal.lockDMAToFrontPorch(false);
// if we uncomment the next two lines we can draw pixels on the TFT via the framebuffer pointer:
// Rect r(0,0,320,240);
// hal.flushFrameBuffer(r);
}
create_20hz_timer();
HAL::getInstance()->taskEntry();
Finally we have two issues that are not clear to us / that do not work:
When trying to address problem 1 we already fiddled with Model::tick() and HAL::tick() but without success.
Thanks in advance for any ideas!
2019-12-11 04:44 AM
You do not need to call flushFrameBuffer() manually.
It is called by TouchGFX hal after
endFrame();
What you do then to get the framebuffer pointer is to call:
HAL::getInstance()->lockFrameBuffer();
Based on Rect calculate where to go in the frame bufferand what to start transferring. Typically:
fbPtr += rect.y * lcd().framebufferStride() + rect.x * (bpp/8); //for 8/16/24bpp
Transfer data using your driver, considering:
rect.width;
rect.height;
You can use lcd().framebufferStride() to get the pointer to the next row.
If using DMA to transfer data you need additional synchronization like a semaphore to ensure that flushFrameBuffer(Rect& rect) does not return before transfer is completed.
When done call:
HAL::getInstance()->unlockFrameBuffer();
/Martin
2019-12-13 06:20 AM
Hello Martin,
thanks for the info. The manual calling of flushFrameBuffer was just a test to make sure our hardware works (as suggested in one of the linked threads). And indeed, calling flushFrameBuffer manually we can draw a pixel pattern to frameBuf0 in that function. So hardware setup should be OK. But flushFrameBuffer it is not called by touchGFX main loop. As described above, our application is generated via touch Designer. Maybe there is a link missing, because we don't have an OS, see below:
This currently is working (checked by stepping via debugger):
In our hw timer irq -> "touchgfx::HAL::getInstance()->vSync(); touchgfx::OSWrappers::signalVSync();"
Then, because we don't have an OS, we have stripped down the main loop to this code:
#if TRY_WITH_DESIGNER_CODE
// from tutorials/01_hello_world
Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(),
BitmapDatabase::getInstanceSize(), 0, 0);
Texts texts;
TypedText::registerTexts(&texts);
Texts::setLanguage(0); // Change '0' to the initial language, e.g. 'GB'
//The Keyboard uses the FontManager to get at FontProvider.
ApplicationFontProvider fontProvider;
FontManager::setFontProvider(&fontProvider);
// (*) if we uncomment the next two lines, program crashes:
// FrontendHeap& heap = FrontendHeap::getInstance();
// (void) heap; // we need to obtain the reference above to initialize the frontend heap.
HAL::getInstance()->registerEventListener(*(Application::getInstance()));
// --------------- end from tutorials/01_hello_world
#endif
// suggestion from https://touchgfx.zendesk.com/hc/en-us/articles/204887741
// instead of "HAL::getInstance()->taskEntry();" do it manually:
HAL::getInstance()->enableLCDControllerInterrupt();
HAL::getInstance()->enableInterrupts();
while(1)
{
OSWrappers::waitForVSync();
HAL::getInstance()->backPorchExited();
}
Via the timer, backPorchExited() is called regularly. There, we call:
virtual void backPorchExited() {
swapFrameBuffers();
HAL::getInstance()->endFrame();
}
but nothing happens, none of both flushFrameBuffer functions is ever called.
The first code snippet we can compile with TRY_WITH_DESIGNER_CODE defined or not defined - no change. If we define it and uncomment the two lines below the "// (*)" comment the program crashes, but at least from the call stack we can see that touchGFX tries to Screen::draw() something! To me it looks as if there is some initial setup missing:
Thread #1 57005 (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)
HardFault_Handler() at stm32f1xx_it.cpp:77 0x8004ae6
<signal handler called>() at 0xfffffff9
touchgfx::Screen::draw() at 0x802c676
touchgfx::Application::Application() at 0x802b978
touchgfx::MVPApplication::MVPApplication() at MVPApplication.hpp:58 0x8017cac
FrontendApplicationBase::FrontendApplicationBase() at FrontendApplicationBase.cpp:20 0x8017eac
FrontendApplication::FrontendApplication() at FrontendApplication.cpp:4 0x8018710
FrontendHeap::FrontendHeap() at FrontendHeap.hpp:68 0x80173e8
FrontendHeap::getInstance() at FrontendHeap.hpp:56 0x801731e
touchgfx_main() at main.cpp:157 0x80174ce
main() at main.cpp:1.300 0x802475e
Thanks and greetings!
2020-01-10 06:37 AM
Hi there,
unfortunately we still don't see an output from our Designer code (for the first test this simply should be a colored background with a rectangle in a different color in the center). Via the simulator we see this test. Here is the current pseudo-code with some remarks:
hardware_init()
// touchgfx init:
HAL& hal = touchgfx_generic_init<STM32F103HAL>(dma, display, tc, 120, 80, 0, 0)
hal.setFrameBufferStartAddress((uint16_t*)frameBuf0, 16, true, false)
//[1] Designer App init (?):
Bitmap::registerBitmapDatabase()
TypedText::registerTexts()
FontManager::setFontProvider()
//[2] FrontendHeap& heap = FrontendHeap::getInstance()
HAL::getInstance()->registerEventListener(*(Application::getInstance()))
HAL::getInstance()->enableLCDControllerInterrupt()
HAL::getInstance()->enableInterrupts()
HAL::getInstance()->unlockFrameBuffer()
while (1) {
OSWrappers::waitForVSync() //[2] waits for our timer
swapFramebuffers()
endFrame()
//[3] uint16_t* fbPtr = HAL::getInstance()->lockFrameBuffer()
//[3] *fbPtr = 0xffff
//[3] HAL::getInstance()->unlockFrameBuffer();
}
The hardware init and tgfx init seem to work fine, because when commenting out the last three lines ("//[3]") we can see the white dot on our TFT. Where we are not sure about is the section below "//[1]": what is missing to trigger the touchGFX draw() functions? Apart from the dot the screen just remains black. (Maybe this posting's subject now is misleading: initially we thought flushFrameBuffer() somehow triggers the Designer generated elements to call their draw() function...)
If we remove the comment "//[2]" we still get the stacktrace from our last comment. Is this related to the issue discussed in HardFault when upgrading TouchGFX 4.9.3 to 4.10.0? But for our STM32F103 there is no __HAL_RCC_CRC_CLK_ENABLE.
Thanks and greetings!
2020-02-28 01:14 AM
Short follow-up, in case anybody hits this thread. Issue solved, our test-app is running. Finally it was two things:
Greetings!
2020-02-28 01:20 AM
Thanks for the update. Do you still need me to take a look at something or are you good? Seems like you're calling a lot of functions manually, and i'd have to think about how that impacts the internals of the main event loop, etc.
flushFrameBuffer(Rect& rect) is only called if there's something to transfer. So, depending on your application, at least once.
/Martin
2020-02-28 02:12 AM
Hi Martin,
the test app currently runs fine with our display hardware, so no further help on this topic needed. Next step is to connect some digital inputs (our hardware buttons, the display doesn't have touch!) to the event loop. Maybe there new questions will be arising ... Side note: as you can see from the "timing" of my messages this is a test project (how to port our projects to touchGFX) that runs in parallel to daily work...
2020-05-05 08:53 AM
have started the CRC,But it still cannot go into the flushFrameBuffer().I've tried a lot. Am I missing something?Or is there any other possibility
2020-05-06 12:09 AM
Check out the article i wrote on using external events as triggers in the designer https://support.touchgfx.com/docs/development/board-bring-up/example-gpio
And check out the webinar i did on this topic: Connecting hardware to your UI.
/Martin
2020-05-06 12:10 AM
Could you start a new topic about your issue?