Skip to content

Commit

Permalink
samples: drivers: added a simple touch controller sample
Browse files Browse the repository at this point in the history
The sample is supposed to help examine the issues with touchscreen.
It draws a plus in last touched position.

Signed-off-by: Dominik Lau <dlau@internships.antmicro.com>
Signed-off-by: Filip Kokosinski <fkokosinski@antmicro.com>
  • Loading branch information
laudominik authored and fkokosinski committed Aug 19, 2024
1 parent ad3e941 commit 5657949
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 0 deletions.
7 changes: 7 additions & 0 deletions samples/drivers/touch/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(touch)

target_sources(app PRIVATE src/main.c)
32 changes: 32 additions & 0 deletions samples/drivers/touch/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.. zephyr:code-sample:: touch
:name: touchs
:relevant-api: io_interfaces

Basic touchscreen sample.

Overview
********
This sample will draw a small plus in the last touched coordinates, that way you can check
if the touch screen works for a board, examine its parameters such as inverted/swapped axes.

Building and Running
********************
While this is a generic sample and it should work with any boards with both display controllers
and touch controllers supported by Zephyr (provided the corresponding /chosen node properties
are set i.e. `zephyr,touch` and `zephyr,display`).
Below is an example on how to build the sample for :ref:`stm32f746g_disco`;

.. zephyr-app-commands::
:zephyr-app: samples/drivers/touch
:board: stm32f746g_disco
:goals: build
:compact:

For testing purpose without the need of any hardware, the :ref:`native_sim <native_sim>`
board is also supported and can be built as follows;

.. zephyr-app-commands::
:zephyr-app: samples/drivers/touch
:board: native_sim
:goals: build
:compact:
6 changes: 6 additions & 0 deletions samples/drivers/touch/boards/native_posix_64.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/ {
chosen {
zephyr,display = &sdl_dc;
zephyr,touch = &input_sdl_touch;
};
};
5 changes: 5 additions & 0 deletions samples/drivers/touch/boards/stm32f429i_disc1.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/ {
chosen {
zephyr,touch = &stmpe811;
};
};
5 changes: 5 additions & 0 deletions samples/drivers/touch/boards/stm32f746g_disco.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/ {
chosen {
zephyr,touch = &ft5336;
};
};
4 changes: 4 additions & 0 deletions samples/drivers/touch/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_LOG=y
CONFIG_INPUT=y
CONFIG_DISPLAY=y
11 changes: 11 additions & 0 deletions samples/drivers/touch/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
sample:
description: Sample application for touch controllers
name: touch_sample
tests:
sample.touch.ft5336:
platform_allow:
- stm32f429i_disc1
- stm32f746g_disco
tags:
- touch
harness: none
142 changes: 142 additions & 0 deletions samples/drivers/touch/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright (c) 2024 Antmicro <www.antmicro.com>
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(sample, LOG_LEVEL_INF);

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/input/input.h>
#include <zephyr/drivers/display.h>

#define CROSS_WIDTH 20
#define CROSS_HEIGHT 20
#define BUFFER_SIZE ((CROSS_WIDTH) * (CROSS_HEIGHT) * 4)
#define REFRESH_RATE 100

#ifndef DT_CHOSEN_zephyr_touch
#error "Unsupported board: zephyr,touch is not assigned"
#endif

#ifndef DT_CHOSEN_zephyr_display
#error "Unsupported board: zephyr,display is not assigned"
#endif

static const struct device *const display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
static const struct device *const touch_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_touch));
static struct display_capabilities capabilities;
static struct display_buffer_descriptor buf_desc = {.buf_size = BUFFER_SIZE,
.pitch = CROSS_WIDTH,
.width = CROSS_WIDTH,
.height = CROSS_HEIGHT};

static uint8_t buffer_cross[BUFFER_SIZE] = {0};
static const uint8_t buffer_cross_empty[BUFFER_SIZE] = {0};
static struct k_sem sync_x, sync_y;

static struct {
size_t x;
size_t y;
} touch_point, touch_point_drawn;

static void touch_event_callback(struct input_event *evt, void *user_data)
{
if (evt->code == INPUT_ABS_X) {
touch_point.x = evt->value;
k_sem_give(&sync_x);
}
if (evt->code == INPUT_ABS_Y) {
touch_point.y = evt->value;
k_sem_give(&sync_y);
}
}

static void clear_screen(void)
{
int x;
int y;

for (x = 0; x < capabilities.x_resolution; x += CROSS_WIDTH) {
for (y = 0; y < capabilities.y_resolution; y += CROSS_HEIGHT) {
display_write(display_dev, x, y, &buf_desc, buffer_cross_empty);
}
}
}

static void fill_cross_buffer(int bpp)
{
int i;
int x;
int y;
int index;

for (i = 0; i < bpp; i++) {
for (x = 0; x < CROSS_WIDTH; x++) {
index = bpp * (CROSS_HEIGHT / 2 * CROSS_WIDTH + x);
buffer_cross[index + i] = -1;
}
for (y = 0; y < CROSS_HEIGHT; y++) {
index = bpp * (y * CROSS_WIDTH + CROSS_WIDTH / 2);
buffer_cross[index + i] = -1;
}
}
}

int main(void)
{
size_t tick_count;
size_t bpp;

LOG_INF("Touch sample for touchscreen: %s, dc: %s", touch_dev->name, display_dev->name);

if (!device_is_ready(touch_dev)) {
LOG_ERR("Device %s not found. Aborting sample.", display_dev->name);
return 1;
}

if (!device_is_ready(display_dev)) {
LOG_ERR("Device %s not found. Aborting sample.", display_dev->name);
return 1;
}

display_get_capabilities(display_dev, &capabilities);
bpp = DISPLAY_BITS_PER_PIXEL(capabilities.current_pixel_format) / 8u;

if (bpp == 0 || bpp > 4) {
LOG_ERR("Unsupported BPP=%d", bpp);
return 1;
}
fill_cross_buffer(bpp);
display_blanking_off(display_dev);

clear_screen();
tick_count = 0;
touch_point_drawn.x = CROSS_WIDTH / 2;
touch_point_drawn.y = CROSS_HEIGHT / 2;
touch_point.x = -1;
touch_point.y = -1;

k_sem_init(&sync_x, 0, 1);
k_sem_init(&sync_y, 0, 1);
INPUT_CALLBACK_DEFINE(NULL, touch_event_callback, NULL);

while (1) {
k_msleep(REFRESH_RATE);
k_sem_take(&sync_x, K_FOREVER);
k_sem_take(&sync_y, K_FOREVER);
LOG_INF("TOUCH X, Y: (%d, %d)", touch_point.x, touch_point.y);

display_write(display_dev, touch_point_drawn.x - CROSS_WIDTH / 2,
touch_point_drawn.y - CROSS_HEIGHT / 2, &buf_desc,
buffer_cross_empty);
display_write(display_dev, touch_point.x - CROSS_WIDTH / 2,
touch_point.y - CROSS_HEIGHT / 2, &buf_desc, buffer_cross);

touch_point_drawn.x = touch_point.x;
touch_point_drawn.y = touch_point.y;
}
return 0;
}

0 comments on commit 5657949

Please sign in to comment.