diff options
-rw-r--r-- | board/nucleo-f072rb/board.c | 5 | ||||
-rw-r--r-- | board/nucleo-f072rb/board.h | 4 | ||||
-rw-r--r-- | board/nucleo-f072rb/gpio.inc | 3 | ||||
-rw-r--r-- | board/stm32l476g-eval/gpio.inc | 5 | ||||
-rw-r--r-- | cts/interrupt/cts.testlist | 12 | ||||
-rw-r--r-- | cts/interrupt/dut.c | 53 | ||||
-rw-r--r-- | cts/interrupt/th.c | 25 |
7 files changed, 92 insertions, 15 deletions
diff --git a/board/nucleo-f072rb/board.c b/board/nucleo-f072rb/board.c index 1d60231ebe..48a51c7b02 100644 --- a/board/nucleo-f072rb/board.c +++ b/board/nucleo-f072rb/board.c @@ -21,9 +21,8 @@ void button_event(enum gpio_signal signal) * Dummy interrupt handler. It's supposed to be overwritten by each suite * if needed. */ -__attribute__((weak)) void cts_irq(enum gpio_signal signal) -{ -} +__attribute__((weak)) void cts_irq1(enum gpio_signal signal) {} +__attribute__((weak)) void cts_irq2(enum gpio_signal signal) {} #endif #include "gpio_list.h" diff --git a/board/nucleo-f072rb/board.h b/board/nucleo-f072rb/board.h index c008deb395..9cc2fc2d0b 100644 --- a/board/nucleo-f072rb/board.h +++ b/board/nucleo-f072rb/board.h @@ -18,10 +18,14 @@ /* Optional features */ #define CONFIG_STM_HWTIMER32 +#ifdef CTS_MODULE +#undef STM32_IRQ_EXT2_3_PRIORITY +#define STM32_IRQ_EXT2_3_PRIORITY 2 #ifdef CTS_MODULE_I2C #define CONFIG_I2C #define CONFIG_I2C_MASTER #endif +#endif #undef CONFIG_WATCHDOG_HELP #undef CONFIG_LID_SWITCH diff --git a/board/nucleo-f072rb/gpio.inc b/board/nucleo-f072rb/gpio.inc index 31149bf633..6f3b592845 100644 --- a/board/nucleo-f072rb/gpio.inc +++ b/board/nucleo-f072rb/gpio.inc @@ -13,11 +13,12 @@ GPIO_INT(USER_BUTTON, PIN(C, 13), GPIO_INT_FALLING, button_event) #ifndef CTS_MODULE_GPIO /* Overload C1 for interrupt. Enabled only for non-GPIO suites as * GPIO tests don't require a separate notification line. */ -GPIO_INT(CTS_IRQ, PIN(C, 1), GPIO_INT_FALLING | GPIO_PULL_UP , cts_irq) +GPIO_INT(CTS_IRQ1, PIN(C, 1), GPIO_INT_FALLING | GPIO_PULL_UP , cts_irq1) /* Used to disable interrupt. This IRQ# has to match the number used for the * pin set above */ #define CTS_IRQ_NUMBER STM32_IRQ_EXTI0_1 #endif +GPIO_INT(CTS_IRQ2, PIN(C, 2), GPIO_INT_FALLING | GPIO_PULL_UP , cts_irq2) #endif /* Outputs */ diff --git a/board/stm32l476g-eval/gpio.inc b/board/stm32l476g-eval/gpio.inc index ff896d8da5..9cf5bc0aa4 100644 --- a/board/stm32l476g-eval/gpio.inc +++ b/board/stm32l476g-eval/gpio.inc @@ -28,9 +28,10 @@ ALTERNATE(PIN_MASK(G, 0x0180), GPIO_ALT_F8, MODULE_UART, 0) /* LPUART: PG7/8 */ #ifdef CTS_MODULE /* CTS Signals */ -GPIO(HANDSHAKE_OUTPUT, PIN(D, 2), GPIO_ODR_LOW) -GPIO(HANDSHAKE_INPUT, PIN(C, 12), GPIO_INPUT | GPIO_PULL_UP) +GPIO(HANDSHAKE_OUTPUT, PIN(A, 9), GPIO_ODR_LOW) +GPIO(HANDSHAKE_INPUT, PIN(A, 8), GPIO_INPUT | GPIO_PULL_UP) GPIO(OUTPUT_TEST, PIN(C, 11), GPIO_ODR_LOW) +GPIO(CTS_IRQ2, PIN(C, 12), GPIO_ODR_LOW) #ifdef CTS_MODULE_GPIO GPIO(INPUT_TEST, PIN(C, 10), GPIO_INPUT | GPIO_PULL_UP) #endif diff --git a/cts/interrupt/cts.testlist b/cts/interrupt/cts.testlist index 6153c2b52d..01d6c1b06e 100644 --- a/cts/interrupt/cts.testlist +++ b/cts/interrupt/cts.testlist @@ -13,6 +13,18 @@ CTS_TEST(test_task_wait_event) /* Test task_disable_irq */ CTS_TEST(test_task_disable_irq) +/* Test nested interrupt. Lower priority IRQ is fired, followed by + * higher priority IRQ. Handler executions should be nested. + * + * P1 *-----* + * / \ + * P2 *----* *----* + * / \ + * task_cts ----* *---- + * A B C D + */ +CTS_TEST(test_nested_interrupt_low_high) + /* * Other ideas * diff --git a/cts/interrupt/dut.c b/cts/interrupt/dut.c index 43740147a7..9bf7eabde6 100644 --- a/cts/interrupt/dut.c +++ b/cts/interrupt/dut.c @@ -3,6 +3,7 @@ * found in the LICENSE file. */ +#include <string.h> #include "common.h" #include "gpio.h" #include "registers.h" @@ -13,6 +14,8 @@ static int got_interrupt; static int wake_me_up; +static int state_index; +static char state[4]; /* * Raw busy loop. Returns 1 if loop finishes before interrupt is triggered. @@ -39,14 +42,35 @@ static int busy_loop(void) /* * Interrupt handler. */ -void cts_irq(enum gpio_signal signal) +void cts_irq1(enum gpio_signal signal) { + state[state_index++] = 'B'; /* test some APIs */ got_interrupt = in_interrupt_context(); /* Wake up the CTS task */ if (wake_me_up) task_wake(TASK_ID_CTS); + state[state_index++] = 'C'; +} + +void cts_irq2(enum gpio_signal signal) +{ + state[state_index++] = 'A'; + busy_loop(); + state[state_index++] = 'D'; +} + +static void clear_state(void) +{ + uint32_t *event; + + got_interrupt = 0; + wake_me_up = 0; + state_index = 0; + memset(state, '_', sizeof(state)); + event = task_get_event_bitmap(TASK_ID_CTS); + *event = 0; } enum cts_rc test_task_wait_event(void) @@ -106,6 +130,27 @@ enum cts_rc test_interrupt_disable(void) return CTS_RC_SUCCESS; } +enum cts_rc test_nested_interrupt_low_high(void) +{ + uint32_t event; + + event = task_wait_event(CTS_INTERRUPT_TRIGGER_DELAY_US * 4); + if (event != TASK_EVENT_TIMER) { + CPRINTS("Woke up by 0x%08x", event); + return CTS_RC_FAILURE; + } + if (!got_interrupt) { + CPRINTS("Interrupt context not detected"); + return CTS_RC_TIMEOUT; + } + if (memcmp(state, "ABCD", sizeof(state))) { + CPRINTS("State transition differs from expectation"); + return CTS_RC_FAILURE; + } + + return CTS_RC_SUCCESS; +} + #include "cts_testlist.h" void cts_task(void) @@ -113,11 +158,11 @@ void cts_task(void) enum cts_rc rc; int i; - gpio_enable_interrupt(GPIO_CTS_IRQ); + gpio_enable_interrupt(GPIO_CTS_IRQ1); + gpio_enable_interrupt(GPIO_CTS_IRQ2); interrupt_enable(); for (i = 0; i < CTS_TEST_ID_COUNT; i++) { - got_interrupt = 0; - wake_me_up = 0; + clear_state(); sync(); rc = tests[i].run(); interrupt_enable(); diff --git a/cts/interrupt/th.c b/cts/interrupt/th.c index 3bcf2168b6..87582490ed 100644 --- a/cts/interrupt/th.c +++ b/cts/interrupt/th.c @@ -9,34 +9,48 @@ #include "timer.h" #include "watchdog.h" -static void trigger_interrupt(void) +static void trigger_interrupt1(void) { usleep(CTS_INTERRUPT_TRIGGER_DELAY_US); gpio_set_level(GPIO_OUTPUT_TEST, 0); usleep(CTS_INTERRUPT_TRIGGER_DELAY_US); } +static void trigger_interrupt2(void) +{ + usleep(CTS_INTERRUPT_TRIGGER_DELAY_US); + gpio_set_level(GPIO_CTS_IRQ2, 0); + usleep(CTS_INTERRUPT_TRIGGER_DELAY_US); +} + enum cts_rc test_task_wait_event(void) { - trigger_interrupt(); + trigger_interrupt1(); return CTS_RC_SUCCESS; } enum cts_rc test_task_disable_irq(void) { - trigger_interrupt(); + trigger_interrupt1(); return CTS_RC_SUCCESS; } enum cts_rc test_interrupt_enable(void) { - trigger_interrupt(); + trigger_interrupt1(); return CTS_RC_SUCCESS; } enum cts_rc test_interrupt_disable(void) { - trigger_interrupt(); + trigger_interrupt1(); + return CTS_RC_SUCCESS; +} + +enum cts_rc test_nested_interrupt_low_high(void) +{ + trigger_interrupt2(); + trigger_interrupt1(); return CTS_RC_SUCCESS; } @@ -51,6 +65,7 @@ void cts_task(void) for (i = 0; i < CTS_TEST_ID_COUNT; i++) { gpio_set_level(GPIO_OUTPUT_TEST, 1); + gpio_set_level(GPIO_CTS_IRQ2, 1); sync(); rc = tests[i].run(); CPRINTF("\n%s %d\n", tests[i].name, rc); |