5555__version__ = "0.0.0-auto.0"
5656__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LSM6DS.git"
5757
58+ import struct
5859from time import sleep
5960from math import radians
6061from micropython import const
6162from adafruit_bus_device import i2c_device
6263
6364from adafruit_register .i2c_struct import ROUnaryStruct , Struct
6465from adafruit_register .i2c_bits import RWBits
65- from adafruit_register .i2c_bit import RWBit
66+ from adafruit_register .i2c_bit import RWBit , ROBit
6667
6768try :
6869 from typing import Tuple , Optional
@@ -139,22 +140,34 @@ class AccelHPF(CV):
139140
140141LSM6DS_CHIP_ID = const (0x6C )
141142
143+ _LSM6DS_MLC_INT1 = const (0x0D )
142144_LSM6DS_WHOAMI = const (0xF )
143145_LSM6DS_CTRL1_XL = const (0x10 )
144146_LSM6DS_CTRL2_G = const (0x11 )
145147_LSM6DS_CTRL3_C = const (0x12 )
146148_LSM6DS_CTRL8_XL = const (0x17 )
147149_LSM6DS_CTRL9_XL = const (0x18 )
148150_LSM6DS_CTRL10_C = const (0x19 )
151+ _LSM6DS_ALL_INT_SRC = const (0x1A )
149152_LSM6DS_OUT_TEMP_L = const (0x20 )
150153_LSM6DS_OUTX_L_G = const (0x22 )
151154_LSM6DS_OUTX_L_A = const (0x28 )
155+ _LSM6DS_MLC_STATUS = const (0x38 )
152156_LSM6DS_STEP_COUNTER = const (0x4B )
157+ _LSM6DS_TAP_CFG0 = const (0x56 )
153158_LSM6DS_TAP_CFG = const (0x58 )
154-
159+ _LSM6DS_MLC0_SRC = const ( 0x70 )
155160_MILLI_G_TO_ACCEL = 0.00980665
156161
157162
163+ _LSM6DS_EMB_FUNC_EN_A = const (0x04 )
164+ _LSM6DS_EMB_FUNC_EN_B = const (0x05 )
165+ _LSM6DS_FUNC_CFG_ACCESS = const (0x01 )
166+ _LSM6DS_FUNC_CFG_BANK_USER = const (0 )
167+ _LSM6DS_FUNC_CFG_BANK_HUB = const (1 )
168+ _LSM6DS_FUNC_CFG_BANK_EMBED = const (2 )
169+
170+
158171class LSM6DS : # pylint: disable=too-many-instance-attributes
159172
160173 """Driver for the LSM6DSOX 6-axis accelerometer and gyroscope.
@@ -171,7 +184,9 @@ class LSM6DS: # pylint: disable=too-many-instance-attributes
171184 _raw_accel_data = Struct (_LSM6DS_OUTX_L_A , "<hhh" )
172185 _raw_gyro_data = Struct (_LSM6DS_OUTX_L_G , "<hhh" )
173186 _raw_temp_data = Struct (_LSM6DS_OUT_TEMP_L , "<h" )
174-
187+ _emb_func_en_a = Struct (_LSM6DS_EMB_FUNC_EN_A , "<b" )
188+ _emb_func_en_b = Struct (_LSM6DS_EMB_FUNC_EN_B , "<b" )
189+ _mlc0_src = Struct (_LSM6DS_MLC0_SRC , "<bbbbbbbb" )
175190 # RWBits:
176191 _accel_range = RWBits (2 , _LSM6DS_CTRL1_XL , 2 )
177192 _accel_data_rate = RWBits (4 , _LSM6DS_CTRL1_XL , 4 )
@@ -187,13 +202,22 @@ class LSM6DS: # pylint: disable=too-many-instance-attributes
187202 _i3c_disable = RWBit (_LSM6DS_CTRL9_XL , 1 )
188203 _pedometer_reset = RWBit (_LSM6DS_CTRL10_C , 1 )
189204 _func_enable = RWBit (_LSM6DS_CTRL10_C , 2 )
205+ _mem_bank = RWBit (_LSM6DS_FUNC_CFG_ACCESS , 7 )
206+ _mlc_status = ROBit (_LSM6DS_MLC_STATUS , 0 )
207+ _i3c_disable = RWBit (_LSM6DS_CTRL9_XL , 0 )
208+ _block_data_enable = RWBit (_LSM6DS_CTRL3_C , 4 )
209+ _route_int1 = RWBit (_LSM6DS_MLC_INT1 , 0 )
210+ _tap_latch = RWBit (_LSM6DS_TAP_CFG0 , 0 )
211+ _tap_clear = RWBit (_LSM6DS_TAP_CFG0 , 6 )
190212 _ped_enable = RWBit (_LSM6DS_TAP_CFG , 6 )
191213 pedometer_steps = ROUnaryStruct (_LSM6DS_STEP_COUNTER , "<h" )
192214 """The number of steps detected by the pedometer. You must enable with `pedometer_enable`
193215 before calling. Use ``pedometer_reset`` to reset the number of steps"""
194216 CHIP_ID = None
195217
196- def __init__ (self , i2c_bus : I2C , address : int = LSM6DS_DEFAULT_ADDRESS ) -> None :
218+ def __init__ (
219+ self , i2c_bus : I2C , address : int = LSM6DS_DEFAULT_ADDRESS , ucf : str = None
220+ ) -> None :
197221 self ._cached_accel_range = None
198222 self ._cached_gyro_range = None
199223
@@ -215,6 +239,9 @@ def __init__(self, i2c_bus: I2C, address: int = LSM6DS_DEFAULT_ADDRESS) -> None:
215239
216240 self .accelerometer_range = AccelRange .RANGE_4G # pylint: disable=no-member
217241 self .gyro_range = GyroRange .RANGE_250_DPS # pylint: disable=no-member
242+ # Load and configure MLC if UCF file is provided
243+ if ucf is not None :
244+ self .load_mlc (ucf )
218245
219246 def reset (self ) -> None :
220247 "Resets the sensor's configuration into an initial state"
@@ -376,3 +403,62 @@ def temperature(self) -> float:
376403 return (temp - 2 ** 13 ) * 0.0625
377404
378405 return temp * 0.0625
406+
407+ def _set_embedded_functions (self , enable , emb_ab = None ):
408+ """Enable/disable embedded functions - returns prior settings when disabled"""
409+ self ._mem_bank = 1
410+ if enable :
411+ self ._emb_func_en_a = emb_ab [0 ]
412+ self ._emb_func_en_b = emb_ab [1 ]
413+ else :
414+ emb_a = self ._emb_func_en_a
415+ emb_b = self ._emb_func_en_b
416+ self ._emb_func_en_a = (emb_a [0 ] & 0xC7 ,)
417+ self ._emb_func_en_b = (emb_b [0 ] & 0xE6 ,)
418+ emb_ab = (emb_a , emb_b )
419+
420+ self ._mem_bank = 0
421+ return emb_ab
422+
423+ def load_mlc (self , ucf ):
424+ """Load MLC configuration file into sensor"""
425+ buf = bytearray (2 )
426+ with self .i2c_device as i2c :
427+ # Load MLC config from file
428+ with open (ucf , "r" ) as ucf_file :
429+ for line in ucf_file :
430+ if line .startswith ("Ac" ):
431+ command = [int (v , 16 ) for v in line .strip ().split (" " )[1 :3 ]]
432+ buf [0 ] = command [0 ]
433+ buf [1 ] = command [1 ]
434+ i2c .write (buf )
435+
436+ # Disable embudded function -- save current settings
437+ emb_ab = self ._set_embedded_functions (False )
438+
439+ # Disable I3C interface
440+ self ._i3c_disable = 1
441+
442+ # Enable Block Data Update
443+ self ._block_data_enable = 1
444+
445+ # Route signals on interrupt pin 1
446+ self ._mem_bank = 1
447+ self ._route_int1 &= 1
448+ self ._mem_bank = 0
449+
450+ # Configure interrupt pin mode
451+ self ._tap_latch = 1
452+ self ._tap_clear = 1
453+
454+ # Enabble Embedded Functions using previously stored settings
455+ self ._set_embedded_functions (True , emb_ab )
456+
457+ def read_mlc_output (self ):
458+ """Read MLC results"""
459+ buf = None
460+ if self ._mlc_status :
461+ self ._mem_bank = 1
462+ buf = self ._mlc0_src
463+ self ._mem_bank = 0
464+ return buf
0 commit comments