mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	use helper
This commit is contained in:
		| @@ -11,6 +11,7 @@ from esphome.const import ( | |||||||
|     CONF_OUTPUT, |     CONF_OUTPUT, | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | AUTO_LOAD = ["gpio_expander"] | ||||||
| DEPENDENCIES = ["i2c"] | DEPENDENCIES = ["i2c"] | ||||||
| MULTI_CONF = True | MULTI_CONF = True | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,9 +17,8 @@ void PCF8574Component::setup() { | |||||||
|   this->read_gpio_(); |   this->read_gpio_(); | ||||||
| } | } | ||||||
| void PCF8574Component::loop() { | void PCF8574Component::loop() { | ||||||
|   // Invalidate the cache at the start of each loop. |   // Invalidate the cache at the start of each loop | ||||||
|   // The actual read will happen on demand in digital_read() |   this->reset_pin_cache_(); | ||||||
|   this->cache_valid_ = false; |  | ||||||
| } | } | ||||||
| void PCF8574Component::dump_config() { | void PCF8574Component::dump_config() { | ||||||
|   ESP_LOGCONFIG(TAG, "PCF8574:"); |   ESP_LOGCONFIG(TAG, "PCF8574:"); | ||||||
| @@ -29,20 +28,21 @@ void PCF8574Component::dump_config() { | |||||||
|     ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL); |     ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| bool PCF8574Component::digital_read(uint8_t pin) { | bool PCF8574Component::digital_read(uint8_t pin) { return this->get_pin_value_(pin); } | ||||||
|   // Read the inputs once per loop on demand and cache the result |  | ||||||
|   if (!this->cache_valid_ && this->read_gpio_()) { | bool PCF8574Component::digital_read_hw(uint8_t pin) { | ||||||
|     this->cache_valid_ = true; |   return this->read_gpio_() ? (this->input_mask_ & (1 << pin)) : false; | ||||||
|   } |  | ||||||
|   return this->input_mask_ & (1 << pin); |  | ||||||
| } | } | ||||||
| void PCF8574Component::digital_write(uint8_t pin, bool value) { |  | ||||||
|  | bool PCF8574Component::digital_read_cache(uint8_t pin) { return this->input_mask_ & (1 << pin); } | ||||||
|  | void PCF8574Component::digital_write(uint8_t pin, bool value) { this->set_pin_value_(pin, value); } | ||||||
|  |  | ||||||
|  | void PCF8574Component::digital_write_hw(uint8_t pin, bool value) { | ||||||
|   if (value) { |   if (value) { | ||||||
|     this->output_mask_ |= (1 << pin); |     this->output_mask_ |= (1 << pin); | ||||||
|   } else { |   } else { | ||||||
|     this->output_mask_ &= ~(1 << pin); |     this->output_mask_ &= ~(1 << pin); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   this->write_gpio_(); |   this->write_gpio_(); | ||||||
| } | } | ||||||
| void PCF8574Component::pin_mode(uint8_t pin, gpio::Flags flags) { | void PCF8574Component::pin_mode(uint8_t pin, gpio::Flags flags) { | ||||||
|   | |||||||
| @@ -3,11 +3,16 @@ | |||||||
| #include "esphome/core/component.h" | #include "esphome/core/component.h" | ||||||
| #include "esphome/core/hal.h" | #include "esphome/core/hal.h" | ||||||
| #include "esphome/components/i2c/i2c.h" | #include "esphome/components/i2c/i2c.h" | ||||||
|  | #include "esphome/components/gpio_expander/cached_gpio.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace pcf8574 { | namespace pcf8574 { | ||||||
|  |  | ||||||
| class PCF8574Component : public Component, public i2c::I2CDevice { | // PCF8574(8 pins)/PCF8575(16 pins) always read/write all pins in a single I2C transaction | ||||||
|  | // so we use uint16_t as bank type to ensure all pins are in one bank and cached together | ||||||
|  | class PCF8574Component : public Component, | ||||||
|  |                          public i2c::I2CDevice, | ||||||
|  |                          public gpio_expander::CachedGpioExpander<uint16_t, 16> { | ||||||
|  public: |  public: | ||||||
|   PCF8574Component() = default; |   PCF8574Component() = default; | ||||||
|  |  | ||||||
| @@ -17,8 +22,6 @@ class PCF8574Component : public Component, public i2c::I2CDevice { | |||||||
|   void setup() override; |   void setup() override; | ||||||
|   /// Invalidate cache at start of each loop |   /// Invalidate cache at start of each loop | ||||||
|   void loop() override; |   void loop() override; | ||||||
|   /// Helper function to read the value of a pin. |  | ||||||
|   bool digital_read(uint8_t pin); |  | ||||||
|   /// Helper function to write the value of a pin. |   /// Helper function to write the value of a pin. | ||||||
|   void digital_write(uint8_t pin, bool value); |   void digital_write(uint8_t pin, bool value); | ||||||
|   /// Helper function to set the pin mode of a pin. |   /// Helper function to set the pin mode of a pin. | ||||||
| @@ -30,8 +33,11 @@ class PCF8574Component : public Component, public i2c::I2CDevice { | |||||||
|   void dump_config() override; |   void dump_config() override; | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   bool read_gpio_(); |   bool digital_read_hw(uint8_t pin) override; | ||||||
|  |   bool digital_read_cache(uint8_t pin) override; | ||||||
|  |   void digital_write_hw(uint8_t pin, bool value) override; | ||||||
|  |  | ||||||
|  |   bool read_gpio_(); | ||||||
|   bool write_gpio_(); |   bool write_gpio_(); | ||||||
|  |  | ||||||
|   /// Mask for the pin mode - 1 means output, 0 means input |   /// Mask for the pin mode - 1 means output, 0 means input | ||||||
| @@ -40,8 +46,6 @@ class PCF8574Component : public Component, public i2c::I2CDevice { | |||||||
|   uint16_t output_mask_{0x00}; |   uint16_t output_mask_{0x00}; | ||||||
|   /// The state read in read_gpio_ - 1 means HIGH, 0 means LOW |   /// The state read in read_gpio_ - 1 means HIGH, 0 means LOW | ||||||
|   uint16_t input_mask_{0x00}; |   uint16_t input_mask_{0x00}; | ||||||
|   /// Cache validity flag - true if we've read inputs this loop cycle |  | ||||||
|   bool cache_valid_{false}; |  | ||||||
|   bool pcf8575_;  ///< TRUE->16-channel PCF8575, FALSE->8-channel PCF8574 |   bool pcf8575_;  ///< TRUE->16-channel PCF8575, FALSE->8-channel PCF8574 | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user