[nextion] TFT upload no longer fails when the display sends a split 0x08 ack (#16205)

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
Edward Firmo
2026-05-03 10:40:09 +02:00
committed by GitHub
parent 5e9db1c8c6
commit 8046ff7e1e
2 changed files with 54 additions and 0 deletions

View File

@@ -88,6 +88,33 @@ int Nextion::upload_by_chunks_(HTTPClient &http_client, uint32_t &range_start) {
this->write_array(buffer, buffer_size);
App.feed_wdt();
this->recv_ret_string_(recv_string, NEXTION_UPLOAD_ACK_TIMEOUT_MS, true);
// Some Nextion firmware variants (notably bootloader/recovery mode on panels
// with no installed TFT) emit the 5-byte 0x08+position fast-mode ack with a
// multi-second gap between the leading 0x08 byte and the 4 trailing position
// bytes. recv_ret_string_ returns after the first byte; manually drain the
// trailing bytes from the UART before continuing.
if (!recv_string.empty() && recv_string[0] == 0x08 && recv_string.size() < 5) {
const uint32_t deadline = millis() + NEXTION_UPLOAD_ACK_TIMEOUT_MS;
while (recv_string.size() < 5 && millis() < deadline) {
if (this->available()) {
uint8_t b = 0;
if (this->read_byte(&b)) {
recv_string.push_back(static_cast<char>(b));
}
} else {
delay(5); // NOLINT
App.feed_wdt();
}
}
if (recv_string.size() < 5) {
ESP_LOGE(TAG, "Truncated 0x08 response: got %zu bytes within %" PRIu32 "ms", recv_string.size(),
NEXTION_UPLOAD_ACK_TIMEOUT_MS);
allocator.deallocate(buffer, 4096);
buffer = nullptr;
return -1;
}
}
this->content_length_ -= read_len;
const float upload_percentage = 100.0f * (this->tft_size_ - this->content_length_) / this->tft_size_;
ESP_LOGD(TAG, "Upload: %0.2f%% (%" PRIu32 " left, heap: %" PRIu32 ")", upload_percentage, this->content_length_,

View File

@@ -104,6 +104,33 @@ int Nextion::upload_by_chunks_(esp_http_client_handle_t http_client, uint32_t &r
this->write_array(buffer, buffer_size);
App.feed_wdt();
this->recv_ret_string_(recv_string, NEXTION_UPLOAD_ACK_TIMEOUT_MS, true);
// Some Nextion firmware variants (notably bootloader/recovery mode on panels
// with no installed TFT) emit the 5-byte 0x08+position fast-mode ack with a
// multi-second gap between the leading 0x08 byte and the 4 trailing position
// bytes. recv_ret_string_ returns after the first byte; manually drain the
// trailing bytes from the UART before continuing.
if (!recv_string.empty() && recv_string[0] == 0x08 && recv_string.size() < 5) {
const uint32_t deadline = millis() + NEXTION_UPLOAD_ACK_TIMEOUT_MS;
while (recv_string.size() < 5 && millis() < deadline) {
if (this->available()) {
uint8_t b = 0;
if (this->read_byte(&b)) {
recv_string.push_back(static_cast<char>(b));
}
} else {
vTaskDelay(pdMS_TO_TICKS(5)); // NOLINT
App.feed_wdt();
}
}
if (recv_string.size() < 5) {
ESP_LOGE(TAG, "Truncated 0x08 response: got %zu bytes within %" PRIu32 "ms", recv_string.size(),
NEXTION_UPLOAD_ACK_TIMEOUT_MS);
allocator.deallocate(buffer, 4096);
buffer = nullptr;
return -1;
}
}
this->content_length_ -= read_len;
const float upload_percentage = 100.0f * (this->tft_size_ - this->content_length_) / this->tft_size_;
#ifdef USE_PSRAM