This commit is contained in:
Greg Gibeling 2024-05-15 14:44:00 +03:00 committed by GitHub
commit 0c24e0469d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 14 deletions

View File

@ -48,31 +48,52 @@ 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();
}
@ -91,9 +112,8 @@ 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_);
}
void SN74HC595GPIOPin::digital_write(bool value) { 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_); }
} // namespace sn74hc595

View File

@ -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 {