mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-16 18:13:49 +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 */
|
/* 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");
|
DEBUG("[ft5x06] init: configuring touchscreen interrupt\n");
|
||||||
gpio_init_int(dev->params->int_pin, GPIO_IN, GPIO_RISING, cb, arg);
|
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);
|
i2c_release(FT5X06_BUS);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -1,6 +1,16 @@
|
|||||||
BOARD ?= stm32f746g-disco
|
BOARD ?= stm32f746g-disco
|
||||||
include ../Makefile.drivers_common
|
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
|
USEMODULE += ft5x06
|
||||||
|
|
||||||
|
ifneq (0,$(FT5X06_POLLING_MODE))
|
||||||
|
USEMODULE += ztimer_msec
|
||||||
|
endif
|
||||||
|
|
||||||
include $(RIOTBASE)/Makefile.include
|
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.h"
|
||||||
#include "ft5x06_params.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)
|
static void _touch_event_cb(void *arg)
|
||||||
{
|
{
|
||||||
mutex_unlock(arg);
|
mutex_unlock(arg);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static ft5x06_touch_position_t positions[FT5X06_TOUCHES_COUNT_MAX];
|
static ft5x06_touch_position_t positions[FT5X06_TOUCHES_COUNT_MAX];
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
#if !IS_ACTIVE(FT5X06_POLLING_MODE)
|
||||||
mutex_t lock = MUTEX_INIT_LOCKED;
|
mutex_t lock = MUTEX_INIT_LOCKED;
|
||||||
|
#endif
|
||||||
|
|
||||||
ft5x06_t dev;
|
ft5x06_t dev;
|
||||||
|
|
||||||
puts("FT5x06 test application\n");
|
puts("FT5x06 test application\n");
|
||||||
|
|
||||||
printf("+------------Initializing------------+\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);
|
int ret = ft5x06_init(&dev, &ft5x06_params[0], _touch_event_cb, &lock);
|
||||||
|
#endif
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
puts("[Error] Initialization failed");
|
puts("[Error] Initialization failed");
|
||||||
return 1;
|
return 1;
|
||||||
@ -53,9 +70,13 @@ int main(void)
|
|||||||
uint8_t last_touch_count = current_touch_count;
|
uint8_t last_touch_count = current_touch_count;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
#if IS_ACTIVE(FT5X06_POLLING_MODE)
|
||||||
|
/* polling is used */
|
||||||
|
ztimer_sleep(ZTIMER_MSEC, FT5X06_POLLING_PERIOD);
|
||||||
|
#else
|
||||||
/* wait for touch event */
|
/* wait for touch event */
|
||||||
mutex_lock(&lock);
|
mutex_lock(&lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
ft5x06_read_touch_count(&dev, ¤t_touch_count);
|
ft5x06_read_touch_count(&dev, ¤t_touch_count);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user