I was having issues talking to an I2C device, and I noticed that the sense of the ack_write flag appears to be backwards in the stock I2C interface module.
From the i2c_controller.luc:
// Write interface
input data_in[8], // data to write
input write, // start write signal (1 = start write)
output ack_write, // was the last write acknowledged (1 = ack, 0 = no_ack)
This seems reasonable, however lower down we see:
// Write a byte
States.WRITE:
// if we aren't on the acknowledge bit
if (bit_ctr.q != 8)
sda_value = data.q[7] // write the MSB of data
// otherwise, if the clock counter is 0
else if (scl_reg.q == 0)
ack_write_reg.d = sda // read the acknowledge bit
To acknowledge a message, an I2C peripheral would pull the sda pin low, and so a value of 0 would be written to ack_write. It seems like this should be:
ack_write_reg.d = ~sda // read the acknowledge bit
And we can see that the correct negation is performed for the ack_read bit:
// Read in a byte
States.READ:
// if we at the end of the 8th bit or later
if (bit_ctr.q == 9 || (bit_ctr.q > 7 && scl_reg.q >= c{2b11, ($width(scl_reg.q)-2)x{1b0}})) {
sda_value = ~ack_read_reg.q // write the acknowledge bit
Am I missing something?