cancel
Showing results for 
Search instead for 
Did you mean: 

Where did the touch driver code go?

vince
Associate III

I’ve updated to IDE 1.2.1 and GFX 4.13. After a HARD uphill struggle, I finally figured out how to get a screen running on a 746 Discovery board. I can’t find how to enable the touch controller, though. In the previous software, this functionality was generated in a cpp file in the TouchGFX folder. That file contains nothing but comments now, with no code to initialize or service touch events. How do we get the touch function going? We need some clear example code or instruction. (And may I vent a bit here? This release can not possibly have been regression tested. I’ve done this long enough to recognize a train wreck when I see one. ST “broke the build�?, and left their base to suffer the consequences. It is inexcusable.)

1 ACCEPTED SOLUTION

Accepted Solutions
Martin KJELDSEN
Chief III

Hi @vince​,

Did you read the documentation on developing for STM32 display kits?

"Generally, two different project types exist when developing TouchGFX applications:

  1. Prototype (perhaps using STM32 display kits)
  2. Product

When developing prototype applications the main focus is almost always UI Application development getting an overview over the capabilities of TouchGFX, not having to worry about hardware. In this scenario the TouchGFX Designer is the starting point where applications can be based on an existing Application Template (AT) for a particular STM32 display kit. This gives developers a chance to try their UI applications on real hardware quickly. In this case the TouchGFX Generator and CubeMX, generally, are used when changes to the hardware is required."

"For custom STM32 based boards the entry point will typically be CubeMX and the TouchGFX Generator."

I could go on. If you'd bothered searching this community you would also find this information in many posts.

Think of CubeMX (Cube Micro eXplorer) as an MCU configurator. Despite knowing about existing display kits, it won't care what peripherals you have on your board, including your touch controller. It can initialize your controllers according to sdram and qspi and whatever else might be on your board but it won't provide the code to set them up because, from an MCU perpective, it does not make sense to talk about touch controllers.

It's late here, but your vent triggered me enough to pull out my laptop and reply. If you've "done this long enough" may i suggest that you read the documentation before calling something a "train wreck"?

/Martin

View solution in original post

29 REPLIES 29
Martin KJELDSEN
Chief III

Hi @vince​,

Did you read the documentation on developing for STM32 display kits?

"Generally, two different project types exist when developing TouchGFX applications:

  1. Prototype (perhaps using STM32 display kits)
  2. Product

When developing prototype applications the main focus is almost always UI Application development getting an overview over the capabilities of TouchGFX, not having to worry about hardware. In this scenario the TouchGFX Designer is the starting point where applications can be based on an existing Application Template (AT) for a particular STM32 display kit. This gives developers a chance to try their UI applications on real hardware quickly. In this case the TouchGFX Generator and CubeMX, generally, are used when changes to the hardware is required."

"For custom STM32 based boards the entry point will typically be CubeMX and the TouchGFX Generator."

I could go on. If you'd bothered searching this community you would also find this information in many posts.

Think of CubeMX (Cube Micro eXplorer) as an MCU configurator. Despite knowing about existing display kits, it won't care what peripherals you have on your board, including your touch controller. It can initialize your controllers according to sdram and qspi and whatever else might be on your board but it won't provide the code to set them up because, from an MCU perpective, it does not make sense to talk about touch controllers.

It's late here, but your vent triggered me enough to pull out my laptop and reply. If you've "done this long enough" may i suggest that you read the documentation before calling something a "train wreck"?

/Martin

Martin, my apology to you personally if my critique of the product offended, but after hours of head banging (which included reading literally everything published on this topic, including the material you reiterated, plus scouring the forums in an attempt to piece together a coherent path to success), I had to express my dissatisfaction to someone. I actually feel sorry for you, as I have been following your posts regularly and know for certain you have been a VERY busy man, thrown into quite a mess. But yes, I have done this for many years, and I detect an air of emergency in the boards lighting up out there. When a system that was working no longer does after a new release, this tells me that, indeed, there is not adequate testing in place, as I know that regression testing in software is designed to ensure that such things do not catch an installed user base off guard. So, again, my critique is not aimed at you specifically, an employee of ST doing the best you can to put out fires, and "train wreck" is less a value judgement, and more a description of what I take to have been an avoidable problem on ST's part. Live and learn, I guess.

That said, I have read everything I can get my hands on about this new release, and spent several hours bringing up a demo on a Discovery board. Part of the problem, I think, is that the “Templates�? are nowhere to be found within my installation of Designer 4.13 (I have installed/repaired it three times now; only the simulator is available to select. I do not know why this is. It certainly contradicts the published guides I have seen.) Even so, I managed to go in from the Cube side and get a screen up and running, using the .part file that was generated there, but without the touch facility. This is when I discovered that the cpp file which formerly implemented this feature apparently no longer does. This is pretty much dead in the water at this point, as there are no examples without the template. Perhaps I missed a step along the way. Taking what I can from various users out there, I have learned much, but I'm not finding a single source that shows how this last piece is done. Again, I could have missed something that in retrospect will seem obvious, but from the trenches, it is hidden at this point.

