I'm trying to read from a Sam&Wing XW12A 12 channel touch sensor IC using I²C. The IC responds to an address read packet with 16 uninterrupted bits representing its state.
However, since I²C usually uses 8 bit bytes separated with an ACK signal, the 9th bit is lost when the controller sends an ACK bit for the first 8 bits.
My current code, using the Wire library, is below:
Wire.beginTransmission(devAddr);
Wire.requestFrom((uint8_t)devAddr, 2);
uint16_t buf;
Wire.readBytes((uint8_t *)&buf, 2);
This will return a 16 bit value, with bits 0-7 correct, then bits 9-15 shifted along with bit 8 missing.
Is there a way to prevent the controller from sending ACK bits and read the continuous 16 bits using the Wire library? And if not, is there any other better approach than just bitbanging the signal manually?
Edit: I've translated the I2C section of the datasheet below.
Edit 2: To prove that there's an issue, I've captured oscilloscope traces while bitbanging the address read header to the IC (but not sending ACKs). I've included a capture for each pad being pressed (and none pressed), you can see that pad 8 occurs on the first clock pulse after pad 7. If the IC was implementing I²C correctly, I would expect a gap of one clock pulse at this point while the IC waits for an ACK from the controller.




Your translation of the datasheet states "The information is transmitted in bytes (8 bits), and the receiver generates a response at the 9th bit." So that 9th bit IS just the Acknowlegment.I think that the datasheet is just referring to the header here, i.e. the controller sends the 8 bits representing the address and the R/W flag, and the target responds with an ACK at the 9th bit.
– Jim Jan 04 '22 at 11:56for(bitnum=0;bitnum<16;bitnum++)loop in your linked ICman SC12A datasheet supports your assertion also. They read 16bits of data without any handling for the ACK/NACK that standard I2C requires in the middle. This seems spectacularly stupid on the chip-makers part. I suppose if you wanted you could use the I2C peripheral to read other things on the bus and then disable the I2C peripheral and bitbang their wacky2C protocol on the same pins, allowing them to coexist on the same lines. At least, I think that could work. – timemage Jan 04 '22 at 20:35