samples: basic: custom devicetree binding demo

This sample shows how to define a custom devicetree binding to use
GPIO pins for a specific purpose.

Signed-off-by: Martin Jäger <martin@libre.solar>
This commit is contained in:
Martin Jäger 2020-05-25 17:47:00 +02:00 committed by Carles Cufí
commit aef8419e9e
7 changed files with 153 additions and 0 deletions

View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(gpio_custom_dts_binding)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

View file

@ -0,0 +1,55 @@
.. _gpio-custom-dts-binding-sample:
GPIO with custom devicetree binding
###################################
Overview
********
In Zephyr, all hardware-specific configuration is described in the devicetree.
Consequently, also GPIO pins are configured in the devicetree and assigned to a specific purpose
using a compatible.
This is in contrast to other embedded environments like Arduino, where e.g. the direction (input /
output) of a GPIO pin is configured in the application firmware.
For typical use cases like LEDs or buttons, the existing :dtcompatible:`gpio-leds` or
:dtcompatible:`gpio-keys` compatibles can be used.
This sample demonstrates how to use a GPIO pin for other purposes with a custom devicetree binding.
We assume that a load with high current demands should be switched on or off via a MOSFET. The
custom devicetree binding for the power output controlled via a GPIO pin is specified in the file
:zephyr_file:`samples/basic/custom_dts_binding/dts/bindings/power-switch.yaml`. The gate driver for
the MOSFET would be connected to the pin as specified in the ``.overlay`` file in the boards
folder.
Building and Running
********************
For each board that should be supported, a ``.overlay`` file has to be defined
in the ``boards`` subfolder.
Afterwards, the sample can be built and executed for the ``<board>`` as follows:
.. zephyr-app-commands::
:zephyr-app: samples/basic/custom_dts_binding
:board: <board>
:goals: build flash
:compact:
For demonstration purposes, some boards use the GPIO pin of the built-in LED.
Sample output
=============
The GPIO pin should be switched to active level after one second.
The following output is printed:
.. code-block:: console
Initializing pin with inactive level.
Waiting one second.
Setting pin to active level.

View file

@ -0,0 +1,13 @@
/*
* Copyright (c) 2023 Martin Jäger / Libre Solar
*
* SPDX-License-Identifier: Apache-2.0
*/
/ {
load_switch: load_switch {
compatible = "power-switch";
/* using built-in LED pin for demonstration */
gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>;
};
};

View file

@ -0,0 +1,13 @@
# Copyright (c) 2023 Libre Solar Technologies GmbH
# SPDX-License-Identifier: Apache-2.0
description: GPIO pin to switch a power output on or off
compatible: "power-switch"
properties:
gpios:
type: phandle-array
required: true
description: |
The GPIO connected to the gate driver for the MOSFET.

View file

@ -0,0 +1 @@
CONFIG_GPIO=y

View file

@ -0,0 +1,16 @@
sample:
name: GPIO with custom devicetree binding
tests:
sample.basic.custom_dts_binding:
tags: gpio devicetree
platform_allow: nucleo_l073rz
integration_platforms:
- nucleo_l073rz
depends_on: gpio
harness: console
harness_config:
type: multi_line
regex:
- "Initializing pin with inactive level."
- "Waiting one second."
- "Setting pin to active level."

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2023 Libre Solar Technologies GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#if !DT_NODE_EXISTS(DT_NODELABEL(load_switch))
#error "Overlay for power output node not properly defined."
#endif
static const struct gpio_dt_spec load_switch =
GPIO_DT_SPEC_GET_OR(DT_NODELABEL(load_switch), gpios, {0});
void main(void)
{
int err;
if (!gpio_is_ready_dt(&load_switch)) {
printf("The load switch pin GPIO port is not ready.\n");
return;
}
printf("Initializing pin with inactive level.\n");
err = gpio_pin_configure_dt(&load_switch, GPIO_OUTPUT_INACTIVE);
if (err != 0) {
printf("Configuring GPIO pin failed: %d\n", err);
return;
}
printf("Waiting one second.\n");
k_sleep(K_MSEC(1000));
printf("Setting pin to active level.\n");
err = gpio_pin_set_dt(&load_switch, 1);
if (err != 0) {
printf("Setting GPIO pin level failed: %d\n", err);
}
}