Best regards to you and your support team, and thanks for any insight you might provide. Eventually these things settle out, and I can wait until the next clean release if necessary.

-Vince

Hey @vince​ 

I just did a video on the setup : https://www.youtube.com/watch?v=o42r4xXOnbo

I know it's without the touch drivers that you ask about but I believe that it should be the same procedure as fore the previous versions:

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

If you start at around 10:40'ish I'm talking about how to add the touch driver.

Now, I haven't tried this on the 4.13.0 version (and 1.2.1 for CubeIDE) and since it's pretty late for me I will have to wait after the weekend until I try. But it SHOULD be the same procedure 🙂 Maybe you can give it a go?

And sorry for the poor audio quality :\

Do you have some red icon in the designer telling you that there's a connection issue? Are you behind a firewall of sorts? Try going to %APPDATA% and removing TouchGFX-4.13.0 entirely. This should trigger a re-download of all application templates.

I'm really sorry you're having these issues, though. There's nothing "unclean" about this release. It's just very difficult integration process, apparently. Many tools inplay, TouchGFX designer, Generator, CubeMX, CubeIDE, st-link, etc, etc, etc.

If it was easy, anyone could do it.

/Martin

vince
Associate III

YES, I have watched your series. Killer stuff (thank you). The part where you discuss adding touch capability is just the part where the new release does not align... there just is no driver code generated (although, curiously, the files are still created). I am certain if I could figure out what are the new calls into the library, all would be well. I am trying to modify the "old" generated code (the part you uncommented in one of your videos) to mesh within the new paradigm.

vince
Associate III

No, there is not a red icon, and I'm not behind a firewall of any sorts. I will search for the %APPDATA% you reference. I assume you mean the variable in the Windows registry.

vince
Associate III

Martin, I found the folder (and not a registry key, which I at first believed). I also discovered in doing so the cause of this template download issue. While I do not use a firewall, I thought to try to disabling my VPN; the templates loaded afterward. This was not an issue in v4.12.x, but apparently is so now. So, that is maybe one step closer to achieving complete integration under this new system. I will have some time later to run several more tests. (By the way, I do get your point about separation of hardware and software domains under this new conception, and agree that this is ultimately desirable; my confusion/frustration, and probably some others' as well, is that the Cube doesn't just let us select a bare micro (which should be driver neutral), but it also lets us select a complete board, which we would presume comes along with an appropriate board support package, including the necessary drivers. Such was at any rate provided in earlier versions of the Cube.)

HP
Senior III

I was curious about this so I found a few minutes to do some digging. TL;DR - I got it working.

@Martin KJELDSEN​ There seems to indeed be some code missing here - I'm not sure if this falls in the soft-config category, but if it's possible to have the AT generate these few snippets again it would make the process 'work like the old versions' :D

So what I did:

I started off by copying the drivers from the F7 repository as per my old videos.

Then, in the STM32TouchController.cpp (in TouchGFX->target->generated folder) I've written essentially what was there before:

/**
  ******************************************************************************
  * File Name          : STM32TouchController.cpp
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under Ultimate Liberty license
  * SLA0044, the "License"; You may not use this file except in compliance with
  * the License. You may obtain a copy of the License at:
  *                             www.st.com/SLA0044
  *
  ******************************************************************************
  */
 
/* USER CODE BEGIN STM32TouchController */
 
#include <STM32TouchController.hpp>
#include "stm32746g_discovery_ts.h"
 
extern "C"
{
uint32_t LCD_GetXSize();
uint32_t LCD_GetYSize();
 
}
 
 
void STM32TouchController::init()
{
    /**
     * Initialize touch controller and driver
     *
     */
	BSP_TS_Init(480, 272);
}
 
bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y)
{
    /**
     * By default sampleTouch returns false,
     * return true if a touch has been detected, otherwise false.
     *
     * Coordinates are passed to the caller by reference by x and y.
     *
     * This function is called by the TouchGFX framework.
     * By default sampleTouch is called every tick, this can be adjusted by HAL::setTouchSampleRate(int8_t);
     *
     */
	  TS_StateTypeDef state = { 0 };
	    BSP_TS_GetState(&state);
	    if (state.touchDetected)
	    {
	        x = state.touchX[0];
	        y = state.touchY[0];
 
	        return true;
	    }
    return false;
}
 
/* USER CODE END STM32TouchController */
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Do note that skipped the LCD_GetXsize() and LCD_GetYSize() since they will just return a static value (hardcoded by the generator). I'm sure I could find the values somewhere if I went digging, but for now I just put the screensize directly in the BSP_TS_Init call

