gpio.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
  2. // Copyright (C) 2013 Henner Zeller <h.zeller@acm.org>
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation version 2.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program. If not, see <http://gnu.org/licenses/gpl-2.0.txt>
  15. #ifndef RPI_GPIO_H
  16. #define RPI_GPIO_H
  17. #include <stdint.h>
  18. #include <vector>
  19. // Putting this in our namespace to not collide with other things called like
  20. // this.
  21. namespace rgb_matrix {
  22. // For now, everything is initialized as output.
  23. class GPIO {
  24. public:
  25. // Available bits that actually have pins.
  26. static const uint32_t kValidBits;
  27. GPIO();
  28. // Initialize before use. Returns 'true' if successful, 'false' otherwise
  29. // (e.g. due to a permission problem).
  30. bool Init(int
  31. #if RGB_SLOWDOWN_GPIO
  32. slowdown = RGB_SLOWDOWN_GPIO
  33. #else
  34. slowdown = 1
  35. #endif
  36. );
  37. // Initialize outputs.
  38. // Returns the bits that were available and could be set for output.
  39. // (never use the optional adafruit_hack_needed parameter, it is used
  40. // internally to this library).
  41. uint32_t InitOutputs(uint32_t outputs, bool adafruit_hack_needed = false);
  42. // Request given bitmap of GPIO inputs.
  43. // Returns the bits that were available and could be reserved.
  44. uint32_t RequestInputs(uint32_t inputs);
  45. // Set the bits that are '1' in the output. Leave the rest untouched.
  46. inline void SetBits(uint32_t value) {
  47. if (!value) return;
  48. *gpio_set_bits_ = value;
  49. for (int i = 0; i < slowdown_; ++i) {
  50. *gpio_set_bits_ = value;
  51. }
  52. }
  53. // Clear the bits that are '1' in the output. Leave the rest untouched.
  54. inline void ClearBits(uint32_t value) {
  55. if (!value) return;
  56. *gpio_clr_bits_ = value;
  57. for (int i = 0; i < slowdown_; ++i) {
  58. *gpio_clr_bits_ = value;
  59. }
  60. }
  61. // Write all the bits of "value" mentioned in "mask". Leave the rest untouched.
  62. inline void WriteMaskedBits(uint32_t value, uint32_t mask) {
  63. // Writing a word is two operations. The IO is actually pretty slow, so
  64. // this should probably be unnoticable.
  65. ClearBits(~value & mask);
  66. SetBits(value & mask);
  67. }
  68. inline void Write(uint32_t value) { WriteMaskedBits(value, output_bits_); }
  69. inline uint32_t Read() const { return *gpio_read_bits_ & input_bits_; }
  70. private:
  71. uint32_t output_bits_;
  72. uint32_t input_bits_;
  73. uint32_t reserved_bits_;
  74. int slowdown_;
  75. volatile uint32_t *gpio_set_bits_;
  76. volatile uint32_t *gpio_clr_bits_;
  77. volatile uint32_t *gpio_read_bits_;
  78. };
  79. // A PinPulser is a utility class that pulses a GPIO pin. There can be various
  80. // implementations.
  81. class PinPulser {
  82. public:
  83. // Factory for a PinPulser. Chooses the right implementation depending
  84. // on the context (CPU and which pins are affected).
  85. // "gpio_mask" is the mask that should be output (since we only
  86. // need negative pulses, this is what it does)
  87. // "nano_wait_spec" contains a list of time periods we'd like
  88. // invoke later. This can be used to pre-process timings if needed.
  89. static PinPulser *Create(GPIO *io, uint32_t gpio_mask,
  90. bool allow_hardware_pulsing,
  91. const std::vector<int> &nano_wait_spec);
  92. virtual ~PinPulser() {}
  93. // Send a pulse with a given length (index into nano_wait_spec array).
  94. virtual void SendPulse(int time_spec_number) = 0;
  95. // If SendPulse() is asynchronously implemented, wait for pulse to finish.
  96. virtual void WaitPulseFinished() {}
  97. };
  98. // Get rolling over microsecond counter. We get this from a hardware register
  99. // if possible and a terrible slow fallback otherwise.
  100. uint32_t GetMicrosecondCounter();
  101. } // end namespace rgb_matrix
  102. #endif // RPI_GPIO_H