diff --git a/lib/lis2mdl/lis2mdl/device.py b/lib/lis2mdl/lis2mdl/device.py index a1d91aa3..8f97be0c 100644 --- a/lib/lis2mdl/lis2mdl/device.py +++ b/lib/lis2mdl/lis2mdl/device.py @@ -168,6 +168,16 @@ def set_hw_offsets(self, x: int, y: int, z: int): # --- READ functions --- ## + def _ensure_data(self): + """Trigger a single conversion if the sensor is in idle mode.""" + if self.is_idle(): + self.set_mode("single") + for _ in range(50): + if self.data_ready(): + return + sleep_ms(2) + raise OSError("LIS2MDL data ready timeout") + 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 @@ -222,6 +232,7 @@ def _to_int16(v): def read_magnet(self): # Read the raw magnetic field data (X, Y, Z) from the sensor. + self._ensure_data() buf = self.i2c.readfrom_mem(self.address, LIS2MDL_OUTX_L_REG | 0x80, 6) x = self._to_int16((buf[1] << 8) | buf[0]) y = self._to_int16((buf[3] << 8) | buf[2]) @@ -232,6 +243,7 @@ def read_magnet(self): def read_temperature_raw(self) -> int: """Reads the raw temperature (LSB), 8 LSB/°C, absolute offset not guaranteed.""" + self._ensure_data() lo = self._read_reg(LIS2MDL_TEMP_OUT_L_REG) hi = self._read_reg(LIS2MDL_TEMP_OUT_H_REG) v = (hi << 8) | lo diff --git a/tests/scenarios/lis2mdl.yaml b/tests/scenarios/lis2mdl.yaml index 54e0b9f3..5a546a1b 100644 --- a/tests/scenarios/lis2mdl.yaml +++ b/tests/scenarios/lis2mdl.yaml @@ -86,6 +86,69 @@ tests: expect_range: [19.0, 21.0] mode: [mock] + # ----- Auto-trigger ----- + + - name: "Magnetic field readable after power down" + action: script + script: | + dev.power_down() + x, y, z = dev.read_magnet() + result = isinstance(x, int) and isinstance(y, int) and isinstance(z, int) + expect_true: true + mode: [mock] + + - name: "Temperature readable after power down" + action: script + script: | + dev.power_down() + t = dev.read_temperature_c() + result = isinstance(t, float) + expect_true: true + mode: [mock] + + - name: "Auto-trigger writes single mode to CFG_REG_A" + action: script + script: | + dev.power_down() + i2c.clear_write_log() + dev.read_magnet() + log = i2c.get_write_log() + wrote_cfg_a = any(reg == 0x60 for reg, data in log) + result = wrote_cfg_a + expect_true: true + mode: [mock] + + - name: "No auto-trigger when already active" + action: script + script: | + dev.read_magnet() + i2c.clear_write_log() + dev.read_magnet() + log = i2c.get_write_log() + result = len(log) == 0 + expect_true: true + mode: [mock] + + - name: "Fresh magnitude after power down" + action: script + script: | + dev.power_down() + mag = dev.magnitude_uT() + result = 10.0 < mag < 300.0 + expect_true: true + mode: [hardware] + + - name: "Fresh temperature after power down" + action: script + script: | + dev.power_down() + t = dev.read_temperature_c() + result = 10.0 < t < 45.0 + expect_true: true + mode: [hardware] + + # ----- Hardware ----- + - name: "Magnitude in plausible range" action: call method: magnitude_uT