cancel
Showing results for 
Search instead for 
Did you mean: 

Hardware button

MEde.1
Associate III

I have been struggling for a few days now with trying to trigger an interaction within TouchGFX (V4.23.1) via a hardware button.

The board is a STM32H747i Discovery. The board bring up has been completed with a standard TouchGFX template and the touch screen and display are working fine.

I have verified that I can toggle LED4 with the wake button suing a RTOS function

 

 

 

#define LED4_GPIO_Port GPIOI

#define LED4_Pin GPIO_PIN_15

...

/* USER CODE BEGIN RTOS_THREADS */

osThreadId_t toggleLEDTaskHandle;

const osThreadAttr_t toggleLEDTask_attributes = {

.name = "toggleLEDTask",

.stack_size = 128 * 4, // Adjust stack size as needed

.priority = (osPriority_t) osPriorityNormal,

};



toggleLEDTaskHandle = osThreadNew(ToggleLEDTask, NULL, &toggleLEDTask_attributes);



/* USER CODE END RTOS_THREADS */

...

/* USER CODE BEGIN 4 */

void ToggleLEDTask(void *argument) {

uint8_t ledState = 0; // Track LED state, 0 = off, 1 = on



for(;;) {

if(HAL_GPIO_ReadPin(BTN_USER_GPIO_Port, BTN_USER_Pin) == GPIO_PIN_SET) {

key = 1; // Set key to 1 to indicate button press



// If button is pressed, toggle the LED state

ledState = !ledState; // Toggle state

HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, ledState ? GPIO_PIN_SET : GPIO_PIN_RESET);



// Debounce delay and wait for button release

osDelay(200); // Adjust delay as needed for debounce

while(HAL_GPIO_ReadPin(BTN_USER_GPIO_Port, BTN_USER_Pin) == GPIO_PIN_SET){

osDelay(10); // Short delay to wait for button release

}

}

osDelay(10); // Small delay to prevent the task from hogging CPU resources

}





}







/* USER CODE END 4 */

...

 

 

I am pretty confident that the LED and USER_BTN are configured correctly as the LED toggles when I press the USR_BTN.

 

I am trying to follow this:

 

https://support.touchgfx.com/docs/development/scenarios/example-gpio

 

I am unsure where this code should be added:

 

MEde1_0-1708011935228.png

 

I have modified this:

MEde1_1-1708011989401.png

 

Everything compiles but whilst the LED toggles and the BTN_USER is selectable in the TouchGFX designer interactions drop down, the interaction doesn't get triggered. I am a bit stumped.

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
MEde.1
Associate III

Hi Louis,

Thanks for your reply,

I managed to get the button working by following the steps in these two videos (I have added the links below so that if someone else needs to follow them, he gives recipes for both polling and interrupt-based, both of which work)  :

https://www.youtube.com/watch?v=ufvJ5bcesL8

https://www.youtube.com/watch?v=QgEDSjvGAlk&t=189s

However, TouchGFX Designer 4.23.1 can't program and run target. However, CubeIDE can compile and run the code. Changes can be made in designer and once the code is generated you can use CubeIDE to flash the board and run the code.

I have tried your suggestion of putting the files in the same folder:

 

MEde1_1-1708440680959.png

And whilst I can get it to compile and run in CubeIDE (after adding the path to the "target" directory) TouchGFX Designer 4.23.1 can't actually "program and run target". 

 

 

View solution in original post

10 REPLIES 10
LouisB
ST Employee

Hello @MEde.1 ,

Can you show me a picture of your CubeMx GPIO setup ?
And are you using CubeIDE ?

 

Regards, 

Louis BOUDO
ST Software Developer | TouchGFX

Sure, using CubeMX and CubeIDE

I have tried triggering it with an interrupt as well and again I toggle the LED but not trigger the interaction in TouchGFX. I just feel I am missing a step!

 

The GPIO setup

 

MEde1_0-1708072387917.png

 

LouisB
ST Employee

In CubeMX Try to set your PC13 to pull-up instead,

1) Create your button controller

Then go to CubeIDE, and in "STM32H747I-DISCO_CM7/Application/User/Core" do New->File  :

step1.png

Name the new file "MyButtonController.cpp" (Give it the name you want, they called it "H783ButtonController" in the tutorial), edit that file :

 

 

#include <MyButtonController.hpp>
#include <main.h>
#include <touchgfx/hal/HAL.hpp>

void MyButtonController::init()
{
	previousState = 0x00;
}

bool MyButtonController::sample(uint8_t& key)
{

	if ((HAL_GPIO_ReadPin(BTN_USER_GPIO_Port, BTN_USER_Pin) == GPIO_PIN_RESET) && previousState == 0x00)
	{
		previousState = 0xFF;
		key = 1; // here key determines which key will be trigger in TouchGFX
		return true;
	}
    previousState = 0x00;
    return false;
}

 

 

 

And then create a ".hpp" in "User/Core/Inc" :

 

#ifndef MyBUTTONCONTROLLER_HPP_
#define MyBUTTONCONTROLLER_HPP_

#include <platform/driver/button/ButtonController.hpp>

class MyButtonController : public touchgfx::ButtonController
{
    virtual void init();
    virtual bool sample(uint8_t& key);

private:
    uint8_t previousState;
    
};
#endif

 

 

