Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

mainclass.cpp 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "mainclass.hh"
  2. #include <iostream>
  3. #include <libgen.h>
  4. #include <sysexits.h>
  5. #include <climits>
  6. #include <getopt.h>
  7. #include <unistd.h>
  8. #include <pifacedigital.h>
  9. int MainClass::current_device_ = -1;
  10. uint8_t MainClass::pins_ = 0;
  11. MainClass::MainClass(int argc, char* argv[])
  12. : argc_(argc)
  13. , argv_(argv)
  14. {
  15. }
  16. int MainClass::usage()
  17. {
  18. std::cerr << "Usage: " << basename(argv_[0]) << std::endl <<
  19. " [--device DEVICE|--device=DEVICE|-e DEVICE]" << std::endl <<
  20. " [--up OUTPUT|--up=OUTPUT|-u OUTPUT]" << std::endl <<
  21. " [--down OUTPUT|--down=OUPUT|-d OUTPUT]" << std::endl <<
  22. " [--sleep MS|--sleep=MS|-s MS]" << std::endl <<
  23. " [--help|-h]" << std::endl <<
  24. " [--version|-v]" << std::endl;
  25. std::cerr << std::endl << "Controls the output pins of a PiFace digital IO."
  26. << std::endl << std::endl;
  27. std::cerr << "--device \tSwitch to the provided device."
  28. << std::endl << "--up \t\tEnable the provided ouput pin."
  29. << std::endl << "--down \t\tDisable the provided output pin."
  30. << std::endl << "--sleep \tSleep for the provided amount of milliseconds."
  31. << std::endl << "--help \t\tDisplay this message."
  32. << std::endl << "--version \tDisplay version."
  33. << std::endl << std::endl;
  34. std::cerr << "OUTPUT \t: The output pin to enable/disable. 0 <= OUTPUT <= 7."
  35. << std::endl << "MS \t: The number of milliseconds to sleep. 0 <= MS <= "
  36. << UINT_MAX << "."
  37. << std::endl << "DEVICE \t: The device number. Default is 0. "
  38. "0 <= DEVICE <= 4." << std::endl;
  39. return EX_USAGE;
  40. }
  41. bool MainClass::bad_value_()
  42. {
  43. extern int optind;
  44. extern char* optarg;
  45. std::cerr << "Bad value " << optarg <<
  46. " for option " << argv_[optind - 2] << std::endl << std::endl;
  47. return false;
  48. }
  49. bool MainClass::build_actions_()
  50. {
  51. option opts[] = {
  52. {"device", 1, 0, 'e'},
  53. {"up", 1, 0, 'u'},
  54. {"down", 1, 0, 'd'},
  55. {"sleep", 1, 0, 's'},
  56. {"help", 0, 0, 'h'},
  57. {"version", 0, 0, 'v'},
  58. {0, 0, 0, 0}
  59. };
  60. int opt;
  61. extern int optind;
  62. extern char* optarg;
  63. char* endptr;
  64. while ((opt = getopt_long(argc_, argv_, "e:u:d:s:hv", opts, 0)) != -1)
  65. {
  66. long int arg = optarg ? strtol(optarg, &endptr, 10) : 0;
  67. if (arg < 0)
  68. return bad_value_();
  69. if (opt == 'e')
  70. {
  71. if (arg > 4)
  72. return bad_value_();
  73. actions_.push_back([arg]() -> bool
  74. {
  75. pifacedigital_close(get_current_device());
  76. return set_current_device(arg);
  77. });
  78. }
  79. else if (opt == 'u' || opt == 'd')
  80. {
  81. if (arg > 7)
  82. return bad_value_();
  83. actions_.push_back([arg, opt]() -> bool
  84. {
  85. if (get_current_device() == -1 &&
  86. !set_current_device(arg))
  87. return false;
  88. pifacedigital_write_bit(opt == 'u', arg, OUTPUT,
  89. get_current_device());
  90. /*pifacedigital_write_reg(opt == 'u' ? up_pin(arg) : down_pin(arg),
  91. OUTPUT, get_current_device());
  92. std::cout << std::hex << (int)get_pins() << std::endl;*/
  93. return true;
  94. });
  95. }
  96. else if (opt == 's')
  97. {
  98. if (arg > UINT_MAX)
  99. return bad_value_();
  100. actions_.push_back([arg]() -> bool
  101. {
  102. usleep(arg * 1000);
  103. return true;
  104. });
  105. }
  106. else if (opt == 'v')
  107. {
  108. std::cout << "camotion-piface 1.0" << std::endl;
  109. actions_.clear();
  110. return true;
  111. }
  112. else if (opt == 'h')
  113. {
  114. usage();
  115. actions_.clear();
  116. return true;
  117. }
  118. else
  119. return false;
  120. }
  121. return optind == argc_;
  122. }
  123. int MainClass::execute()
  124. {
  125. if (argc_ == 1 || !build_actions_())
  126. return usage();
  127. for (auto f : actions_)
  128. if (!f())
  129. return 1;
  130. return 0;
  131. }
  132. int MainClass::get_current_device()
  133. {
  134. return current_device_;
  135. }
  136. bool MainClass::set_current_device(int c)
  137. {
  138. if (pifacedigital_open((current_device_ = c)) == -1)
  139. {
  140. std::cerr << std::endl;
  141. return false;
  142. }
  143. pins_ = pifacedigital_read_reg(c, OUTPUT);
  144. return true;
  145. }
  146. uint8_t MainClass::get_pins()
  147. {
  148. return pins_;
  149. }
  150. uint8_t MainClass::up_pin(uint8_t pin)
  151. {
  152. return (pins_ |= (1 << pin));
  153. }
  154. uint8_t MainClass::down_pin(uint8_t pin)
  155. {
  156. return (pins_ &= ~(1 << pin));
  157. }