#include "gpio.hpp" #include #include #include #include using namespace std; static string construct_filename(const string &prefix, int pin, const string &suffix) { stringstream filename; filename << prefix << pin << suffix; return filename.str(); } gpio::gpio(int pin, pin_direction direction, pin_type type, bool default_state) : pin(pin), direction(direction), type(type), current_state(false) { ofstream export_file("/sys/class/gpio/export"); export_file << pin; export_file.close(); ofstream direction_file(construct_filename("/sys/class/gpio/gpio", pin, "/direction").c_str()); if (direction == pin_direction::INPUT) { direction_file << "in"; } else { direction_file << "out"; } direction_file.close(); if (direction == pin_direction::OUTPUT) { set_value(default_state, false); } } gpio::gpio(gpio&& old) : pin(old.pin), direction(old.direction), type(old.type), current_state(old.current_state) { old.pin = -1; } gpio::~gpio() { if (pin != -1) { ofstream unexport_file("/sys/class/gpio/unexport"); unexport_file << pin; } } void gpio::set_value(bool on, bool use_cache) { if (pin == -1) throw logic_error("Usage of moved gpio"); if (direction == pin_direction::INPUT) { stringstream errormsg; errormsg << "Cannot write to input pin " << pin; throw logic_error(errormsg.str()); } if (!use_cache || current_state != on) { bool value; if (type == pin_type::HIGH_ON) value = on; else value = !on; ofstream value_file(construct_filename("/sys/class/gpio/gpio", pin, "/value")); value_file << value; } current_state = on; } void gpio::set_value(bool on) { set_value(on, true); } bool gpio::get_value() { if (pin == -1) throw logic_error("Usage of moved gpio"); if (direction == pin_direction::OUTPUT) return current_state; ifstream value_file(construct_filename("/sys/class/gpio/gpio", pin, "/value")); bool value; value_file >> value; bool on; if (type == pin_type::HIGH_ON) on = value; else on = !value; return on; } int gpio::get_pin() const { return pin; }