LINUX.ORG.RU

Проблема с I2C на BBB c Debian

 , ,


0

1

Добрый день. Использую Beaglebone Black, где установлен Debian 9.3. Проблема состоит в том, что не получается читать данные по I2C. Выполнение различных команд в терминале даёт такой результат:


debian@beaglebone:~/temp$ i2cdetect -l
i2c-1	i2c       	OMAP I2C adapter                	I2C adapter
i2c-2	i2c       	OMAP I2C adapter                	I2C adapter
i2c-0	i2c       	OMAP I2C adapter                	I2C adapter



debian@beaglebone:~/temp$ i2cdetect -r 2
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-2 using read byte commands.
I will probe address range 0x03-0x77.
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --      


debian@beaglebone:~/temp$ ls -l /sys/bus/i2c/devices/i2c-*
lrwxrwxrwx 1 root root 0 Jan 28 15:47 /sys/bus/i2c/devices/i2c-0 -> ../../../devices/platform/ocp/44e0b000.i2c/i2c-0
lrwxrwxrwx 1 root root 0 Jan 28 15:47 /sys/bus/i2c/devices/i2c-1 -> ../../../devices/platform/ocp/4802a000.i2c/i2c-1
lrwxrwxrwx 1 root root 0 Jan 28 15:47 /sys/bus/i2c/devices/i2c-2 -> ../../../devices/platform/ocp/4819c000.i2c/i2c-2

Использую i2c-2. К Beaglebone по I2C подключен микроконтроллер, который в режиме мастера постоянно шлёт данные. Для чтения на стороне Beaglebone использую следующий код, собираемый из-под Qt:


#include <QCoreApplication>

#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <linux/i2c-dev.h>

using namespace std;

int i2c_desc = 0;
int i2c_ioc = 0;
char num = 0;
char file[11] = "/dev/i2c-X";

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    cout << "Enter the I2C-device number: ";
    cin >> num;

    file[9] = num;
    cout << "I2C file: " << file << endl;

    if ((i2c_desc = open(file, O_RDWR)) < 0)
            cout << "Error opening the I2C file" << endl;
    else
    {
        cout << "I2C file is open" << endl;

        if ((i2c_ioc = ioctl(i2c_desc, I2C_SLAVE, 0x42)) < 0)
            cout << "Error setting parameters" << endl;
        else
            cout << "Settings are set" << endl;
    }

    unsigned char buf[8] = ".......";

    while(true)
    {
        int res = read(i2c_desc, buf, 8);

        if(res >= 0)
            cout << "I2C data: " << buf << endl;
        else
            cout << "Error: " << strerror(errno) << endl;
    }

    return a.exec();
}


Но при исполнении программы получаю ошибки «Resource temporarily unavailable», изредка разбавляемые «Device or resource busy». Как я понимаю, проблема либо где-то в системе, либо в том, что я как-то неправильно читаю из I2C.

Может, у кого есть мысли о том, почему так происходит?


режиме мастера постоянно шлёт данные

У тебя на той же шине «висят» i2c eeprom которые cape определяют, так что либо перевешивай контроллер на пустой i2c, либо разбирайся как с i2cdev сделать мультимастер, лично я не знаю.

UPD: Насколько я нагуглил - линукс не умеет в мультимастер.

Dark_SavanT ★★★★★ ()
Последнее исправление: Dark_SavanT (всего исправлений: 2)
Ответ на: комментарий от Dark_SavanT

Спасибо за ответ. Я не совсем понял, что означает фраза «i2c eeprom которые cape определяют», в частности, что такое «cape» и что значит определить его. Нашёл статью https://elinux.org/Beagleboard:Cape_Expansion_Headers, где была такая информация: «Every cape that utilizes pins on the expansion headers is expected to notify software on the board by providing contents within EEPROM connected to I2C2 with an address from 0x54 to 0x57. To work with other capes you can make your address selectable between those values to avoid conflicts.» Попробовал поменять адрес BBB на 0х55, что (ожидаемо) не сработало — ещё при выполнении

   i2c_ioc = ioctl(i2c_desc, I2C_SLAVE, 0x55) 
выпала ошибка, и далее — «Device or resource busy». Возможно, я что-то не так понял

shem ()
Ответ на: комментарий от shem

cape - это платы которые сверху ставятся.

Ещё раз - переноси на i2c0 или i2c1, либо выпиливай всё что отвечает за определение cape на плате.

Dark_SavanT ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.