Инструмент чтения и записи i2c, чтение цикла оболочки и значение регистра записи

В реальной разработке мы можем столкнуться с необходимостью чтения и записи значения в соответствующий регистр i2c, i2ctool — очень хороший инструмент, но иногда мы сталкиваемся с соответствующей ситуацией при использовании i2cset для записи значения регистра, как показано ниже:

i2cset -f -y 0 0x2d 0x00 0x11 i2cset: слишком длинный режим (см. «i2cset --help»)

Появится подсказка о том, что мы ввели слишком много параметров, но мы не ввели слишком много параметров, поэтому мы не можем нормально записать значение соответствующего регистра.После моей собственной проверки следующие инструменты могут очень хорошо решить эту проблему. Проблемы с возможностью записи регистров. Существует также сценарий оболочки, который используется, когда нам нужно прочитать и записать большое количество значений регистра i2c, потому что я ленив, поэтому я не люблю медленно набирать команды слово за словом, что слишком хлопотно, это Инструмент Его можно интегрировать в систему Android, и сценарий также передается в систему Android для выполнения. Конкретные связанные методы будут продолжены.

Следующая команда должна быть выполнена до нажатия adb. В противном случае будет сообщено об ошибке разрешения. И сценарий должен использовать chmod для добавления разрешения на выполнение перед выполнением.

корень adb

adb перемонтировать

#include <stdio.h>  
#include <linux/types.h>  
#include <fcntl.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <sys/types.h>  
#include <sys/ioctl.h>  
#include <errno.h>  
#include <assert.h>  
#include <string.h>  
#include <linux/i2c.h>  

#define I2C_RETRIES	0x0701	/* number of times a device address should be polled when not acknowledging */
#define I2C_TIMEOUT	0x0702	/* set timeout in units of 10 ms */
#define I2C_RDWR	0x0707	/* Combined R/W transfer (one STOP only) */


/* This is the structure as used in the I2C_RDWR ioctl call */  
struct i2c_rdwr_ioctl_data {  
        struct i2c_msg __user *msgs;    /* pointers to i2c_msgs */  
        __u32 nmsgs;                    /* number of i2c_msgs */  
};  
  
int i2c_read_reg(char *dev, unsigned char *buf, unsigned slave_address, unsigned reg_address, int len)  
{  
    struct i2c_rdwr_ioctl_data work_queue;  
    unsigned char w_val = reg_address;  
    int ret;  
  
    int fd = open(dev, O_RDWR);  
    if (!fd) {  
        printf("Error on opening the device file\n");  
        return 0;  
    }  
  
    work_queue.nmsgs = 2;  
    work_queue.msgs = (struct i2c_msg*)malloc(work_queue.nmsgs *sizeof(struct  
            i2c_msg));  
    if (!work_queue.msgs) {  
        printf("Memory alloc error\n");  
        close(fd);  
        return 0;  
    }  
  
    ioctl(fd, I2C_TIMEOUT, 2);  
    ioctl(fd, I2C_RETRIES, 1);  
  
    (work_queue.msgs[0]).len = 1;  
    (work_queue.msgs[0]).addr = slave_address;  
    (work_queue.msgs[0]).buf = &w_val;  
  
    (work_queue.msgs[1]).len = len;  
    (work_queue.msgs[1]).flags = I2C_M_RD;  
    (work_queue.msgs[1]).addr = slave_address;  
    (work_queue.msgs[1]).buf = buf;  
  
    ret = ioctl(fd, I2C_RDWR, (unsigned long) &work_queue);  
    if (ret < 0) {  
        printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);  
        close(fd);  
        free(work_queue.msgs);  
        return 0;  
    } else {  
        printf("read salve:%02x reg:%02x\n", slave_address, reg_address);  
        close(fd);  
        free(work_queue.msgs);  
        return len;  
    }  
}  
  
int i2c_write_reg(char *dev, unsigned char *buf, unsigned slave_address, unsigned reg_address, int len)  
{  
    struct i2c_rdwr_ioctl_data work_queue;  
    unsigned char w_val = reg_address;  
    unsigned char w_buf[len+1];  
    int ret;  
  
    w_buf[0] = reg_address;  
  
    int fd = open(dev, O_RDWR);  
    if (!fd) {  
        printf("Error on opening the device file\n");  
        return 0;  
    }  
  
    work_queue.nmsgs = 1;  
    work_queue.msgs = (struct i2c_msg*)malloc(work_queue.nmsgs *sizeof(struct i2c_msg));  
    if (!work_queue.msgs) {  
        printf("Memory alloc error\n");  
        close(fd);  
        return 0;  
    }  
  
    ioctl(fd, I2C_TIMEOUT, 2);  
    ioctl(fd, I2C_RETRIES, 1);  
  
    (work_queue.msgs[0]).len = 1 + len;  
    (work_queue.msgs[0]).addr = slave_address;  
    (work_queue.msgs[0]).buf = w_buf;  
  
    memcpy(w_buf + 1, buf, len);  
  
    ret = ioctl(fd, I2C_RDWR, (unsigned long) &work_queue);  
    if (ret < 0) {  
        printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);  
        close(fd);  
        free(work_queue.msgs);  
        return 0;  
    } else {  
        printf("write salve:%02x reg:%02x\n", slave_address, reg_address);  
        close(fd);  
        free(work_queue.msgs);  
        return len;  
    }  
}  
  
