Я пытаюсь реализовать мастер 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;
}