0

我正在尝试实现一个主 Linux 驱动程序来与Omron D6t-PH 差压流量计从设备进行通信。

阅读该仪器的手册和提供的示例代码(用于 STM32 uC),看来我需要在初始“写入访问地址”之后增加从地址。这将允许我从设备中读取测量数据。

Linux i2c smbus 库中提供了一个函数执行此操作,尽管它似乎不支持初始“访问寄存器写入”之后的地址增量。

有谁知道有关如何处理此设备地址递增要求的解决方法或一些建议?

以下是我一直在关注的一些文档和指南。首先是设备手册;

地址增量要求显示在D6T... 手册的 P.7 表 3 中

写入期间:将从机地址的 LSB 设置为“0”以形成 D8h (1101_1000b)。

读期间:设置从机地址的 LSB 为“1”,形成 D9h (1101_1001b)。

所需命令的流程图在 P.12,P20-22

一些概述相同的示例代码在 P.28 上

I2C1_MastrSel(添加,1);/* 从机 7bit => 8bit 用于 RD */

关于我正在尝试编写的主 Linux 用户空间驱动程序,如何更改“SMBus Block Read”命令,以便在第二个“Start”命令之后增加地址?这是命令结构:

S Addr Wr [A] Comm [A] S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] 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;
}
4

0 回答 0