bool axi_iic_bus::send(i2c_address_type i2c_addr, size_t size, const uint8_t* data)
{
register_value_type interrupt_status;
register_value_type control;
write_register(Register::TxFifo, (i2c_addr << 1) | 0);
interrupt_status = read_register(Register::InterruptStatus);
interrupt_status &= InterruptStatusBit::TransmitComplete |
InterruptStatusBit::TransmitError |
InterruptStatusBit::ArbitrationLost;
write_register(Register::InterruptStatus, interrupt_status);
control = ControlBit::TransmitModeSelect |
ControlBit::MasterModeSelect |
ControlBit::Enable;
write_register(Register::Control, control);
if (!wait_busy())
{
reset();
return false;
}
interrupt_status = read_register(Register::InterruptStatus);
interrupt_status &= InterruptStatusBit::BusNotBusy;
write_register(Register::InterruptStatus, interrupt_status);
while (size--)
{
do
{
interrupt_status = read_register(Register::InterruptStatus);
interrupt_status &= InterruptStatusBit::BusNotBusy |
InterruptStatusBit::TransmitComplete |
InterruptStatusBit::TransmitError |
InterruptStatusBit::ArbitrationLost;
} while (!interrupt_status);
if (interrupt_status & ~InterruptStatusBit::TransmitComplete)
{
reset();
return false;
}
if (!size)
{
control = read_register(Register::Control);
control &= ~ControlBit::MasterModeSelect;
write_register(Register::Control, control);
}
write_register(Register::TxFifo, *data++);
write_register(Register::InterruptStatus, interrupt_status);
}
do
{
interrupt_status = read_register(Register::InterruptStatus);
interrupt_status &= InterruptStatusBit::BusNotBusy |
InterruptStatusBit::TransmitError |
InterruptStatusBit::ArbitrationLost;
} while (!interrupt_status);
if (interrupt_status & ~InterruptStatusBit::BusNotBusy)
{
reset();
return false;
}
return true;
}