mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Remove PCF8574 input_pullup mode and cleanup (#828)
Fixes https://github.com/esphome/issues/issues/755 Closes https://github.com/esphome/esphome/pull/822 Fixes https://github.com/esphome/issues/issues/667 Closes https://github.com/esphome/esphome/pull/808 Co-Authored-By: Amish Vishwakarma <amishv@users.noreply.github.com> Co-Authored-By: S-Przybylski <s-przybylski@users.noreply.github.com>
This commit is contained in:
		| @@ -11,7 +11,6 @@ pcf8574_ns = cg.esphome_ns.namespace('pcf8574') | |||||||
| PCF8574GPIOMode = pcf8574_ns.enum('PCF8574GPIOMode') | PCF8574GPIOMode = pcf8574_ns.enum('PCF8574GPIOMode') | ||||||
| PCF8674_GPIO_MODES = { | PCF8674_GPIO_MODES = { | ||||||
|     'INPUT': PCF8574GPIOMode.PCF8574_INPUT, |     'INPUT': PCF8574GPIOMode.PCF8574_INPUT, | ||||||
|     'INPUT_PULLUP': PCF8574GPIOMode.PCF8574_INPUT_PULLUP, |  | ||||||
|     'OUTPUT': PCF8574GPIOMode.PCF8574_OUTPUT, |     'OUTPUT': PCF8574GPIOMode.PCF8574_OUTPUT, | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -33,16 +32,24 @@ def to_code(config): | |||||||
|     cg.add(var.set_pcf8575(config[CONF_PCF8575])) |     cg.add(var.set_pcf8575(config[CONF_PCF8575])) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def validate_pcf8574_gpio_mode(value): | ||||||
|  |     value = cv.string(value) | ||||||
|  |     if value.upper() == 'INPUT_PULLUP': | ||||||
|  |         raise cv.Invalid("INPUT_PULLUP mode has been removed in 1.14 and been combined into " | ||||||
|  |                          "INPUT mode (they were the same thing). Please use INPUT instead.") | ||||||
|  |     return cv.enum(PCF8674_GPIO_MODES, upper=True)(value) | ||||||
|  |  | ||||||
|  |  | ||||||
| PCF8574_OUTPUT_PIN_SCHEMA = cv.Schema({ | PCF8574_OUTPUT_PIN_SCHEMA = cv.Schema({ | ||||||
|     cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component), |     cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component), | ||||||
|     cv.Required(CONF_NUMBER): cv.int_, |     cv.Required(CONF_NUMBER): cv.int_, | ||||||
|     cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(PCF8674_GPIO_MODES, upper=True), |     cv.Optional(CONF_MODE, default="OUTPUT"): validate_pcf8574_gpio_mode, | ||||||
|     cv.Optional(CONF_INVERTED, default=False): cv.boolean, |     cv.Optional(CONF_INVERTED, default=False): cv.boolean, | ||||||
| }) | }) | ||||||
| PCF8574_INPUT_PIN_SCHEMA = cv.Schema({ | PCF8574_INPUT_PIN_SCHEMA = cv.Schema({ | ||||||
|     cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component), |     cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component), | ||||||
|     cv.Required(CONF_NUMBER): cv.int_, |     cv.Required(CONF_NUMBER): cv.int_, | ||||||
|     cv.Optional(CONF_MODE, default="INPUT"): cv.enum(PCF8674_GPIO_MODES, upper=True), |     cv.Optional(CONF_MODE, default="INPUT"): validate_pcf8574_gpio_mode, | ||||||
|     cv.Optional(CONF_INVERTED, default=False): cv.boolean, |     cv.Optional(CONF_INVERTED, default=False): cv.boolean, | ||||||
| }) | }) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,9 +31,9 @@ bool PCF8574Component::digital_read(uint8_t pin) { | |||||||
| } | } | ||||||
| void PCF8574Component::digital_write(uint8_t pin, bool value) { | void PCF8574Component::digital_write(uint8_t pin, bool value) { | ||||||
|   if (value) { |   if (value) { | ||||||
|     this->port_mask_ |= (1 << pin); |     this->output_mask_ |= (1 << pin); | ||||||
|   } else { |   } else { | ||||||
|     this->port_mask_ &= ~(1 << pin); |     this->output_mask_ &= ~(1 << pin); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   this->write_gpio_(); |   this->write_gpio_(); | ||||||
| @@ -41,16 +41,14 @@ void PCF8574Component::digital_write(uint8_t pin, bool value) { | |||||||
| void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) { | void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) { | ||||||
|   switch (mode) { |   switch (mode) { | ||||||
|     case PCF8574_INPUT: |     case PCF8574_INPUT: | ||||||
|       this->ddr_mask_ &= ~(1 << pin); |       // Clear mode mask bit | ||||||
|       this->port_mask_ &= ~(1 << pin); |       this->mode_mask_ &= ~(1 << pin); | ||||||
|       break; |       // Write GPIO to enable input mode | ||||||
|     case PCF8574_INPUT_PULLUP: |       this->write_gpio_(); | ||||||
|       this->ddr_mask_ &= ~(1 << pin); |  | ||||||
|       this->port_mask_ |= (1 << pin); |  | ||||||
|       break; |       break; | ||||||
|     case PCF8574_OUTPUT: |     case PCF8574_OUTPUT: | ||||||
|       this->ddr_mask_ |= (1 << pin); |       // Set mode mask bit | ||||||
|       this->port_mask_ &= ~(1 << pin); |       this->mode_mask_ |= 1 << pin; | ||||||
|       break; |       break; | ||||||
|     default: |     default: | ||||||
|       break; |       break; | ||||||
| @@ -59,21 +57,20 @@ void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) { | |||||||
| bool PCF8574Component::read_gpio_() { | bool PCF8574Component::read_gpio_() { | ||||||
|   if (this->is_failed()) |   if (this->is_failed()) | ||||||
|     return false; |     return false; | ||||||
|  |   bool success; | ||||||
|  |   uint8_t data[2]; | ||||||
|   if (this->pcf8575_) { |   if (this->pcf8575_) { | ||||||
|     if (!this->parent_->raw_receive_16(this->address_, &this->input_mask_, 1)) { |     success = this->read_bytes_raw(data, 2); | ||||||
|       this->status_set_warning(); |     this->input_mask_ = (uint16_t(data[1]) << 8) | (uint16_t(data[0]) << 0); | ||||||
|       return false; |  | ||||||
|     } |  | ||||||
|   } else { |   } else { | ||||||
|     uint8_t data; |     success = this->read_bytes_raw(data, 1); | ||||||
|     if (!this->parent_->raw_receive(this->address_, &data, 1)) { |     this->input_mask_ = data[0]; | ||||||
|       this->status_set_warning(); |  | ||||||
|       return false; |  | ||||||
|     } |  | ||||||
|     this->input_mask_ = data; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   if (!success) { | ||||||
|  |     this->status_set_warning(); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|   this->status_clear_warning(); |   this->status_clear_warning(); | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
| @@ -81,20 +78,20 @@ bool PCF8574Component::write_gpio_() { | |||||||
|   if (this->is_failed()) |   if (this->is_failed()) | ||||||
|     return false; |     return false; | ||||||
|  |  | ||||||
|   uint16_t value = (this->input_mask_ & ~this->ddr_mask_) | this->port_mask_; |   uint16_t value = 0; | ||||||
|  |   // Pins in OUTPUT mode and where pin is HIGH. | ||||||
|  |   value |= this->mode_mask_ & this->output_mask_; | ||||||
|  |   // Pins in INPUT mode must also be set here | ||||||
|  |   value |= ~this->mode_mask_; | ||||||
|  |  | ||||||
|   this->parent_->raw_begin_transmission(this->address_); |   uint8_t data[2]; | ||||||
|   uint8_t data = value & 0xFF; |   data[0] = value; | ||||||
|   this->parent_->raw_write(this->address_, &data, 1); |   data[1] = value >> 8; | ||||||
|  |   if (!this->write_bytes_raw(data, this->pcf8575_ ? 2 : 1)) { | ||||||
|   if (this->pcf8575_) { |  | ||||||
|     data = (value >> 8) & 0xFF; |  | ||||||
|     this->parent_->raw_write(this->address_, &data, 1); |  | ||||||
|   } |  | ||||||
|   if (!this->parent_->raw_end_transmission(this->address_)) { |  | ||||||
|     this->status_set_warning(); |     this->status_set_warning(); | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   this->status_clear_warning(); |   this->status_clear_warning(); | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -10,7 +10,6 @@ namespace pcf8574 { | |||||||
| /// Modes for PCF8574 pins | /// Modes for PCF8574 pins | ||||||
| enum PCF8574GPIOMode : uint8_t { | enum PCF8574GPIOMode : uint8_t { | ||||||
|   PCF8574_INPUT = INPUT, |   PCF8574_INPUT = INPUT, | ||||||
|   PCF8574_INPUT_PULLUP = INPUT_PULLUP, |  | ||||||
|   PCF8574_OUTPUT = OUTPUT, |   PCF8574_OUTPUT = OUTPUT, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -38,9 +37,12 @@ class PCF8574Component : public Component, public i2c::I2CDevice { | |||||||
|  |  | ||||||
|   bool write_gpio_(); |   bool write_gpio_(); | ||||||
|  |  | ||||||
|   uint16_t ddr_mask_{0x00}; |   /// Mask for the pin mode - 1 means output, 0 means input | ||||||
|  |   uint16_t mode_mask_{0x00}; | ||||||
|  |   /// The mask to write as output state - 1 means HIGH, 0 means LOW | ||||||
|  |   uint16_t output_mask_{0x00}; | ||||||
|  |   /// The state read in read_gpio_ - 1 means HIGH, 0 means LOW | ||||||
|   uint16_t input_mask_{0x00}; |   uint16_t input_mask_{0x00}; | ||||||
|   uint16_t port_mask_{0x00}; |  | ||||||
|   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