blob: d336acf4f50322a945507fe14ff58ecdefab4ca0 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include "sw/device/lib/testing/i2c_testutils.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_i2c.h"
#include "sw/device/lib/runtime/hart.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "i2c_regs.h" // Generated.
static const uint8_t kI2cWrite = 0;
static const uint8_t kI2cRead = 1;
// Default flags for i2c operations.
static const dif_i2c_fmt_flags_t kDefaultFlags = {.start = false,
.stop = false,
.read = false,
.read_cont = false,
.suppress_nak_irq = false};
void i2c_testutils_wr(dif_i2c_t *i2c, uint8_t addr, uint8_t byte_count,
uint8_t *data, bool skip_stop) {
dif_i2c_fmt_flags_t flags = kDefaultFlags;
uint8_t data_frame;
// TODO: The current function does not support write payloads
// larger than the fifo depth.
CHECK(byte_count < I2C_PARAM_FIFO_DEPTH);
// First write the address.
flags.start = true;
data_frame = (addr << 1) | kI2cWrite;
CHECK_DIF_OK(dif_i2c_write_byte_raw(i2c, data_frame, flags));
// Once address phase is through, blast the rest as generic data.
flags = kDefaultFlags;
for (uint8_t i = 0; i < byte_count; ++i) {
// Issue a stop for the last byte.
flags.stop = ((i == byte_count - 1) && !skip_stop);
CHECK_DIF_OK(dif_i2c_write_byte_raw(i2c, data[i], flags));
}
// TODO: Check for errors / status.
}
void i2c_testutils_rd(dif_i2c_t *i2c, uint8_t addr, uint8_t byte_count) {
dif_i2c_fmt_flags_t flags = kDefaultFlags;
uint8_t data_frame;
uint8_t fifo_level;
// First write the address.
flags.start = true;
data_frame = (addr << 1) | kI2cRead;
CHECK_DIF_OK(dif_i2c_write_byte_raw(i2c, data_frame, flags));
// Once address phase is through, issue the read transaction.
flags = kDefaultFlags;
flags.read = true;
flags.stop = true;
// Inform the controller how many bytes to read overall.
CHECK_DIF_OK(dif_i2c_write_byte_raw(i2c, byte_count, flags));
// TODO: Check for errors / status.
}