Skip to content

Commit c6f380c

Browse files
committed
lsm9ds1: avoid unnecessary heap allocations
1 parent 297ad41 commit c6f380c

File tree

1 file changed

+34
-27
lines changed

1 file changed

+34
-27
lines changed

lsm9ds1/lsm9ds1.go

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"errors"
88

99
"tinygo.org/x/drivers"
10-
"tinygo.org/x/drivers/internal/legacy"
1110
)
1211

1312
type AccelRange uint8
@@ -28,7 +27,7 @@ type Device struct {
2827
accelMultiplier int32
2928
gyroMultiplier int32
3029
magMultiplier int32
31-
buf [6]uint8
30+
buf [7]uint8 // up to 6 bytes for read + 1 byte for the register address
3231
}
3332

3433
// Configuration for LSM9DS1 device.
@@ -61,9 +60,14 @@ func New(bus drivers.I2C) *Device {
6160
// Case of boolean false and error nil means I2C is up,
6261
// but "who am I" responses have unexpected values.
6362
func (d *Device) Connected() bool {
64-
data1, data2 := d.buf[:1], d.buf[1:2]
65-
legacy.ReadRegister(d.bus, d.AccelAddress, WHO_AM_I, data1)
66-
legacy.ReadRegister(d.bus, d.MagAddress, WHO_AM_I_M, data2)
63+
data1, err := d.readBytes(d.AccelAddress, WHO_AM_I, 1)
64+
if err != nil {
65+
return false
66+
}
67+
data2, err := d.readBytes(d.MagAddress, WHO_AM_I_M, 1)
68+
if err != nil {
69+
return false
70+
}
6771
return data1[0] == 0x68 && data2[0] == 0x3D
6872
}
6973

@@ -72,8 +76,7 @@ func (d *Device) Connected() bool {
7276
// and the sensor is not moving the returned value will be around 1000000 or
7377
// -1000000.
7478
func (d *Device) ReadAcceleration() (x, y, z int32, err error) {
75-
data := d.buf[:6]
76-
err = legacy.ReadRegister(d.bus, uint8(d.AccelAddress), OUT_X_L_XL, data)
79+
data, err := d.readBytes(d.AccelAddress, OUT_X_L_XL, 6)
7780
if err != nil {
7881
return
7982
}
@@ -88,8 +91,7 @@ func (d *Device) ReadAcceleration() (x, y, z int32, err error) {
8891
// rotation along one axis and while doing so integrate all values over time,
8992
// you would get a value close to 360000000.
9093
func (d *Device) ReadRotation() (x, y, z int32, err error) {
91-
data := d.buf[:6]
92-
err = legacy.ReadRegister(d.bus, uint8(d.AccelAddress), OUT_X_L_G, data)
94+
data, err := d.readBytes(d.AccelAddress, OUT_X_L_G, 6)
9395
if err != nil {
9496
return
9597
}
@@ -102,8 +104,7 @@ func (d *Device) ReadRotation() (x, y, z int32, err error) {
102104
// ReadMagneticField reads the current magnetic field from the device and returns
103105
// it in nT (nanotesla). 1 G (gauss) = 100_000 nT (nanotesla).
104106
func (d *Device) ReadMagneticField() (x, y, z int32, err error) {
105-
data := d.buf[:6]
106-
err = legacy.ReadRegister(d.bus, uint8(d.MagAddress), OUT_X_L_M, data)
107+
data, err := d.readBytes(d.MagAddress, OUT_X_L_M, 6)
107108
if err != nil {
108109
return
109110
}
@@ -115,8 +116,7 @@ func (d *Device) ReadMagneticField() (x, y, z int32, err error) {
115116

116117
// ReadTemperature returns the temperature in Celsius milli degrees (°C/1000)
117118
func (d *Device) ReadTemperature() (t int32, err error) {
118-
data := d.buf[:2]
119-
err = legacy.ReadRegister(d.bus, uint8(d.AccelAddress), OUT_TEMP_L, data)
119+
data, err := d.readBytes(d.AccelAddress, OUT_TEMP_L, 2)
120120
if err != nil {
121121
return
122122
}
@@ -167,20 +167,16 @@ func (d *Device) doConfigure(cfg Configuration) (err error) {
167167
d.magMultiplier = 58
168168
}
169169

170-
data := d.buf[:1]
171-
172170
// Configure accelerometer
173171
// Sample rate & measurement range
174-
data[0] = uint8(cfg.AccelSampleRate)<<5 | uint8(cfg.AccelRange)<<3
175-
err = legacy.WriteRegister(d.bus, d.AccelAddress, CTRL_REG6_XL, data)
172+
err = d.writeByte(d.AccelAddress, CTRL_REG6_XL, uint8(cfg.AccelSampleRate)<<5|uint8(cfg.AccelRange)<<3)
176173
if err != nil {
177174
return
178175
}
179176

180177
// Configure gyroscope
181178
// Sample rate & measurement range
182-
data[0] = uint8(cfg.GyroSampleRate)<<5 | uint8(cfg.GyroRange)<<3
183-
err = legacy.WriteRegister(d.bus, d.AccelAddress, CTRL_REG1_G, data)
179+
err = d.writeByte(d.AccelAddress, CTRL_REG1_G, uint8(cfg.GyroSampleRate)<<5|uint8(cfg.GyroRange)<<3)
184180
if err != nil {
185181
return
186182
}
@@ -190,33 +186,44 @@ func (d *Device) doConfigure(cfg Configuration) (err error) {
190186
// Temperature compensation enabled
191187
// High-performance mode XY axis
192188
// Sample rate
193-
data[0] = 0b10000000 | 0b01000000 | uint8(cfg.MagSampleRate)<<2
194-
err = legacy.WriteRegister(d.bus, d.MagAddress, CTRL_REG1_M, data)
189+
err = d.writeByte(d.MagAddress, CTRL_REG1_M, 0b10000000|0b01000000|uint8(cfg.MagSampleRate)<<2)
195190
if err != nil {
196191
return
197192
}
198193

199194
// Measurement range
200-
data[0] = uint8(cfg.MagRange) << 5
201-
err = legacy.WriteRegister(d.bus, d.MagAddress, CTRL_REG2_M, data)
195+
err = d.writeByte(d.MagAddress, CTRL_REG2_M, uint8(cfg.MagRange)<<5)
202196
if err != nil {
203197
return
204198
}
205199

206200
// Continuous-conversion mode
207201
// https://electronics.stackexchange.com/questions/237397/continuous-conversion-vs-single-conversion-mode
208-
data[0] = 0b00000000
209-
err = legacy.WriteRegister(d.bus, d.MagAddress, CTRL_REG3_M, data)
202+
err = d.writeByte(d.MagAddress, CTRL_REG3_M, 0b00000000)
210203
if err != nil {
211204
return
212205
}
213206

214207
// High-performance mode Z axis
215-
data[0] = 0b00001000
216-
err = legacy.WriteRegister(d.bus, d.MagAddress, CTRL_REG4_M, data)
208+
err = d.writeByte(d.MagAddress, CTRL_REG4_M, 0b00001000)
217209
if err != nil {
218210
return
219211
}
220212

221213
return nil
222214
}
215+
216+
func (d *Device) readBytes(addr, reg, size uint8) ([]byte, error) {
217+
d.buf[0] = reg
218+
err := d.bus.Tx(uint16(addr), d.buf[0:1], d.buf[1:size+1])
219+
if err != nil {
220+
return nil, err
221+
}
222+
return d.buf[1 : size+1], nil
223+
}
224+
225+
func (d *Device) writeByte(addr, reg, value uint8) error {
226+
d.buf[0] = reg
227+
d.buf[1] = value
228+
return d.bus.Tx(uint16(addr), d.buf[0:2], nil)
229+
}

0 commit comments

Comments
 (0)