Skip to content

Commit 4105af7

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

File tree

1 file changed

+157
-1
lines changed

1 file changed

+157
-1
lines changed

micropython/drivers/imu/lsm6dsox/lsm6dsox.py

Lines changed: 157 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,7 +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)
7892

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)
7997

8098
class LSM6DSOX:
8199
def __init__(
@@ -108,8 +126,9 @@ def __init__(
108126
if self._read_reg(_WHO_AM_I_REG) != 108:
109127
raise OSError("No LSM6DS device was found at address 0x%x" % (self.address))
110128

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

114133
SCALE_GYRO = {250: 0, 500: 1, 1000: 2, 2000: 3}
115134
SCALE_ACCEL = {2: 0, 4: 2, 8: 3, 16: 1}
@@ -185,6 +204,12 @@ def _write_reg(self, reg, val):
185204
finally:
186205
self.cs(1)
187206

207+
def _set_bits(self, reg, mask):
208+
self._write_reg(reg, self._read_reg(reg) | mask)
209+
210+
def _clear_bits(self, reg, mask):
211+
self._write_reg(reg, self._read_reg(reg) & ~mask)
212+
188213
def _read_reg_into(self, reg, buf):
189214
if self._use_i2c:
190215
self.bus.readfrom_mem_into(self.address, reg, buf)
@@ -196,6 +221,55 @@ def _read_reg_into(self, reg, buf):
196221
finally:
197222
self.cs(1)
198223

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

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

0 commit comments

Comments
 (0)