feat: add support for inverted data transfer in SPI communication
This commit is contained in:
@@ -191,7 +191,7 @@ esp_err_t EPDHandler::dangerous_epd_write_data_without_lock_(const uint8_t data)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t EPDHandler::transfer_spi_data(const uint8_t* data, const size_t& length, uint32_t transaction_id) {
|
esp_err_t EPDHandler::transfer_spi_data(const uint8_t* data, const size_t& length, uint32_t transaction_id, bool inverted) {
|
||||||
ESP_LOGI(TAG, "transfer_spi_data: waiting to send %zu bytes of data", length);
|
ESP_LOGI(TAG, "transfer_spi_data: waiting to send %zu bytes of data", length);
|
||||||
|
|
||||||
SemaphoreGuard transaction_guard(spi_transaction_mutex_);
|
SemaphoreGuard transaction_guard(spi_transaction_mutex_);
|
||||||
@@ -212,12 +212,37 @@ esp_err_t EPDHandler::transfer_spi_data(const uint8_t* data, const size_t& lengt
|
|||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
size_t remaining = length;
|
size_t remaining = length;
|
||||||
gpio_set_level(PIN_DC, 1); // Data mode
|
gpio_set_level(PIN_DC, 1); // Data mode
|
||||||
|
|
||||||
|
// Allocate a temporary buffer for inverted data (only if inverted)
|
||||||
|
uint8_t* temp_transfer_buffer = nullptr;
|
||||||
|
if (inverted) {
|
||||||
|
temp_transfer_buffer = (uint8_t*)heap_caps_malloc(DMA_TRANSFER_CHUNK_SIZE, MALLOC_CAP_DMA);
|
||||||
|
if (temp_transfer_buffer == nullptr) {
|
||||||
|
ESP_LOGE(TAG, "Failed to allocate memory for inverted data transfer buffer");
|
||||||
|
ESP_LOGI(TAG, "Current free heap size: %u bytes", esp_get_free_heap_size());
|
||||||
|
ESP_LOGI(TAG, "Current free DMA-capable memory size: %u bytes",
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_DMA));
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
size_t transfer_size = (remaining < DMA_TRANSFER_CHUNK_SIZE) ? remaining : DMA_TRANSFER_CHUNK_SIZE;
|
size_t transfer_size = (remaining < DMA_TRANSFER_CHUNK_SIZE) ? remaining : DMA_TRANSFER_CHUNK_SIZE;
|
||||||
|
|
||||||
|
const uint8_t* transfer_buffer = nullptr;
|
||||||
|
if (inverted) {
|
||||||
|
// Invert only the current chunk into the temporary buffer
|
||||||
|
for (size_t i = 0; i < transfer_size; ++i) {
|
||||||
|
temp_transfer_buffer[i] = ~data[offset + i];
|
||||||
|
}
|
||||||
|
transfer_buffer = temp_transfer_buffer;
|
||||||
|
} else {
|
||||||
|
transfer_buffer = data + offset;
|
||||||
|
}
|
||||||
|
|
||||||
spi_transaction_t t = {};
|
spi_transaction_t t = {};
|
||||||
t.length = transfer_size * 8; // Length in bits
|
t.length = transfer_size * 8; // Length in bits
|
||||||
t.tx_buffer = data + offset;
|
t.tx_buffer = transfer_buffer;
|
||||||
|
|
||||||
esp_err_t ret = spi_device_polling_transmit(spi_, &t);
|
esp_err_t ret = spi_device_polling_transmit(spi_, &t);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
@@ -227,6 +252,10 @@ esp_err_t EPDHandler::transfer_spi_data(const uint8_t* data, const size_t& lengt
|
|||||||
ESP_LOGE(TAG, "Current free DMA-capable memory size: %u bytes",
|
ESP_LOGE(TAG, "Current free DMA-capable memory size: %u bytes",
|
||||||
heap_caps_get_free_size(MALLOC_CAP_DMA));
|
heap_caps_get_free_size(MALLOC_CAP_DMA));
|
||||||
}
|
}
|
||||||
|
if (inverted && temp_transfer_buffer != nullptr) {
|
||||||
|
// Free the temporary inverted buffer
|
||||||
|
heap_caps_free(temp_transfer_buffer);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,6 +269,11 @@ esp_err_t EPDHandler::transfer_spi_data(const uint8_t* data, const size_t& lengt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inverted && temp_transfer_buffer != nullptr) {
|
||||||
|
// Free the temporary inverted buffer
|
||||||
|
heap_caps_free(temp_transfer_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
ESP_LOGI(TAG, "transfer_spi_data: completed sending %zu bytes of data", length);
|
ESP_LOGI(TAG, "transfer_spi_data: completed sending %zu bytes of data", length);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public:
|
|||||||
esp_err_t epd_write_cmd(const uint8_t cmd, uint32_t transaction_id);
|
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_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 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);
|
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;
|
bool is_busy(void) const;
|
||||||
void wait_for_idle(void) const;
|
void wait_for_idle(void) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user