summaryrefslogtreecommitdiffstats
path: root/gpio-util/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gpio-util/main.cpp')
-rw-r--r--gpio-util/main.cpp180
1 files changed, 180 insertions, 0 deletions
diff --git a/gpio-util/main.cpp b/gpio-util/main.cpp
index b8801aa..fb56e66 100644
--- a/gpio-util/main.cpp
+++ b/gpio-util/main.cpp
@@ -14,7 +14,187 @@
* limitations under the License.
*/
+/**
+ * This program is a utility for accessing GPIOs.
+ * Actions:
+ * low: Set a GPIO low
+ * high: Set a GPIO high
+ * low_high: Set a GPIO low, delay if requested, set it high
+ * high_low: Set a GPIO high, delay if requested, set it low
+ */
+
+#include <algorithm>
+#include <chrono>
+#include <iostream>
+#include <map>
+#include <thread>
+#include <phosphor-logging/log.hpp>
+#include "argument.hpp"
+#include "gpio.hpp"
+
+using namespace phosphor::gpio;
+using namespace phosphor::logging;
+
+typedef void (*gpioFunction)(GPIO&, unsigned int);
+using gpioFunctionMap = std::map<std::string, gpioFunction>;
+
+/**
+ * Sets a GPIO low
+ *
+ * @param[in] gpio - the GPIO object
+ * @param[in] delayInMS - Unused in this function
+ */
+void low(GPIO& gpio, unsigned int delayInMS)
+{
+ gpio.set(GPIO::Value::low);
+}
+
+
+/**
+ * Sets a GPIO high
+ *
+ * @param[in] gpio - the GPIO object
+ * @param[in] delayInMS - Unused in this function
+ */
+void high(GPIO& gpio, unsigned int delayInMS)
+{
+ gpio.set(GPIO::Value::high);
+}
+
+
+/**
+ * Sets a GPIO high, then delays, then sets it low
+ *
+ * @param[in] gpio - the GPIO object
+ * @param[in] delayInMS - The delay in between the sets
+ */
+void highLow(GPIO& gpio, unsigned int delayInMS)
+{
+ gpio.set(GPIO::Value::high);
+
+ std::chrono::milliseconds delay{delayInMS};
+ std::this_thread::sleep_for(delay);
+
+ gpio.set(GPIO::Value::low);
+}
+
+
+/**
+ * Sets a GPIO low, then delays, then sets it high
+ *
+ * @param[in] gpio - the GPIO to write
+ * @param[in] delayInMS - The delay in between the sets
+ */
+void lowHigh(GPIO& gpio, unsigned int delayInMS)
+{
+ gpio.set(GPIO::Value::low);
+
+ std::chrono::milliseconds delay{delayInMS};
+ std::this_thread::sleep_for(delay);
+
+ gpio.set(GPIO::Value::high);
+}
+
+
+/**
+ * The actions supported by this program
+ */
+static const gpioFunctionMap functions
+{
+ {"low", low},
+ {"high", high},
+ {"low_high", lowHigh},
+ {"high_low", highLow}
+};
+
+
+/**
+ * Prints usage and exits the program
+ *
+ * @param[in] err - the error message to print
+ * @param[in] argv - argv from main()
+ */
+void exitWithError(const char* err, char** argv)
+{
+ std::cerr << "ERROR: " << err << "\n";
+ ArgumentParser::usage(argv);
+ exit(EXIT_FAILURE);
+}
+
+
+/**
+ * Returns the number value of the argument passed in.
+ *
+ * @param[in] name - the argument name
+ * @param[in] parser - the argument parser
+ * @param[in] argv - arv from main()
+ */
+template<typename T>
+T getValueFromArg(const char* name,
+ ArgumentParser& parser,
+ char** argv)
+{
+ char* p = NULL;
+ auto val = strtol(parser[name].c_str(), &p, 10);
+
+ //strol sets p on error, also we don't allow negative values
+ if (*p || (val < 0))
+ {
+ using namespace std::string_literals;
+ std::string msg = "Invalid "s + name + " value passed in";
+ exitWithError(msg.c_str(), argv);
+ }
+ return static_cast<T>(val);
+}
+
+
int main(int argc, char** argv)
{
+ ArgumentParser args(argc, argv);
+
+ auto path = args["path"];
+ if (path == ArgumentParser::emptyString)
+ {
+ exitWithError("GPIO device path not specified", argv);
+ }
+
+ auto action = args["action"];
+ if (action == ArgumentParser::emptyString)
+ {
+ exitWithError("Action not specified", argv);
+ }
+
+ if (args["gpio"] == ArgumentParser::emptyString)
+ {
+ exitWithError("GPIO not specified", argv);
+ }
+
+ auto gpioNum = getValueFromArg<gpioNum_t>("gpio", args, argv);
+
+ //Not all actions require a delay, so not required
+ unsigned int delay = 0;
+ if (args["delay"] != ArgumentParser::emptyString)
+ {
+ delay = getValueFromArg<decltype(delay)>("delay", args, argv);
+ }
+
+ auto function = functions.find(action);
+ if (function == functions.end())
+ {
+ exitWithError("Invalid action value passed in", argv);
+ }
+
+ GPIO gpio{path, gpioNum, GPIO::Direction::output};
+
+ try
+ {
+ function->second(gpio, delay);
+ }
+ catch (std::runtime_error& e)
+ {
+ std::cerr << e.what();
+ return -1;
+ }
+
return 0;
}
OpenPOWER on IntegriCloud