Skip to content

Commit 38056ff

Browse files
committed
lsm6dsox: Add pedometer support.
Signed-off-by: Sebastian Romero <s.romero@arduino.cc>
1 parent d0511a4 commit 38056ff

File tree

1 file changed

+158
-1
lines changed

1 file changed

+158
-1
lines changed

micropython/drivers/imu/lsm6dsox/lsm6dsox.py

Lines changed: 158 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@
6060
_OUTX_L_G = const(0x22)
6161
_OUTX_L_XL = const(0x28)
6262
_MLC_STATUS = const(0x38)
63+
_STEP_COUNTER_L = const(0x62)
64+
_EMB_FUNC_SRC = const(0x64)
65+
66+
_PAGE_SEL = const(0x02)
67+
_PAGE_ADDRESS = const(0x08)
68+
_PAGE_VALUE = const(0x09)
69+
_PAGE_RW = const(0x17)
70+
71+
_MD1_CFG = const(0x5E)
72+
_MD2_CFG = const(0x5F)
6373

6474
_DEFAULT_ADDR = const(0x6A)
6575
_WHO_AM_I_REG = const(0x0F)
@@ -75,6 +85,15 @@
7585

7686
_EMB_FUNC_EN_A = const(0x04)
7787
_EMB_FUNC_EN_B = const(0x05)
88+
_EMB_FUNC_INT1 = const(0x0A)
89+
_EMB_FUNC_INT2 = const(0x0E)
90+
91+
_PEDO_DEB_STEPS_CONF = const(0x0184)
92+
93+
_PEDO_EN_MASK = const(0x08)
94+
_PEDO_RST_STEP_MASK = const(0x80)
95+
_PEDO_INT_MASK = const(0x08)
96+
_INT_EMB_FUNC_MASK = const(0x02)
7897

7998

