210 lines
7.1 KiB
ReStructuredText
210 lines
7.1 KiB
ReStructuredText
.. _shields:
|
|
|
|
Shields
|
|
#######
|
|
|
|
Shields, also known as "add-on" or "daughter boards", attach to a board
|
|
to extend its features and services for easier and modularized prototyping.
|
|
In Zephyr, the shield feature provides Zephyr-formatted shield
|
|
descriptions for easier compatibility with applications.
|
|
|
|
Shield porting and configuration
|
|
********************************
|
|
|
|
Shield configuration files are available in the board directory
|
|
under :zephyr_file:`/boards/shields`:
|
|
|
|
.. code-block:: none
|
|
|
|
boards/shields/<shield>
|
|
├── <shield>.overlay
|
|
├── Kconfig.shield
|
|
└── Kconfig.defconfig
|
|
|
|
These files provides shield configuration as follows:
|
|
|
|
* **<shield>.overlay**: This file provides a shield description in devicetree
|
|
format that is merged with the board's :ref:`devicetree <dt-guide>`
|
|
before compilation.
|
|
|
|
* **Kconfig.shield**: This file defines shield Kconfig symbols that will be
|
|
used for default shield configuration. To ease use with applications,
|
|
the default shield configuration here should be consistent with those in
|
|
the :ref:`default_board_configuration`.
|
|
|
|
* **Kconfig.defconfig**: This file defines the default shield configuration. It
|
|
is made to be consistent with the :ref:`default_board_configuration`. Hence,
|
|
shield configuration should be done by keeping in mind that features
|
|
activation is application responsibility.
|
|
|
|
Besides, in order to avoid name conflicts with devices that may be defined at
|
|
board level, it is advised, specifically for shields devicetree descriptions,
|
|
to provide a device nodelabel is the form <device>_<shield>, for instance:
|
|
|
|
.. code-block:: devicetree
|
|
|
|
sdhc_myshield: sdhc@1 {
|
|
reg = <1>;
|
|
...
|
|
};
|
|
|
|
|
|
Board compatibility
|
|
*******************
|
|
|
|
Hardware shield-to-board compatibility depends on the use of well-known
|
|
connectors used on popular boards (such as Arduino and 96boards). For
|
|
software compatibility, boards must also provide a configuration matching
|
|
their supported connectors.
|
|
|
|
This should be done at two different level:
|
|
|
|
* Pinmux: Connector pins should be correctly configured to match shield pins
|
|
|
|
* Devicetree: A board :ref:`devicetree <dt-guide>` file,
|
|
:file:`BOARD.dts` should define an alternate nodelabel for each connector interface.
|
|
For example, for Arduino I2C:
|
|
|
|
.. code-block:: devicetree
|
|
|
|
arduino_i2c: &i2c1 {};
|
|
|
|
Board specific shield configuration
|
|
-----------------------------------
|
|
|
|
If modifications are needed to fit a shield to a particular board or board
|
|
revision, you can override a shield description for a specific board by adding
|
|
board or board revision overriding files to a shield, as follows:
|
|
|
|
.. code-block:: none
|
|
|
|
boards/shields/<shield>
|
|
└── boards
|
|
├── <board>_<revision>.overlay
|
|
├── <board>.overlay
|
|
├── <board>.defconfig
|
|
├── <board>_<revision>.conf
|
|
└── <board>.conf
|
|
|
|
|
|
Shield activation
|
|
*****************
|
|
|
|
Activate support for one or more shields by adding the matching -DSHIELD arg to
|
|
CMake command
|
|
|
|
.. zephyr-app-commands::
|
|
:zephyr-app: your_app
|
|
:shield: "x_nucleo_idb05a1 x_nucleo_iks01a1"
|
|
:goals: build
|
|
|
|
|
|
Alternatively, it could be set by default in a project's CMakeLists.txt:
|
|
|
|
.. code-block:: none
|
|
|
|
set(SHIELD x_nucleo_iks01a1)
|
|
|
|
Shield variants
|
|
***************
|
|
|
|
Some shields may support several variants or revisions. In that case, it is
|
|
possible to provide multiple version of the shields description:
|
|
|
|
.. code-block:: none
|
|
|
|
boards/shields/<shield>
|
|
├── <shield_v1>.overlay
|
|
├── <shield_v1>.defconfig
|
|
├── <shield_v2>.overlay
|
|
└── <shield_v2>.defconfig
|
|
|
|
In this case, a shield-particular revision name can be used:
|
|
|
|
.. zephyr-app-commands::
|
|
:zephyr-app: your_app
|
|
:shield: shield_v2
|
|
:goals: build
|
|
|
|
You can also provide a board-specific configuration to a specific shield
|
|
revision:
|
|
|
|
.. code-block:: none
|
|
|
|
boards/shields/<shield>
|
|
├── <shield_v1>.overlay
|
|
├── <shield_v1>.defconfig
|
|
├── <shield_v2>.overlay
|
|
├── <shield_v2>.defconfig
|
|
└── boards
|
|
└── <shield_v2>
|
|
├── <board>.overlay
|
|
└── <board>.defconfig
|
|
|
|
GPIO nexus nodes
|
|
****************
|
|
|
|
GPIOs accessed by the shield peripherals must be identified using the
|
|
shield GPIO abstraction, for example from the ``arduino-header-r3``
|
|
compatible. Boards that provide the header must map the header pins
|
|
to SOC-specific pins. This is accomplished by including a `nexus
|
|
node`_ that looks like the following into the board devicetree file:
|
|
|
|
.. _nexus node:
|
|
https://github.com/devicetree-org/devicetree-specification/blob/4b1dac80eaca45b4babf5299452a951008a5d864/source/devicetree-basics.rst#nexus-nodes-and-specifier-mapping
|
|
|
|
.. code-block:: none
|
|
|
|
arduino_header: connector {
|
|
compatible = "arduino-header-r3";
|
|
#gpio-cells = <2>;
|
|
gpio-map-mask = <0xffffffff 0xffffffc0>;
|
|
gpio-map-pass-thru = <0 0x3f>;
|
|
gpio-map = <0 0 &gpioa 0 0>, /* A0 */
|
|
<1 0 &gpioa 1 0>, /* A1 */
|
|
<2 0 &gpioa 4 0>, /* A2 */
|
|
<3 0 &gpiob 0 0>, /* A3 */
|
|
<4 0 &gpioc 1 0>, /* A4 */
|
|
<5 0 &gpioc 0 0>, /* A5 */
|
|
<6 0 &gpioa 3 0>, /* D0 */
|
|
<7 0 &gpioa 2 0>, /* D1 */
|
|
<8 0 &gpioa 10 0>, /* D2 */
|
|
<9 0 &gpiob 3 0>, /* D3 */
|
|
<10 0 &gpiob 5 0>, /* D4 */
|
|
<11 0 &gpiob 4 0>, /* D5 */
|
|
<12 0 &gpiob 10 0>, /* D6 */
|
|
<13 0 &gpioa 8 0>, /* D7 */
|
|
<14 0 &gpioa 9 0>, /* D8 */
|
|
<15 0 &gpioc 7 0>, /* D9 */
|
|
<16 0 &gpiob 6 0>, /* D10 */
|
|
<17 0 &gpioa 7 0>, /* D11 */
|
|
<18 0 &gpioa 6 0>, /* D12 */
|
|
<19 0 &gpioa 5 0>, /* D13 */
|
|
<20 0 &gpiob 9 0>, /* D14 */
|
|
<21 0 &gpiob 8 0>; /* D15 */
|
|
};
|
|
|
|
This specifies how Arduino pin references like ``<&arduino_header 11
|
|
0>`` are converted to SOC gpio pin references like ``<&gpiob 4 0>``.
|
|
|
|
In Zephyr GPIO specifiers generally have two parameters (indicated by
|
|
``#gpio-cells = <2>``): the pin number and a set of flags. The low 6
|
|
bits of the flags correspond to features that can be configured in
|
|
devicetree. In some cases it's necessary to use a non-zero flag value
|
|
to tell the driver how a particular pin behaves, as with:
|
|
|
|
.. code-block:: none
|
|
|
|
drdy-gpios = <&arduino_header 11 GPIO_ACTIVE_LOW>;
|
|
|
|
After preprocessing this becomes ``<&arduino_header 11 1>``. Normally
|
|
the presence of such a flag would cause the map lookup to fail,
|
|
because there is no map entry with a non-zero flags value. The
|
|
``gpio-map-mask`` property specifies that, for lookup, all bits of the
|
|
pin and all but the low 6 bits of the flags are used to identify the
|
|
specifier. Then the ``gpio-map-pass-thru`` specifies that the low 6
|
|
bits of the flags are copied over, so the SOC GPIO reference becomes
|
|
``<&gpiob 4 1>`` as intended.
|
|
|
|
See `nexus node`_ for more information about this capability.
|