gobot.io/x/gobot@v1.16.0/platforms/digispark/digispark_i2c.go (about) 1 package digispark 2 3 import ( 4 "errors" 5 "fmt" 6 ) 7 8 type digisparkI2cConnection struct { 9 address uint8 10 adaptor *Adaptor 11 } 12 13 // NewDigisparkI2cConnection creates an i2c connection to an i2c device at 14 // the specified address 15 func NewDigisparkI2cConnection(adaptor *Adaptor, address uint8) (connection *digisparkI2cConnection) { 16 return &digisparkI2cConnection{adaptor: adaptor, address: address} 17 } 18 19 // Init makes sure that the i2c device is already initialized 20 func (c *digisparkI2cConnection) Init() (err error) { 21 if !c.adaptor.i2c { 22 if err = c.adaptor.littleWire.i2cInit(); err != nil { 23 return 24 } 25 c.adaptor.i2c = true 26 } 27 return 28 } 29 30 // Test tests i2c connection with the given address 31 func (c *digisparkI2cConnection) Test(address uint8) error { 32 if !c.adaptor.i2c { 33 return errors.New("Digispark i2c not initialized") 34 } 35 return c.adaptor.littleWire.i2cStart(address, 0) 36 } 37 38 // UpdateDelay updates i2c signal delay amount; tune if neccessary to fit your requirements 39 func (c *digisparkI2cConnection) UpdateDelay(duration uint) error { 40 if !c.adaptor.i2c { 41 return errors.New("Digispark i2c not initialized") 42 } 43 return c.adaptor.littleWire.i2cUpdateDelay(duration) 44 } 45 46 // Read tries to read a full buffer from the i2c device. 47 // Returns an empty array if the response from the board has timed out. 48 func (c *digisparkI2cConnection) Read(b []byte) (countRead int, err error) { 49 if !c.adaptor.i2c { 50 err = errors.New("Digispark i2c not initialized") 51 return 52 } 53 if err = c.adaptor.littleWire.i2cStart(c.address, 1); err != nil { 54 return 55 } 56 l := 8 57 stop := uint8(0) 58 59 for stop == 0 { 60 if countRead+l >= len(b) { 61 l = len(b) - countRead 62 stop = 1 63 } 64 if err = c.adaptor.littleWire.i2cRead(b[countRead:countRead+l], l, stop); err != nil { 65 return 66 } 67 countRead += l 68 } 69 return 70 } 71 72 // Write writes the buffer content in data to the i2c device. 73 func (c *digisparkI2cConnection) Write(data []byte) (countWritten int, err error) { 74 if !c.adaptor.i2c { 75 err = errors.New("Digispark i2c not initialized") 76 return 77 } 78 if err = c.adaptor.littleWire.i2cStart(c.address, 0); err != nil { 79 return 80 } 81 l := 4 82 stop := uint8(0) 83 84 for stop == 0 { 85 if countWritten+l >= len(data) { 86 l = len(data) - countWritten 87 stop = 1 88 } 89 if err = c.adaptor.littleWire.i2cWrite(data[countWritten:countWritten+l], l, stop); err != nil { 90 return 91 } 92 countWritten += l 93 } 94 return 95 } 96 97 // Close do nothing than return nil. 98 func (c *digisparkI2cConnection) Close() error { 99 return nil 100 } 101 102 // ReadByte reads one byte from the i2c device. 103 func (c *digisparkI2cConnection) ReadByte() (val byte, err error) { 104 buf := []byte{0} 105 if err = c.readAndCheckCount(buf); err != nil { 106 return 107 } 108 val = buf[0] 109 return 110 } 111 112 // ReadByteData reads one byte of the given register address from the i2c device. 113 func (c *digisparkI2cConnection) ReadByteData(reg uint8) (val uint8, err error) { 114 if err = c.WriteByte(reg); err != nil { 115 return 116 } 117 return c.ReadByte() 118 } 119 120 // ReadWordData reads two bytes of the given register address from the i2c device. 121 func (c *digisparkI2cConnection) ReadWordData(reg uint8) (val uint16, err error) { 122 if err = c.WriteByte(reg); err != nil { 123 return 124 } 125 126 buf := []byte{0, 0} 127 if err = c.readAndCheckCount(buf); err != nil { 128 return 129 } 130 low, high := buf[0], buf[1] 131 132 val = (uint16(high) << 8) | uint16(low) 133 return 134 } 135 136 // WriteByte writes one byte to the i2c device. 137 func (c *digisparkI2cConnection) WriteByte(val byte) (err error) { 138 buf := []byte{val} 139 return c.writeAndCheckCount(buf) 140 } 141 142 // WriteByteData writes one byte to the given register address of the i2c device. 143 func (c *digisparkI2cConnection) WriteByteData(reg uint8, val byte) (err error) { 144 buf := []byte{reg, val} 145 return c.writeAndCheckCount(buf) 146 } 147 148 // WriteWordData writes two bytes to the given register address of the i2c device. 149 func (c *digisparkI2cConnection) WriteWordData(reg uint8, val uint16) (err error) { 150 low := uint8(val & 0xff) 151 high := uint8((val >> 8) & 0xff) 152 buf := []byte{reg, low, high} 153 return c.writeAndCheckCount(buf) 154 } 155 156 // WriteBlockData writes a block of maximum 32 bytes to the given register address of the i2c device. 157 func (c *digisparkI2cConnection) WriteBlockData(reg uint8, data []byte) (err error) { 158 if len(data) > 32 { 159 data = data[:32] 160 } 161 162 buf := make([]byte, len(data)+1) 163 copy(buf[:1], data) 164 buf[0] = reg 165 return c.writeAndCheckCount(buf) 166 } 167 168 func (c *digisparkI2cConnection) writeAndCheckCount(buf []byte) (err error) { 169 countWritten := 0 170 if countWritten, err = c.Write(buf); err != nil { 171 return 172 } 173 expectedCount := len(buf) 174 if countWritten != expectedCount { 175 err = fmt.Errorf("Digispark i2c write %d bytes, expected %d bytes", countWritten, expectedCount) 176 return 177 } 178 return 179 } 180 181 func (c *digisparkI2cConnection) readAndCheckCount(buf []byte) (err error) { 182 countRead := 0 183 if countRead, err = c.Read(buf); err != nil { 184 return 185 } 186 expectedCount := len(buf) 187 if countRead != expectedCount { 188 err = fmt.Errorf("Digispark i2c read %d bytes, expected %d bytes", countRead, expectedCount) 189 return 190 } 191 return 192 }