Livt packages
Livt.IO
Version 1.8.1
Memory, UART, I2C, SPI, and Ethernet input/output components for Livt hardware designs.
Published files (126)
tests/i2c/I2cIntegrationTest.lvt
namespace Livt.IO.Tests
using Livt.IO
/**
* Test bus adapter that exposes observed line levels and low-drive requests without
* physical board pins.
*/
component ResolvedI2CTestBus : I2CBus
{
/**
* Initializes fixture state and constructor bindings. Test cases share the fixture
* instance rather than constructing a fresh subject for each method.
*/
new()
{
this.scl = 0b1
this.sda = 0b1
}
/**
* Models pull-ups: a low-drive request resolves low and a released line resolves high.
*/
process ResolveLines()
{
state {
if (this.scl_drive_low == 0b1) {
this.scl = 0b0
} else {
this.scl = 0b1
}
if (this.sda_drive_low == 0b1) {
this.sda = 0b0
} else {
this.sda = 0b1
}
}
}
}
/**
* Exercises I2CIntegration with a shared fixture instance. Each scenario establishes the
* inputs and state it needs.
*/
@Test
component I2CIntegrationTest
{
// Shared fixture instances, signals, and observation state.
bus: ResolvedI2CTestBus
combiner: I2CBusCombiner
master: I2CMaster
slave: I2CSlave
/**
* Creates the shared fixture instances (ResolvedI2CTestBus, I2CBusCombiner, I2CMaster,
* I2CSlave). Tests initialize the state required by their scenario.
*/
new()
{
this.bus = new ResolvedI2CTestBus()
this.combiner = new I2CBusCombiner(this.bus)
this.master = new I2CMaster(this.combiner.controller)
this.slave = new I2CSlave(this.combiner.target, 0x42)
}
/**
* Waits until the master is no longer busy; the test runner timeout bounds a stalled
* command.
*/
fn WaitForCommand()
{
while (this.master.IsBusy()) {
state {
}
}
}
/**
* Asserts START acceptance, waits for completion, and clears the retained master result.
*/
fn RunStart()
{
var accepted: bool = this.master.BeginStart()
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
this.master.ClearResult()
}
/**
* Asserts STOP acceptance, waits for completion, and clears the retained master result.
*/
fn RunStop()
{
var accepted: bool = this.master.BeginStop()
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
this.master.ClearResult()
}
/**
* Sends a seven-bit write address, asserts acceptance/completion, and returns the ACK flag
* before clearing status.
*/
fn RunWriteAddress(address: byte) bool
{
var accepted: bool = this.master.BeginWriteAddress(address)
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
var acked: bool = this.master.WasAckReceived()
this.master.ClearResult()
return acked
}
/**
* Sends a seven-bit read address, asserts acceptance/completion, and returns the ACK flag
* before clearing status.
*/
fn RunReadAddress(address: byte) bool
{
var accepted: bool = this.master.BeginReadAddress(address)
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
var acked: bool = this.master.WasAckReceived()
this.master.ClearResult()
return acked
}
/**
* Sends one data byte, asserts acceptance/completion, and returns the ACK flag before
* clearing status.
*/
fn RunWriteByte(value: byte) bool
{
var accepted: bool = this.master.BeginWriteByte(value)
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
var acked: bool = this.master.WasAckReceived()
this.master.ClearResult()
return acked
}
/**
* Receives one byte with the requested controller ACK/NACK, checks completion, and clears
* status before returning the byte.
*/
fn RunReadByte(sendAck: bool) byte
{
var accepted: bool = this.master.BeginReadByte(sendAck)
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
var value: byte = this.master.GetReadByte()
this.master.ClearResult()
return value
}
/**
* Checks the master writes byte to slave case.
*/
@Test
fn TestMasterWritesByteToSlave()
{
this.slave.ClearAddressMatch()
this.slave.ClearReceivedByte()
this.RunStart()
var addressAck: bool = this.RunWriteAddress(0x42)
assert this.slave.HasAddressMatch() == true
var dataAck: bool = this.RunWriteByte(0xA5)
this.RunStop()
assert addressAck == true
assert dataAck == true
assert this.slave.HasAddressMatch() == true
assert this.slave.WasWriteAddressed() == true
assert this.slave.HasReceivedByte() == true
assert this.slave.GetReceivedByte() == 0xA5
}
}
/**
* Exercises I2CReadIntegration with a shared fixture instance. Each scenario establishes
* the inputs and state it needs.
*/
@Test
component I2CReadIntegrationTest
{
// Shared fixture instances, signals, and observation state.
bus: ResolvedI2CTestBus
combiner: I2CBusCombiner
master: I2CMaster
slave: I2CSlave
/**
* Creates the shared fixture instances (ResolvedI2CTestBus, I2CBusCombiner, I2CMaster,
* I2CSlave). Tests initialize the state required by their scenario.
*/
new()
{
this.bus = new ResolvedI2CTestBus()
this.combiner = new I2CBusCombiner(this.bus)
this.master = new I2CMaster(this.combiner.controller)
this.slave = new I2CSlave(this.combiner.target, 0x42)
}
/**
* Waits until the master is no longer busy; the test runner timeout bounds a stalled
* command.
*/
fn WaitForCommand()
{
while (this.master.IsBusy()) {
state {
}
}
}
/**
* Asserts START acceptance, waits for completion, and clears the retained master result.
*/
fn RunStart()
{
var accepted: bool = this.master.BeginStart()
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
this.master.ClearResult()
}
/**
* Asserts STOP acceptance, waits for completion, and clears the retained master result.
*/
fn RunStop()
{
var accepted: bool = this.master.BeginStop()
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
this.master.ClearResult()
}
/**
* Sends a seven-bit read address, asserts acceptance/completion, and returns the ACK flag
* before clearing status.
*/
fn RunReadAddress(address: byte) bool
{
var accepted: bool = this.master.BeginReadAddress(address)
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
var acked: bool = this.master.WasAckReceived()
this.master.ClearResult()
return acked
}
/**
* Receives one byte with the requested controller ACK/NACK, checks completion, and clears
* status before returning the byte.
*/
fn RunReadByte(sendAck: bool) byte
{
var accepted: bool = this.master.BeginReadByte(sendAck)
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
var value: byte = this.master.GetReadByte()
this.master.ClearResult()
return value
}
/**
* Checks the master reads byte from slave case.
*/
@Test
fn TestMasterReadsByteFromSlave()
{
this.slave.ClearAddressMatch()
this.slave.ClearReadRequested()
this.slave.ClearTransmittedByte()
this.slave.SetTransmitByte(0x5A)
this.RunStart()
var addressAck: bool = this.RunReadAddress(0x42)
var value: byte = this.RunReadByte(false)
this.RunStop()
assert addressAck == true
assert this.slave.HasAddressMatch() == true
assert this.slave.WasReadAddressed() == true
assert value == 0x5A
assert this.slave.HasTransmittedByte() == true
assert this.slave.WasTransmitAcked() == false
}
}
/**
* Exercises I2CRegisterIntegration with a shared fixture instance. Each scenario
* establishes the inputs and state it needs.
*/
@Test
component I2CRegisterIntegrationTest
{
// Shared fixture instances, signals, and observation state.
bus: ResolvedI2CTestBus
combiner: I2CBusCombiner
master: I2CMaster
registers: I2CRegisterSlave
/**
* Creates the shared fixture instances (ResolvedI2CTestBus, I2CBusCombiner, I2CMaster,
* I2CRegisterSlave). Tests initialize the state required by their scenario.
*/
new()
{
this.bus = new ResolvedI2CTestBus()
this.combiner = new I2CBusCombiner(this.bus)
this.master = new I2CMaster(this.combiner.controller)
this.registers = new I2CRegisterSlave(this.combiner.target, 0x42)
}
/**
* Waits until the master is no longer busy; the test runner timeout bounds a stalled
* command.
*/
fn WaitForCommand()
{
while (this.master.IsBusy()) {
state {
}
}
}
/**
* Asserts START acceptance, waits for completion, and clears the retained master result.
*/
fn RunStart()
{
var accepted: bool = this.master.BeginStart()
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
this.master.ClearResult()
}
/**
* Asserts STOP acceptance, waits for completion, and clears the retained master result.
*/
fn RunStop()
{
var accepted: bool = this.master.BeginStop()
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
this.master.ClearResult()
}
/**
* Sends a seven-bit write address, asserts acceptance/completion, and returns the ACK flag
* before clearing status.
*/
fn RunWriteAddress(address: byte) bool
{
var accepted: bool = this.master.BeginWriteAddress(address)
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
var acked: bool = this.master.WasAckReceived()
this.master.ClearResult()
return acked
}
/**
* Sends a seven-bit read address, asserts acceptance/completion, and returns the ACK flag
* before clearing status.
*/
fn RunReadAddress(address: byte) bool
{
var accepted: bool = this.master.BeginReadAddress(address)
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
var acked: bool = this.master.WasAckReceived()
this.master.ClearResult()
return acked
}
/**
* Sends one data byte, asserts acceptance/completion, and returns the ACK flag before
* clearing status.
*/
fn RunWriteByte(value: byte) bool
{
var accepted: bool = this.master.BeginWriteByte(value)
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
var acked: bool = this.master.WasAckReceived()
this.master.ClearResult()
return acked
}
/**
* Receives one byte with the requested controller ACK/NACK, checks completion, and clears
* status before returning the byte.
*/
fn RunReadByte(sendAck: bool) byte
{
var accepted: bool = this.master.BeginReadByte(sendAck)
assert accepted == true
this.WaitForCommand()
assert this.master.HasResult() == true
var value: byte = this.master.GetReadByte()
this.master.ClearResult()
return value
}
/**
* Checks the master writes then reads register case.
*/
@Test
fn TestMasterWritesThenReadsRegister()
{
this.RunStart()
assert this.RunWriteAddress(0x42) == true
assert this.RunWriteByte(0x10) == true
assert this.RunWriteByte(0x5A) == true
assert this.RunWriteByte(0xC3) == true
this.RunStop()
assert this.registers.GetRegister(0x10) == 0x5A
assert this.registers.GetRegister(0x11) == 0xC3
this.RunStart()
assert this.RunWriteAddress(0x42) == true
assert this.RunWriteByte(0x10) == true
assert this.registers.GetPointer() == 0x10
this.RunStart()
assert this.RunReadAddress(0x42) == true
var first: byte = this.RunReadByte(true)
var second: byte = this.RunReadByte(false)
this.RunStop()
assert first == 0x5A
assert second == 0xC3
assert this.registers.GetPointer() == 0x11
}
}