diff --git a/esphome/components/rf_bridge/rf_bridge.cpp b/esphome/components/rf_bridge/rf_bridge.cpp index f1537cdc87..42689ecf82 100644 --- a/esphome/components/rf_bridge/rf_bridge.cpp +++ b/esphome/components/rf_bridge/rf_bridge.cpp @@ -15,59 +15,74 @@ void RFBridgeComponent::ack_() { this->flush(); } -void RFBridgeComponent::decode_() { - uint8_t action = uartbuf_[0]; - RFBridgeData data{}; +bool RFBridgeComponent::parse_bridge_byte_(uint8_t byte) { + size_t at = this->rx_buffer_.size(); + this->rx_buffer_.push_back(byte); + const uint8_t *raw = &this->rx_buffer_[0]; + + // Byte 0: Start + if (at == 0) + return byte == RF_CODE_START; + + // Byte 1: Action + if (at == 1) + return byte >= RF_CODE_ACK && byte <= RF_CODE_RFOUT; + uint8_t action = raw[1]; switch (action) { case RF_CODE_ACK: ESP_LOGD(TAG, "Action OK"); break; case RF_CODE_LEARN_KO: - this->ack_(); - ESP_LOGD(TAG, "Learn timeout"); + ESP_LOGD(TAG, "Learning timeout"); break; case RF_CODE_LEARN_OK: - ESP_LOGD(TAG, "Learn started"); case RF_CODE_RFIN: - this->ack_(); + if (at < RF_MESSAGE_SIZE + 2) + return true; - data.sync = (uartbuf_[1] << 8) | uartbuf_[2]; - data.low = (uartbuf_[3] << 8) | uartbuf_[4]; - data.high = (uartbuf_[5] << 8) | uartbuf_[6]; - data.code = (uartbuf_[7] << 16) | (uartbuf_[8] << 8) | uartbuf_[9]; + RFBridgeData data; + data.sync = (raw[2] << 8) | raw[3]; + data.low = (raw[4] << 8) | raw[5]; + data.high = (raw[6] << 8) | raw[7]; + data.code = (raw[8] << 16) | (raw[9] << 8) | raw[10]; + + if (action == RF_CODE_LEARN_OK) + ESP_LOGD(TAG, "Learning success"); ESP_LOGD(TAG, "Received RFBridge Code: sync=0x%04X low=0x%04X high=0x%04X code=0x%06X", data.sync, data.low, data.high, data.code); this->callback_.call(data); break; default: - ESP_LOGD(TAG, "Unknown action: 0x%02X", action); + ESP_LOGW(TAG, "Unknown action: 0x%02X", action); break; } - this->last_ = millis(); + + ESP_LOGVV(TAG, "Parsed: 0x%02X", byte); + + if (byte == RF_CODE_STOP && action != RF_CODE_ACK) + this->ack_(); + + // return false to reset buffer + return false; } void RFBridgeComponent::loop() { - bool receiving = false; - if (this->last_ != 0 && millis() - this->last_ > RF_DEBOUNCE) { - this->last_ = 0; + const uint32_t now = millis(); + if (now - this->last_bridge_byte_ > 50) { + this->rx_buffer_.clear(); + this->last_bridge_byte_ = now; } while (this->available()) { - uint8_t c = this->read(); - if (receiving) { - if (c == RF_CODE_STOP && (this->uartpos_ == 1 || this->uartpos_ == RF_MESSAGE_SIZE + 1)) { - this->decode_(); - receiving = false; - } else if (this->uartpos_ <= RF_MESSAGE_SIZE) { - this->uartbuf_[uartpos_++] = c; - } else { - receiving = false; - } - } else if (c == RF_CODE_START) { - this->uartpos_ = 0; - receiving = true; + uint8_t byte; + this->read_byte(&byte); + if (this->parse_bridge_byte_(byte)) { + ESP_LOGVV(TAG, "Parsed: 0x%02X", byte); + this->last_bridge_byte_ = now; + } else { + this->rx_buffer_.clear(); } } } @@ -77,11 +92,17 @@ void RFBridgeComponent::send_code(RFBridgeData data) { data.code); this->write(RF_CODE_START); this->write(RF_CODE_RFOUT); - this->write(data.sync); - this->write(data.low); - this->write(data.high); - this->write(data.code); + this->write((data.sync >> 8) & 0xFF); + this->write(data.sync & 0xFF); + this->write((data.low >> 8) & 0xFF); + this->write(data.low & 0xFF); + this->write((data.high >> 8) & 0xFF); + this->write(data.high & 0xFF); + this->write((data.code >> 16) & 0xFF); + this->write((data.code >> 8) & 0xFF); + this->write(data.code & 0xFF); this->write(RF_CODE_STOP); + this->flush(); } void RFBridgeComponent::learn() { @@ -89,6 +110,7 @@ void RFBridgeComponent::learn() { this->write(RF_CODE_START); this->write(RF_CODE_LEARN); this->write(RF_CODE_STOP); + this->flush(); } void RFBridgeComponent::dump_config() { diff --git a/esphome/components/rf_bridge/rf_bridge.h b/esphome/components/rf_bridge/rf_bridge.h index 86713b8a5c..7ae84a032f 100644 --- a/esphome/components/rf_bridge/rf_bridge.h +++ b/esphome/components/rf_bridge/rf_bridge.h @@ -45,10 +45,10 @@ class RFBridgeComponent : public uart::UARTDevice, public Component { protected: void ack_(); void decode_(); + bool parse_bridge_byte_(uint8_t byte); - unsigned long last_ = 0; - unsigned char uartbuf_[RF_MESSAGE_SIZE + 3] = {0}; - unsigned char uartpos_ = 0; + std::vector rx_buffer_; + uint32_t last_bridge_byte_{0}; CallbackManager callback_; };