From 5ea5becf2b3b9b543bc233ca143d8c3eed5fe290 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Thu, 25 Sep 2025 14:34:18 -0500 Subject: [PATCH 1/4] SPI support --- adafruit_bmp5xx.py | 50 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/adafruit_bmp5xx.py b/adafruit_bmp5xx.py index 0cfb20e..989d737 100644 --- a/adafruit_bmp5xx.py +++ b/adafruit_bmp5xx.py @@ -1,4 +1,3 @@ -# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries # SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries # # SPDX-License-Identifier: MIT @@ -34,15 +33,17 @@ import time from adafruit_bus_device.i2c_device import I2CDevice -from adafruit_register.i2c_bit import ROBit, RWBit -from adafruit_register.i2c_bits import ROBits, RWBits -from adafruit_register.i2c_struct import ROUnaryStruct, UnaryStruct +from adafruit_bus_device.spi_device import SPIDevice # noqa: PLC0415 +from adafruit_register.register_accessor import I2CRegisterAccessor, SPIRegisterAccessor +from adafruit_register.register_bit import ROBit, RWBit +from adafruit_register.register_bits import ROBits, RWBits from micropython import const try: from typing import Optional - from busio import I2C + from busio import I2C, SPI + from digitalio import DigitalInOut except ImportError: pass @@ -71,6 +72,7 @@ BMP5XX_REG_DSP_IIR = const(0x31) BMP5XX_REG_DSP_CONFIG = const(0x30) BMP5XX_REG_INT_SOURCE = const(0x15) +BMP_REG_ASIC_STATUS = const(0x11) # ODR settings BMP5XX_ODR_240_HZ = const(0x00) @@ -138,12 +140,12 @@ BMP585_CHIP_ID = const(0x51) -class BMP5XX_I2C: +class BMP5XX: """ Bosche BMP5xx temperature and pressure sensor breakout CircuitPython driver. """ - chip_id: int = ROUnaryStruct(BMP5_REG_ID, "B") + chip_id: int = ROBits(8, BMP5_REG_ID, 0) # Status register bits status_nvm_ready: bool = ROBit(BMP5_REG_STATUS, 1) # NVM ready @@ -219,14 +221,31 @@ class BMP5XX_I2C: output_data_rate = RWBits(5, BMP5XX_REG_ODR_CONFIG, 2) """Output data rate. Must be one of the ODR constants.""" - command = UnaryStruct(BMP5_REG_CMD, "B") # command register + command = RWBits(8, BMP5_REG_CMD, 0) # command register """Command register""" - def __init__(self, i2c: I2C, address: int = DEFAULT_ADAFRUIT_ADDR) -> None: - try: - self.i2c_device = I2CDevice(i2c, address) - except ValueError: - raise ValueError(f"No I2C device found at address 0x{address:02X}") + hardware_interface = RWBits(2, BMP_REG_ASIC_STATUS, 0) + + def __init__( + self, + i2c: I2C = None, + address: Optional[int] = DEFAULT_ADAFRUIT_ADDR, + spi: SPI = None, + cs: DigitalInOut = None, + ) -> None: + if spi is not None and cs is not None: + try: + self.spi_device = SPIDevice(spi, cs, baudrate=1000000) + self.register_accessor = SPIRegisterAccessor(self.spi_device) + except ValueError: + raise ValueError(f"No SPI device found.") + + elif i2c is not None: + try: + i2c_device = I2CDevice(i2c, address) + self.register_accessor = I2CRegisterAccessor(i2c_device) + except ValueError: + raise ValueError(f"No I2C device found.") self.sea_level_pressure = 1013.25 self.reset() @@ -271,10 +290,11 @@ def altitude(self) -> float: def reset(self) -> None: """Reset the BMP5xx device.""" self.command = BMP5_SOFT_RESET_CMD - time.sleep(0.006) + time.sleep(0.012) + _throwaway = self.chip_id if self.chip_id not in {BMP581_CHIP_ID, BMP585_CHIP_ID}: - raise ValueError(f"CHIP_ID was zero") + raise ValueError(f"CHIP_ID was incorrect") if not self.status_nvm_ready: raise ValueError("NVM not ready") if self.status_nvm_err: From d52f6a8d0a99e592fd1e16d976255947513b4d9a Mon Sep 17 00:00:00 2001 From: foamyguy Date: Thu, 25 Sep 2025 14:45:43 -0500 Subject: [PATCH 2/4] fix simpletest. add SPI example --- examples/bmp5xx_simpletest.py | 4 ++-- examples/bmp5xx_spi_simpletest.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 examples/bmp5xx_spi_simpletest.py diff --git a/examples/bmp5xx_simpletest.py b/examples/bmp5xx_simpletest.py index 96a3fc5..8dfc44e 100644 --- a/examples/bmp5xx_simpletest.py +++ b/examples/bmp5xx_simpletest.py @@ -5,7 +5,7 @@ import board -from adafruit_bmp5xx import BMP5XX_I2C +from adafruit_bmp5xx import BMP5XX SEALEVELPRESSURE_HPA = 1013.25 @@ -13,7 +13,7 @@ i2c = board.I2C() # uses board.SCL and board.SDA # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller -bmp = BMP5XX_I2C(i2c) +bmp = BMP5XX(i2c) bmp.sea_level_pressure = SEALEVELPRESSURE_HPA diff --git a/examples/bmp5xx_spi_simpletest.py b/examples/bmp5xx_spi_simpletest.py new file mode 100644 index 0000000..97e168b --- /dev/null +++ b/examples/bmp5xx_spi_simpletest.py @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries +# +# SPDX-License-Identifier: Unlicense +import time + +import board +from digitalio import DigitalInOut, Direction + +from adafruit_bmp5xx import BMP5XX + +SEALEVELPRESSURE_HPA = 1013.25 + +# SPI setup +spi = board.SPI() # uses board.SCL and board.SDA +spi = board.SPI() +cs = DigitalInOut(board.D10) +cs.direction = Direction.OUTPUT +bmp = BMP5XX(spi=spi, cs=cs) + + +bmp.sea_level_pressure = SEALEVELPRESSURE_HPA + +while True: + if bmp.data_ready: + print( + f"temp F: {bmp.temperature * (9 / 5) + 32} " + f"pressure: {bmp.pressure} hPa " + f"Approx altitude: {bmp.altitude} m" + ) + time.sleep(1) From 83189a5c8dce9c570e6389a9a17a209f9eada7f4 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Fri, 26 Sep 2025 08:55:59 -0500 Subject: [PATCH 3/4] spi multi-device example --- docs/examples.rst | 8 ++++++ examples/bmp5xx_spi_multi_device.py | 44 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 examples/bmp5xx_spi_multi_device.py diff --git a/docs/examples.rst b/docs/examples.rst index b68bc01..0acb2cf 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -6,3 +6,11 @@ Ensure your device works with this simple test. .. literalinclude:: ../examples/bmp5xx_simpletest.py :caption: examples/bmp5xx_simpletest.py :linenos: + +.. literalinclude:: ../examples/bmp5xx_spi_simpletest.py + :caption: examples/bmp5xx_spi_simpletest.py + :linenos: + +.. literalinclude:: ../examples/bmp5xx_spi_multi_device.py + :caption: examples/bmp5xx_spi_multi_device.py + :linenos: diff --git a/examples/bmp5xx_spi_multi_device.py b/examples/bmp5xx_spi_multi_device.py new file mode 100644 index 0000000..a66094c --- /dev/null +++ b/examples/bmp5xx_spi_multi_device.py @@ -0,0 +1,44 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries +# +# SPDX-License-Identifier: MIT +import time + +import board +from digitalio import DigitalInOut, Direction + +from adafruit_bmp5xx import BMP5XX + +SEALEVELPRESSURE_HPA = 1013.25 + +# SPI setup +spi = board.SPI() + +# first sensor setup +cs1 = DigitalInOut(board.D10) +cs1.direction = Direction.OUTPUT +bmp1 = BMP5XX(spi=spi, cs=cs1) + +# second sensor setup, different CS pin, same SPI bus +cs2 = DigitalInOut(board.D11) +cs2.direction = Direction.OUTPUT +bmp2 = BMP5XX(spi=spi, cs=cs2) + +bmp1.sea_level_pressure = SEALEVELPRESSURE_HPA +bmp2.sea_level_pressure = SEALEVELPRESSURE_HPA + +while True: + if bmp1.data_ready: + print( + f"BMP1 temp F: {bmp1.temperature * (9 / 5) + 32} " + f"pressure: {bmp1.pressure} hPa " + f"Approx altitude: {bmp1.altitude} m" + ) + + if bmp2.data_ready: + print( + f"BMP2 temp F: {bmp2.temperature * (9 / 5) + 32} " + f"pressure: {bmp2.pressure} hPa " + f"Approx altitude: {bmp2.altitude} m" + ) + print("-----") + time.sleep(1) From ab031e101f3327ba612433a8b3fa8bd2997a1b52 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Thu, 2 Oct 2025 12:05:24 -0500 Subject: [PATCH 4/4] removed unused register --- adafruit_bmp5xx.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/adafruit_bmp5xx.py b/adafruit_bmp5xx.py index 989d737..32a1424 100644 --- a/adafruit_bmp5xx.py +++ b/adafruit_bmp5xx.py @@ -72,7 +72,6 @@ BMP5XX_REG_DSP_IIR = const(0x31) BMP5XX_REG_DSP_CONFIG = const(0x30) BMP5XX_REG_INT_SOURCE = const(0x15) -BMP_REG_ASIC_STATUS = const(0x11) # ODR settings BMP5XX_ODR_240_HZ = const(0x00) @@ -224,8 +223,6 @@ class BMP5XX: command = RWBits(8, BMP5_REG_CMD, 0) # command register """Command register""" - hardware_interface = RWBits(2, BMP_REG_ASIC_STATUS, 0) - def __init__( self, i2c: I2C = None,