I2C EEPROM: может писать, но читать только 0xFF

В настоящее время я работаю над связью I2C между i.MX6 (Android BSP) и 24C08WP EEPROM.

Я использую на i.MX6 двоичный файл, ранее скомпилированный под NDK под Linux.

Я обнаружил компонент NTAG 5, подключенный к шине I2C (адрес 0x50) i.MX6, благодаря инструменту i2cdetect.

С помощью следующего кода я могу выполнить операцию записи, которую я могу проверить с помощью платы Arduino и операции чтения I2C.

Однако, когда я выполняю операции чтения в пользовательском пространстве под i.MX6, я получаю только значение 0xFF.

Вот мой код:

#include <stdio.h>
#include <stdlib.h>

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <linux/i2c-dev.h>

#include "board.h"
#include "debug_tools.h"
#include "boardselection.h"

int main(void) {
    int file;
    int adapter_nr = 1; /* probably dynamically determined */
    char filename[20];

    snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
    file = open(filename, O_RDWR);
    if (file < 0) {
        /* ERROR HANDLING; you can check errno to see what went wrong */
        exit(1);
    }

    int addr = 0x50; /* The I2C address */

    if (ioctl(file, I2C_SLAVE, addr) < 0) {
        /* ERROR HANDLING; you can check errno to see what went wrong */
        exit(1);
    }

    uint8_t reg = 0x00;

    uint8_t data_w[4] = {0x00, 0x00, 0x00, 0x00};

    data_w[0] = reg;
    data_w[1] = 0x01;
    data_w[2] = 0x02;
    data_w[3] = 0x03;
    
    /* Write the register */
    if (write(file, data_w, 4) != 4)
    {
        perror("Failed to write to the i2c bus");
        exit(1);
    }

    usleep(2000000);

    uint8_t data_r[4] = {0x00, 0x00, 0x00, 0x00};

    if (read(file, data_r, 3) != 3) {
        /* ERROR HANDLING: i2c transaction failed */
        perror("Failed to read register value");
        exit(1);
    }

    /* data_r[0] contains the read byte */
    printf("%X %X %X\n", data_r[0], data_r[1], data_r[2]);

    return 0;
}

Можешь мне помочь?

В этой ветке описывается почти та же проблема, связанная с получение значения 0xFF.


person Martin Denion    schedule 08.03.2021    source источник


Ответы (1)


Как сказал @Andrew Cottrell в этой теме : Для чтения с вашего устройства I2C, предполагая, что он использует однобайтовый регистр, запишите буфер из одного байта (адрес регистра), затем прочитайте буфер из одного или нескольких байтов (значение в этом регистре и последующих регистрах) .

Итак, правильный код следующий:

#include <stdio.h>
#include <stdlib.h>

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <linux/i2c-dev.h>

#include "board.h"
#include "debug_tools.h"
#include "boardselection.h"

int main(void) {
    int file;
    int adapter_nr = 1; /* probably dynamically determined */
    char filename[20];

    snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
    file = open(filename, O_RDWR);
    if (file < 0) {
        /* ERROR HANDLING; you can check errno to see what went wrong */
        exit(1);
    }

    int addr = 0x50; /* The I2C address */

    if (ioctl(file, I2C_SLAVE, addr) < 0) {
        /* ERROR HANDLING; you can check errno to see what went wrong */
        exit(1);
    }

    uint8_t reg = 0x00;

    uint8_t data_w[4] = {0x00, 0x00, 0x00, 0x00};

    data_w[0] = reg;
    data_w[1] = 0x44;

    /* Write the register */
    if (write(file, data_w, 2) != 2)
    {
        perror("Failed to write to the i2c bus");
        exit(1);
    }

    usleep(1000000);

    uint8_t data_r[4] = {0x00, 0x00, 0x00, 0x00};

    if (write(file, &reg, 1) != 1)
    {
        perror("Failed to write to the i2c bus");
        exit(1);
    }

    if (read(file, data_r, 1) != 1) {
        /* ERROR HANDLING: i2c transaction failed */
        perror("Failed to read register value");
        exit(1);
    }

    /* data_r[0] contains the read byte: 0x44 */
    printf("%02X\n", data_r[0]);

    return 0;
}

Примечание: если вы не используете usleep() для ожидания между двумя операциями записи, вторая операция записи может завершиться ошибкой.

person Martin Denion    schedule 09.03.2021