private void Write(int deviceAddress, byte[] buffer)
{
this.EnsureDeviceAddress(deviceAddress);
var len = (uint)buffer.Length;
var dlen = this.bscAddress + (int)Interop.BCM2835_BSC_DLEN;
var fifo = this.bscAddress + (int)Interop.BCM2835_BSC_FIFO;
var status = this.bscAddress + (int)Interop.BCM2835_BSC_S;
var control = this.bscAddress + (int)Interop.BCM2835_BSC_C;
var remaining = len;
var i = 0;
// Clear FIFO
WriteUInt32Mask(control, Interop.BCM2835_BSC_C_CLEAR_1, Interop.BCM2835_BSC_C_CLEAR_1);
// Clear Status
WriteUInt32(status, Interop.BCM2835_BSC_S_CLKT | Interop.BCM2835_BSC_S_ERR | Interop.BCM2835_BSC_S_DONE);
// Set Data Length
WriteUInt32(dlen, len);
while (remaining != 0 && i < Interop.BCM2835_BSC_FIFO_SIZE)
{
WriteUInt32(fifo, buffer[i]);
i++;
remaining--;
}
// Enable device and start transfer
WriteUInt32(control, Interop.BCM2835_BSC_C_I2CEN | Interop.BCM2835_BSC_C_ST);
while ((ReadUInt32(status) & Interop.BCM2835_BSC_S_DONE) == 0)
{
while (remaining != 0 && (ReadUInt32(status) & Interop.BCM2835_BSC_S_TXD) != 0)
{
// Write to FIFO, no barrier
WriteUInt32(fifo, buffer[i]);
i++;
remaining--;
}
this.Wait(remaining);
}
if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_ERR) != 0) // Received a NACK
throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_NACK status");
if ((SafeReadUInt32(status) & Interop.BCM2835_BSC_S_CLKT) != 0) // Received Clock Stretch Timeout
throw new InvalidOperationException("Read operation failed with BCM2835_I2C_REASON_ERROR_CLKT status");
if (remaining != 0) // Not all data is sent
throw new InvalidOperationException(string.Format("Read operation failed with BCM2835_I2C_REASON_ERROR_DATA status, missing {0} bytes", remaining));
}