lsm9ds1: avoid unnecessary heap allocations

This commit is contained in:
Yurii Soldak
2025-10-17 23:49:21 +02:00
committed by Ron Evans
parent 5cb360a4bf
commit 34da2d208a
+35 -28
View File
@@ -7,7 +7,6 @@ import (
"errors" "errors"
"tinygo.org/x/drivers" "tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/legacy"
) )
type AccelRange uint8 type AccelRange uint8
@@ -28,7 +27,7 @@ type Device struct {
accelMultiplier int32 accelMultiplier int32
gyroMultiplier int32 gyroMultiplier int32
magMultiplier int32 magMultiplier int32
buf [6]uint8 buf [7]uint8 // up to 6 bytes for read + 1 byte for the register address
} }
// Configuration for LSM9DS1 device. // Configuration for LSM9DS1 device.
@@ -61,10 +60,15 @@ func New(bus drivers.I2C) *Device {
// Case of boolean false and error nil means I2C is up, // Case of boolean false and error nil means I2C is up,
// but "who am I" responses have unexpected values. // but "who am I" responses have unexpected values.
func (d *Device) Connected() bool { func (d *Device) Connected() bool {
data1, data2 := d.buf[:1], d.buf[1:2] data, err := d.readBytes(d.AccelAddress, WHO_AM_I, 1)
legacy.ReadRegister(d.bus, d.AccelAddress, WHO_AM_I, data1) if err != nil || data[0] != 0x68 {
legacy.ReadRegister(d.bus, d.MagAddress, WHO_AM_I_M, data2) return false
return data1[0] == 0x68 && data2[0] == 0x3D }
data, err = d.readBytes(d.MagAddress, WHO_AM_I_M, 1)
if err != nil || data[0] != 0x3D {
return false
}
return true
} }
// ReadAcceleration reads the current acceleration from the device and returns // ReadAcceleration reads the current acceleration from the device and returns
@@ -72,8 +76,7 @@ func (d *Device) Connected() bool {
// and the sensor is not moving the returned value will be around 1000000 or // and the sensor is not moving the returned value will be around 1000000 or
// -1000000. // -1000000.
func (d *Device) ReadAcceleration() (x, y, z int32, err error) { func (d *Device) ReadAcceleration() (x, y, z int32, err error) {
data := d.buf[:6] data, err := d.readBytes(d.AccelAddress, OUT_X_L_XL, 6)
err = legacy.ReadRegister(d.bus, uint8(d.AccelAddress), OUT_X_L_XL, data)
if err != nil { if err != nil {
return return
} }
@@ -88,8 +91,7 @@ func (d *Device) ReadAcceleration() (x, y, z int32, err error) {
// rotation along one axis and while doing so integrate all values over time, // rotation along one axis and while doing so integrate all values over time,
// you would get a value close to 360000000. // you would get a value close to 360000000.
func (d *Device) ReadRotation() (x, y, z int32, err error) { func (d *Device) ReadRotation() (x, y, z int32, err error) {
data := d.buf[:6] data, err := d.readBytes(d.AccelAddress, OUT_X_L_G, 6)
err = legacy.ReadRegister(d.bus, uint8(d.AccelAddress), OUT_X_L_G, data)
if err != nil { if err != nil {
return return
} }
@@ -102,8 +104,7 @@ func (d *Device) ReadRotation() (x, y, z int32, err error) {
// ReadMagneticField reads the current magnetic field from the device and returns // ReadMagneticField reads the current magnetic field from the device and returns
// it in nT (nanotesla). 1 G (gauss) = 100_000 nT (nanotesla). // it in nT (nanotesla). 1 G (gauss) = 100_000 nT (nanotesla).
func (d *Device) ReadMagneticField() (x, y, z int32, err error) { func (d *Device) ReadMagneticField() (x, y, z int32, err error) {
data := d.buf[:6] data, err := d.readBytes(d.MagAddress, OUT_X_L_M, 6)
err = legacy.ReadRegister(d.bus, uint8(d.MagAddress), OUT_X_L_M, data)
if err != nil { if err != nil {
return return
} }
@@ -115,8 +116,7 @@ func (d *Device) ReadMagneticField() (x, y, z int32, err error) {
// ReadTemperature returns the temperature in Celsius milli degrees (°C/1000) // ReadTemperature returns the temperature in Celsius milli degrees (°C/1000)
func (d *Device) ReadTemperature() (t int32, err error) { func (d *Device) ReadTemperature() (t int32, err error) {
data := d.buf[:2] data, err := d.readBytes(d.AccelAddress, OUT_TEMP_L, 2)
err = legacy.ReadRegister(d.bus, uint8(d.AccelAddress), OUT_TEMP_L, data)
if err != nil { if err != nil {
return return
} }
@@ -167,20 +167,16 @@ func (d *Device) doConfigure(cfg Configuration) (err error) {
d.magMultiplier = 58 d.magMultiplier = 58
} }
data := d.buf[:1]
// Configure accelerometer // Configure accelerometer
// Sample rate & measurement range // Sample rate & measurement range
data[0] = uint8(cfg.AccelSampleRate)<<5 | uint8(cfg.AccelRange)<<3 err = d.writeByte(d.AccelAddress, CTRL_REG6_XL, uint8(cfg.AccelSampleRate)<<5|uint8(cfg.AccelRange)<<3)
err = legacy.WriteRegister(d.bus, d.AccelAddress, CTRL_REG6_XL, data)
if err != nil { if err != nil {
return return
} }
// Configure gyroscope // Configure gyroscope
// Sample rate & measurement range // Sample rate & measurement range
data[0] = uint8(cfg.GyroSampleRate)<<5 | uint8(cfg.GyroRange)<<3 err = d.writeByte(d.AccelAddress, CTRL_REG1_G, uint8(cfg.GyroSampleRate)<<5|uint8(cfg.GyroRange)<<3)
err = legacy.WriteRegister(d.bus, d.AccelAddress, CTRL_REG1_G, data)
if err != nil { if err != nil {
return return
} }
@@ -190,33 +186,44 @@ func (d *Device) doConfigure(cfg Configuration) (err error) {
// Temperature compensation enabled // Temperature compensation enabled
// High-performance mode XY axis // High-performance mode XY axis
// Sample rate // Sample rate
data[0] = 0b10000000 | 0b01000000 | uint8(cfg.MagSampleRate)<<2 err = d.writeByte(d.MagAddress, CTRL_REG1_M, 0b10000000|0b01000000|uint8(cfg.MagSampleRate)<<2)
err = legacy.WriteRegister(d.bus, d.MagAddress, CTRL_REG1_M, data)
if err != nil { if err != nil {
return return
} }
// Measurement range // Measurement range
data[0] = uint8(cfg.MagRange) << 5 err = d.writeByte(d.MagAddress, CTRL_REG2_M, uint8(cfg.MagRange)<<5)
err = legacy.WriteRegister(d.bus, d.MagAddress, CTRL_REG2_M, data)
if err != nil { if err != nil {
return return
} }
// Continuous-conversion mode // Continuous-conversion mode
// https://electronics.stackexchange.com/questions/237397/continuous-conversion-vs-single-conversion-mode // https://electronics.stackexchange.com/questions/237397/continuous-conversion-vs-single-conversion-mode
data[0] = 0b00000000 err = d.writeByte(d.MagAddress, CTRL_REG3_M, 0b00000000)
err = legacy.WriteRegister(d.bus, d.MagAddress, CTRL_REG3_M, data)
if err != nil { if err != nil {
return return
} }
// High-performance mode Z axis // High-performance mode Z axis
data[0] = 0b00001000 err = d.writeByte(d.MagAddress, CTRL_REG4_M, 0b00001000)
err = legacy.WriteRegister(d.bus, d.MagAddress, CTRL_REG4_M, data)
if err != nil { if err != nil {
return return
} }
return nil return nil
} }
func (d *Device) readBytes(addr, reg, size uint8) ([]byte, error) {
d.buf[0] = reg
err := d.bus.Tx(uint16(addr), d.buf[0:1], d.buf[1:size+1])
if err != nil {
return nil, err
}
return d.buf[1 : size+1], nil
}
func (d *Device) writeByte(addr, reg, value uint8) error {
d.buf[0] = reg
d.buf[1] = value
return d.bus.Tx(uint16(addr), d.buf[0:2], nil)
}