-
Notifications
You must be signed in to change notification settings - Fork 0
/
i2c.go
113 lines (98 loc) · 2.49 KB
/
i2c.go
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package i2c
import (
"fmt"
"syscall"
"unsafe"
)
const (
I2C_SLAVE = 0x0703 /* Use this slave address */
I2C_SLAVE_FORCE = 0x0706
I2C_SMBUS = 0x0720 /* SMBus transfer */
)
/* i2c_smbus_xfer read or write markers */
const (
I2C_SMBUS_READ = 1
I2C_SMBUS_WRITE = 0
)
/* SMBus transaction types (size parameter in the above functions)
Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
const (
I2C_SMBUS_QUICK = 0
I2C_SMBUS_BYTE = 1
I2C_SMBUS_BYTE_DATA = 2
I2C_SMBUS_WORD_DATA = 3
I2C_SMBUS_PROC_CALL = 4
I2C_SMBUS_BLOCK_DATA = 5
I2C_SMBUS_I2C_BLOCK_BROKEN = 6
I2C_SMBUS_BLOCK_PROC_CALL = 7 /* SMBus 2.0 */
I2C_SMBUS_I2C_BLOCK_DATA = 8
)
/*
func smbusWriteByteData(device *Device, command uint8, value uint8) error {
data := &[4]uint8{value}
return smbusAccess(device,
I2C_SMBUS_WRITE, value,
I2C_SMBUS_BYTE_DATA, uintptr(unsafe.Pointer(data)))
}
*/
type Device struct {
fd int
}
func (device *Device) Close() error {
return syscall.Close(device.fd)
}
func ioctl(a1, a2, a3 uintptr) (r1, r2 uintptr, err error) {
err = nil
r1, r2, errno := syscall.Syscall(syscall.SYS_IOCTL, a1, a2, a3)
if errno != 0 {
err = errno
}
return
}
type smbusIoctlData struct {
readWrite uint8
command uint8
size uint32
data uintptr
}
func (device *Device) smbusAccess(readWrite uint8, command uint8, size int, data uintptr) error {
ioctlData := &smbusIoctlData{readWrite, command, uint32(size), data}
_, _, err := ioctl(
uintptr(device.fd),
uintptr(I2C_SMBUS),
uintptr(unsafe.Pointer(ioctlData)))
return err
}
func (device *Device) setSlaveAddr(addr int) error {
_, _, err := ioctl(uintptr(device.fd), uintptr(I2C_SLAVE), uintptr(addr))
return err
}
func (device *Device) WriteByteData(slave int, command uint8, value uint8) error {
if err := device.setSlaveAddr(slave); err != nil {
return err
}
data := [4]uint8{value, 0, 0, 0}
dataPtr := uintptr(unsafe.Pointer(&data[0]))
if err := device.smbusAccess(I2C_SMBUS_WRITE, command,
I2C_SMBUS_BYTE_DATA, dataPtr); err != nil {
return err
}
return nil
}
func open(path string) (device *Device, err error) {
fd, err := syscall.Open(path, syscall.O_RDWR, 0x644)
if err != nil {
return nil, err
}
device = &Device{fd}
return
}
func Open(busno int) (device *Device, err error) {
// first try
device, err = open(fmt.Sprintf("/dev/i2c/%d", busno))
if err != nil {
// second try
device, err = open(fmt.Sprintf("/dev/i2c-%d", busno))
}
return
}