mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-16 01:53:51 +01:00
Merge #19880
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:
commit
5cf32002f5
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
31
tests/drivers/ft5x06/README.md
Normal file
31
tests/drivers/ft5x06/README.md
Normal 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
|
||||
```
|
||||
@ -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, ¤t_touch_count);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user