gpio-linux.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include <stdbool.h>
  2. #include <sys/mman.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include "logging.h"
  8. #include "gpio.h"
  9. extern struct bfg_gpio_controller _linux_gpio;
  10. bool bfg_gpio_init(void)
  11. {
  12. const int fd = open("/dev/mem", O_RDWR | O_SYNC);
  13. if (fd < 0)
  14. applogr(false, LOG_ERR, "Failed to open /dev/mem");
  15. volatile unsigned *gpio;
  16. gpio = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x20200000);
  17. if (gpio == MAP_FAILED)
  18. applogr(false, LOG_ERR, "Failed to mmap GPIO from /dev/mem");
  19. close(fd);
  20. linux_gpio->all_gpios = gpio_bitmask_all;
  21. linux_gpio->p = (void*)gpio;
  22. return true;
  23. }
  24. static
  25. bool linux_gpio_set_mode(struct bfg_gpio_controller * const gc, const gpio_bitmask_t pins, int mode)
  26. {
  27. volatile unsigned * const gpio = gc->p;
  28. if (mode > 1)
  29. {
  30. if (mode > 3)
  31. {
  32. if (mode > 5)
  33. return false;
  34. mode = 7 - mode;
  35. }
  36. else
  37. mode |= 4;
  38. }
  39. for (int i = gpio_highest; i >= 0; --i)
  40. {
  41. volatile unsigned * const g = &gpio[i / 10];
  42. const int sh = (i % 10) * 3;
  43. *g = (*g & ~(7 << sh)) | (mode << sh);
  44. }
  45. return true;
  46. }
  47. static
  48. void linux_gpio_set_values(struct bfg_gpio_controller * const gc, const gpio_bitmask_t pins, const gpio_bitmask_t vals)
  49. {
  50. volatile unsigned * const gpio = gc->p;
  51. gpio[7] = pins & vals;
  52. gpio[10] = pins & ~vals;
  53. }
  54. static
  55. gpio_bitmask_t linux_gpio_get_values(struct bfg_gpio_controller * const gc, const gpio_bitmask_t pins)
  56. {
  57. volatile unsigned * const gpio = gc->p;
  58. return gpio[13] & pins;
  59. }
  60. static
  61. const struct bfg_gpio_controller_drv linux_gpio_drv = {
  62. .set_mode = linux_gpio_set_mode,
  63. .set_values = linux_gpio_set_values,
  64. .get_values = linux_gpio_get_values,
  65. };
  66. struct bfg_gpio_controller _linux_gpio = {
  67. .drv = &linux_gpio_drv,
  68. };