Keysight i2c decode - missing ack - Page 1
Forum section: electronics / projects

author: TomS_
author_rank: Frequent Contributor
timestamp: August 10, 2017, 08:44:28 am
content: Hi everyone,I feel a bit like this is a newbie question, but Im trying to work out if its me that is missing something or what else.Ive written some C code for a PIC microcontroller (PIC18F25K22) to read bytes from a Microchip I2C EEPROM (24LC512). Its working and I can seemingly read the contents of the EEPROM just fine (they are all default values of 0xFF so far as I havent written the code to write anything to the EEPROM yet).During development Ive been using my Keysight scope to do serial decoding and see whats going on to help with debugging (and its been amazingly helpful). Throughout the entire process I seem to be stuck with a missing ack error being reported on the scope.Ive attached a screenshot. The red arrow points to the 9th bit of the last byte (transmitted by the EEPROM) which is where my PIC is generating an ACK for the byte that has been received from the EEPROM. I believe this is all correct from what I have read about the I2C protocol...Ive also attached my code for review if someone is interested to take a look and see if I am doing anything wrong in there?It all seems to work, so I dont suppose there can be too much that is wrong, but the missing ack is bugging me. Does anyone see anything that Im doing wrong, or am I misunderstanding what the missing ack column on the scope means (basically, it would seem to indicate that an ACK is missing when there should have been one)?ThanksTom

author: kilobyte
author_rank: Regular Contributor
timestamp: August 10, 2017, 05:57:56 pm
content: Hi Tom,the Missing Ack error shown by the protocol decoder is correct.According to the I2C specification on ACK/NAK (5. A master-receiver must signal the end of the transfer to the slave transmitter.) and the Datasheet of the 24LC512 the Master have to send a NAK on the last byte he reads before the STOP condition.Best RegardsKai

