cotsos Posted February 22, 2017 Report Posted February 22, 2017 (edited) First of all let me thank you for the ugfx, it is couple of weeks i have been playing with it and it looks awesome. I have met the following issue on an STM32F469 Discovery, BareMetal, with the display and touch driver implementations from the other topic around here So in a very basic application switching between two pages with a page change button on each, when i have just the gfxYield(); and the event switch in the main function, everything works correctly. When i insert a simple delay within the main while loop, occasionally, most frequently with prolonged key presses on the buttons, I will get the button frozen in the pressed state and no further gui response - obviously with no touch input. The gui may return to responsive sometimes after some time, some other times not. the main loop: while (1) { /* USER CODE END WHILE */ // HAL_Delay(50); gfxYield(); // Get an event pe = geventEventWait(&glistener,0); switch (pe->type) { case GEVENT_GWIN_BUTTON: if (((GEventGWinButton*)pe)->gwin == ghButton1) { guiShowPage(1); } if (((GEventGWinButton*)pe)->gwin == ghButton2) { guiShowPage(0); } break; default: break; } Edited February 22, 2017 by cotsos
Joel Bodenmann Posted February 22, 2017 Report Posted February 22, 2017 Hello @cotsos and welcome to the µGFX community! That is expected behavior. For various reasons (which all boil down to saving resources), GEVENT doesn't internally buffer or queue up events. Each listener provides its own buffer with the size of one event. Therefore, if you're not listening you'll miss it. This is a design choice that was made to vastly simplify code complexity and decrease resource usage because the event system is only used for GUI interactions with a user which are always very slow. You get the press but not the release because the press event fits into the one-event sized buffer. Then the release event happens but it can't be stored anyway. The proper way of doing this is using the second parameter of the geventEventWait() function which is the timeout parameter. In a usual application where the event loop runs in its own thread you'd leave this to TIME_INFINITE. Using a timeout of 0 is definitely a bad approach because you're almost guaranteed to miss the event(s). I hope that helps. By the way: Can you share with us what kind of performance you get out of that STM32F469i-Discovery driver from the other thread? Just the overall user experience, not actual measurements. Is it so slow that you see the image being rendered or is everything blazingly fast?
cotsos Posted February 22, 2017 Author Report Posted February 22, 2017 1 hour ago, Joel Bodenmann said: By the way: Can you share with us what kind of performance you get out of that STM32F469i-Discovery driver from the other thread? Just the overall user experience, not actual measurements. Is it so slow that you see the image being rendered or is everything blazingly fast? The driver is pretty much usable and quite fast, with an issue though - ie for item locations close to the diagonal you can easily detect tearing from the panel scan when pressing / depressing for example, guess has to do with DSI in video mode which does stream the framebuffer from the ram continuously.
inmarket Posted February 23, 2017 Report Posted February 23, 2017 There are a couple of errors in your code that also may be causing your problem... 1. Don't use HAL_Delay. It prevents uGFX being able to respond to events. 2. The 2nd parameter to geventEventWait is a timeout. Specifing zero means to not wait for an event - just return one if there is one available. The error occurs if there is no event available - the function will return NULL. You are however dereferencing the result without checking for NULL first. The correct way to do what you are currently trying to do is to drop the HAL_Delay and the gfxYield and instead put 50 as the 2nd parameter to geventEventWait. Also check for NULL before testing the type. The other solution is to use TIME_FOREVER for the 2nd parameter (still dropping HAL_Delay and gfxYield). In that case you are guaranteed it won't return until it has an event and you won't have to check for NULL.
cotsos Posted February 23, 2017 Author Report Posted February 23, 2017 I inserted HAL_Delay as a way to simulate a large blocking event. I set the timeout 0 wanting to avoid spending the timeout value waiting for an event. What I did was follow your instructions from 2, inserting a check for NULL, as in the code below, and seems the issue is gone while (1) { /* USER CODE END WHILE */ // HAL_Delay(50); gfxYield(); // Get an event pe = geventEventWait(&glistener,0); if (pe != NULL){ switch (pe->type) { case GEVENT_GWIN_BUTTON: if (((GEventGWinButton*)pe)->gwin == ghButton1) { guiShowPage(1); } if (((GEventGWinButton*)pe)->gwin == ghButton2) { guiShowPage(0); } break; default: break; }} /* USER CODE BEGIN 3 */ }
Joel Bodenmann Posted February 23, 2017 Report Posted February 23, 2017 Usually you'd want your event loop to run in its own thread so you'd use TIME_INFINITE as the timeout parameter of geventEventWait(). This solves all your problems. Keep in mind that you have to use gfxSleepMilliseconds() instead of HAL_Delay() in any case as pointed out by @inmarket.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now