5 #include "sw/device/lib/testing/i2c_testutils.h"
17 #include "sw/device/lib/testing/pinmux_testutils.h"
18 #include "sw/device/lib/testing/test_framework/check.h"
23 #define MODULE_ID MAKE_MODULE_ID('i', 'i', 't')
35 .suppress_nak_irq =
false};
96 static status_t map_platform_to_pins(i2c_pinmux_platform_id_t platform,
99 TRY_CHECK(pins != NULL);
101 case I2cPinmuxPlatformIdHyper310:
113 case I2cPinmuxPlatformIdDvsim:
118 TRY(map_platform_to_pins(I2cPinmuxPlatformIdHyper310, i2c_id, pins));
135 TRY(map_platform_to_pins(I2cPinmuxPlatformIdCw310Pmod, i2c_id, pins));
138 TRY_CHECK(
false,
"invalid i2c_id: %0d", i2c_id);
142 case I2cPinmuxPlatformIdCw310Pmod:
155 TRY_CHECK(
false,
"invalid platform: %0d", platform);
161 status_t i2c_testutils_write(
const dif_i2c_t *i2c, uint8_t addr,
162 size_t byte_count,
const uint8_t *data,
167 TRY_CHECK(byte_count > 0);
171 data_frame = (uint8_t)(addr << 1) | (uint8_t)kI2cWrite;
175 flags = kDefaultFlags;
176 if (byte_count > 1) {
180 flags.
stop = !skip_stop;
187 status_t i2c_testutils_issue_read(
const dif_i2c_t *i2c, uint8_t addr,
188 uint8_t byte_count) {
195 data_frame = (uint8_t)(addr << 1) | (uint8_t)kI2cRead;
198 TRY(i2c_testutils_wait_transaction_finish(i2c));
203 flags = kDefaultFlags;
219 status_t i2c_testutils_read(
const dif_i2c_t *i2c, uint8_t addr,
220 size_t byte_count, uint8_t *data,
size_t timeout) {
221 uint32_t nak_count = 0;
234 I2C_PARAM_FIFO_DEPTH < UINT8_MAX ? I2C_PARAM_FIFO_DEPTH : UINT8_MAX;
235 uint8_t chunk = (uint8_t)(byte_count < max_chunk ? byte_count : max_chunk);
238 while (TRY(i2c_testutils_issue_read(i2c, addr, chunk))) {
241 return DEADLINE_EXCEEDED();
250 }
while (byte_count > 0);
252 TRY(i2c_testutils_wait_transaction_finish(i2c));
253 return OK_STATUS((int32_t)nak_count);
256 status_t i2c_testutils_target_check_start(
const dif_i2c_t *i2c, uint8_t *addr) {
259 TRY_CHECK(acq_fifo_lvl > 1);
268 return OK_STATUS(
byte & kI2cRead);
271 status_t i2c_testutils_target_check_end(
const dif_i2c_t *i2c,
272 uint8_t *cont_byte) {
275 TRY_CHECK(acq_fifo_lvl >= 1);
283 return OK_STATUS(
false);
285 TRY_CHECK(cont_byte != NULL);
289 return OK_STATUS(
true);
292 status_t i2c_testutils_target_read(
const dif_i2c_t *i2c, uint16_t byte_count,
293 const uint8_t *data) {
297 TRY_CHECK(tx_fifo_lvl + byte_count <= I2C_PARAM_FIFO_DEPTH);
298 TRY_CHECK(acq_fifo_lvl + 2 <= I2C_PARAM_FIFO_DEPTH);
300 for (uint16_t i = 0; i < byte_count; ++i) {
307 status_t i2c_testutils_target_check_read(
const dif_i2c_t *i2c, uint8_t *addr,
308 uint8_t *cont_byte) {
309 int32_t dir = TRY(i2c_testutils_target_check_start(i2c, addr));
310 TRY_CHECK(dir == kI2cRead);
312 return i2c_testutils_target_check_end(i2c, cont_byte);
315 status_t i2c_testutils_target_write(
const dif_i2c_t *i2c, uint16_t byte_count) {
318 TRY_CHECK(acq_fifo_lvl + 2 + byte_count <= I2C_PARAM_FIFO_DEPTH);
324 status_t i2c_testutils_target_check_write(
const dif_i2c_t *i2c,
325 uint16_t byte_count, uint8_t *addr,
326 uint8_t *bytes, uint8_t *cont_byte) {
329 TRY_CHECK(acq_fifo_lvl >= 2 + byte_count);
331 int32_t dir = TRY(i2c_testutils_target_check_start(i2c, addr));
332 TRY_CHECK(dir == kI2cWrite);
334 for (uint16_t i = 0; i < byte_count; ++i) {
342 return i2c_testutils_target_check_end(i2c, cont_byte);
345 status_t i2c_testutils_select_pinmux(
const dif_pinmux_t *pinmux, uint8_t i2c_id,
346 i2c_pinmux_platform_id_t platform) {
348 platform < I2cPinmuxPlatformIdCount && i2c_id <
ARRAYSIZE(kI2cPinmuxPins),
349 "Index out of bounds");
351 TRY(map_platform_to_pins(platform, i2c_id, &platform_pins));
354 platform_pins.sda.insel));
356 kI2cPinmuxPins[i2c_id].sda.outsel));
360 platform_pins.scl.insel));
362 kI2cPinmuxPins[i2c_id].scl.outsel));
366 status_t i2c_testutils_detach_pinmux(
const dif_pinmux_t *pinmux,
379 uint32_t speed_khz = 0;
382 LOG_INFO(
"Setting i2c to %s mode.",
"Standard (100kHz)");
386 LOG_INFO(
"Setting i2c to %s mode.",
"Fast (400kHz)");
390 LOG_INFO(
"Setting i2c to %s mode.",
"FastPlus (1000kHz)");
397 .clock_period_nanos =
399 .sda_rise_nanos = 400,
400 .sda_fall_nanos = 110,
401 .scl_period_nanos = 1000000 / speed_khz};
411 LOG_INFO(
"period:%d nanos, cycles={fall=%d, rise=%d, hi=%d, lo=%d}",
413 config.rise_cycles, config.scl_time_high_cycles,
414 config.scl_time_low_cycles);
425 status_t i2c_testutils_wait_host_idle(
const dif_i2c_t *i2c) {
429 }
while (!
status.host_idle);
433 status_t i2c_testutils_wait_transaction_finish(
const dif_i2c_t *i2c) {
435 bool controller_halted =
false;
437 TRY(dif_i2c_irq_is_pending(i2c, kDifI2cIrqControllerHalt,
438 &controller_halted));
439 if (controller_halted) {
443 }
while (!
status.fmt_fifo_empty);