#include "mainclass.hh" #include #include #include #include #include #include #include int MainClass::current_device_ = -1; MainClass::MainClass(int argc, char* argv[]) : argc_(argc) , argv_(argv) { } int MainClass::usage() { std::cerr << "Usage: " << basename(argv_[0]) << std::endl << " [--device DEVICE|--device=DEVICE|-e DEVICE]" << std::endl << " [--up OUTPUT|--up=OUTPUT|-u OUTPUT]" << std::endl << " [--down OUTPUT|--down=OUTPUT|-d OUTPUT]" << std::endl << " [--read INPUT|--read=INPUT|-r INPUT]" << std::endl << " [--sleep MS|--sleep=MS|-s MS]" << std::endl << " [--help|-h]" << std::endl << " [--version|-v]" << std::endl; std::cerr << std::endl << "Controls the output pins and read pins of a PiFace digital IO." << std::endl << std::endl; std::cerr << "--device \tSwitch to the provided device." << std::endl << "--up \t\tEnable the provided ouput pin." << std::endl << "--down \t\tDisable the provided output pin." << std::endl << "--read \t\tRead and print the provided input pin." << std::endl << "--sleep \tSleep for the provided amount of milliseconds." << std::endl << "--help \t\tDisplay this message." << std::endl << "--version \tDisplay version." << std::endl << std::endl; std::cerr << "OUTPUT \t: The output pin to enable/disable. 0 <= OUTPUT <= 7." << std::endl << "INPUT \t: The input pin to read. 0 <= INPUT <= 7." << std::endl << "MS \t: The number of milliseconds to sleep. 0 <= MS <= " << UINT_MAX << "." << std::endl << "DEVICE \t: The device number. Default is 0. " "0 <= DEVICE <= 4." << std::endl; return EX_USAGE; } bool MainClass::bad_value_() { extern int optind; extern char* optarg; std::cerr << "Bad value " << optarg << " for option " << argv_[optind - 2] << std::endl << std::endl; return false; } bool MainClass::build_actions_() { option opts[] = { {"device", 1, 0, 'e'}, {"up", 1, 0, 'u'}, {"down", 1, 0, 'd'}, {"read", 1, 0, 'r'}, {"sleep", 1, 0, 's'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'v'}, {0, 0, 0, 0} }; int opt; extern int optind; extern char* optarg; char* endptr; while ((opt = getopt_long(argc_, argv_, "e:u:d:r:s:hv", opts, 0)) != -1) { long int arg = optarg ? strtol(optarg, &endptr, 10) : 0; if (arg < 0) return bad_value_(); if (opt == 'e') { if (arg > 4) return bad_value_(); actions_.push_back([arg]() -> bool { pifacedigital_close(get_current_device()); return set_current_device(arg); }); } else if (opt == 'u' || opt == 'd') { if (arg > 7) return bad_value_(); actions_.push_back([arg, opt]() -> bool { if (get_current_device() == -1 && !set_current_device(0)) return false; std::cout << "Setting pin " << arg << " " << (opt == 'u' ? "up" : "down") << std::endl; pifacedigital_write_bit(opt == 'u', arg, OUTPUT, get_current_device()); return true; }); } else if (opt == 'r') { if (arg > 7) return bad_value_(); actions_.push_back([arg, opt]() -> bool { if (get_current_device() == -1 && !set_current_device(0)) return false; uint8_t status = pifacedigital_read_bit(arg, INPUT, get_current_device()); std::cout << "Pin " << arg << " value: " << (int) status << std::endl; return true; }); } else if (opt == 's') { if (arg > INT_MAX) return bad_value_(); actions_.push_back([arg]() -> bool { std::cout << "Sleeping " << (arg * 1000) << " ms" << std::endl; usleep(arg * 1000); return true; }); } else if (opt == 'v') { std::cout << "camotion-piface 1.1" << std::endl; actions_.clear(); return true; } else if (opt == 'h') { usage(); actions_.clear(); return true; } else return false; } return optind == argc_; } int MainClass::execute() { if (argc_ == 1 || !build_actions_()) return usage(); for (auto f : actions_) if (!f()) return 1; return 0; } int MainClass::get_current_device() { return current_device_; } bool MainClass::set_current_device(int c) { std::cout << "Switching to device " << c << std::endl; if (pifacedigital_open((current_device_ = c)) == -1) { std::cerr << std::endl; return false; } return true; }