I2C Bus and ADL_BUS_LINE_ERROR

I am attempting to use the I2C (I squared C) bus to communicate with a slave device.

I am using the new IDE along with “Open AT OS Package (4.25.0.01), Library API: ADL” for “Open AT Firmware Package (6.6.3.g.00)”.

I am using the IO+USB+GPS IESM Plugin and the 16 pin IO plug to connect the modem to the slave device. From the various manuals I have determined the following:

  • Pin 9 (Purple wire) of the socket is connected to GPIO 26 which is multiplexed with the clock line of the I2C bus.
  • Pin 7 (White wire) of the socket is connected to GPIO 27 which is multiplexed with the signalling line of the I2C bus.
  • Pin 16 (Black wire) of the socket is connected to modem ground (reference ground for the I2C bus)

The slave device is powered by an independant 5v power supply however the grounding can’t be managed well and as such the modem ground line is connected directly to the power supply ground to provide a common ground.

The slave device is operating on I2C slave address 0x30 and is expecting an intial read on boot.

I will not post the entire code here as most of it is unrelated but the relevant calls that I am using are as follows:
(note, the code below is a summary of the calls from a number of functions with constants replaced with their values to simplify the code down to its basics, please don’t comment on my use of magic numbers etc :stuck_out_tongue: )

//variables
	adl_busSettings_u settings;
	s32 success;
	adl_busAccess_t accessMode =
	{
			0x00000000,		//address
			0,		//Opcode
			0,		//Opcode Length
			0,		//Address length
			ADL_BUS_SIZE_BYTE,	//size
	};
	u8 readData[8];

	//initialise settings
	settings.I2C.ChipAddress = 0x30;
	settings.I2C.Clk_Speed = ADL_BUS_I2C_CLK_STD;

	//subscribe bus
	iButton_busHdl = adl_busSubscribe(ADL_BUS_I2C, &settings);

	//check bus subscribe result
	if (iButton_busHdl < 0)
	{
		TRACE((1, "Subscribe failed"));
		return FALSE;
	}
	TRACE((1, "Subscribe succeeded."));

	//read status register
	success = adl_busRead(iButton_busHdl, &accessMode, 1, readData);

	//check read success
	if (success == OK)
	{
		TRACE((1, "Read Good, read %d", readData[0]));
	}
	else
	{
		TRACE((1, "Read failed: %d", success));
	}

The output from the above code is as follows (trace level, trace):

24, Bus subs (4): 0
1, Subscribe succeeded.
24, Bus Read (0,1): -21
1, Read failed: -21

I have looked up error value -21 and it is ADL_BUS_LINE_ERROR.

Unfortunately the only documentation I can find on it is from the ADL guide: “ADL_BUS_LINE_ERROR if I2C lines are not in a good state (I2C bus only).”

I didn’t find this particularly helpful.

If anyone can tell me what step I am missing or what I have done wrong it would be greatly appreciated since I’m completely stuck on this. Nothing I have tried has changed the outcome at all.

have you provided the necessary pullup on the I2C line?

I was under the assumption that this was supplied within the modem hardware. The I2C protocol specifies that the master device must supply the clock, the start and stop signals as well as the line pull up. Since the modem is acting as master I had assumed that this was supplied.

Does this match the line error response? Is that what it means?

it can mean a lot of things (as wavecom errors usually do), but that is one of the meanings.

But to my understanding the master does not need to provide the pullup. Those are always seperate resisors because they need to be matched to the circuit.

In this case, I think it’s fair enough: the modem cannot distinguish a missing pullup from, say, a short to ground; all it can see is that the lines are in an “inappropriate” state - which is what, I think, ADL_BUS_LINE_ERROR means… :question:

Thanks heaps, I have added the two pull up resistors (2.2kohm for standard speed) and I have got the CRO working today, I can see the modem write the address so it is working to an extent.

I am now getting a return code of -2 which is ADL_RET_ERR_PARAM. Keeping in mind the manual says “ADL_RET_ERR_BAD_STATE if there is no acknowledgement from the remote chip on the bus (I2C bus only).” so that isn’t the problem.

Can anyone see which param is out and in what way? I will be looking myself and I’ll post as soon as I spot the problem, but if someone can shortcut my investigation it would be much appreciated.

Fixed! It turned out it wasn’t responding, there was no ack, but for some reason it was giving me a param error instead of a state error like the manual said it would.

No skin off my nose, it’s working now so I’m happy :smiley: