Linux(I2C)

格式

i2c 分兩種格式: 7bit & 10bit

1
2
3
4
5
6
7
(M) = Master to Slave
(S) = Slave to Master
# Write 格式
S(M) + Slave Address(M) + W = 0(M) + A(S) + DATA(M) + A(S) + DATA(M) + A(S) + P(M)

# Read 格式
S(M) + Slave Address(M) + R = 1(M) + A(S) + DATA(S) + A(M) + DATA(S) + A(M) + P(M)

C example

要先 include

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
int file;
int adapter_nr = 2; /* Bus-2 可動態決定 */
char filename[20];

snprintf(filename, 19, "/dev/i2c-%d", adapter_nr); /* 打開 /dev/i2c-2 */
file = open(filename, O_RDWR);
if (file < 0) {
exit(1);
}

/* 設定要 R/W 的 Device Address */
int addr = 0x40; /* The I2C address */
if (ioctl(file, I2C_SLAVE, addr) < 0) {
exit(1);
}

/* 設定要 R/W Device 的哪一個 register */
__u8 reg = 0x10; /* Device register to access */
__s32 res;
char buf[10];


res = i2c_smbus_read_word_data(file, reg);
if (res < 0) {
/* ERROR */
}

/* I2C Write */
buf[0] = reg;
buf[1] = 0x43;
buf[2] = 0x65;
if (write(file, buf, 3) != 3) {
/* ERROR HANDLING: i2c transaction failed */
}

/* I2C Read */
if (read(file, buf, 1) != 1) {
/* ERROR */
}

Linux 格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct i2c_rdwr_ioctl_data {  
struct i2c_msg __user *msgs; /* pointers to i2c_msgs */
__u32 nmsgs; /* number of i2c_msgs */
};

struct i2c_msg {
__u16 addr; /* slave address */
__u16 flags;
#define I2C_M_RD 0x0001 /* read data, from slave to master */
/* I2C_M_RD is guaranteed to be 0x0001! */
#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
#define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */
__u16 len; /* msg length */
__u8 *buf; /* pointer to msg data */
};

SMBUS

Spec

1
2
# (Master/Slave:bit)
S(M:1) + Slave Address(M:7) + Wr(M:1) + A(S:1) + DATA(M:8) + A(S:1) + P(M:1)

每一個 Slave Device 都有獨一的 address,可以寫在 Slave Address 裡面

但 Slave Address 有一些預設的 address 不能用

2016-08-30_095751.png

Debug Level

參考-1

參考-2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0 (KERN_EMERG)  The system is unusable.
1 (KERN_ALERT) Actions that must be taken care of immediately.
2 (KERN_CRIT) Critical conditions.
3 (KERN_ERR) Noncritical error conditions.
4 (KERN_WARNING)Warning conditions that should be taken care of.
5 (KERN_NOTICE) Normal, but significant events.
6 (KERN_INFO) Informational messages that require no action.
7 (KERN_DEBUG) Kernel debugging messages, output by the kernel if the developer enabled debugging at compile time.


# 目前 Level 設定
cat /proc/sys/kernel/printk
7 4 1 7

# 設定 Level
dmesg -n 7
echo "0 0 0 0" > /proc/sys/kernel/printk
echo "8" > /proc/sys/kernel/printk

# 顯示 message
tail /var/log/messages
dmesg

OpenSource

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
CC=../XXX/arm-linux-
ROOT=../image

CPPFLAGS := -DMY_FALG
INCLUDE_PATH := ../include
TOOL_PATH := ./

i2cdetect: i2cdetect.c i2cbusses.c ../lib/smbus.c
$(CC)gcc -I$(INCLUDE_PATH) -I$(TOOL_PATH) $(CPPFLAGS) -static -o $@ $^
cp ./i2cdetect $(ROOT)

i2cdump: i2cdump.c i2cbusses.c util.c ../lib/smbus.c
$(CC)gcc -I$(INCLUDE_PATH) -I$(TOOL_PATH) $(CPPFLAGS) -static -o $@ $^
cp ./i2cdump $(ROOT)

i2cget: i2cget.c i2cbusses.c util.c ../lib/smbus.c
$(CC)gcc -I$(INCLUDE_PATH) -I$(TOOL_PATH) $(CPPFLAGS) -static -o $@ $^
cp ./i2cget $(ROOT)

i2cset: i2cset.c i2cbusses.c util.c ../lib/smbus.c
$(CC)gcc -I$(INCLUDE_PATH) -I$(TOOL_PATH) $(CPPFLAGS) -static -o $@ $^
cp ./i2cset $(ROOT)

I2C_Test: I2C_Test.c i2cbusses.c util.c ../lib/smbus.c
$(CC)gcc -I$(INCLUDE_PATH) -I$(TOOL_PATH) $(CPPFLAGS) -static -o $@ $^
cp ./I2C_Test $(ROOT)


TOOLS_TARGETS := i2cdetect i2cdump i2cget i2cset I2C_Test
all: $(TOOLS_TARGETS)

clean:
rm -rf *.o i2cdetect i2cdump i2cget i2cset

參考

參考-1

參考-2

參考-3