13 #include "sw/device/lib/runtime/irq.h"
16 #include "sw/device/lib/testing/i2c_testutils.h"
17 #include "sw/device/lib/testing/rv_core_ibex_testutils.h"
18 #include "sw/device/lib/testing/rv_plic_testutils.h"
19 #include "sw/device/lib/testing/test_framework/check.h"
25 static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__,
26 "This test assumes the target platform is little endian.");
28 OTTF_DEFINE_TEST_CONFIG();
38 kIrqVoid = UINT32_MAX,
42 kDefaultTimeoutMicros = 5000,
45 static dif_rv_core_ibex_t rv_core_ibex;
46 static dif_pinmux_t pinmux;
48 static dif_rv_plic_t plic;
53 static volatile dif_i2c_irq_t irq_fired;
74 "IRQ from incorrect peripheral: exp = %d(i2c2), found = %d",
81 LOG_INFO(
"%s: plic:%d, i2c:%d", __func__, plic_irq_id, irq_fired);
85 TRY(dif_i2c_irq_get_type(&i2c, irq_fired, &irq_type));
88 TRY(dif_i2c_irq_acknowledge(&i2c, irq_fired));
98 void ottf_external_isr(uint32_t *exc_info) {
100 if (status_ok(isr_result)) {
105 static status_t write_byte(
const uint8_t addr[2], uint8_t
byte) {
106 uint8_t data[3] = {addr[0], addr[1],
byte};
107 return i2c_testutils_write(&i2c, kDeviceAddr,
sizeof(data), data,
false);
115 TRY(dif_i2c_irq_set_enabled(&i2c, kDifI2cIrqControllerHalt,
119 const uint8_t kAddr[2] = {0x03, 0x21};
120 TRY(write_byte(kAddr, 0xAB));
122 irq_global_ctrl(
false);
123 irq_fired = kIrqVoid;
124 irq_global_ctrl(
true);
130 .suppress_nak_irq =
false};
134 ATOMIC_WAIT_FOR_INTERRUPT(irq_fired == kDifI2cIrqControllerHalt);
136 TRY(dif_i2c_irq_set_enabled(&i2c, kDifI2cIrqControllerHalt,
149 static status_t nak_irq_disabled(
void) {
154 TRY(dif_i2c_irq_set_enabled(&i2c, kDifI2cIrqControllerHalt,
158 const uint8_t kAddr[2] = {0x03, 0x21};
159 TRY(write_byte(kAddr, 0xAB));
161 irq_global_ctrl(
false);
162 irq_fired = kIrqVoid;
163 irq_global_ctrl(
true);
169 .suppress_nak_irq =
true};
175 TRY(i2c_testutils_wait_transaction_finish(&i2c));
176 TRY_CHECK(irq_fired != kDifI2cIrqControllerHalt,
"Unexpected IRQ %u",
179 TRY(dif_i2c_irq_set_enabled(&i2c, kDifI2cIrqControllerHalt,
184 static status_t cmd_complete_irq(
void) {
186 TRY(dif_i2c_irq_acknowledge(&i2c, kDifI2cIrqCmdComplete));
189 irq_global_ctrl(
false);
190 irq_fired = kIrqVoid;
191 irq_global_ctrl(
true);
194 const uint8_t kAddr[2] = {0x03, 0x21};
195 TRY(write_byte(kAddr, 0xAB));
197 ATOMIC_WAIT_FOR_INTERRUPT(irq_fired == kDifI2cIrqCmdComplete);
203 static status_t fmt_threshold_irq(
void) {
207 TRY(dif_i2c_irq_get_type(&i2c, irq_fired, &irq_type));
211 TRY(dif_i2c_irq_acknowledge(&i2c, kDifI2cIrqFmtThreshold));
213 TRY(dif_i2c_irq_set_enabled(&i2c, kDifI2cIrqFmtThreshold,
218 irq_global_ctrl(
false);
219 irq_fired = kIrqVoid;
220 irq_global_ctrl(
true);
223 TRY(dif_i2c_irq_set_enabled(&i2c, kDifI2cIrqFmtThreshold,
227 const uint8_t kAddr[2] = {0x03, 0x21};
230 for (
size_t i = 0; i < 5; ++i) {
231 TRY(write_byte(kAddr, 0xAB));
235 TRY(dif_i2c_irq_set_enabled(&i2c, kDifI2cIrqFmtThreshold,
241 ATOMIC_WAIT_FOR_INTERRUPT(irq_fired == kDifI2cIrqFmtThreshold);
243 TRY(dif_i2c_irq_set_enabled(&i2c, kDifI2cIrqFmtThreshold,
248 static status_t rx_threshold_irq(
void) {
250 TRY(dif_i2c_irq_acknowledge(&i2c, kDifI2cIrqRxThreshold));
254 irq_global_ctrl(
false);
255 irq_fired = kIrqVoid;
256 irq_global_ctrl(
true);
259 const uint8_t kAddr[2] = {0x03, 0x21};
260 TRY(i2c_testutils_write(&i2c, kDeviceAddr, 2, kAddr,
true));
262 while (TRY(i2c_testutils_issue_read(&i2c, kDeviceAddr,
sizeof(bytes))))
266 ATOMIC_WAIT_FOR_INTERRUPT(irq_fired == kDifI2cIrqRxThreshold);
272 static status_t rx_overflow_irq(
void) {
274 TRY(dif_i2c_irq_acknowledge(&i2c, kDifI2cIrqRxOverflow));
277 irq_global_ctrl(
false);
278 irq_fired = kIrqVoid;
279 irq_global_ctrl(
true);
281 const uint8_t kAddr[2] = {0x03, 0x21};
282 uint8_t bytes[I2C_PARAM_FIFO_DEPTH + 1];
283 TRY(i2c_testutils_write(&i2c, kDeviceAddr, 2, kAddr,
true));
285 TRY(i2c_testutils_issue_read(&i2c, kDeviceAddr,
sizeof(bytes)));
288 ATOMIC_WAIT_FOR_INTERRUPT(irq_fired == kDifI2cIrqRxOverflow);
298 TRY(dif_rv_core_ibex_init(base_addr, &rv_core_ibex));
301 TRY(dif_i2c_init(base_addr, &i2c));
304 TRY(dif_pinmux_init(base_addr, &pinmux));
306 TRY(i2c_testutils_select_pinmux(&pinmux, 2, I2cPinmuxPlatformIdCw310Pmod));
311 TRY(dif_rv_plic_init(base_addr, &plic));
313 rv_plic_testutils_irq_range_enable(&plic, kHart,
318 irq_global_ctrl(
true);
319 irq_external_ctrl(
true);
326 CHECK_STATUS_OK(test_init());
328 test_result = OK_STATUS();
337 return status_ok(test_result);