Skip to content

Commit 145b0e0

Browse files
committed
tests: misc: added stm32 tsc driver test implementation
integration tests for stm32 tsc Signed-off-by: Arif Balik <[email protected]>
1 parent 3dab88a commit 145b0e0

File tree

6 files changed

+286
-0
lines changed

6 files changed

+286
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2024 Arif Balik <[email protected]>
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
cmake_minimum_required(VERSION 3.20.0)
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
project(stm32_tsc)
7+
8+
FILE(GLOB app_sources src/*.c)
9+
target_sources(app PRIVATE ${app_sources})
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2024 Arif Balik <[email protected]>
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
/ {
7+
zephyr,user {
8+
/* This will be used to trigger the SYNC pin high and low programmatically.
9+
* They have to be connected.
10+
*/
11+
signal-gpios = <&gpioa 10 GPIO_ACTIVE_HIGH>;
12+
};
13+
};
14+
15+
&tsc {
16+
status = "okay";
17+
18+
pinctrl-0 = <&tsc_g1_io1_pb12 &tsc_g1_io2_pb13 &tsc_g6_io1_pd10
19+
&tsc_g6_io2_pd11 &tsc_sync_pd2>;
20+
pinctrl-names = "default";
21+
22+
st,pulse-generator-prescaler = <TSC_PG_PRESCALER_128>;
23+
24+
st,spread-spectrum;
25+
st,spread-spectrum-prescaler = <2>;
26+
st,spread-spectrum-deviation = <10>;
27+
28+
st,max-count-value = <TSC_MAX_COUNT_16383>;
29+
30+
st,synced-acquisition;
31+
st,syncpol-rising;
32+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_ZTEST=y
2+
CONFIG_INPUT=y
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (c) 2024 Arif Balik <[email protected]>
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <zephyr/device.h>
7+
#include <zephyr/drivers/gpio.h>
8+
#include <zephyr/kernel.h>
9+
#include <zephyr/ztest.h>
10+
11+
extern const struct gpio_dt_spec signal_mock;
12+
13+
static void *stm32_tsc_setup(void)
14+
{
15+
zexpect_ok(gpio_pin_configure_dt(&signal_mock, GPIO_OUTPUT_INACTIVE),
16+
"Failed to configure signal_mock pin");
17+
18+
return NULL;
19+
}
20+
21+
ZTEST_SUITE(stm32_tsc, NULL, stm32_tsc_setup, NULL, NULL, NULL);
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*
2+
* Copyright (c) 2024 Arif Balik <[email protected]>
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
/**
7+
* @file
8+
* @brief Verify STM32 TSC peripheral is configured properly and can be started
9+
*
10+
* @details
11+
* This test requires an external connection on the stm32u083c_dk board. The
12+
* pin GPIOA 10 should be connected to GPIOD 2 manually so that sync signal can
13+
* be generated. Also make sure to press TS1 pad on the board in order to
14+
* generate touch signal on test 5.
15+
* - Test Steps
16+
* -# Get a TSC device
17+
* -# Verify the device is ready
18+
* -# Verify MIMO region with device tree values
19+
* -# Test the acquisition in polling mode
20+
* -# Test the acquisition in interrupt mode
21+
* - Expected Results
22+
* -# The device is ready
23+
* -# The device tree values are correctly mapped to the TSC registers
24+
* -# The acquisition is successful in polling mode
25+
* -# The acquisition is successful in interrupt mode
26+
*
27+
*/
28+
29+
#include <soc.h>
30+
#include <autoconf.h>
31+
#include <inttypes.h>
32+
#include <zephyr/ztest.h>
33+
#include <zephyr/device.h>
34+
#include <zephyr/kernel.h>
35+
#include <zephyr/input/input.h>
36+
#include <zephyr/drivers/gpio.h>
37+
38+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_tsc)
39+
#define TSC_NODE DT_INST(0, st_stm32_tsc)
40+
#else
41+
#error "Could not find an st,stm32-tsc compatible device in DT"
42+
#endif
43+
44+
#define ZEPHYR_USER_NODE DT_PATH(zephyr_user)
45+
46+
const struct gpio_dt_spec signal_mock = GPIO_DT_SPEC_GET(ZEPHYR_USER_NODE, signal_gpios);
47+
48+
ZTEST(stm32_tsc, test_1_device_ready)
49+
{
50+
const struct device *dev = DEVICE_DT_GET(TSC_NODE);
51+
52+
zassert_true(device_is_ready(dev), "STM32 TSC device is not ready");
53+
}
54+
55+
ZTEST(stm32_tsc, test_2_cr_reg)
56+
{
57+
TSC_TypeDef *tsc = (TSC_TypeDef *)DT_REG_ADDR(TSC_NODE);
58+
59+
volatile const uint32_t *tsc_cr = &tsc->CR;
60+
const uint32_t pgpsc = DT_PROP(TSC_NODE, st_pulse_generator_prescaler);
61+
const uint8_t ctph = DT_PROP(TSC_NODE, st_charge_transfer_pulse_high);
62+
const uint8_t ctpl = DT_PROP(TSC_NODE, st_charge_transfer_pulse_low);
63+
const uint8_t ssd = DT_PROP(TSC_NODE, st_spread_spectrum_deviation);
64+
const bool spread_spectrum = DT_PROP(TSC_NODE, st_spread_spectrum);
65+
const uint8_t sscpsc = DT_PROP(TSC_NODE, st_spread_spectrum_prescaler);
66+
const uint16_t max_count = DT_PROP(TSC_NODE, st_max_count_value);
67+
const bool iodef = DT_PROP(TSC_NODE, st_iodef_float);
68+
const bool sync_pol = DT_PROP(TSC_NODE, st_syncpol_rising);
69+
const bool sync_acq = DT_PROP(TSC_NODE, st_synced_acquisition);
70+
71+
/* check charge transfer pulse high value (bits 31:28) */
72+
zassert_equal((*tsc_cr & TSC_CR_CTPL_Msk) >> TSC_CR_CTPL_Pos, ctph - 1,
73+
"CTPH value is not correct, expected %d, got %d", ctph - 1,
74+
(*tsc_cr & TSC_CR_CTPL_Msk) >> TSC_CR_CTPL_Pos);
75+
76+
/* check charge transfer pulse low value (bits 27:24) */
77+
zassert_equal((*tsc_cr & TSC_CR_CTPL_Msk) >> TSC_CR_CTPL_Pos, ctpl - 1,
78+
"CTPL value is not correct, expected %d, got %d", ctpl - 1,
79+
(*tsc_cr & TSC_CR_CTPL_Msk) >> TSC_CR_CTPL_Pos);
80+
81+
/* check spread spectrum deviation value (bits 23:17) */
82+
zassert_equal((*tsc_cr & TSC_CR_SSD_Msk) >> TSC_CR_SSD_Pos, ssd,
83+
"SSD value is not correct, expected %d, got %d", ssd,
84+
(*tsc_cr & TSC_CR_SSD_Msk) >> TSC_CR_SSD_Pos);
85+
86+
/* check spread spectrum enable bit (bit 16) */
87+
if (spread_spectrum) {
88+
zexpect_true(*tsc_cr & TSC_CR_SSE_Msk);
89+
} else {
90+
zexpect_false(*tsc_cr & TSC_CR_SSE_Msk);
91+
}
92+
93+
/* check spread spectrum prescaler value (bits 15) */
94+
if (sscpsc == 2) {
95+
zexpect_true(*tsc_cr & TSC_CR_SSPSC_Msk);
96+
} else {
97+
zexpect_false(*tsc_cr & TSC_CR_SSPSC_Msk);
98+
}
99+
100+
/* check pulse generator prescaler value (bits 14:12) */
101+
zassert_equal((*tsc_cr & TSC_CR_PGPSC_Msk), pgpsc << TSC_CR_PGPSC_Pos,
102+
"PGPSC value is not correct, expected %d, got %d", pgpsc,
103+
(*tsc_cr & TSC_CR_PGPSC_Msk));
104+
105+
/* check max count value (bits 7:5) */
106+
zassert_equal((*tsc_cr & TSC_CR_MCV_Msk), max_count << TSC_CR_MCV_Pos,
107+
"MCV value is not correct, expected %d, got %d", max_count,
108+
(*tsc_cr & TSC_CR_MCV_Msk));
109+
110+
/* check I/O default mode bit (bit 4) */
111+
if (iodef) {
112+
zexpect_true(*tsc_cr & TSC_CR_IODEF_Msk);
113+
} else {
114+
zexpect_false(*tsc_cr & TSC_CR_IODEF_Msk);
115+
}
116+
117+
/* check sync polarity bit (bit 3) */
118+
if (sync_pol) {
119+
zexpect_true(*tsc_cr & TSC_CR_SYNCPOL_Msk);
120+
} else {
121+
zexpect_false(*tsc_cr & TSC_CR_SYNCPOL_Msk);
122+
}
123+
124+
/* check sync acquisition bit (bit 2) */
125+
if (sync_acq) {
126+
zexpect_true(*tsc_cr & TSC_CR_AM_Msk);
127+
} else {
128+
zexpect_false(*tsc_cr & TSC_CR_AM_Msk);
129+
}
130+
131+
/* check TSC enable bit (bit 0) */
132+
zexpect_true(*tsc_cr & TSC_CR_TSCE_Msk);
133+
}
134+
135+
ZTEST(stm32_tsc, test_3_group_registers)
136+
{
137+
TSC_TypeDef *tsc = (TSC_TypeDef *)DT_REG_ADDR(TSC_NODE);
138+
volatile const uint32_t *tsc_iohcr = &tsc->IOHCR;
139+
volatile const uint32_t *tsc_ioscr = &tsc->IOSCR;
140+
volatile const uint32_t *tsc_ioccr = &tsc->IOCCR;
141+
volatile const uint32_t *tsc_iogcsr = &tsc->IOGCSR;
142+
143+
#define GET_GROUP_BITS(val) (uint32_t)(((val) & 0x0f) << ((group - 1) * 4))
144+
145+
#define STM32_TSC_GROUP_TEST(node) \
146+
do { \
147+
const uint8_t group = DT_PROP(node, group); \
148+
const uint8_t channel_ios = DT_PROP(node, channel_ios); \
149+
const uint8_t sampling_io = DT_PROP(node, sampling_io); \
150+
const bool use_as_shield = DT_PROP(node, st_use_as_shield); \
151+
\
152+
/* check schmitt trigger hysteresis for enabled I/Os */ \
153+
zassert_equal((*tsc_iohcr & GET_GROUP_BITS(channel_ios | sampling_io)), 0, \
154+
"Schmitt trigger hysteresis not disabled, expected %d, got %d", 0, \
155+
(*tsc_iohcr & GET_GROUP_BITS(channel_ios | sampling_io))); \
156+
\
157+
/* check channel I/Os */ \
158+
zassert_equal( \
159+
(*tsc_ioccr & GET_GROUP_BITS(channel_ios)), GET_GROUP_BITS(channel_ios), \
160+
"Channel I/Os value is not correct, expected %d, got %d", \
161+
GET_GROUP_BITS(channel_ios), (*tsc_ioccr & GET_GROUP_BITS(channel_ios))); \
162+
\
163+
/* check sampling I/O */ \
164+
zassert_equal( \
165+
(*tsc_ioscr & GET_GROUP_BITS(sampling_io)), GET_GROUP_BITS(sampling_io), \
166+
"Sampling I/O value is not correct, expected %d, got %d", \
167+
GET_GROUP_BITS(sampling_io), (*tsc_ioscr & GET_GROUP_BITS(sampling_io))); \
168+
\
169+
/* check enabled groups */ \
170+
if (use_as_shield) { \
171+
zassert_not_equal((*tsc_iogcsr & BIT(group - 1)), BIT(group - 1), \
172+
"Group %d is a shield group and should not be enabled", \
173+
group); \
174+
} else { \
175+
zassert_equal((*tsc_iogcsr & BIT(group - 1)), BIT(group - 1), \
176+
"Group %d is not enabled", group); \
177+
} \
178+
} while (0)
179+
180+
#define GROUP_TEST_RUN(node) STM32_TSC_GROUP_TEST(node);
181+
182+
DT_FOREACH_CHILD_STATUS_OKAY(TSC_NODE, GROUP_TEST_RUN);
183+
}
184+
185+
static volatile bool tsc_input_received;
186+
187+
static void tsc_input_callback(struct input_event *evt, void *user_data)
188+
{
189+
ARG_UNUSED(evt);
190+
ARG_UNUSED(user_data);
191+
192+
tsc_input_received = true;
193+
}
194+
INPUT_CALLBACK_DEFINE(NULL, tsc_input_callback, NULL);
195+
196+
ZTEST(stm32_tsc, test_5_acquisition_interrupt)
197+
{
198+
TSC_TypeDef *tsc = (TSC_TypeDef *)DT_REG_ADDR(TSC_NODE);
199+
volatile const uint32_t *tsc_isr = &tsc->ISR;
200+
201+
k_sleep(K_MSEC(100));
202+
203+
/* test ISR register max count error flag */
204+
zexpect_false((*tsc_isr & TSC_ISR_MCEF_Msk) >> TSC_ISR_MCEF_Pos);
205+
206+
/* this should fail because of the sync pin */
207+
zexpect_false(tsc_input_received);
208+
209+
zexpect_ok(gpio_pin_toggle_dt(&signal_mock));
210+
211+
/* press the TS1 pad */
212+
213+
k_sleep(K_MSEC(3000));
214+
215+
zexpect_true(tsc_input_received);
216+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
tests:
2+
drivers.input.stm32_tsc:
3+
tags: drivers input stm32 tsc
4+
filter: dt_compat_enabled("st,stm32-tsc")
5+
depends_on: tsc
6+
integration_platforms: [stm32u083c_dk]

0 commit comments

Comments
 (0)