int main(int argc, char **argv)  
{  
    unsigned int fd;  
    unsigned int slave_address, reg_address;  
    unsigned r_w;  
    unsigned w_val;  
    unsigned char rw_val;  
  
    if (argc < 5) {  
        printf("Usage:\n%s /dev/i2c-x start_addr reg_addr rw[0|1] [write_val]\n", argv[0]);  
        return 0;  
    }  
  
    fd = open(argv[1], O_RDWR);  
  
    if (!fd) {  
        printf("Error on opening the device file %s\n", argv[1]);  
        return 0;  
    }  
  
    sscanf(argv[2], "%x", &slave_address);  
    sscanf(argv[3], "%x", &reg_address);  
    sscanf(argv[4], "%d", &r_w);  
  
    if (r_w == 0) {  
        i2c_read_reg(argv[1], &rw_val, slave_address, reg_address, 1);  
        printf("Read %s-%x reg %x, read value:%x\n", argv[1], slave_address, reg_address, rw_val);  
    } else {  
        if (argc < 6) {  
            printf("Usage:\n%s /dev/i2c-x start_addr reg_addr r|w[0|1] [write_val]\n", argv[0]);  
            return 0;  
        }  
        sscanf(argv[5], "%x", &w_val);  
        if ((w_val & ~0xff) != 0)  
            printf("Error on written value %s\n", argv[5]);  
  
        rw_val = (unsigned char)w_val;  
        i2c_write_reg(argv[1], &rw_val, slave_address, reg_address, 1);  
    }  
  
    return 0;  
}  

Соответствующий Android.mk

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

ifeq ($(SPEC_FOR_5071_TMFP),true)
        LOCAL_CFLAGS += -DCONFIG_SPEC_FOR_5071_TMFP
else
endif

LOCAL_MODULE = i2c_rw
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := i2c_rw_tool.c //换成该.c文件名,可换为文件命

include $(BUILD_EXECUTABLE)

Сценарий оболочки, сценарий оболочки может быть основан на том, является ли входная командная строка файлом или адресом.Если это xxx.txt, сценарий оболочки используется для записи значения регистра i2c.Если он должен прочитать значение в адресе регистра i2c нужно ввести значение для чтения Адрес регистра.

#At present, the value of I2C read register needs to be improved, 
#and the value of I2C corresponding register can be written normally

#!/bin/bash
b=1 #i2c number
i2c_path="/dev/i2c-1"	#read / write path
i2c_reg="0x2c" #i2c reg address
num=1   
file_name=$1

 if [ $# == 0 ]
 then
 	echo "Please re-enter and exit the script"
 	exit 1
 elif [ $# == 1 ]
 then
	if [ ! -f $1 ]
	then              
		echo "the $1 is not a file"
		exit 
	else
		flage=1
		echo "write the value of the register"
		echo "Start reading file data"
	fi
 else
 	flage=0
 	echo "Read the value of the register"	
 fi

i2cdetect -y $b
i2cdump -f -y $b $i2c_reg 
echo "Start the read/write i2c adder"
   
if [ $flage == 1 ] #write
	then
	while ((num<=$(cat "$file_name"|wc -l)))  
	    do  
		file_reg[$num]=$(cat "$file_name"|sed -n "${num}p"|awk -F ',' '{print $1}')  
		((num+=1))  
           done  
	num=1
	while ((num<=$(cat "$file_name"|wc -l)))  
	    do  
		file_val[$num]=$(cat "$file_name"|sed -n "${num}p"|awk -F ',' '{print $2}')  
		((num+=1))  
	    done 
	    
    num=`expr $num - 1` 
 	i=$num
 else   #read
 	#i=`expr $#/2`
 	i=$#
 fi
	while ((i>0))
	do		
	        if [ $flage == 0 ] #read
	        then
	        	i2c_rw $i2c_path $i2c_reg $flage $1  	
	        	echo "$1"
	        	shift 1
	        else  #write
	        	i2c_rw $i2c_path $i2c_reg ${file_reg[i]} $flage ${file_val[i]}
	        	echo ${file_reg[i]}
	        	echo ${file_val[i]}
	        	
	        fi
		let i--
	done
i2cdump -f -y $b $i2c_reg     


     

Случаи использования:

/data # ./write_i2c.sh 0x14 0x01 0x15 0x23 0x16 0x40 0x17 0x00 0x18 0x01 0x19 0x23 0x1A 0x40 0x1B 0x00 Эта команда используется для чтения значения в регистре i2c.

/data # ./write_i2c.sh file.txt Эта команда используется для записи значений в регистры пакетами.

Содержимое файла file.txt следующее:

0x00,0xAA
0x48,0x02
0xB6,0x20
0x01,0x38
0x02,0x80
0x03,0x74
0x04,0x64
0x05,0x50
0x06,0x64
0x07,0x00
0x08,0x14
0x09,0x05
0x0A,0x14
0x0B,0x02
0x0C,0x52
0x0D,0x01
0x0E,0x80
0x0F,0x20
0x10,0x20
0x11,0x03
0x12,0x1B
0x13,0x53
0x14,0x32
0x15,0x10
0x16,0x40
0x17,0x00
0x18,0x32
0x19,0x10
0x1A,0x40
0x1B,0x00
0x1E,0x46
0x51,0x30
0x1F,0x10
0x2A,0x01


注:左边是寄存器地址,右侧是要写如寄存器地址中的值

Supongo que te gusta

Origin blog.csdn.net/qq_48709036/article/details/123105311
Recomendado
Clasificación