// Type representing a bus connection
// Data that is passed to/from ioctl calls
type i2c_smbus_ioctl_data struct {
// Constants used by ioctl, from i2c-dev.h
// Create an I2cBus for the specified address
func CreateBus(address uint8) *I2cBus {
file, err := os.OpenFile("/dev/i2c-0", os.O_RDWR, os.ModeExclusive)
fmt.Println("About to open Bus fd ", file.Fd(), " IOCTL ", I2C_SLAVE, " Arg ", address)
_, _, er := syscall.Syscall(syscall.SYS_IOCTL, uintptr(file.Fd()), I2C_SLAVE, uintptr(address))
func (bus *I2cBus) Close() {
if err := bus.fd.Close(); err != nil {
// Write 1 byte onto the bus
func (bus *I2cBus) Write8(command, data uint8) {
// i2c_smbus_access(file,I2C_SMBUS_WRITE,command,I2C_SMBUS_BYTE_DATA, &data);
busData := i2c_smbus_ioctl_data{
read_write: I2C_SMBUS_WRITE,
size: I2C_SMBUS_BYTE_DATA,
fmt.Println("About to Write8 ", bus.fd.Fd(), " IOCTL ", I2C_SMBUS, " Command ", command, " Data ", data)
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(bus.fd.Fd()), I2C_SMBUS, uintptr(unsafe.Pointer(&busData)))
panic(syscall.Errno(err))
// Read 1 byte from the bus
func (bus *I2cBus) Read8(command uint8) uint8 {
// i2c_smbus_access(file,I2C_SMBUS_READ,command,I2C_SMBUS_BYTE_DATA,&data)
busData := i2c_smbus_ioctl_data{
read_write: I2C_SMBUS_READ,
size: I2C_SMBUS_BYTE_DATA,
fmt.Println("About to Read8 ", bus.fd.Fd(), " IOCTL ", I2C_SMBUS, " Command ", command)
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(bus.fd.Fd()), I2C_SMBUS, uintptr(unsafe.Pointer(&busData)))
panic(syscall.Errno(err))