xref: /qemu/tests/qtest/stm32l4x5_exti-test.c (revision 658178c3)
1 /*
2  * QTest testcase for STM32L4x5_EXTI
3  *
4  * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
5  * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
6  *
7  * This work is licensed under the terms of the GNU GPL, version 2 or later.
8  * See the COPYING file in the top-level directory.
9  */
10 
11 #include "qemu/osdep.h"
12 #include "libqtest-single.h"
13 
14 #define EXTI_BASE_ADDR 0x40010400
15 #define EXTI_IMR1 0x00
16 #define EXTI_EMR1 0x04
17 #define EXTI_RTSR1 0x08
18 #define EXTI_FTSR1 0x0C
19 #define EXTI_SWIER1 0x10
20 #define EXTI_PR1 0x14
21 #define EXTI_IMR2 0x20
22 #define EXTI_EMR2 0x24
23 #define EXTI_RTSR2 0x28
24 #define EXTI_FTSR2 0x2C
25 #define EXTI_SWIER2 0x30
26 #define EXTI_PR2 0x34
27 
28 #define NVIC_ISER 0xE000E100
29 #define NVIC_ISPR 0xE000E200
30 #define NVIC_ICPR 0xE000E280
31 
32 #define EXTI0_IRQ 6
33 #define EXTI1_IRQ 7
34 #define EXTI35_IRQ 1
35 
36 static void enable_nvic_irq(unsigned int n)
37 {
38     writel(NVIC_ISER, 1 << n);
39 }
40 
41 static void unpend_nvic_irq(unsigned int n)
42 {
43     writel(NVIC_ICPR, 1 << n);
44 }
45 
46 static bool check_nvic_pending(unsigned int n)
47 {
48     return readl(NVIC_ISPR) & (1 << n);
49 }
50 
51 static void exti_writel(unsigned int offset, uint32_t value)
52 {
53     writel(EXTI_BASE_ADDR + offset, value);
54 }
55 
56 static uint32_t exti_readl(unsigned int offset)
57 {
58     return readl(EXTI_BASE_ADDR + offset);
59 }
60 
61 static void exti_set_irq(int num, int level)
62 {
63    qtest_set_irq_in(global_qtest, "/machine/soc/exti", NULL,
64                     num, level);
65 }
66 
67 static void test_reg_write_read(void)
68 {
69     /* Test that non-reserved bits in xMR and xTSR can be set and cleared */
70 
71     exti_writel(EXTI_IMR1, 0xFFFFFFFF);
72     g_assert_cmpuint(exti_readl(EXTI_IMR1), ==, 0xFFFFFFFF);
73     exti_writel(EXTI_IMR1, 0x00000000);
74     g_assert_cmpuint(exti_readl(EXTI_IMR1), ==, 0x00000000);
75 
76     exti_writel(EXTI_EMR1, 0xFFFFFFFF);
77     g_assert_cmpuint(exti_readl(EXTI_EMR1), ==, 0xFFFFFFFF);
78     exti_writel(EXTI_EMR1, 0x00000000);
79     g_assert_cmpuint(exti_readl(EXTI_EMR1), ==, 0x00000000);
80 
81     exti_writel(EXTI_RTSR1, 0xFFFFFFFF);
82     g_assert_cmpuint(exti_readl(EXTI_RTSR1), ==, 0x007DFFFF);
83     exti_writel(EXTI_RTSR1, 0x00000000);
84     g_assert_cmpuint(exti_readl(EXTI_RTSR1), ==, 0x00000000);
85 
86     exti_writel(EXTI_FTSR1, 0xFFFFFFFF);
87     g_assert_cmpuint(exti_readl(EXTI_FTSR1), ==, 0x007DFFFF);
88     exti_writel(EXTI_FTSR1, 0x00000000);
89     g_assert_cmpuint(exti_readl(EXTI_FTSR1), ==, 0x00000000);
90 
91     exti_writel(EXTI_IMR2, 0xFFFFFFFF);
92     g_assert_cmpuint(exti_readl(EXTI_IMR2), ==, 0x000000FF);
93     exti_writel(EXTI_IMR2, 0x00000000);
94     g_assert_cmpuint(exti_readl(EXTI_IMR2), ==, 0x00000000);
95 
96     exti_writel(EXTI_EMR2, 0xFFFFFFFF);
97     g_assert_cmpuint(exti_readl(EXTI_EMR2), ==, 0x000000FF);
98     exti_writel(EXTI_EMR2, 0x00000000);
99     g_assert_cmpuint(exti_readl(EXTI_EMR2), ==, 0x00000000);
100 
101     exti_writel(EXTI_RTSR2, 0xFFFFFFFF);
102     g_assert_cmpuint(exti_readl(EXTI_RTSR2), ==, 0x00000078);
103     exti_writel(EXTI_RTSR2, 0x00000000);
104     g_assert_cmpuint(exti_readl(EXTI_RTSR2), ==, 0x00000000);
105 
106     exti_writel(EXTI_FTSR2, 0xFFFFFFFF);
107     g_assert_cmpuint(exti_readl(EXTI_FTSR2), ==, 0x00000078);
108     exti_writel(EXTI_FTSR2, 0x00000000);
109     g_assert_cmpuint(exti_readl(EXTI_FTSR2), ==, 0x00000000);
110 }
111 
112 static void test_direct_lines_write(void)
113 {
114     /* Test that direct lines reserved bits are not written to */
115 
116     exti_writel(EXTI_RTSR1, 0xFF820000);
117     g_assert_cmpuint(exti_readl(EXTI_RTSR1), ==, 0x00000000);
118 
119     exti_writel(EXTI_FTSR1, 0xFF820000);
120     g_assert_cmpuint(exti_readl(EXTI_FTSR1), ==, 0x00000000);
121 
122     exti_writel(EXTI_SWIER1, 0xFF820000);
123     g_assert_cmpuint(exti_readl(EXTI_SWIER1), ==, 0x00000000);
124 
125     exti_writel(EXTI_PR1, 0xFF820000);
126     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
127 
128     exti_writel(EXTI_RTSR2, 0x00000087);
129     g_assert_cmpuint(exti_readl(EXTI_RTSR2), ==, 0x00000000);
130 
131     exti_writel(EXTI_FTSR2, 0x00000087);
132     g_assert_cmpuint(exti_readl(EXTI_FTSR2), ==, 0x00000000);
133 
134     exti_writel(EXTI_SWIER2, 0x00000087);
135     g_assert_cmpuint(exti_readl(EXTI_SWIER2), ==, 0x00000000);
136 
137     exti_writel(EXTI_PR2, 0x00000087);
138     g_assert_cmpuint(exti_readl(EXTI_PR2), ==, 0x00000000);
139 }
140 
141 static void test_reserved_bits_write(void)
142 {
143     /* Test that reserved bits stay are not written to */
144 
145     exti_writel(EXTI_IMR2, 0xFFFFFF00);
146     g_assert_cmpuint(exti_readl(EXTI_IMR2), ==, 0x00000000);
147 
148     exti_writel(EXTI_EMR2, 0xFFFFFF00);
149     g_assert_cmpuint(exti_readl(EXTI_EMR2), ==, 0x00000000);
150 
151     exti_writel(EXTI_RTSR2, 0xFFFFFF00);
152     g_assert_cmpuint(exti_readl(EXTI_RTSR2), ==, 0x00000000);
153 
154     exti_writel(EXTI_FTSR2, 0xFFFFFF00);
155     g_assert_cmpuint(exti_readl(EXTI_FTSR2), ==, 0x00000000);
156 
157     exti_writel(EXTI_SWIER2, 0xFFFFFF00);
158     g_assert_cmpuint(exti_readl(EXTI_SWIER2), ==, 0x00000000);
159 
160     exti_writel(EXTI_PR2, 0xFFFFFF00);
161     g_assert_cmpuint(exti_readl(EXTI_PR2), ==, 0x00000000);
162 }
163 
164 static void test_software_interrupt(void)
165 {
166     /*
167      * Test that we can launch a software irq by :
168      * - enabling its line in IMR
169      * - and then setting a bit from '0' to '1' in SWIER
170      *
171      * And that the interruption stays pending in NVIC
172      * even after clearing the pending bit in PR.
173      */
174 
175     /*
176      * Testing interrupt line EXTI0
177      * Bit 0 in EXTI_*1 registers (EXTI0) corresponds to GPIO Px_0
178      */
179 
180     enable_nvic_irq(EXTI0_IRQ);
181     /* Check that there are no interrupts already pending in PR */
182     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
183     /* Check that this specific interrupt isn't pending in NVIC */
184     g_assert_false(check_nvic_pending(EXTI0_IRQ));
185 
186     /* Enable interrupt line EXTI0 */
187     exti_writel(EXTI_IMR1, 0x00000001);
188     /* Set the right SWIER bit from '0' to '1' */
189     exti_writel(EXTI_SWIER1, 0x00000000);
190     exti_writel(EXTI_SWIER1, 0x00000001);
191 
192     /* Check that the write in SWIER was effective */
193     g_assert_cmpuint(exti_readl(EXTI_SWIER1), ==, 0x00000001);
194     /* Check that the corresponding pending bit in PR is set */
195     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000001);
196     /* Check that the corresponding interrupt is pending in the NVIC */
197     g_assert_true(check_nvic_pending(EXTI0_IRQ));
198 
199     /* Clear the pending bit in PR */
200     exti_writel(EXTI_PR1, 0x00000001);
201 
202     /* Check that the write in PR was effective */
203     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
204     /* Check that the corresponding bit in SWIER was cleared */
205     g_assert_cmpuint(exti_readl(EXTI_SWIER1), ==, 0x00000000);
206     /* Check that the interrupt is still pending in the NVIC */
207     g_assert_true(check_nvic_pending(EXTI0_IRQ));
208 
209     /*
210      * Testing interrupt line EXTI35
211      * Bit 3 in EXTI_*2 registers (EXTI35) corresponds to PVM 1 Wakeup
212      */
213 
214     enable_nvic_irq(EXTI35_IRQ);
215     /* Check that there are no interrupts already pending */
216     g_assert_cmpuint(exti_readl(EXTI_PR2), ==, 0x00000000);
217     g_assert_false(check_nvic_pending(EXTI35_IRQ));
218 
219     /* Enable interrupt line EXTI0 */
220     exti_writel(EXTI_IMR2, 0x00000008);
221     /* Set the right SWIER bit from '0' to '1' */
222     exti_writel(EXTI_SWIER2, 0x00000000);
223     exti_writel(EXTI_SWIER2, 0x00000008);
224 
225     /* Check that the write in SWIER was effective */
226     g_assert_cmpuint(exti_readl(EXTI_SWIER2), ==, 0x00000008);
227     /* Check that the corresponding pending bit in PR is set */
228     g_assert_cmpuint(exti_readl(EXTI_PR2), ==, 0x00000008);
229     /* Check that the corresponding interrupt is pending in the NVIC */
230     g_assert_true(check_nvic_pending(EXTI35_IRQ));
231 
232     /* Clear the pending bit in PR */
233     exti_writel(EXTI_PR2, 0x00000008);
234 
235     /* Check that the write in PR was effective */
236     g_assert_cmpuint(exti_readl(EXTI_PR2), ==, 0x00000000);
237     /* Check that the corresponding bit in SWIER was cleared */
238     g_assert_cmpuint(exti_readl(EXTI_SWIER2), ==, 0x00000000);
239     /* Check that the interrupt is still pending in the NVIC */
240     g_assert_true(check_nvic_pending(EXTI35_IRQ));
241 
242     /* Clean NVIC */
243     unpend_nvic_irq(EXTI0_IRQ);
244     g_assert_false(check_nvic_pending(EXTI0_IRQ));
245     unpend_nvic_irq(EXTI35_IRQ);
246     g_assert_false(check_nvic_pending(EXTI35_IRQ));
247 }
248 
249 static void test_edge_selector(void)
250 {
251     enable_nvic_irq(EXTI0_IRQ);
252 
253     /* Configure EXTI line 0 irq on rising edge */
254     exti_set_irq(0, 1);
255     exti_writel(EXTI_IMR1, 0x00000001);
256     exti_writel(EXTI_RTSR1, 0x00000001);
257     exti_writel(EXTI_FTSR1, 0x00000000);
258 
259     /* Test that an irq is raised on rising edge only */
260     exti_set_irq(0, 0);
261     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
262     g_assert_false(check_nvic_pending(EXTI0_IRQ));
263 
264     exti_set_irq(0, 1);
265     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000001);
266     g_assert_true(check_nvic_pending(EXTI0_IRQ));
267 
268     /* Clean the test */
269     exti_writel(EXTI_PR1, 0x00000001);
270     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
271     unpend_nvic_irq(EXTI0_IRQ);
272     g_assert_false(check_nvic_pending(EXTI0_IRQ));
273 
274     /* Configure EXTI line 0 irq on falling edge */
275     exti_set_irq(0, 0);
276     exti_writel(EXTI_IMR1, 0x00000001);
277     exti_writel(EXTI_RTSR1, 0x00000000);
278     exti_writel(EXTI_FTSR1, 0x00000001);
279 
280     /* Test that an irq is raised on falling edge only */
281     exti_set_irq(0, 1);
282     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
283     g_assert_false(check_nvic_pending(EXTI0_IRQ));
284 
285     exti_set_irq(0, 0);
286     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000001);
287     g_assert_true(check_nvic_pending(EXTI0_IRQ));
288 
289     /* Clean the test */
290     exti_writel(EXTI_PR1, 0x00000001);
291     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
292     unpend_nvic_irq(EXTI0_IRQ);
293     g_assert_false(check_nvic_pending(EXTI0_IRQ));
294 
295     /* Configure EXTI line 0 irq on falling and rising edge */
296     exti_writel(EXTI_IMR1, 0x00000001);
297     exti_writel(EXTI_RTSR1, 0x00000001);
298     exti_writel(EXTI_FTSR1, 0x00000001);
299 
300     /* Test that an irq is raised on rising edge */
301     exti_set_irq(0, 1);
302     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000001);
303     g_assert_true(check_nvic_pending(EXTI0_IRQ));
304 
305     /* Clean the test */
306     exti_writel(EXTI_PR1, 0x00000001);
307     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
308     unpend_nvic_irq(EXTI0_IRQ);
309     g_assert_false(check_nvic_pending(EXTI0_IRQ));
310 
311     /* Test that an irq is raised on falling edge */
312     exti_set_irq(0, 0);
313     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000001);
314     g_assert_true(check_nvic_pending(EXTI0_IRQ));
315 
316     /* Clean the test */
317     exti_writel(EXTI_PR1, 0x00000001);
318     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
319     unpend_nvic_irq(EXTI0_IRQ);
320     g_assert_false(check_nvic_pending(EXTI0_IRQ));
321 
322     /* Configure EXTI line 0 irq without selecting an edge trigger */
323     exti_writel(EXTI_IMR1, 0x00000001);
324     exti_writel(EXTI_RTSR1, 0x00000000);
325     exti_writel(EXTI_FTSR1, 0x00000000);
326 
327     /* Test that no irq is raised */
328     exti_set_irq(0, 1);
329     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
330     g_assert_false(check_nvic_pending(EXTI0_IRQ));
331 
332     exti_set_irq(0, 0);
333     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
334     g_assert_false(check_nvic_pending(EXTI0_IRQ));
335 }
336 
337 static void test_no_software_interrupt(void)
338 {
339     /*
340      * Test that software irq doesn't happen when :
341      * - corresponding bit in IMR isn't set
342      * - SWIER is set to 1 before IMR is set to 1
343      */
344 
345     /*
346      * Testing interrupt line EXTI0
347      * Bit 0 in EXTI_*1 registers (EXTI0) corresponds to GPIO Px_0
348      */
349 
350     enable_nvic_irq(EXTI0_IRQ);
351     /* Check that there are no interrupts already pending in PR */
352     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
353     /* Check that this specific interrupt isn't pending in NVIC */
354     g_assert_false(check_nvic_pending(EXTI0_IRQ));
355 
356     /* Mask interrupt line EXTI0 */
357     exti_writel(EXTI_IMR1, 0x00000000);
358     /* Set the corresponding SWIER bit from '0' to '1' */
359     exti_writel(EXTI_SWIER1, 0x00000000);
360     exti_writel(EXTI_SWIER1, 0x00000001);
361 
362     /* Check that the write in SWIER was effective */
363     g_assert_cmpuint(exti_readl(EXTI_SWIER1), ==, 0x00000001);
364     /* Check that the pending bit in PR wasn't set */
365     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
366     /* Check that the interrupt isn't pending in NVIC */
367     g_assert_false(check_nvic_pending(EXTI0_IRQ));
368 
369     /* Enable interrupt line EXTI0 */
370     exti_writel(EXTI_IMR1, 0x00000001);
371 
372     /* Check that the pending bit in PR wasn't set */
373     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
374     /* Check that the interrupt isn't pending in NVIC */
375     g_assert_false(check_nvic_pending(EXTI0_IRQ));
376 
377     /*
378      * Testing interrupt line EXTI35
379      * Bit 3 in EXTI_*2 registers (EXTI35) corresponds to PVM 1 Wakeup
380      */
381 
382     enable_nvic_irq(EXTI35_IRQ);
383     /* Check that there are no interrupts already pending in PR */
384     g_assert_cmpuint(exti_readl(EXTI_PR2), ==, 0x00000000);
385     /* Check that this specific interrupt isn't pending in NVIC */
386     g_assert_false(check_nvic_pending(EXTI35_IRQ));
387 
388     /* Mask interrupt line EXTI35 */
389     exti_writel(EXTI_IMR2, 0x00000000);
390     /* Set the corresponding SWIER bit from '0' to '1' */
391     exti_writel(EXTI_SWIER2, 0x00000000);
392     exti_writel(EXTI_SWIER2, 0x00000008);
393 
394     /* Check that the write in SWIER was effective */
395     g_assert_cmpuint(exti_readl(EXTI_SWIER2), ==, 0x00000008);
396     /* Check that the pending bit in PR wasn't set */
397     g_assert_cmpuint(exti_readl(EXTI_PR2), ==, 0x00000000);
398     /* Check that the interrupt isn't pending in NVIC */
399     g_assert_false(check_nvic_pending(EXTI35_IRQ));
400 
401     /* Enable interrupt line EXTI35 */
402     exti_writel(EXTI_IMR2, 0x00000008);
403 
404     /* Check that the pending bit in PR wasn't set */
405     g_assert_cmpuint(exti_readl(EXTI_PR2), ==, 0x00000000);
406     /* Check that the interrupt isn't pending in NVIC */
407     g_assert_false(check_nvic_pending(EXTI35_IRQ));
408 }
409 
410 static void test_masked_interrupt(void)
411 {
412     /*
413      * Test that irq doesn't happen when :
414      * - corresponding bit in IMR isn't set
415      * - SWIER is set to 1 before IMR is set to 1
416      */
417 
418     /*
419      * Testing interrupt line EXTI1
420      * with rising edge from GPIOx pin 1
421      */
422 
423     enable_nvic_irq(EXTI1_IRQ);
424     /* Check that there are no interrupts already pending in PR */
425     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
426     /* Check that this specific interrupt isn't pending in NVIC */
427     g_assert_false(check_nvic_pending(EXTI1_IRQ));
428 
429     /* Mask interrupt line EXTI1 */
430     exti_writel(EXTI_IMR1, 0x00000000);
431 
432     /* Configure interrupt on rising edge */
433     exti_writel(EXTI_RTSR1, 0x00000002);
434 
435     /* Simulate rising edge from GPIO line 1 */
436     exti_set_irq(1, 1);
437 
438     /* Check that the pending bit in PR wasn't set */
439     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
440     /* Check that the interrupt isn't pending in NVIC */
441     g_assert_false(check_nvic_pending(EXTI1_IRQ));
442 
443     /* Enable interrupt line EXTI1 */
444     exti_writel(EXTI_IMR1, 0x00000002);
445 
446     /* Check that the pending bit in PR wasn't set */
447     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
448     /* Check that the interrupt isn't pending in NVIC */
449     g_assert_false(check_nvic_pending(EXTI1_IRQ));
450 }
451 
452 static void test_interrupt(void)
453 {
454     /*
455      * Test that we can launch an irq by :
456      * - enabling its line in IMR
457      * - configuring interrupt on rising edge
458      * - and then setting the input line from '0' to '1'
459      *
460      * And that the interruption stays pending in NVIC
461      * even after clearing the pending bit in PR.
462      */
463 
464     /*
465      * Testing interrupt line EXTI1
466      * with rising edge from GPIOx pin 1
467      */
468 
469     enable_nvic_irq(EXTI1_IRQ);
470     /* Check that there are no interrupts already pending in PR */
471     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
472     /* Check that this specific interrupt isn't pending in NVIC */
473     g_assert_false(check_nvic_pending(EXTI1_IRQ));
474 
475     /* Enable interrupt line EXTI1 */
476     exti_writel(EXTI_IMR1, 0x00000002);
477 
478     /* Configure interrupt on rising edge */
479     exti_writel(EXTI_RTSR1, 0x00000002);
480 
481     /* Simulate rising edge from GPIO line 1 */
482     exti_set_irq(1, 1);
483 
484     /* Check that the pending bit in PR was set */
485     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000002);
486     /* Check that the interrupt is pending in NVIC */
487     g_assert_true(check_nvic_pending(EXTI1_IRQ));
488 
489     /* Clear the pending bit in PR */
490     exti_writel(EXTI_PR1, 0x00000002);
491 
492     /* Check that the write in PR was effective */
493     g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
494     /* Check that the interrupt is still pending in the NVIC */
495     g_assert_true(check_nvic_pending(EXTI1_IRQ));
496 
497     /* Clean NVIC */
498     unpend_nvic_irq(EXTI1_IRQ);
499     g_assert_false(check_nvic_pending(EXTI1_IRQ));
500 }
501 
502 int main(int argc, char **argv)
503 {
504     int ret;
505 
506     g_test_init(&argc, &argv, NULL);
507     g_test_set_nonfatal_assertions();
508     qtest_add_func("stm32l4x5/exti/direct_lines", test_direct_lines_write);
509     qtest_add_func("stm32l4x5/exti/reserved_bits", test_reserved_bits_write);
510     qtest_add_func("stm32l4x5/exti/reg_write_read", test_reg_write_read);
511     qtest_add_func("stm32l4x5/exti/no_software_interrupt",
512                    test_no_software_interrupt);
513     qtest_add_func("stm32l4x5/exti/software_interrupt",
514                    test_software_interrupt);
515     qtest_add_func("stm32l4x5/exti/masked_interrupt", test_masked_interrupt);
516     qtest_add_func("stm32l4x5/exti/interrupt", test_interrupt);
517     qtest_add_func("stm32l4x5/exti/test_edge_selector", test_edge_selector);
518 
519     qtest_start("-machine b-l475e-iot01a");
520     ret = g_test_run();
521     qtest_end();
522 
523     return ret;
524 }
525