6

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.

XW12A I²C signal per datasheet

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.

The controller is sending an ACK after the first 8 bytes

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.

I²C section of the XW12A datasheet translated


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.

Oscilloscope traces for each pad being pressed when bitbanging the header.

Jim
  • 161
  • 3
  • what are datasheet sections 4.6.3 and 4.6.4 about? – jsotola Jan 03 '22 at 17:41
  • I've added a translation of the I2C section of the datasheet to the question. – Jim Jan 03 '22 at 17:56
  • 2
    I think the documentation is just somewhat bad in that it doesn't show the an ACK where they almost certainly are. Not having one there would make this not I2C and not compatible with things that are I2C for no particularly good reason. Did you confirm that is this actually a problem? Or are you just noticing the lack of an ACK in the documentation? – timemage Jan 03 '22 at 18:24
  • This is definitely a problem - the capture shown in the question is from an actual device using this IC, I can see that the bit representing PAD8 is missing in the response data, and should appear at the same point that the controler sends the ACK. I haven't been able to confirm that the bit value is set correctly by the target when the controller does not send an ACK yet, but it seems more likely to me that the I2C protocol implementation is non-standard than the IC's read data just omitting this pin state altogether. – Jim Jan 03 '22 at 18:31
  • I've managed to bitbang the address read byte to the IC and I can confirm that it does behave as defined in the datasheet, i.e. sends the 9th bit on the same clock pulse that the controller sends an ACK. – Jim Jan 03 '22 at 19:43
  • 3
    Don't know what to tell you. Section 4.6.3, when machine translated to English, seems to describe standard I2C behaviour for ACK/NAK at each 9th bit. You even received the four padding '1' bits on the end that they described to make the actual data bits, to be padded to 16. Anyway, if you want to do something like I2C but not have the ACK/NAK where it is required by the I2C standard, then yes you'd need to bit-bang. But, I don't see putting that as answer because I don't think it has anything to do with the actual problem. So far as I can tell, your diagram is just a better diagram. – timemage Jan 03 '22 at 20:00
  • 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. So from our perspective this is just plain I2C. We also only can go with the datasheet. Are you really sure that the bit for pad8 the ack bit? – chrisl Jan 04 '22 at 01:56
  • 1
    Can you please explain in more detail why you think that the bit for Pad8 is missing? In the question I don't see much supporting your theory that the ack should not be used (besides the last image in the datasheet snippet. And I don't really trust that image) – chrisl Jan 04 '22 at 02:04
  • 1
    I've edited my question to add oscilloscope captures for each pad being pressed while bitbanging the header. If the IC was implementing I²C correctly, I'd expect to see a gap of one clock pulse between pad 7 and pad 8 as the IC waits for the ACK signal from the controller, but you can see that pulse for pad 8 follows directly on from pad 7. – Jim Jan 04 '22 at 11:47
  • 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:56
  • Interestingly, I've noticed that the ICman SC12A IC seems to describe the same behaviour in its datasheet. It's a similar IC, but has slightly different functionality and doesn't seem to be a clone. I was initially thinking that there might be a 16 bit variant of I²C that's more common in the Chinese market, but now I'm leaning towards it being a mistake in one implementation that's been copied from manufacturer to manufacturer. – Jim Jan 04 '22 at 12:42
  • The for(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
  • 1
    Ultimately, if this question is properly answerable by anyone, it's probably going to be by you. In which case, you could rewrite it as more of a "How do I use the Sam&Wing XW12A 12 channel touch sensor IC with Arduino", maybe make reference how a conventional I2C reading code fails, and then present what you've learned above cleaned up in an answer. Just so they're not reading the saga. If you go that route it may make more sense to delete this question and present the your own Q&A in one go under a new question. – timemage Jan 04 '22 at 20:44
  • As you already have a code for bitbanging it partly I would suggest using this and extend it to read the data bits. That shouldn't be that difficult at this point. It might be possible to get this working with your own changes in the Wire or a Software I2C library (the former is less probable), but probably it is not really worth the hassle. Though you might wanna go the extra mile and make a library specific for reading that sensor, which you could then publish on github for others. – chrisl Jan 05 '22 at 14:53
  • If you happen to be on an AVR with a USI peripheral, this may give some hardware assistance, since it doesn't do I2C outright, but has the building blocks for it and, I think, this non-standard protocol. But, most of the AVR used with Arduino don't and it may not be worth doing this either. However, it is the closest thing that comes to mind for supporting hardware. – timemage Jan 05 '22 at 20:56

0 Answers0