From patchwork Fri Jun 23 04:38:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1798739 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=WMKzgAZo; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QnPfS2NQDz20Xp for ; Fri, 23 Jun 2023 14:39:44 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231144AbjFWEjl (ORCPT ); Fri, 23 Jun 2023 00:39:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46492 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231281AbjFWEja (ORCPT ); Fri, 23 Jun 2023 00:39:30 -0400 Received: from mail-oi1-x235.google.com (mail-oi1-x235.google.com [IPv6:2607:f8b0:4864:20::235]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 708112126 for ; Thu, 22 Jun 2023 21:39:25 -0700 (PDT) Received: by mail-oi1-x235.google.com with SMTP id 5614622812f47-38c35975545so164082b6e.1 for ; Thu, 22 Jun 2023 21:39:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687495164; x=1690087164; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=aoK00yeec6APSg9Ik1QujBFi/HkkdEKRwbIwZAAu4Cs=; b=WMKzgAZovnacf/xXuRAWLGzCq3wdv1okMb+W0FxjTM/SNdEbB0tIq/7DpO8ItP7L3i QsnNptVRaW2IkSUgZSJWjt1L5NBd2WIY2FjJBmYJu14jALzq/+VorP4ktuEwI4MAr+iy 3+0nP+dL96SP8SitTccUC0s0GEZV1ar9iTNB9ln6HWz30u3EYh2QvhOCgAx/apbRCA/N tGJvo3MJkWi3nUqxB3oFZJvVNMrX9Njrw7t5pknXLPpHD1pky4lPhcNoasgOdJe28lML HceopcnLhz2RJHydgoFwnhhA0I849YZk0UdDdjJxcZgkQN4z2Y+5PvOBQ5p1N7t2dP3H tbSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687495164; x=1690087164; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aoK00yeec6APSg9Ik1QujBFi/HkkdEKRwbIwZAAu4Cs=; b=hzTBR/Z3IVqD/2YTD9VaZFO3t54IvL+Rqx5elzusPj4+h40x6dgz1qFl/svfL2EK/x HsWn0jq7ubtsmk9azBh0aQxsO9UXi/vTrYVjX/LDoHPX5b/YwUYX7N/N0Sn18cBpgHjt WLbvrEqFNX0RX4Y33Jatf3FSmpFHSGsqK8R6zMPs//oYd7YiG6X3DdOqqspLUJRXw0CD I0Z2hoS3Zy8YY6InHCuuDvzCqkPc07DW8qVWpFSQzFs6uVBpFI5yxirnupqB28EltrGZ 0+/lRzuUqHVcf4p9jmdPPcYI18T9xSHfqFqD9C/C1eRFDaGdtHgNSKlvvqdUdFCh4Cd2 U15w== X-Gm-Message-State: AC+VfDwML0o0UGs+qXImOEul3gF6IsZWIDLhV+K5lyWzuNqy3HpP2aH6 Ug30f2k06xC2oVh+49crG4rtmJYSHSc= X-Google-Smtp-Source: ACHHUZ5Fk1+BI3KO5dAOlbpnecnccoWfc4La/Yk3O7wd0+iR1W5j2yfKvj3ADa7GW2exJBHKn2Dbmg== X-Received: by 2002:a05:6808:2007:b0:39e:b986:6601 with SMTP id q7-20020a056808200700b0039eb9866601mr14347462oiw.28.1687495164631; Thu, 22 Jun 2023 21:39:24 -0700 (PDT) Received: from sol.home.arpa (194-223-178-180.tpgi.com.au. [194.223.178.180]) by smtp.gmail.com with ESMTPSA id q23-20020a17090ad39700b0025c2c398d33sm509463pju.39.2023.06.22.21.39.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jun 2023 21:39:24 -0700 (PDT) From: Kent Gibson To: linux-gpio@vger.kernel.org, brgl@bgdev.pl Cc: Kent Gibson Subject: [libgpiod][PATCH 1/8] core: examples: consistency cleanups Date: Fri, 23 Jun 2023 12:38:54 +0800 Message-ID: <20230623043901.16764-2-warthog618@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230623043901.16764-1-warthog618@gmail.com> References: <20230623043901.16764-1-warthog618@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org A collection of minor cleanups to make the examples more consistent and ease the addition of more examples: - reformat Makefile.am to simplify adding more examples - add line offset to value output - remove commas from edge event output - replace while(1) with for (;;) - fix a typo in Makefile.am - fix an error handling goto in toggle_line_value.c Signed-off-by: Kent Gibson --- examples/Makefile.am | 8 ++++++-- examples/async_watch_line_value.c | 6 +++--- examples/get_line_value.c | 11 +++++++---- examples/toggle_line_value.c | 17 ++++++++++------- examples/watch_line_value.c | 6 +++--- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/examples/Makefile.am b/examples/Makefile.am index 4ad124b..55dfe39 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -6,12 +6,16 @@ AM_CFLAGS += -Wall -Wextra -g -std=gnu89 LDADD = $(top_builddir)/lib/libgpiod.la -bin_PROGRAMS = async_watch_line_value get_line_value toggle_line_value watch_line_value +noinst_PROGRAMS = \ + async_watch_line_value \ + get_line_value \ + toggle_line_value \ + watch_line_value async_watch_line_value_SOURCES = async_watch_line_value.c get_line_value_SOURCES = get_line_value.c -toggle_line_valuer_SOURCES = toggle_line_value.c +toggle_line_value_SOURCES = toggle_line_value.c watch_line_value_SOURCES = watch_line_value.c diff --git a/examples/async_watch_line_value.c b/examples/async_watch_line_value.c index 3292dda..f35fb1a 100644 --- a/examples/async_watch_line_value.c +++ b/examples/async_watch_line_value.c @@ -74,7 +74,7 @@ static const char *edge_event_type_str(struct gpiod_edge_event *event) { switch (gpiod_edge_event_get_event_type(event)) { case GPIOD_EDGE_EVENT_RISING_EDGE: - return "Rising "; + return "Rising"; case GPIOD_EDGE_EVENT_FALLING_EDGE: return "Falling"; default: @@ -117,7 +117,7 @@ int main(void) pollfd.fd = gpiod_line_request_get_fd(request); pollfd.events = POLLIN; - while (1) { + for (;;) { ret = poll(&pollfd, 1, -1); if (ret == -1) { fprintf(stderr, "error waiting for edge events: %s\n", @@ -134,7 +134,7 @@ int main(void) for (i = 0; i < ret; i++) { event = gpiod_edge_event_buffer_get_event(event_buffer, i); - printf("offset: %d, type: %s, event #%ld\n", + printf("offset: %d type: %-7s event #%ld\n", gpiod_edge_event_get_line_offset(event), edge_event_type_str(event), gpiod_edge_event_get_line_seqno(event)); diff --git a/examples/get_line_value.c b/examples/get_line_value.c index 08e263a..1de9901 100644 --- a/examples/get_line_value.c +++ b/examples/get_line_value.c @@ -64,12 +64,12 @@ close_chip: return request; } -static int print_value(enum gpiod_line_value value) +static int print_value(unsigned int offset, enum gpiod_line_value value) { if (value == GPIOD_LINE_VALUE_ACTIVE) - printf("Active\n"); + printf("%d=Active\n", offset); else if (value == GPIOD_LINE_VALUE_INACTIVE) { - printf("Inactive\n"); + printf("%d=Inactive\n", offset); } else { fprintf(stderr, "error reading value: %s\n", strerror(errno)); @@ -97,7 +97,10 @@ int main(void) } value = gpiod_line_request_get_value(request, line_offset); - ret = print_value(value); + ret = print_value(line_offset, value); + + /* not strictly required here, but if the app wasn't exiting... */ + gpiod_line_request_release(request); return ret; } diff --git a/examples/toggle_line_value.c b/examples/toggle_line_value.c index 63d7fb9..6e522d6 100644 --- a/examples/toggle_line_value.c +++ b/examples/toggle_line_value.c @@ -40,7 +40,7 @@ request_output_line(const char *chip_path, unsigned int offset, ret = gpiod_line_config_add_line_settings(line_cfg, &offset, 1, settings); if (ret) - goto free_settings; + goto free_line_config; if (consumer) { req_cfg = gpiod_request_config_new(); @@ -72,12 +72,15 @@ static enum gpiod_line_value toggle_line_value(enum gpiod_line_value value) GPIOD_LINE_VALUE_ACTIVE; } -static void print_value(enum gpiod_line_value value) +static const char * value_str(enum gpiod_line_value value) { if (value == GPIOD_LINE_VALUE_ACTIVE) - printf("Active\n"); - else - printf("Inactive\n"); + return "Active"; + else if (value == GPIOD_LINE_VALUE_INACTIVE) { + return "Inactive"; + } else { + return "Unknown"; + } } int main(void) @@ -97,8 +100,8 @@ int main(void) return EXIT_FAILURE; } - while (1) { - print_value(value); + for (;;) { + printf("%d=%s\n", line_offset, value_str(value)); sleep(1); value = toggle_line_value(value); gpiod_line_request_set_value(request, line_offset, value); diff --git a/examples/watch_line_value.c b/examples/watch_line_value.c index d962f20..879b09b 100644 --- a/examples/watch_line_value.c +++ b/examples/watch_line_value.c @@ -73,7 +73,7 @@ static const char *edge_event_type_str(struct gpiod_edge_event *event) { switch (gpiod_edge_event_get_event_type(event)) { case GPIOD_EDGE_EVENT_RISING_EDGE: - return "Rising "; + return "Rising"; case GPIOD_EDGE_EVENT_FALLING_EDGE: return "Falling"; default: @@ -112,7 +112,7 @@ int main(void) return EXIT_FAILURE; } - while (1) { + for (;;) { /* Blocks until at least one event is available. */ ret = gpiod_line_request_read_edge_events(request, event_buffer, event_buf_size); @@ -124,7 +124,7 @@ int main(void) for (i = 0; i < ret; i++) { event = gpiod_edge_event_buffer_get_event(event_buffer, i); - printf("offset: %d, type: %s, event #%ld\n", + printf("offset: %d type: %-7s event #%ld\n", gpiod_edge_event_get_line_offset(event), edge_event_type_str(event), gpiod_edge_event_get_line_seqno(event)); From patchwork Fri Jun 23 04:38:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1798740 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=gFy1K8do; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QnPfd122Gz20XS for ; Fri, 23 Jun 2023 14:39:53 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230091AbjFWEjr (ORCPT ); Fri, 23 Jun 2023 00:39:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46298 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231135AbjFWEjk (ORCPT ); Fri, 23 Jun 2023 00:39:40 -0400 Received: from mail-qt1-x832.google.com (mail-qt1-x832.google.com [IPv6:2607:f8b0:4864:20::832]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52F352128 for ; Thu, 22 Jun 2023 21:39:37 -0700 (PDT) Received: by mail-qt1-x832.google.com with SMTP id d75a77b69052e-3f9b1f43bd0so3884841cf.0 for ; Thu, 22 Jun 2023 21:39:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687495176; x=1690087176; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ctNOQCyLHkudXr2/oPyM3S869JlUqDDShl06PMk1r+c=; b=gFy1K8doszE1L2IesBdlEKkGH4mtYNEMsl4xrdlYJtVa7tD3UD7gol4v9VlnRSfMAy HS5L8d2VdY9+6JRRPN8NY1irCflLY33XPUMSnAdQD4nD5x0aPJyTz0fpnzk3NfMjvJuc /PbdhQHfnBnYSbMdzOKqJfL/EwT7jq1hOF5uJHrbKv116y7gEDU3725a+QyEtXbE3yez 33OSpMG5Q/ePz2G/6t7zH6JRyHbQeNnqAdkT7VhCGnTf5ZEtpIkhbR08ktPSC+h6xFho GNjH87icGJI8ybCoSTdi3/ioc0pYxj6PKAt0XvsT9dnOUF26QBCjecqwVMUFV3MhYRdO dXjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687495176; x=1690087176; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ctNOQCyLHkudXr2/oPyM3S869JlUqDDShl06PMk1r+c=; b=U8X86H86dIXOH/SnvcSiAZVmZz9QhIzK9z3nv7Q3UnC/ouQMMGwuwatlnzehl/WLRq BkrmlYj1/sWHPcHC6EgmSn3LCuy9Zlvk5nDY3J23SSk5r8uLqMEZVjyFKxKKKQhOilMn Qz1v3PrYiOee3vKAiVv/zWFeUog2d5kl/VFkBfif7nZpaORmkH0Bnh4Zb8YMyxXYCufn rFcQ39kyHl2UvJXrlPp6TCL7bsSphlqpgNjxZfJ6tF+XfvuafKl9TZXoB/WM+zfa38Gp 3fHB/5iR00AdHzzuoBYnHjtsDAQF8gN2Z8aSBHBt+S1LJAXQxstVR0aWbnZvx2du8A+p f+wg== X-Gm-Message-State: AC+VfDwGWsmL14emMq70EofFsaCsB+O/K7HEVIGxRXDneFaivVmzqh2Q 17G/tC+bqbrCQ/J9hZ9kLsH0EQNf27U= X-Google-Smtp-Source: ACHHUZ7S1mCsUQ4BydDOh9Hv8CbF8+xA4tqAkWc3H/gi+t3/6ZVBiShMUOeF140LYdV3g5B8jq/6wA== X-Received: by 2002:a05:622a:1cb:b0:3fd:e07a:24f7 with SMTP id t11-20020a05622a01cb00b003fde07a24f7mr14431222qtw.40.1687495175741; Thu, 22 Jun 2023 21:39:35 -0700 (PDT) Received: from sol.home.arpa (194-223-178-180.tpgi.com.au. [194.223.178.180]) by smtp.gmail.com with ESMTPSA id q23-20020a17090ad39700b0025c2c398d33sm509463pju.39.2023.06.22.21.39.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jun 2023 21:39:35 -0700 (PDT) From: Kent Gibson To: linux-gpio@vger.kernel.org, brgl@bgdev.pl Cc: Kent Gibson Subject: [libgpiod][PATCH 2/8] core: examples: add more use case examples Date: Fri, 23 Jun 2023 12:38:55 +0800 Message-ID: <20230623043901.16764-3-warthog618@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230623043901.16764-1-warthog618@gmail.com> References: <20230623043901.16764-1-warthog618@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add examples for use cases drawn from the tools. Signed-off-by: Kent Gibson --- examples/.gitignore | 9 ++ examples/Makefile.am | 29 ++++- examples/find_line_by_name.c | 111 ++++++++++++++++++ examples/get_chip_info.c | 40 +++++++ examples/get_line_info.c | 56 +++++++++ examples/get_multiple_line_values.c | 119 +++++++++++++++++++ examples/reconfigure_input_to_output.c | 152 +++++++++++++++++++++++++ examples/toggle_multiple_line_values.c | 136 ++++++++++++++++++++++ examples/watch_line_info.c | 72 ++++++++++++ examples/watch_line_rising.c | 129 +++++++++++++++++++++ examples/watch_multiple_line_values.c | 140 +++++++++++++++++++++++ 11 files changed, 992 insertions(+), 1 deletion(-) create mode 100644 examples/find_line_by_name.c create mode 100644 examples/get_chip_info.c create mode 100644 examples/get_line_info.c create mode 100644 examples/get_multiple_line_values.c create mode 100644 examples/reconfigure_input_to_output.c create mode 100644 examples/toggle_multiple_line_values.c create mode 100644 examples/watch_line_info.c create mode 100644 examples/watch_line_rising.c create mode 100644 examples/watch_multiple_line_values.c diff --git a/examples/.gitignore b/examples/.gitignore index bdfde9a..8fd3ff3 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -2,6 +2,15 @@ # SPDX-FileCopyrightText: 2023 Kent Gibson async_watch_line_value +find_line_by_name +get_chip_info +get_line_info get_line_value +get_multiple_line_values +reconfigure_input_to_output toggle_line_value +toggle_multiple_line_values +watch_line_info +watch_line_rising watch_line_value +watch_multiple_line_values diff --git a/examples/Makefile.am b/examples/Makefile.am index 55dfe39..daf902b 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -8,14 +8,41 @@ LDADD = $(top_builddir)/lib/libgpiod.la noinst_PROGRAMS = \ async_watch_line_value \ + find_line_by_name \ + get_chip_info \ + get_line_info \ get_line_value \ + get_multiple_line_values \ + reconfigure_input_to_output \ toggle_line_value \ - watch_line_value + toggle_multiple_line_values \ + watch_line_info \ + watch_line_rising \ + watch_line_value \ + watch_multiple_line_values async_watch_line_value_SOURCES = async_watch_line_value.c +find_line_by_name_SOURCES = find_line_by_name.c + +get_chip_info_SOURCES = get_chip_info.c + +get_line_info_SOURCES = get_line_info.c + get_line_value_SOURCES = get_line_value.c +get_multiple_line_values_SOURCES = get_multiple_line_values.c + +reconfigure_input_to_output_SOURCES = reconfigure_input_to_output.c + toggle_line_value_SOURCES = toggle_line_value.c +toggle_multiple_line_value_SOURCES = toggle_multiple_line_value.c + +watch_line_info_SOURCES = watch_line_info.c + +watch_line_rising_SOURCES = watch_line_rising.c + watch_line_value_SOURCES = watch_line_value.c + +watch_multiple_line_values_SOURCES = watch_multiple_line_values.c diff --git a/examples/find_line_by_name.c b/examples/find_line_by_name.c new file mode 100644 index 0000000..ea1d938 --- /dev/null +++ b/examples/find_line_by_name.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of finding a line with the given name. */ + +#include +#include +#include +#include +#include +#include +#include + +static int chip_dir_filter(const struct dirent *entry) +{ + struct stat sb; + int ret = 0; + char *path; + + if (asprintf(&path, "/dev/%s", entry->d_name) < 0) + return 0; + + if ((lstat(path, &sb) == 0) && (!S_ISLNK(sb.st_mode)) && + gpiod_is_gpiochip_device(path)) + ret = 1; + + free(path); + + return ret; +} + +static int all_chip_paths(char ***paths_ptr) +{ + int i, j, num_chips, ret = 0; + struct dirent **entries; + char **paths; + + num_chips = scandir("/dev/", &entries, chip_dir_filter, versionsort); + if (num_chips < 0) + return 0; + + paths = calloc(num_chips, sizeof(*paths)); + if (!paths) + return 0; + + for (i = 0; i < num_chips; i++) { + if (asprintf(&paths[i], "/dev/%s", entries[i]->d_name) < 0) { + for (j = 0; j < i; j++) + free(paths[j]); + + free(paths); + return 0; + } + } + + *paths_ptr = paths; + ret = num_chips; + + for (i = 0; i < num_chips; i++) + free(entries[i]); + + free(entries); + return ret; +} + +int main(void) +{ + /* Example configuration - customize to suit your situation. */ + static const char *const line_name = "GPIO19"; + + struct gpiod_chip *chip; + struct gpiod_chip_info *cinfo; + struct gpiod_line_info *linfo; + char **chip_paths; + const char *name; + unsigned int j, num_lines; + int i, num_chips; + + /* + * Names are not guaranteed unique, so this finds the first line with + * the given name. + */ + num_chips = all_chip_paths(&chip_paths); + for (i = 0; i < num_chips; i++) { + chip = gpiod_chip_open(chip_paths[i]); + if (!chip) + continue; + cinfo = gpiod_chip_get_info(chip); + if (!cinfo) + continue; + + num_lines = gpiod_chip_info_get_num_lines(cinfo); + for (j = 0; j < num_lines; j++) { + linfo = gpiod_chip_get_line_info(chip, j); + if (!linfo) + continue; + name = gpiod_line_info_get_name(linfo); + if (name && (strcmp(line_name, name) == 0)) { + printf("%s: %s %d\n", line_name, + gpiod_chip_info_get_name(cinfo), j); + return EXIT_SUCCESS; + } + gpiod_line_info_free(linfo); + } + gpiod_chip_info_free(cinfo); + gpiod_chip_close(chip); + } + + printf("line '%s' not found\n", line_name); + return EXIT_FAILURE; +} diff --git a/examples/get_chip_info.c b/examples/get_chip_info.c new file mode 100644 index 0000000..5c181c8 --- /dev/null +++ b/examples/get_chip_info.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of reading the info for a chip. */ + +#include +#include +#include +#include +#include + +int main(void) +{ + /* Example configuration - customize to suit your situation. */ + static const char *const chip_path = "/dev/gpiochip0"; + + struct gpiod_chip_info *info; + struct gpiod_chip *chip; + + chip = gpiod_chip_open(chip_path); + if (!chip) { + fprintf(stderr, "failed to open chip: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + info = gpiod_chip_get_info(chip); + if (!info) { + fprintf(stderr, "failed to read info: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + printf("%s [%s] (%zu lines)\n", gpiod_chip_info_get_name(info), + gpiod_chip_info_get_label(info), + gpiod_chip_info_get_num_lines(info)); + + gpiod_chip_info_free(info); + gpiod_chip_close(chip); + + return EXIT_SUCCESS; +} diff --git a/examples/get_line_info.c b/examples/get_line_info.c new file mode 100644 index 0000000..743c98f --- /dev/null +++ b/examples/get_line_info.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of reading the info for a line. */ + +#include +#include +#include +#include +#include + +int main(void) +{ + /* Example configuration - customize to suit your situation. */ + static const char *const chip_path = "/dev/gpiochip0"; + static const unsigned int line_offset = 3; + + struct gpiod_line_info *info; + struct gpiod_chip *chip; + const char *name, *consumer, *dir; + + chip = gpiod_chip_open(chip_path); + if (!chip) { + fprintf(stderr, "failed to open chip: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + info = gpiod_chip_get_line_info(chip, line_offset); + if (!info) { + fprintf(stderr, "failed to read info: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + name = gpiod_line_info_get_name(info); + if (!name) + name = "unnamed"; + + consumer = gpiod_line_info_get_consumer(info); + if (!consumer) + consumer = "unused"; + + dir = (gpiod_line_info_get_direction(info) == + GPIOD_LINE_DIRECTION_INPUT) ? + "input" : + "output"; + + printf("line %3d: %12s %12s %8s %10s\n", + gpiod_line_info_get_offset(info), name, consumer, dir, + gpiod_line_info_is_active_low(info) ? "active-low" : + "active-high"); + + gpiod_line_info_free(info); + gpiod_chip_close(chip); + + return EXIT_SUCCESS; +} diff --git a/examples/get_multiple_line_values.c b/examples/get_multiple_line_values.c new file mode 100644 index 0000000..fc26636 --- /dev/null +++ b/examples/get_multiple_line_values.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of reading a single line. */ + +#include +#include +#include +#include +#include + +/* Request a line as input. */ +static struct gpiod_line_request * +request_input_lines(const char *chip_path, const unsigned int *offsets, + unsigned int num_lines, const char *consumer) +{ + struct gpiod_request_config *req_cfg = NULL; + struct gpiod_line_request *request = NULL; + struct gpiod_line_settings *settings; + struct gpiod_line_config *line_cfg; + struct gpiod_chip *chip; + unsigned int i; + int ret; + + chip = gpiod_chip_open(chip_path); + if (!chip) + return NULL; + + settings = gpiod_line_settings_new(); + if (!settings) + goto close_chip; + + gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT); + + line_cfg = gpiod_line_config_new(); + if (!line_cfg) + goto free_settings; + + for (i = 0; i < num_lines; i++) { + ret = gpiod_line_config_add_line_settings(line_cfg, &offsets[i], + 1, settings); + if (ret) + goto free_line_config; + } + + if (consumer) { + req_cfg = gpiod_request_config_new(); + if (!req_cfg) + goto free_line_config; + + gpiod_request_config_set_consumer(req_cfg, consumer); + } + + request = gpiod_chip_request_lines(chip, req_cfg, line_cfg); + + gpiod_request_config_free(req_cfg); + +free_line_config: + gpiod_line_config_free(line_cfg); + +free_settings: + gpiod_line_settings_free(settings); + +close_chip: + gpiod_chip_close(chip); + + return request; +} + +static int print_values(const unsigned int *offsets, unsigned int num_lines, + enum gpiod_line_value *values) +{ + unsigned int i; + + for (i = 0; i < num_lines; i++) { + if (values[i] == GPIOD_LINE_VALUE_ACTIVE) + printf("%d=Active ", offsets[i]); + else if (values[i] == GPIOD_LINE_VALUE_INACTIVE) { + printf("%d=Inactive ", offsets[i]); + } else { + fprintf(stderr, "error reading value: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + } + printf("\n"); + + return EXIT_SUCCESS; +} + +#define NUM_LINES 3 + +int main(void) +{ + /* Example configuration - customize to suit your situation. */ + static const char *const chip_path = "/dev/gpiochip0"; + static const unsigned int line_offsets[NUM_LINES] = { 5, 3, 7 }; + + struct gpiod_line_request *request; + enum gpiod_line_value values[NUM_LINES]; + int ret; + + request = request_input_lines(chip_path, line_offsets, NUM_LINES, + "get-multiple-line-values"); + if (!request) { + fprintf(stderr, "failed to request lines: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + + ret = gpiod_line_request_get_values(request, values); + if (ret == -1) { + fprintf(stderr, "failed to get values: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + ret = print_values(line_offsets, NUM_LINES, values); + + return ret; +} diff --git a/examples/reconfigure_input_to_output.c b/examples/reconfigure_input_to_output.c new file mode 100644 index 0000000..e8fbb1c --- /dev/null +++ b/examples/reconfigure_input_to_output.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of reading a single line. */ + +#include +#include +#include +#include +#include + +/* Request a line as input. */ +static struct gpiod_line_request *request_input_line(const char *chip_path, + unsigned int offset, + const char *consumer) +{ + struct gpiod_request_config *req_cfg = NULL; + struct gpiod_line_request *request = NULL; + struct gpiod_line_settings *settings; + struct gpiod_line_config *line_cfg; + struct gpiod_chip *chip; + int ret; + + chip = gpiod_chip_open(chip_path); + if (!chip) + return NULL; + + settings = gpiod_line_settings_new(); + if (!settings) + goto close_chip; + + gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT); + + line_cfg = gpiod_line_config_new(); + if (!line_cfg) + goto free_settings; + + ret = gpiod_line_config_add_line_settings(line_cfg, &offset, 1, + settings); + if (ret) + goto free_line_config; + + if (consumer) { + req_cfg = gpiod_request_config_new(); + if (!req_cfg) + goto free_line_config; + + gpiod_request_config_set_consumer(req_cfg, consumer); + } + + request = gpiod_chip_request_lines(chip, req_cfg, line_cfg); + + gpiod_request_config_free(req_cfg); + +free_line_config: + gpiod_line_config_free(line_cfg); + +free_settings: + gpiod_line_settings_free(settings); + +close_chip: + gpiod_chip_close(chip); + + return request; +} + +static int reconfigure_as_output_line(struct gpiod_line_request *request, + unsigned int offset, + enum gpiod_line_value value) +{ + struct gpiod_request_config *req_cfg = NULL; + struct gpiod_line_settings *settings; + struct gpiod_line_config *line_cfg; + int ret = -1; + + settings = gpiod_line_settings_new(); + if (!settings) + return -1; + + gpiod_line_settings_set_direction(settings, + GPIOD_LINE_DIRECTION_OUTPUT); + gpiod_line_settings_set_output_value(settings, value); + + line_cfg = gpiod_line_config_new(); + if (!line_cfg) + goto free_settings; + + ret = gpiod_line_config_add_line_settings(line_cfg, &offset, 1, + settings); + if (ret) + goto free_line_config; + + ret = gpiod_line_request_reconfigure_lines(request, line_cfg); + + gpiod_request_config_free(req_cfg); + +free_line_config: + gpiod_line_config_free(line_cfg); + +free_settings: + gpiod_line_settings_free(settings); + + return ret; +} + +static const char * value_str(enum gpiod_line_value value) +{ + if (value == GPIOD_LINE_VALUE_ACTIVE) + return "Active"; + else if (value == GPIOD_LINE_VALUE_INACTIVE) { + return "Inactive"; + } else { + return "Unknown"; + } +} + +int main(void) +{ + /* Example configuration - customize to suit your situation. */ + static const char *const chip_path = "/dev/gpiochip0"; + static const unsigned int line_offset = 5; + + struct gpiod_line_request *request; + enum gpiod_line_value value; + int ret; + + /* request the line initially as an input */ + request = request_input_line(chip_path, line_offset, + "reconfigure-input-to-output"); + if (!request) { + fprintf(stderr, "failed to request line: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + + /* read the current line value */ + value = gpiod_line_request_get_value(request, line_offset); + printf("%d=%s (input)\n", line_offset, value_str(value)); + + /* switch the line to an output and drive it low */ + ret = reconfigure_as_output_line(request, line_offset, + GPIOD_LINE_VALUE_INACTIVE); + + /* report the current driven value */ + value = gpiod_line_request_get_value(request, line_offset); + printf("%d=%s (output)\n", line_offset, value_str(value)); + + /* not strictly required here, but if the app wasn't exiting... */ + gpiod_line_request_release(request); + + return ret; +} diff --git a/examples/toggle_multiple_line_values.c b/examples/toggle_multiple_line_values.c new file mode 100644 index 0000000..059a79f --- /dev/null +++ b/examples/toggle_multiple_line_values.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of toggling multiple lines. */ + +#include +#include +#include +#include +#include +#include + +static struct gpiod_line_request * +request_output_lines(const char *chip_path, const unsigned int *offsets, + enum gpiod_line_value *values, unsigned int num_lines, + const char *consumer) +{ + struct gpiod_request_config *rconfig = NULL; + struct gpiod_line_request *request = NULL; + struct gpiod_line_settings *settings; + struct gpiod_line_config *lconfig; + struct gpiod_chip *chip; + unsigned int i; + int ret; + + chip = gpiod_chip_open(chip_path); + if (!chip) + return NULL; + + settings = gpiod_line_settings_new(); + if (!settings) + goto close_chip; + + gpiod_line_settings_set_direction(settings, + GPIOD_LINE_DIRECTION_OUTPUT); + + lconfig = gpiod_line_config_new(); + if (!lconfig) + goto free_settings; + + for (i = 0; i < num_lines; i++) { + ret = gpiod_line_config_add_line_settings(lconfig, &offsets[i], + 1, settings); + if (ret) + goto free_line_config; + } + gpiod_line_config_set_output_values(lconfig, values, num_lines); + + if (consumer) { + rconfig = gpiod_request_config_new(); + if (!rconfig) + goto free_line_config; + + gpiod_request_config_set_consumer(rconfig, consumer); + } + + request = gpiod_chip_request_lines(chip, rconfig, lconfig); + + gpiod_request_config_free(rconfig); + +free_line_config: + gpiod_line_config_free(lconfig); + +free_settings: + gpiod_line_settings_free(settings); + +close_chip: + gpiod_chip_close(chip); + + return request; +} + +static enum gpiod_line_value toggle_line_value(enum gpiod_line_value value) +{ + return (value == GPIOD_LINE_VALUE_ACTIVE) ? GPIOD_LINE_VALUE_INACTIVE : + GPIOD_LINE_VALUE_ACTIVE; +} + +static void toggle_line_values(enum gpiod_line_value *values, + unsigned int num_lines) +{ + unsigned int i; + + for (i = 0; i < num_lines; i++) { + values[i] = toggle_line_value(values[i]); + } +} + +static void print_values(const unsigned int *offsets, + const enum gpiod_line_value *values, + unsigned int num_lines) +{ + unsigned int i; + + for (i = 0; i < num_lines; i++) { + if (values[i] == GPIOD_LINE_VALUE_ACTIVE) + printf("%d=Active ", offsets[i]); + else + printf("%d=Inactive ", offsets[i]); + } + printf("\n"); +} + +#define NUM_LINES 3 + +int main(void) +{ + /* Example configuration - customize to suit your situation. */ + static const char *const chip_path = "/dev/gpiochip0"; + static const unsigned int line_offsets[NUM_LINES] = { 5, 3, 7 }; + + enum gpiod_line_value values[NUM_LINES] = { GPIOD_LINE_VALUE_ACTIVE, + GPIOD_LINE_VALUE_ACTIVE, + GPIOD_LINE_VALUE_INACTIVE }; + struct gpiod_line_request *request; + + request = request_output_lines(chip_path, line_offsets, values, + NUM_LINES, + "toggle-multiple-line-values"); + if (!request) { + fprintf(stderr, "failed to request line: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + + for (;;) { + print_values(line_offsets, values, NUM_LINES); + sleep(1); + toggle_line_values(values, NUM_LINES); + gpiod_line_request_set_values(request, values); + } + + gpiod_line_request_release(request); + + return EXIT_SUCCESS; +} diff --git a/examples/watch_line_info.c b/examples/watch_line_info.c new file mode 100644 index 0000000..51fb5c7 --- /dev/null +++ b/examples/watch_line_info.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of watching for info changes on particular lines. */ + +#include +#include +#include +#include +#include + +const char *event_type(struct gpiod_info_event *event) +{ + switch (gpiod_info_event_get_event_type(event)) { + case GPIOD_INFO_EVENT_LINE_REQUESTED: + return "Requested"; + case GPIOD_INFO_EVENT_LINE_RELEASED: + return "Released"; + case GPIOD_INFO_EVENT_LINE_CONFIG_CHANGED: + return "Reconfig"; + default: + return "Unknown"; + } +} + +#define NUM_LINES 3 + +int main(void) +{ + /* Example configuration - customize to suit your situation. */ + static const char *const chip_path = "/dev/gpiochip0"; + static const unsigned int line_offsets[NUM_LINES] = { 5, 3, 7 }; + + struct gpiod_line_info *info; + struct gpiod_info_event *event; + struct gpiod_chip *chip; + unsigned int i; + uint64_t timestamp_ns; + + chip = gpiod_chip_open(chip_path); + if (!chip) { + fprintf(stderr, "failed to open chip: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + for (i = 0; i < NUM_LINES; i++) { + info = gpiod_chip_watch_line_info(chip, line_offsets[i]); + if (!info) { + fprintf(stderr, "failed to read info: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + } + + for (;;) { + /* Blocks until an event is available. */ + event = gpiod_chip_read_info_event(chip); + if (!event) { + fprintf(stderr, "failed to read event: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + + info = gpiod_info_event_get_line_info(event); + timestamp_ns = gpiod_info_event_get_timestamp_ns(event); + printf("line %3d: %-9s %ld.%ld\n", + gpiod_line_info_get_offset(info), event_type(event), + timestamp_ns / 1000000000, timestamp_ns % 1000000000); + + gpiod_info_event_free(event); + } +} diff --git a/examples/watch_line_rising.c b/examples/watch_line_rising.c new file mode 100644 index 0000000..062a46a --- /dev/null +++ b/examples/watch_line_rising.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of watching for rising edges on a single line. */ + +#include +#include +#include +#include +#include + +/* Request a line as input with edge detection. */ +static struct gpiod_line_request *request_input_line(const char *chip_path, + unsigned int offset, + const char *consumer) +{ + struct gpiod_request_config *req_cfg = NULL; + struct gpiod_line_request *request = NULL; + struct gpiod_line_settings *settings; + struct gpiod_line_config *line_cfg; + struct gpiod_chip *chip; + int ret; + + chip = gpiod_chip_open(chip_path); + if (!chip) + return NULL; + + settings = gpiod_line_settings_new(); + if (!settings) + goto close_chip; + + gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT); + gpiod_line_settings_set_edge_detection(settings, GPIOD_LINE_EDGE_RISING); + + line_cfg = gpiod_line_config_new(); + if (!line_cfg) + goto free_settings; + + ret = gpiod_line_config_add_line_settings(line_cfg, &offset, 1, + settings); + if (ret) + goto free_line_config; + + if (consumer) { + req_cfg = gpiod_request_config_new(); + if (!req_cfg) + goto free_line_config; + + gpiod_request_config_set_consumer(req_cfg, consumer); + } + + request = gpiod_chip_request_lines(chip, req_cfg, line_cfg); + + gpiod_request_config_free(req_cfg); + +free_line_config: + gpiod_line_config_free(line_cfg); + +free_settings: + gpiod_line_settings_free(settings); + +close_chip: + gpiod_chip_close(chip); + + return request; +} + +static const char *edge_event_type_str(struct gpiod_edge_event *event) +{ + switch (gpiod_edge_event_get_event_type(event)) { + case GPIOD_EDGE_EVENT_RISING_EDGE: + return "Rising"; + case GPIOD_EDGE_EVENT_FALLING_EDGE: + return "Falling"; + default: + return "Unknown"; + } +} + +int main(void) +{ + /* Example configuration - customize to suit your situation. */ + static const char *const chip_path = "/dev/gpiochip0"; + static const unsigned int line_offset = 5; + + struct gpiod_edge_event_buffer *event_buffer; + struct gpiod_line_request *request; + struct gpiod_edge_event *event; + int i, ret, event_buf_size; + + request = request_input_line(chip_path, line_offset, + "watch-line-value"); + if (!request) { + fprintf(stderr, "failed to request line: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + + /* + * A larger buffer is an optimisation for reading bursts of events from + * the kernel, but that is not necessary in this case, so 1 is fine. + */ + event_buf_size = 1; + event_buffer = gpiod_edge_event_buffer_new(event_buf_size); + if (!event_buffer) { + fprintf(stderr, "failed to create event buffer: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + + for (;;) { + /* Blocks until at least one event is available. */ + ret = gpiod_line_request_read_edge_events(request, event_buffer, + event_buf_size); + if (ret == -1) { + fprintf(stderr, "error reading edge events: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + for (i = 0; i < ret; i++) { + event = gpiod_edge_event_buffer_get_event(event_buffer, + i); + printf("offset: %d type: %-7s event #%ld\n", + gpiod_edge_event_get_line_offset(event), + edge_event_type_str(event), + gpiod_edge_event_get_line_seqno(event)); + } + } +} diff --git a/examples/watch_multiple_line_values.c b/examples/watch_multiple_line_values.c new file mode 100644 index 0000000..6918aa6 --- /dev/null +++ b/examples/watch_multiple_line_values.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of watching for edges on a single line. */ + +#include +#include +#include +#include +#include + +/* Request a line as input with edge detection. */ +static struct gpiod_line_request * +request_input_lines(const char *chip_path, const unsigned int *offsets, + unsigned int num_lines, const char *consumer) +{ + struct gpiod_request_config *req_cfg = NULL; + struct gpiod_line_request *request = NULL; + struct gpiod_line_settings *settings; + struct gpiod_line_config *line_cfg; + struct gpiod_chip *chip; + unsigned int i; + int ret; + + chip = gpiod_chip_open(chip_path); + if (!chip) + return NULL; + + settings = gpiod_line_settings_new(); + if (!settings) + goto close_chip; + + gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT); + gpiod_line_settings_set_edge_detection(settings, GPIOD_LINE_EDGE_BOTH); + /* Assume a button connecting the pin to ground, so pull it up... */ + gpiod_line_settings_set_bias(settings, GPIOD_LINE_BIAS_PULL_UP); + /* ... and provide some debounce. */ + gpiod_line_settings_set_debounce_period_us(settings, 10000); + + line_cfg = gpiod_line_config_new(); + if (!line_cfg) + goto free_settings; + + for (i = 0; i < num_lines; i++) { + ret = gpiod_line_config_add_line_settings(line_cfg, &offsets[i], + 1, settings); + if (ret) + goto free_line_config; + } + + if (consumer) { + req_cfg = gpiod_request_config_new(); + if (!req_cfg) + goto free_line_config; + + gpiod_request_config_set_consumer(req_cfg, consumer); + } + + request = gpiod_chip_request_lines(chip, req_cfg, line_cfg); + + gpiod_request_config_free(req_cfg); + +free_line_config: + gpiod_line_config_free(line_cfg); + +free_settings: + gpiod_line_settings_free(settings); + +close_chip: + gpiod_chip_close(chip); + + return request; +} + +static const char *edge_event_type_str(struct gpiod_edge_event *event) +{ + switch (gpiod_edge_event_get_event_type(event)) { + case GPIOD_EDGE_EVENT_RISING_EDGE: + return "Rising"; + case GPIOD_EDGE_EVENT_FALLING_EDGE: + return "Falling"; + default: + return "Unknown"; + } +} + +#define NUM_LINES 3 + +int main(void) +{ + /* Example configuration - customize to suit your situation. */ + static const char *const chip_path = "/dev/gpiochip0"; + static const unsigned int line_offsets[NUM_LINES] = { 5, 3, 7 }; + + struct gpiod_edge_event_buffer *event_buffer; + struct gpiod_line_request *request; + struct gpiod_edge_event *event; + int i, ret, event_buf_size; + + request = request_input_lines(chip_path, line_offsets, NUM_LINES, + "watch-multiple-line-values"); + if (!request) { + fprintf(stderr, "failed to request line: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + + /* + * A larger buffer is an optimisation for reading bursts of events from + * the kernel, so even a value of 1 would be fine. + * The size here allows for a simultaneous event on each of the lines + * to be copied in one read. + */ + event_buf_size = NUM_LINES; + event_buffer = gpiod_edge_event_buffer_new(event_buf_size); + if (!event_buffer) { + fprintf(stderr, "failed to create event buffer: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + + for (;;) { + /* Blocks until at least one event is available. */ + ret = gpiod_line_request_read_edge_events(request, event_buffer, + event_buf_size); + if (ret == -1) { + fprintf(stderr, "error reading edge events: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + for (i = 0; i < ret; i++) { + event = gpiod_edge_event_buffer_get_event(event_buffer, + i); + printf("offset: %d type: %-7s event #%ld\n", + gpiod_edge_event_get_line_offset(event), + edge_event_type_str(event), + gpiod_edge_event_get_line_seqno(event)); + } + } +} From patchwork Fri Jun 23 04:38:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1798741 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=YSHLVqoK; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QnPfg4jRLz20XS for ; Fri, 23 Jun 2023 14:39:55 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230062AbjFWEjx (ORCPT ); Fri, 23 Jun 2023 00:39:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231245AbjFWEjt (ORCPT ); Fri, 23 Jun 2023 00:39:49 -0400 Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 200B12128 for ; Thu, 22 Jun 2023 21:39:48 -0700 (PDT) Received: by mail-pj1-x1036.google.com with SMTP id 98e67ed59e1d1-25ecc896007so122570a91.3 for ; Thu, 22 Jun 2023 21:39:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687495187; x=1690087187; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=azHESUpHEVERDexMnZPMiho7ZUBqMaLa/ekyNW2kk+Y=; b=YSHLVqoKXtvyJLkmXKh2K2fRFSc86jIZkmUgeLAZ6USxauL69FvKEx1SLTf2b+HQOF wXD6E9il9npYZS7WIbkiQG0UpD5ZJzvyPHlW7xXzzEivYitzpzYJGYpNoRXnQQjZC9wF xDuZVZUOl+RIipErJ0lv31iW1CccZpBOxV+X3BZtWYc1iPUCnI7/cnHJ8I5y8DB3uaJX /y4GlXA6ivqu0had+WlJnhg+yLr0ZbrDGXoPSw1+H2VakhOn8j189Fwiu0XCJlaGCpfM IQmEerFHT7wCoetYIw6Mj8OWOEcZn7UoKH0C9390FBIzxfd/CcQ4g9V8fypZ9lOJtoz9 lVGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687495187; x=1690087187; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=azHESUpHEVERDexMnZPMiho7ZUBqMaLa/ekyNW2kk+Y=; b=bEGnX/g6zGHSa/W5SO1vE2cib3Cmy87PVaV7fWwpDOLfxHUq+sTpLvS3o88iM4rJN4 eY/6Af8sbEbpt1EX2v/EKZDh7c2ON0VE+044tTcPF3go+0ym3w3G7/M8oTxMqmIFFvhZ OTqU6gA51ucrywqOTTuGftCY/yThgol5s5zN12RVVIxEOAW9rcNRf9HQy0S+306G1l40 XEzQHKCm2fgnXJglXW9/d03ad+4OZmxbYrv00WWfIydl5CtuR/VQ5GWcCELvboqiEeye 2rz+BBGbEBKd5hAohqS/PZsD1kC47p6q25PtiPerZoXmLlFZCpg2KrJi/cs3FZG1CCDP hGag== X-Gm-Message-State: AC+VfDxExEJCF673hwK8OTB2jjBBAO5rd1l1kB5gPLMMZAhfILi+RCGu rlWk0JLh3mHC79EyQVGOMaMequ7lh2Y= X-Google-Smtp-Source: ACHHUZ5Rh0ZJF2Hnso5gA+lrdbDNtXC1bdVu8XT25+s+jD+NgOm6HWMSuu4Wz+zmlNCpKTzXocqftA== X-Received: by 2002:a17:90a:f2d2:b0:25e:86ab:f4d7 with SMTP id gt18-20020a17090af2d200b0025e86abf4d7mr18334034pjb.22.1687495187321; Thu, 22 Jun 2023 21:39:47 -0700 (PDT) Received: from sol.home.arpa (194-223-178-180.tpgi.com.au. [194.223.178.180]) by smtp.gmail.com with ESMTPSA id q23-20020a17090ad39700b0025c2c398d33sm509463pju.39.2023.06.22.21.39.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jun 2023 21:39:47 -0700 (PDT) From: Kent Gibson To: linux-gpio@vger.kernel.org, brgl@bgdev.pl Cc: Kent Gibson Subject: [libgpiod][PATCH 3/8] bindings: cxx: examples: consistency cleanup Date: Fri, 23 Jun 2023 12:38:56 +0800 Message-ID: <20230623043901.16764-4-warthog618@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230623043901.16764-1-warthog618@gmail.com> References: <20230623043901.16764-1-warthog618@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org A collection of minor changes to be more consistent with other examples: - capitalize comments - add line offset to value outputs - drop comma from edge event outputs - drop trailing return where example loops indefintely - sort includes Signed-off-by: Kent Gibson --- .../cxx/examples/async_watch_line_value.cpp | 8 +++--- bindings/cxx/examples/get_line_value.cpp | 28 +++++++++++-------- bindings/cxx/examples/toggle_line_value.cpp | 16 +++++------ bindings/cxx/examples/watch_line_value.cpp | 12 ++++---- 4 files changed, 33 insertions(+), 31 deletions(-) diff --git a/bindings/cxx/examples/async_watch_line_value.cpp b/bindings/cxx/examples/async_watch_line_value.cpp index e1d4a1e..d8317a5 100644 --- a/bindings/cxx/examples/async_watch_line_value.cpp +++ b/bindings/cxx/examples/async_watch_line_value.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -79,10 +80,9 @@ int main(void) for (const auto& event : buffer) ::std::cout << "offset: " << event.line_offset() - << ", type: " << edge_event_type_str(event) - << ", event #" << event.line_seqno() + << " type: " << ::std::setw(7) + << ::std::left << edge_event_type_str(event) + << " event #" << event.line_seqno() << ::std::endl; } - - return EXIT_SUCCESS; } diff --git a/bindings/cxx/examples/get_line_value.cpp b/bindings/cxx/examples/get_line_value.cpp index 8f4e739..a14d7e4 100644 --- a/bindings/cxx/examples/get_line_value.cpp +++ b/bindings/cxx/examples/get_line_value.cpp @@ -10,7 +10,7 @@ namespace { -/* example configuration - customize to suit your situation */ +/* Example configuration - customize to suit your situation */ const ::std::filesystem::path chip_path("/dev/gpiochip0"); const ::gpiod::line::offset line_offset = 5; @@ -18,17 +18,21 @@ const ::gpiod::line::offset line_offset = 5; int main(void) { - auto request = - ::gpiod::chip(chip_path) - .prepare_request() - .set_consumer("get-line-value") - .add_line_settings( - line_offset, - ::gpiod::line_settings().set_direction( - ::gpiod::line::direction::INPUT)) - .do_request(); - - ::std::cout << request.get_value(line_offset) << ::std::endl; + auto request = ::gpiod::chip(chip_path) + .prepare_request() + .set_consumer("get-line-value") + .add_line_settings( + line_offset, + ::gpiod::line_settings().set_direction( + ::gpiod::line::direction::INPUT)) + .do_request(); + + ::std::cout << line_offset << "=" + << (request.get_value(line_offset) == + ::gpiod::line::value::ACTIVE ? + "Active" : + "Inactive") + << ::std::endl; return EXIT_SUCCESS; } diff --git a/bindings/cxx/examples/toggle_line_value.cpp b/bindings/cxx/examples/toggle_line_value.cpp index a060e8a..a17b43b 100644 --- a/bindings/cxx/examples/toggle_line_value.cpp +++ b/bindings/cxx/examples/toggle_line_value.cpp @@ -6,8 +6,8 @@ #include #include #include -#include #include +#include #include namespace { @@ -19,15 +19,15 @@ const ::gpiod::line::offset line_offset = 5; ::gpiod::line::value toggle_value(::gpiod::line::value v) { return (v == ::gpiod::line::value::ACTIVE) ? - ::gpiod::line::value::INACTIVE : - ::gpiod::line::value::ACTIVE; + ::gpiod::line::value::INACTIVE : + ::gpiod::line::value::ACTIVE; } } /* namespace */ int main(void) { - ::gpiod::line::value val = ::gpiod::line::value::ACTIVE; + ::gpiod::line::value value = ::gpiod::line::value::ACTIVE; auto request = ::gpiod::chip(chip_path) @@ -40,12 +40,10 @@ int main(void) .do_request(); for (;;) { - ::std::cout << val << ::std::endl; + ::std::cout << line_offset << "=" << value << ::std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); - val = toggle_value(val); - request.set_value(line_offset, val); + value = toggle_value(value); + request.set_value(line_offset, value); } - - return EXIT_SUCCESS; } diff --git a/bindings/cxx/examples/watch_line_value.cpp b/bindings/cxx/examples/watch_line_value.cpp index 5436884..5055789 100644 --- a/bindings/cxx/examples/watch_line_value.cpp +++ b/bindings/cxx/examples/watch_line_value.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace { @@ -18,7 +19,7 @@ const char *edge_event_type_str(const ::gpiod::edge_event &event) { switch (event.type()) { case ::gpiod::edge_event::event_type::RISING_EDGE: - return "Rising "; + return "Rising"; case ::gpiod::edge_event::event_type::FALLING_EDGE: return "Falling"; default: @@ -61,11 +62,10 @@ int main(void) request.read_edge_events(buffer); for (const auto &event : buffer) - ::std::cout << "offset: " << event.line_offset() - << ", type: " << edge_event_type_str(event) - << ", event #" << event.line_seqno() + ::std::cout << "line: " << event.line_offset() + << " type: " << ::std::setw(7) + << ::std::left << edge_event_type_str(event) + << " event #" << event.line_seqno() << ::std::endl; } - - return EXIT_SUCCESS; } From patchwork Fri Jun 23 04:38:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1798742 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=EsGuyTmd; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QnPfr5WYQz20XS for ; Fri, 23 Jun 2023 14:40:04 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231181AbjFWEkE (ORCPT ); Fri, 23 Jun 2023 00:40:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46770 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230433AbjFWEkC (ORCPT ); Fri, 23 Jun 2023 00:40:02 -0400 Received: from mail-qt1-x82b.google.com (mail-qt1-x82b.google.com [IPv6:2607:f8b0:4864:20::82b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6A5BA2128 for ; Thu, 22 Jun 2023 21:39:59 -0700 (PDT) Received: by mail-qt1-x82b.google.com with SMTP id d75a77b69052e-3f9eea9d0a1so3771951cf.1 for ; Thu, 22 Jun 2023 21:39:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687495198; x=1690087198; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+N8+i6cDajhzbtCQrXq/0cc1Y/3j3/6u3W3lCYEaJgQ=; b=EsGuyTmdDjGBgTRFduduAiXdmUVNxrJTN9pgclkm5uUXsMICV2Ku0TVSbZJivFV7Wv 6DnJdffNHzHipKxuPGwtutGg4izpC71pfqTs98np7u3lApl01YMLWcdsEVOrfRntLO7Q 6APSFO5fJXjhiee8ge/xedUttVfnypxWX8Pvcv2SeojqpyVk5f/Wn+5zfQuLUuf+L0S+ jmjNDOgmtcu0lboxj9GYmJEaGtKlI7yTnmbnSYPrzD6z/WrIpqz95IRJLj6+ViI9NtHl 1s4vHesY9c1uXu/2RjuBMpY4cFN8dR5LG7Xm3BZA2Ndthxkhik8wl+bEbtNwwA5OwLnv OUPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687495198; x=1690087198; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+N8+i6cDajhzbtCQrXq/0cc1Y/3j3/6u3W3lCYEaJgQ=; b=U6RvPMwOMIJS0kW6DwBwwJjn2vQZ0UnjAXjqty8749GjrJqPVDN++TAGc0glqDQp91 YiNUuKh2e8574WfEWoY8zfeNTv5uoHSTKaY/iXfQ36bwfAppAcRDqzMeAbt7cFxC+kDp LGQVdQEOFty8YyZ4+Ac+k4n5x3smlb2XeoyQq6gQXVTRU0PMC2ReZTLWZaRP2xfr4HPP 54pLaMgpo5fOEYL6AfL6rQKebUd5kL7tdUrUFe4YuNnHp4K992bYe2tAy1QCCgML9OBs gzYnQbHUfQB3rDdQvvt+MdBSNfnw0eviynEIXjJY9IDm2dnE7KP9FLcBXmvwJW0JhVqB IeEg== X-Gm-Message-State: AC+VfDz4OLs2HZXO5H3zV5sNlQYxFRDsOHZ+sDDJWw0rjIKYI+EHGjeu k8sK3BETjoSO/jrvpvX+QquliVKvMvU= X-Google-Smtp-Source: ACHHUZ4Ryiu7Mju9Zd6Y67zjEZiHDGRCq6cJAVAc81LAudv7a7tipOXK5BCPKCdrlTCS0POlo2SyNg== X-Received: by 2002:a05:622a:13cd:b0:3ff:1ef7:9d03 with SMTP id p13-20020a05622a13cd00b003ff1ef79d03mr14642244qtk.63.1687495197942; Thu, 22 Jun 2023 21:39:57 -0700 (PDT) Received: from sol.home.arpa (194-223-178-180.tpgi.com.au. [194.223.178.180]) by smtp.gmail.com with ESMTPSA id q23-20020a17090ad39700b0025c2c398d33sm509463pju.39.2023.06.22.21.39.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jun 2023 21:39:57 -0700 (PDT) From: Kent Gibson To: linux-gpio@vger.kernel.org, brgl@bgdev.pl Cc: Kent Gibson Subject: [libgpiod][PATCH 4/8] bindings: cxx: examples: replace tools examples with use case examples Date: Fri, 23 Jun 2023 12:38:57 +0800 Message-ID: <20230623043901.16764-5-warthog618@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230623043901.16764-1-warthog618@gmail.com> References: <20230623043901.16764-1-warthog618@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Replace tool examples with use case examples drawn from the tools. Signed-off-by: Kent Gibson --- bindings/cxx/examples/.gitignore | 16 +++-- bindings/cxx/examples/Makefile.am | 42 +++++++----- bindings/cxx/examples/find_line_by_name.cpp | 42 ++++++++++++ bindings/cxx/examples/get_chip_info.cpp | 27 ++++++++ bindings/cxx/examples/get_line_info.cpp | 39 +++++++++++ .../cxx/examples/get_multiple_line_values.cpp | 40 ++++++++++++ bindings/cxx/examples/gpiodetectcxx.cpp | 30 --------- bindings/cxx/examples/gpiofindcxx.cpp | 32 --------- bindings/cxx/examples/gpiogetcxx.cpp | 40 ------------ bindings/cxx/examples/gpioinfocxx.cpp | 61 ----------------- bindings/cxx/examples/gpiomoncxx.cpp | 65 ------------------- bindings/cxx/examples/gpionotifycxx.cpp | 55 ---------------- bindings/cxx/examples/gpiosetcxx.cpp | 53 --------------- .../examples/reconfigure_input_to_output.cpp | 56 ++++++++++++++++ .../examples/toggle_multiple_line_values.cpp | 63 ++++++++++++++++++ bindings/cxx/examples/watch_line_info.cpp | 49 ++++++++++++++ bindings/cxx/examples/watch_line_rising.cpp | 64 ++++++++++++++++++ .../examples/watch_multiple_line_values.cpp | 60 +++++++++++++++++ 18 files changed, 473 insertions(+), 361 deletions(-) create mode 100644 bindings/cxx/examples/find_line_by_name.cpp create mode 100644 bindings/cxx/examples/get_chip_info.cpp create mode 100644 bindings/cxx/examples/get_line_info.cpp create mode 100644 bindings/cxx/examples/get_multiple_line_values.cpp delete mode 100644 bindings/cxx/examples/gpiodetectcxx.cpp delete mode 100644 bindings/cxx/examples/gpiofindcxx.cpp delete mode 100644 bindings/cxx/examples/gpiogetcxx.cpp delete mode 100644 bindings/cxx/examples/gpioinfocxx.cpp delete mode 100644 bindings/cxx/examples/gpiomoncxx.cpp delete mode 100644 bindings/cxx/examples/gpionotifycxx.cpp delete mode 100644 bindings/cxx/examples/gpiosetcxx.cpp create mode 100644 bindings/cxx/examples/reconfigure_input_to_output.cpp create mode 100644 bindings/cxx/examples/toggle_multiple_line_values.cpp create mode 100644 bindings/cxx/examples/watch_line_info.cpp create mode 100644 bindings/cxx/examples/watch_line_rising.cpp create mode 100644 bindings/cxx/examples/watch_multiple_line_values.cpp diff --git a/bindings/cxx/examples/.gitignore b/bindings/cxx/examples/.gitignore index 268b3f6..0f9b39e 100644 --- a/bindings/cxx/examples/.gitignore +++ b/bindings/cxx/examples/.gitignore @@ -1,14 +1,16 @@ # SPDX-License-Identifier: GPL-2.0-or-later # SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski -gpiodetectcxx -gpiofindcxx -gpiogetcxx -gpioinfocxx -gpiomoncxx -gpionotifycxx -gpiosetcxx async_watch_line_value +find_line_by_name +get_chip_info +get_line_info get_line_value +get_multiple_line_values +reconfigure_input_to_output toggle_line_value +toggle_multiple_line_values +watch_line_info +watch_line_rising watch_line_value +watch_multiple_line_values diff --git a/bindings/cxx/examples/Makefile.am b/bindings/cxx/examples/Makefile.am index 0213973..64ced20 100644 --- a/bindings/cxx/examples/Makefile.am +++ b/bindings/cxx/examples/Makefile.am @@ -6,36 +6,42 @@ AM_CXXFLAGS += -Wall -Wextra -g -std=gnu++17 AM_LDFLAGS = -lgpiodcxx -L$(top_builddir)/bindings/cxx/ noinst_PROGRAMS = \ - gpiodetectcxx \ - gpiofindcxx \ - gpiogetcxx \ - gpioinfocxx \ - gpiomoncxx \ - gpionotifycxx \ - gpiosetcxx \ async_watch_line_value \ + find_line_by_name \ + get_chip_info \ + get_line_info \ get_line_value \ + get_multiple_line_values \ + reconfigure_input_to_output \ toggle_line_value \ - watch_line_value + toggle_multiple_line_values \ + watch_line_info \ + watch_line_rising \ + watch_line_value \ + watch_multiple_line_values -gpiodetectcxx_SOURCES = gpiodetectcxx.cpp +async_watch_line_value_SOURCES = async_watch_line_value.cpp -gpiofindcxx_SOURCES = gpiofindcxx.cpp +find_line_by_name_SOURCES = find_line_by_name.cpp -gpiogetcxx_SOURCES = gpiogetcxx.cpp +get_chip_info_SOURCES = get_chip_info.cpp -gpioinfocxx_SOURCES = gpioinfocxx.cpp +get_line_info_SOURCES = get_line_info.cpp -gpiomoncxx_SOURCES = gpiomoncxx.cpp +get_line_value_SOURCES = get_line_value.cpp -gpionotifycxx_SOURCES = gpionotifycxx.cpp +get_multiple_line_values_SOURCES = get_multiple_line_values.cpp -gpiosetcxx_SOURCES = gpiosetcxx.cpp +reconfigure_input_to_output_SOURCES = reconfigure_input_to_output.cpp -async_watch_line_value_SOURCES = async_watch_line_value.cpp +toggle_line_value_SOURCES = toggle_line_value.cpp -get_line_value_SOURCES = get_line_value.cpp +toggle_multiple_line_values_SOURCES = toggle_multiple_line_values.cpp -toggle_line_value_SOURCES = toggle_line_value.cpp +watch_line_info_SOURCES = watch_line_info.cpp watch_line_value_SOURCES = watch_line_value.cpp + +watch_line_rising_SOURCES = watch_line_rising.cpp + +watch_multiple_line_values_SOURCES = watch_multiple_line_values.cpp diff --git a/bindings/cxx/examples/find_line_by_name.cpp b/bindings/cxx/examples/find_line_by_name.cpp new file mode 100644 index 0000000..4529ed6 --- /dev/null +++ b/bindings/cxx/examples/find_line_by_name.cpp @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of finding a line with the given name. */ + +#include +#include +#include +#include + +namespace +{ + +/* Example configuration - customize to suit your situation */ +const ::std::string line_name = "GPIO19"; + +} /* namespace */ + +int main(void) +{ + /* + * Names are not guaranteed unique, so this finds the first line with + * the given name. + */ + for (const auto &entry : + ::std::filesystem::directory_iterator("/dev/")) { + if (::gpiod::is_gpiochip_device(entry.path())) { + ::gpiod::chip chip(entry.path()); + + auto offset = chip.get_line_offset_from_name(line_name); + if (offset >= 0) { + ::std::cout << line_name << ": " + << chip.get_info().name() << " " + << offset << ::std::endl; + return EXIT_SUCCESS; + } + } + } + ::std::cout << "line '" << line_name << "' not found" << ::std::endl; + + return EXIT_FAILURE; +} diff --git a/bindings/cxx/examples/get_chip_info.cpp b/bindings/cxx/examples/get_chip_info.cpp new file mode 100644 index 0000000..073a6c3 --- /dev/null +++ b/bindings/cxx/examples/get_chip_info.cpp @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of reading the info for a chip. */ + +#include +#include +#include +#include + +namespace { + +/* Example configuration - customize to suit your situation */ +const ::std::filesystem::path chip_path("/dev/gpiochip0"); + +} /* namespace */ + +int main(void) +{ + ::gpiod::chip chip(chip_path); + auto info = chip.get_info(); + + ::std::cout << info.name() << " [" << info.label() << "] (" + << info.num_lines() << " lines)" << ::std::endl; + + return EXIT_SUCCESS; +} diff --git a/bindings/cxx/examples/get_line_info.cpp b/bindings/cxx/examples/get_line_info.cpp new file mode 100644 index 0000000..f2f071e --- /dev/null +++ b/bindings/cxx/examples/get_line_info.cpp @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of reading the info for a line. */ + +#include +#include +#include +#include +#include + +namespace { + +/* Example configuration - customize to suit your situation */ +const ::std::filesystem::path chip_path("/dev/gpiochip0"); +const ::gpiod::line::offset line_offset = 3; + +} /* namespace */ + +int main(void) +{ + auto chip = ::gpiod::chip(chip_path); + auto info = chip.get_line_info(line_offset); + + ::std::cout << "line " << ::std::setw(3) << info.offset() << ": " + << ::std::setw(12) + << (info.name().empty() ? "unnamed" : info.name()) << " " + << ::std::setw(12) + << (info.consumer().empty() ? "unused" : info.consumer()) + << " " << ::std::setw(8) + << (info.direction() == ::gpiod::line::direction::INPUT ? + "input" : + "output") + << " " << ::std::setw(10) + << (info.active_low() ? "active-low" : "active-high") + << ::std::endl; + + return EXIT_SUCCESS; +} diff --git a/bindings/cxx/examples/get_multiple_line_values.cpp b/bindings/cxx/examples/get_multiple_line_values.cpp new file mode 100644 index 0000000..d1f22e7 --- /dev/null +++ b/bindings/cxx/examples/get_multiple_line_values.cpp @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of reading multiple lines. */ + +#include +#include +#include + +namespace { + +/* Example configuration - customize to suit your situation */ +const ::std::filesystem::path chip_path("/dev/gpiochip0"); +const ::gpiod::line::offsets line_offsets = { 5, 3, 7 }; + +} /* namespace */ + +int main(void) +{ + auto request = ::gpiod::chip(chip_path) + .prepare_request() + .set_consumer("get-multiple-line-values") + .add_line_settings( + line_offsets, + ::gpiod::line_settings().set_direction( + ::gpiod::line::direction::INPUT)) + .do_request(); + + auto values = request.get_values(); + + for (size_t i = 0; i < line_offsets.size(); i++) + ::std::cout << line_offsets[i] << "=" + << (values[i] == ::gpiod::line::value::ACTIVE ? + "Active" : + "Inactive") + << ' '; + ::std::cout << ::std::endl; + + return EXIT_SUCCESS; +} diff --git a/bindings/cxx/examples/gpiodetectcxx.cpp b/bindings/cxx/examples/gpiodetectcxx.cpp deleted file mode 100644 index 7dbb0e0..0000000 --- a/bindings/cxx/examples/gpiodetectcxx.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski - -/* C++ reimplementation of the gpiodetect tool. */ - -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - if (argc != 1) { - ::std::cerr << "usage: " << argv[0] << ::std::endl; - return EXIT_FAILURE; - } - - for (const auto& entry: ::std::filesystem::directory_iterator("/dev/")) { - if (::gpiod::is_gpiochip_device(entry.path())) { - ::gpiod::chip chip(entry.path()); - auto info = chip.get_info(); - - ::std::cout << info.name() << " [" << - info.label() << "] (" << - info.num_lines() << " lines)" << ::std::endl; - } - } - - return EXIT_SUCCESS; -} diff --git a/bindings/cxx/examples/gpiofindcxx.cpp b/bindings/cxx/examples/gpiofindcxx.cpp deleted file mode 100644 index cd36be7..0000000 --- a/bindings/cxx/examples/gpiofindcxx.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski - -/* C++ reimplementation of the gpiofind tool. */ - -#include - -#include -#include -#include - -int main(int argc, char **argv) -{ - if (argc != 2) { - ::std::cerr << "usage: " << argv[0] << " " << ::std::endl; - return EXIT_FAILURE; - } - - for (const auto& entry: ::std::filesystem::directory_iterator("/dev/")) { - if (::gpiod::is_gpiochip_device(entry.path())) { - ::gpiod::chip chip(entry.path()); - - auto offset = chip.get_line_offset_from_name(argv[1]); - if (offset >= 0) { - ::std::cout << chip.get_info().name() << " " << offset << ::std::endl; - return EXIT_SUCCESS; - } - } - } - - return EXIT_FAILURE; -} diff --git a/bindings/cxx/examples/gpiogetcxx.cpp b/bindings/cxx/examples/gpiogetcxx.cpp deleted file mode 100644 index b0d4a7d..0000000 --- a/bindings/cxx/examples/gpiogetcxx.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski - -/* Simplified C++ reimplementation of the gpioget tool. */ - -#include - -#include -#include - -int main(int argc, char **argv) -{ - if (argc < 3) { - ::std::cerr << "usage: " << argv[0] << " ..." << ::std::endl; - return EXIT_FAILURE; - } - - ::gpiod::line::offsets offsets; - - for (int i = 2; i < argc; i++) - offsets.push_back(::std::stoul(argv[i])); - - auto request = ::gpiod::chip(argv[1]) - .prepare_request() - .set_consumer("gpiogetcxx") - .add_line_settings( - offsets, - ::gpiod::line_settings() - .set_direction(::gpiod::line::direction::INPUT) - ) - .do_request(); - - auto vals = request.get_values(); - - for (auto& it: vals) - ::std::cout << (it == ::gpiod::line::value::ACTIVE ? "1" : "0") << ' '; - ::std::cout << ::std::endl; - - return EXIT_SUCCESS; -} diff --git a/bindings/cxx/examples/gpioinfocxx.cpp b/bindings/cxx/examples/gpioinfocxx.cpp deleted file mode 100644 index 3612092..0000000 --- a/bindings/cxx/examples/gpioinfocxx.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski - -/* Simplified C++ reimplementation of the gpioinfo tool. */ - -#include - -#include -#include -#include - -namespace { - -void show_chip(const ::gpiod::chip& chip) -{ - auto info = chip.get_info(); - - ::std::cout << info.name() << " - " << info.num_lines() << " lines:" << ::std::endl; - - for (unsigned int offset = 0; offset < info.num_lines(); offset++) { - auto info = chip.get_line_info(offset); - - ::std::cout << "\tline "; - ::std::cout.width(3); - ::std::cout << info.offset() << ": "; - - ::std::cout.width(12); - ::std::cout << (info.name().empty() ? "unnamed" : info.name()); - ::std::cout << " "; - - ::std::cout.width(12); - ::std::cout << (info.consumer().empty() ? "unused" : info.consumer()); - ::std::cout << " "; - - ::std::cout.width(8); - ::std::cout << (info.direction() == ::gpiod::line::direction::INPUT ? "input" : "output"); - ::std::cout << " "; - - ::std::cout.width(10); - ::std::cout << (info.active_low() ? "active-low" : "active-high"); - - ::std::cout << ::std::endl; - } -} - -} /* namespace */ - -int main(int argc, char **argv) -{ - if (argc != 1) { - ::std::cerr << "usage: " << argv[0] << ::std::endl; - return EXIT_FAILURE; - } - - for (const auto& entry: ::std::filesystem::directory_iterator("/dev/")) { - if (::gpiod::is_gpiochip_device(entry.path())) - show_chip(::gpiod::chip(entry.path())); - } - - return EXIT_SUCCESS; -} diff --git a/bindings/cxx/examples/gpiomoncxx.cpp b/bindings/cxx/examples/gpiomoncxx.cpp deleted file mode 100644 index 8325bf8..0000000 --- a/bindings/cxx/examples/gpiomoncxx.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski - -/* Simplified C++ reimplementation of the gpiomon tool. */ - -#include -#include -#include - -namespace { - -void print_event(const ::gpiod::edge_event& event) -{ - if (event.type() == ::gpiod::edge_event::event_type::RISING_EDGE) - ::std::cout << " RISING EDGE"; - else - ::std::cout << "FALLING EDGE"; - - ::std::cout << " "; - - ::std::cout << event.timestamp_ns() / 1000000000; - ::std::cout << "."; - ::std::cout << event.timestamp_ns() % 1000000000; - - ::std::cout << " line: " << event.line_offset(); - - ::std::cout << ::std::endl; -} - -} /* namespace */ - -int main(int argc, char **argv) -{ - if (argc < 3) { - ::std::cout << "usage: " << argv[0] << " ..." << ::std::endl; - return EXIT_FAILURE; - } - - ::gpiod::line::offsets offsets; - offsets.reserve(argc - 2); - for (int i = 2; i < argc; i++) - offsets.push_back(::std::stoul(argv[i])); - - auto request = ::gpiod::chip(argv[1]) - .prepare_request() - .set_consumer("gpiomoncxx") - .add_line_settings( - offsets, - ::gpiod::line_settings() - .set_direction(::gpiod::line::direction::INPUT) - .set_edge_detection(::gpiod::line::edge::BOTH) - ) - .do_request(); - - ::gpiod::edge_event_buffer buffer; - - for (;;) { - request.read_edge_events(buffer); - - for (const auto& event: buffer) - print_event(event); - } - - return EXIT_SUCCESS; -} diff --git a/bindings/cxx/examples/gpionotifycxx.cpp b/bindings/cxx/examples/gpionotifycxx.cpp deleted file mode 100644 index 668734c..0000000 --- a/bindings/cxx/examples/gpionotifycxx.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: 2023 Bartosz Golaszewski - -/* Simplified C++ reimplementation of the gpionotify tool. */ - -#include -#include -#include - -namespace { - -void print_event(const ::gpiod::info_event& event) -{ - switch (event.type()) { - case ::gpiod::info_event::event_type::LINE_REQUESTED: - ::std::cout << "LINE REQUESTED"; - break; - case ::gpiod::info_event::event_type::LINE_RELEASED: - ::std::cout << "LINE RELEASED"; - break; - case ::gpiod::info_event::event_type::LINE_CONFIG_CHANGED: - ::std::cout << "CONFIG CHANGED"; - break; - } - - ::std::cout << " "; - - ::std::cout << event.timestamp_ns() / 1000000000; - ::std::cout << "."; - ::std::cout << event.timestamp_ns() % 1000000000; - - ::std::cout << " line: " << event.get_line_info().offset(); - - ::std::cout << ::std::endl; -} - -} /* namespace */ - -int main(int argc, char **argv) -{ - if (argc < 3) { - ::std::cout << "usage: " << argv[0] << " ..." << ::std::endl; - return EXIT_FAILURE; - } - - ::gpiod::chip chip(argv[1]); - - for (int i = 2; i < argc; i++) - chip.watch_line_info(::std::stoul(argv[i])); - - for (;;) - print_event(chip.read_info_event()); - - return EXIT_SUCCESS; -} diff --git a/bindings/cxx/examples/gpiosetcxx.cpp b/bindings/cxx/examples/gpiosetcxx.cpp deleted file mode 100644 index f46cb85..0000000 --- a/bindings/cxx/examples/gpiosetcxx.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski - -/* Simplified C++ reimplementation of the gpioset tool. */ - -#include - -#include -#include - -int main(int argc, char **argv) -{ - if (argc < 3) { - ::std::cerr << "usage: " << argv[0] << - " = ..." << ::std::endl; - return EXIT_FAILURE; - } - - ::gpiod::line::offsets offsets; - ::gpiod::line::values values; - - for (int i = 2; i < argc; i++) { - ::std::string arg(argv[i]); - - size_t pos = arg.find('='); - - ::std::string offset(arg.substr(0, pos)); - ::std::string value(arg.substr(pos + 1, ::std::string::npos)); - - if (offset.empty() || value.empty()) - throw ::std::invalid_argument("invalid offset=value mapping: " + - ::std::string(argv[i])); - - offsets.push_back(::std::stoul(offset)); - values.push_back(::std::stoul(value) ? ::gpiod::line::value::ACTIVE : - ::gpiod::line::value::INACTIVE); - } - - auto request = ::gpiod::chip(argv[1]) - .prepare_request() - .set_consumer("gpiosetcxx") - .add_line_settings( - offsets, - ::gpiod::line_settings() - .set_direction(::gpiod::line::direction::OUTPUT) - ) - .set_output_values(values) - .do_request(); - - ::std::cin.get(); - - return EXIT_SUCCESS; -} diff --git a/bindings/cxx/examples/reconfigure_input_to_output.cpp b/bindings/cxx/examples/reconfigure_input_to_output.cpp new file mode 100644 index 0000000..7d7e75c --- /dev/null +++ b/bindings/cxx/examples/reconfigure_input_to_output.cpp @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of requesting a line intended for bi-directional use as input and then switching to output. */ + +#include +#include +#include +#include + +namespace +{ + +/* Example configuration - customize to suit your situation */ +const ::std::filesystem::path chip_path("/dev/gpiochip0"); +const ::gpiod::line::offset line_offset = 5; + +} /* namespace */ + +int main(void) +{ + /* request the line initially as an input */ + auto request = ::gpiod::chip(chip_path) + .prepare_request() + .set_consumer("reconfigure-input-to-output") + .add_line_settings( + line_offset, + ::gpiod::line_settings().set_direction( + ::gpiod::line::direction::INPUT)) + .do_request(); + + /* read the current line value */ + ::std::cout << line_offset << "=" + << (request.get_value(line_offset) == + ::gpiod::line::value::ACTIVE ? + "Active" : + "Inactive") + << " (input)" << ::std::endl; + + /* switch the line to an output and drive it low */ + request.reconfigure_lines(::gpiod::line_config().add_line_settings( + line_offset, + ::gpiod::line_settings() + .set_direction(::gpiod::line::direction::OUTPUT) + .set_output_value(::gpiod::line::value::INACTIVE))); + + /* report the current driven value */ + ::std::cout << line_offset << "=" + << (request.get_value(line_offset) == + ::gpiod::line::value::ACTIVE ? + "Active" : + "Inactive") + << " (output)" << ::std::endl; + + return EXIT_SUCCESS; +} diff --git a/bindings/cxx/examples/toggle_multiple_line_values.cpp b/bindings/cxx/examples/toggle_multiple_line_values.cpp new file mode 100644 index 0000000..a5b84bf --- /dev/null +++ b/bindings/cxx/examples/toggle_multiple_line_values.cpp @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of toggling multiple lines. */ + +#include +#include +#include +#include + +namespace { + +/* Example configuration - customize to suit your situation */ +const ::std::filesystem::path chip_path("/dev/gpiochip0"); +const ::gpiod::line::offsets line_offsets = { 5, 3, 7 }; + +::gpiod::line::value toggle_value(::gpiod::line::value v) +{ + return (v == ::gpiod::line::value::ACTIVE) ? + ::gpiod::line::value::INACTIVE : + ::gpiod::line::value::ACTIVE; +} + +void toggle_values(::gpiod::line::values &values) +{ + for (size_t i = 0; i < values.size(); i++) + values[i] = toggle_value(values[i]); +} + +void print_values(::gpiod::line::offsets const &offsets, + ::gpiod::line::values const &values) +{ + for (size_t i = 0; i < offsets.size(); i++) + ::std::cout << offsets[i] << "=" << values[i] << ' '; + ::std::cout << ::std::endl; +} + +} /* namespace */ + +int main(void) +{ + ::gpiod::line::values values = { ::gpiod::line::value::ACTIVE, + ::gpiod::line::value::ACTIVE, + ::gpiod::line::value::INACTIVE }; + + auto request = + ::gpiod::chip(chip_path) + .prepare_request() + .set_consumer("toggle-multiple-line-values") + .add_line_settings( + line_offsets, + ::gpiod::line_settings().set_direction( + ::gpiod::line::direction::OUTPUT)) + .set_output_values(values) + .do_request(); + + for (;;) { + print_values(line_offsets, values); + std::this_thread::sleep_for(std::chrono::seconds(1)); + toggle_values(values); + request.set_values(line_offsets, values); + } +} diff --git a/bindings/cxx/examples/watch_line_info.cpp b/bindings/cxx/examples/watch_line_info.cpp new file mode 100644 index 0000000..fe37f18 --- /dev/null +++ b/bindings/cxx/examples/watch_line_info.cpp @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of watching for requests on particular lines. */ + +#include +#include +#include +#include + +namespace { + +/* Example configuration - customize to suit your situation. */ +const ::std::filesystem::path chip_path("/dev/gpiochip0"); +const ::gpiod::line::offsets line_offsets = { 5, 3, 7 }; + +const char *event_type(const ::gpiod::info_event &event) +{ + switch (event.type()) { + case ::gpiod::info_event::event_type::LINE_REQUESTED: + return "Requested"; + case ::gpiod::info_event::event_type::LINE_RELEASED: + return "Released"; + case ::gpiod::info_event::event_type::LINE_CONFIG_CHANGED: + return "Reconfig"; + default: + return "Unknown"; + } +} + +} /* namespace */ + +int main(void) +{ + ::gpiod::chip chip(chip_path); + for (auto offset :line_offsets) { + chip.watch_line_info(offset); + } + + for (;;) { + /* Blocks until at least one event is available */ + auto event = chip.read_info_event(); + ::std::cout << "line: " << event.get_line_info().offset() << " " + << ::std::setw(9) << ::std::left + << event_type(event) << " " + << event.timestamp_ns() / 1000000000 << "." + << event.timestamp_ns() % 1000000000 << ::std::endl; + } +} diff --git a/bindings/cxx/examples/watch_line_rising.cpp b/bindings/cxx/examples/watch_line_rising.cpp new file mode 100644 index 0000000..d773063 --- /dev/null +++ b/bindings/cxx/examples/watch_line_rising.cpp @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of watching for rising edges on a single line. */ + +#include +#include +#include +#include +#include + +namespace { + +/* Example configuration - customize to suit your situation. */ +const ::std::filesystem::path chip_path("/dev/gpiochip0"); +const ::gpiod::line::offset line_offset = 5; + +const char *edge_event_type_str(const ::gpiod::edge_event &event) +{ + switch (event.type()) { + case ::gpiod::edge_event::event_type::RISING_EDGE: + return "Rising"; + case ::gpiod::edge_event::event_type::FALLING_EDGE: + return "Falling"; + default: + return "Unknown"; + } +} + +} /* namespace */ + +int main(void) +{ + auto request = + ::gpiod::chip(chip_path) + .prepare_request() + .set_consumer("watch-line-value") + .add_line_settings( + line_offset, + ::gpiod::line_settings() + .set_direction( + ::gpiod::line::direction::INPUT) + .set_edge_detection( + ::gpiod::line::edge::RISING) +) + .do_request(); + + /* + * A larger buffer is an optimisation for reading bursts of events from + * the kernel, but that is not necessary in this case, so 1 is fine. + */ + ::gpiod::edge_event_buffer buffer(1); + + for (;;) { + /* Blocks until at least one event is available. */ + request.read_edge_events(buffer); + + for (const auto &event : buffer) + ::std::cout << "line: " << event.line_offset() + << " type: " << ::std::setw(7) << ::std::left << edge_event_type_str(event) + << " event #" << event.line_seqno() + << ::std::endl; + } +} diff --git a/bindings/cxx/examples/watch_multiple_line_values.cpp b/bindings/cxx/examples/watch_multiple_line_values.cpp new file mode 100644 index 0000000..42b7213 --- /dev/null +++ b/bindings/cxx/examples/watch_multiple_line_values.cpp @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2023 Kent Gibson + +/* Minimal example of watching for edges on multiple lines. */ + +#include +#include +#include +#include + +namespace { + +/* Example configuration - customize to suit your situation */ +const ::std::filesystem::path chip_path("/dev/gpiochip0"); +const ::gpiod::line::offsets line_offsets = { 5, 3, 7 }; + +const char *edge_event_type_str(const ::gpiod::edge_event &event) +{ + switch (event.type()) { + case ::gpiod::edge_event::event_type::RISING_EDGE: + return "Rising"; + case ::gpiod::edge_event::event_type::FALLING_EDGE: + return "Falling"; + default: + return "Unknown"; + } +} + +} /* namespace */ + +int main(void) +{ + auto request = + ::gpiod::chip(chip_path) + .prepare_request() + .set_consumer("watch-multiple-line-values") + .add_line_settings( + line_offsets, + ::gpiod::line_settings() + .set_direction( + ::gpiod::line::direction::INPUT) + .set_edge_detection( + ::gpiod::line::edge::BOTH)) + .do_request(); + + ::gpiod::edge_event_buffer buffer; + + for (;;) { + /* Blocks until at leat one event available */ + request.read_edge_events(buffer); + + for (const auto &event : buffer) + ::std::cout << "offset: " << event.line_offset() + << " type: " << ::std::setw(7) + << ::std::left << edge_event_type_str(event) + << " event #" << event.global_seqno() + << " line event #" << event.line_seqno() + << ::std::endl; + } +} From patchwork Fri Jun 23 04:38:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1798743 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=h7fScYj9; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QnPfz6dVMz20Xk for ; Fri, 23 Jun 2023 14:40:11 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230264AbjFWEkK (ORCPT ); Fri, 23 Jun 2023 00:40:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46802 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230242AbjFWEkJ (ORCPT ); Fri, 23 Jun 2023 00:40:09 -0400 Received: from mail-oi1-x22c.google.com (mail-oi1-x22c.google.com [IPv6:2607:f8b0:4864:20::22c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9E242128 for ; Thu, 22 Jun 2023 21:40:08 -0700 (PDT) Received: by mail-oi1-x22c.google.com with SMTP id 5614622812f47-3a04cb10465so155242b6e.3 for ; Thu, 22 Jun 2023 21:40:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687495208; x=1690087208; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4X00U/c2a3nAqsZ7vytz9mK2p+5PhIFXIomdlvmJivo=; b=h7fScYj95euSbBNJ4kqmngRo8/uRzdmSfCgaUZxnZJGdaBh0klmWi0rYMZC41FY9c4 2s8+T9Ee7VshtmqKN132fi7b3GvviHscZK1fFvxrh7nD0Pg1aFEJnOxgaswSSFKo1xqF skjJ/Pliru/vCvWPMbB7eaOyKBS8j7OtPMDvIBKvFgWdRvWAwmSgQjZiucXuxq3lc60f wk2SFleZ1MKMEIsP5ESHYQdG+WzpsXqVZ9GYYUgDZVOTVxaQkobaer6Uk4iglyiWVJJ2 y2SAiqeVQKSCZfPcYO5yzT9EP+XVcyL+hxN9S22JZNA5oETFcWBTf5g9FSQV+ALmaW/4 KYcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687495208; x=1690087208; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4X00U/c2a3nAqsZ7vytz9mK2p+5PhIFXIomdlvmJivo=; b=Vf9rQ5qhBV8tbfrCS82Zv5H3d5l7ECJ1ghAMW3ss9EtVON7IMEdMNg30ea/yRA1k5A PzGvTlPYIlH6ZZQfPqVwL/6r0u210grnXZTqIuqGc7vHXSkvsUMtMzec7M+Dm58FANHr sXaqRdXI31GXxWtUxmXFD0DxBzjPG0HpngIyOKIfgLMGx9fkmfuylNs0TLsD25MV+P7q gQnfZXfBw2sKZtiPjs8sJ8fQ4EhpkyOF5t/oaSij2XTrO5FbbYgc2+YGkiT/OGacva8u 56l7q9WLL+aQaBZaG3DBvZxfurPIVdhjdevOmDifysMt9OMp5erPViF3RjOhw0E3nmKw buOg== X-Gm-Message-State: AC+VfDx0KA9HYpGNnqDvxGn0jmTskEtgVLb1uu7Lz+c+tRaYe3lPryMl cbV5Ly7xzt7eIwKNZDWM9reAQ2VIniI= X-Google-Smtp-Source: ACHHUZ5Wem9dy2NQBeVFjYs+NIlFDgTr58X5XEb/HElhN7WDhqIZ6fuYnegtN04QLguDCvtjBcJ4KQ== X-Received: by 2002:a54:4111:0:b0:3a0:6949:c884 with SMTP id l17-20020a544111000000b003a06949c884mr2852166oic.34.1687495208072; Thu, 22 Jun 2023 21:40:08 -0700 (PDT) Received: from sol.home.arpa (194-223-178-180.tpgi.com.au. [194.223.178.180]) by smtp.gmail.com with ESMTPSA id q23-20020a17090ad39700b0025c2c398d33sm509463pju.39.2023.06.22.21.40.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jun 2023 21:40:07 -0700 (PDT) From: Kent Gibson To: linux-gpio@vger.kernel.org, brgl@bgdev.pl Cc: Kent Gibson Subject: [libgpiod][PATCH 5/8] bindings: python: examples: consistency cleanup Date: Fri, 23 Jun 2023 12:38:58 +0800 Message-ID: <20230623043901.16764-6-warthog618@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230623043901.16764-1-warthog618@gmail.com> References: <20230623043901.16764-1-warthog618@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org A collection of minor changes to be more consistent with other examples: - capitalize comments - add line offset to value outputs - drop comma from edge event outputs - improve behaviour if run on a platform that does not match the example configuration - use with to cleanup request in toggle_line_value.py Signed-off-by: Kent Gibson --- .../python/examples/async_watch_line_value.py | 15 ++++---- bindings/python/examples/get_line_value.py | 13 ++++--- bindings/python/examples/toggle_line_value.py | 34 +++++++------------ bindings/python/examples/watch_line_value.py | 19 +++++------ 4 files changed, 35 insertions(+), 46 deletions(-) diff --git a/bindings/python/examples/async_watch_line_value.py b/bindings/python/examples/async_watch_line_value.py index ed09ec9..ea8314f 100755 --- a/bindings/python/examples/async_watch_line_value.py +++ b/bindings/python/examples/async_watch_line_value.py @@ -19,12 +19,8 @@ def edge_type(event): return "Unknown" -def async_watch_line_value(): - # example configuration - customise to suit your situation - chip_path = "/dev/gpiochip0" - line_offset = 5 - - # assume a button connecting the pin to ground, +def async_watch_line_value(chip_path, line_offset): + # Assume a button connecting the pin to ground, # so pull it up and provide some debounce. with gpiod.request_lines( chip_path, @@ -40,7 +36,7 @@ def async_watch_line_value(): poll = select.poll() poll.register(request.fd, select.POLLIN) while True: - # other fds could be registered with the poll and be handled + # Other fds could be registered with the poll and be handled # separately using the return value (fd, event) from poll() poll.poll() for event in request.read_edge_events(): @@ -51,4 +47,7 @@ def async_watch_line_value(): if __name__ == "__main__": - async_watch_line_value() + try: + async_watch_line_value("/dev/gpiochip0", 5) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/bindings/python/examples/get_line_value.py b/bindings/python/examples/get_line_value.py index ab733df..f3ca13b 100755 --- a/bindings/python/examples/get_line_value.py +++ b/bindings/python/examples/get_line_value.py @@ -9,19 +9,18 @@ import gpiod from gpiod.line import Direction -def get_line_value(): - # example configuration - customise to suit your situation - chip_path = "/dev/gpiochip0" - line_offset = 5 - +def get_line_value(chip_path, line_offset): with gpiod.request_lines( chip_path, consumer="get-line-value", config={line_offset: gpiod.LineSettings(direction=Direction.INPUT)}, ) as request: value = request.get_value(line_offset) - print(value) + print("{}={}".format(line_offset, value)) if __name__ == "__main__": - get_line_value() + try: + get_line_value("/dev/gpiochip0", 5) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/bindings/python/examples/toggle_line_value.py b/bindings/python/examples/toggle_line_value.py index 46e52f9..e0de8fb 100755 --- a/bindings/python/examples/toggle_line_value.py +++ b/bindings/python/examples/toggle_line_value.py @@ -16,21 +16,11 @@ def toggle_value(value): return Value.INACTIVE -def print_value(value): - if value == Value.ACTIVE: - print("Active") - else: - print("Inactive") - - -def toggle_line_value(): - # example configuration - customise to suit your situation - chip_path = "/dev/gpiochip0" - line_offset = 5 - +def toggle_line_value(chip_path, line_offset): + value_str = {Value.ACTIVE: "Active", Value.INACTIVE: "Inactive"} value = Value.ACTIVE - request = gpiod.request_lines( + with gpiod.request_lines( chip_path, consumer="toggle-line-value", config={ @@ -38,14 +28,16 @@ def toggle_line_value(): direction=Direction.OUTPUT, output_value=value ) }, - ) - - while True: - print_value(value) - time.sleep(1) - value = toggle_value(value) - request.set_value(line_offset, value) + ) as request: + while True: + print("{}={}".format(line_offset, value_str[value])) + time.sleep(1) + value = toggle_value(value) + request.set_value(line_offset, value) if __name__ == "__main__": - toggle_line_value() + try: + toggle_line_value("/dev/gpiochip0", 5) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/bindings/python/examples/watch_line_value.py b/bindings/python/examples/watch_line_value.py index 42fc0bd..841bf40 100755 --- a/bindings/python/examples/watch_line_value.py +++ b/bindings/python/examples/watch_line_value.py @@ -12,18 +12,14 @@ from gpiod.line import Bias, Edge def edge_type(event): if event.event_type is event.Type.RISING_EDGE: - return "Rising " + return "Rising" if event.event_type is event.Type.FALLING_EDGE: return "Falling" return "Unknown" -def watch_line_value(): - # example configuration - customise to suit your situation - chip_path = "/dev/gpiochip0" - line_offset = 5 - - # assume a button connecting the pin to ground, +def watch_line_value(chip_path, line_offset): + # Assume a button connecting the pin to ground, # so pull it up and provide some debounce. with gpiod.request_lines( chip_path, @@ -37,13 +33,16 @@ def watch_line_value(): }, ) as request: while True: - # blocks until at least one event is available + # Blocks until at least one event is available for event in request.read_edge_events(): print( - "offset: %d, type: %s, event #%d" + "line: %d type: %-7s event #%d" % (event.line_offset, edge_type(event), event.line_seqno) ) if __name__ == "__main__": - watch_line_value() + try: + watch_line_value("/dev/gpiochip0", 5) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") From patchwork Fri Jun 23 04:38:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1798744 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=ZZoSWvSP; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QnPgG5FJHz20Xk for ; Fri, 23 Jun 2023 14:40:26 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230071AbjFWEkZ (ORCPT ); Fri, 23 Jun 2023 00:40:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229484AbjFWEkX (ORCPT ); Fri, 23 Jun 2023 00:40:23 -0400 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82F612126 for ; Thu, 22 Jun 2023 21:40:20 -0700 (PDT) Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-25e8b2931f2so136393a91.2 for ; Thu, 22 Jun 2023 21:40:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687495220; x=1690087220; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=I7PehO+mKk6dDFItCgpuXwovJGnD81J2UstOEWa9kdo=; b=ZZoSWvSPAq3t9eZagV2OP/uxd7b5aQs2z4WGpgwneUG7ZUTjfA0S+NIsfxkFFOqnw5 ZIjJsGGoOcqbTPwIf5WnoggOcJGrxPsJwLJbjPckxQ7z7aXcpZVJjBMwDdb77mCSvCSf Codv1Fsq8/nR18Gnxr0+gTGQdHE7hgebfIPN+bLcCik6joobbkcv3cVJ0wNA867bYlDh Gv+LSTAoIT1j1wM9zFkCH0tOBPZIuIyYae8lBZHF7X95Cpmt2CQtBIvt7iIskvJh/Uuk mPxtySW0rnBjizRUfbnsPrBsW2PjbG+zo+hAoSbTDDvGnu4ovOv9Ejhjm0j/uPTzTwVD wRew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687495220; x=1690087220; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=I7PehO+mKk6dDFItCgpuXwovJGnD81J2UstOEWa9kdo=; b=N94qByXtB8HHcuXOM6bQ+8qA2EFkCZV/e6cul0ZBdR3HxxVaE6skO4hIQQynCNOAqF DzPIwzQtoBUwgOPkN9bZI1ljfXgRHvfw3xLkjBCdZ7vnakXGSpNhta2Hs9lLXUwbSnDS LebmxiJ9QQe3urIny/vYX16U7CX98ZcueStU5nEqcO17muREkRN4seXHojKv1bbPtvFv fhRqguvpNAg/BHH9qJAZ7TTWEHO0iCSjSojCOtJir95xT0h1RIT8sDoYH/q7WTtwwe1u YvcV9SLoUahR7fisFh1EEoXoXU0ECqF7kTlmNabdH2Ihg0TJg4LaqFueGAJcOda3lkGB HWog== X-Gm-Message-State: AC+VfDwJ+p+Mm0BQSSfkvJmMhOSuKEZle/SuSTo37ZTsZTljtwsmkv5P iCL1Os72K4gukDoc3SFswnpHz+YUyhM= X-Google-Smtp-Source: ACHHUZ4JGhkaIzAfNYvLQe66ptG5/RJlBu6M7ynG25+KhKXbNka2llJtXb+hqcMl9VxWwB+yzdBzPg== X-Received: by 2002:a17:90a:2d8f:b0:255:2dde:17cc with SMTP id p15-20020a17090a2d8f00b002552dde17ccmr19746887pjd.47.1687495219415; Thu, 22 Jun 2023 21:40:19 -0700 (PDT) Received: from sol.home.arpa (194-223-178-180.tpgi.com.au. [194.223.178.180]) by smtp.gmail.com with ESMTPSA id q23-20020a17090ad39700b0025c2c398d33sm509463pju.39.2023.06.22.21.40.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jun 2023 21:40:19 -0700 (PDT) From: Kent Gibson To: linux-gpio@vger.kernel.org, brgl@bgdev.pl Cc: Kent Gibson Subject: [libgpiod][PATCH 6/8] bindings: python: examples: replace tools examples with use case examples Date: Fri, 23 Jun 2023 12:38:59 +0800 Message-ID: <20230623043901.16764-7-warthog618@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230623043901.16764-1-warthog618@gmail.com> References: <20230623043901.16764-1-warthog618@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Replace tool examples with use case examples drawn from the tools. Signed-off-by: Kent Gibson --- bindings/python/examples/Makefile.am | 18 +++---- bindings/python/examples/find_line_by_name.py | 37 +++++++++++++++ bindings/python/examples/get_chip_info.py | 20 ++++++++ bindings/python/examples/get_line_info.py | 29 ++++++++++++ .../examples/get_multiple_line_values.py | 29 ++++++++++++ bindings/python/examples/gpiodetect.py | 15 ------ bindings/python/examples/gpiofind.py | 20 -------- bindings/python/examples/gpioget.py | 29 ------------ bindings/python/examples/gpioinfo.py | 28 ----------- bindings/python/examples/gpiomon.py | 26 ---------- bindings/python/examples/gpionotify.py | 21 --------- bindings/python/examples/gpioset.py | 36 -------------- bindings/python/examples/helpers.py | 15 ------ .../examples/reconfigure_input_to_output.py | 39 +++++++++++++++ .../examples/toggle_multiple_line_values.py | 47 +++++++++++++++++++ bindings/python/examples/watch_line_info.py | 23 +++++++++ bindings/python/examples/watch_line_rising.py | 31 ++++++++++++ .../examples/watch_multiple_line_values.py | 43 +++++++++++++++++ 18 files changed, 308 insertions(+), 198 deletions(-) create mode 100755 bindings/python/examples/find_line_by_name.py create mode 100755 bindings/python/examples/get_chip_info.py create mode 100755 bindings/python/examples/get_line_info.py create mode 100755 bindings/python/examples/get_multiple_line_values.py delete mode 100755 bindings/python/examples/gpiodetect.py delete mode 100755 bindings/python/examples/gpiofind.py delete mode 100755 bindings/python/examples/gpioget.py delete mode 100755 bindings/python/examples/gpioinfo.py delete mode 100755 bindings/python/examples/gpiomon.py delete mode 100755 bindings/python/examples/gpionotify.py delete mode 100755 bindings/python/examples/gpioset.py delete mode 100644 bindings/python/examples/helpers.py create mode 100755 bindings/python/examples/reconfigure_input_to_output.py create mode 100755 bindings/python/examples/toggle_multiple_line_values.py create mode 100755 bindings/python/examples/watch_line_info.py create mode 100755 bindings/python/examples/watch_line_rising.py create mode 100755 bindings/python/examples/watch_multiple_line_values.py diff --git a/bindings/python/examples/Makefile.am b/bindings/python/examples/Makefile.am index c8c1c98..52abafc 100644 --- a/bindings/python/examples/Makefile.am +++ b/bindings/python/examples/Makefile.am @@ -3,13 +3,15 @@ EXTRA_DIST = \ async_watch_line_value.py \ + find_line_by_name.py \ + get_chip_info.py \ + get_line_info.py \ get_line_value.py \ - gpiodetect.py \ - gpiofind.py \ - gpioget.py \ - gpioinfo.py \ - gpiomon.py \ - gpionotify.py \ - gpioset.py \ + get_multiple_line_values.py \ + reconfigure_input_to_output.py \ toggle_line_value.py \ - watch_line_value.py + toggle_multiple_line_values.py \ + watch_line_requests.py \ + watch_line_value.py \ + watch_line_rising.py \ + watch_multiple_line_values.py diff --git a/bindings/python/examples/find_line_by_name.py b/bindings/python/examples/find_line_by_name.py new file mode 100755 index 0000000..58f1cd0 --- /dev/null +++ b/bindings/python/examples/find_line_by_name.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Kent Gibson + +"""Minimal example of finding a line with the given name.""" + +import gpiod +import os + + +def gpio_chips(): + for entry in os.scandir("/dev/"): + if gpiod.is_gpiochip_device(entry.path): + yield entry.path + + +def find_line_by_name(line_name): + # Names are not guaranteed unique, so this finds the first line with + # the given name. + for path in gpio_chips(): + with gpiod.Chip(path) as chip: + try: + offset = chip.line_offset_from_id(line_name) + print("{}: {} {}".format(line_name, chip.get_info().name, offset)) + return + except OSError: + # An OSError is raised if the name is not found. + continue + + print("line '{}' not found".format(line_name)) + + +if __name__ == "__main__": + try: + find_line_by_name("GPIO19") + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/bindings/python/examples/get_chip_info.py b/bindings/python/examples/get_chip_info.py new file mode 100755 index 0000000..7dc76fb --- /dev/null +++ b/bindings/python/examples/get_chip_info.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Kent Gibson + +"""Minimal example of reading the info for a chip.""" + +import gpiod + + +def get_chip_info(chip_path): + with gpiod.Chip(chip_path) as chip: + info = chip.get_info() + print("{} [{}] ({} lines)".format(info.name, info.label, info.num_lines)) + + +if __name__ == "__main__": + try: + get_chip_info("/dev/gpiochip0") + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/bindings/python/examples/get_line_info.py b/bindings/python/examples/get_line_info.py new file mode 100755 index 0000000..cd4ebcc --- /dev/null +++ b/bindings/python/examples/get_line_info.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Kent Gibson + +"""Minimal example of reading the info for a line.""" + +import gpiod + + +def get_line_info(chip_path, line_offset): + with gpiod.Chip(chip_path) as chip: + info = chip.get_line_info(line_offset) + is_input = info.direction == gpiod.line.Direction.INPUT + print( + "line {:>3}: {:>12} {:>12} {:>8} {:>10}".format( + info.offset, + info.name or "unnamed", + info.consumer or "unused", + "input" if is_input else "output", + "active-low" if info.active_low else "active-high", + ) + ) + + +if __name__ == "__main__": + try: + get_line_info("/dev/gpiochip0", 3) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/bindings/python/examples/get_multiple_line_values.py b/bindings/python/examples/get_multiple_line_values.py new file mode 100755 index 0000000..46cf0b2 --- /dev/null +++ b/bindings/python/examples/get_multiple_line_values.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Kent Gibson + +"""Minimal example of reading multiple lines.""" + +import gpiod + +from gpiod.line import Direction + + +def get_multiple_line_values(chip_path, line_offsets): + with gpiod.request_lines( + chip_path, + consumer="get-multiple-line-values", + config={tuple(line_offsets): gpiod.LineSettings(direction=Direction.INPUT)}, + ) as request: + vals = request.get_values() + + for offset, val in zip(line_offsets, vals): + print("{}={} ".format(offset, val), end="") + print() + + +if __name__ == "__main__": + try: + get_multiple_line_values("/dev/gpiochip0", [5, 3, 7]) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/bindings/python/examples/gpiodetect.py b/bindings/python/examples/gpiodetect.py deleted file mode 100755 index dc98b03..0000000 --- a/bindings/python/examples/gpiodetect.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: GPL-2.0-or-later -# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski - -"""Reimplementation of the gpiodetect tool in Python.""" - -import gpiod -import os - -from helpers import gpio_chips - -if __name__ == "__main__": - for chip in gpio_chips(): - info = chip.get_info() - print("{} [{}] ({} lines)".format(info.name, info.label, info.num_lines)) diff --git a/bindings/python/examples/gpiofind.py b/bindings/python/examples/gpiofind.py deleted file mode 100755 index d41660d..0000000 --- a/bindings/python/examples/gpiofind.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: GPL-2.0-or-later -# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski - -"""Reimplementation of the gpiofind tool in Python.""" - -import gpiod -import os -import sys - -if __name__ == "__main__": - for entry in os.scandir("/dev/"): - if gpiod.is_gpiochip_device(entry.path): - with gpiod.Chip(entry.path) as chip: - offset = chip.line_offset_from_id(sys.argv[1]) - if offset is not None: - print("{} {}".format(chip.get_info().name, offset)) - sys.exit(0) - - sys.exit(1) diff --git a/bindings/python/examples/gpioget.py b/bindings/python/examples/gpioget.py deleted file mode 100755 index bf7e0a6..0000000 --- a/bindings/python/examples/gpioget.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: GPL-2.0-or-later -# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski - -"""Simplified reimplementation of the gpioget tool in Python.""" - -import gpiod -import sys - -from gpiod.line import Direction - -if __name__ == "__main__": - if len(sys.argv) < 3: - raise TypeError("usage: gpioget.py ...") - - path = sys.argv[1] - lines = [int(line) if line.isdigit() else line for line in sys.argv[2:]] - - request = gpiod.request_lines( - path, - consumer="gpioget.py", - config={tuple(lines): gpiod.LineSettings(direction=Direction.INPUT)}, - ) - - vals = request.get_values() - - for val in vals: - print("{} ".format(val.value), end="") - print() diff --git a/bindings/python/examples/gpioinfo.py b/bindings/python/examples/gpioinfo.py deleted file mode 100755 index 3996dcf..0000000 --- a/bindings/python/examples/gpioinfo.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: GPL-2.0-or-later -# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski - -"""Simplified reimplementation of the gpioinfo tool in Python.""" - -import gpiod -import os - -from helpers import gpio_chips - -if __name__ == "__main__": - for chip in gpio_chips(): - cinfo = chip.get_info() - print("{} - {} lines:".format(cinfo.name, cinfo.num_lines)) - - for offset in range(0, cinfo.num_lines): - linfo = chip.get_line_info(offset) - is_input = linfo.direction == gpiod.line.Direction.INPUT - print( - "\tline {:>3}: {:>18} {:>12} {:>8} {:>10}".format( - linfo.offset, - linfo.name or "unnamed", - linfo.consumer or "unused", - "input" if is_input else "output", - "active-low" if linfo.active_low else "active-high", - ) - ) diff --git a/bindings/python/examples/gpiomon.py b/bindings/python/examples/gpiomon.py deleted file mode 100755 index 702d7c8..0000000 --- a/bindings/python/examples/gpiomon.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: GPL-2.0-or-later -# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski - -"""Simplified reimplementation of the gpiomon tool in Python.""" - -import gpiod -import sys - -from gpiod.line import Edge - -if __name__ == "__main__": - if len(sys.argv) < 3: - raise TypeError("usage: gpiomon.py ...") - - path = sys.argv[1] - lines = [int(line) if line.isdigit() else line for line in sys.argv[2:]] - - with gpiod.request_lines( - path, - consumer="gpiomon.py", - config={tuple(lines): gpiod.LineSettings(edge_detection=Edge.BOTH)}, - ) as request: - while True: - for event in request.read_edge_events(): - print(event) diff --git a/bindings/python/examples/gpionotify.py b/bindings/python/examples/gpionotify.py deleted file mode 100755 index 4e50515..0000000 --- a/bindings/python/examples/gpionotify.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: GPL-2.0-or-later -# SPDX-FileCopyrightText: 2023 Bartosz Golaszewski - -"""Simplified reimplementation of the gpionotify tool in Python.""" - -import gpiod -import sys - -if __name__ == "__main__": - if len(sys.argv) < 3: - raise TypeError("usage: gpionotify.py ...") - - path = sys.argv[1] - - with gpiod.Chip(path) as chip: - for line in sys.argv[2:]: - chip.watch_line_info(line) - - while True: - print(chip.read_info_event()) diff --git a/bindings/python/examples/gpioset.py b/bindings/python/examples/gpioset.py deleted file mode 100755 index e6a516c..0000000 --- a/bindings/python/examples/gpioset.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: GPL-2.0-or-later -# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski - -"""Simplified reimplementation of the gpioset tool in Python.""" - -import gpiod -import sys - -from gpiod.line import Direction, Value - -if __name__ == "__main__": - if len(sys.argv) < 3: - raise TypeError( - "usage: gpioset.py = = ..." - ) - - path = sys.argv[1] - - def parse_value(arg): - x, y = arg.split("=") - return (x, Value(int(y))) - - def make_settings(val): - return gpiod.LineSettings(direction=Direction.OUTPUT, output_value=val) - - lvs = [parse_value(arg) for arg in sys.argv[2:]] - config = dict((l, make_settings(v)) for (l, v) in lvs) - - request = gpiod.request_lines( - path, - consumer="gpioset.py", - config=config, - ) - - input() diff --git a/bindings/python/examples/helpers.py b/bindings/python/examples/helpers.py deleted file mode 100644 index 8b91173..0000000 --- a/bindings/python/examples/helpers.py +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: LGPL-2.1-or-later -# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski - -import gpiod -import os - - -def gpio_chips(): - for path in [ - entry.path - for entry in os.scandir("/dev/") - if gpiod.is_gpiochip_device(entry.path) - ]: - with gpiod.Chip(path) as chip: - yield chip diff --git a/bindings/python/examples/reconfigure_input_to_output.py b/bindings/python/examples/reconfigure_input_to_output.py new file mode 100755 index 0000000..60d3015 --- /dev/null +++ b/bindings/python/examples/reconfigure_input_to_output.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Kent Gibson + +"""Minimal example of requesting a line intended for bi-directional use as input and then switching to output.""" + +import gpiod + +from gpiod.line import Direction, Value + + +def reconfigure_input_to_output(chip_path, line_offset): + # request the line initially as an input + with gpiod.request_lines( + chip_path, + consumer="reconfigure-input-to-output", + config={line_offset: gpiod.LineSettings(direction=Direction.INPUT)}, + ) as request: + # read the current line value + value = request.get_value(line_offset) + print("{}={} (input)".format(line_offset, value)) + # switch the line to an output and drive it low + request.reconfigure_lines( + config={ + line_offset: gpiod.LineSettings( + direction=Direction.OUTPUT, output_value=Value.INACTIVE + ) + } + ) + # report the current driven value + value = request.get_value(line_offset) + print("{}={} (output)".format(line_offset, value)) + + +if __name__ == "__main__": + try: + reconfigure_input_to_output("/dev/gpiochip0", 5) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/bindings/python/examples/toggle_multiple_line_values.py b/bindings/python/examples/toggle_multiple_line_values.py new file mode 100755 index 0000000..12b968d --- /dev/null +++ b/bindings/python/examples/toggle_multiple_line_values.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Kent Gibson + +"""Minimal example of toggling multiple lines.""" + +import gpiod +import time + +from gpiod.line import Direction, Value + + +def toggle_value(value): + if value == Value.INACTIVE: + return Value.ACTIVE + return Value.INACTIVE + + +def toggle_multiple_line_values(chip_path, line_values): + value_str = {Value.ACTIVE: "Active", Value.INACTIVE: "Inactive"} + + request = gpiod.request_lines( + chip_path, + consumer="toggle-multiple-line-values", + config={ + tuple(line_values.keys()): gpiod.LineSettings(direction=Direction.OUTPUT) + }, + output_values=line_values, + ) + + while True: + print( + " ".join("{}={}".format(l, value_str[v]) for (l, v) in line_values.items()) + ) + time.sleep(1) + for l, v in line_values.items(): + line_values[l] = toggle_value(v) + request.set_values(line_values) + + +if __name__ == "__main__": + try: + toggle_multiple_line_values( + "/dev/gpiochip0", {5: Value.ACTIVE, 3: Value.ACTIVE, 7: Value.INACTIVE} + ) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/bindings/python/examples/watch_line_info.py b/bindings/python/examples/watch_line_info.py new file mode 100755 index 0000000..e49a669 --- /dev/null +++ b/bindings/python/examples/watch_line_info.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Kent Gibson + +"""Minimal example of watching for info changes on particular lines.""" + +import gpiod + + +def watch_line_info(chip_path, line_offsets): + with gpiod.Chip(chip_path) as chip: + for offset in line_offsets: + chip.watch_line_info(offset) + + while True: + print(chip.read_info_event()) + + +if __name__ == "__main__": + try: + watch_line_info("/dev/gpiochip0", [5, 3, 7]) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/bindings/python/examples/watch_line_rising.py b/bindings/python/examples/watch_line_rising.py new file mode 100755 index 0000000..2350d76 --- /dev/null +++ b/bindings/python/examples/watch_line_rising.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Kent Gibson + +"""Minimal example of watching for rising edges on a single line.""" + +import gpiod + +from gpiod.line import Edge + + +def watch_line_rising(chip_path, line_offset): + with gpiod.request_lines( + chip_path, + consumer="watch-line-rising", + config={line_offset: gpiod.LineSettings(edge_detection=Edge.RISING)}, + ) as request: + while True: + # Blocks until at least one event is available + for event in request.read_edge_events(): + print( + "line: %d type: Rising event #%d" + % (event.line_offset, event.line_seqno) + ) + + +if __name__ == "__main__": + try: + watch_line_rising("/dev/gpiochip0", 5) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/bindings/python/examples/watch_multiple_line_values.py b/bindings/python/examples/watch_multiple_line_values.py new file mode 100755 index 0000000..4fbf05c --- /dev/null +++ b/bindings/python/examples/watch_multiple_line_values.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Kent Gibson + +"""Minimal example of watching for edges on multiple lines.""" + +import gpiod + +from gpiod.line import Edge + + +def edge_type(event): + if event.event_type is event.Type.RISING_EDGE: + return "Rising" + if event.event_type is event.Type.FALLING_EDGE: + return "Falling" + return "Unknown" + + +def watch_multiple_line_values(chip_path, line_offsets): + with gpiod.request_lines( + chip_path, + consumer="watch-multiple-line-values", + config={tuple(line_offsets): gpiod.LineSettings(edge_detection=Edge.BOTH)}, + ) as request: + while True: + for event in request.read_edge_events(): + print( + "offset: %d type: %-7s event #%d line event #%d" + % ( + event.line_offset, + edge_type(event), + event.global_seqno, + event.line_seqno, + ) + ) + + +if __name__ == "__main__": + try: + watch_multiple_line_values("/dev/gpiochip0", [5, 3, 7]) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") From patchwork Fri Jun 23 04:39:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1798745 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=AaZknz7S; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QnPgQ1GTRz20Xk for ; Fri, 23 Jun 2023 14:40:34 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230242AbjFWEkd (ORCPT ); Fri, 23 Jun 2023 00:40:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46886 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229484AbjFWEkb (ORCPT ); Fri, 23 Jun 2023 00:40:31 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D09CC2126 for ; Thu, 22 Jun 2023 21:40:30 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id 98e67ed59e1d1-25695bb6461so1017059a91.1 for ; Thu, 22 Jun 2023 21:40:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687495230; x=1690087230; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Aicv3iSaSdW9gNmipfOFxBBI9tBLPlse2rRBJRUbMeA=; b=AaZknz7SMHmWuWa6UKsYvLuWLk6xPlgbC7J9gHd8Zmm2FNjSd/mR83kohGW0BNBl4z s3TWjeLITBJkFcwmW/jRQVO475SqX1WK+IT9zj7PMoAoHH/bqOUguH6amLq8jtoVBgSn YHaQMREdaP+bstufwjd//bKXc/rbjiO4HiyVK0npU6oBXzBnnJaqphueWMUZufOuPngF cPCJTh8K8q6iOClSdtreqEzycWFZH4XVTs374DkpTq6Ef+ekqv0Q9aXO1tsdObzSTGyq F2SJ8C2kg5BtvM5C81U3TieRuCarR12yVJhFmZ3dtFIDpDK8y8iK57WGZA0GEjcaqOvw 7zqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687495230; x=1690087230; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Aicv3iSaSdW9gNmipfOFxBBI9tBLPlse2rRBJRUbMeA=; b=a0FfeOFZziV497fWIXuj37kp9oHtcl4HcqRwU0Nf5Pv+gUIKqD2EqeNyAKyRYUGeOq sqxMr4lgrPtAtFJwdzijwL6rLEvESlZssoZHXQmlT/ZujewQzm2AuM2HcldSpoYGu6+v A7uLZZZydNQ15VLPSWm0G0Xi69T3aYGeJTAwUZd3ai2Ej0/VB+uN3n23QwJ71EdRAbH2 zLp+vtB2sgS5KH0XwZd7cm7w4z1cRwvcanB0bl9kyMp/2xzuyhr18utKTGsA7A6mjX4G Cy9Uwac487aH3xcWvj2+l9FWqG510koSZ0yu1zo6A8DTe19jz0opyIe5BMKe+worQkCc Z8PA== X-Gm-Message-State: AC+VfDwcUEkd7jmzjbbMiqOL+xf676fFD+dXuq3F8DtECvfTJlkYE4jn /YAKIPAiIJYEOlxjy8MWwk2U7eHp44E= X-Google-Smtp-Source: ACHHUZ6d4av/ZP/porE8MMvDAEl6fb2rBa0BM9FEy+U4g1+Zz2fyrHwt9MT2GOUHxEJ0OuHGeeRq5A== X-Received: by 2002:a17:90a:6286:b0:25e:b5d4:a156 with SMTP id d6-20020a17090a628600b0025eb5d4a156mr28140822pjj.2.1687495230091; Thu, 22 Jun 2023 21:40:30 -0700 (PDT) Received: from sol.home.arpa (194-223-178-180.tpgi.com.au. [194.223.178.180]) by smtp.gmail.com with ESMTPSA id q23-20020a17090ad39700b0025c2c398d33sm509463pju.39.2023.06.22.21.40.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jun 2023 21:40:29 -0700 (PDT) From: Kent Gibson To: linux-gpio@vger.kernel.org, brgl@bgdev.pl Cc: Kent Gibson Subject: [libgpiod][PATCH 7/8] bindings: rust: examples: consistency cleanup Date: Fri, 23 Jun 2023 12:39:00 +0800 Message-ID: <20230623043901.16764-8-warthog618@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230623043901.16764-1-warthog618@gmail.com> References: <20230623043901.16764-1-warthog618@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org A collection of minor changes to be more consistent with other examples: - capitalize comments - add line offset to value outputs - drop comma from edge event outputs Signed-off-by: Kent Gibson Reviewed-by: Erik Schilling --- .../rust/libgpiod/examples/get_line_value.rs | 4 ++-- .../rust/libgpiod/examples/toggle_line_value.rs | 17 ++++++++--------- .../rust/libgpiod/examples/watch_line_value.rs | 10 +++++----- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/bindings/rust/libgpiod/examples/get_line_value.rs b/bindings/rust/libgpiod/examples/get_line_value.rs index 732fb71..39141e2 100644 --- a/bindings/rust/libgpiod/examples/get_line_value.rs +++ b/bindings/rust/libgpiod/examples/get_line_value.rs @@ -6,7 +6,7 @@ use libgpiod::line; fn main() -> libgpiod::Result<()> { - // example configuration - customize to suit your situation + // Example configuration - customize to suit your situation let chip_path = "/dev/gpiochip0"; let line_offset = 5; @@ -23,6 +23,6 @@ fn main() -> libgpiod::Result<()> { let request = chip.request_lines(Some(&rconfig), &lconfig)?; let value = request.value(line_offset)?; - println!("{:?}", value); + println!("{}={:?}", line_offset, value); Ok(()) } diff --git a/bindings/rust/libgpiod/examples/toggle_line_value.rs b/bindings/rust/libgpiod/examples/toggle_line_value.rs index cd7038e..6d5f697 100644 --- a/bindings/rust/libgpiod/examples/toggle_line_value.rs +++ b/bindings/rust/libgpiod/examples/toggle_line_value.rs @@ -3,22 +3,21 @@ // // Minimal example of toggling a single line. -use libgpiod::line; -use std::time::Duration; +use core::time::Duration; +use libgpiod::line::{self, Value}; -fn toggle_value(value: line::Value) -> line::Value { +fn toggle_value(value: Value) -> Value { match value { - line::Value::Active => line::Value::InActive, - line::Value::InActive => line::Value::Active, + Value::Active => Value::InActive, + Value::InActive => Value::Active, } } fn main() -> libgpiod::Result<()> { - // example configuration - customize to suit your situation + // Example configuration - customize to suit your situation let chip_path = "/dev/gpiochip0"; let line_offset = 5; - - let mut value = line::Value::Active; + let mut value = Value::Active; let mut settings = line::Settings::new()?; settings @@ -35,7 +34,7 @@ fn main() -> libgpiod::Result<()> { let mut req = chip.request_lines(Some(&rconfig), &lconfig)?; loop { - println!("{:?}", value); + println!("{}={:?}", line_offset, value); std::thread::sleep(Duration::from_secs(1)); value = toggle_value(value); req.set_value(line_offset, value)?; diff --git a/bindings/rust/libgpiod/examples/watch_line_value.rs b/bindings/rust/libgpiod/examples/watch_line_value.rs index 5a95b6a..3bf40af 100644 --- a/bindings/rust/libgpiod/examples/watch_line_value.rs +++ b/bindings/rust/libgpiod/examples/watch_line_value.rs @@ -7,12 +7,12 @@ use libgpiod::line; use std::time::Duration; fn main() -> libgpiod::Result<()> { - // example configuration - customize to suit your situation + // Example configuration - customize to suit your situation let chip_path = "/dev/gpiochip0"; let line_offset = 5; let mut lsettings = line::Settings::new()?; - // assume a button connecting the pin to ground, + // Assume a button connecting the pin to ground, // so pull it up and provide some debounce. lsettings .set_edge_detection(Some(line::Edge::Both))? @@ -28,7 +28,7 @@ fn main() -> libgpiod::Result<()> { let chip = libgpiod::chip::Chip::open(&chip_path)?; let request = chip.request_lines(Some(&rconfig), &lconfig)?; - // a larger buffer is an optimisation for reading bursts of events from the + // A larger buffer is an optimisation for reading bursts of events from the // kernel, but that is not necessary in this case, so 1 is fine. let mut buffer = libgpiod::request::Buffer::new(1)?; loop { @@ -37,10 +37,10 @@ fn main() -> libgpiod::Result<()> { for event in events { let event = event?; println!( - "line: {}, type: {}, event #{}", + "line: {} type: {:<7} event #{}", event.line_offset(), match event.event_type()? { - line::EdgeKind::Rising => "Rising ", + line::EdgeKind::Rising => "Rising", line::EdgeKind::Falling => "Falling", }, event.line_seqno() From patchwork Fri Jun 23 04:39:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Gibson X-Patchwork-Id: 1798746 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=canMXTyV; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QnPgr5VMvz20Xk for ; Fri, 23 Jun 2023 14:40:56 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231460AbjFWEkx (ORCPT ); Fri, 23 Jun 2023 00:40:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47012 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231316AbjFWEkq (ORCPT ); Fri, 23 Jun 2023 00:40:46 -0400 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 08C592686 for ; Thu, 22 Jun 2023 21:40:42 -0700 (PDT) Received: by mail-pj1-x102e.google.com with SMTP id 98e67ed59e1d1-25e9e5f9e0cso70082a91.0 for ; Thu, 22 Jun 2023 21:40:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687495241; x=1690087241; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=iBXQ2xN/9S3exvadY1sG7spNVMDB2/dnp1h0M9QqrDY=; b=canMXTyV8e9pubb83w7cSidIhJL8lhVvEACmmo/QLeN8Yqu3/ltGDyTb3rqDH1DGDr 6Dt7cL2zqw+C7tu3so9ZhXFibN5T1GxOp/KA/SmMYrHWG2R764pQS5qvIXZvtA6xRoVm 0mwfkYN/3l00/1rN/aly+ePPwBMcWlQVIxbZtSjWz9Fiz2ev1kqH++HGb8uo5wKfs/XR QAp/1b5S+uY2TyEamQlrKtGPSF/wWcf49VqVpwfcW2DyYh5UgaS6xPjFjHeupXy1tGJ0 cyxEdM+3wkPIzxcpBECFzzjodhIqblZEQXZd9sl2ztQ2R7DXH7cvlUdM9kY0nb8K9m/C kxAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687495241; x=1690087241; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=iBXQ2xN/9S3exvadY1sG7spNVMDB2/dnp1h0M9QqrDY=; b=MpmSu7389hiDIXEDRwaMCTIop9STVF/RR2UO6ZDN+jKwl/uBty5B+6kCC1sBWPqyxp tEzIQRPR3Fq/Y5r04aCFqNEBjjwYPaOR2QDNI8d011FQvsdKLFyUfMj6zLqumHaqPW9C uVnFy5Jj445a8synZd63zbKC9VvvePD7SKA6hj66dPEtQhp/tnxK9ouCJq0LjCEkLDIo PKfqwbKvft4qS/h6CTHKoBWA59XoUVwF/DVBGuo8tmnhbzLnhtiWrxbrh+oYBmbAkl/U Zc2ardEsygQs0D01Pn30hUZ/t1OZ18WgsqlrViqL1DiG9IZttEuEIepOgF51FGUdQTtI T9xw== X-Gm-Message-State: AC+VfDxXMrhO9OpPmyU/tjWQkatYm+u0IwMDc82l18zpC5gde0xRV68r DMfvxbnXnS43HGQDcQVOFVIP489hBqU= X-Google-Smtp-Source: ACHHUZ4+XXCQGPBxbjA+bScmTR3LRoPSPwT2BvzLPB3R+bHv+5B/8uOsVcAwAtFqHFG1SpDvON/WnQ== X-Received: by 2002:a17:90a:30d:b0:262:a8b1:c241 with SMTP id 13-20020a17090a030d00b00262a8b1c241mr90448pje.47.1687495240232; Thu, 22 Jun 2023 21:40:40 -0700 (PDT) Received: from sol.home.arpa (194-223-178-180.tpgi.com.au. [194.223.178.180]) by smtp.gmail.com with ESMTPSA id q23-20020a17090ad39700b0025c2c398d33sm509463pju.39.2023.06.22.21.40.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jun 2023 21:40:39 -0700 (PDT) From: Kent Gibson To: linux-gpio@vger.kernel.org, brgl@bgdev.pl Cc: Kent Gibson Subject: [libgpiod][PATCH 8/8] bindings: rust: examples: replace tools examples with use case examples Date: Fri, 23 Jun 2023 12:39:01 +0800 Message-ID: <20230623043901.16764-9-warthog618@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230623043901.16764-1-warthog618@gmail.com> References: <20230623043901.16764-1-warthog618@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Replace tool examples with use case examples drawn from the tools, gpio_events example with buffered_event_lifetimes, and gpio_threaded_info_events with reconfigure_input_to_output. Signed-off-by: Kent Gibson Reviewed-by: Erik Schilling --- bindings/rust/libgpiod/examples/Makefile.am | 21 +-- .../examples/buffered_event_lifetimes.rs | 58 ++++++++ .../libgpiod/examples/find_line_by_name.rs | 29 ++++ .../rust/libgpiod/examples/get_chip_info.rs | 22 +++ .../rust/libgpiod/examples/get_line_info.rs | 37 +++++ .../examples/get_multiple_line_values.rs | 29 ++++ .../rust/libgpiod/examples/gpio_events.rs | 88 ------------ .../examples/gpio_threaded_info_events.rs | 132 ------------------ bindings/rust/libgpiod/examples/gpiodetect.rs | 30 ---- bindings/rust/libgpiod/examples/gpiofind.rs | 36 ----- bindings/rust/libgpiod/examples/gpioget.rs | 45 ------ bindings/rust/libgpiod/examples/gpioinfo.rs | 97 ------------- bindings/rust/libgpiod/examples/gpiomon.rs | 74 ---------- bindings/rust/libgpiod/examples/gpionotify.rs | 53 ------- bindings/rust/libgpiod/examples/gpioset.rs | 63 --------- bindings/rust/libgpiod/examples/gpiowatch.rs | 53 ------- .../examples/reconfigure_input_to_output.rs | 42 ++++++ .../examples/toggle_multiple_line_values.rs | 55 ++++++++ .../rust/libgpiod/examples/watch_line_info.rs | 32 +++++ .../libgpiod/examples/watch_line_rising.rs | 44 ++++++ .../examples/watch_multiple_line_values.rs | 46 ++++++ 21 files changed, 405 insertions(+), 681 deletions(-) create mode 100644 bindings/rust/libgpiod/examples/buffered_event_lifetimes.rs create mode 100644 bindings/rust/libgpiod/examples/find_line_by_name.rs create mode 100644 bindings/rust/libgpiod/examples/get_chip_info.rs create mode 100644 bindings/rust/libgpiod/examples/get_line_info.rs create mode 100644 bindings/rust/libgpiod/examples/get_multiple_line_values.rs delete mode 100644 bindings/rust/libgpiod/examples/gpio_events.rs delete mode 100644 bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs delete mode 100644 bindings/rust/libgpiod/examples/gpiodetect.rs delete mode 100644 bindings/rust/libgpiod/examples/gpiofind.rs delete mode 100644 bindings/rust/libgpiod/examples/gpioget.rs delete mode 100644 bindings/rust/libgpiod/examples/gpioinfo.rs delete mode 100644 bindings/rust/libgpiod/examples/gpiomon.rs delete mode 100644 bindings/rust/libgpiod/examples/gpionotify.rs delete mode 100644 bindings/rust/libgpiod/examples/gpioset.rs delete mode 100644 bindings/rust/libgpiod/examples/gpiowatch.rs create mode 100644 bindings/rust/libgpiod/examples/reconfigure_input_to_output.rs create mode 100644 bindings/rust/libgpiod/examples/toggle_multiple_line_values.rs create mode 100644 bindings/rust/libgpiod/examples/watch_line_info.rs create mode 100644 bindings/rust/libgpiod/examples/watch_line_rising.rs create mode 100644 bindings/rust/libgpiod/examples/watch_multiple_line_values.rs diff --git a/bindings/rust/libgpiod/examples/Makefile.am b/bindings/rust/libgpiod/examples/Makefile.am index b3338bd..ea1826f 100644 --- a/bindings/rust/libgpiod/examples/Makefile.am +++ b/bindings/rust/libgpiod/examples/Makefile.am @@ -3,16 +3,17 @@ # SPDX-FileCopyrightText: 2022 Bartosz Golaszewski EXTRA_DIST = \ + buffered_event_lifetimes.rs \ + find_line_by_name.rs \ + get_chip_info.rs \ + get_line_info.rs \ get_line_value.rs \ - gpiodetect.rs \ - gpio_events.rs \ - gpiofind.rs \ - gpioget.rs \ - gpioinfo.rs \ - gpiomon.rs \ - gpionotify.rs \ - gpioset.rs \ + get_multiple_line_values.rs \ gpio_threaded_info_events.rs \ - gpiowatch.rs \ + reconfigure_input_to_output \ toggle_line_value.rs \ - watch_line_value.rs + toggle_multiple_line_values.rs \ + watch_line_info.rs \ + watch_line_rising.rs \ + watch_line_value.rs \ + watch_multiple_line_values.rs diff --git a/bindings/rust/libgpiod/examples/buffered_event_lifetimes.rs b/bindings/rust/libgpiod/examples/buffered_event_lifetimes.rs new file mode 100644 index 0000000..ad90d7b --- /dev/null +++ b/bindings/rust/libgpiod/examples/buffered_event_lifetimes.rs @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// SPDX-FileCopyrightText: 2022 Linaro Ltd. +// SPDX-FileCopyrightText: 2022 Viresh Kumar +// +// An example demonstrating that an edge event must be cloned to outlive +// subsequent writes to the containing event buffer. + +use libgpiod::line; + +fn main() -> libgpiod::Result<()> { + // Example configuration - customize to suit your situation + let chip_path = "/dev/gpiochip0"; + let line_offset = 5; + + let mut lsettings = line::Settings::new()?; + lsettings.set_edge_detection(Some(line::Edge::Both))?; + + let mut lconfig = line::Config::new()?; + lconfig.add_line_settings(&[line_offset], lsettings)?; + + let mut rconfig = libgpiod::request::Config::new()?; + rconfig.set_consumer("buffered-event-lifetimes")?; + + let chip = libgpiod::chip::Chip::open(&chip_path)?; + let request = chip.request_lines(Some(&rconfig), &lconfig)?; + + let mut buffer = libgpiod::request::Buffer::new(4)?; + + loop { + // Blocks until at least one event is available + let mut events = request.read_edge_events(&mut buffer)?; + + // This can't be used across the next read_edge_events(). + let event = events.next().unwrap()?; + + // This will out live `event` and the next read_edge_events(). + let cloned_event = libgpiod::request::Event::event_clone(event)?; + + let events = request.read_edge_events(&mut buffer)?; + for event in events { + let event = event?; + println!( + "line: {} type: {:?} event #{}", + event.line_offset(), + event.event_type(), + event.line_seqno(), + ); + } + + // `cloned_event` is still available to be used. + println!( + "line: {} type: {:?} event #{}", + cloned_event.line_offset(), + cloned_event.event_type(), + cloned_event.line_seqno(), + ); + } +} diff --git a/bindings/rust/libgpiod/examples/find_line_by_name.rs b/bindings/rust/libgpiod/examples/find_line_by_name.rs new file mode 100644 index 0000000..f7b9919 --- /dev/null +++ b/bindings/rust/libgpiod/examples/find_line_by_name.rs @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// SPDX-FileCopyrightText: 2023 Kent Gibson +// +// Minimal example of finding a line with the given name. + +fn main() -> libgpiod::Result<()> { + // Example configuration - customize to suit your situation + let line_name = "GPIO19"; + + // Names are not guaranteed unique, so this finds the first line with + // the given name. + for chip in libgpiod::gpiochip_devices(&"/dev")? { + let offset = chip.line_offset_from_name(line_name); + + if offset.is_ok() { + let info = chip.info()?; + println!( + "{}: {} {}", + line_name, + info.name()?, + offset? + ); + return Ok(()); + } + } + + println!("line '{}' not found", line_name); + Ok(()) +} diff --git a/bindings/rust/libgpiod/examples/get_chip_info.rs b/bindings/rust/libgpiod/examples/get_chip_info.rs new file mode 100644 index 0000000..cc23c86 --- /dev/null +++ b/bindings/rust/libgpiod/examples/get_chip_info.rs @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// SPDX-FileCopyrightText: 2023 Kent Gibson +// +// Minimal example of reading the info for a chip. + +use libgpiod::{self, Result}; + +fn main() -> Result<()> { + // Example configuration - customize to suit your situation + let chip_path = "/dev/gpiochip0"; + + let chip = libgpiod::chip::Chip::open(&chip_path)?; + let info = chip.info()?; + println!( + "{} [{}] ({} lines)", + info.name()?, + info.label()?, + info.num_lines(), + ); + + Ok(()) +} diff --git a/bindings/rust/libgpiod/examples/get_line_info.rs b/bindings/rust/libgpiod/examples/get_line_info.rs new file mode 100644 index 0000000..086db90 --- /dev/null +++ b/bindings/rust/libgpiod/examples/get_line_info.rs @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// SPDX-FileCopyrightText: 2023 Kent Gibson +// +// Minimal example of reading the info for a line. + +use libgpiod::line::Direction; + +fn main() -> libgpiod::Result<()> { + // Example configuration - customize to suit your situation + let chip_path = "/dev/gpiochip0"; + let line_offset = 3; + + let chip = libgpiod::chip::Chip::open(&chip_path)?; + let info = chip.line_info(line_offset)?; + + let name = info.name().unwrap_or("unnamed"); + let consumer = info.consumer().unwrap_or("unused"); + + let dir = match info.direction()? { + Direction::AsIs => "none", + Direction::Input => "input", + Direction::Output => "output", + }; + + let low = if info.is_active_low() { + "active-low" + } else { + "active-high" + }; + + println!( + "line {:>3}: {:>12} {:>12} {:>8} {:>10}", + line_offset, name, consumer, dir, low + ); + + Ok(()) +} diff --git a/bindings/rust/libgpiod/examples/get_multiple_line_values.rs b/bindings/rust/libgpiod/examples/get_multiple_line_values.rs new file mode 100644 index 0000000..a1be5a6 --- /dev/null +++ b/bindings/rust/libgpiod/examples/get_multiple_line_values.rs @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// SPDX-FileCopyrightText: 2023 Kent Gibson +// +// Minimal example of reading multiple lines. + +use libgpiod::line::{self, Direction}; + +fn main() -> libgpiod::Result<()> { + // Example configuration - customize to suit your situation + let chip_path = "/dev/gpiochip0"; + let line_offsets = [5, 3, 7]; + + let mut lsettings = line::Settings::new()?; + let mut lconfig = line::Config::new()?; + + lsettings.set_direction(Direction::Input)?; + lconfig.add_line_settings(&line_offsets, lsettings)?; + + let chip = libgpiod::chip::Chip::open(&chip_path)?; + + let mut rconfig = libgpiod::request::Config::new()?; + rconfig.set_consumer("get-multiple-line-values")?; + + let request = chip.request_lines(Some(&rconfig), &lconfig)?; + let values = request.values()?; + + println!("{:?}", values); + Ok(()) +} diff --git a/bindings/rust/libgpiod/examples/gpio_events.rs b/bindings/rust/libgpiod/examples/gpio_events.rs deleted file mode 100644 index a45b6db..0000000 --- a/bindings/rust/libgpiod/examples/gpio_events.rs +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause -// SPDX-FileCopyrightText: 2022 Linaro Ltd. -// SPDX-FileCopyrightText: 2022 Viresh Kumar -// -// Simplified Rust implementation to show handling of events, when the buffer -// is read into multiple times. Based on gpiomon example. - -use std::env; - -use libgpiod::{ - chip::Chip, - line::{self, Edge, Offset}, - request, Error, Result, -}; - -fn usage(name: &str) { - println!("Usage: {} ...", name); -} - -fn main() -> Result<()> { - let args: Vec = env::args().collect(); - if args.len() < 3 { - usage(&args[0]); - return Err(Error::InvalidArguments); - } - - let mut lsettings = line::Settings::new()?; - let mut lconfig = line::Config::new()?; - let mut offsets = Vec::::new(); - - for arg in &args[2..] { - let offset = arg.parse::().map_err(|_| Error::InvalidArguments)?; - offsets.push(offset); - } - - lsettings.set_edge_detection(Some(Edge::Both))?; - lconfig.add_line_settings(&offsets, lsettings)?; - - let path = format!("/dev/gpiochip{}", args[1]); - let chip = Chip::open(&path)?; - - let rconfig = request::Config::new()?; - - let mut buffer = request::Buffer::new(1)?; - let request = chip.request_lines(Some(&rconfig), &lconfig)?; - - loop { - match request.wait_edge_events(None) { - Err(x) => { - println!("{:?}", x); - return Err(Error::InvalidArguments); - } - - Ok(false) => { - // This shouldn't happen as the call is blocking. - panic!(); - } - Ok(true) => (), - } - - let mut events = request.read_edge_events(&mut buffer)?; - - // This can't be used across the next read_edge_events(). - let event = events.next().unwrap()?; - - // This will out live `event` and the next read_edge_events(). - let cloned_event = request::Event::event_clone(event)?; - - let events = request.read_edge_events(&mut buffer)?; - for event in events { - let event = event?; - println!( - "line: {} type: {:?}, time: {:?}", - event.line_offset(), - event.event_type(), - event.timestamp() - ); - } - - // `cloned_event` is still available to be used. - println!( - "line: {} type: {:?}, time: {:?}", - cloned_event.line_offset(), - cloned_event.event_type(), - cloned_event.timestamp() - ); - } -} diff --git a/bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs b/bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs deleted file mode 100644 index 8853a7b..0000000 --- a/bindings/rust/libgpiod/examples/gpio_threaded_info_events.rs +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause -// SPDX-FileCopyrightText: 2022 Linaro Ltd. -// SPDX-FileCopyrightText: 2022 Viresh Kumar -// -// Simplified Rust implementation to show handling of info events, that are -// generated from another thread. - -use std::{ - env, - sync::{ - mpsc::{self, Receiver, Sender}, - Arc, Mutex, - }, - thread, - time::Duration, -}; - -use libgpiod::{ - chip::Chip, - line::{self, Direction, InfoChangeKind, Offset}, - request, Error, Result, -}; - -fn usage(name: &str) { - println!("Usage: {} ", name); -} - -fn request_reconfigure_line( - chip: Arc>, - offset: Offset, - tx: Sender<()>, - rx: Receiver<()>, -) { - thread::spawn(move || { - let mut lconfig = line::Config::new().unwrap(); - let lsettings = line::Settings::new().unwrap(); - lconfig.add_line_settings(&[offset], lsettings).unwrap(); - let rconfig = request::Config::new().unwrap(); - - let mut request = chip - .lock() - .unwrap() - .request_lines(Some(&rconfig), &lconfig) - .unwrap(); - - // Signal the parent to continue - tx.send(()).expect("Could not send signal on channel"); - - // Wait for parent to signal - rx.recv().expect("Could not receive from channel"); - - let mut lconfig = line::Config::new().unwrap(); - let mut lsettings = line::Settings::new().unwrap(); - lsettings.set_direction(Direction::Output).unwrap(); - lconfig.add_line_settings(&[offset], lsettings).unwrap(); - - request.reconfigure_lines(&lconfig).unwrap(); - - // Signal the parent to continue - tx.send(()).expect("Could not send signal on channel"); - - // Wait for parent to signal - rx.recv().expect("Could not receive from channel"); - }); -} - -fn main() -> Result<()> { - let args: Vec = env::args().collect(); - if args.len() != 3 { - usage(&args[0]); - return Err(Error::InvalidArguments); - } - - let path = format!("/dev/gpiochip{}", args[1]); - let offset = args[2] - .parse::() - .map_err(|_| Error::InvalidArguments)?; - - let chip = Arc::new(Mutex::new(Chip::open(&path)?)); - chip.lock().unwrap().watch_line_info(offset)?; - - // Thread synchronizing mechanism - let (tx_main, rx_thread) = mpsc::channel(); - let (tx_thread, rx_main) = mpsc::channel(); - - // Generate events - request_reconfigure_line(chip.clone(), offset, tx_thread, rx_thread); - - // Wait for thread to signal - rx_main.recv().expect("Could not receive from channel"); - - // Line requested event - assert!(chip - .lock() - .unwrap() - .wait_info_event(Some(Duration::from_secs(1)))?); - let event = chip.lock().unwrap().read_info_event()?; - assert_eq!(event.event_type()?, InfoChangeKind::LineRequested); - - // Signal the thread to continue - tx_main.send(()).expect("Could not send signal on channel"); - - // Wait for thread to signal - rx_main.recv().expect("Could not receive from channel"); - - // Line changed event - assert!(chip - .lock() - .unwrap() - .wait_info_event(Some(Duration::from_millis(10)))?); - let event = chip.lock().unwrap().read_info_event()?; - assert_eq!(event.event_type()?, InfoChangeKind::LineConfigChanged); - - // Signal the thread to continue - tx_main.send(()).expect("Could not send signal on channel"); - - // Line released event - assert!(chip - .lock() - .unwrap() - .wait_info_event(Some(Duration::from_millis(10)))?); - let event = chip.lock().unwrap().read_info_event()?; - assert_eq!(event.event_type().unwrap(), InfoChangeKind::LineReleased); - - // No events available - assert!(!chip - .lock() - .unwrap() - .wait_info_event(Some(Duration::from_millis(100)))?); - - Ok(()) -} diff --git a/bindings/rust/libgpiod/examples/gpiodetect.rs b/bindings/rust/libgpiod/examples/gpiodetect.rs deleted file mode 100644 index 9792252..0000000 --- a/bindings/rust/libgpiod/examples/gpiodetect.rs +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause -// SPDX-FileCopyrightText: 2022 Linaro Ltd. -// SPDX-FileCopyrightText: 2022 Viresh Kumar -// -// Simplified Rust implementation of gpiodetect tool. - -use std::env; -use std::path::Path; - -use libgpiod::{self, Error, Result}; - -fn main() -> Result<()> { - let args: Vec = env::args().collect(); - if args.len() > 1 { - println!("Usage: {}", args[0]); - return Err(Error::InvalidArguments); - } - - for chip in libgpiod::gpiochip_devices(&Path::new("/dev"))? { - let info = chip.info()?; - println!( - "{} [{}] ({})", - info.name()?, - info.label()?, - info.num_lines(), - ); - } - - Ok(()) -} diff --git a/bindings/rust/libgpiod/examples/gpiofind.rs b/bindings/rust/libgpiod/examples/gpiofind.rs deleted file mode 100644 index da0530d..0000000 --- a/bindings/rust/libgpiod/examples/gpiofind.rs +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause -// SPDX-FileCopyrightText: 2022 Linaro Ltd. -// SPDX-FileCopyrightText: 2022 Viresh Kumar -// -// Simplified Rust implementation of gpiofind tool. - -use std::env; -use std::path::Path; - -use libgpiod::{self, Error, Result}; - -fn main() -> Result<()> { - let args: Vec = env::args().collect(); - if args.len() != 2 { - println!("Usage: {} ", args[0]); - return Err(Error::InvalidArguments); - } - - for chip in libgpiod::gpiochip_devices(&Path::new("/dev"))? { - let offset = chip.line_offset_from_name(&args[1]); - let info = chip.info()?; - - if offset.is_ok() { - println!( - "Line {} found: Chip: {}, offset: {}", - args[1], - info.name()?, - offset? - ); - return Ok(()); - } - } - - println!("Failed to find line: {}", args[1]); - Ok(()) -} diff --git a/bindings/rust/libgpiod/examples/gpioget.rs b/bindings/rust/libgpiod/examples/gpioget.rs deleted file mode 100644 index 8e390f3..0000000 --- a/bindings/rust/libgpiod/examples/gpioget.rs +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause -// SPDX-FileCopyrightText: 2022 Linaro Ltd. -// SPDX-FileCopyrightText: 2022 Viresh Kumar -// -// Simplified Rust implementation of gpioget tool. - -use std::env; - -use libgpiod::{ - chip::Chip, - line::{self, Direction, Offset}, - request, Error, Result, -}; - -fn main() -> Result<()> { - let args: Vec = env::args().collect(); - if args.len() < 3 { - println!("Usage: {} ...", args[0]); - return Err(Error::InvalidArguments); - } - - let mut lsettings = line::Settings::new()?; - let mut lconfig = line::Config::new()?; - let mut offsets = Vec::::new(); - - for arg in &args[2..] { - let offset = arg.parse::().map_err(|_| Error::InvalidArguments)?; - offsets.push(offset); - } - - lsettings.set_direction(Direction::Input)?; - lconfig.add_line_settings(&offsets, lsettings)?; - - let path = format!("/dev/gpiochip{}", args[1]); - let chip = Chip::open(&path)?; - - let mut rconfig = request::Config::new()?; - rconfig.set_consumer(&args[0])?; - - let request = chip.request_lines(Some(&rconfig), &lconfig)?; - let map = request.values()?; - - println!("{:?}", map); - Ok(()) -} diff --git a/bindings/rust/libgpiod/examples/gpioinfo.rs b/bindings/rust/libgpiod/examples/gpioinfo.rs deleted file mode 100644 index 1fe1ae0..0000000 --- a/bindings/rust/libgpiod/examples/gpioinfo.rs +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause -// SPDX-FileCopyrightText: 2022 Linaro Ltd. -// SPDX-FileCopyrightText: 2022 Viresh Kumar -// -// Simplified Rust implementation of gpioinfo tool. - -use std::env; -use std::path::Path; - -use libgpiod::{ - chip::Chip, - line::{Direction, Offset}, - Error, Result, -}; - -fn line_info(chip: &Chip, offset: Offset) -> Result<()> { - let info = chip.line_info(offset)?; - let off = info.offset(); - - let name = match info.name() { - Ok(name) => name, - _ => "unused", - }; - - let consumer = match info.consumer() { - Ok(name) => name, - _ => "unnamed", - }; - - let low = if info.is_active_low() { - "active-low" - } else { - "active-high" - }; - - let dir = match info.direction()? { - Direction::AsIs => "None", - Direction::Input => "Input", - Direction::Output => "Output", - }; - - println!( - "\tline {:>3}\ - \t{:>10}\ - \t{:>10}\ - \t{:>6}\ - \t{:>14}", - off, name, consumer, dir, low - ); - - Ok(()) -} - -fn chip_info(chip: &Chip) -> Result<()> { - let info = chip.info()?; - let ngpio = info.num_lines(); - - println!("GPIO Chip name: {}", info.name()?); - println!("\tlabel: {}", info.label()?); - println!("\tpath: {}", chip.path()?); - println!("\tngpio: {}\n", ngpio); - - println!("\tLine information:"); - - for offset in 0..ngpio { - line_info(chip, offset as Offset)?; - } - println!("\n"); - - Ok(()) -} - -fn main() -> Result<()> { - let args: Vec = env::args().collect(); - if args.len() > 2 { - println!("Usage: {}", args[0]); - return Err(Error::InvalidArguments); - } - - if args.len() == 1 { - for chip in libgpiod::gpiochip_devices(&Path::new("/dev"))? { - chip_info(&chip)?; - } - } else { - let index = args[1] - .parse::() - .map_err(|_| Error::InvalidArguments)?; - let path = format!("/dev/gpiochip{}", index); - if libgpiod::is_gpiochip_device(&path) { - let chip = Chip::open(&path)?; - - chip_info(&chip)?; - } - } - - Ok(()) -} diff --git a/bindings/rust/libgpiod/examples/gpiomon.rs b/bindings/rust/libgpiod/examples/gpiomon.rs deleted file mode 100644 index c3564db..0000000 --- a/bindings/rust/libgpiod/examples/gpiomon.rs +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause -// SPDX-FileCopyrightText: 2022 Linaro Ltd. -// SPDX-FileCopyrightText: 2022 Viresh Kumar -// -// Simplified Rust implementation of the gpiomon tool. - -use std::env; - -use libgpiod::{ - chip::Chip, - line::{self, Edge, EdgeKind, Offset}, - request, Error, Result, -}; - -fn usage(name: &str) { - println!("Usage: {} ...", name); -} - -fn main() -> Result<()> { - let args: Vec = env::args().collect(); - if args.len() < 3 { - usage(&args[0]); - return Err(Error::InvalidArguments); - } - - let mut lsettings = line::Settings::new()?; - let mut lconfig = line::Config::new()?; - let mut offsets = Vec::::new(); - - for arg in &args[2..] { - let offset = arg.parse::().map_err(|_| Error::InvalidArguments)?; - offsets.push(offset); - } - - lsettings.set_edge_detection(Some(Edge::Both))?; - lconfig.add_line_settings(&offsets, lsettings)?; - - let path = format!("/dev/gpiochip{}", args[1]); - let chip = Chip::open(&path)?; - - let rconfig = request::Config::new()?; - - let mut buffer = request::Buffer::new(1)?; - let request = chip.request_lines(Some(&rconfig), &lconfig)?; - - loop { - match request.wait_edge_events(None) { - Err(x) => { - println!("{:?}", x); - return Err(Error::InvalidArguments); - } - - Ok(false) => { - // This shouldn't happen as the call is blocking. - panic!(); - } - Ok(true) => (), - } - - let events = request.read_edge_events(&mut buffer)?; - for event in events { - let event = event?; - println!( - "line: {} type: {}, time: {:?}", - event.line_offset(), - match event.event_type()? { - EdgeKind::Rising => "Rising", - EdgeKind::Falling => "Falling", - }, - event.timestamp() - ); - } - } -} diff --git a/bindings/rust/libgpiod/examples/gpionotify.rs b/bindings/rust/libgpiod/examples/gpionotify.rs deleted file mode 100644 index fca1086..0000000 --- a/bindings/rust/libgpiod/examples/gpionotify.rs +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause -// SPDX-FileCopyrightText: 2023 Linaro Ltd. -// SPDX-FileCopyrightText: 2023 Bartosz Golaszewski -// -// Simplified Rust implementation of the gpionotify tool. - -use std::env; - -use libgpiod::{ - chip::Chip, - line::{Offset, InfoChangeKind}, - Error, Result, -}; - -fn usage(name: &str) { - println!("Usage: {} ...", name); -} - -fn main() -> Result<()> { - let args: Vec = env::args().collect(); - if args.len() < 3 { - usage(&args[0]); - return Err(Error::InvalidArguments); - } - - let mut offsets = Vec::::new(); - - for arg in &args[2..] { - let offset = arg.parse::().map_err(|_| Error::InvalidArguments)?; - offsets.push(offset); - } - - let path = format!("/dev/gpiochip{}", args[1]); - let chip = Chip::open(&path)?; - - for &offset in offsets.iter() { - let _info = chip.watch_line_info(offset).unwrap(); - } - - loop { - let event = chip.read_info_event().unwrap(); - println!( - "event: {}, line: {}, timestamp: {:?}", - match event.event_type()? { - InfoChangeKind::LineRequested => "Line requested", - InfoChangeKind::LineReleased => "Line released", - InfoChangeKind::LineConfigChanged => "Line config changed", - }, - event.line_info().unwrap().offset(), - event.timestamp() - ); - } -} diff --git a/bindings/rust/libgpiod/examples/gpioset.rs b/bindings/rust/libgpiod/examples/gpioset.rs deleted file mode 100644 index 607407d..0000000 --- a/bindings/rust/libgpiod/examples/gpioset.rs +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause -// SPDX-FileCopyrightText: 2022 Linaro Ltd. -// SPDX-FileCopyrightText: 2022 Viresh Kumar -// -// Simplified Rust implementation of the gpioset tool. - -use std::env; -use std::io::{stdin, Read}; - -use libgpiod::{ - chip::Chip, - line::{self, Direction, Offset, SettingVal, Value}, - request, Error, Result, -}; - -fn usage(name: &str) { - println!("Usage: {} = ...", name); -} - -fn main() -> Result<()> { - let args: Vec = env::args().collect(); - if args.len() < 3 { - usage(&args[0]); - return Err(Error::InvalidArguments); - } - - let mut lconfig = line::Config::new()?; - - for arg in &args[2..] { - let pair: Vec<&str> = arg.split('=').collect(); - if pair.len() != 2 { - usage(&args[0]); - return Err(Error::InvalidArguments); - } - - let offset = pair[0] - .parse::() - .map_err(|_| Error::InvalidArguments)?; - let value = pair[1] - .parse::() - .map_err(|_| Error::InvalidArguments)?; - - let mut lsettings = line::Settings::new()?; - lsettings.set_prop(&[ - SettingVal::Direction(Direction::Output), - SettingVal::OutputValue(Value::new(value)?), - ])?; - lconfig.add_line_settings(&[offset], lsettings)?; - } - - let path = format!("/dev/gpiochip{}", args[1]); - let chip = Chip::open(&path)?; - - let mut rconfig = request::Config::new()?; - rconfig.set_consumer(&args[0])?; - - chip.request_lines(Some(&rconfig), &lconfig)?; - - // Wait for keypress, let user verify line status. - stdin().read_exact(&mut [0u8]).unwrap(); - - Ok(()) -} diff --git a/bindings/rust/libgpiod/examples/gpiowatch.rs b/bindings/rust/libgpiod/examples/gpiowatch.rs deleted file mode 100644 index 26a2ed8..0000000 --- a/bindings/rust/libgpiod/examples/gpiowatch.rs +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause -// SPDX-FileCopyrightText: 2022 Linaro Ltd. -// SPDX-FileCopyrightText: 2022 Viresh Kumar -// -// Simplified Rust implementation of the gpiowatch tool. - -use std::env; - -use libgpiod::{chip::Chip, line::Offset, Error, Result}; - -fn usage(name: &str) { - println!("Usage: {} ...", name); -} - -fn main() -> Result<()> { - let args: Vec = env::args().collect(); - if args.len() < 2 { - usage(&args[0]); - return Err(Error::InvalidArguments); - } - - let path = format!("/dev/gpiochip{}", args[1]); - let offset = args[2] - .parse::() - .map_err(|_| Error::InvalidArguments)?; - - let chip = Chip::open(&path)?; - let _info = chip.watch_line_info(offset)?; - - match chip.wait_info_event(None) { - Err(x) => { - println!("{:?}", x); - return Err(Error::InvalidArguments); - } - - Ok(false) => { - // This shouldn't happen as the call is blocking. - panic!(); - } - Ok(true) => (), - } - - let event = chip.read_info_event()?; - println!( - "line: {} type: {:?}, time: {:?}", - offset, - event.event_type()?, - event.timestamp() - ); - - chip.unwatch(offset); - Ok(()) -} diff --git a/bindings/rust/libgpiod/examples/reconfigure_input_to_output.rs b/bindings/rust/libgpiod/examples/reconfigure_input_to_output.rs new file mode 100644 index 0000000..3e2f2c7 --- /dev/null +++ b/bindings/rust/libgpiod/examples/reconfigure_input_to_output.rs @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// SPDX-FileCopyrightText: 2023 Kent Gibson +// +// Minimal example of requesting a line intended for bi-directional use as input and then switching to output. + +use libgpiod::line; + +fn main() -> libgpiod::Result<()> { + // Example configuration - customize to suit your situation + let chip_path = "/dev/gpiochip0"; + let line_offset = 5; + + let mut lsettings = line::Settings::new()?; + lsettings.set_direction(line::Direction::Input)?; + + let mut lconfig = line::Config::new()?; + lconfig.add_line_settings(&[line_offset], lsettings)?; + + let mut rconfig = libgpiod::request::Config::new()?; + rconfig.set_consumer("reconfigure-input-to-output")?; + + let chip = libgpiod::chip::Chip::open(&chip_path)?; + // request the line initially as an input + let mut request = chip.request_lines(Some(&rconfig), &lconfig)?; + + // read the current line value + let value = request.value(line_offset)?; + println!("{}={:?} (input)", line_offset, value); + + // switch the line to an output and drive it low + let mut lsettings = line::Settings::new()?; + lsettings.set_direction(line::Direction::Output)?; + lsettings.set_output_value(line::Value::InActive)?; + lconfig.add_line_settings(&[line_offset], lsettings)?; + request.reconfigure_lines(&lconfig)?; + + // report the current driven value + let value = request.value(line_offset)?; + println!("{}={:?} (output)", line_offset, value); + + Ok(()) +} diff --git a/bindings/rust/libgpiod/examples/toggle_multiple_line_values.rs b/bindings/rust/libgpiod/examples/toggle_multiple_line_values.rs new file mode 100644 index 0000000..b7e6915 --- /dev/null +++ b/bindings/rust/libgpiod/examples/toggle_multiple_line_values.rs @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// SPDX-FileCopyrightText: 2023 Kent Gibson +// +// Minimal example of toggling multiple lines. + +use core::time::Duration; +use libgpiod::line::{self, Offset, Value}; + +fn toggle_value(value: Value) -> Value { + match value { + Value::Active => Value::InActive, + Value::InActive => Value::Active, + } +} + +fn toggle_values(values: &mut [Value]) { + for i in values.iter_mut() { + *i = toggle_value(*i); + } +} + +fn print_values(offsets: &[Offset], values: &[Value]) { + for i in 0..offsets.len() { + print!("{}={:?} ", offsets[i], values[i]); + } + println!(); +} + +fn main() -> libgpiod::Result<()> { + // Example configuration - customize to suit your situation + let chip_path = "/dev/gpiochip0"; + let line_offsets = [5, 3, 7]; + let mut values = vec![Value::Active, Value::Active, Value::InActive]; + + let mut lsettings = line::Settings::new()?; + lsettings.set_direction(line::Direction::Output)?; + + let mut lconfig = line::Config::new()?; + lconfig + .add_line_settings(&line_offsets, lsettings)? + .set_output_values(&values)?; + + let mut rconfig = libgpiod::request::Config::new()?; + rconfig.set_consumer("toggle-multiple-line-values")?; + + let chip = libgpiod::chip::Chip::open(&chip_path)?; + let mut req = chip.request_lines(Some(&rconfig), &lconfig)?; + + loop { + print_values(&line_offsets, &values); + std::thread::sleep(Duration::from_secs(1)); + toggle_values(&mut values); + req.set_values(&values)?; + } +} diff --git a/bindings/rust/libgpiod/examples/watch_line_info.rs b/bindings/rust/libgpiod/examples/watch_line_info.rs new file mode 100644 index 0000000..e84ce13 --- /dev/null +++ b/bindings/rust/libgpiod/examples/watch_line_info.rs @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// SPDX-FileCopyrightText: 2023 Kent Gibson +// +// Minimal example of watching for info changes on particular lines. + +use libgpiod::line::InfoChangeKind; + +fn main() -> libgpiod::Result<()> { + // Example configuration - customize to suit your situation + let chip_path = "/dev/gpiochip0"; + let line_offsets = [5, 3, 7]; + + let chip = libgpiod::chip::Chip::open(&chip_path)?; + for offset in line_offsets { + let _info = chip.watch_line_info(offset)?; + } + + loop { + // Blocks until at least one event is available. + let event = chip.read_info_event()?; + println!( + "line: {} {:<9} {:?}", + event.line_info()?.offset(), + match event.event_type()? { + InfoChangeKind::LineRequested => "Requested", + InfoChangeKind::LineReleased => "Released", + InfoChangeKind::LineConfigChanged => "Reconfig", + }, + event.timestamp() + ); + } +} diff --git a/bindings/rust/libgpiod/examples/watch_line_rising.rs b/bindings/rust/libgpiod/examples/watch_line_rising.rs new file mode 100644 index 0000000..81a2407 --- /dev/null +++ b/bindings/rust/libgpiod/examples/watch_line_rising.rs @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// SPDX-FileCopyrightText: 2023 Kent Gibson +// +// Minimal example of watching for edges on a single line. + +use libgpiod::line; + +fn main() -> libgpiod::Result<()> { + // Example configuration - customize to suit your situation + let chip_path = "/dev/gpiochip0"; + let line_offset = 5; + + let mut lsettings = line::Settings::new()?; + lsettings.set_edge_detection(Some(line::Edge::Rising))?; + + let mut lconfig = line::Config::new()?; + lconfig.add_line_settings(&[line_offset], lsettings)?; + + let mut rconfig = libgpiod::request::Config::new()?; + rconfig.set_consumer("watch-line-value")?; + + let chip = libgpiod::chip::Chip::open(&chip_path)?; + let request = chip.request_lines(Some(&rconfig), &lconfig)?; + + // A larger buffer is an optimisation for reading bursts of events from the + // kernel, but that is not necessary in this case, so 1 is fine. + let mut buffer = libgpiod::request::Buffer::new(1)?; + loop { + // blocks until at least one event is available + let events = request.read_edge_events(&mut buffer)?; + for event in events { + let event = event?; + println!( + "line: {} type: {:<7} event #{}", + event.line_offset(), + match event.event_type()? { + line::EdgeKind::Rising => "Rising", + line::EdgeKind::Falling => "Falling", + }, + event.line_seqno() + ); + } + } +} diff --git a/bindings/rust/libgpiod/examples/watch_multiple_line_values.rs b/bindings/rust/libgpiod/examples/watch_multiple_line_values.rs new file mode 100644 index 0000000..3fc88ba --- /dev/null +++ b/bindings/rust/libgpiod/examples/watch_multiple_line_values.rs @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// SPDX-FileCopyrightText: 2023 Kent Gibson +// +// Minimal example of watching for edges on multiple lines. + +use libgpiod::{ + line::{self, EdgeKind}, + request, +}; + +fn main() -> libgpiod::Result<()> { + // Example configuration - customize to suit your situation + let chip_path = "/dev/gpiochip0"; + let line_offsets = [5, 3, 7]; + + let mut lsettings = line::Settings::new()?; + lsettings.set_edge_detection(Some(line::Edge::Both))?; + + let mut lconfig = line::Config::new()?; + lconfig.add_line_settings(&line_offsets, lsettings)?; + + let mut rconfig = request::Config::new()?; + rconfig.set_consumer("watch-multiple-line-values")?; + + let chip = libgpiod::chip::Chip::open(&chip_path)?; + let request = chip.request_lines(Some(&rconfig), &lconfig)?; + + let mut buffer = request::Buffer::new(4)?; + loop { + // Blocks until at least one event is available. + let events = request.read_edge_events(&mut buffer)?; + for event in events { + let event = event?; + println!( + "offset: {} type: {:<7} event #{} line event #{}", + event.line_offset(), + match event.event_type()? { + EdgeKind::Rising => "Rising", + EdgeKind::Falling => "Falling", + }, + event.global_seqno(), + event.line_seqno(), + ); + } + } +}