blob: f36e62aa1e4bd0c800ffddd92bbb233fd3612776 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/mock-i2c/mock-i2c.h>
#include <hwreg/i2c.h>
class DummyI2cRegister : public hwreg::I2cRegisterBase<DummyI2cRegister, uint8_t, sizeof(uint8_t)> {
public:
DEF_BIT(7, test_bit);
DEF_FIELD(3, 0, test_field);
static auto Get() { return hwreg::I2cRegisterAddr<DummyI2cRegister>(0xAB); }
};
TEST(I2cHwregTest, Read) {
auto dut = DummyI2cRegister::Get().FromValue(0);
mock_i2c::MockI2c mock_i2c;
mock_i2c.ExpectWrite({0xAB}).ExpectReadStop({0x8A});
auto proto = ddk::I2cProtocolClient(mock_i2c.GetProto());
EXPECT_OK(dut.ReadFrom(proto));
EXPECT_EQ(dut.test_bit(), 1);
EXPECT_EQ(dut.test_field(), 0xA);
mock_i2c.VerifyAndClear();
}
TEST(I2cHwregTest, Write) {
auto dut = DummyI2cRegister::Get().FromValue(0);
dut.set_test_bit(1);
dut.set_test_field(0xA);
mock_i2c::MockI2c mock_i2c;
mock_i2c.ExpectWriteStop({0xAB, 0x8A});
auto proto = ddk::I2cProtocolClient(mock_i2c.GetProto());
EXPECT_OK(dut.WriteTo(proto));
mock_i2c.VerifyAndClear();
}
class I2cRegister3ByteAddress
: public hwreg::I2cRegisterBase<I2cRegister3ByteAddress, uint8_t, sizeof(uint8_t) * 3,
hwreg::LittleEndian> {
public:
DEF_BIT(7, test_bit);
DEF_FIELD(3, 0, test_field);
static auto Get() { return hwreg::I2cRegisterAddr<I2cRegister3ByteAddress>(0xABCDEF); }
};
TEST(I2cHwregTest, I2c3ByteAddressRead) {
auto dut = I2cRegister3ByteAddress::Get().FromValue(0);
mock_i2c::MockI2c mock_i2c;
mock_i2c.ExpectWrite({0xEF, 0xCD, 0xAB}).ExpectReadStop({0x8A});
auto proto = ddk::I2cProtocolClient(mock_i2c.GetProto());
EXPECT_OK(dut.ReadFrom(proto));
EXPECT_EQ(dut.test_bit(), 1);
EXPECT_EQ(dut.test_field(), 0xA);
mock_i2c.VerifyAndClear();
}
TEST(I2cHwregTest, I2c3BytesAddressWrite) {
auto dut = I2cRegister3ByteAddress::Get().FromValue(0);
dut.set_test_bit(1);
dut.set_test_field(0xA);
mock_i2c::MockI2c mock_i2c;
mock_i2c.ExpectWriteStop({0xEF, 0xCD, 0xAB, 0x8A});
auto proto = ddk::I2cProtocolClient(mock_i2c.GetProto());
EXPECT_OK(dut.WriteTo(proto));
mock_i2c.VerifyAndClear();
}
class I2cBigEndianRegister : public hwreg::I2cRegisterBase<I2cBigEndianRegister, uint16_t,
sizeof(uint8_t) * 3, hwreg::BigEndian> {
public:
DEF_FIELD(15, 8, msb);
DEF_FIELD(7, 0, lsb);
static auto Get() { return hwreg::I2cRegisterAddr<I2cBigEndianRegister>(0xABCDEF); }
};
TEST(I2cHwregTest, BigEndianRead) {
auto dut = I2cBigEndianRegister::Get().FromValue(0);
mock_i2c::MockI2c mock_i2c;
mock_i2c.ExpectWrite({0xAB, 0xCD, 0xEF}).ExpectReadStop({0x0A, 0x0B});
auto proto = ddk::I2cProtocolClient(mock_i2c.GetProto());
EXPECT_OK(dut.ReadFrom(proto));
EXPECT_EQ(dut.msb(), 0x0A);
EXPECT_EQ(dut.lsb(), 0x0B);
mock_i2c.VerifyAndClear();
}
TEST(I2cHwregTest, BigEndianWrite) {
auto dut = I2cBigEndianRegister::Get().FromValue(0);
dut.set_msb(0xA);
dut.set_lsb(0xB);
mock_i2c::MockI2c mock_i2c;
mock_i2c.ExpectWriteStop({0xAB, 0xCD, 0xEF, 0x0A, 0x0B});
auto proto = ddk::I2cProtocolClient(mock_i2c.GetProto());
EXPECT_OK(dut.WriteTo(proto));
mock_i2c.VerifyAndClear();
}