That's basically it. I 'just' took what was written in the old code and it seems to work fine. I can do a video on this topic if needed but it's fairly straightforward.

I don't get it, sorry 🙂 What "snippets" are you talking about?

Here's the STM32TouchController.cpp you get from the F746G-DISCO Application template. Works fine, i just tested it (again) 🙂

#include <STM32TouchController.hpp>
#include <TouchGFXHAL.hpp>
#include <ft5336.h>
#include <stm32f7xx_hal.h>
#include <touchgfx/hal/OSWrappers.hpp>
 
static TS_DrvTypeDef* tsDriver;
extern I2C_HandleTypeDef hi2c3;
 
void STM32TouchController::init()
{
    /* Initialize the TS driver structure */
    tsDriver = &ft5336_ts_drv;
 
    /* Initialize the TS driver */
    tsDriver->Start(TS_I2C_ADDRESS);
}
 
bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y)
{
    /* Checking if the screen has been touched */
 
    if (tsDriver)
    {
        if (tsDriver->DetectTouch(TS_I2C_ADDRESS))
        {
            /* Get each touch coordinates */
            tsDriver->GetXY(TS_I2C_ADDRESS, (uint16_t*)&y, (uint16_t*)&x);
            return true;
        }
    }
    return false;
}
 
/**
  * @brief  Manages error callback by re-initializing I2C.
  * @param  i2c_handler : I2C handler
  * @param  Addr: I2C Address
  * @retval None
  */
static void I2Cx_Error(I2C_HandleTypeDef* i2c_handler, uint8_t Addr)
{
    /* De-initialize the I2C communication bus */
    HAL_I2C_DeInit(i2c_handler);
 
    /* Re-Initialize the I2C communication bus */
    //I2Cx_Init(i2c_handler);
}
 
/**
  * @brief  Reads multiple data.
  * @param  i2c_handler : I2C handler
  * @param  Addr: I2C address
  * @param  Reg: Reg address
  * @param  MemAddress: Memory address
  * @param  Buffer: Pointer to data buffer
  * @param  Length: Length of the data
  * @retval Number of read data
  */
static HAL_StatusTypeDef I2Cx_ReadMultiple(I2C_HandleTypeDef* i2c_handler,
                                           uint8_t Addr,
                                           uint16_t Reg,
                                           uint16_t MemAddress,
                                           uint8_t* Buffer,
                                           uint16_t Length)
{
    HAL_StatusTypeDef status = HAL_OK;
 
    status = HAL_I2C_Mem_Read(i2c_handler, Addr, (uint16_t)Reg, MemAddress, Buffer, Length, 1000);
 
    /* Check the communication status */
    if (status != HAL_OK)
    {
        /* I2C error occurred */
        I2Cx_Error(i2c_handler, Addr);
    }
    return status;
}
 
/**
  * @brief  Writes a value in a register of the device through BUS in using DMA mode.
  * @param  i2c_handler : I2C handler
  * @param  Addr: Device address on BUS Bus.
  * @param  Reg: The target register address to write
  * @param  MemAddress: Memory address
  * @param  Buffer: The target register value to be written
  * @param  Length: buffer size to be written
  * @retval HAL status
  */
static HAL_StatusTypeDef I2Cx_WriteMultiple(I2C_HandleTypeDef* i2c_handler,
                                            uint8_t Addr,
                                            uint16_t Reg,
                                            uint16_t MemAddress,
                                            uint8_t* Buffer,
                                            uint16_t Length)
{
    HAL_StatusTypeDef status = HAL_OK;
 
    status = HAL_I2C_Mem_Write(i2c_handler, Addr, (uint16_t)Reg, MemAddress, Buffer, Length, 1000);
 
    /* Check the communication status */
    if (status != HAL_OK)
    {
        /* Re-Initiaize the I2C Bus */
        I2Cx_Error(i2c_handler, Addr);
    }
    return status;
}
 
/**
  * @brief  Writes a single data.
  * @param  Addr: I2C address
  * @param  Reg: Reg address
  * @param  Value: Data to be written
  * @retval None
  */
void TS_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value)
{
    I2Cx_WriteMultiple(&hi2c3, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&Value, 1);
}
 
/**
  * @brief  Reads a single data.
  * @param  Addr: I2C address
  * @param  Reg: Reg address
  * @retval Data to be read
  */
uint8_t TS_IO_Read(uint8_t Addr, uint8_t Reg)
{
    uint8_t read_value = 0;
 
    I2Cx_ReadMultiple(&hi2c3, Addr, Reg, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&read_value, 1);
 
    return read_value;
}
 
/**
  * @brief  TS delay
  * @param  Delay: Delay in ms
  * @retval None
  */
void TS_IO_Delay(uint32_t Delay)
{
    HAL_Delay(Delay);
}