Skip to content

Instantly share code, notes, and snippets.

@tetsu-koba
Created January 15, 2018 08:58
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save tetsu-koba/33b339d26ac9c730fb09773acf39eac5 to your computer and use it in GitHub Desktop.
Save tetsu-koba/33b339d26ac9c730fb09773acf39eac5 to your computer and use it in GitHub Desktop.
Golang ioctl sample
Golang ioctl sample
package i2c
import (
"os"
"syscall"
"unsafe"
)
type I2c_client struct {
f *os.File
}
func Open(devname string) (c *I2c_client, err error) {
f, err := os.OpenFile(devname, syscall.O_RDWR, 0666)
if err != nil {
return nil, err
}
return &I2c_client{f: f}, nil
}
func (c *I2c_client) Close() (err error) {
return c.f.Close()
}
func (c *I2c_client) ReadByte(slave uint8, offset uint8) (b uint8, err error) {
buf := []uint8{0}
msg := []i2c_msg{
{
addr: uint16(slave),
flags: 0,
len: 1,
buf: uintptr(unsafe.Pointer(&offset)),
},
{
addr: uint16(slave),
flags: uint16(_I2C_M_RD),
len: uint16(len(buf)),
buf: uintptr(unsafe.Pointer(&buf[0])),
},
}
err = transfer(c.f, &msg[0], len(msg))
if err != nil {
return 0, err
}
return buf[0], nil
}
func (c *I2c_client) ReadWord(slave uint8, offset uint8) (w uint16, err error) {
buf := []uint8{0,0}
msg := []i2c_msg{
{
addr: uint16(slave),
flags: 0,
len: 1,
buf: uintptr(unsafe.Pointer(&offset)),
},
{
addr: uint16(slave),
flags: uint16(_I2C_M_RD),
len: uint16(len(buf)),
buf: uintptr(unsafe.Pointer(&buf[0])),
},
}
err = transfer(c.f, &msg[0], len(msg))
if err != nil {
return 0, err
}
w = (uint16(buf[0]) << 8) | uint16(buf[1])
return
}
func (c *I2c_client) WriteByte(slave uint8, offset uint8, b uint8) (err error) {
buf := []uint8{offset, b}
msg := []i2c_msg{
{
addr: uint16(slave),
flags: 0,
len: uint16(len(buf)),
buf: uintptr(unsafe.Pointer(&buf[0])),
},
}
return transfer(c.f, &msg[0], len(msg))
}
const (
_I2C_RDWR = 0x0707
_I2C_RDRW_IOCTL_MAX_MSGS = 42
_I2C_M_RD = 0x0001
)
type i2c_msg struct {
addr uint16
flags uint16
len uint16
__padding uint16
buf uintptr
}
type i2c_rdwr_ioctl_data struct {
msgs uintptr
nmsgs uint32
}
func transfer(f *os.File, msgs *i2c_msg, n int) (err error) {
data := i2c_rdwr_ioctl_data{
msgs: uintptr(unsafe.Pointer(msgs)),
nmsgs: uint32(n),
}
err = nil
_, _, errno := syscall.Syscall(
syscall.SYS_IOCTL,
uintptr(f.Fd()),
uintptr(_I2C_RDWR),
uintptr(unsafe.Pointer(&data)),
)
if (errno != 0) {
err = errno
}
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment