I am programming a microcontroller to talk with a slave device via I2C. My I2C transactions always get NACK'd, but I believe the slave is ACK'ing the transaction, just a little bit too late and my microcontroller thinks it's a NACK. Please correct me if I'm wrong.
Here is a trace of the transaction.
The slave drives SDA low at the end to ACK the transaction. But my I2C library always reports it a NACK. Further more, the slave keeps SDA low since their isn't a 9th clock pulse, and my I2C peripheral gets stuck trying to finish the stop condition.
My I2C library is a reliable one from manufacturer that I've used many times successfully with different devices. I'm thinking the slave is just a bit too slow with the ACK.
The current trace is at 100 KHz but I've tried at 10KHz and it does the same thing. Any suggestions to solve this?
You are only showing 8 clock pulses for data, and is not showing the 9th ACK clock pulse.
The SDA should not be falling at the same time as SCL rises. It should have settled low within a couple of us of SCL falling, and before SCL rises. The master should be outputting the 9th clock falling edge and sampling just before/at the falling edge.
If this is a HW master, maybe it isn't set for I2C i.e. it's doing 8 clocks not 9.
If it is a bit bash master, then you should be sampling SDA just before you make SCL fall (which your aren't doing), and definitely a couple of us after the rising edge.
I suspect your slave is not acking (SDA stays high) and your library is aborting and forcing SDA low perhaps.
Have a look at this app note I wrote, that shows you how to see which chip (master or slave) is pulling the pin down. It talks about SCL, but will work the same for SDA
BTW, from experience, manufacturers libraries are seldom fully functional or adequately debugged.
The slave drives SDA low at the end to ACK the transaction.
I don't see this. The SDA line should not go up at all. The slave reads incoming data on the rising edge of the clock. So, when 8th clock goes up slave already knows if this was the right address, so it pulls SDA down almost immediately. When clock goes up for 9th time SDA should stay low.
Make sure the address is right.
Further more, the slave keeps SDA low since their isn't a 9th clock pulse, and my I2C peripheral gets stuck trying to finish the stop condition.
How do you know it is the slave that keeps line low? It is quite possible your reliable library does not handle NACK properly.