12 #include "sw/device/lib/runtime/irq.h"
14 #include "sw/device/lib/testing/i2c_testutils.h"
15 #include "sw/device/lib/testing/rand_testutils.h"
16 #include "sw/device/lib/testing/test_framework/check.h"
18 #include "sw/device/lib/testing/test_framework/status.h"
21 #include "sw/device/lib/testing/autogen/isr_testutils.h"
24 #include "pinmux_regs.h"
27 static dif_pinmux_t pinmux;
28 static dif_rv_plic_t plic;
30 OTTF_DEFINE_TEST_CONFIG();
37 static volatile const uint8_t kClockPeriodNanos = 0;
38 static volatile const uint8_t kI2cRiseFallNanos = 0;
39 static volatile const uint32_t kI2cClockPeriodNanos = 0;
40 static volatile const uint8_t kI2cCdcInstrumentationEnabled = 0;
47 static volatile const uint8_t kI2cIdx = 0;
54 static volatile bool fmt_irq_seen =
false;
55 static volatile bool rx_irq_seen =
false;
56 static volatile bool done_irq_seen =
false;
60 static uint32_t i2c_irq_fmt_threshold_id;
61 static uint32_t i2c_base_addr;
64 void ottf_external_isr(uint32_t *exc_info) {
65 plic_isr_ctx_t plic_ctx = {.rv_plic = &plic,
68 i2c_isr_ctx_t i2c_ctx = {.i2c = &i2c,
69 .plic_i2c_start_irq_id = i2c_irq_fmt_threshold_id,
71 .is_only_irq =
false};
74 dif_i2c_irq_t i2c_irq;
75 isr_testutils_i2c_isr(plic_ctx, i2c_ctx,
false, &peripheral, &i2c_irq);
79 case kDifI2cIrqFmtThreshold:
81 i2c_irq = kDifI2cIrqFmtThreshold;
84 case kDifI2cIrqRxThreshold:
86 i2c_irq = kDifI2cIrqRxThreshold;
89 case kDifI2cIrqCmdComplete:
91 i2c_irq = kDifI2cIrqCmdComplete;
94 LOG_ERROR(
"Unexpected interrupt (at I2C): %d", i2c_irq);
104 static void en_plic_irqs(dif_rv_plic_t *plic) {
107 for (uint32_t i = 0; i <
ARRAYSIZE(plic_irqs); ++i) {
117 irq_global_ctrl(
true);
118 irq_external_ctrl(
true);
121 static void en_i2c_irqs(dif_i2c_t *i2c) {
122 dif_i2c_irq_t i2c_irqs[] = {
123 kDifI2cIrqRxThreshold, kDifI2cIrqRxOverflow, kDifI2cIrqControllerHalt,
124 kDifI2cIrqSclInterference, kDifI2cIrqSdaInterference,
125 kDifI2cIrqStretchTimeout,
128 kDifI2cIrqCmdComplete};
130 for (uint32_t i = 0; i <
ARRAYSIZE(i2c_irqs); ++i) {
135 static void en_i2c_status_irqs(dif_i2c_t *i2c) {
146 void config_i2c_with_index(
void) {
240 LOG_FATAL(
"Unsupported i2c index %d", kI2cIdx);
253 void issue_test_transactions(
bool skip_stop) {
255 uint8_t byte_count = (uint8_t)rand_testutils_gen32_range(30, 64);
256 uint8_t device_addr = (uint8_t)rand_testutils_gen32_range(0, 16);
257 uint8_t expected_data[byte_count];
258 LOG_INFO(
"Loopback %d bytes with device %d", byte_count, device_addr);
262 for (uint32_t i = 0; i < byte_count; ++i) {
263 expected_data[i] = (uint8_t)rand_testutils_gen32_range(0, 0xff);
267 CHECK_STATUS_OK(i2c_testutils_write(&i2c, device_addr, byte_count,
268 expected_data, skip_stop));
269 CHECK(!fmt_irq_seen);
270 en_i2c_status_irqs(&i2c);
278 }
while (fmt_fifo_lvl > 0);
280 fmt_irq_seen =
false;
284 CHECK_STATUS_OK(i2c_testutils_issue_read(&i2c, device_addr, byte_count));
290 }
while (rx_fifo_lvl < byte_count);
294 for (uint32_t i = 0; i < byte_count; ++i) {
297 if (expected_data[i] !=
byte) {
298 LOG_ERROR(
"Byte %d, Expected data 0x%x, read data 0x%x", i,
299 expected_data[i],
byte);
302 CHECK(done_irq_seen);
306 LOG_INFO(
"Testing I2C index %d", kI2cIdx);
307 CHECK_DIF_OK(dif_pinmux_init(
310 config_i2c_with_index();
313 CHECK_DIF_OK(dif_rv_plic_init(
321 .clock_period_nanos = kClockPeriodNanos,
322 .sda_rise_nanos = kI2cRiseFallNanos,
323 .sda_fall_nanos = kI2cRiseFallNanos,
324 .scl_period_nanos = kI2cClockPeriodNanos};
328 if (kI2cCdcInstrumentationEnabled) {
332 config.rise_cycles++;
342 CHECK(!fmt_irq_seen);
344 CHECK(!done_irq_seen);
345 issue_test_transactions(
false);
349 fmt_irq_seen =
false;
351 done_irq_seen =
false;
352 issue_test_transactions(
true);