The 2024 Embedded Online Conference

Why logic High input is logic low on I2C data bus?

Started by learn 4 years ago2 replieslatest reply 4 years ago699 views

NXP LPC11E68JBD48E Microcontroller I2C1 is Master.   I2C1 is in Master Transmitter Mode.
I2C1 peripheral is in chapter 13.  http://www.mouser.com/ds/2/302/UM10732-315822.pdf
NXP PCAL6416A I2C 16-bit I/O Expander is Slave. https://www.nxp.com/docs/en/data-sheet/PCAL6416A.pdf.

Master reads one byte from slave port 0.  On one board all Eight bits are logic 1's as expected.  On the other board Seven bits are logic 1's as expected
but bit 2 is logic 0.  The input pin connected to bit 2 is pulled up to 3.3V but it's logic 0 on I2C data bus.  Why?

                              D7 D6 D5 D4 D3 D2 D1 D0
Expected               1    1    1    1    1    1   1    1
One board             1    1    1    1    1    1   1    1
Another board       1    1    1    1    1    0   1    1

Explanation/Questions on attached scope screenshots:  Master sends slave address 0100 001(A6-A0), followed by write bit(logic 0).  Slave responds with ACK(logic 0).
Then, master send command byte 0x00(read byte from Input port 0).
Master sends start bit, followed by slave address, followed by read bit(logic 1).  Slave sends ACK.
On one board, slave send 0xFF as expected.  On other board, slave sends 0xFB, not expected. Master follow with a NAK.  Slave pulls data bus low before the stop
condition?  Why slave pulls data bus low?

The primary question is why is bit 2 logic 0 on the I2C bus when it's pulled up to 3.3V ?

Are we setting the I2C device properly?
INT pin(active low) is floating.

/* Enable selection of Pull Up / Pull Down on unused inputs */
    b = mIOExtender.PuPdEnablePort0(0x02);
    b = mIOExtender.PuPdEnablePort1(0x70);

/* Pull up unused inputs */
    b = mIOExtender.PuPdSelectPort0(0xFF);
    b = mIOExtender.PuPdSelectPort1(0xFF);



[ - ]
Reply by CustomSargeSeptember 24, 2019

I'll answer the title question. Since it's a bus (multiple devices sharing signal lines) it's Much easier to function as a "wired OR" configuration. Wired OR has line idle high, active low. It's why there are pull up resistors on the bus lines. Bear in mind, I2C can be confusing as Hell until you start to understand it's simplicity and elegance.

I wrote my bit-banging assembler version before uCs had built-in handlers. Took a While to make it work, but by then I understood the protocol pretty well. Now it's my preference for I/O expansion and sensors.

Debugging I/O as your situ, I attach 2 hex thumbwheels (or equ) as input or 2 decoder / displays for output. Looking for all 1 state can easily hide the problem. Be able to change patterns until it all behaves.

[ - ]
Reply by mr_banditSeptember 24, 2019

look at the data pin itself. - are you really sure about

The primary question is why is bit 2 logic 0 on the I2C bus when it's pulled up to 3.3V ?

the chip is probably working correctly. the pin is probably a bad solder joint or otherwise not being pulled high as expected.

The 2024 Embedded Online Conference