11 #include "sw/device/lib/runtime/irq.h"
13 #include "sw/device/lib/testing/pinmux_testutils.h"
14 #include "sw/device/lib/testing/rv_plic_testutils.h"
15 #include "sw/device/lib/testing/test_framework/check.h"
18 static const dt_gpio_t kGpioDt = kDtGpio;
19 static const dt_pinmux_t kPinmuxDt = kDtPinmuxAon;
20 static const dt_rv_plic_t kRvPlicDt = kDtRvPlic;
27 static_assert(kDtGpioPeriphIoGpio0 == 0,
"kDtGpioPinGpio0 is expected to be 0");
29 static_assert(kDtGpioIrqGpio0 == 0,
"kDtGpioIrqGpio0 is expected to be 0");
31 "kDtGpioPinCount does not match kDifGpioNumPins");
33 static dif_gpio_t gpio;
34 static dif_pinmux_t pinmux;
35 static dif_rv_plic_t plic;
39 static volatile uint32_t expected_gpio_pin_irq;
40 static volatile bool expected_irq_edge;
72 static void gpio_output_test(
const dif_gpio_t *gpio, uint32_t mask) {
73 LOG_INFO(
"Starting GPIO output test");
80 uint32_t gpio_val = 1 << i;
93 CHECK(gpio_val == read_val,
"GPIOs mismatched (written = %x, read = %x)",
105 uint32_t gpio_val = ~(1 << i);
118 CHECK(gpio_val == read_val,
"GPIOs mismatched (written = %x, read = %x)",
139 static void gpio_input_test(
const dif_gpio_t *gpio, uint32_t mask) {
140 LOG_INFO(
"Starting GPIO input test");
151 CHECK_DIF_OK(dif_gpio_irq_restore_all(gpio, &mask));
157 expected_irq_edge =
true;
158 for (expected_gpio_pin_irq = 0; expected_gpio_pin_irq <
kDifGpioNumPins;
159 ++expected_gpio_pin_irq) {
163 uint32_t gpio_exp_val;
167 CHECK(gpio_exp_val == read_val,
168 "GPIOs mismatched (expected = %x, actual = %x)", gpio_exp_val,
172 expected_irq_edge =
false;
173 for (expected_gpio_pin_irq = 0; expected_gpio_pin_irq <
kDifGpioNumPins;
174 ++expected_gpio_pin_irq) {
178 gpio_exp_val = ~mask;
180 CHECK(gpio_exp_val == read_val,
181 "GPIOs mismatched (expected = %x, actual = %x)", gpio_exp_val,
190 void ottf_external_isr(uint32_t *exc_info) {
196 dt_instance_id_t inst_id = dt_plic_id_to_instance_id(plic_irq_id);
197 CHECK(inst_id == dt_gpio_instance_id(kGpioDt),
198 "Interrupt from incorrect peripheral: (exp: %d, obs: %s)",
199 dt_gpio_instance_id(kGpioDt), inst_id);
202 uint32_t gpio_pin_irq_fired = dt_gpio_irq_from_plic_id(kGpioDt, plic_irq_id);
205 CHECK(gpio_pin_irq_fired == expected_gpio_pin_irq,
206 "Incorrect GPIO interrupt (exp: %d, obs: %d)", expected_gpio_pin_irq,
210 uint32_t gpio_irqs_status;
211 CHECK_DIF_OK(dif_gpio_irq_get_state(&gpio, &gpio_irqs_status));
212 CHECK(gpio_irqs_status == (1 << expected_gpio_pin_irq),
213 "Incorrect GPIO irqs status {exp: %x, obs: %x}",
214 (1 << expected_gpio_pin_irq), gpio_irqs_status);
218 CHECK_DIF_OK(
dif_gpio_read(&gpio, expected_gpio_pin_irq, &pin_val));
221 CHECK(pin_val == expected_irq_edge,
"Incorrect GPIO %d pin value (exp: %b)",
222 expected_gpio_pin_irq, expected_irq_edge);
225 CHECK_DIF_OK(dif_gpio_irq_acknowledge(&gpio, gpio_pin_irq_fired));
231 OTTF_DEFINE_TEST_CONFIG();
233 void configure_pinmux(
void) {
236 dt_periph_io_t periph_io =
237 dt_gpio_periph_io(kGpioDt, kDtGpioPeriphIoGpio0 + i);
238 dt_pad_t pad = kPinmuxTestutilsGpioPads[i];
240 pinmux_testutils_connect(&pinmux, periph_io, kDtPeriphIoDirInout, pad));
246 CHECK_DIF_OK(dif_pinmux_init_from_dt(kPinmuxDt, &pinmux));
247 pinmux_testutils_init(&pinmux);
251 CHECK_DIF_OK(dif_gpio_init_from_dt(kGpioDt, &gpio));
254 CHECK_DIF_OK(dif_rv_plic_init_from_dt(kRvPlicDt, &plic));
257 dt_plic_irq_id_t first_irq = dt_gpio_irq_to_plic_id(kGpioDt, kDtGpioIrqGpio0);
258 rv_plic_testutils_irq_range_enable(&plic, kPlicTarget, first_irq,
262 irq_global_ctrl(
true);
263 irq_external_ctrl(
true);
266 uint32_t gpio_mask = pinmux_testutils_get_testable_gpios_mask();
267 gpio_output_test(&gpio, gpio_mask);
268 gpio_input_test(&gpio, gpio_mask);