Commit e70c167c authored by David Boddie's avatar David Boddie
Browse files

Add inertial module D-Bus information, refactor files

parent 55c49455
Pipeline #52336 passed with stage
in 1 minute and 24 seconds
......@@ -3,15 +3,12 @@
Inertial Module
===============
.. |I2C| raw:: html
I<sup>2</sup>C
The Librem 5 development board is equipped with a collection of sensors provided
by the `LSM9DS1`_ inertial module, including a accelerometer, gyroscope and
magnetometer. These sensors can be accessed programmatically via messages sent
to the relevant addresses on the appropriate |I2C| bus. Applications can also
receive sensor information by accessing the appropriate system D-Bus interface.
magnetometer. At a low level, these sensors can be accessed programmatically
via messages sent to the relevant addresses on the appropriate |I2C| bus.
Applications will typically receive sensor information by accessing the
appropriate system D-Bus interface.
.. contents::
:local:
......@@ -19,149 +16,56 @@ receive sensor information by accessing the appropriate system D-Bus interface.
This guide provides a basic overview of the commands that can be used to access
each device; first via the D-Bus interface, then using the I2C bus.
D-Bus Interface
---------------
.. note:: Support for this interface is only present in recent kernels. Please
update the kernel on your device if you experience problems starting
the service.
The gyroscope and magnetometer are exposed to applications via the
`net.hadess.SensorProxy`_ service on the system D-Bus. This is provided by the
`iio-sensor-proxy`_ service.
Information about the orientation of the phone and the magnetic field can be
obtained by querying the interface provided by the D-Bus service, calling
methods to access devices and reading their properties.
.. /sys/bus/iio/devices/iio:device0 is where data are exposed to user space.
Preparations
~~~~~~~~~~~~
If the ``iio-sensor-proxy`` daemon is not already running, start it from the
command line in the following way::
systemctl start iio-sensor-proxy
Check that it is running with this command::
systemctl status iio-sensor-proxy
This should include useful information to help diagnose problems if the service
does not start.
I2C Bus
-------
.. note:: This section contains advice that only works with older Linux
kernels that do not have built-in support for the inertial module.
If the ``i2cdetect`` tool does not produce the expected output then
the devices are being managed by the kernel and their |I2C|
interfaces are not accessible to user space programs.
The inertial module exposes a magnetometer via one |I2C| bus address and both
an accelerometer and gyroscope via another. Each device contains a set of
registers that can be accessed by their addresses in that device. This means
that we need two addresses -- a bus address and a device address -- to access a
register.
The kernel provides abstractions that allow the sensors to be accessed fairly
simply without requiring knowledge of the message protocol used for |I2C|
devices.
Preparations
~~~~~~~~~~~~
Before trying to access the sensors as the ``purism`` user, you need to
install the ``i2c-tools`` package on the development board::
sudo apt install i2c-tools
Then add the ``purism`` user to the ``i2c`` group::
sudo usermod -a -G i2c purism
This user should now have permission to read and write the device files for the
|I2C| devices and run the tools to access them.
Magnetometer
~~~~~~~~~~~~
The magnetometer is available via address ``0x1e`` on |I2C| bus 2. This can be
verified by running the ``i2cdetect`` tool::
purism@pureos:~$ /usr/sbin/i2cdetect -y 2
This should produce output like the following::
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- UU -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- UU -- --
60: 60 -- -- -- -- -- -- -- -- -- UU -- -- -- -- --
70: -- -- -- -- -- -- -- --
It should be clear that there is a device at address ``0x1e`` on the |I2C| bus
-- this should be the magnetometer.
Reading the Device ID
+++++++++++++++++++++
.. include:: ../../common/Sensors_DBus.txt
We check that the device at address ``0x1e`` on |I2C| bus 2 is the magnetometer
by querying its ``WHO_AM_I_M`` register, which should be readable at address
``0x0f`` on the device. We can do this with the ``i2cget`` tool::
.. code:: bash
/usr/sbin/i2cget -y 2 0x1e 0x0f
purism@pureos:~$ monitor-sensor | grep Accelerometer
Accelerometer orientation changed: bottom-up
Accelerometer orientation changed: right-up
Accelerometer orientation changed: left-up
Accelerometer orientation changed: normal
The expected value is ``0x3d`` for the magnetometer. If a different value is
returned then the device is not the one we were expecting.
This provides verification that the sensor is reporting changes via the D-Bus interface.
Powering the Device
+++++++++++++++++++
Reading the Device Orientation
------------------------------
Initially, the device will be powered down. To determine its state we read its
``CTRL_REG3_M`` register at ``0x22`` on the device::
Using the ``gdbus`` tool again, first check that the accelerometer is available to be read:
/usr/sbin/i2cget -y 2 0x1e 0x22
.. code:: bash
This should return ``0x03``, indicating an operating mode of binary ``11``
(power-down mode). Set it to ``00`` (continuous-conversion mode) with the
``i2cset`` tool::
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
--method org.freedesktop.DBus.Properties.Get \
net.hadess.SensorProxy HasAccelerometer
/usr/sbin/i2cset -y 2 0x1e 0x22 0
If it returns ``(<true>,)`` then you can claim the sensor:
When we no longer need to read from the device, we set the operating mode to
power-down again::
.. code:: bash
/usr/sbin/i2cset -y 2 0x1e 0x22 3
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
--method net.hadess.SensorProxy.ClaimAccelerometer
We can read the state of the device again to verify that it has powered down,
if necessary.
This will cause the ``AccelerometerOrientation`` property to be updated:
Obtaining Readings
++++++++++++++++++
.. code:: bash
We need to enable temperature compensation if we want accurate readings. This
is done by setting bit 7 (``0x80``) in the ``CTRL_REG1_M`` register at ``0x20``
on the device. This is in addition to the existing value of ``0x18`` that the
register contains, so we write a value of ``0x98``::
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
--method org.freedesktop.DBus.Properties.Get \
net.hadess.SensorProxy AccelerometerOrientation
/usr/sbin/i2cset -y 2 0x1e 0x20 0x98
Finally, release the sensor to stop the service from polling the device:
It is now possible to obtain readings for the three components of the magnetic
field along each axis (x, y and z respectively) from the registers, ``OUT_X_M``,
``OUT_Y_M`` and ``OUT_Z_M``, passing the ``w`` argument to indicate that these
registers are 16-bits in size::
.. code:: bash
/usr/sbin/i2cget -y 2 0x1e 0x28 w
/usr/sbin/i2cget -y 2 0x1e 0x2a w
/usr/sbin/i2cget -y 2 0x1e 0x2c w
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
--method net.hadess.SensorProxy.ReleaseAccelerometer
If you reorientate the development board and read these values again, you should
notice that the values have changed.
This can also be performed using the ``Gio.DBusProxy`` class -- see the
`GNOME API Reference`_ for further information.
.. include:: /links.txt
......@@ -3,15 +3,11 @@
Proximity and Ambient Light Sensor
==================================
.. |I2C| raw:: html
I<sup>2</sup>C
The Librem 5 development board has a proximity sensor (PS) and ambient light
sensor (ALS) provided by the `VCNL4040M3OE-H5`_ module. These sensors can be
accessed programmatically via messages sent to the relevant addresses on the
appropriate |I2C| bus. Applications can also receive sensor information by
accessing the appropriate system D-Bus interface.
sensor (ALS) provided by the `VCNL4040M3OE-H5`_ module. At a low level, these
sensors can be accessed programmatically via messages sent to the relevant
addresses on the appropriate |I2C| bus. Applications will typically receive
sensor information by accessing the appropriate system D-Bus interface.
.. contents::
:local:
......@@ -20,63 +16,53 @@ This guide provides a basic overview of the commands that can be used to obtain
ambient light and proximity information from the device; first via the D-Bus
interface, then using the I2C bus.
D-Bus Interface
---------------
.. note:: Support for this interface is only present in recent kernels. Please
update the kernel on your device if you experience problems starting
the service.
The ambient light and proximity sensors are exposed to applications via the
`net.hadess.SensorProxy`_ service on the system D-Bus. This is provided by the
`iio-sensor-proxy`_ service.
Information about the light level and proximity of nearby objects can be
obtained by querying the interface provided by the D-Bus service, calling
methods to access devices and reading their properties.
.. include:: ../../common/Sensors_DBus.txt
Preparations
~~~~~~~~~~~~
.. code:: bash
If the ``iio-sensor-proxy`` daemon is not already running, start it from the
command line in the following way::
purism@pureos:~$ monitor-sensor | grep Light
Light changed: 1.440000 (lux)
Light changed: 1.800000 (lux)
Light changed: 16.560000 (lux)
Light changed: 8.040000 (lux)
Light changed: 1.440000 (lux)
Light changed: 3.240000 (lux)
Light changed: 0.000000 (lux)
systemctl start iio-sensor-proxy
This provides verification that the sensor is reporting changes via the D-Bus interface.
Check that it is running with this command::
systemctl status iio-sensor-proxy
This should include useful information to help diagnose problems if the service
does not start.
Reading the Ambient Light Level
-------------------------------
Introspecting the D-Bus Object
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using the ``gdbus`` tool again, first check that the ambient light sensor is available to be read:
It is useful to get an overview of the properties and methods that the service
exposes via D-Bus. Use the ``gdbus`` tool from the command line to discover
these::
.. code:: bash
gdbus introspect --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
--method org.freedesktop.DBus.Properties.Get \
net.hadess.SensorProxy HasAmbientLight
Reading the Ambient Light Level
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If it returns ``(<true>,)`` then you can claim the sensor:
Using the ``gdbus`` tool again, first claim the light::
.. code:: bash
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
--method net.hadess.SensorProxy.ClaimLight
This will cause the ``LightLevel`` property to be updated::
This will cause the ``LightLevel`` property to be updated:
.. code:: bash
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
--method org.freedesktop.DBus.Properties.Get \
net.hadess.SensorProxy LightLevel
Finally, release the light to stop the service from polling the device::
Finally, release the sensor to stop the service from polling the device:
.. code:: bash
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
......@@ -85,34 +71,44 @@ Finally, release the light to stop the service from polling the device::
This can also be performed using the ``Gio.DBusProxy`` class -- see the
`GNOME API Reference`_ for further information.
I2C Bus
-------
Reading the Proximity
---------------------
Check that the proximity sensor light is available to be read:
.. code:: bash
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
--method org.freedesktop.DBus.Properties.Get \
net.hadess.SensorProxy HasProximity
.. note:: This section contains advice that only works with older Linux
kernels that do not have built-in support for the proximity and
ambient light sensors.
If the ``i2cdetect`` tool does not produce the expected output then
the devices are being managed by the kernel and their |I2C|
interfaces are not accessible to user space programs.
If it returns ``(<true>,)`` then you can claim the sensor:
The proximity and ambient light sensors are located at the top edge of the
development board below the ``LS1601`` label.
.. code:: bash
.. figure:: images/devkit-ambient-sensor.svg
:align: center
:width: 40%
:alt: The location of the proximity and ambient light sensors (click to enlarge)
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
--method net.hadess.SensorProxy.ClaimProximity
The location of the proximity and ambient light sensors
This will cause the ``ProximityNear`` property to be updated:
.. |i2cbus| replace:: 2
.. |i2c-0a| replace:: UU
.. |i2c-1e| replace:: 1e
.. |i2c-3c| replace:: UU
.. |i2c-3e| replace:: --
.. |i2c-5d| replace:: UU
.. |i2c-60| replace:: 60
.. |i2c-6a| replace:: UU
.. code:: bash
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
--method org.freedesktop.DBus.Properties.Get \
net.hadess.SensorProxy ProximityNear
Finally, release the sensor to stop the service from polling the device:
.. code:: bash
gdbus call --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy \
--method net.hadess.SensorProxy.ReleaseProximity
This can also be performed using the ``Gio.DBusProxy`` class -- see the
`GNOME API Reference`_ for further information.
.. include:: ../../common/Proximity_I2C.txt
.. include:: /links.txt
......@@ -3,10 +3,6 @@
Testing the Proximity and Ambient Light Sensors
===============================================
.. |I2C| raw:: html
I<sup>2</sup>C
The Librem 5 phone has a proximity sensor (PS) and ambient light sensor (ALS) provided by the `VCNL4040M3OE-H5`_ module. These sensors can be accessed programmatically via messages sent to the relevant addresses on the appropriate |I2C| bus. It can be useful to test that these sensors are working before using the appropriate system D-Bus interface.
.. contents::
......
D-Bus Interface
---------------
The sensors are exposed to applications via the `net.hadess.SensorProxy`_
service on the system D-Bus. This is provided by the `iio-sensor-proxy`_
service.
Information from the sensors can be obtained by querying the interface provided
by the D-Bus service, calling methods to access devices and reading their
properties.
Preparations
------------
If the ``iio-sensor-proxy`` daemon is not already running, start it from the
command line in the following way::
systemctl start iio-sensor-proxy
Check that it is running with this command::
systemctl status iio-sensor-proxy
This should include useful information to help diagnose problems if the service
does not start.
Introspecting the D-Bus Object
------------------------------
It is useful to get an overview of the properties and methods that the service
exposes via D-Bus. Use the ``gdbus`` tool from the command line to discover
these:
.. code:: bash
gdbus introspect --system --dest net.hadess.SensorProxy \
--object-path /net/hadess/SensorProxy
Monitor the Sensor
------------------
It can be useful to quickly check that the sensors are working by running the ``monitor-sensor`` tool, as shown in this shell output:
.. code:: bash
purism@pureos:-$ monitor-sensor
Waiting for iio-sensor-proxy to appear
+++ iio-sensor-proxy appeared
=== Has accelerometer (orientation: bottom-up)
=== Has ambient light sensor (value: 0.000000, unit: lux)
=== No proximity sensor
The tool outputs information from all sensors. By filtering the output from ``monitor-sensor`` you can see changes to the sensor you are interested in.
......@@ -295,3 +295,9 @@
.. _`Etnaviv`: https://github.com/etnaviv
.. _`J5 Create JCA374`: https://en.j5create.com/collections/type-c/products/jca374
.. Common substitutions
.. |I2C| raw:: html
I<sup>2</sup>C
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment