mirror of
https://github.com/esphome/esphome.git
synced 2025-01-30 23:02:14 +01:00
SN74HC595 support for inverted & restore modes without relay pulsing
This commit is contained in:
parent
c35a21773e
commit
9373ebe353
@ -48,31 +48,53 @@ void SN74HC595Component::digital_write_(uint16_t pin, bool value) {
|
||||
return;
|
||||
}
|
||||
if (value) {
|
||||
this->output_bytes_[pin / 8] |= (1 << (pin % 8));
|
||||
this->value_bytes_[pin / 8] |= (1 << (pin % 8));
|
||||
} else {
|
||||
this->output_bytes_[pin / 8] &= ~(1 << (pin % 8));
|
||||
this->value_bytes_[pin / 8] &= ~(1 << (pin % 8));
|
||||
}
|
||||
this->write_gpio();
|
||||
}
|
||||
void SN74HC595Component::set_inverted_(uint16_t pin, bool inverted) {
|
||||
if (pin >= this->sr_count_ * 8) {
|
||||
ESP_LOGE(TAG, "Pin %u is out of range! Maximum pin number with %u chips in series is %u", pin, this->sr_count_,
|
||||
(this->sr_count_ * 8) - 1);
|
||||
return;
|
||||
}
|
||||
if (inverted) {
|
||||
this->inverted_bytes_[pin / 8] |= (1 << (pin % 8));
|
||||
} else {
|
||||
this->inverted_bytes_[pin / 8] &= ~(1 << (pin % 8));
|
||||
}
|
||||
}
|
||||
|
||||
void SN74HC595GPIOComponent::write_gpio() {
|
||||
for (auto byte = this->output_bytes_.rbegin(); byte != this->output_bytes_.rend(); byte++) {
|
||||
auto value = this->value_bytes_.rbegin();
|
||||
auto inverted = this->inverted_bytes_.rbegin();
|
||||
while (value != this->value_bytes_.rend() && inverted != this->inverted_bytes_.rend()) {
|
||||
for (int8_t i = 7; i >= 0; i--) {
|
||||
bool bit = (*byte >> i) & 1;
|
||||
this->data_pin_->digital_write(bit);
|
||||
bool value_bit = (*value >> i) & 1;
|
||||
bool value_inverted = (*inverted >> i) & 1;
|
||||
this->data_pin_->digital_write(value_bit != value_inverted);
|
||||
this->clock_pin_->digital_write(true);
|
||||
this->clock_pin_->digital_write(false);
|
||||
}
|
||||
value++;
|
||||
inverted++;
|
||||
}
|
||||
SN74HC595Component::write_gpio();
|
||||
}
|
||||
|
||||
#ifdef USE_SPI
|
||||
void SN74HC595SPIComponent::write_gpio() {
|
||||
for (auto byte = this->output_bytes_.rbegin(); byte != this->output_bytes_.rend(); byte++) {
|
||||
auto value = this->value_bytes_.rbegin();
|
||||
auto inverted = this->inverted_bytes_.rbegin();
|
||||
while (value != this->value_bytes_.rend() && inverted != this->inverted_bytes_.rend()) {
|
||||
this->enable();
|
||||
this->transfer_byte(*byte);
|
||||
this->transfer_byte((*byte) ^ (*inverted));
|
||||
this->disable();
|
||||
|
||||
value++;
|
||||
inverted++;
|
||||
}
|
||||
SN74HC595Component::write_gpio();
|
||||
}
|
||||
@ -92,7 +114,10 @@ void SN74HC595Component::write_gpio() {
|
||||
float SN74HC595Component::get_setup_priority() const { return setup_priority::IO; }
|
||||
|
||||
void SN74HC595GPIOPin::digital_write(bool value) {
|
||||
this->parent_->digital_write_(this->pin_, value != this->inverted_);
|
||||
this->parent_->digital_write_(this->pin_, value);
|
||||
}
|
||||
void SN74HC595GPIOPin::set_inverted(bool inverted) {
|
||||
this->parent_->set_inverted_(this->pin_, inverted);
|
||||
}
|
||||
std::string SN74HC595GPIOPin::dump_summary() const { return str_snprintf("%u via SN74HC595", 18, pin_); }
|
||||
|
||||
|
@ -29,12 +29,14 @@ class SN74HC595Component : public Component {
|
||||
}
|
||||
void set_sr_count(uint8_t count) {
|
||||
this->sr_count_ = count;
|
||||
this->output_bytes_.resize(count);
|
||||
this->value_bytes_.resize(count);
|
||||
this->inverted_bytes_.resize(count);
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class SN74HC595GPIOPin;
|
||||
void digital_write_(uint16_t pin, bool value);
|
||||
void set_inverted_(uint16_t pin, bool inverted);
|
||||
virtual void write_gpio();
|
||||
|
||||
void pre_setup_();
|
||||
@ -44,7 +46,8 @@ class SN74HC595Component : public Component {
|
||||
GPIOPin *oe_pin_;
|
||||
uint8_t sr_count_;
|
||||
bool have_oe_pin_{false};
|
||||
std::vector<uint8_t> output_bytes_;
|
||||
std::vector<uint8_t> value_bytes_;
|
||||
std::vector<uint8_t> inverted_bytes_;
|
||||
};
|
||||
|
||||
/// Helper class to expose a SC74HC595 pin as an internal output GPIO pin.
|
||||
@ -57,11 +60,10 @@ class SN74HC595GPIOPin : public GPIOPin, public Parented<SN74HC595Component> {
|
||||
std::string dump_summary() const override;
|
||||
|
||||
void set_pin(uint16_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
void set_inverted(bool inverted);
|
||||
|
||||
protected:
|
||||
uint16_t pin_;
|
||||
bool inverted_;
|
||||
};
|
||||
|
||||
class SN74HC595GPIOComponent : public SN74HC595Component {
|
||||
|
Loading…
Reference in New Issue
Block a user