This repository has been archived on 2018-05-28. You can view files and clone it, but cannot push or open issues or pull requests.
BBB-Simple-ACS/client/lib/gpio.cpp

188 lines
4.4 KiB
C++

/*
* 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 <fstream>
#include <string>
#include <iostream>
#include <unistd.h>
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();
}