6060_OUTX_L_G = const (0x22 )
6161_OUTX_L_XL = const (0x28 )
6262_MLC_STATUS = const (0x38 )
63+ _MD1_CFG = const (0x5E )
64+ _MD2_CFG = const (0x5F )
65+
66+ _PAGE_SEL = const (0x02 )
67+ _PAGE_ADDRESS = const (0x08 )
68+ _PAGE_VALUE = const (0x09 )
69+ _PAGE_RW = const (0x17 )
6370
6471_DEFAULT_ADDR = const (0x6A )
6572_WHO_AM_I_REG = const (0x0F )
7582
7683_EMB_FUNC_EN_A = const (0x04 )
7784_EMB_FUNC_EN_B = const (0x05 )
85+ _EMB_FUNC_INT1 = const (0x0A )
86+ _EMB_FUNC_INT2 = const (0x0E )
87+ _EMB_FUNC_SRC = const (0x64 )
88+ _STEP_COUNTER_L = const (0x62 )
89+
90+ _PEDO_DEB_STEPS_CONF = const (0x0184 )
91+
92+ _PEDO_EN_MASK = const (0x08 )
93+ _PEDO_RST_STEP_MASK = const (0x80 )
94+ _PEDO_INT_MASK = const (0x08 )
95+ _INT_EMB_FUNC_MASK = const (0x02 )
7896
7997
8098class LSM6DSOX :
@@ -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,9 @@ def _write_reg(self, reg, val):
185204 finally :
186205 self .cs (1 )
187206
207+ def _modify_bits (self , reg , clr_mask = 0 , set_mask = 0 ):
208+ self ._write_reg (reg , (self ._read_reg (reg ) & ~ clr_mask ) | set_mask )
209+
188210 def _read_reg_into (self , reg , buf ):
189211 if self ._use_i2c :
190212 self .bus .readfrom_mem_into (self .address , reg , buf )
@@ -196,17 +218,51 @@ def _read_reg_into(self, reg, buf):
196218 finally :
197219 self .cs (1 )
198220
221+ def _select_page (self , address , value = None ):
222+ """
223+ Selects the embedded function page and reads/writes the value at the given address.
224+ If value is None, it reads the value at the address. Otherwise, it writes the value to the address.
225+ """
226+ msb = (address >> 8 ) & 0x0F # MSB is the page number
227+ lsb = address & 0xFF # LSB is the register address within the page
228+
229+ self .set_mem_bank (_FUNC_CFG_BANK_EMBED )
230+
231+ rw_bit = 0x20 if value is None else 0x40
232+ # Clear both read and write bits first, then set read (bit 5) or write (bit 6).
233+ self ._modify_bits (_PAGE_RW , clr_mask = 0x60 , set_mask = rw_bit )
234+
235+ # select page
236+ self ._write_reg (_PAGE_SEL , (msb << 4 ) | 0x01 )
237+
238+ # set page addr
239+ self ._write_reg (_PAGE_ADDRESS , lsb )
240+
241+ val = None
242+ if value is None :
243+ # read value
244+ val = self ._read_reg (_PAGE_VALUE )
245+ else :
246+ # write value
247+ self ._write_reg (_PAGE_VALUE , value )
248+
249+ # unset page write/read and page_sel
250+ self ._write_reg (_PAGE_SEL , 0x01 )
251+ self ._modify_bits (_PAGE_RW , clr_mask = rw_bit )
252+
253+ self .set_mem_bank (_FUNC_CFG_BANK_USER )
254+ return val
255+
199256 def reset (self ):
200- self ._write_reg (_CTRL3_C , self . _read_reg ( _CTRL3_C ) | 0x1 )
257+ self ._modify_bits (_CTRL3_C , set_mask = 0x1 )
201258 for i in range (10 ):
202259 if (self ._read_reg (_CTRL3_C ) & 0x01 ) == 0 :
203260 return
204261 time .sleep_ms (10 )
205262 raise OSError ("Failed to reset LSM6DS device." )
206263
207264 def set_mem_bank (self , bank ):
208- cfg = self ._read_reg (_FUNC_CFG_ACCESS ) & 0x3F
209- self ._write_reg (_FUNC_CFG_ACCESS , cfg | (bank << 6 ))
265+ self ._modify_bits (_FUNC_CFG_ACCESS , clr_mask = 0xC0 , set_mask = (bank << 6 ))
210266
211267 def set_embedded_functions (self , enable , emb_ab = None ):
212268 self .set_mem_bank (_FUNC_CFG_BANK_EMBED )
@@ -234,18 +290,18 @@ def load_mlc(self, ucf):
234290 emb_ab = self .set_embedded_functions (False )
235291
236292 # Disable I3C interface
237- self ._write_reg (_CTRL9_XL , self . _read_reg ( _CTRL9_XL ) | 0x01 )
293+ self ._modify_bits (_CTRL9_XL , set_mask = 0x01 )
238294
239295 # Enable Block Data Update
240- self ._write_reg (_CTRL3_C , self . _read_reg ( _CTRL3_C ) | 0x40 )
296+ self ._modify_bits (_CTRL3_C , set_mask = 0x40 )
241297
242298 # Route signals on interrupt pin 1
243299 self .set_mem_bank (_FUNC_CFG_BANK_EMBED )
244- self ._write_reg (_MLC_INT1 , self . _read_reg ( _MLC_INT1 ) & 0x01 )
300+ self ._modify_bits (_MLC_INT1 , clr_mask = 0xFE )
245301 self .set_mem_bank (_FUNC_CFG_BANK_USER )
246302
247303 # Configure interrupt pin mode
248- self ._write_reg (_TAP_CFG0 , self . _read_reg ( _TAP_CFG0 ) | 0x41 )
304+ self ._modify_bits (_TAP_CFG0 , set_mask = 0x41 )
249305
250306 self .set_embedded_functions (True , emb_ab )
251307
@@ -258,6 +314,36 @@ def mlc_output(self):
258314 self .set_mem_bank (_FUNC_CFG_BANK_USER )
259315 return buf
260316
317+ def pedometer_config (self , enable = True , debounce = 10 , int1_enable = False , int2_enable = False ):
318+ """Configure the pedometer features."""
319+ self ._select_page (_PEDO_DEB_STEPS_CONF , debounce )
320+
321+ if int1_enable :
322+ self ._modify_bits (_MD1_CFG , set_mask = _INT_EMB_FUNC_MASK )
323+ if int2_enable :
324+ self ._modify_bits (_MD2_CFG , set_mask = _INT_EMB_FUNC_MASK )
325+
326+ self .set_mem_bank (_FUNC_CFG_BANK_EMBED )
327+
328+ self ._modify_bits (_EMB_FUNC_EN_A , _PEDO_EN_MASK , enable and _PEDO_EN_MASK )
329+ self ._modify_bits (_EMB_FUNC_INT1 , _PEDO_INT_MASK , int1_enable and _PEDO_INT_MASK )
330+ self ._modify_bits (_EMB_FUNC_INT2 , _PEDO_INT_MASK , int2_enable and _PEDO_INT_MASK )
331+
332+ self .set_mem_bank (_FUNC_CFG_BANK_USER )
333+
334+ def pedometer_reset (self ):
335+ """Reset the step counter."""
336+ self .set_mem_bank (_FUNC_CFG_BANK_EMBED )
337+ self ._modify_bits (_EMB_FUNC_SRC , set_mask = _PEDO_RST_STEP_MASK )
338+ self .set_mem_bank (_FUNC_CFG_BANK_USER )
339+
340+ def steps (self ):
341+ """Return the number of detected steps."""
342+ self .set_mem_bank (_FUNC_CFG_BANK_EMBED )
343+ self ._read_reg_into (_STEP_COUNTER_L , self .scratch_2b )
344+ self .set_mem_bank (_FUNC_CFG_BANK_USER )
345+ return self .scratch_2b [0 ] | (self .scratch_2b [1 ] << 8 )
346+
261347 def gyro (self ):
262348 """Returns gyroscope vector in degrees/sec."""
263349 mv = memoryview (self .scratch_int )
0 commit comments