# i2c on different logic level devices

I'm having a problem making LPC2148 work with SRF10 sensor. LPC is 3.3v device with 5v compatible i2c (at least user docu claims that). On the other side there is SRF10 device which is 5v. I have tried with both levels as pull-up lvl connected with 4.7k resistor (i have 3 devices on same line so i used higher value resistor).

Strange thing is that it sometimes read the value correctly but it fails to read values from 2 registers... Basically, it doesnt work.

Now, what is strange on this picture, is that logic lvl on SDA is 0 by default and it should be 1. That means that pull-up is not doing the job well ? Could that be related to logic lvl differences between uc and slave ?

EDIT:01.03

Here is my implementation of state 0x50, a_chn is i2c0 or i2c1

void slaveDataReceived (uint8_t a_chn)
{
uint8_t k;
volatile unsigned char *i2cConClear;
volatile unsigned char *i2cConSet;
volatile unsigned char *i2cData;

if (a_chn == 1) {
i2cData = (volatile unsigned char *)(0xE005C008);
i2cConClear = (volatile unsigned char *)(0xE005C018);
i2cConSet = (volatile unsigned char *)(0xE005C000);
}
else {
i2cData = (volatile unsigned char *)(0xE001C008);
i2cConClear = (volatile unsigned char *)(0xE001C018);
i2cConSet = (volatile unsigned char *)(0xE001C000);
}

k = *i2cData;
appendToDataBuffer (a_chn, k);
I2CMasterState[a_chn] = I2C_IDLE;
*i2cConSet = I2CON_SET_STO;
*i2cConClear = I2CON_CLR_AAC;
}
else {
*i2cConSet = I2CON_SET_AA;
}
*i2cConClear = I2CON_CLR_SIC;
}

• If it's reading/writing from every device except just 2 registers from one device, then that should tell you the i2c bus is working correctly, and it's possibly either your code, or the srf10 that's buggy. As for the SDA being low, it shouldn't matter until a start condition is attempted in your single master setup. Is one of the other i2c devices not 5v tolerant? Does the line go high if you place only the LPC and the SRF10 on the bus and nothing else? Can you read from all registers with only the LPC and SRF on the bus? – Passerby Feb 28 '13 at 8:32
• All three devices are 5v and only lpc is 3.3v (but 5v tolerant). I tried disconnecting all devices except one and i get the same behavior. SRF is working as i tried it on AVR (5v). SRF has 4 registers. First is revision, which i could read and got 5 as value (which should be ok). Second is unused but it returns 0x80 when reading. (also correctly read). And registers 3-4 are 16bit value. Reading those registers returns strange values. (I have "calibration" environment in which i have tested read values and concluded that they are garbage.) – Gossamer Feb 28 '13 at 8:57
• From your scope output, are you giving it a big enough delay? The ranger will not respond while ranging. Check your code to see if you can find why the SDA output is held low before i2c transmission is enabled, that might be what is throwing things off (But imho, I don't think that's too big of an issue). Aside from that, someone else might chime in. – Passerby Feb 28 '13 at 9:40
• I know that between ranging and readout needs at least 65ms, i have put 100ms. This low level before and after the reading is somewhat strange. When i use SDA/SCL pins as GPIO and create square signal, everything acts normal. Regardless of pull-up which is connected to lines. Output is from LA not scope. I checked it also with scope and i get low lvl as -0.3v and high lvl as ~3v. – Gossamer Feb 28 '13 at 10:08
• These issues are likely beyond the capabilities of a logic analyzer. I highly recommend you use an oscilloscope to check communications because there can be very marginal logic levels that usually work and then fail. – Gustavo Litovsky Feb 28 '13 at 16:04

• Well it seems i had too many ACK's in the code. I was lead by the documentation for LPC21xx in which they stated that almost every state should set ACK bit in register. Also i have removed *i2cConSet = I2CON_SET_STO; from code in question post. All of those or some of those recent changes in the code made i2c working now. Now i have to analyze what exactly caused the problems by re-enabling the old code line by line. – Gossamer Mar 4 '13 at 10:29