gpio.cc 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include "common/gpio.h"
  2. #include <string>
  3. #ifdef __APPLE__
  4. int gpio_init(int pin_nr, bool output) {
  5. return 0;
  6. }
  7. int gpio_set(int pin_nr, bool high) {
  8. return 0;
  9. }
  10. int gpiochip_get_ro_value_fd(const char* consumer_label, int gpiochiop_id, int pin_nr) {
  11. return 0;
  12. }
  13. #else
  14. #include <fcntl.h>
  15. #include <unistd.h>
  16. #include <cstring>
  17. #include <linux/gpio.h>
  18. #include <sys/ioctl.h>
  19. #include "common/util.h"
  20. #include "common/swaglog.h"
  21. int gpio_init(int pin_nr, bool output) {
  22. char pin_dir_path[50];
  23. int pin_dir_path_len = snprintf(pin_dir_path, sizeof(pin_dir_path),
  24. "/sys/class/gpio/gpio%d/direction", pin_nr);
  25. if (pin_dir_path_len <= 0) {
  26. return -1;
  27. }
  28. const char *value = output ? "out" : "in";
  29. return util::write_file(pin_dir_path, (void*)value, strlen(value));
  30. }
  31. int gpio_set(int pin_nr, bool high) {
  32. char pin_val_path[50];
  33. int pin_val_path_len = snprintf(pin_val_path, sizeof(pin_val_path),
  34. "/sys/class/gpio/gpio%d/value", pin_nr);
  35. if (pin_val_path_len <= 0) {
  36. return -1;
  37. }
  38. return util::write_file(pin_val_path, (void*)(high ? "1" : "0"), 1);
  39. }
  40. int gpiochip_get_ro_value_fd(const char* consumer_label, int gpiochiop_id, int pin_nr) {
  41. // Assumed that all interrupt pins are unexported and rights are given to
  42. // read from gpiochip0.
  43. std::string gpiochip_path = "/dev/gpiochip" + std::to_string(gpiochiop_id);
  44. int fd = open(gpiochip_path.c_str(), O_RDONLY);
  45. if (fd < 0) {
  46. LOGE("Error opening gpiochip0 fd");
  47. return -1;
  48. }
  49. // Setup event
  50. struct gpioevent_request rq;
  51. rq.lineoffset = pin_nr;
  52. rq.handleflags = GPIOHANDLE_REQUEST_INPUT;
  53. /* Requesting both edges as the data ready pulse from the lsm6ds sensor is
  54. very short(75us) and is mostly detected as falling edge instead of rising.
  55. So if it is detected as rising the following falling edge is skipped. */
  56. rq.eventflags = GPIOEVENT_REQUEST_BOTH_EDGES;
  57. strncpy(rq.consumer_label, consumer_label, std::size(rq.consumer_label) - 1);
  58. int ret = util::safe_ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &rq);
  59. if (ret == -1) {
  60. LOGE("Unable to get line event from ioctl : %s", strerror(errno));
  61. close(fd);
  62. return -1;
  63. }
  64. close(fd);
  65. return rq.fd;
  66. }
  67. #endif