/* * GPIO.cpp Created on: 29 Apr 2014 * Copyright (c) 2014 Derek Molloy (www.derekmolloy.ie) * Made available for the book "Exploring BeagleBone" * If you use this code in your work please cite: * Derek Molloy, "Exploring BeagleBone: Tools and Techniques for Building * with Embedded Linux", Wiley, 2014, ISBN:9781118935125. * See: www.exploringbeaglebone.com * Licensed under the EUPL V.1.1 * * This Software is provided to You under the terms of the European * Union Public License (the "EUPL") version 1.1 as published by the * European Union. Any use of this Software, other than as authorized * under this License is strictly prohibited (to the extent such use * is covered by a right of the copyright holder of this Software). * * This Software is provided under the License on an "AS IS" basis and * without warranties of any kind concerning the Software, including * without limitation merchantability, fitness for a particular purpose, * absence of defects or errors, accuracy, and non-infringement of * intellectual property rights other than copyright. This disclaimer * of warranty is an essential part of the License and a condition for * the grant of any rights to this Software. * * For more details, see http://www.derekmolloy.ie/ */ #include "gpio.hpp" #include #include #include #include int gpio::write(const std::string& path, const std::string& filename, const std::string& value) { std::ofstream fs; fs.open(path + filename); if (!fs.is_open()) { std::cerr << "GPIO: write failed to open file." << std::endl; return -1; } fs << value; fs.close(); return 0; } std::string gpio::read(const std::string& path, const std::string& filename) { std::ifstream fs; fs.open(path + filename); if (!fs.is_open()) { std::cerr << "GPIO: read failed to open file " << std::endl; return { }; } std::string input; getline(fs, input); fs.close(); return input; } int gpio::write(const std::string& path, const std::string& filename, int value) { return write(path, filename, std::to_string(value)); } gpio::gpio(int number) : number_(number) { name_ = std::string("gpio") + std::to_string(number); path_ = std::string(base_path) + this->name_ + "/"; this->export_gpio(); // Need to give Linux time to set up the sysfs structure usleep(300'000); } int gpio::export_gpio() { return write(base_path, "export", number_); } int gpio::unexport_gpio() { return write(base_path, "unexport", number_); } int gpio::set_direction(direction dir) { switch (dir) { case input: return write(path_, "direction", "in"); case output: return write(path_, "direction", "out"); } return -1; } int gpio::set_value(value value) { switch (value) { case high: return write(path_, "value", "1"); case low: return write(path_, "value", "0"); } return -1; } int gpio::set_edge_type(edge value) { switch (value) { case none: return write(path_, "edge", "none"); case rising: return write(path_, "edge", "rising"); case falling: return write(path_, "edge", "falling"); case both: return write(path_, "edge", "both"); } return -1; } int gpio::set_active_low(bool is_low) { if (is_low) return write(path_, "active_low", "1"); return write(path_, "active_low", "0"); } int gpio::set_active_high() { return this->set_active_low(false); } gpio::value gpio::get_value() const { auto input = read(path_, "value"); if (input == "0") return low; return high; } gpio::direction gpio::get_direction() const { auto direction = read(path_, "direction"); if (direction == "in") return input; return output; } gpio::edge gpio::get_edge_type() const { auto edge = read(path_, "edge"); if (edge == "rising") return rising; if (edge == "falling") return falling; if (edge == "both") return both; return none; } int gpio::stream_open() { stream_.open(path_ + "value"); return 0; } int gpio::stream_write(value value) { stream_ << value << std::flush; return 0; } int gpio::stream_close() { stream_.close(); return 0; } int gpio::toggle_output() { set_direction(output); if (get_value()) set_value(low); else set_value(high); return 0; } gpio::~gpio() { this->unexport_gpio(); }