lis2mdl: better examples showing how to create unit tests

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram
2020-08-27 00:16:15 +02:00
committed by Ron Evans
parent 2ae950e96d
commit 4ad210060f
3 changed files with 79 additions and 39 deletions
+13 -13
View File
@@ -1,7 +1,7 @@
// Package lis2mdl implements a driver for the LIS2MDL, // Package lis2mdl implements a driver for the LIS2MDL,
// a magnetic sensor which is included on BBC micro:bit v1.5. // a magnetic sensor which is included on BBC micro:bit v1.5.
// //
// Datasheet: https://www.st.com/resource/en/datasheet/lsm303agr.pdf // Datasheet: https://www.st.com/resource/en/datasheet/lis2mdl.pdf
// //
package lis2mdl // import "tinygo.org/x/drivers/lis2mdl" package lis2mdl // import "tinygo.org/x/drivers/lis2mdl"
@@ -33,13 +33,13 @@ type Configuration struct {
// //
// This function only creates the Device object, it does not touch the device. // This function only creates the Device object, it does not touch the device.
func New(bus drivers.I2C) Device { func New(bus drivers.I2C) Device {
return Device{bus: bus, Address: MAG_ADDRESS} return Device{bus: bus, Address: ADDRESS}
} }
// Connected returns whether LIS2MDL sensor has been found. // Connected returns whether LIS2MDL sensor has been found.
func (d *Device) Connected() bool { func (d *Device) Connected() bool {
data := []byte{0} data := []byte{0}
d.bus.ReadRegister(uint8(d.Address), MAG_WHO_AM_I, data) d.bus.ReadRegister(uint8(d.Address), WHO_AM_I, data)
return data[0] == 0x40 return data[0] == 0x40
} }
@@ -48,44 +48,44 @@ func (d *Device) Configure(cfg Configuration) {
if cfg.PowerMode != 0 { if cfg.PowerMode != 0 {
d.PowerMode = cfg.PowerMode d.PowerMode = cfg.PowerMode
} else { } else {
d.PowerMode = MAG_POWER_NORMAL d.PowerMode = POWER_NORMAL
} }
if cfg.DataRate != 0 { if cfg.DataRate != 0 {
d.DataRate = cfg.DataRate d.DataRate = cfg.DataRate
} else { } else {
d.DataRate = MAG_DATARATE_100HZ d.DataRate = DATARATE_100HZ
} }
if cfg.SystemMode != 0 { if cfg.SystemMode != 0 {
d.SystemMode = cfg.SystemMode d.SystemMode = cfg.SystemMode
} else { } else {
d.SystemMode = MAG_SYSTEM_CONTINUOUS d.SystemMode = SYSTEM_CONTINUOUS
} }
cmd := []byte{0} cmd := []byte{0}
// reset // reset
cmd[0] = byte(1 << 5) cmd[0] = byte(1 << 5)
d.bus.WriteRegister(uint8(d.Address), MAG_MR_CFG_REG_A, cmd) d.bus.WriteRegister(uint8(d.Address), CFG_REG_A, cmd)
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
// reboot // reboot
cmd[0] = byte(1 << 6) cmd[0] = byte(1 << 6)
d.bus.WriteRegister(uint8(d.Address), MAG_MR_CFG_REG_A, cmd) d.bus.WriteRegister(uint8(d.Address), CFG_REG_A, cmd)
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
// bdu // bdu
cmd[0] = byte(1 << 4) cmd[0] = byte(1 << 4)
d.bus.WriteRegister(uint8(d.Address), MAG_MR_CFG_REG_C, cmd) d.bus.WriteRegister(uint8(d.Address), CFG_REG_C, cmd)
// Temperature compensation is on for magnetic sensor (0x80) // Temperature compensation is on for magnetic sensor (0x80)
cmd[0] = byte(0x80) cmd[0] = byte(0x80)
d.bus.WriteRegister(uint8(d.Address), MAG_MR_CFG_REG_A, cmd) d.bus.WriteRegister(uint8(d.Address), CFG_REG_A, cmd)
// speed // speed
cmd[0] = byte(0x80 | d.DataRate) cmd[0] = byte(0x80 | d.DataRate)
d.bus.WriteRegister(uint8(d.Address), MAG_MR_CFG_REG_A, cmd) d.bus.WriteRegister(uint8(d.Address), CFG_REG_A, cmd)
} }
// ReadMagneticField reads the current magnetic field from the device and returns // ReadMagneticField reads the current magnetic field from the device and returns
@@ -94,11 +94,11 @@ func (d *Device) ReadMagneticField() (x int32, y int32, z int32) {
// turn back on read mode, even though it is supposed to be continuous? // turn back on read mode, even though it is supposed to be continuous?
cmd := []byte{0} cmd := []byte{0}
cmd[0] = byte(0x80 | d.PowerMode<<4 | d.DataRate<<2 | d.SystemMode) cmd[0] = byte(0x80 | d.PowerMode<<4 | d.DataRate<<2 | d.SystemMode)
d.bus.WriteRegister(uint8(d.Address), MAG_MR_CFG_REG_A, cmd) d.bus.WriteRegister(uint8(d.Address), CFG_REG_A, cmd)
time.Sleep(10 * time.Millisecond) time.Sleep(10 * time.Millisecond)
data := make([]byte, 6) data := make([]byte, 6)
d.bus.ReadRegister(uint8(d.Address), MAG_OUT_X_L_M, data) d.bus.ReadRegister(uint8(d.Address), OUTX_L_REG, data)
x = int32(int16((uint16(data[0]) << 8) | uint16(data[1]))) x = int32(int16((uint16(data[0]) << 8) | uint16(data[1])))
y = int32(int16((uint16(data[2]) << 8) | uint16(data[3]))) y = int32(int16((uint16(data[2]) << 8) | uint16(data[3])))
+34 -7
View File
@@ -11,22 +11,49 @@ func TestDefaultI2CAddress(t *testing.T) {
c := qt.New(t) c := qt.New(t)
bus := tester.NewI2CBus(c) bus := tester.NewI2CBus(c)
dev := New(bus) dev := New(bus)
c.Assert(dev.Address, qt.Equals, uint8(MAG_ADDRESS)) c.Assert(dev.Address, qt.Equals, uint8(ADDRESS))
} }
func TestWhoAmI(t *testing.T) { func TestWhoAmI(t *testing.T) {
c := qt.New(t) c := qt.New(t)
bus := tester.NewI2CBus(c) bus := tester.NewI2CBus(c)
fake := tester.NewI2CDevice(c, MAG_ADDRESS) fake := tester.NewI2CDevice(c, ADDRESS)
fake.SetupRegisters(defaultRegisters())
bus.AddDevice(fake) bus.AddDevice(fake)
dev := New(bus) dev := New(bus)
fake.SetupRegisters([]uint8{
0x4F: 0x40,
})
c.Assert(dev.Connected(), qt.Equals, true) c.Assert(dev.Connected(), qt.Equals, true)
fake.SetupRegister(0x4F, 0x99) fake.SetupRegister(WHO_AM_I, 0x99)
c.Assert(dev.Connected(), qt.Equals, false) c.Assert(dev.Connected(), qt.Equals, false)
} }
// defaultRegisters returns the default values for all of the device's registers.
// see table 22 on page 27 of the datasheet.
func defaultRegisters() []uint8 {
return []uint8{
OFFSET_X_REG_L: 0,
OFFSET_X_REG_H: 0,
OFFSET_Y_REG_L: 0,
OFFSET_Y_REG_H: 0,
OFFSET_Z_REG_L: 0,
OFFSET_Z_REG_H: 0,
WHO_AM_I: 0x40,
CFG_REG_A: 0x03,
CFG_REG_B: 0,
CFG_REG_C: 0,
INT_CRTL_REG: 0xE0,
INT_SOURCE_REG: 0,
INT_THS_L_REG: 0,
INT_THS_H_REG: 0,
STATUS_REG: 0,
OUTX_L_REG: 0,
OUTX_H_REG: 0,
OUTY_L_REG: 0,
OUTY_H_REG: 0,
OUTZ_L_REG: 0,
OUTZ_H_REG: 0,
TEMP_OUT_L_REG: 0,
TEMP_OUT_H_REG: 0,
}
}
+32 -19
View File
@@ -2,31 +2,44 @@ package lis2mdl
const ( const (
// Constants/addresses used for I2C. // Constants/addresses used for I2C.
MAG_ADDRESS = 0x1E ADDRESS = 0x1E
// magnetic sensor registers. // magnetic sensor registers.
MAG_WHO_AM_I = 0x4F OFFSET_X_REG_L = 0x45
MAG_MR_CFG_REG_A = 0x60 OFFSET_X_REG_H = 0x46
MAG_MR_CFG_REG_B = 0x61 OFFSET_Y_REG_L = 0x47
MAG_MR_CFG_REG_C = 0x62 OFFSET_Y_REG_H = 0x48
MAG_OUT_X_L_M = 0x68 OFFSET_Z_REG_L = 0x49
MAG_OUT_X_H_M = 0x69 OFFSET_Z_REG_H = 0x4A
MAG_OUT_Y_L_M = 0x6A WHO_AM_I = 0x4F
MAG_OUT_Y_H_M = 0x6B CFG_REG_A = 0x60
MAG_OUT_Z_L_M = 0x6C CFG_REG_B = 0x61
MAG_OUT_Z_H_M = 0x6D CFG_REG_C = 0x62
INT_CRTL_REG = 0x63
INT_SOURCE_REG = 0x64
INT_THS_L_REG = 0x65
INT_THS_H_REG = 0x66
STATUS_REG = 0x67
OUTX_L_REG = 0x68
OUTX_H_REG = 0x69
OUTY_L_REG = 0x6A
OUTY_H_REG = 0x6B
OUTZ_L_REG = 0x6C
OUTZ_H_REG = 0x6D
TEMP_OUT_L_REG = 0x6E
TEMP_OUT_H_REG = 0x6F
// magnetic sensor power mode. // magnetic sensor power mode.
MAG_POWER_NORMAL = 0x00 // default POWER_NORMAL = 0x00 // default
MAG_POWER_LOW = 0x01 POWER_LOW = 0x01
// magnetic sensor operate mode. // magnetic sensor operate mode.
MAG_SYSTEM_CONTINUOUS = 0x00 // default SYSTEM_CONTINUOUS = 0x00 // default
MAG_SYSTEM_SINGLE = 0x01 SYSTEM_SINGLE = 0x01
// magnetic sensor data rate // magnetic sensor data rate
MAG_DATARATE_10HZ = 0x00 // default DATARATE_10HZ = 0x00 // default
MAG_DATARATE_20HZ = 0x01 DATARATE_20HZ = 0x01
MAG_DATARATE_50HZ = 0x02 DATARATE_50HZ = 0x02
MAG_DATARATE_100HZ = 0x03 DATARATE_100HZ = 0x03
) )