mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 14:43:51 +00:00 
			
		
		
		
	Merge branch 'gpio_expander_fix_more_than_8_pins_in_bank' into optimize_pcf8574
This commit is contained in:
		| @@ -4,6 +4,7 @@ | ||||
| #include <cstdint> | ||||
| #include <cstring> | ||||
| #include <limits> | ||||
| #include <type_traits> | ||||
| #include "esphome/core/hal.h" | ||||
|  | ||||
| namespace esphome::gpio_expander { | ||||
| @@ -20,14 +21,18 @@ namespace esphome::gpio_expander { | ||||
| ///                          Examples: MCP23017 (2x8-bit banks), TCA9555 (2x8-bit banks) | ||||
| ///               * uint16_t: For chips that read all pins at once (up to 16 pins) | ||||
| ///                          Examples: PCF8574/8575 (8/16 pins), PCA9554/9555 (8/16 pins) | ||||
| ///           N - Total number of pins (as uint8_t) | ||||
| template<typename T, uint8_t N> class CachedGpioExpander { | ||||
| ///           N - Total number of pins (maximum 65535) | ||||
| ///           P - Type for pin number parameters (automatically selected based on N: | ||||
| ///               uint8_t for N<=256, uint16_t for N>256). Can be explicitly specified | ||||
| ///               if needed (e.g., for components like SN74HC165 with >256 pins) | ||||
| template<typename T, uint16_t N, typename P = typename std::conditional<(N > 256), uint16_t, uint8_t>::type> | ||||
| class CachedGpioExpander { | ||||
|  public: | ||||
|   /// @brief Read the state of the given pin. This will invalidate the cache for the given pin number. | ||||
|   /// @param pin Pin number to read | ||||
|   /// @return Pin state | ||||
|   bool digital_read(uint8_t pin) { | ||||
|     const uint8_t bank = pin / BANK_SIZE; | ||||
|   bool digital_read(P pin) { | ||||
|     const P bank = pin / BANK_SIZE; | ||||
|     const T pin_mask = (1 << (pin % BANK_SIZE)); | ||||
|     // Check if specific pin cache is valid | ||||
|     if (this->read_cache_valid_[bank] & pin_mask) { | ||||
| @@ -43,7 +48,7 @@ template<typename T, uint8_t N> class CachedGpioExpander { | ||||
|     return this->digital_read_cache(pin); | ||||
|   } | ||||
|  | ||||
|   void digital_write(uint8_t pin, bool value) { this->digital_write_hw(pin, value); } | ||||
|   void digital_write(P pin, bool value) { this->digital_write_hw(pin, value); } | ||||
|  | ||||
|  protected: | ||||
|   /// @brief Read GPIO bank from hardware into internal state | ||||
| @@ -51,23 +56,23 @@ template<typename T, uint8_t N> class CachedGpioExpander { | ||||
|   /// @return true if read succeeded, false on communication error | ||||
|   /// @note This does NOT return the pin state. It returns whether the read operation succeeded. | ||||
|   ///       The actual pin state should be returned by digital_read_cache(). | ||||
|   virtual bool digital_read_hw(uint8_t pin) = 0; | ||||
|   virtual bool digital_read_hw(P pin) = 0; | ||||
|  | ||||
|   /// @brief Get cached pin value from internal state | ||||
|   /// @param pin Pin number to read | ||||
|   /// @return Pin state (true = HIGH, false = LOW) | ||||
|   virtual bool digital_read_cache(uint8_t pin) = 0; | ||||
|   virtual bool digital_read_cache(P pin) = 0; | ||||
|  | ||||
|   /// @brief Write GPIO state to hardware | ||||
|   /// @param pin Pin number to write | ||||
|   /// @param value Pin state to write (true = HIGH, false = LOW) | ||||
|   virtual void digital_write_hw(uint8_t pin, bool value) = 0; | ||||
|   virtual void digital_write_hw(P pin, bool value) = 0; | ||||
|  | ||||
|   /// @brief Invalidate cache. This function should be called in component loop(). | ||||
|   void reset_pin_cache_() { memset(this->read_cache_valid_, 0x00, CACHE_SIZE_BYTES); } | ||||
|  | ||||
|   static constexpr uint8_t BITS_PER_BYTE = 8; | ||||
|   static constexpr uint8_t BANK_SIZE = sizeof(T) * BITS_PER_BYTE; | ||||
|   static constexpr uint16_t BITS_PER_BYTE = 8; | ||||
|   static constexpr uint16_t BANK_SIZE = sizeof(T) * BITS_PER_BYTE; | ||||
|   static constexpr size_t BANKS = N / BANK_SIZE; | ||||
|   static constexpr size_t CACHE_SIZE_BYTES = BANKS * sizeof(T); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user