mirror of
https://github.com/esphome/esphome.git
synced 2025-10-30 06:33:51 +00:00
Add support for PCA9535 16 bit I/O expander (#5634)
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
namespace esphome {
|
||||
namespace pca9554 {
|
||||
|
||||
// for 16 bit expanders, these addresses will be doubled.
|
||||
const uint8_t INPUT_REG = 0;
|
||||
const uint8_t OUTPUT_REG = 1;
|
||||
const uint8_t INVERT_REG = 2;
|
||||
@@ -13,9 +14,10 @@ static const char *const TAG = "pca9554";
|
||||
|
||||
void PCA9554Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up PCA9554/PCA9554A...");
|
||||
this->reg_width_ = (this->pin_count_ + 7) / 8;
|
||||
// Test to see if device exists
|
||||
if (!this->read_inputs_()) {
|
||||
ESP_LOGE(TAG, "PCA9554 not available under 0x%02X", this->address_);
|
||||
ESP_LOGE(TAG, "PCA95xx not detected at 0x%02X", this->address_);
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
@@ -44,6 +46,7 @@ void PCA9554Component::loop() {
|
||||
|
||||
void PCA9554Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "PCA9554:");
|
||||
ESP_LOGCONFIG(TAG, " I/O Pins: %d", this->pin_count_);
|
||||
LOG_I2C_DEVICE(this)
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGE(TAG, "Communication with PCA9554 failed!");
|
||||
@@ -85,25 +88,33 @@ void PCA9554Component::pin_mode(uint8_t pin, gpio::Flags flags) {
|
||||
}
|
||||
|
||||
bool PCA9554Component::read_inputs_() {
|
||||
uint8_t inputs;
|
||||
uint8_t inputs[2];
|
||||
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGD(TAG, "Device marked failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((this->last_error_ = this->read_register(INPUT_REG, &inputs, 1, true)) != esphome::i2c::ERROR_OK) {
|
||||
if ((this->last_error_ = this->read_register(INPUT_REG * this->reg_width_, inputs, this->reg_width_, true)) !=
|
||||
esphome::i2c::ERROR_OK) {
|
||||
this->status_set_warning();
|
||||
ESP_LOGE(TAG, "read_register_(): I2C I/O error: %d", (int) this->last_error_);
|
||||
return false;
|
||||
}
|
||||
this->status_clear_warning();
|
||||
this->input_mask_ = inputs;
|
||||
this->input_mask_ = inputs[0];
|
||||
if (this->reg_width_ == 2) {
|
||||
this->input_mask_ |= inputs[1] << 8;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PCA9554Component::write_register_(uint8_t reg, uint8_t value) {
|
||||
if ((this->last_error_ = this->write_register(reg, &value, 1, true)) != esphome::i2c::ERROR_OK) {
|
||||
bool PCA9554Component::write_register_(uint8_t reg, uint16_t value) {
|
||||
uint8_t outputs[2];
|
||||
outputs[0] = (uint8_t) value;
|
||||
outputs[1] = (uint8_t) (value >> 8);
|
||||
if ((this->last_error_ = this->write_register(reg * this->reg_width_, outputs, this->reg_width_, true)) !=
|
||||
esphome::i2c::ERROR_OK) {
|
||||
this->status_set_warning();
|
||||
ESP_LOGE(TAG, "write_register_(): I2C I/O error: %d", (int) this->last_error_);
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user