I2C interface problem: not getting ACK back

Thread Starter

Gundam

Joined Dec 11, 2008
4
Hi All,

I'm trying to control an Avago color sensor development kit (HDJD-JD14). I'm using the driver they provided (ftd2xx.dll) but I cannot get an ACK back from the sensor after sending the slave address for writing (B0H). I've also attached my C code below. Could anyone tell me what I've done wrong?

Thank you very much,
Gordon

#include<stdio.h>
#include<windows.h>
#include "ftd2xx.h"
#pragma comment(lib, "FTD2XX.lib")
FT_STATUS ftStatus;
FT_HANDLE ftHandle;
// start condition
void i2c_start()
{
DWORD dwBytesInQueue = 0;
UCHAR cBufWrite; //buffer to contain data to write to device

cBufWrite = 0x03;
ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufWrite),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);//1=asynchronous bit-bang mode
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written

cBufWrite = 0x02;
ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufWrite),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written

cBufWrite = 0x00;
ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufWrite),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written
}
// byte send, Ack returned
unsigned char i2c_tx(unsigned char databyte)
{
unsigned char i=0,b,c,ack=0;
DWORD dwBytesInQueue = 0;

for(i=0;i<8;i++)
{
c=(databyte>>(7-i))&0x01;

b=0x00|c;
ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written

b=0x02|c;
ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written

b=0x00|c;
ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written
}

c=0x01;
b=0x01|c;
ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFE,0x01);//set LSB(SDA) as output
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written

b=0x03|c;
ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFE,0x01);
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written

ftStatus=FT_GetBitMode(ftHandle,&ack);
if(ftStatus!=FT_OK) printf("Device GetBit error");
ack=ack&0x01;

b=0x01|c;
ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFE,0x01);
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written

return ack;
}
// Stop condition
void i2c_stop()
{
DWORD dwBytesInQueue = 0;
UCHAR cBufWrite; //buffer to contain data to write to device

cBufWrite = 0x00;
ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufWrite),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written

cBufWrite = 0x02;
ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufWrite),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written

cBufWrite = 0x03;
ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufWrite),&dwBytesInQueue);
if(ftStatus!=FT_OK) printf("Device setBit error");
ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
if(ftStatus!=FT_OK) printf("Device setBit error");
dwBytesInQueue = 0; //reset counter for bytes written
}
int main()
{
DWORD numDevs;
UCHAR x;
char buffer[64];

ftStatus=FT_ListDevices(&numDevs,NULL,FT_LIST_NUMBER_ONLY);
if(ftStatus==FT_OK)
{
printf("%i devices found\n",(int)numDevs);
}
if(numDevs>=1)
{
ftStatus=FT_ListDevices((PVOID)0,buffer,FT_LIST_BY_INDEX|FT_OPEN_BY_DESCRIPTION);
if(ftStatus==FT_OK)
printf("Description of Device 0: %s\n",buffer);
ftStatus=FT_Open(0,&ftHandle);
if(ftStatus==FT_OK)
{
printf("Device opened\n");

i2c_start();
x=i2c_tx(0xb0);
printf("%X\n", (unsigned) x);
i2c_stop();
}
}
return 0;
}
 

SgtWookie

Joined Jul 17, 2007
22,230
I just indented your source code so it's easier to read.

