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