|
1 | | -# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries |
2 | 1 | # SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries |
3 | 2 | # |
4 | 3 | # SPDX-License-Identifier: MIT |
|
34 | 33 | import time |
35 | 34 |
|
36 | 35 | from adafruit_bus_device.i2c_device import I2CDevice |
37 | | -from adafruit_register.i2c_bit import ROBit, RWBit |
38 | | -from adafruit_register.i2c_bits import ROBits, RWBits |
39 | | -from adafruit_register.i2c_struct import ROUnaryStruct, UnaryStruct |
| 36 | +from adafruit_bus_device.spi_device import SPIDevice # noqa: PLC0415 |
| 37 | +from adafruit_register.register_accessor import I2CRegisterAccessor, SPIRegisterAccessor |
| 38 | +from adafruit_register.register_bit import ROBit, RWBit |
| 39 | +from adafruit_register.register_bits import ROBits, RWBits |
40 | 40 | from micropython import const |
41 | 41 |
|
42 | 42 | try: |
43 | | - from typing import Optional |
| 43 | + from typing import Optional, Union |
44 | 44 |
|
45 | | - from busio import I2C |
| 45 | + from busio import I2C, SPI |
| 46 | + from digitalio import DigitalInOut |
46 | 47 | except ImportError: |
47 | 48 | pass |
48 | 49 |
|
|
138 | 139 | BMP585_CHIP_ID = const(0x51) |
139 | 140 |
|
140 | 141 |
|
141 | | -class BMP5XX_I2C: |
| 142 | +class BMP5XX: |
142 | 143 | """ |
143 | 144 | Bosche BMP5xx temperature and pressure sensor breakout CircuitPython driver. |
144 | 145 | """ |
145 | 146 |
|
146 | | - chip_id: int = ROUnaryStruct(BMP5_REG_ID, "B") |
| 147 | + chip_id: int = ROBits(8, BMP5_REG_ID, 0) |
147 | 148 |
|
148 | 149 | # Status register bits |
149 | 150 | status_nvm_ready: bool = ROBit(BMP5_REG_STATUS, 1) # NVM ready |
@@ -219,14 +220,41 @@ class BMP5XX_I2C: |
219 | 220 | output_data_rate = RWBits(5, BMP5XX_REG_ODR_CONFIG, 2) |
220 | 221 | """Output data rate. Must be one of the ODR constants.""" |
221 | 222 |
|
222 | | - command = UnaryStruct(BMP5_REG_CMD, "B") # command register |
| 223 | + command = RWBits(8, BMP5_REG_CMD, 0) # command register |
223 | 224 | """Command register""" |
224 | 225 |
|
225 | | - def __init__(self, i2c: I2C, address: int = DEFAULT_ADAFRUIT_ADDR) -> None: |
226 | | - try: |
227 | | - self.i2c_device = I2CDevice(i2c, address) |
228 | | - except ValueError: |
229 | | - raise ValueError(f"No I2C device found at address 0x{address:02X}") |
| 226 | + @staticmethod |
| 227 | + def over_spi(spi: SPI, cs: DigitalInOut): |
| 228 | + """ |
| 229 | + Initialize BMP5XX breakout over SPI bus. |
| 230 | +
|
| 231 | + :param spi: busio.SPI instance to communicate over |
| 232 | + :param cs: DigitalInOut instance to use for chip select |
| 233 | + :return: Initialized BMP5XX object |
| 234 | + """ |
| 235 | + spi_device = SPIDevice(spi, cs) |
| 236 | + return BMP5XX(spi_device) |
| 237 | + |
| 238 | + @staticmethod |
| 239 | + def over_i2c(i2c: I2C, address=DEFAULT_ADAFRUIT_ADDR): |
| 240 | + """ |
| 241 | + Initialize BMP5XX breakout over I2C bus. |
| 242 | +
|
| 243 | + :param i2c: busio.I2C instance to communicate over |
| 244 | + :param address: The I2C address to use. Defaults to DEFAULT_ADAFRUIT_ADDR |
| 245 | + :return: Initialized BMP5XX object |
| 246 | + """ |
| 247 | + i2c_device = I2CDevice(i2c, address) |
| 248 | + return BMP5XX(i2c_device) |
| 249 | + |
| 250 | + def __init__(self, bus_device: Union[I2CDevice, SPIDevice]): |
| 251 | + if isinstance(bus_device, SPIDevice): |
| 252 | + self.register_accessor = SPIRegisterAccessor(bus_device) |
| 253 | + |
| 254 | + elif isinstance(bus_device, I2CDevice): |
| 255 | + self.register_accessor = I2CRegisterAccessor(bus_device) |
| 256 | + else: |
| 257 | + raise ValueError("bus_device must be an instance of I2CDevice or SPIDevice.") |
230 | 258 |
|
231 | 259 | self.sea_level_pressure = 1013.25 |
232 | 260 | self.reset() |
@@ -271,10 +299,11 @@ def altitude(self) -> float: |
271 | 299 | def reset(self) -> None: |
272 | 300 | """Reset the BMP5xx device.""" |
273 | 301 | self.command = BMP5_SOFT_RESET_CMD |
274 | | - time.sleep(0.006) |
| 302 | + time.sleep(0.012) |
| 303 | + _throwaway = self.chip_id |
275 | 304 |
|
276 | 305 | if self.chip_id not in {BMP581_CHIP_ID, BMP585_CHIP_ID}: |
277 | | - raise ValueError(f"CHIP_ID was zero") |
| 306 | + raise ValueError(f"CHIP_ID was incorrect") |
278 | 307 | if not self.status_nvm_ready: |
279 | 308 | raise ValueError("NVM not ready") |
280 | 309 | if self.status_nvm_err: |
@@ -309,3 +338,13 @@ def mode(self, new_mode: int) -> None: |
309 | 338 |
|
310 | 339 | self.deep_disabled = True |
311 | 340 | self._mode = new_mode |
| 341 | + |
| 342 | + |
| 343 | +def BMP5XX_I2C(i2c: I2C, address: int = DEFAULT_ADAFRUIT_ADDR) -> BMP5XX: |
| 344 | + import warnings # noqa: PLC0415, import outside top level |
| 345 | + |
| 346 | + warnings.warn( |
| 347 | + "Warning: BMP5XX_I2C class is deprecated and will be removed in a future version. " |
| 348 | + "User code should be updated to use BMP5XX.over_i2c()" |
| 349 | + ) |
| 350 | + return BMP5XX.over_i2c(i2c, address) |
0 commit comments