Fix partial refresh color inversion problem
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#define DISPLAY_BUFFER_SIZE (EINK_HEIGHT* EINK_WIDTH) / 8 // 1 bit per pixels
|
||||
#define MINIMUM_PIN_SETUP_DELAY_MS 10
|
||||
#define MINIMUM_POWER_ON_DELAY_MS 100
|
||||
#define PARTIAL_REFRESH_THRESHOLD 5 // Full refresh every N partial refreshes
|
||||
|
||||
static uint8_t* DRAW_BUFFER; // 1 bit per pixel
|
||||
static uint8_t* OLD_DRAW_BUFFER; // 1 bit per pixel
|
||||
@@ -99,32 +100,43 @@ esp_err_t EInkDisplayHandler::deep_sleep_display(void) {
|
||||
esp_err_t EInkDisplayHandler::refresh_display() {
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
{
|
||||
ESP_LOGI(TAG, "Waiting for display to be idle...");
|
||||
TransactionGuard transaction_guard(this->epd_handler_);
|
||||
err = transaction_guard.begin(pdMS_TO_TICKS(10000));
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to begin transaction for display refresh: %s", esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
if (is_deep_sleep_) {
|
||||
epd_init_internal_(transaction_guard.transaction_id());
|
||||
}
|
||||
|
||||
epd_handler_.wait_for_idle();
|
||||
ESP_LOGI(TAG, "Starting display refresh...");
|
||||
err = epd_handler_.epd_write_cmd(0x92, transaction_guard.transaction_id()); // enter normal mode
|
||||
if (is_deep_sleep_) {
|
||||
|
||||
err = full_write(draw_buffer_, true);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to enter normal mode: %s", esp_err_to_name(err));
|
||||
ESP_LOGE(TAG, "Full write failed during refresh_display: %s", esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
err = epd_handler_.epd_write_cmd(0x12, transaction_guard.transaction_id()); // display refresh
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send display refresh command: %s", esp_err_to_name(err));
|
||||
return err;
|
||||
} else {
|
||||
// refresh does not correctly work after recovering from deep sleep due to sram reset
|
||||
{
|
||||
ESP_LOGI(TAG, "Waiting for display to be idle...");
|
||||
TransactionGuard transaction_guard(this->epd_handler_);
|
||||
err = transaction_guard.begin(pdMS_TO_TICKS(10000));
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to begin transaction for display refresh: %s", esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
if (is_deep_sleep_) {
|
||||
epd_init_internal_(transaction_guard.transaction_id());
|
||||
}
|
||||
|
||||
epd_handler_.wait_for_idle();
|
||||
ESP_LOGI(TAG, "Starting display refresh...");
|
||||
err = epd_handler_.epd_write_cmd(0x92, transaction_guard.transaction_id()); // enter normal mode
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to enter normal mode: %s", esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
err = epd_handler_.epd_write_cmd(0x12, transaction_guard.transaction_id()); // display refresh
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send display refresh command: %s", esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(MINIMUM_PIN_SETUP_DELAY_MS)); // at least 200us delay
|
||||
epd_handler_.wait_for_idle();
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(MINIMUM_PIN_SETUP_DELAY_MS)); // at least 200us delay
|
||||
epd_handler_.wait_for_idle();
|
||||
}
|
||||
|
||||
{
|
||||
@@ -235,6 +247,7 @@ esp_err_t EInkDisplayHandler::partial_refresh(const uint8_t* incoming_partial_fr
|
||||
ESP_LOGI(TAG, "Partial refresh skipped (not last partial update)");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
{
|
||||
TransactionGuard transaction_guard(this->epd_handler_);
|
||||
err = transaction_guard.begin(pdMS_TO_TICKS(5000));
|
||||
@@ -359,7 +372,7 @@ esp_err_t EInkDisplayHandler::partial_refresh(const uint8_t* incoming_partial_fr
|
||||
// Send only the partial area data, not the full display buffer
|
||||
ESP_LOGI(TAG, "Sending new partial buffer: %zu bytes (area: %dx%d)",
|
||||
partial_buffer_size, area_width_bytes * 8, area_height);
|
||||
err = epd_handler_.transfer_spi_data(partial_buffer, partial_buffer_size, transaction_guard.transaction_id());
|
||||
err = epd_handler_.transfer_spi_data(partial_buffer, partial_buffer_size, transaction_guard.transaction_id(), true); // Inverted for partial refresh
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send partial_buffer data for partial refresh: %s", esp_err_to_name(err));
|
||||
heap_caps_free(partial_buffer);
|
||||
@@ -391,6 +404,13 @@ esp_err_t EInkDisplayHandler::partial_refresh(const uint8_t* incoming_partial_fr
|
||||
}
|
||||
}
|
||||
ESP_LOGI(TAG, "Partial refresh complete");
|
||||
|
||||
err = deep_sleep_display();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to enter deep sleep after partial refresh: %s", esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
if (force_full_refresh_) {
|
||||
ESP_LOGI(TAG, "Full refresh already requested, skipping partial refresh count increment");
|
||||
err = refresh_display();
|
||||
@@ -400,6 +420,7 @@ esp_err_t EInkDisplayHandler::partial_refresh(const uint8_t* incoming_partial_fr
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
{
|
||||
SemaphoreGuard guard(refresh_mutex_);
|
||||
if (guard.take(pdMS_TO_TICKS(5000)) != pdTRUE) {
|
||||
@@ -418,11 +439,6 @@ esp_err_t EInkDisplayHandler::partial_refresh(const uint8_t* incoming_partial_fr
|
||||
}
|
||||
}
|
||||
|
||||
err = deep_sleep_display();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to enter deep sleep after partial refresh: %s", esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
refresh_area_.reset();
|
||||
|
||||
Reference in New Issue
Block a user