Refractored epd handler

This commit is contained in:
GW_MC
2026-01-28 17:35:49 +08:00
parent 38d5facc24
commit fc79e92660
7 changed files with 619 additions and 786 deletions

View File

@@ -5,6 +5,7 @@
#include "common/semaphore_guard.h"
#include <vector>
#include <atomic>
#include "epd_handler.h"
// Refresh mode configuration
#define PARTIAL_REFRESH_THRESHOLD 10 // Full refresh every N partial refreshes
@@ -62,74 +63,37 @@ public:
// Request a full refresh on next flush
void request_full_refresh(void);
// Check if display is busy (refreshing)
bool is_busy(void) const;
void wait_for_idle(void) const;
bool is_busy() {
return epd_handler_.is_busy();
}
esp_lcd_touch_handle_t get_touch_handle() const { return tp_handle_; }
protected:
esp_err_t epd_write_cmd(const uint8_t cmd, uint32_t transaction_id);
esp_err_t epd_write_data(const uint8_t data, uint32_t transaction_id);
esp_err_t epd_write_cmd_with_data(const uint8_t cmd, std::vector<uint8_t>& data, uint32_t transaction_id);
esp_err_t transfer_spi_data(const uint8_t* data, const size_t& length, uint32_t transaction_id);
private:
esp_err_t init_display_pins_(void);
esp_err_t epd_init_(void); // full fast refresh init
esp_err_t epd_init_partial_(void); // partial refresh init (standalone)
esp_err_t epd_init_internal_(uint32_t transaction_id); // full fast refresh init
esp_err_t epd_init_partial_internal_(uint32_t transaction_id); // partial refresh init (within existing transaction)
esp_err_t init_touch_(void);
esp_err_t dangerous_epd_write_cmd_without_lock_(const uint8_t cmd);
esp_err_t dangerous_epd_write_data_without_lock_(const uint8_t data);
// write to the internal draw buffer
void write_to_buffer_(const uint8_t* src, const RefreshArea& area);
// write the internal draw buffer to the display's old sram
esp_err_t refresh_old_buffer_(uint32_t transaction_id);
esp_err_t begin_transaction_(TickType_t timeout, uint32_t& out_id);
esp_err_t end_transaction_(void);
// given a transaction ID, wait for current transaction to complete. The transaction ID will determine if the wait is needed.
esp_err_t wait_for_transaction_end_(TickType_t timeout, uint32_t awaiting_transaction_id, SemaphoreGuard& out_transaction_guard);
friend class TransactionGuard;
EPDHandler epd_handler_;
uint32_t partial_refresh_count_ = 0;
bool force_full_refresh_ = false;
std::atomic<bool> is_deep_sleep_ { false };
SemaphoreHandle_t spi_mutex_ = nullptr;
SemaphoreHandle_t spi_transaction_mutex_ = nullptr;
SemaphoreHandle_t refresh_mutex_ = nullptr;
uint32_t spi_transaction_id = 0; // For tracking SPI transactions
spi_device_handle_t spi_ = nullptr;
esp_lcd_panel_io_handle_t tp_io_handle_ = nullptr;
esp_lcd_touch_handle_t tp_handle_ = nullptr;
// this buffer reflects the current display state (1=black, 0=white)
uint8_t* draw_buffer_ = nullptr;
uint8_t* old_buffer_ = nullptr;
RefreshArea refresh_area_ = { 0, 0, 0, 0 };
};
class TransactionGuard {
public:
TransactionGuard(EInkDisplayHandler& handler, TickType_t timeout = portMAX_DELAY)
: handler_(handler) { }
~TransactionGuard() { if (transaction_id_) handler_.end_transaction_(); }
esp_err_t begin(TickType_t timeout = portMAX_DELAY) {
esp_err_t err = handler_.begin_transaction_(timeout, transaction_id_);
return err;
}
uint32_t transaction_id() const { return transaction_id_; }
bool is_active() const { return transaction_id_ != 0; }
private:
// delete copy constructor and assignment operator
TransactionGuard(const TransactionGuard&) = delete;
TransactionGuard& operator=(const TransactionGuard&) = delete;
EInkDisplayHandler& handler_;
uint32_t transaction_id_ = 0;
};