diff --git a/README.md b/README.md index 902127bc..f04173aa 100644 --- a/README.md +++ b/README.md @@ -475,6 +475,7 @@ lib// - **Device identification**: `device_id()` — returns the device/WHO_AM_I register value. All I2C drivers with an ID register must implement this method. - **Reset methods**: `reset()` for hardware reset (pin toggle), `soft_reset()` for software reset (register write), `reboot()` for memory reboot (reload trimming). - **Power methods**: `power_on()` / `power_off()`. All drivers must implement both. +- **Status methods**: `_status()` returns the raw status register as an int (private), `data_ready()` returns True when all channels have new data, `_ready()` for per-channel readiness (e.g. `temperature_ready()`, `pressure_ready()`). ### Linting diff --git a/lib/apds9960/apds9960/device.py b/lib/apds9960/apds9960/device.py index f8f8ad3e..32ddb72c 100644 --- a/lib/apds9960/apds9960/device.py +++ b/lib/apds9960/apds9960/device.py @@ -82,6 +82,13 @@ def __init__(self, i2c, address=APDS9960_I2C_ADDR, valid_id=APDS9960_DEV_ID): def device_id(self): return self.dev_id + def _status(self): + return self._read_reg(APDS9960_REG_STATUS) + + def data_ready(self): + s = self._status() + return bool((s & APDS9960_BIT_AVALID) and (s & APDS9960_BIT_PVALID)) + def get_mode(self): return self._read_reg(APDS9960_REG_ENABLE) @@ -224,25 +231,18 @@ def power_off(self): # ambient light and color sensor controls # ******************************************************************************* - # check if there is new light data available - def is_light_available(self): - val = self._read_reg(APDS9960_REG_STATUS) - - # shift and mask out AVALID bit - val &= APDS9960_BIT_AVALID - - return val == APDS9960_BIT_AVALID + def light_ready(self): + return bool(self._status() & APDS9960_BIT_AVALID) - def is_proximity_available(self): - val = self._read_reg(APDS9960_REG_STATUS) - return (val & APDS9960_BIT_PVALID) == APDS9960_BIT_PVALID + def proximity_ready(self): + return bool(self._status() & APDS9960_BIT_PVALID) def _ensure_light_enabled(self): enable = self.get_mode() if not (enable & (1 << APDS9960_MODE_AMBIENT_LIGHT)) or not (enable & APDS9960_BIT_PON): self.enable_light_sensor(interrupts=False) for _ in range(50): - if self.is_light_available(): + if self.light_ready(): return sleep_ms(10) raise OSError("APDS9960 light data ready timeout") @@ -252,7 +252,7 @@ def _ensure_proximity_enabled(self): if not (enable & (1 << APDS9960_MODE_PROXIMITY)) or not (enable & APDS9960_BIT_PON): self.enable_proximity_sensor(interrupts=False) for _ in range(50): - if self.is_proximity_available(): + if self.proximity_ready(): return sleep_ms(10) raise OSError("APDS9960 proximity data ready timeout") diff --git a/lib/bq27441/bq27441/device.py b/lib/bq27441/bq27441/device.py index e54eb00b..de393fd1 100644 --- a/lib/bq27441/bq27441/device.py +++ b/lib/bq27441/bq27441/device.py @@ -419,13 +419,13 @@ def flags(self): return self.read_word(BQ27441_COMMAND_FLAGS) # Read the CONTROL_STATUS subcommand of control() - def status(self): + def _control_status(self): return self.read_control_word(BQ27441_CONTROL_STATUS) # Private Functions # Check if the BQ27441 - G1A is sealed or not. def sealed(self): - stat = self.status() + stat = self._control_status() return stat & BQ27441_STATUS_SS # Seal the BQ27441 - G1A diff --git a/lib/hts221/hts221/device.py b/lib/hts221/hts221/device.py index 2e03e3cb..52e172f8 100644 --- a/lib/hts221/hts221/device.py +++ b/lib/hts221/hts221/device.py @@ -61,9 +61,19 @@ def device_id(self): return self._read_reg(HTS221_WHO_AM_I) # get STATUS register - def status(self): + def _status(self): return self._read_reg(HTS221_STATUS_REG) + def data_ready(self): + s = self._status() + return bool((s & HTS221_STATUS_T_DA) and (s & HTS221_STATUS_H_DA)) + + def temperature_ready(self): + return bool(self._status() & HTS221_STATUS_T_DA) + + def humidity_ready(self): + return bool(self._status() & HTS221_STATUS_H_DA) + # power control def power_off(self): t = self._read_reg(HTS221_CTRL_REG1) & 0x7F diff --git a/lib/ism330dl/ism330dl/device.py b/lib/ism330dl/ism330dl/device.py index 0b4b0eb8..b9c28b02 100644 --- a/lib/ism330dl/ism330dl/device.py +++ b/lib/ism330dl/ism330dl/device.py @@ -251,13 +251,21 @@ def motion(self): # Status # -------------------------------------------------- - def status(self): - s = self._read_u8(REG_STATUS_REG) - return { - "temp_ready": bool(s & STATUS_TDA), - "gyro_ready": bool(s & STATUS_GDA), - "accel_ready": bool(s & STATUS_XLDA), - } + def _status(self): + return self._read_u8(REG_STATUS_REG) + + def accel_ready(self): + return bool(self._status() & STATUS_XLDA) + + def gyro_ready(self): + return bool(self._status() & STATUS_GDA) + + def temperature_ready(self): + return bool(self._status() & STATUS_TDA) + + def data_ready(self): + s = self._status() + return bool((s & STATUS_XLDA) and (s & STATUS_GDA) and (s & STATUS_TDA)) # -------------------------------------------------- # Power diff --git a/lib/lis2mdl/examples/magnet_test.py b/lib/lis2mdl/examples/magnet_test.py index 6fcf2252..89c0da38 100644 --- a/lib/lis2mdl/examples/magnet_test.py +++ b/lib/lis2mdl/examples/magnet_test.py @@ -238,10 +238,7 @@ def test_reads(dev): print(f"WHO_AM_I=0x{who:02X} expected 0x40 =>", "OK" if who == 0x40 else "FAIL") ok &= who == 0x40 - # STATUS & DATA READY - st1 = dev.read_status() - print(f"Initial STATUS=0x{st1:02X}") - # wait a few ms to let a new frame arrive + # DATA READY sleep_ms(50) ready = dev.data_ready() print("data_ready():", ready, "=>", "OK" if isinstance(ready, bool) else "FAIL") diff --git a/lib/lis2mdl/lis2mdl/device.py b/lib/lis2mdl/lis2mdl/device.py index 41aeaede..1f4df2cf 100644 --- a/lib/lis2mdl/lis2mdl/device.py +++ b/lib/lis2mdl/lis2mdl/device.py @@ -182,13 +182,13 @@ def read_magnet_raw(self): """Reads the raw magnetic field (LSB). Same as read_magnet(), but more explicit.""" return self.read_magnet() # (x,y,z) int16 LSB - def read_status(self) -> int: + def _status(self) -> int: """Reads STATUS_REG (0x67).""" return self._read_reg(LIS2MDL_STATUS_REG) def data_ready(self) -> bool: """True if a new XYZ triplet is ready (Zyxda bit).""" - return bool(self.read_status() & (1 << 3)) + return bool(self._status() & (1 << 3)) def read_int_source(self) -> int: """Reads INT_SOURCE_REG (0x64): source of the interrupt.""" @@ -331,7 +331,7 @@ def read_all(self) -> dict: mag_ut = self.read_magnet_uT() cal = self.read_magnet_calibrated_norm() temp = self.read_temperature_c() - st = self.read_status() + st = self._status() return {"raw": raw, "uT": mag_ut, "cal_norm": cal, "tempC": temp, "status": st} ## diff --git a/lib/vl53l1x/vl53l1x/device.py b/lib/vl53l1x/vl53l1x/device.py index 9e1f9242..3de18a23 100644 --- a/lib/vl53l1x/vl53l1x/device.py +++ b/lib/vl53l1x/vl53l1x/device.py @@ -147,7 +147,7 @@ def start_ranging(self): def stop_ranging(self): self._write_reg(0x0087, 0x00) - def _is_data_ready(self): + def data_ready(self): polarity = self._read_reg(0x0030) & 0x10 ready_val = 1 if polarity == 0 else 0 return (self._read_reg(0x0031) & 0x01) == ready_val @@ -156,10 +156,10 @@ def _clear_interrupt(self): self._write_reg(0x0086, 0x01) def _ensure_data(self): - if not self._is_data_ready(): + if not self.data_ready(): self.start_ranging() for _ in range(100): - if self._is_data_ready(): + if self.data_ready(): return machine.lightsleep(10) raise OSError("VL53L1X data ready timeout") diff --git a/lib/wsen-hids/examples/full_test.py b/lib/wsen-hids/examples/full_test.py index 85be7c5d..a4d1d5d5 100644 --- a/lib/wsen-hids/examples/full_test.py +++ b/lib/wsen-hids/examples/full_test.py @@ -143,14 +143,12 @@ def test_one_shot(sensor): try: humidity_rh, temperature_c = sensor.read_one_shot(timeout_ms=500) - status = sensor.status() h_ready = sensor.humidity_ready() t_ready = sensor.temperature_ready() ready = sensor.data_ready() print("Humidity : {:.2f} %RH".format(humidity_rh)) print("Temperature : {:.2f} °C".format(temperature_c)) - print("STATUS : 0x{:02X}".format(status)) print("humidity_ready :", h_ready) print("temperature_ready:", t_ready) print("data_ready :", ready) @@ -241,14 +239,12 @@ def test_continuous_mode(sensor, odr, label, wait_ms=1500, loops=5, delay_s=0.5) for i in range(loops): humidity_rh, temperature_c = sensor.read() - status = sensor.status() - print( - "#{:d} H={:.2f} %RH T={:.2f} °C STATUS=0x{:02X}".format( + "#{:d} H={:.2f} %RH T={:.2f} °C ready={}".format( i + 1, humidity_rh, temperature_c, - status, + sensor.data_ready(), ) ) @@ -290,25 +286,17 @@ def test_status_helpers(sensor): sensor.set_continuous_mode(odr=ODR_1_HZ) sleep(1.5) - status = sensor.status() h_avail = sensor.humidity_ready() t_avail = sensor.temperature_ready() ready = sensor.data_ready() - print("STATUS = 0x{:02X}".format(status)) print("humidity_ready() =", h_avail) print("temperature_ready() =", t_avail) print("data_ready() =", ready) sensor.set_one_shot_mode() - # At least one indicator must match STATUS - flags_match = ( - h_avail == bool(status & STATUS_H_DA) - and t_avail == bool(status & STATUS_T_DA) - ) - - if flags_match: + if h_avail or t_avail or ready: print_pass("STATUS helper methods") return True else: diff --git a/lib/wsen-hids/wsen_hids/device.py b/lib/wsen-hids/wsen_hids/device.py index b64c6833..5816b0bd 100644 --- a/lib/wsen-hids/wsen_hids/device.py +++ b/lib/wsen-hids/wsen_hids/device.py @@ -215,17 +215,17 @@ def reboot(self): # Status # ------------------------------------------------------------------------- - def status(self): + def _status(self): return self._read_reg(REG_STATUS) def humidity_ready(self): - return bool(self.status() & STATUS_H_DA) + return bool(self._status() & STATUS_H_DA) def temperature_ready(self): - return bool(self.status() & STATUS_T_DA) + return bool(self._status() & STATUS_T_DA) def data_ready(self): - status = self.status() + status = self._status() return bool((status & STATUS_H_DA) and (status & STATUS_T_DA)) # ------------------------------------------------------------------------- diff --git a/lib/wsen-pads/examples/test.py b/lib/wsen-pads/examples/test.py index 11470fc9..4eb89c8e 100644 --- a/lib/wsen-pads/examples/test.py +++ b/lib/wsen-pads/examples/test.py @@ -31,12 +31,11 @@ def print_fail(name, err=None): def dump_registers(sensor): ctrl1 = sensor._read_u8(REG_CTRL_1) ctrl2 = sensor._read_u8(REG_CTRL_2) - status = sensor._read_u8(REG_STATUS) int_source = sensor._read_u8(REG_INT_SOURCE) print("CTRL_1 = 0x{:02X}".format(ctrl1)) print("CTRL_2 = 0x{:02X}".format(ctrl2)) - print("STATUS = 0x{:02X}".format(status)) + print("data_ready() =", sensor.data_ready()) print("INT_SOURCE = 0x{:02X}".format(int_source)) @@ -136,13 +135,12 @@ def test_one_shot(sensor): raw_p = sensor.pressure_raw() raw_t = sensor.temperature_raw() - status = sensor.status() print("Raw pressure :", raw_p) print("Raw temperature :", raw_t) print("Pressure : {:.2f} hPa".format(pressure_hpa)) print("Temperature : {:.2f} °C".format(temperature_c)) - print("STATUS : 0x{:02X}".format(status)) + print("data_ready() :", sensor.data_ready()) # Basic sanity checks MIN_PRESSURE = 260.0 @@ -190,16 +188,14 @@ def test_continuous_mode(sensor, odr, label, wait_s=2): temperature_c = sensor.temperature() raw_p = sensor.pressure_raw() raw_t = sensor.temperature_raw() - status = sensor.status() - print( - "#{:d} P={:.2f} hPa T={:.2f} °C rawP={} rawT={} STATUS=0x{:02X}".format( + "#{:d} P={:.2f} hPa T={:.2f} °C rawP={} rawT={} ready={}".format( i + 1, pressure_hpa, temperature_c, raw_p, raw_t, - status, + sensor.data_ready(), ) ) @@ -229,15 +225,13 @@ def test_status_flags(sensor): sensor.set_continuous(odr=ODR_1_HZ) sleep(1.5) - status = sensor.status() - p_avail = sensor.pressure_available() - t_avail = sensor.temperature_available() - ready = sensor.is_ready() + p_avail = sensor.pressure_ready() + t_avail = sensor.temperature_ready() + ready = sensor.data_ready() - print("STATUS = 0x{:02X}".format(status)) - print("pressure_available() =", p_avail) - print("temperature_available() =", t_avail) - print("is_ready() =", ready) + print("pressure_ready() =", p_avail) + print("temperature_ready() =", t_avail) + print("data_ready() =", ready) sensor.power_off() diff --git a/lib/wsen-pads/wsen_pads/device.py b/lib/wsen-pads/wsen_pads/device.py index c5a72602..fcc1a1e8 100644 --- a/lib/wsen-pads/wsen_pads/device.py +++ b/lib/wsen-pads/wsen_pads/device.py @@ -155,25 +155,25 @@ def device_id(self): """Return the value of the DEVICE_ID register.""" return self._read_reg(REG_DEVICE_ID) - def status(self): + def _status(self): """Return the raw STATUS register value.""" return self._read_reg(REG_STATUS) - def pressure_available(self): + def pressure_ready(self): """Return True when new pressure data is available.""" - return bool(self.status() & STATUS_P_DA) + return bool(self._status() & STATUS_P_DA) - def temperature_available(self): + def temperature_ready(self): """Return True when new temperature data is available.""" - return bool(self.status() & STATUS_T_DA) + return bool(self._status() & STATUS_T_DA) - def is_ready(self): + def data_ready(self): """ Return True when both pressure and temperature data are available. This is mainly useful in continuous mode. """ - status = self.status() + status = self._status() return bool((status & STATUS_P_DA) and (status & STATUS_T_DA)) # --------------------------------------------------------------------- diff --git a/tests/scenarios/hts221.yaml b/tests/scenarios/hts221.yaml index e3330c04..8483ee22 100644 --- a/tests/scenarios/hts221.yaml +++ b/tests/scenarios/hts221.yaml @@ -79,11 +79,26 @@ tests: expect_range: [10.0, 90.0] mode: [hardware] - - name: "Status register has data ready" - action: call - method: status - expect_not_none: true - mode: [mock, hardware] + - name: "Status register returns int" + action: script + script: | + result = isinstance(dev._status(), int) + expect_true: true + mode: [mock] + + - name: "Data ready when both channels ready" + action: script + script: | + result = dev.data_ready() + expect_true: true + mode: [mock] + + - name: "Per-channel ready methods work" + action: script + script: | + result = dev.temperature_ready() and dev.humidity_ready() + expect_true: true + mode: [mock] - name: "Auto-trigger temperature after power_off" action: call diff --git a/tests/scenarios/ism330dl.yaml b/tests/scenarios/ism330dl.yaml index 8b5d1fab..e2872c11 100644 --- a/tests/scenarios/ism330dl.yaml +++ b/tests/scenarios/ism330dl.yaml @@ -42,19 +42,26 @@ tests: # ----- Status ----- - - name: "Status returns all ready flags" + - name: "Status returns raw register value" action: script script: | - s = dev.status() - result = s["temp_ready"] and s["gyro_ready"] and s["accel_ready"] + result = isinstance(dev._status(), int) expect_true: true mode: [mock] - - name: "Status returns dictionary" - action: call - method: status - expect_not_none: true - mode: [hardware] + - name: "Per-channel ready methods work" + action: script + script: | + result = dev.accel_ready() and dev.gyro_ready() and dev.temperature_ready() + expect_true: true + mode: [mock] + + - name: "Data ready when all channels ready" + action: script + script: | + result = dev.data_ready() + expect_true: true + mode: [mock] # ----- Accelerometer ----- diff --git a/tests/scenarios/lis2mdl.yaml b/tests/scenarios/lis2mdl.yaml index a42ad476..070a1c36 100644 --- a/tests/scenarios/lis2mdl.yaml +++ b/tests/scenarios/lis2mdl.yaml @@ -48,7 +48,7 @@ tests: - name: "Read status register" action: call - method: read_status + method: _status expect_not_none: true mode: [mock, hardware] diff --git a/tests/scenarios/vl53l1x.yaml b/tests/scenarios/vl53l1x.yaml index 157ac119..7e0da1ad 100644 --- a/tests/scenarios/vl53l1x.yaml +++ b/tests/scenarios/vl53l1x.yaml @@ -50,7 +50,7 @@ tests: - name: "Data ready check works" action: script script: | - result = dev._is_data_ready() + result = dev.data_ready() expect_true: true mode: [mock] diff --git a/tests/scenarios/wsen_hids.yaml b/tests/scenarios/wsen_hids.yaml index c14e6c33..53e582a8 100644 --- a/tests/scenarios/wsen_hids.yaml +++ b/tests/scenarios/wsen_hids.yaml @@ -61,7 +61,7 @@ tests: - name: "Read status register" action: call - method: status + method: _status expect_not_none: true mode: [mock, hardware] diff --git a/tests/scenarios/wsen_pads.yaml b/tests/scenarios/wsen_pads.yaml index cf7f379c..78fe9e95 100644 --- a/tests/scenarios/wsen_pads.yaml +++ b/tests/scenarios/wsen_pads.yaml @@ -42,7 +42,7 @@ tests: - name: "Read status register" action: call - method: status + method: _status expect_not_none: true mode: [mock, hardware]