Here "HAL_GPIO_ReadPin" has "BTN_USER_GPIO_PORT" and "BTN_USER_PIN" in its function parameter.
These two variables are defined when you add label to your GPIO and generate the code in CubeMX, you can see their values in "main.h" :

 

stepa.png

 

 

 

 

 

If you use "GPIOC" and "GPIO_PIN_13" it also works, it's the same.


When you don't set labels in CubeMX, you can also check which "GPIOX" and which "GPIO_PIN_XX" in "main.c" :
2024-02-16 11_08_16-workspaceBT - STM32H747I-DISCO_CM7_Application_User_Core_main.c - STM32CubeIDE.png

 

 

 

(here I set PC13 without any label)

2) Setup in your TouchGFXHAL file

Now open your "TouchGFXHAL.cpp" and add the following lines to each sections:

 

...
/* USER CODE BEGIN Includes */
...
#include "MyButtonController.hpp"
/* USER CODE END Includes */
...
/* USER CODE BEGIN private variables */
...
MyButtonController bc;
/* USER CODE END private variables */
...
void TouchGFXHAL::initialize()
{
    ...
    /* USER CODE BEGIN initialize step 2 */
    setButtonController(&bc);
    ...
    /* USER CODE END initialize step 2 */
    ...
}
...

 

 

3) Setup in TouchGFX

To use your button in TouchGFX, create an interaction with a trigger "hardware button is clicked" trigger and select the key that you set for the button's GPIO in "MyButtonController".

2024-02-16 11_33_36-.png
If you modified your ".touchgfx" physical button section then, you will see your label displayed beside the key in "Choose button key".

I hope it answers your question.
Regards,

Louis BOUDO
ST Software Developer | TouchGFX
MEde.1
Associate III

Thank you Louis, I have tried modifying my existing efforts but I am getting the following when I try to "program and run target"


CM7/TouchGFX/build/STM32H747I_DISCO/CM7/TouchGFX/target/TouchGFXHAL.o: In function `_GLOBAL__sub_I_bc':
c:\TouchGFXProjects\MyApplication_16/CM7/TouchGFX/target/TouchGFXHAL.cpp:515: undefined reference to `vtable for MyButtonController'

I am guessing that the linker that TouchGFX designer doesn't know where the MyButtonController.hpp is. 

MyButtonController.hpp is here:

C:\TouchGFXProjects\MyApplication_17\CM7\Core\Inc

and MyButtonController.cpp is here:

C:\TouchGFXProjects\MyApplication_17\STM32CubeIDE\CM7\Application\User\Core

 

or maybe it's something else? Sorry for what are probably quite basic questions, whilst this isn't my first STM32 project it's my first using TouchGFX and the directory structure is quite bewildering initially!

It seems to compile quite happily in STM32CubeIDE but the button still doesn't work. 

LouisB,

Any thoughts on why I am getting the error message?

LouisB
ST Employee

Hi @MEde.1 , 

You are getting this error because the "MyButtonController.cpp" is only visible by the CubeIDE, you can place both files (".hpp" & ".cpp") in that directory : "<Your_project_folder>\CM7\TouchGFX\target" directly. It should be working in Designer.

For your hardware button, can you try with another button ? Like "PK4" (Joystick left), configure it in CubeMX :

LouisB_0-1708421241710.png

 



and change the "MyButtonController.cpp" with :

 

#include <MyButtonController.hpp>
#include <main.h>
#include <touchgfx/hal/HAL.hpp>

void MyButtonController::init()
{
	previousState = 0x00;
}

bool MyButtonController::sample(uint8_t& key)
{

	if ((HAL_GPIO_ReadPin(JOY_LEFT_GPIO_Port, JOY_LEFT_Pin) == GPIO_PIN_RESET) && previousState == 0x00)
	{
		previousState = 0xFF;
		key = 1;
		return true;
	}
    previousState = 0x00;
    return false;
}

 

Louis BOUDO
ST Software Developer | TouchGFX
MEde.1
Associate III

Hi Louis,

Thanks for your reply,

I managed to get the button working by following the steps in these two videos (I have added the links below so that if someone else needs to follow them, he gives recipes for both polling and interrupt-based, both of which work)  :

https://www.youtube.com/watch?v=ufvJ5bcesL8

https://www.youtube.com/watch?v=QgEDSjvGAlk&t=189s

However, TouchGFX Designer 4.23.1 can't program and run target. However, CubeIDE can compile and run the code. Changes can be made in designer and once the code is generated you can use CubeIDE to flash the board and run the code.

I have tried your suggestion of putting the files in the same folder:

 

MEde1_1-1708440680959.png

And whilst I can get it to compile and run in CubeIDE (after adding the path to the "target" directory) TouchGFX Designer 4.23.1 can't actually "program and run target". 

 

 

This is normal. TouchGFX dont handle new files, then after add you need update build configs etc.

Second way is not add and use TouchGFXGPIO files for your button code. Or simply say only edit existed files.

3. way is in TouchGFX edit build settings and use command for program and build target over cubeIDE.(headless-build)

But most usable is as you write only generate and do build in IDE. Plus you can debug here.

LouisB
ST Employee

Hello all,

Glad to hear that you were able to make it work @MEde.1 👍
@MM..1 is right, TouchGFX will need to update build files, you have to delete this folder : <Your_project>\CM7\TouchGFX\build  , then it should work on Designer and you should be able to build on target.

I hope that solves your issue.

Regards,

Louis BOUDO
ST Software Developer | TouchGFX