Rich (BB code):
#include<stdio.h>
#include<windows.h>
#include "ftd2xx.h"
#pragma comment(lib, "FTD2XX.lib")
FT_STATUS ftStatus;
FT_HANDLE ftHandle;
// start condition 
void i2c_start()
{
	DWORD dwBytesInQueue = 0;
	UCHAR cBufWrite; //buffer to contain data to write to device

	cBufWrite = 0x03;
	ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufW rite),&dwBytesInQueue);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);//1=asynchronous bit-bang mode
	if(ftStatus!=FT_OK) printf("Device setBit error");
	dwBytesInQueue = 0; //reset counter for bytes written

	cBufWrite = 0x02;
	ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufW rite),&dwBytesInQueue);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	dwBytesInQueue = 0; //reset counter for bytes written

	cBufWrite = 0x00;
	ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufW rite),&dwBytesInQueue);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	dwBytesInQueue = 0; //reset counter for bytes written
}
// byte send, Ack returned
unsigned char i2c_tx(unsigned char databyte)
{
	unsigned char i=0,b,c,ack=0;
	DWORD dwBytesInQueue = 0;

	for(i=0;i<8;i++)
	{
		c=(databyte>>(7-i))&0x01;

		b=0x00|c;
		ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesIn Queue);
		if(ftStatus!=FT_OK) printf("Device setBit error");
		ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
		if(ftStatus!=FT_OK) printf("Device setBit error");
		dwBytesInQueue = 0; //reset counter for bytes written

		b=0x02|c;
		ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesIn Queue);
		if(ftStatus!=FT_OK) printf("Device setBit error");
		ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
		if(ftStatus!=FT_OK) printf("Device setBit error");
		dwBytesInQueue = 0; //reset counter for bytes written

		b=0x00|c;
		ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesIn Queue);
		if(ftStatus!=FT_OK) printf("Device setBit error");
		ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
		if(ftStatus!=FT_OK) printf("Device setBit error");
		dwBytesInQueue = 0; //reset counter for bytes written
	}

	c=0x01;
	b=0x01|c;
	ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesIn Queue);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	ftStatus=FT_SetBitMode(ftHandle,0xFE,0x01);//set LSB(SDA) as output
	if(ftStatus!=FT_OK) printf("Device setBit error");
	dwBytesInQueue = 0; //reset counter for bytes written

	b=0x03|c;
	ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesIn Queue);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	ftStatus=FT_SetBitMode(ftHandle,0xFE,0x01);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	dwBytesInQueue = 0; //reset counter for bytes written

	ftStatus=FT_GetBitMode(ftHandle,&ack);
	if(ftStatus!=FT_OK) printf("Device GetBit error");
	ack=ack&0x01;

	b=0x01|c;
	ftStatus=FT_Write(ftHandle,&b,sizeof(b),&dwBytesIn Queue);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	ftStatus=FT_SetBitMode(ftHandle,0xFE,0x01);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	dwBytesInQueue = 0; //reset counter for bytes written

	return ack;
}
// Stop condition
void i2c_stop()
{
	DWORD dwBytesInQueue = 0;
	UCHAR cBufWrite; //buffer to contain data to write to device

	cBufWrite = 0x00;
	ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufW rite),&dwBytesInQueue);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	dwBytesInQueue = 0; //reset counter for bytes written

	cBufWrite = 0x02;
	ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufW rite),&dwBytesInQueue);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	dwBytesInQueue = 0; //reset counter for bytes written

	cBufWrite = 0x03;
	ftStatus=FT_Write(ftHandle,&cBufWrite,sizeof(cBufW rite),&dwBytesInQueue);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	ftStatus=FT_SetBitMode(ftHandle,0xFF,0x01);
	if(ftStatus!=FT_OK) printf("Device setBit error");
	dwBytesInQueue = 0; //reset counter for bytes written
}
int main()
{
	DWORD numDevs;
	UCHAR x;
	char buffer[64];

	ftStatus=FT_ListDevices(&numDevs,NULL,FT_LIST_NUMB ER_ONLY);
	if(ftStatus==FT_OK)
	{
		printf("%i devices found\n",(int)numDevs);
	}
	if(numDevs>=1)
	{
		ftStatus=FT_ListDevices((PVOID)0,buffer,FT_LIST_BY _INDEX|FT_OPEN_BY_DESCRIPTION);
		if(ftStatus==FT_OK)
		printf("Description of Device 0: %s\n",buffer);
		ftStatus=FT_Open(0,&ftHandle);
		if(ftStatus==FT_OK)
		{
			printf("Device opened\n");

			i2c_start();
			x=i2c_tx(0xb0);
			printf("%X\n", (unsigned) x);
			i2c_stop();
		}
	}
	return 0;
}
 

leftyretro

Joined Nov 25, 2008
395
I'm not a code warrior so I can't really comment on your code, but I can share from other forums that the vast majority of problems with I2C seem to boil down to the required pull up resistors and the device addressing schem.

Seems to be a lot of confusion about 7 bit addressing Vs 8 bit with the LSB being a read/write bit. Also insuring the I2C devices are at the address you think they are at, as there is usually a device base address and a hardwired additional address bits so as to allow several devices of the same type to share the I2C buss and those hardwired address bits have to be wired high or low to generate the full address desired for the device. If this is all old news to you then never mind ;)

I've experminated a little with a few I2C devices and I'm a real fan of this buss.

Lefty
 

Thread Starter

Gundam

Joined Dec 11, 2008
4
Hi Lefty,

Suppose the slave address is 58H, thus for reading should be B1H. After I've sent the LSB (write/read bit) (which is 1 in this case), should the SDA line go to LOW state immediately as an ACK? Or will the SDA line go to LOW state after I've made SCL go HIGH?

Thank you very much,
Gordon
 

Misbah

Joined Mar 9, 2009
2
First check the slave address whether it is correct or not ????

SDA should go low as ACK that can verified using scope ...

If your slave address is correct then probably your slave device is not responding due to improper design ....get confirmed with the pull up resistor value to be correct .... last but not least check the timings ....

In which mode (speed r u operating ) Is the device external or internal to the board ???

What is the capacitive inductance it is offering ????
 
Top