From eef03917ab9cb8f4acd7758d84f746c16582d921 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 21 Jun 2023 10:49:12 +0200 Subject: [PATCH] bma42x: add new BMA421/BMA425 driver I wrote this for the PineTime, and all available sensors (accelerometer, step counter, temperature sensor) do work. This commit also includes two "configuration files", that actually appear to be firmware files to run on the accelerometer for special features like step counting. I'm not sure where they originally came for, and I don't know the copyright status of them. However, Bosch has open-sourced the BMA423 driver which includes a similar binary blob and the InfiniTime and Wasp-OS projects have been shipping these blobs without issues, so I think it's reasonably safe to include these binary blobs directly in the source. --- bma42x/bma421-config-waspos.bin | Bin 0 -> 6145 bytes bma42x/bma425-config-waspos.bin | Bin 0 -> 6145 bytes bma42x/bma42x.go | 352 ++++++++++++++++++++++++++++++++ bma42x/registers.go | 73 +++++++ examples/bma42x/main.go | 54 +++++ smoketest.sh | 1 + 6 files changed, 480 insertions(+) create mode 100644 bma42x/bma421-config-waspos.bin create mode 100644 bma42x/bma425-config-waspos.bin create mode 100644 bma42x/bma42x.go create mode 100644 bma42x/registers.go create mode 100644 examples/bma42x/main.go diff --git a/bma42x/bma421-config-waspos.bin b/bma42x/bma421-config-waspos.bin new file mode 100644 index 0000000000000000000000000000000000000000..cc49293f460d903aa63175fe5204af813d765a5e GIT binary patch literal 6145 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 1 { + // Expected either 0 ("not_init") or 1 ("init_ok"). + return errInitFailed + } + if time.Since(start) >= 150*time.Millisecond { + // The datasheet says initialization should not take longer than + return errTimeout + } + // Don't bother the chip all the time while it's initializing. + time.Sleep(50 * time.Microsecond) + } + + if config.Features&FeatureStepCounting != 0 { + // Enable step counter. + // TODO: support step counter parameters. + var buf [71]byte + buf[0] = _FEATURES_IN // prefix buf with the command + data := buf[1:] + err = d.readn(_FEATURES_IN, data) + if err != nil { + return err + } + data[0x3A+1] |= 0x10 // enable step counting by setting a magical bit + err = d.bus.Tx(uint16(d.address), buf[:], nil) + if err != nil { + return err + } + } + + // Enable the accelerometer. + err = d.write1(_PWR_CTRL, 0x04) + if err != nil { + return err + } + + // Configure accelerometer for low power usage: + // acc_perf_mode=0 (power saving enabled) + // acc_bwp=osr4_avg1 (no averaging) + // acc_odr=50Hz (50Hz sampling interval, enough for the step counter) + const accelConf = 0x00<<7 | 0x00<<4 | 0x07<<0 + err = d.write1(_ACC_CONF, accelConf) + if err != nil { + return err + } + + // Reduce current consumption. + // With power saving enabled (and the above ACC_CONF) the chip consumes only + // 14µA. + err = d.write1(_PWR_CONF, 0x03) + if err != nil { + return err + } + + return nil +} + +func (d *Device) Update(which drivers.Measurement) error { + // TODO: combine temperature and step counter into a single read. + if which&drivers.Temperature != 0 { + val, err := d.read1(_TEMPERATURE) + if err != nil { + return err + } + d.combinedTempSteps[4] = val + } + if which&drivers.Acceleration != 0 { + // The acceleration data is stored in DATA8 through DATA13 as 3 12-bit + // values. + err := d.readn(_DATA_8, d.accelData[:]) // ACC_X(LSB) + if err != nil { + return err + } + err = d.readn(_STEP_COUNTER_0, d.combinedTempSteps[:4]) + if err != nil { + return err + } + } + return nil +} + +// Temperature returns the last read temperature in celsius milli degrees (1°C +// is 1000). +func (d *Device) Temperature() int32 { + // The temperature value is a two's complement number (meaning: signed) in + // units of 1 kelvin, with 0 being 23°C. + return (int32(int8(d.combinedTempSteps[4])) + 23) * 1000 +} + +// Acceleration returns the last read acceleration in µg (micro-gravity). +// When one of the axes is pointing straight to Earth and the sensor is not +// moving the returned value will be around 1000000 or -1000000. +func (d *Device) Acceleration() (x, y, z int32) { + // Combine raw data from d.accelData (stored as 12-bit signed values) into a + // number (0..4095): + x = int32(d.accelData[0])>>4 | int32(d.accelData[1])<<4 + y = int32(d.accelData[2])>>4 | int32(d.accelData[3])<<4 + z = int32(d.accelData[4])>>4 | int32(d.accelData[5])<<4 + // Sign extend this number to -2048..2047: + x = (x << 20) >> 20 + y = (y << 20) >> 20 + z = (z << 20) >> 20 + // Scale from -512..511 to -1000_000..998_046. + // Or, at the maximum range (4g), from -2048..2047 to -2000_000..3998_046. + // The formula derived as follows (where 512 is the expected value at 1g): + // x = x * 1000_000 / 512 + // x = x * (1000_000/64) / (512/64) + // x = x * 15625 / 8 + x = x * 15625 / 8 + y = y * 15625 / 8 + z = z * 15625 / 8 + return +} + +// Steps returns the number of steps counted since the BMA42x sensor was +// initialized. +func (d *Device) Steps() (steps uint32) { + steps |= uint32(d.combinedTempSteps[0]) << 0 + steps |= uint32(d.combinedTempSteps[1]) << 8 + steps |= uint32(d.combinedTempSteps[2]) << 16 + steps |= uint32(d.combinedTempSteps[3]) << 24 + return +} + +func (d *Device) read1(register uint8) (uint8, error) { + d.dataBuf[0] = register + err := d.bus.Tx(uint16(d.address), d.dataBuf[:1], d.dataBuf[1:2]) + return d.dataBuf[1], err +} + +func (d *Device) readn(register uint8, data []byte) error { + d.dataBuf[0] = register + return d.bus.Tx(uint16(d.address), d.dataBuf[:1], data) +} + +func (d *Device) write1(register uint8, data uint8) error { + d.dataBuf[0] = register + d.dataBuf[1] = data + return d.bus.Tx(uint16(d.address), d.dataBuf[:2], nil) +} + +func unsafeStringToSlice(s string) []byte { + // TODO: use unsafe.Slice(unsafe.StringData(...)) once we require Go 1.20. + sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) + return unsafe.Slice((*byte)(unsafe.Pointer(sh.Data)), len(s)) +} + +func identifyChip(chipID uint8) DeviceType { + switch chipID { + case 0x11: + return DeviceBMA421 + case 0x13: + return DeviceBMA425 + default: + return noDevice + } +} diff --git a/bma42x/registers.go b/bma42x/registers.go new file mode 100644 index 0000000..aea75d5 --- /dev/null +++ b/bma42x/registers.go @@ -0,0 +1,73 @@ +package bma42x + +const ( + // I2C registers + _CHIP_ID = 0x00 + _ERR_REG = 0x02 + _STATUS = 0x03 + _DATA_0 = 0x0A + _DATA_1 = 0x0B + _DATA_2 = 0x0C + _DATA_3 = 0x0D + _DATA_4 = 0x0E + _DATA_5 = 0x0F + _DATA_6 = 0x10 + _DATA_7 = 0x11 + _DATA_8 = 0x12 + _DATA_9 = 0x13 + _DATA_10 = 0x14 + _DATA_11 = 0x15 + _DATA_12 = 0x16 + _DATA_13 = 0x17 + _SENSORTIME_0 = 0x18 + _SENSORTIME_1 = 0x19 + _SENSORTIME_2 = 0x1A + _EVENT = 0x1B + _INT_STATUS_0 = 0x1C + _INT_STATUS_1 = 0x1D + _STEP_COUNTER_0 = 0x1E + _STEP_COUNTER_1 = 0x1F + _STEP_COUNTER_2 = 0x20 + _STEP_COUNTER_3 = 0x21 + _TEMPERATURE = 0x22 + _FIFO_LENGTH_0 = 0x24 + _FIFO_LENGTH_1 = 0x25 + _FIFO_DATA = 0x26 + _ACTIVITY_TYPE = 0x27 + _INTERNAL_STATUS = 0x2A + _ACC_CONF = 0x40 + _ACC_RANGE = 0x41 + _AUX_CONF = 0x44 + _FIFO_DOWNS = 0x45 + _FIFO_WTM_0 = 0x46 + _FIFO_WTM_1 = 0x47 + _FIFO_CONFIG_0 = 0x48 + _FIFO_CONFIG_1 = 0x49 + _AUX_DEV_ID = 0x4B + _AUX_IF_CONF = 0x4C + _AUX_RD_ADDR = 0x4D + _AUX_WR_ADDR = 0x4E + _AUX_WR_DATA = 0x4F + _INT1_IO_CTRL = 0x53 + _INT2_IO_CTRL = 0x54 + _INT_LATCH = 0x55 + _INT1_MAP = 0x56 + _INT2_MAP = 0x57 + _INT_MAP_DATA = 0x58 + _INIT_CTRL = 0x59 + _FEATURES_IN = 0x5E + _INTERNAL_ERROR = 0x5F + _NVM_CONF = 0x6A + _IF_CONF = 0x6B + _ACC_SELF_TEST = 0x6D + _NV_CONF = 0x70 + _OFFSET_0 = 0x71 + _OFFSET_1 = 0x72 + _OFFSET_2 = 0x73 + _PWR_CONF = 0x7C + _PWR_CTRL = 0x7D + _CMD = 0x7E + + // Commands send to regCommand. + cmdSoftReset = 0xB6 +) diff --git a/examples/bma42x/main.go b/examples/bma42x/main.go new file mode 100644 index 0000000..8f0b4a0 --- /dev/null +++ b/examples/bma42x/main.go @@ -0,0 +1,54 @@ +package main + +// Smoke test for the BMA421/BMA425 sensors. +// Warning: this code has _not been tested_. It's only here as a smoke test. + +import ( + "fmt" + "machine" + "time" + + "tinygo.org/x/drivers" + "tinygo.org/x/drivers/bma42x" +) + +func main() { + time.Sleep(5 * time.Second) + + i2cBus := machine.I2C1 + i2cBus.Configure(machine.I2CConfig{ + Frequency: 400 * machine.KHz, + SDA: machine.SDA_PIN, + SCL: machine.SCL_PIN, + }) + + sensor := bma42x.NewI2C(i2cBus, bma42x.Address) + err := sensor.Configure(bma42x.Config{ + Device: bma42x.DeviceBMA421 | bma42x.DeviceBMA425, + Features: bma42x.FeatureStepCounting, + }) + if err != nil { + println("could not configure BMA421/BMA425:", err) + return + } + + if !sensor.Connected() { + println("BMA42x not connected") + return + } + + for { + time.Sleep(time.Second) + + err := sensor.Update(drivers.Acceleration | drivers.Temperature) + if err != nil { + println("Error reading sensor", err) + continue + } + + fmt.Printf("Temperature: %.2f °C\n", float32(sensor.Temperature())/1000) + + accelX, accelY, accelZ := sensor.Acceleration() + fmt.Printf("Acceleration: %.2fg %.2fg %.2fg\n", float32(accelX)/1e6, float32(accelY)/1e6, float32(accelZ)/1e6) + } +} diff --git a/smoketest.sh b/smoketest.sh index 38bfed6..d2712e5 100755 --- a/smoketest.sh +++ b/smoketest.sh @@ -13,6 +13,7 @@ tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa tinygo build -size short -o ./build/test.hex -target=microbit ./examples/at24cx/main.go tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bh1750/main.go tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/blinkm/main.go +tinygo build -size short -o ./build/test.hex -target=pinetime ./examples/bma42x/main.go tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmi160/main.go tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp180/main.go tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp280/main.go