13 #include "sw/device/lib/runtime/irq.h"
15 #include "sw/device/lib/testing/i2c_testutils.h"
16 #include "sw/device/lib/testing/rand_testutils.h"
17 #include "sw/device/lib/testing/test_framework/check.h"
19 #include "sw/device/lib/testing/test_framework/status.h"
22 #include "sw/device/lib/testing/autogen/isr_testutils.h"
26 #include "pinmux_regs.h"
29 static dif_pinmux_t pinmux;
30 static dif_rv_plic_t plic;
32 OTTF_DEFINE_TEST_CONFIG();
41 static volatile const uint8_t kClockPeriodNanos = 0;
42 static volatile const uint8_t kI2cRiseFallNanos = 0;
43 static volatile const uint32_t kI2cClockPeriodNanos = 0;
49 static volatile const uint8_t kI2cIdx = 0;
55 static volatile const uint8_t kI2cDeviceAddress0 = 0x55;
56 static volatile const uint8_t kI2cDeviceMask0 = 0x7f;
57 static volatile const uint8_t kI2cDeviceAddress1 = 0x7f;
59 static volatile const uint8_t kI2cDeviceMask1 = 0x7f;
68 static volatile const uint8_t kI2cByteCount = 0;
70 static volatile bool tx_empty_irq_seen =
false;
71 static volatile bool cmd_complete_irq_seen =
false;
81 const int unsigned base_addr;
82 const uint32_t i2c_irq_fmt_threshold_id;
114 void ottf_external_isr(uint32_t *exc_info) {
115 plic_isr_ctx_t plic_ctx = {.rv_plic = &plic,
118 i2c_isr_ctx_t i2c_ctx = {
120 .plic_i2c_start_irq_id =
121 i2c_configuration[kI2cIdx].i2c_irq_fmt_threshold_id,
123 .is_only_irq =
false};
126 dif_i2c_irq_t i2c_irq;
127 isr_testutils_i2c_isr(plic_ctx, i2c_ctx,
false, &peripheral, &i2c_irq);
130 case kDifI2cIrqTxStretch:
131 tx_empty_irq_seen =
true;
132 i2c_irq = kDifI2cIrqTxStretch;
134 case kDifI2cIrqCmdComplete:
135 cmd_complete_irq_seen =
true;
136 i2c_irq = kDifI2cIrqCmdComplete;
139 LOG_ERROR(
"Unexpected interrupt (at I2C): %d", i2c_irq);
150 LOG_INFO(
"Testing I2C index %d", kI2cIdx);
152 if (kI2cByteCount > I2C_PARAM_FIFO_DEPTH - 4) {
154 "Test cannot fit %d bytes, 2 START records, and 2 STOP records in "
155 "buffers of depth %d",
156 kI2cByteCount, I2C_PARAM_FIFO_DEPTH);
159 CHECK_DIF_OK(dif_i2c_init(
162 CHECK_DIF_OK(dif_pinmux_init(
165 CHECK_DIF_OK(dif_rv_plic_init(
169 i2c_testutils_select_pinmux(&pinmux, kI2cIdx, I2cPinmuxPlatformIdDvsim));
173 for (uint32_t i = 0; i < kNumI2cIrqs; ++i) {
175 &plic, i2c_configuration[kI2cIdx].plic_irqs[i],
184 irq_global_ctrl(
true);
185 irq_external_ctrl(
true);
190 .clock_period_nanos = kClockPeriodNanos,
191 .sda_rise_nanos = kI2cRiseFallNanos,
192 .sda_fall_nanos = kI2cRiseFallNanos,
193 .scl_period_nanos = kI2cClockPeriodNanos};
198 dif_i2c_id_t id0 = {.
mask = kI2cDeviceMask0, .address = kI2cDeviceAddress0},
199 id1 = {.
mask = kI2cDeviceMask1, .address = kI2cDeviceAddress1};
204 CHECK(!cmd_complete_irq_seen);
212 uint8_t expected_data[kI2cByteCount];
213 LOG_INFO(
"Loopback %d bytes with addresses %0h, %0h", kI2cByteCount,
214 kI2cDeviceAddress0, kI2cDeviceAddress1);
218 for (uint32_t i = 0; i < kI2cByteCount; ++i) {
219 expected_data[i] = (uint8_t)rand_testutils_gen32_range(0, 0xff);
224 IBEX_SPIN_FOR(!(tx_fifo_lvl > 0 && tx_empty_irq_seen ==
false), 100);
226 i2c_testutils_target_read(&i2c, kI2cByteCount, expected_data));
227 tx_empty_irq_seen =
false;
235 }
while (acq_fifo_lvl < 2);
237 CHECK(tx_fifo_lvl == 0);
240 CHECK_STATUS_OK(i2c_testutils_target_check_read(&i2c, &addr, NULL));
241 check_addr(addr, id0, id1);
244 CHECK_STATUS_OK(i2c_testutils_target_write(&i2c, kI2cByteCount));
248 }
while (acq_fifo_lvl < kI2cByteCount + 2);
251 uint8_t received_data[kI2cByteCount];
252 CHECK_STATUS_OK(i2c_testutils_target_check_write(&i2c, kI2cByteCount, &addr,
253 received_data, NULL));
254 check_addr(addr, id0, id1);
256 for (uint8_t i = 0; i < kI2cByteCount; ++i) {
257 CHECK(expected_data[i] == received_data[i]);
260 CHECK(cmd_complete_irq_seen);