1 /*
2  * Copyright (c) 2024 Arif Balik <arifbalik@outlook.com>
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 
ZTEST(stm32_tsc,test_1_device_ready)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 
ZTEST(stm32_tsc,test_2_cr_reg)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 = LOG2CEIL(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 = LOG2CEIL(DT_PROP(TSC_NODE, st_max_count_value) + 1) - 8;
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 
ZTEST(stm32_tsc,test_3_group_registers)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 
tsc_input_callback(struct input_event * evt,void * user_data)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 
ZTEST(stm32_tsc,test_5_acquisition_interrupt)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 }
217