#pragma once #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "driver/spi_master.h" #include "common/semaphore_guard.h" #include #include "display/transaction_guard.h" class EPDHandler : public WithTransaction { public: EPDHandler(); ~EPDHandler(); esp_err_t init(); 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& data, uint32_t transaction_id); esp_err_t transfer_spi_data(const uint8_t* data, const size_t& length, uint32_t transaction_id, bool inverted = false); bool is_busy(void) const; void wait_for_idle(void) const; private: 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); esp_err_t begin_transaction_(TickType_t timeout, uint32_t& out_id) override; esp_err_t end_transaction_(void) override; // 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); spi_device_handle_t spi_ = nullptr; SemaphoreHandle_t spi_mutex_ = nullptr; SemaphoreHandle_t spi_transaction_mutex_ = nullptr; uint32_t spi_transaction_id = 0; // For tracking SPI transactions friend class TransactionGuard; };