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.

I2c Trace

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?

More details:

  • slave: AMS AS3955

  • master: Silicon labs EFM32 Pearl


I bit banged the I2C operation in question and added the 9th clock cycle. The same problem occurs. After the operation, I disconnect SDA and measure it on the microcontroller side and slave side. Micro-SDA is high (correct) but slave-SDA is pulled low still. So it seems this may be more of an issue with the slave device than an I2C issue, right?

enter image description here

Update 2

See my posted answer.

  • 2
    \$\begingroup\$ It looks like your host is misbehaving. Even if a slave is slow, your host should register some condition, ACK or NACK, it shouldn't have any effect on the end of packet. The slave can't remove the ACK because there must be another "LOW" phase of the clock, which is not coming from your host. \$\endgroup\$ Commented Aug 2, 2018 at 4:15
  • 2
    \$\begingroup\$ What is the slave? \$\endgroup\$
    – The Photon
    Commented Aug 2, 2018 at 4:31
  • \$\begingroup\$ Is this a slave you've used before? It should generate the ACK on the ninth falling edge of the clock, but it appears to be waiting until the subsequent rising edge. Since it happens at any speed, it isn't a simple timing issue. \$\endgroup\$
    – Dave Tweed
    Commented Aug 2, 2018 at 13:09
  • 1
    \$\begingroup\$ BTW, there are nine clock pulses -- since the idle state of the clock is high, you need to count the number of times it goes low, and there are nine of them. 9 falling edges that trigger either device to change the state of the data line, and 9 rising edges where they both sample it. \$\endgroup\$
    – Dave Tweed
    Commented Aug 2, 2018 at 13:17
  • \$\begingroup\$ This is a new slave for me. It is AMS AS3955 NFC chip. \$\endgroup\$ Commented Aug 2, 2018 at 14:02

3 Answers 3


Turns out my I2C slave doesn't support I2C.

The AMS AS3955 is configured as a SPI or I2C device at factory time. My device is a SPI one and I didn't notice.

Thanks for the discussions!

  • 5
    \$\begingroup\$ ROFL You sure got us jumping through the hoops \$\endgroup\$
    – Maple
    Commented Aug 3, 2018 at 9:13

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 after SCL goes down.

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.

  • \$\begingroup\$ btw, slaves don't read data on the rising edge (as it can change any time SCL is low, and may not have settled when SCL rises). They read it on the falling edge. \$\endgroup\$
    – Henry Crun
    Commented Aug 2, 2018 at 4:58
  • 2
    \$\begingroup\$ @HenryCrun What a load of baloney! Slaves cannot possibly know when falling edge comes in. Technically they read SDA during high state of SCL, but the reading is triggered by rising edge, and that is exactly what is called "reading on rising edge". Learn the basics before giving advice. \$\endgroup\$
    – Maple
    Commented Aug 2, 2018 at 7:59
  • 2
    \$\begingroup\$ "Slaves cannot possibly know when falling edge comes in." I thought watching SCL would let them see the falling edge? \$\endgroup\$
    – Henry Crun
    Commented Aug 2, 2018 at 8:39
  • 1
    \$\begingroup\$ Sampling SDA on falling edge does not make any sense, especially at higher clock rates. It creates all kinds of problems, see this for example. On the other hand sampling on rising edge is perfectly safe, because SDA must be already set long before that. \$\endgroup\$
    – Maple
    Commented Aug 2, 2018 at 9:33
  • 1
    \$\begingroup\$ @ConorPatrick Stop condition is low-to-high SCL transition while SDA is low. And if SDA is low already nothing prevents master from bringing clock down and up again. From your screenshot master not even tries to do this. It looks more like the library does not know what to do with NACK. You are sending address 0x50. Are you sure the lower 3 bits haven't been overridden in EEPROM? \$\endgroup\$
    – Maple
    Commented Aug 2, 2018 at 16:33

You are only showing 8 clock pulses for data, and is not showing the 9th ACK clock pulse falling edge.

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 SDA just before/at the falling edge.

I suspect your slave is not acking (address is wrong) as SDA stays high, and your library is aborting and forcing SDA low perhaps.

If this is a HW master, maybe it isn't set for I2C i.e. it's doing 8 clocks not 9. (as it is in SPI mode)

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.

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


simulate this circuit – Schematic created using CircuitLab

BTW, from experience, manufacturers libraries are seldom fully functional or adequately debugged.

  • \$\begingroup\$ I think this circuit might make the logic low voltage levels too high for reliable operation. The maximum \$V_{OL}\$ for a standard device is 0.4V so you're really talking about a logic low voltage of about 1.1V. I would suggest using Schottky diodes instead. \$\endgroup\$ Commented Aug 2, 2018 at 11:37
  • \$\begingroup\$ Nah, VIL is what counts (0.3VDD = 1.5V) . It works fine. Read the appnote. There is a special case where you need schottkys: bus extenders and isolators. These have to use a threshold to determine driving direction. But if you have schottkys, they work fine or better also. \$\endgroup\$
    – Henry Crun
    Commented Aug 2, 2018 at 11:47
  • \$\begingroup\$ You are assuming that \$V_{DD}\$ is 5V...that's a pretty old-fashioned microcontroller. If by "appnote" you mean NXP UM10204 then I have read it. And you may be meeting the \$V_{IL}\$ but you have sacrificed a lot of the noise margin. At least we agree that Schottky diodes would work better. \$\endgroup\$ Commented Aug 2, 2018 at 12:13
  • \$\begingroup\$ Elliot, this is a simple test jig for someone to work out which chip is driving. Its not going to mars. Its not been nominated for a nobel prize, and its not running in liquid nitrogen or helping Comrade Kim land on the Sun at night. In the scope traces (you looked right?) the voltage is 0.7V with real chips. It works OK on earth, when I don't have to wear socks. Maybe not on mars. \$\endgroup\$
    – Henry Crun
    Commented Aug 2, 2018 at 12:20
  • \$\begingroup\$ My concern is that someone who doesn't know better will try to use this circuit to debug a system running at, say, 3.0V (on Earth, at room temperature, with socks on) and will end up running around in circles when nothing works at all. Yes, you were able to make it work at 5V with a certain set of devices, I see that. I just echoed information that was in your own appnote, in case the reader didn't click through. \$\endgroup\$ Commented Aug 2, 2018 at 13:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.