drivers/sensor: lsm6dso: Fix shub init and configuration failures
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>
Loading
Please sign in to comment