188 lines
4.4 KiB
C++
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();
|
|
}
|