summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Shen <shawnshen@google.com>2015-10-27 18:36:40 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-10-27 18:36:40 +0000
commitbc48472c82d67aaba0e19c7a0a1fab8d8fbafd34 (patch)
tree84f73a259732cb41e95eef983892aec2cc430a90
parent4a81a9c30bdb731383c5b0e37b097c7a3ca1902b (diff)
parent66566d404e7dc463b3b7b117a034f1206367e038 (diff)
downloadcommon-bc48472c82d67aaba0e19c7a0a1fab8d8fbafd34.tar.gz
Merge "Brillo GPIO sample: write to output pin and read input pin Usage: gpio_playground --gin=28 --gout=24 --goffset=902" into mnc-brillo-dev
-rw-r--r--brillo_gpios/AndroidProducts.mk16
-rw-r--r--brillo_gpios/README43
-rw-r--r--brillo_gpios/brillo_gpios.mk22
-rw-r--r--brillo_gpios/src/gpio_playground/Android.mk24
-rw-r--r--brillo_gpios/src/gpio_playground/gpio_playground.cpp210
-rw-r--r--brillo_gpios/vendorsetup.sh1
6 files changed, 316 insertions, 0 deletions
diff --git a/brillo_gpios/AndroidProducts.mk b/brillo_gpios/AndroidProducts.mk
new file mode 100644
index 0000000..e31e144
--- /dev/null
+++ b/brillo_gpios/AndroidProducts.mk
@@ -0,0 +1,16 @@
+#
+# Copyright 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+PRODUCT_MAKEFILES := $(LOCAL_DIR)/brillo_gpios.mk
diff --git a/brillo_gpios/README b/brillo_gpios/README
new file mode 100644
index 0000000..be80916
--- /dev/null
+++ b/brillo_gpios/README
@@ -0,0 +1,43 @@
+README for Brillo GPIO sample
+
+This GPIO sample demonstrates how to set up GPIO and write/read to GPIO pins.
+Specifically this app does the following.
+
+ - Export an input and output GPIO pins
+ - Set output e.g. pin 24 direction to "out" and value to 1
+ - Set input e.g. pin 28 direction to "in" and edge to "both"
+ - Read input pin by polling
+ - Once input pin is triggered to input value 1, set output value to 0
+
+Once built, you can find the binary inside your tree at:
+
+out/target/product/dragonboard/symbols/system/bin/gpio_playground
+
+Do the following to deploy the sample:
+ - adb root
+ - adb remount
+ - adb sync
+
+Hardware setup:
+ - You need to connect a GPIO pin as output to an LED
+ - You need to connect a GPIO pin as input to a push button switch
+
+Do the following to run the sample on Dragonboard and check logs for info:
+ - Open a shell window and run: adb logcat
+ - Open another shell window and run:
+ - Default input pin 28 and output pin 24
+ - adb shell '/system/bin/gpio_playground &'
+ - Choose your own output and input pins
+ - adb shell '/system/bin/gpio_playground --gin=<input> --gout=<output> &'
+ - For example, adb shell '/system/bin/gpio_playground --gin=28 --gout=24 &'
+ - Observe the logging info from the first window
+ - Observe that the LED of pin 24 is turned on
+ - Now push the switch of pin 28 and see that the LED gets turned off
+
+Notes:
+ - There is a GPIO port offset defined by const kDefaultGpioOffset that depends
+ on what kind of boards you use. For Dragonboard it is 902. This offset can
+ also be configured by a commandline parameter.
+ - There is an output pin and input pin defined by const kDefaultGpioOut and
+ kDefaultGpioIn respectively. They can both be configured by commandline
+ parameters.
diff --git a/brillo_gpios/brillo_gpios.mk b/brillo_gpios/brillo_gpios.mk
new file mode 100644
index 0000000..2c92214
--- /dev/null
+++ b/brillo_gpios/brillo_gpios.mk
@@ -0,0 +1,22 @@
+#
+# Copyright 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+$(call inherit-product, device/generic/brillo/brillo_base.mk)
+
+PRODUCT_NAME := brillo_gpios
+PRODUCT_BRAND := Brillo
+
+PRODUCT_DEVICE := dragonboard
+PRODUCT_PACKAGES += gpio_playground
diff --git a/brillo_gpios/src/gpio_playground/Android.mk b/brillo_gpios/src/gpio_playground/Android.mk
new file mode 100644
index 0000000..275151f
--- /dev/null
+++ b/brillo_gpios/src/gpio_playground/Android.mk
@@ -0,0 +1,24 @@
+#
+# Copyright 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := gpio_playground
+LOCAL_SRC_FILES := gpio_playground.cpp
+LOCAL_SHARED_LIBRARIES := libchrome libchromeos libchromeos-stream
+LOCAL_C_INCLUDES := external/gtest/include
+LOCAL_CFLAGS := -Wall -Werror
+include $(BUILD_EXECUTABLE)
diff --git a/brillo_gpios/src/gpio_playground/gpio_playground.cpp b/brillo_gpios/src/gpio_playground/gpio_playground.cpp
new file mode 100644
index 0000000..64e3d0e
--- /dev/null
+++ b/brillo_gpios/src/gpio_playground/gpio_playground.cpp
@@ -0,0 +1,210 @@
+/* Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <sys/poll.h>
+#include <sys/signalfd.h>
+#include <sys/timerfd.h>
+
+#include <base/files/file_path.h>
+#include <base/format_macros.h>
+#include <base/logging.h>
+#include <base/strings/stringprintf.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/string_util.h>
+
+#include <brillo/flag_helper.h>
+#include <brillo/streams/file_stream.h>
+#include <brillo/streams/stream_utils.h>
+
+// Define defaults that work on the Dragonboard 410c.
+const int kDefaultGpioPortOffset = 902;
+const int kDefaultGpioOut = 24;
+const int kDefaultGpioIn = 28;
+
+// GPIO sysfs path
+const char* const kGPIOSysfsPath = "/sys/class/gpio";
+// GPIO polling timeout in milliseconds
+const int kPollTimeoutMsecs = 3000; /* 3 seconds */
+const int kBufSize = 10;
+
+namespace {
+
+/*
+ * Get a file stream for GPIO export
+ * bool write: access mode with true for write
+ * return: file stream pointer
+ */
+brillo::StreamPtr GetGPIOExportStream(bool write) {
+ std::string gpio_path;
+ gpio_path = base::StringPrintf("%s/export", kGPIOSysfsPath);
+ base::FilePath dev_path{gpio_path};
+ auto access_mode = brillo::stream_utils::MakeAccessMode(!write, write);
+ return brillo::FileStream::Open(
+ dev_path, access_mode, brillo::FileStream::Disposition::OPEN_EXISTING,
+ nullptr);
+}
+
+/*
+ * Get a file stream for GPIO data
+ * int gpio: GPIO pin number
+ * std::string type: GPIO type e.g. direction, edge, value
+ * bool write: access mode with true for write
+ * return: file stream pointer
+ */
+brillo::StreamPtr GetGPIODataStream(int gpio, const std::string type, bool write) {
+ std::string gpio_path;
+ gpio_path = base::StringPrintf("%s/gpio%d/%s", kGPIOSysfsPath, gpio, type.c_str());
+ base::FilePath dev_path{gpio_path};
+ auto access_mode = brillo::stream_utils::MakeAccessMode(!write, write);
+ return brillo::FileStream::Open(
+ dev_path, access_mode, brillo::FileStream::Disposition::OPEN_EXISTING,
+ nullptr);
+}
+
+} // anonymous namespace
+
+/*
+ * Export GPIO to user space
+ * int gpio: GPIO pin number
+ */
+void export_gpio(int gpio) {
+
+ brillo::StreamPtr stream = GetGPIOExportStream(true);
+ if (!stream)
+ return;
+
+ std::string value = base::StringPrintf("%d", gpio);
+ stream->WriteAllBlocking(value.data(), value.size(), nullptr);
+}
+
+/*
+ * Write to GPIO
+ * std::string type: what GPIO type i.e. direction, value, edge
+ * std::string v: value to be written
+ * return: true
+ */
+bool write_gpio(int gpio, const std::string type, std::string v) {
+
+ brillo::StreamPtr stream = GetGPIODataStream(gpio, type, true);
+ if (!stream)
+ return false;
+
+ stream->WriteAllBlocking(v.data(), v.size(), nullptr);
+ return true;
+}
+
+/*
+ * This method polls GPIO pin for 0 -> 1 transition.
+ * int gpio: GPIO pin to be polled.
+ * return:
+ * true if polling reads back successfully
+ * false if GPIO open error or polling error
+ */
+bool poll_gpio(int gpio) {
+ char buf[kBufSize];
+ struct pollfd fdset[1];
+ int nfds = 1;
+ int fd = -1;
+ int rc = -1;
+ int len = -1;
+
+ std::string gpio_path;
+ gpio_path = base::StringPrintf("%s/gpio%d/value", kGPIOSysfsPath, gpio);
+ fd = open(gpio_path.c_str(), O_RDONLY | O_NONBLOCK );
+ if (fd < 0) {
+ PLOG(ERROR) << "GPIO open error";
+ return false;
+ }
+
+ // Use this sawZeroValue to ignore the first spurious interrupt.
+ bool sawZeroValue = false;
+
+ while(1) {
+ memset((void*)fdset, 0, sizeof(fdset));
+ fdset[0].fd = fd;
+ fdset[0].events = POLLPRI;
+
+ rc = poll(fdset, nfds, kPollTimeoutMsecs);
+ if (rc < 0) {
+ PLOG(ERROR) << "poll() failed!";
+ close(fd);
+ return false;
+ } else if (rc == 0) {
+ LOG(INFO) << "polling...";
+ } else if (fdset[0].revents & POLLPRI) {
+ len = read(fdset[0].fd, buf, kBufSize - 1);
+ lseek(fdset[0].fd, 0, SEEK_SET);
+ if (len >= 0) {
+ buf[len] = '\0';
+ }
+ if (buf[0] == '0') {
+ LOG(INFO) << "First interrupt with value 0 ignored.";
+ sawZeroValue = true;
+ continue;
+ }
+ if (sawZeroValue && buf[0] == '1') {
+ LOG(INFO) << "GPIO pin reset and interrupt with value 1 caught.";
+ close(fd);
+ return true;
+ }
+ }
+ }
+ close(fd);
+ return true;
+}
+
+int main(int argc, char **argv) {
+ int gpio_out = -1;
+ int gpio_in = -1;
+ int goffset = kDefaultGpioPortOffset;
+
+ DEFINE_int32(gin, 28, "GPIO input");
+ DEFINE_int32(gout, 24, "GPIO output");
+ DEFINE_int32(goffset, 902, "GPIO port offset for Dragonboard");
+ brillo::FlagHelper::Init(argc, argv, "GPIO Playground.");
+
+ if (argc == 1 || argc == 3 || argc == 4) {
+ if (FLAGS_goffset) {
+ goffset = FLAGS_goffset;
+ }
+ gpio_out = FLAGS_gout + goffset;
+ gpio_in = FLAGS_gin + goffset;
+ } else {
+ printf("Pass input & output GPIO pin as follows\n");
+ printf("adb shell '/system/bin/gpio_playground --gin=28 --gout=24 --goffset=902 &'\n");
+ return -1;
+ }
+
+ LOG(INFO) << "Export pin " << kDefaultGpioOut << " to userspace";
+ export_gpio(gpio_out);
+ LOG(INFO) << "Set pin " << kDefaultGpioOut << " direction to out";
+ write_gpio(gpio_out, "direction", "out");
+ LOG(INFO) << "Set pin " << kDefaultGpioOut << " value to 1";
+ write_gpio(gpio_out, "value", "1");
+
+ LOG(INFO) << "Export pin " << kDefaultGpioIn << " to userspace";
+ export_gpio(gpio_in);
+ LOG(INFO) << "Set pin " << kDefaultGpioIn << " direction to in";
+ write_gpio(gpio_in, "direction", "in");
+ LOG(INFO) << "Set pin " << kDefaultGpioIn << " edge to both";
+ write_gpio(gpio_in, "edge", "both");
+
+ if (poll_gpio(gpio_in)) {
+ LOG(INFO) << "Pin " << kDefaultGpioIn << " pushed. Now turn off LED";
+ write_gpio(gpio_out, "value", "0");
+ }
+ return 0;
+}
diff --git a/brillo_gpios/vendorsetup.sh b/brillo_gpios/vendorsetup.sh
new file mode 100644
index 0000000..cdec5ff
--- /dev/null
+++ b/brillo_gpios/vendorsetup.sh
@@ -0,0 +1 @@
+add_lunch_combo brillo_gpios-userdebug