SMBus Block Read со смещением адреса после написания начальной команды - PullRequest
0 голосов
/ 22 марта 2020

Я пытаюсь реализовать мастер Linux драйвер для связи с расходомером дифференциального давления Omron D6t-PH подчиненное устройство.

Чтение руководства по данному инструменту и Приведенный пример кода (который предназначен для STM32 u C), кажется, мне нужно увеличить адрес подчиненного устройства после первоначальной «записи в адрес доступа». Это позволит мне читать измеренные данные с устройства.

В библиотеке Linux i2 c smbus имеется функция *1007*, которая будет это делать, хотя это не так. по-видимому, для поддержки приращения адреса, следующего за начальной «записью в регистр доступа».

Кто-нибудь знает обходной путь или какой-либо совет о том, как справиться с этим требованием увеличения адреса устройства?

Ниже приведены некоторые действия c и руководства, которым я следовал. Во-первых, это руководство для устройства;

Требование увеличения адреса показано на стр. 7 таблицы 3. руководства D6T ...

Во время записи: установлено LSB подчиненного адреса в «0» для формирования D8h (1101_1000b).

Во время чтения: установите LSB подчиненного адреса в «1» для формирования D9h (1101_1001b).

Поток таблица требуемых команд приведена на стр.12, P20-22

Некоторые примеры кода, описывающие то же самое, приведены на стр.28

I2C1_MastrSel (add, 1); / * Slave 7bit => 8bit для RD * /

Относительно основного Linux драйвера пространства пользователя Я пытаюсь написать, как я могу изменить "SMBus Block Read" команда, чтобы я мог увеличить адрес после второй команды «Пуск»? Вот структура команд:

S Addr Wr [A] Comm [A] S Addr Rd [A] [Количество] A [Данные] A [Данные] A. .. A [Данные] NA P

Это некоторый код прототипа, который я написал до сих пор, и он успешно работает до конца блока:

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
// Make sure to link when compiling,... -li2c -o ...
#include <i2c/smbus.h>
#include <fcntl.h>
#include <stdlib.h>

/*******************************************************
Read block will read a block of data from the device
This is a challenge as this device requires that the addres is
incremented by 1 after writing the command to its access register.

The prototype function from smbus doesnt seem to offer this functionality
what i need appears to match the i2c_smbus_read_block_data() function,
although it does not increment the address after writing the initial command.
********************************************************/

void readBlock(file){

char res[2];
int readData = i2c_smbus_read_block_data(file,0x07,res);

if (readData<0){
 printf("readDatafailed");
}else{
 printf("dataRead, 0x%x",res);
}

}

/*********************************************************
START PROGRAM
********************************************************/
int main () {

/******************************************************
 Open the device, as a file... Use adapter i2c-1
*******************************************************/
int file;
int adapter_nr = 1; /* adapter 1 */
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 */
 int errnum = errno;
 fprintf(stderr, "Value of errno: %d\n", errno);
 perror("Error printed by perror");
 fprintf(stderr, "Error opening file: %s\n", strerror( errnum ));
 exit(1);
}else{
 char str[80];
 sprintf(str,"Opened the device");
 /*Device does open*/
 puts(str);
}

/****************************************************************
Next, afer the file is open and using the correct system driver,
Use the system i2c driver to open the correct i2c slave device by referencing
the address 0x6c
*****************************************************************/

int addr = 0x6C; /* The I2C address of this flow meter */

if (ioctl(file, I2C_SLAVE, addr) < 0) {
 /* ERROR HANDLING; you can check errno to see what went wrong */
 int  errnum = errno;
 fprintf(stderr, "Value of errno: %d\n", errno);
 perror("Error printed by perror");
 fprintf(stderr, "Error opening file: %s\n", strerror( errnum ));
 exit(1);
}else{
 char str[80];
 sprintf(str,"Opened the device at address 0x6C");
 puts(str);
}

/*************************************************************
Now try and read a conf. register from the Omron flow meter
*************************************************************/
__u8 reg = 0x02; /* Device register to access */
__s32 res;
char buf[10];

/* Using SMBus commands */
res = i2c_smbus_read_byte_data(file, reg);
if (res < 0) {
 /* ERROR HANDLING: I2C transaction failed */
}else{
 /* res contains the read word */
 printf("Data received...Ox%X.\n",res); 
 /*Receives 0x04 which is correct*/
}


/***************************************************
Now set up the configuration register by writing 00 to 0b
*******************************************************/

char reg1 = 0x0b;
char data1 = 0x00;
__s32 res1;

//write to initialization register
res1 = i2c_smbus_write_byte_data(file,reg1,data1);
//check data and report
if (res1 < 0) {
 perror("error writing to Initialization register");
}else{
 perror("device initialized");
/*Device is initialized*/
}

//readBlock(); 
/*This fails as i cannnot increment address*/
/*How to alter the read block function???*/
return 0;
}
...