mirror of
https://github.com/esphome/esphome.git
synced 2024-12-23 22:14:54 +01:00
pca9554 cache reads (#5137)
This commit is contained in:
parent
99a765dc06
commit
be6f95d43e
2 changed files with 29 additions and 2 deletions
|
@ -26,7 +26,7 @@ void PCA9554Component::setup() {
|
||||||
this->config_mask_ = 0;
|
this->config_mask_ = 0;
|
||||||
// Invert mask as the part sees a 1 as an input
|
// Invert mask as the part sees a 1 as an input
|
||||||
this->write_register_(CONFIG_REG, ~this->config_mask_);
|
this->write_register_(CONFIG_REG, ~this->config_mask_);
|
||||||
// All ouputs low
|
// All outputs low
|
||||||
this->output_mask_ = 0;
|
this->output_mask_ = 0;
|
||||||
this->write_register_(OUTPUT_REG, this->output_mask_);
|
this->write_register_(OUTPUT_REG, this->output_mask_);
|
||||||
// Read the inputs
|
// Read the inputs
|
||||||
|
@ -34,6 +34,14 @@ void PCA9554Component::setup() {
|
||||||
ESP_LOGD(TAG, "Initialization complete. Warning: %d, Error: %d", this->status_has_warning(),
|
ESP_LOGD(TAG, "Initialization complete. Warning: %d, Error: %d", this->status_has_warning(),
|
||||||
this->status_has_error());
|
this->status_has_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PCA9554Component::loop() {
|
||||||
|
// The read_inputs_() method will cache the input values from the chip.
|
||||||
|
this->read_inputs_();
|
||||||
|
// Clear all the previously read flags.
|
||||||
|
this->was_previously_read_ = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
void PCA9554Component::dump_config() {
|
void PCA9554Component::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "PCA9554:");
|
ESP_LOGCONFIG(TAG, "PCA9554:");
|
||||||
LOG_I2C_DEVICE(this)
|
LOG_I2C_DEVICE(this)
|
||||||
|
@ -43,7 +51,16 @@ void PCA9554Component::dump_config() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PCA9554Component::digital_read(uint8_t pin) {
|
bool PCA9554Component::digital_read(uint8_t pin) {
|
||||||
this->read_inputs_();
|
// Note: We want to try and avoid doing any I2C bus read transactions here
|
||||||
|
// to conserve I2C bus bandwidth. So what we do is check to see if we
|
||||||
|
// have seen a read during the time esphome is running this loop. If we have,
|
||||||
|
// we do an I2C bus transaction to get the latest value. If we haven't
|
||||||
|
// we return a cached value which was read at the time loop() was called.
|
||||||
|
if (this->was_previously_read_ & (1 << pin))
|
||||||
|
this->read_inputs_(); // Force a read of a new value
|
||||||
|
// Indicate we saw a read request for this pin in case a
|
||||||
|
// read happens later in the same loop.
|
||||||
|
this->was_previously_read_ |= (1 << pin);
|
||||||
return this->input_mask_ & (1 << pin);
|
return this->input_mask_ & (1 << pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +115,10 @@ bool PCA9554Component::write_register_(uint8_t reg, uint8_t value) {
|
||||||
|
|
||||||
float PCA9554Component::get_setup_priority() const { return setup_priority::IO; }
|
float PCA9554Component::get_setup_priority() const { return setup_priority::IO; }
|
||||||
|
|
||||||
|
// Run our loop() method very early in the loop, so that we cache read values before
|
||||||
|
// before other components call our digital_read() method.
|
||||||
|
float PCA9554Component::get_loop_priority() const { return 9.0f; } // Just after WIFI
|
||||||
|
|
||||||
void PCA9554GPIOPin::setup() { pin_mode(flags_); }
|
void PCA9554GPIOPin::setup() { pin_mode(flags_); }
|
||||||
void PCA9554GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
void PCA9554GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
||||||
bool PCA9554GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
bool PCA9554GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||||
|
|
|
@ -13,6 +13,8 @@ class PCA9554Component : public Component, public i2c::I2CDevice {
|
||||||
|
|
||||||
/// Check i2c availability and setup masks
|
/// Check i2c availability and setup masks
|
||||||
void setup() override;
|
void setup() override;
|
||||||
|
/// Poll for input changes periodically
|
||||||
|
void loop() override;
|
||||||
/// Helper function to read the value of a pin.
|
/// Helper function to read the value of a pin.
|
||||||
bool digital_read(uint8_t 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.
|
||||||
|
@ -22,6 +24,8 @@ class PCA9554Component : public Component, public i2c::I2CDevice {
|
||||||
|
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
|
float get_loop_priority() const override;
|
||||||
|
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -35,6 +39,8 @@ class PCA9554Component : public Component, public i2c::I2CDevice {
|
||||||
uint8_t output_mask_{0x00};
|
uint8_t output_mask_{0x00};
|
||||||
/// The state of the actual input pin states - 1 means HIGH, 0 means LOW
|
/// The state of the actual input pin states - 1 means HIGH, 0 means LOW
|
||||||
uint8_t input_mask_{0x00};
|
uint8_t input_mask_{0x00};
|
||||||
|
/// Flags to check if read previously during this loop
|
||||||
|
uint8_t was_previously_read_ = {0x00};
|
||||||
/// Storage for last I2C error seen
|
/// Storage for last I2C error seen
|
||||||
esphome::i2c::ErrorCode last_error_;
|
esphome::i2c::ErrorCode last_error_;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue