1 /*
2 * Copyright (c) 2025 Alexander Kozhinov <ak.alexander.kozhinov@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/irq.h>
9 #include <zephyr/init.h>
10 #include <zephyr/device.h>
11 #include <zephyr/kernel.h>
12 #include <zephyr/sys/atomic.h>
13 #include <zephyr/drivers/interrupt_controller/intc_exti_stm32.h>
14
15
16 #define EXTI_DT_NODE DT_INST(0, st_stm32_exti)
17 #define EXTI_NUM_LINES_TOTAL DT_PROP(EXTI_DT_NODE, num_lines)
18 #define EXTI_NUM_LINES_GPIO DT_PROP(EXTI_DT_NODE, num_gpio_lines)
19
20 #define TEST_EXTI_LINE_NR DT_PROP(DT_INST(0, test_st_stm32_exti), exti_line_nr)
21 #define TEST_EXTI_IRQ_NR DT_PROP(DT_INST(0, test_st_stm32_exti), exti_line_irq_nr)
22 #define TEST_EXTI_IRQ_PRIO DT_PROP(DT_INST(0, test_st_stm32_exti), exti_line_irq_prio)
23
24
25 BUILD_ASSERT(TEST_EXTI_LINE_NR < EXTI_NUM_LINES_TOTAL, "Invalid EXTI line number");
26
27 static atomic_t is_test_exti_isr_called;
28
test_exti_isr(void)29 static void test_exti_isr(void)
30 {
31 zassert_true(stm32_exti_is_pending(TEST_EXTI_LINE_NR));
32 stm32_exti_clear_pending(TEST_EXTI_LINE_NR);
33
34 atomic_set(&is_test_exti_isr_called, true);
35 }
36
ZTEST(intc_exti_stm32,test_sw_interrupt_rising_trigger)37 ZTEST(intc_exti_stm32, test_sw_interrupt_rising_trigger)
38 {
39 int ret = 0;
40
41 ret = stm32_exti_enable(TEST_EXTI_LINE_NR,
42 STM32_EXTI_TRIG_RISING,
43 STM32_EXTI_MODE_IT);
44 zassert_ok(ret, "Failed to enable EXTI line %d", TEST_EXTI_LINE_NR);
45
46 atomic_set(&is_test_exti_isr_called, false);
47
48 ret = stm32_exti_sw_interrupt(TEST_EXTI_LINE_NR);
49 zassert_ok(ret, "Failed to fire SW interrupt on EXTI line %d",
50 TEST_EXTI_LINE_NR);
51
52 zassert_equal(is_test_exti_isr_called, true,
53 "ISR was not called for EXTI line %d", TEST_EXTI_LINE_NR);
54 }
55
ZTEST(intc_exti_stm32,test_sw_interrupt_falling_trigger)56 ZTEST(intc_exti_stm32, test_sw_interrupt_falling_trigger)
57 {
58 int ret = 0;
59
60 ret = stm32_exti_enable(TEST_EXTI_LINE_NR,
61 STM32_EXTI_TRIG_FALLING,
62 STM32_EXTI_MODE_IT);
63 zassert_ok(ret, "Failed to enable EXTI line %d", TEST_EXTI_LINE_NR);
64
65 atomic_set(&is_test_exti_isr_called, false);
66
67 ret = stm32_exti_sw_interrupt(TEST_EXTI_LINE_NR);
68 zassert_ok(ret, "Failed to fire SW interrupt on EXTI line %d",
69 TEST_EXTI_LINE_NR);
70
71 zassert_equal(is_test_exti_isr_called, true,
72 "ISR was not called for EXTI line %d", TEST_EXTI_LINE_NR);
73 }
74
ZTEST(intc_exti_stm32,test_sw_interrupt_both_triggers)75 ZTEST(intc_exti_stm32, test_sw_interrupt_both_triggers)
76 {
77 int ret = 0;
78
79 ret = stm32_exti_enable(TEST_EXTI_LINE_NR,
80 STM32_EXTI_TRIG_BOTH,
81 STM32_EXTI_MODE_IT);
82 zassert_ok(ret, "Failed to enable EXTI line %d", TEST_EXTI_LINE_NR);
83
84 atomic_set(&is_test_exti_isr_called, false);
85
86 ret = stm32_exti_sw_interrupt(TEST_EXTI_LINE_NR);
87 zassert_ok(ret, "Failed to fire SW interrupt on EXTI line %d",
88 TEST_EXTI_LINE_NR);
89
90 zassert_equal(is_test_exti_isr_called, true,
91 "ISR was not called for EXTI line %d", TEST_EXTI_LINE_NR);
92 }
93
test_exti_intc_init(void)94 static void *test_exti_intc_init(void)
95 {
96 IRQ_CONNECT(
97 TEST_EXTI_IRQ_NR, TEST_EXTI_IRQ_PRIO,
98 test_exti_isr, NULL, 0
99 );
100
101 irq_enable(TEST_EXTI_IRQ_NR);
102
103 return NULL;
104 }
105
106 ZTEST_SUITE(intc_exti_stm32, NULL, test_exti_intc_init, NULL, NULL, NULL);
107