Skip to main content
Topic: FTDI FT2232H - Problem reading two bytes from I2C device (Read 4459 times) previous topic - next topic

FTDI FT2232H - Problem reading two bytes from I2C device

Hi All,

I am using visual c++ to communicate with three ICs using I2C, from a PC via usb using a FT2232H.

The devices I am connected via I2C are 2x AD5252 and 1x AD7993. The AD7993 contains 16 bit registers which I am having trouble reading from. I have successfully written and read from the 8bit registers on all three devices, but always get incorrect results when reading the 16bit registers.

Below is a copy of the code I use for reading the 8bit registers in the AD7993 AtoD converter. The code is written in Microsoft Visual C++ 2008 Express Edition and based on code from the I2CTEST example code found at the ftdichip website


I would appreciate it if anyone could point me to how to modify the code for reading two bytes?

Code: [Select]
    //////////////////
    ///READ SECTION
    ///////////////////
    //Purge USB receive buffer first before read operation
    ftStatus = FT_GetQueueStatus(ftHandle, &dwNumInputBuffer); // Get the number of bytes in the device receive buffer
    if ((ftStatus == FT_OK) && (dwNumInputBuffer > 0))
    FT_Read(ftHandle, &InputBuffer, dwNumInputBuffer, &dwNumBytesRead); //Read out all the data from receive buffer
    //////////////////////////////////////////////////////////
    // Set I2C start condition
    //////////////////////////////////////////////////////////
    HighSpeedSetI2CStart();
    bSucceed = SendByteAndCheckACK(0x58); // Address of AD5252 with LSB=0 for write command
    bSucceed = SendByteAndCheckACK(0x01); // Register RDAC1 for W1
    HighSpeedSetI2CStart();
    bSucceed = SendByteAndCheckACK(0x59); // Address of AD5252 with LSB=1 for read command
    //////////////////////////////////////////////////////////
    // Read the data from I2C device
    //////////////////////////////////////////////////////////
    //dwNumBytesToSend = 0; //Clear output buffer
    OutputBuffer[dwNumBytesToSend++] = 'x80'; //Command to set directions of lower 8 pins and force value on bits set as output
    OutputBuffer[dwNumBytesToSend++] = 'x00'; //Set SCL low, WP disabled by SK, GPIOL0 at bit ¡®0¡¯
    OutputBuffer[dwNumBytesToSend++] = 'x11'; //Set SK, GPIOL0 pins as output with bit ¡¯1¡¯, DO and other pins as input with bit ¡®0¡¯
    OutputBuffer[dwNumBytesToSend++] = MSB_FALLING_EDGE_CLOCK_BYTE_IN; //Command to clock data byte in on ¨Cve Clock    Edge MSB first
    OutputBuffer[dwNumBytesToSend++] = 'x00';
    OutputBuffer[dwNumBytesToSend++] = 'x00'; //Data length of 0x0000 means 1 byte data to clock in
    //OutputBuffer[dwNumBytesToSend++] = 'x87'; //Send answer back immediate command

    OutputBuffer[dwNumBytesToSend++] = MSB_RISING_EDGE_CLOCK_BIT_IN; //Command to scan in acknowledge bit , -ve clock    Edge MSB first
    OutputBuffer[dwNumBytesToSend++] = 'x0'; //Length of 0 means to scan in 1 bit
    OutputBuffer[dwNumBytesToSend++] = 'x87'; //Send answer back immediate command
    ftStatus = FT_Write(ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent); //Send off the commands
    dwNumBytesToSend = 0; //Clear output buffer
    ftStatus = FT_Read(ftHandle, InputBuffer, 2, &dwNumBytesRead);//Read one byte from device receive buffer, may need try more times

    ByteDataRead = InputBuffer[0]; //return the data read from EEPROM

    OutputBuffer[dwNumBytesToSend++] = 'x80'; //Command to set directions of lower 8 pins and force value on bits set as output
    OutputBuffer[dwNumBytesToSend++] = 'x02'; //Set SDA high, SCL low, WP disabled by SK at bit '0', DO, GPIOL0 at bit '1'
    OutputBuffer[dwNumBytesToSend++] = 'x13'; //Set SK,DO,GPIOL0 pins as output with bit ¡¯1¡¯, other pins as input with bit ¡®0¡¯
    HighSpeedSetI2CStop();
    ftStatus = FT_Write(ftHandle, OutputBuffer, dwNumBytesToSend, &dwNumBytesSent); //Send off the commands
    dwNumBytesToSend = 0; //Clear output buffer

Jonathan

Re: FTDI FT2232H - Problem reading two bytes from I2C device

Reply #1
I'm really sorry for the problem, but I'm not familiar enough with everything to be much help.

Just to check - are the 16 bit registers 2 8bit registers? Do you need to I2C ACK each 8 bits of the read, or only every 16 bits?
Got a question? Please ask in the forum for the fastest answers.

Re: FTDI FT2232H - Problem reading two bytes from I2C device

Reply #2
2 8bit registers with an ACK each 8 bits. Only one address though.

Re: FTDI FT2232H - Problem reading two bytes from I2C device

Reply #3
Hmm, if I read the datasheet correctly, you have to do the read operation twice. According to page 26, Fig. 30 you first create the start condition; then send the address, get acked by the 7993; then read the byte, ack it; then read the second byte, nack it and create the stop condition.

Re: FTDI FT2232H - Problem reading two bytes from I2C device

Reply #4
In the code above, I believe this section is the key:
Code: [Select]
    OutputBuffer[dwNumBytesToSend++] = 'x00';
    OutputBuffer[dwNumBytesToSend++] = 'x00';  //Data length of 0x0000 means 1 byte data to clock in

That means 0x0001 means 2 byte data to clock in (FTDI should take care of the ack nack stuff) IMO:
Code: [Select]
    OutputBuffer[dwNumBytesToSend++] = 'x00';
    OutputBuffer[dwNumBytesToSend++] = 'x01';  //Data length of 0x0001 means 2 bytes of data to clock in

Can you give this a go?

Re: FTDI FT2232H - Problem reading two bytes from I2C device

Reply #5
Thanks for the tip.

When I tried this I got:
MSB (read first) = 0x27 (sensible value)
LSB (read second) = 0xFF - always the same regardless of the value in the register.

 

Re: FTDI FT2232H - Problem reading two bytes from I2C device

Reply #6
How do you know the value in the register? Can you post your code over here?