mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01:00
pca9554 cache reads (#5137)
This commit is contained in:
parent
5cb21324a1
commit
1269bf9791
2 changed files with 29 additions and 2 deletions
|
@ -26,7 +26,7 @@ void PCA9554Component::setup() {
|
|||
this->config_mask_ = 0;
|
||||
// Invert mask as the part sees a 1 as an input
|
||||
this->write_register_(CONFIG_REG, ~this->config_mask_);
|
||||
// All ouputs low
|
||||
// All outputs low
|
||||
this->output_mask_ = 0;
|
||||
this->write_register_(OUTPUT_REG, this->output_mask_);
|
||||
// Read the inputs
|
||||
|
@ -34,6 +34,14 @@ void PCA9554Component::setup() {
|
|||
ESP_LOGD(TAG, "Initialization complete. Warning: %d, Error: %d", this->status_has_warning(),
|
||||
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() {
|
||||
ESP_LOGCONFIG(TAG, "PCA9554:");
|
||||
LOG_I2C_DEVICE(this)
|
||||
|
@ -43,7 +51,16 @@ void PCA9554Component::dump_config() {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -98,6 +115,10 @@ bool PCA9554Component::write_register_(uint8_t reg, uint8_t value) {
|
|||
|
||||
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::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_; }
|
||||
|
|
|
@ -13,6 +13,8 @@ class PCA9554Component : public Component, public i2c::I2CDevice {
|
|||
|
||||
/// Check i2c availability and setup masks
|
||||
void setup() override;
|
||||
/// Poll for input changes periodically
|
||||
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.
|
||||
|
@ -22,6 +24,8 @@ class PCA9554Component : public Component, public i2c::I2CDevice {
|
|||
|
||||
float get_setup_priority() const override;
|
||||
|
||||
float get_loop_priority() const override;
|
||||
|
||||
void dump_config() override;
|
||||
|
||||
protected:
|
||||
|
@ -35,6 +39,8 @@ class PCA9554Component : public Component, public i2c::I2CDevice {
|
|||
uint8_t output_mask_{0x00};
|
||||
/// The state of the actual input pin states - 1 means HIGH, 0 means LOW
|
||||
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
|
||||
esphome::i2c::ErrorCode last_error_;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue