diff --git a/Makefile b/Makefile index 75c45a9ba..9fc05da76 100644 --- a/Makefile +++ b/Makefile @@ -81,6 +81,8 @@ smoke-test: @md5sum ./build/test.hex tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis3dh/main.go @md5sum ./build/test.hex + tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/lps22hb/main.go + @md5sum ./build/test.hex tinygo build -size short -o ./build/test.hex -target=microbit ./examples/lsm303agr/main.go @md5sum ./build/test.hex tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/lsm6ds3/main.go @@ -214,7 +216,7 @@ DRIVERS = $(wildcard */) NOTESTS = build examples flash semihosting pcd8544 shiftregister st7789 microphone mcp3008 gps microbitmatrix \ hcsr04 ssd1331 ws2812 thermistor apa102 easystepper ssd1351 ili9341 wifinina shifter hub75 \ hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x dht keypad4x4 max72xx p1am tone tm1637 \ - pcf8563 mcp2515 servo sdcard rtl8720dn image cmd i2csoft hts221 + pcf8563 mcp2515 servo sdcard rtl8720dn image cmd i2csoft hts221 lps22hb TESTS = $(filter-out $(addsuffix /%,$(NOTESTS)),$(DRIVERS)) unit-test: diff --git a/examples/lps22hb/main.go b/examples/lps22hb/main.go new file mode 100644 index 000000000..c2200b380 --- /dev/null +++ b/examples/lps22hb/main.go @@ -0,0 +1,37 @@ +package main + +import ( + "machine" + "time" + + "tinygo.org/x/drivers/lps22hb" +) + +func main() { + + machine.I2C1.Configure(machine.I2CConfig{ + SCL: machine.P0_15, // SCL1 on Nano 33 BLE Sense + SDA: machine.P0_14, // SDA1 on Nano 33 BLE Sense + Frequency: machine.TWI_FREQ_400KHZ, + }) + + sensor := lps22hb.New(machine.I2C1) + + if !sensor.Connected() { + println("LPS22HB not connected!") + return + } + + sensor.Configure() + + for { + + p, _ := sensor.ReadPressure() + t, _ := sensor.ReadTemperature() + println("p =", float32(p)/1000.0, "hPa / t =", float32(t)/1000.0, "*C") + time.Sleep(time.Second) + // note: the device would power down itself after each query + + } + +} diff --git a/lps22hb/lps22hb.go b/lps22hb/lps22hb.go new file mode 100644 index 000000000..b9a5ea8ce --- /dev/null +++ b/lps22hb/lps22hb.go @@ -0,0 +1,73 @@ +// Package lps22hb implements a driver for LPS22HB, a MEMS nano pressure sensor. +// +// Datasheet: https://www.st.com/resource/en/datasheet/dm00140895.pdf +// +package lps22hb + +import ( + "tinygo.org/x/drivers" +) + +// Device wraps an I2C connection to a HTS221 device. +type Device struct { + bus drivers.I2C + Address uint8 +} + +// Connected returns whether LPS22HB has been found. +// It does a "who am I" request and checks the response. +func (d *Device) Connected() bool { + data := []byte{0} + d.bus.ReadRegister(d.Address, LPS22HB_WHO_AM_I_REG, data) + return data[0] == 0xB1 +} + +// Configure sets up the LPS22HB device for communication. +func (d *Device) Configure() { + // set to block update mode + d.bus.WriteRegister(d.Address, LPS22HB_CTRL1_REG, []byte{0x02}) +} + +// ReadPressure returns the pressure in milli pascals (mPa). +func (d *Device) ReadPressure() (pressure int32, err error) { + d.waitForOneShot() + + // read data + data := []byte{0, 0, 0} + d.bus.ReadRegister(d.Address, LPS22HB_PRESS_OUT_REG, data[:1]) + d.bus.ReadRegister(d.Address, LPS22HB_PRESS_OUT_REG+1, data[1:2]) + d.bus.ReadRegister(d.Address, LPS22HB_PRESS_OUT_REG+2, data[2:]) + pValue := float32(uint32(data[2])<<16|uint32(data[1])<<8|uint32(data[0])) / 4096.0 + + return int32(pValue * 1000), nil +} + +// ReadTemperature returns the temperature in celsius milli degrees (°C/1000). +func (d *Device) ReadTemperature() (temperature int32, err error) { + d.waitForOneShot() + + // read data + data := []byte{0, 0} + d.bus.ReadRegister(d.Address, LPS22HB_TEMP_OUT_REG, data[:1]) + d.bus.ReadRegister(d.Address, LPS22HB_TEMP_OUT_REG+1, data[1:]) + tValue := float32(int16(uint16(data[1])<<8|uint16(data[0]))) / 100.0 + + return int32(tValue * 1000), nil +} + +// private functions + +// wait and trigger one shot in block update +func (d *Device) waitForOneShot() { + // trigger one shot + d.bus.WriteRegister(d.Address, LPS22HB_CTRL2_REG, []byte{0x01}) + + // wait until one shot is cleared + data := []byte{1} + for { + d.bus.ReadRegister(d.Address, LPS22HB_CTRL2_REG, data) + if data[0]&0x01 == 0 { + break + } + } +} diff --git a/lps22hb/lps22hb_generic.go b/lps22hb/lps22hb_generic.go new file mode 100644 index 000000000..c101e079c --- /dev/null +++ b/lps22hb/lps22hb_generic.go @@ -0,0 +1,14 @@ +//go:build !nano_33_ble +// +build !nano_33_ble + +package lps22hb + +import "tinygo.org/x/drivers" + +// New creates a new LPS22HB connection. The I2C bus must already be +// configured. +// +// This function only creates the Device object, it does not touch the device. +func New(bus drivers.I2C) Device { + return Device{bus: bus, Address: LPS22HB_ADDRESS} +} diff --git a/lps22hb/lps22hb_nano_33_ble.go b/lps22hb/lps22hb_nano_33_ble.go new file mode 100644 index 000000000..eafe3f2f2 --- /dev/null +++ b/lps22hb/lps22hb_nano_33_ble.go @@ -0,0 +1,29 @@ +//go:build nano_33_ble +// +build nano_33_ble + +package lps22hb + +import ( + "machine" + "time" + + "tinygo.org/x/drivers" +) + +// New creates a new LPS22HB connection. The I2C bus must already be +// configured. +// +// This function only creates the Device object, it does not touch the device. +func New(bus drivers.I2C) Device { + // turn on internal power pin (machine.P0_22) and I2C1 pullups power pin (machine.P1_00) + // and wait a moment. + ENV := machine.P0_22 + ENV.Configure(machine.PinConfig{Mode: machine.PinOutput}) + ENV.High() + R := machine.P1_00 + R.Configure(machine.PinConfig{Mode: machine.PinOutput}) + R.High() + time.Sleep(time.Millisecond * 10) + + return Device{bus: bus, Address: LPS22HB_ADDRESS} +} diff --git a/lps22hb/registers.go b/lps22hb/registers.go new file mode 100644 index 000000000..71122e392 --- /dev/null +++ b/lps22hb/registers.go @@ -0,0 +1,15 @@ +package lps22hb + +const ( + + // I2C address + LPS22HB_ADDRESS = 0x5C + + // control/status registers + LPS22HB_WHO_AM_I_REG = 0x0F + LPS22HB_CTRL1_REG = 0x10 + LPS22HB_CTRL2_REG = 0x11 + LPS22HB_STATUS_REG = 0x27 + LPS22HB_PRESS_OUT_REG = 0x28 + LPS22HB_TEMP_OUT_REG = 0x2B +)