It's not necessary to busy wait 150 µs after changing register banks.
Nothing in the data sheet nor app note suggests this. ST's own HAL,
which is used by this driver, does not delay when changing banks. It
does a bank change around every function that accesses a non-user bank
register (it's quite inefficient).
So if it was necessary it would be broken now, as most of the bank
changes have no delay.
One of the few page changes that did have this delay are the those done
before and after reading a sensor sample. Which is where the speed is
significant and is limiting the update rate the driver is capable of.
Signed-off-by: Trent Piepho <trent.piepho@igorinstitute.com>
The code in the ST HAL does a read/modify/write to change the bits in
the LSM6DSO_FUNC_CFG_ACCESS register that control which register bank is
active.
All the other bits in the register are defined as zero. It's possible
to simply set the register to the desired value without reading the
contents first.
This bank switch needs to be done twice for every sensor read when the
sensor hub is used. The driver as it is can not keep up with the higher
update rates of the lsm6dso. So any speed increase in this code allows
for a higher update rate as well as reduced latency.
Previously, a read of the lsm6dso's accel and gyro on a 400 kHz I2C bus
with a 3-axis magnetometer on the sensor hub takes 2.69 ms. This drops
that to 2.26 ms. This is enough to support the 417 Hz ODR.
Signed-off-by: Trent Piepho <trent.piepho@igorinstitute.com>
There is a flaw with I2C communication to peripherals behind the shub
that causes sporadic failures. Especially calls to configure a device
after the lsm6dso initialization is finished, e.g. to set the ODR, can
fail to work correctly.
Access to shub peripheral registers is done by putting the parameters of
the operation into SLV0 and then waiting for the lsm6dso to perform the
xfer on the shub I2C bus. The lsm6dso does this in sync with the
accelerometer update rate. Once the shub is enabled, it peforms the
xfer repeatedly as the accelermeter is sampled.
The wait has a problem: It might detect that a previous shub xfer has
finished, which was done before SLV0 was programmed with new parameters.
The shub status register is read-to-clear. This isn't in the data sheet
or app note, but it is. By reading the status before enabling the
sensor and after programming SLV0, we can be sure when it becomes set it
has finished the current operation and not a previous one.
Also set the write-once flag before shub init. This causes the shub to
only perform I2C writes once instead of continuously. This was set at
the end of init, so any writes done during it would repeat until the
shub was disabled.
Put a timeout in the code that polls for the sensor hub op complete. It
could possibly poll forever. More importantly, if there is no device
connected to the sensor hub, the lsm6dso does not timeout on the
operation for ~13 seconds. Since the shub init does a probe for devices
on startup, this will happen if shub support is enabled but a lsm6dso
has no sensor hub devices. There could be multiple devices, some with
additional sensors and some without. Initialization of the devices
without additional sensors takes tens of seconds without this timeout
being added.
Add a 300 µs wait after disabling the sensor hub. This is necessary
according to the ST app note AN5192 §7.2.1.
Read the shub status from the main bank register instead of the shub
bank register. This avoids an extra bank switch before and after each
status poll. Actually two bank switches on each side, since the lsm6dso
driver switched banks and then the ST HAL function to get the status
register switches again.
The wait for the shub I2C transaction to finish is not needed when the
shub is enabled at the end of init. We aren't starting a new I2C write
or reading the result of a read.
Signed-off-by: Trent Piepho <trent.piepho@igorinstitute.com>
Following zephyr's style guideline, all if statements, including single
line statements shall have braces.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
In order to bring consistency in-tree, migrate all drivers to the new
prefix <zephyr/...>. Note that the conversion has been scripted, refer
to #45388 for more details.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
In case of multi-instance the driver tries to discover whether
there are devices attached to SDx/SCx sensorhub bus. If not it
just turns the shub_inited variable (inside data structure) to false
and skips doing any further sensorhub related action for that
particular LSM6DSO device instance, regardless the fact that the macro
CONFIG_LSM6DSO_SENSORHUB is enabled.
Moreover, the info found during the enumeration process for a
particular instance (number and types of attached devices) must be
saved inside the per-instance data structure, so that more than one
LSM6DSO device can be used as a sensorhub without interfering with
the others.
Signed-off-by: Armando Visconti <armando.visconti@st.com>
Move ctx structure from struct data to struct config, so that
it can be filled at compile time and we could get rid of the bus
init routines.
Signed-off-by: Armando Visconti <armando.visconti@st.com>
Make this driver multi-instance and use the new API.
This commit makes use of some DT macro helpers
In particular:
- get bus devices with DEVICE_DT_GET
- get SPI information with SPI_CONFIG_DT_INST
- get drdy gpios with GPIO_DT_SPEC_GET
Moreover the driver is now using the stmemsc common
routines as requested in issue #33440 and it avoids
the unnecessary declaration of both ctx_i2c and ctx_spi
in the data structure.
Signed-off-by: Armando Visconti <armando.visconti@st.com>
Now that device_api attribute is unmodified at runtime, as well as all
the other attributes, it is possible to switch all device driver
instance to be constant.
A coccinelle rule is used for this:
@r_const_dev_1
disable optional_qualifier
@
@@
-struct device *
+const struct device *
@r_const_dev_2
disable optional_qualifier
@
@@
-struct device * const
+const struct device *
Fixes#27399
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Some sensor drivers modify there struct's based on DT defines. In those
cases we need to make sure that DT_DRV_COMPAT is set on all the source
files associated with that driver. This updates any such files.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Kernel timeouts have always been a 32 bit integer despite the
existence of generation macros, and existing code has been
inconsistent about using them. Upcoming commits are going to make the
timeout arguments opaque, so fix things up to be rigorously correct.
Changes include:
+ Adding a K_TIMEOUT_EQ() macro for code that needs to compare timeout
values for equality (e.g. with K_FOREVER or K_NO_WAIT).
+ Adding a k_msleep() synonym for k_sleep() which can continue to take
integral arguments as k_sleep() moves away to timeout arguments.
+ Pervasively using the K_MSEC(), K_SECONDS(), et. al. macros to
generate timeout arguments.
+ Removing the usage of K_NO_WAIT as the final argument to
K_THREAD_DEFINE(). This is just a count of milliseconds and we need
to use a zero.
This patch include no logic changes and should not affect generated
code at all.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The build infrastructure should not be adding the drivers subdirectory
to the include path. Fix the legacy uses that depended on that
addition.
Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
Cast to (void) the lsm6dso_mem_bank_set() calls as we
are not interested to the return value.
Coverity-CID: 205625
Signed-off-by: Armando Visconti <armando.visconti@st.com>
All sensors were using legacy log module registeration method
where LOG_LEVEL was defined before registeration. This method
was error prone as it requires preserving includes order.
Replaced with LOG_MODULE_REGISTER(foo, level).
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Re-run with updated script to convert integer literal delay arguments to
k_sleep to use the standard timeout macros.
Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
Add support to STM LSM6DSO 6-axis IMU sensor driver.
This driver supports communication with device though both
I2C and SPI bus and both polling and drdy trigger mode.
This driver supports also the sensorhub mode with the possibility
to connect a maximum of two external devices, typically a
magnetometer and an environmental sensor, currently selected among
following devices: lis2mdl magnetometer, lps22hh or lps22hb
pressure and temperature sensors, HTS221 humidity sensor.
Signed-off-by: Armando Visconti <armando.visconti@st.com>