author: TomS_
author_rank: Frequent Contributor
timestamp: August 10, 2017, 08:21:03 pm
content: Hi Kai,Thanks for your response.I think either the datasheet for the EEPROM is incorrect, or I am doing something really stupid, but I do not see what it says I should be seeing.e.g.On page 14 (http://ww1.microchip.com/downloads/en/DeviceDoc/21754M.pdf) it suggests that for each byte that I send to the EEPROM, it should ACK back - which is SDA low while SCL is high?On my scope I see the opposite - I see SDA high while SCL is high which means NAK? This is the case for all 3 of the bytes that I send to the EEPROM (control work and high and low address bytes).Ive also modified my code to send an initial control word with the read/write bit set low initially for write, followed by the high/low address bytes, then a restart, followed by the control word again but with the read/write bit high for read (that seems to be the suggested sequence per the datasheet, although it was working before anyway....). Each byte I want to receive is then communicated by me sending an ACK and that seems to be working just great.So hmm, not sure. I think maybe the EEPROM doesnt operate correctly perhaps? It seems to be sending NAKs when it should be sending ACKs (you see in between the cursors, SDA is high but the datasheet says it should be low)? But my PIC does seem to detect the acknowledge condition seemingly correctly otherwise I think some of my loops would wait forever. Im totally confused.Perhaps I will order some other EEPROMs and see whether the behaviour is the same or different.Tom

author: TomS_
author_rank: Frequent Contributor
timestamp: August 10, 2017, 09:35:38 pm
content: I've got some ON Semi CAT24C256LI-G's on order and should have them on Monday.Datasheet suggests they work the same way and have the same pin out (I guess they all will for compatibility) so should be a drop in replacement and see how it goes.

author: joshtyler
author_rank: Contributor
timestamp: August 10, 2017, 10:53:27 pm
content: Don't be misled by the fact that you are able to read 0xFF for every address. Given that the slave it not ACKing, your MCU will always read 0xFF because nobody is pulling the line.What are the three address pins (pins A2, A1, A0) held at on the EEPROM? Setting those differently to the address you are sending is an easy mistake to make.

author: joshtyler
author_rank: Contributor
timestamp: August 10, 2017, 11:10:16 pm
content: Quote from: TomS_ on August 10, 2017, 08:21:03 pmYes this is correct. Bear in mind that I2C is an open drain system, so a NAK is really sending nothing, but an ACK is actively pulling the line low. Read transactions happen as follows:Master sends slave address. Slave ACKsSlave sends data byte. Master ACKs if it if wants to receive another byte, or it NAKs (does nothing) if this is the end of the transaction.Writes happen as follows:Master sends slave address. Slave ACKsMaster sends data byte. Slave ACKs each byte.QuoteYes this means that the slave isn't responding (slave should always ACK the control byte, for both transaction types). Most likely cause is wrong address, but there could also be hardware problems.QuoteThat sequence is good! But if the slave isn't ACKing the control byte, it isn't listening (it assumes you are talking to some other I2C device), and nothing is happening!

author: rstofer
author_rank: Super Contributor
timestamp: August 10, 2017, 11:30:35 pm
content: More often than not, it's the I2C address that is the problem. A device says its address is 0x32. Fine! But we have to shift it left by one position and then mask in the R/W bit so one could say that the address is really 0x64. Worse yet, datasheets add to the confusion by sometimes shifting the value to 'help' the user. The datasheet does this when they diagram the bit pattern.Doing a manual decode from your scope image, I get the same answer as Keysight: the address bits, after shifting right, are 0x56.0x56 would be ok if A1 and A2 are '1' and A0 is '0'. EDIT: Removed muddy thinking here...Take a look at your address calculation and bounce it off of page 9 here:http://ww1.microchip.com/downloads/en/DeviceDoc/21754M.pdfI would start with 0x50, OR in the A2..A0 bits and then shift left before masking in the R/W bit.

author: TomS_
author_rank: Frequent Contributor
timestamp: August 11, 2017, 09:44:13 am
content: Quote from: joshtyler on August 10, 2017, 11:10:16 pmQuote from: rstofer on August 10, 2017, 11:30:35 pmI think you have both hit the nail on the head, with my thumb in the way. Its all making a LOT more sense now.Im looking at a photo that I took of my breadboard the other day and referencing it to the datasheet, and it looks like I have A0 and A1 pulled high via a 100K resistor, while A2 is pulled low. That makes the slave address 0x3 instead of 0x6 that I have been trying to use. Ive got my address bits reversed.And that also means my code isnt working the right way either, because its continuing on when it shouldnt be. Something to look at this weekend!Thanks for your help! Sometimes you just need a few extra eyes to look at a problem before the fog of confusion lifts.And I guess I'll just have a few more I2C EEPROMs in stock now.edit: and I think I will have to build more error handling in to my code to detect ACK timeouts etc.

author: TomS_
author_rank: Frequent Contributor
timestamp: August 11, 2017, 10:39:02 pm
content: Well, I couldnt wait for the weekend, so I spent a couple of hours on it tonight and I would say its working great now (scope_50).The missing ack at the end is of course expected, since NAK is used to signal to the EEPROM that it should stop sending bytes.Compare to scope_51 which is when I try to request something from a slave address which doesnt exist - it bails afer a NAK on the control word.I will tidy up my code a bit more over the weekend and post it up for anyone who wants to use it in their own projects.

author: bson
author_rank: Unknown
timestamp: August 13, 2017, 05:11:57 am
content: Address 58? On the 24LC256, the base address is 0x50, plus the address pins on bits 0-2.Looking at the Microchip 24LC512 datasheet, the 24xx512 is the same:QuoteSo I think you're reading 0xff from the open drain with a non-responding EEPROM...Oh, nvm, I see you figured it out already.

author: TomS_
author_rank: Frequent Contributor
timestamp: August 14, 2017, 07:58:51 am
content: Quote from: bson on August 13, 2017, 05:11:57 amYeah, that was me fiddling with knobs (physically and metaphorically - there are so many!). I had it in 8 bit address mode when I took those screenshots.First time with I2C, so I guess Ive got a bit to learn about how it works and operational encounters to have etc. Probably I assumed there would be more "error handling" in the hardware, probably Ive just been writing too much Python lately and expected too much.

author: TomS_
author_rank: Frequent Contributor
timestamp: September 16, 2017, 05:52:30 pm
content: Bit of a delay, but I finally got around to uploading my finished code for anyone else that may want to use it:https://github.com/tomstorey/Microchip-PICIn the mean time I also acquired some PIC24 devices, so I decided to add in support for those, so now my routines are good for use on PIC18 and PIC24.