|  | .. _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. | 
|  |  | 
|  | 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 a node alias for each connector interface. | 
|  | For example, for Arduino I2C: | 
|  |  | 
|  | .. code-block:: DTS | 
|  |  | 
|  | #define arduino_i2c i2c1 | 
|  |  | 
|  | aliases { | 
|  | arduino,i2c = &i2c1; | 
|  | }; | 
|  |  | 
|  | Note: With support of dtc v1.4.2, above will be replaced with the recently | 
|  | introduced overriding node element: | 
|  |  | 
|  | .. code-block:: DTS | 
|  |  | 
|  | 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. |