8099
class LSM6DSOX:
@@ -108,8 +127,9 @@ def __init__(
108127
if self._read_reg(_WHO_AM_I_REG) != 108:
109128
raise OSError("No LSM6DS device was found at address 0x%x" % (self.address))
110129

111-
# allocate scratch buffer for efficient conversions and memread op's
130+
# allocate scratch buffers for efficient conversions and memread op's
112131
self.scratch_int = array.array("h", [0, 0, 0])
132+
self.scratch_2b = bytearray(2)
113133

114134
SCALE_GYRO = {250: 0, 500: 1, 1000: 2, 2000: 3}
115135
SCALE_ACCEL = {2: 0, 4: 2, 8: 3, 16: 1}
@@ -185,6 +205,12 @@ def _write_reg(self, reg, val):
185205
finally:
186206
self.cs(1)
187207

208+
def _set_bits(self, reg, mask):
209+
self._write_reg(reg, self._read_reg(reg) | mask)
210+
211+
def _clear_bits(self, reg, mask):
212+
self._write_reg(reg, self._read_reg(reg) & ~mask)
213+
188214
def _read_reg_into(self, reg, buf):
189215
if self._use_i2c:
190216
self.bus.readfrom_mem_into(self.address, reg, buf)
@@ -196,6 +222,55 @@ def _read_reg_into(self, reg, buf):
196222
finally:
197223
self.cs(1)
198224

225+
def _read_page(self, address):
226+
msb = (address >> 8) & 0x0F
227+
lsb = address & 0xFF
228+
229+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
230+
231+
# Clear both read and write bits first, then set read bit (bit 5).
232+
self._write_reg(_PAGE_RW, (self._read_reg(_PAGE_RW) & 0x9F) | 0x20)
233+
234+
# select page
235+
self._write_reg(_PAGE_SEL, (msb << 4) | 0x01)
236+
237+
# set page addr
238+
self._write_reg(_PAGE_ADDRESS, lsb)
239+
240+
# read value
241+
val = self._read_reg(_PAGE_VALUE)
242+
243+
# unset page read and page_sel
244+
self._clear_bits(_PAGE_RW, 0x20)
245+
self._write_reg(_PAGE_SEL, 0x01)
246+
247+
self.set_mem_bank(_FUNC_CFG_BANK_USER)
248+
return val
249+
250+
def _write_page(self, address, val):
251+
msb = (address >> 8) & 0x0F
252+
lsb = address & 0xFF
253+
254+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
255+
256+
# Clear both read and write bits first, then set write bit (bit 6).
257+
self._write_reg(_PAGE_RW, (self._read_reg(_PAGE_RW) & 0x9F) | 0x40)
258+
259+
# select page
260+
self._write_reg(_PAGE_SEL, (msb << 4) | 0x01)
261+
262+
# set page addr
263+
self._write_reg(_PAGE_ADDRESS, lsb)
264+
265+
# write value
266+
self._write_reg(_PAGE_VALUE, val)
267+
268+
# unset page write and page_sel
269+
self._write_reg(_PAGE_SEL, 0x01)
270+
self._clear_bits(_PAGE_RW, 0x40)
271+
272+
self.set_mem_bank(_FUNC_CFG_BANK_USER)
273+
199274
def reset(self):
200275
self._write_reg(_CTRL3_C, self._read_reg(_CTRL3_C) | 0x1)
201276
for i in range(10):
@@ -258,6 +333,88 @@ def mlc_output(self):
258333
self.set_mem_bank(_FUNC_CFG_BANK_USER)
259334
return buf
260335

336+
@property
337+
def pedometer_enabled(self):
338+
"""Whether the pedometer feature is enabled."""
339+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
340+
data = self._read_reg(_EMB_FUNC_EN_A)
341+
self.set_mem_bank(_FUNC_CFG_BANK_USER)
342+
return bool(data & _PEDO_EN_MASK)
343+
344+
@pedometer_enabled.setter
345+
def pedometer_enabled(self, enable):
346+
"""Enable or disable the pedometer feature."""
347+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
348+
if enable:
349+
self._set_bits(_EMB_FUNC_EN_A, _PEDO_EN_MASK)
350+
else:
351+
self._clear_bits(_EMB_FUNC_EN_A, _PEDO_EN_MASK)
352+
self.set_mem_bank(_FUNC_CFG_BANK_USER)
353+
354+
def pedometer_reset(self):
355+
"""Reset the step counter."""
356+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
357+
self._set_bits(_EMB_FUNC_SRC, _PEDO_RST_STEP_MASK)
358+
self.set_mem_bank(_FUNC_CFG_BANK_USER)
359+
360+
@property
361+
def pedometer_int1_enabled(self):
362+
"""Whether step detection interrupt is routed to INT1 pin."""
363+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
364+
data = self._read_reg(_EMB_FUNC_INT1)
365+
self.set_mem_bank(_FUNC_CFG_BANK_USER)
366+
return bool(data & _PEDO_INT_MASK)
367+
368+
@pedometer_int1_enabled.setter
369+
def pedometer_int1_enabled(self, enable):
370+
"""Route step detection interrupt to INT1 pin."""
371+
if enable:
372+
self._set_bits(_MD1_CFG, _INT_EMB_FUNC_MASK)
373+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
374+
self._set_bits(_EMB_FUNC_INT1, _PEDO_INT_MASK)
375+
else:
376+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
377+
self._clear_bits(_EMB_FUNC_INT1, _PEDO_INT_MASK)
378+
self.set_mem_bank(_FUNC_CFG_BANK_USER)
379+
380+
@property
381+
def pedometer_int2_enabled(self):
382+
"""Whether step detection interrupt is routed to INT2 pin."""
383+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
384+
data = self._read_reg(_EMB_FUNC_INT2)
385+
self.set_mem_bank(_FUNC_CFG_BANK_USER)
386+
return bool(data & _PEDO_INT_MASK)
387+
388+
@pedometer_int2_enabled.setter
389+
def pedometer_int2_enabled(self, enable):
390+
"""Route step detection interrupt to INT2 pin."""
391+
if enable:
392+
self._set_bits(_MD2_CFG, _INT_EMB_FUNC_MASK)
393+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
394+
self._set_bits(_EMB_FUNC_INT2, _PEDO_INT_MASK)
395+
else:
396+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
397+
self._clear_bits(_EMB_FUNC_INT2, _PEDO_INT_MASK)
398+
self.set_mem_bank(_FUNC_CFG_BANK_USER)
399+
400+
@property
401+
def pedometer_steps(self):
402+
"""Return the number of detected steps."""
403+
self.set_mem_bank(_FUNC_CFG_BANK_EMBED)
404+
self._read_reg_into(_STEP_COUNTER_L, self.scratch_2b)
405+
self.set_mem_bank(_FUNC_CFG_BANK_USER)
406+
return self.scratch_2b[0] | (self.scratch_2b[1] << 8)
407+
408+
@property
409+
def pedometer_debounce_steps(self):
410+
"""Get the pedometer debounce steps."""
411+
return self._read_page(_PEDO_DEB_STEPS_CONF)
412+
413+
@pedometer_debounce_steps.setter
414+
def pedometer_debounce_steps(self, steps):
415+
"""Set the pedometer debounce steps. Default is 10."""
416+
self._write_page(_PEDO_DEB_STEPS_CONF, steps)
417+
261418
def gyro(self):
262419
"""Returns gyroscope vector in degrees/sec."""
263420
mv = memoryview(self.scratch_int)

0 commit comments

Comments
 (0)