Jump to content

Bare Metal / STM32F469 / Touch Issues


cotsos

Recommended Posts

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 by cotsos
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 */

  }

 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...