I've got a device with an LPC5528 as the I2C bus master. I want to be able to check a specific I2C address and see what is attached to it (Retrieve the I2C Device ID). I'm using the HAL I2C libraries and the FreeRTOS I2C layer. I've spent significant time looking at how to do this, but without luck. Is there an example somewhere of how to do this? I'd think it is somewhere since NXP wrote the I2C spec. Thanks in advance.
I2C Spy is pretty spiffy. Is there a way to see the source code without installing it? I don't see it available for the LPC55xx. I don't want to monitor the bus, I want to tell if a device it at a specific address.
According to the I2C spec, Section 3.1.17, Device ID:
The Device ID field (see Figure 20) is an optional 3-byte read-only (24 bits) word giving the following information:
• Twelve bits with the manufacturer name, unique per manufacturer (for example, NXP)
• Nine bits with the part identification, assigned by manufacturer (for example, PCA9698)
• Three bits with the die revision, assigned by manufacturer (for example, RevX)The Device ID is read-only, hard-wired in the device and can be accessed as follows:
1. START condition
2. The controller sends the Reserved Device ID I2C-bus address followed by the R/W bit set to ‘0’ (write): ‘1111 1000’.
3. The controller sends the I2C-bus target address of the target device it must identify. The LSB is a ‘Don’t care’ value. Only one device must acknowledge this byte (the one that has the I2C-bus target address).
4. The controller sends a Re-START condition.
Remark: A STOP condition followed by a START condition resets the target state machine and the Device ID Read cannot be performed. Also, a STOP condition or a Re-START condition followed by an access to another target device resets the target state machine and the Device ID Read cannot be performed.
5. The controller sends the Reserved Device ID I2C-bus address followed by the R/W bit set to ‘1’ (read): ‘1111 1001’.
6. The Device ID Read can be done, starting with the 12 manufacturer bits (first byte + four MSBs of the second byte), followed by the nine part identification bits (four LSBs of the second byte + five MSBs of the third byte), and then the three die revision bits (three LSBs of the third byte).
7. The controller ends the reading sequence by NACKing the last byte, thus resetting the target device state machine and allowing the controller to send the STOP condition. Remark: The reading of the Device ID can be stopped anytime by sending a NACK.
If the controller continues to ACK the bytes after the third byte, the target rolls back to the first byte and keeps sending the Device ID sequence until a NACK has been detected.
I don't see the built-in drivers supporting this type of transaction, which is a write, re-start, then read. Do you know of an example of this?
Hi @chad_k ,
The source of the I2CSpy is here: https://github.com/ErichStyger/McuOnEclipseLibrary/blob/master/lib/src/McuI2CSpy.c
Erich
I looked through that and it doesn't use the same I2C libraries as the LPC5528 and I don't see anything in there where a restart is done as part of the I2C transaction. Did I miss it?
It uses the MCUXpresso SDK, but through an abstraction layer in https://github.com/ErichStyger/McuOnEclipseLibrary/blob/master/lib/src/McuGenericI2C.c
But that I2CSpy is not reading that Slave ID you have described from the I2C specs (that one is new to me). Sounds like a cool feature. So I might end up implementing it in that I2CSpy module?
Hi @chad_k ,
I have spent some time today on this topic. So I give it try with a SWI2C implementation on top of the NXP SDK, probing some devices, below the NXP PCF850563A RTC:
As you can see: no device ID returned for that NXP device. That device ID would be an interesting feature for all I2C devices, but it seem that it is optional and only few devices have it implemented.
I have several NXP I2C devices in my designs, and none of them implements it. I have only found the datasheet for a PCA9698 which has it documented:
Without a device to test with, I'm even not sure if my signal sequence is correct. But I'll publish my current code within the GenericSWI2C module, just in case.
Erich
Thanks for looking into this. I'll take a look at the code you mentioned.
You are welcome. In parallel I see if I can organize a device which has that device ID implemented. It seems that very few devices might have it?
Is the device (I2C) address not the ID of the device on the bus? If that device has its own ID or serial number, then you need to know how to get that from the device from the data sheet, e.g. reading from that device. How it is done (memory mapped or otherwise) is specified by the device itself and the protocol it has implemented.
So you can probe all I2C addresses on the bus as the I2CSpy does (see https://mcuoneclipse.com/2012/12/23/csi-crime-scene-investigation-with-i2cspy-and-freedom-board/ ). Then you could guess from a database what device might be behind a certain address, as many devices have a fixed address on the bus. Then query that device based o that?