esphal.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #pragma once
  2. #include "Arduino.h"
  3. #ifdef ARDUINO_ARCH_ESP32
  4. #include <esp32-hal.h>
  5. #endif
  6. // Fix some arduino defs
  7. #ifdef round
  8. #undef round
  9. #endif
  10. #ifdef bool
  11. #undef bool
  12. #endif
  13. #ifdef true
  14. #undef true
  15. #endif
  16. #ifdef false
  17. #undef false
  18. #endif
  19. #ifdef min
  20. #undef min
  21. #endif
  22. #ifdef max
  23. #undef max
  24. #endif
  25. #ifdef abs
  26. #undef abs
  27. #endif
  28. namespace esphome {
  29. #define LOG_PIN(prefix, pin) \
  30. if ((pin) != nullptr) { \
  31. ESP_LOGCONFIG(TAG, prefix LOG_PIN_PATTERN, LOG_PIN_ARGS(pin)); \
  32. }
  33. #define LOG_PIN_PATTERN "GPIO%u (Mode: %s%s)"
  34. #define LOG_PIN_ARGS(pin) (pin)->get_pin(), (pin)->get_pin_mode_name(), ((pin)->is_inverted() ? ", INVERTED" : "")
  35. /// Copy of GPIOPin that is safe to use from ISRs (with no virtual functions)
  36. class ISRInternalGPIOPin {
  37. public:
  38. ISRInternalGPIOPin(uint8_t pin,
  39. #ifdef ARDUINO_ARCH_ESP32
  40. volatile uint32_t *gpio_clear, volatile uint32_t *gpio_set,
  41. #endif
  42. volatile uint32_t *gpio_read, uint32_t gpio_mask, bool inverted);
  43. bool digital_read();
  44. void digital_write(bool value);
  45. void clear_interrupt();
  46. protected:
  47. const uint8_t pin_;
  48. const bool inverted_;
  49. volatile uint32_t *const gpio_read_;
  50. const uint32_t gpio_mask_;
  51. #ifdef ARDUINO_ARCH_ESP32
  52. volatile uint32_t *const gpio_clear_;
  53. volatile uint32_t *const gpio_set_;
  54. #endif
  55. };
  56. /** A high-level abstraction class that can expose a pin together with useful options like pinMode.
  57. *
  58. * Set the parameters for this at construction time and use setup() to apply them. The inverted parameter will
  59. * automatically invert the input/output for you.
  60. *
  61. * Use read_value() and write_value() to use digitalRead() and digitalWrite(), respectively.
  62. */
  63. class GPIOPin {
  64. public:
  65. /** Construct the GPIOPin instance.
  66. *
  67. * @param pin The GPIO pin number of this instance.
  68. * @param mode The Arduino pinMode that this pin should be put into at setup().
  69. * @param inverted Whether all digitalRead/digitalWrite calls should be inverted.
  70. */
  71. GPIOPin(uint8_t pin, uint8_t mode, bool inverted = false);
  72. /// Setup the pin mode.
  73. virtual void setup();
  74. /// Read the binary value from this pin using digitalRead (and inverts automatically).
  75. virtual bool digital_read();
  76. /// Write the binary value to this pin using digitalWrite (and inverts automatically).
  77. virtual void digital_write(bool value);
  78. /// Set the pin mode
  79. virtual void pin_mode(uint8_t mode);
  80. /// Get the GPIO pin number.
  81. uint8_t get_pin() const;
  82. const char *get_pin_mode_name() const;
  83. /// Get the pinMode of this pin.
  84. uint8_t get_mode() const;
  85. /// Return whether this pin shall be treated as inverted. (for example active-low)
  86. bool is_inverted() const;
  87. template<typename T> void attach_interrupt(void (*func)(T *), T *arg, int mode) const;
  88. void detach_interrupt() const;
  89. ISRInternalGPIOPin *to_isr() const;
  90. protected:
  91. void attach_interrupt_(void (*func)(void *), void *arg, int mode) const;
  92. void detach_interrupt_() const;
  93. const uint8_t pin_;
  94. const uint8_t mode_;
  95. const bool inverted_;
  96. #ifdef ARDUINO_ARCH_ESP32
  97. volatile uint32_t *const gpio_set_;
  98. volatile uint32_t *const gpio_clear_;
  99. #endif
  100. volatile uint32_t *const gpio_read_;
  101. const uint32_t gpio_mask_;
  102. };
  103. template<typename T> void GPIOPin::attach_interrupt(void (*func)(T *), T *arg, int mode) const {
  104. this->attach_interrupt_(reinterpret_cast<void (*)(void *)>(func), arg, mode);
  105. }
  106. /** This function can be used by the HAL to force-link specific symbols
  107. * into the generated binary without modifying the linker script.
  108. *
  109. * It is called by the application very early on startup and should not be used for anything
  110. * other than forcing symbols to be linked.
  111. */
  112. void force_link_symbols();
  113. } // namespace esphome