1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-16 01:53:51 +01:00
19880: drivers/ft5x06: fix initialization if callback function parameter is NULL r=aabadie a=gschorcht

### Contribution description

This PR fixes the `ft5x06` driver initialization if the callback function parameter `cb` is `NULL. This might be the case for example if the application uses the touch device in polling mode.

If the interrupt pin is initialized if the callback function parameter `cb` is `NULL`, the driver crashes the first time an interrupt is triggered. Therefore, the INT pin must be initialized only if also the callback function parameter `cb` is not `NULL`.

To be able to test the polling mode, this PR also includes a change of the `tests/drivers/ft5x06` application which introduces the environment variables `FT5X06_POLLING_MODE` `FT5X06_POLLING_PERIOD` and in the makefile.

### Testing procedure

1. Use any board with a FTXXXX touch device and test it in polling mode, for example:
   ```
   FT5X06_POLLING_MODE=1 BOARD=stm32f746g-disco make -C tests/drivers/ft5x06 flash term
   ```
   It should work as expected.
   ```
   main(): This is RIOT! (Version: 2023.10-devel-119-g92a44a-drivers/ft5x06_fix_cb_null)
   FT5x06 test application
   +------------Initializing------------+
   Initialization successful
   1 touch detected
   Touch 1 - X: 236, Y:111
   Touch 1 - X: 236, Y:111
   ...
   Touch 1 - X: 236, Y:111
   Released!
   ```

2. Checkout master branch and cerry-pick commit 691a5e6308426ddc685e5a2c297238529211c258. The test application `tests/drivers/ft5x06` will crash once a touch event occur:
   ```
   +------------Initializing------------+
   Initialization successful
   1 touch detected
   Context before hardfault:
   ```

### Issues/PRs references

Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
This commit is contained in:
bors[bot] 2023-08-29 08:19:52 +00:00 committed by GitHub
commit 5cf32002f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 3 deletions

View File

@ -80,12 +80,13 @@ int ft5x06_init(ft5x06_t *dev, const ft5x06_params_t *params, ft5x06_event_cb_t
}
/* Configure interrupt */
if (gpio_is_valid(dev->params->int_pin)) {
if (gpio_is_valid(dev->params->int_pin) && cb) {
DEBUG("[ft5x06] init: configuring touchscreen interrupt\n");
gpio_init_int(dev->params->int_pin, GPIO_IN, GPIO_RISING, cb, arg);
i2c_write_reg(FT5X06_BUS, FT5X06_ADDR, FT5X06_G_MODE_REG, FT5X06_G_MODE_INTERRUPT_TRIGGER & 0x01, 0);
}
i2c_write_reg(FT5X06_BUS, FT5X06_ADDR, FT5X06_G_MODE_REG, FT5X06_G_MODE_INTERRUPT_TRIGGER & 0x01, 0);
i2c_release(FT5X06_BUS);
return 0;

View File

@ -1,6 +1,16 @@
BOARD ?= stm32f746g-disco
include ../Makefile.drivers_common
FT5X06_POLLING_MODE ?= 0
FT5X06_POLLING_PERIOD ?= 50
CFLAGS += -DFT5X06_POLLING_MODE=$(FT5X06_POLLING_MODE)
CFLAGS += -DFT5X06_POLLING_PERIOD=$(FT5X06_POLLING_PERIOD)
USEMODULE += ft5x06
ifneq (0,$(FT5X06_POLLING_MODE))
USEMODULE += ztimer_msec
endif
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,31 @@
# About
This is a manual test application for the FT5x06 touch device driver.
# Usage
The test application initializes the FT5x06 touch device and then waits
for touch events by using interrupts by default. When touch events occur,
the application generates output like the following:
```
+------------Initializing------------+
Initialization successful
1 touch detected
Touch 1 - X: 203, Y:156
Touch 1 - X: 204, Y:157
Touch 1 - X: 204, Y:157
Touch 1 - X: 206, Y:158
Touch 1 - X: 210, Y:159
Touch 1 - X: 210, Y:159
Touch 1 - X: 218, Y:160
Released!
```
To use the touch device in polling mode, the environment variable
`FT5X06_POLLING_MODE` must be set to 1. The polling period in milliseconds
is defined by the environment variable `FT5X06_POLLING_PERIOD`. It is
50 ms by default. It can be changed by setting the environment variable
`FT5X06_POLLING_PERIOD` in the make command, for example:
```
FT5X06_POLLING_MODE=1 FT5X06_POLLING_PERIOD=100 BOARD=... make -C tests/drivers/touch_dev flash term
```

View File

@ -25,22 +25,39 @@
#include "ft5x06.h"
#include "ft5x06_params.h"
#if IS_ACTIVE(FT5X06_POLLING_MODE)
#include "ztimer.h"
#endif
#ifndef FT5X06_POLLING_PERIOD
#define FT5X06_POLLING_PERIOD 50
#endif
#if !IS_ACTIVE(FT5X06_POLLING_MODE)
static void _touch_event_cb(void *arg)
{
mutex_unlock(arg);
}
#endif
static ft5x06_touch_position_t positions[FT5X06_TOUCHES_COUNT_MAX];
int main(void)
{
#if !IS_ACTIVE(FT5X06_POLLING_MODE)
mutex_t lock = MUTEX_INIT_LOCKED;
#endif
ft5x06_t dev;
puts("FT5x06 test application\n");
printf("+------------Initializing------------+\n");
#if IS_ACTIVE(FT5X06_POLLING_MODE)
int ret = ft5x06_init(&dev, &ft5x06_params[0], NULL, NULL);
#else
int ret = ft5x06_init(&dev, &ft5x06_params[0], _touch_event_cb, &lock);
#endif
if (ret != 0) {
puts("[Error] Initialization failed");
return 1;
@ -53,9 +70,13 @@ int main(void)
uint8_t last_touch_count = current_touch_count;
while (1) {
#if IS_ACTIVE(FT5X06_POLLING_MODE)
/* polling is used */
ztimer_sleep(ZTIMER_MSEC, FT5X06_POLLING_PERIOD);
#else
/* wait for touch event */
mutex_lock(&lock);
#endif
ft5x06_read_touch_count(&dev, &current_touch_count);