gobot.io/x/gobot@v1.16.0/drivers/i2c/i2c.go (about) 1 package i2c 2 3 import ( 4 "errors" 5 "io" 6 "sync" 7 ) 8 9 const ( 10 // Error event 11 Error = "error" 12 ) 13 14 const ( 15 // BusNotInitialized is the initial value for a bus 16 BusNotInitialized = -1 17 18 // AddressNotInitialized is the initial value for an address 19 AddressNotInitialized = -1 20 ) 21 22 var ( 23 ErrEncryptedBytes = errors.New("Encrypted bytes") 24 ErrNotEnoughBytes = errors.New("Not enough bytes read") 25 ErrNotReady = errors.New("Device is not ready") 26 ErrInvalidPosition = errors.New("Invalid position value") 27 ) 28 29 type bitState uint8 30 31 const ( 32 clear bitState = 0x00 33 set = 0x01 34 ) 35 36 type I2cOperations interface { 37 io.ReadWriteCloser 38 ReadByte() (val byte, err error) 39 ReadByteData(reg uint8) (val uint8, err error) 40 ReadWordData(reg uint8) (val uint16, err error) 41 WriteByte(val byte) (err error) 42 WriteByteData(reg uint8, val uint8) (err error) 43 WriteWordData(reg uint8, val uint16) (err error) 44 WriteBlockData(reg uint8, b []byte) (err error) 45 } 46 47 // I2cDevice is the interface to a specific i2c bus 48 type I2cDevice interface { 49 I2cOperations 50 SetAddress(int) error 51 } 52 53 // Connector lets Adaptors provide the interface for Drivers 54 // to get access to the I2C buses on platforms that support I2C. 55 type Connector interface { 56 // GetConnection returns a connection to device at the specified address 57 // and bus. Bus numbering starts at index 0, the range of valid buses is 58 // platform specific. 59 GetConnection(address int, bus int) (device Connection, err error) 60 61 // GetDefaultBus returns the default I2C bus index 62 GetDefaultBus() int 63 } 64 65 // Connection is a connection to an I2C device with a specified address 66 // on a specific bus. Used as an alternative to the I2c interface. 67 // Implements I2cOperations to talk to the device, wrapping the 68 // calls in SetAddress to always target the specified device. 69 // Provided by an Adaptor by implementing the I2cConnector interface. 70 type Connection I2cOperations 71 72 type i2cConnection struct { 73 bus I2cDevice 74 address int 75 mutex *sync.Mutex 76 } 77 78 // NewConnection creates and returns a new connection to a specific 79 // i2c device on a bus and address. 80 func NewConnection(bus I2cDevice, address int) (connection *i2cConnection) { 81 return &i2cConnection{bus: bus, address: address, mutex: &sync.Mutex{}} 82 } 83 84 // Read data from an i2c device. 85 func (c *i2cConnection) Read(data []byte) (read int, err error) { 86 c.mutex.Lock() 87 defer c.mutex.Unlock() 88 89 if err = c.bus.SetAddress(c.address); err != nil { 90 return 0, err 91 } 92 read, err = c.bus.Read(data) 93 return 94 } 95 96 // Write data to an i2c device. 97 func (c *i2cConnection) Write(data []byte) (written int, err error) { 98 c.mutex.Lock() 99 defer c.mutex.Unlock() 100 101 if err = c.bus.SetAddress(c.address); err != nil { 102 return 0, err 103 } 104 written, err = c.bus.Write(data) 105 return 106 } 107 108 // Close connection to i2c device. 109 func (c *i2cConnection) Close() error { 110 c.mutex.Lock() 111 defer c.mutex.Unlock() 112 113 return c.bus.Close() 114 } 115 116 // ReadByte reads a single byte from the i2c device. 117 func (c *i2cConnection) ReadByte() (val byte, err error) { 118 c.mutex.Lock() 119 defer c.mutex.Unlock() 120 121 if err := c.bus.SetAddress(c.address); err != nil { 122 return 0, err 123 } 124 return c.bus.ReadByte() 125 } 126 127 // ReadByteData reads a byte value for a register on the i2c device. 128 func (c *i2cConnection) ReadByteData(reg uint8) (val uint8, err error) { 129 c.mutex.Lock() 130 defer c.mutex.Unlock() 131 132 if err := c.bus.SetAddress(c.address); err != nil { 133 return 0, err 134 } 135 return c.bus.ReadByteData(reg) 136 } 137 138 // ReadWordData reads a word value for a register on the i2c device. 139 func (c *i2cConnection) ReadWordData(reg uint8) (val uint16, err error) { 140 c.mutex.Lock() 141 defer c.mutex.Unlock() 142 143 if err := c.bus.SetAddress(c.address); err != nil { 144 return 0, err 145 } 146 return c.bus.ReadWordData(reg) 147 } 148 149 // WriteByte writes a single byte to the i2c device. 150 func (c *i2cConnection) WriteByte(val byte) (err error) { 151 c.mutex.Lock() 152 defer c.mutex.Unlock() 153 154 if err := c.bus.SetAddress(c.address); err != nil { 155 return err 156 } 157 return c.bus.WriteByte(val) 158 } 159 160 // WriteByteData writes a byte value to a register on the i2c device. 161 func (c *i2cConnection) WriteByteData(reg uint8, val uint8) (err error) { 162 c.mutex.Lock() 163 defer c.mutex.Unlock() 164 165 if err := c.bus.SetAddress(c.address); err != nil { 166 return err 167 } 168 return c.bus.WriteByteData(reg, val) 169 } 170 171 // WriteWordData writes a word value to a register on the i2c device. 172 func (c *i2cConnection) WriteWordData(reg uint8, val uint16) (err error) { 173 c.mutex.Lock() 174 defer c.mutex.Unlock() 175 176 if err := c.bus.SetAddress(c.address); err != nil { 177 return err 178 } 179 return c.bus.WriteWordData(reg, val) 180 } 181 182 // WriteBlockData writes a block of bytes to a register on the i2c device. 183 func (c *i2cConnection) WriteBlockData(reg uint8, b []byte) (err error) { 184 c.mutex.Lock() 185 defer c.mutex.Unlock() 186 187 if err := c.bus.SetAddress(c.address); err != nil { 188 return err 189 } 190 return c.bus.WriteBlockData(reg, b) 191 } 192 193 // setBit is used to set a bit at a given position to 1. 194 func setBit(n uint8, pos uint8) uint8 { 195 n |= (1 << pos) 196 return n 197 } 198 199 // clearBit is used to set a bit at a given position to 0. 200 func clearBit(n uint8, pos uint8) uint8 { 201 mask := ^uint8(1 << pos) 202 n &= mask 203 return n 204 }