Search code examples
clinux-device-driveri2ciio

I2C read() lost 1 bit


I try to use I2C to read data from ADS1110, the address of ADS1110 is seven bits, which is 1001 000. Writing data can only change the configuration register, which is done in the form of address + configuration. Reading data returns 3 bytes of data, which are high-order bytes data, low-order bytes data, and configuration. The default configuration of ADS1110 is 0x8C, and the highest bit is generally 0 in continuous mode, indicating that the converted data is the latest. I use read() and write() to implement I2C reading, the code is as follows:

#define NUMS 10
char readbuf[NUMS];

int main(int argc, char** argv)
{
    // int file = i2c_init("/dev/i2c-0", 0x48);
    int file = open("/dev/i2c-0", O_RDWR);
    int addr = 0b01001000;

    if (file < 0) {
        printf("openfile error!\n");
        exit(1);
    }

    if (ioctl(file, I2C_SLAVE, addr) < 0) {
        printf("ioctl error!\n");
        exit(1);
    }

    // Debug Gain 1
    readbuf[0] = 0x0C;

    if (write(file, readbuf, 1) != 1) {
        printf("write error!\n");
        exit(1);
    }

    if (read(file, readbuf, 3) != 3) {
        printf("read error!\n");
        exit(1);
    }

    printf("%x %x %x\n", readbuf[0] & 0xff, readbuf[1] & 0xff, readbuf[2] & 0xff);

    close(file);
    exit(EXIT_SUCCESS);
}

Here I configure the ADS1110 as 0x0C, which means that I am reading in continuous mode, and the gain of the ADC is 1 times, and the specified reading rate is 15sps, that is, I can read 2.048V (7FFF) with 16-bit accuracy enter. But when my input is less than 1.024V, the read result is correct; when the data is greater than 1.024V, D14 should be 1, but I get a result of 0. For example, when the input is 1.5V, the output should is 5D XX (0101), but I only get 1D XX (0001). But except for D14, the values ​​of all registers including Config are correct. The result displayed by the oscilloscope is shown in the following figure:

pic1


Solution

  • There is an NS2009 on the board, and the address conflicts with the ADS1110.