I'm using the AVR128DA in a project where I want to use the TWI normally for some addresses but simply listen/sniff to an attached device's communication with it's IO expanders. It seems like this should be pretty easy, but I've been struggling for weeks now to figure out exactly how to set the TWI Registers based on the incoming data.
For the sniffer, I only care about 3 addresses and I only care about writes to their output ports (Command = 0x02). I can toss reads (which are button presses) which should make things a bit easier. The IO expanders use a specific sequence for writes and reads, where 'Command' is the port we want to target. For the reads, the Command will always be 0x00.
Write: Start >> ADDR+W >> Command >> DATA0 >> DATA1 >> Stop
Read: Start >> ADDR+W >> Command (0x00) >> Rep. Start >> ADDR+R >> DATA0 >> DATA1 >> Stop
I'm using the TWIC with interrupts and can successfully get the address, commands and data. But as far as I can tell, the TWI needs a very specific response when sniffing to avoid triggering errors or bad data. For instance, for ADDR+W and DATA+W, it appears that clearing the CLKHOLD bit in SSTATUS works as it also clears the APIF or DIF and keeps listening without having to ACK/NACK.
Reads are tricky because we don't have any data to send. When we see ADDR+R, I've tried clearing the CLKHOLD bit, but since we don't care about reads, I've also tried setting NOACT and COMPTRANS in the SCMD bit field with both ACK and NACK responses to no longer trigger the interrupts until a new start. For the DATA+R, I've tried all of the above as well, but it appears that the TWI wants to shift out whatever is in the SDATA register (which is the address+read bit) regardless.
Stop is another tricky one. I wouldn't think you'd have to do anything here but clear the CLKHOLD (I use it to set a flag to the main application that we have all the data and can process). However, when a button is pressed on the device we are sniffing, we read the port then read it again 2ms later to verify the press. This will trigger a collision on the 2nd read's ADDR+W, which according to the datasheet means the client address match already took place.
Does anyone know what commands TWI needs to just sniff? The best I've managed to do was get the correct data, but randomly the TWI would interfere with a read causing a button press to be missed on the 'sniffed' device (this does not occur with the sniffer turned off).
Thank you and I hope you all are doing well!!