Commit cc4f35f8 authored by Bodmer's avatar Bodmer

ESP32 DMA update

dmaBusy() checks and is no longer blocking
pushImageDMA() faster if setAddrWindow is not built into transaction list.
parent fc8d912f
...@@ -494,23 +494,30 @@ void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){ ...@@ -494,23 +494,30 @@ void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
/*************************************************************************************** /***************************************************************************************
** Function name: dmaBusy ** Function name: dmaBusy
** Description: Check if DMA is busy (currently blocking!) ** Description: Check if DMA is busy
***************************************************************************************/ ***************************************************************************************/
bool TFT_eSPI::dmaBusy(void) bool TFT_eSPI::dmaBusy(void)
{ {
if (!DMA_Enabled || !spiBusyCheck) return false; if (!DMA_Enabled || !spiBusyCheck) return false;
//spi_transaction_t rtrans;
//bool trans_result=spi_device_polling_transmit(dmaHAL, &rtrans); spi_transaction_t *rtrans;
//return trans_result; esp_err_t ret;
// This works but blocks uint8_t checks = spiBusyCheck;
dmaWait(); for (int i = 0; i < checks; ++i)
return false; {
ret = spi_device_get_trans_result(dmaHAL, &rtrans, 0);
if (ret == ESP_OK) spiBusyCheck--;
}
//Serial.print("spiBusyCheck=");Serial.println(spiBusyCheck);
if (spiBusyCheck ==0) return false;
return true;
} }
/*************************************************************************************** /***************************************************************************************
** Function name: dmaWait ** Function name: dmaWait
** Description: Check if DMA is busy (blocking!) ** Description: Wait until DMA is over (blocking!)
***************************************************************************************/ ***************************************************************************************/
void TFT_eSPI::dmaWait(void) void TFT_eSPI::dmaWait(void)
{ {
...@@ -535,6 +542,11 @@ void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len) ...@@ -535,6 +542,11 @@ void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len)
{ {
if ((len == 0) || (!DMA_Enabled)) return; if ((len == 0) || (!DMA_Enabled)) return;
dmaWait(); dmaWait();
if(_swapBytes) {
for (uint32_t i = 0; i < len; i++) (image[i] = image[i] << 8 | image[i] >> 8);
}
esp_err_t ret; esp_err_t ret;
static spi_transaction_t trans; static spi_transaction_t trans;
...@@ -548,7 +560,7 @@ void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len) ...@@ -548,7 +560,7 @@ void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len)
ret = spi_device_queue_trans(dmaHAL, &trans, portMAX_DELAY); ret = spi_device_queue_trans(dmaHAL, &trans, portMAX_DELAY);
assert(ret == ESP_OK); assert(ret == ESP_OK);
spiBusyCheck = 1; spiBusyCheck++;
} }
...@@ -574,11 +586,9 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t ...@@ -574,11 +586,9 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
if (dw < 1 || dh < 1) return; if (dw < 1 || dh < 1) return;
if (buffer == nullptr) buffer = image;
uint32_t len = dw*dh; uint32_t len = dw*dh;
dmaWait(); if (buffer == nullptr) { buffer = image; dmaWait(); }
// If image is clipped, copy pixels into a contiguous block // If image is clipped, copy pixels into a contiguous block
if ( (dw != w) || (dh != h) ) { if ( (dw != w) || (dh != h) ) {
...@@ -606,43 +616,24 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t ...@@ -606,43 +616,24 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
} }
} }
if (spiBusyCheck) dmaWait(); // Incase we did not wait earlier
setAddrWindow(x, y, dw, dh);
esp_err_t ret; esp_err_t ret;
static spi_transaction_t trans[6]; static spi_transaction_t trans;
for (int i = 0; i < 6; i++)
{ memset(&trans, 0, sizeof(spi_transaction_t));
memset(&trans[i], 0, sizeof(spi_transaction_t));
if ((i & 1) == 0) trans.user = (void *)1;
{ trans.tx_buffer = buffer; //finally send the line data
trans[i].length = 8; trans.length = len * 16; //Data length, in bits
trans[i].user = (void *)0; trans.flags = 0; //SPI_TRANS_USE_TXDATA flag
}
else ret = spi_device_queue_trans(dmaHAL, &trans, portMAX_DELAY);
{
trans[i].length = 8 * 4;
trans[i].user = (void *)1;
}
trans[i].flags = SPI_TRANS_USE_TXDATA;
}
trans[0].tx_data[0] = 0x2A; //Column Address Set
trans[1].tx_data[0] = x >> 8; //Start Col High
trans[1].tx_data[1] = x & 0xFF; //Start Col Low
trans[1].tx_data[2] = (x + dw - 1) >> 8; //End Col High
trans[1].tx_data[3] = (x + dw - 1) & 0xFF; //End Col Low
trans[2].tx_data[0] = 0x2B; //Page address set
trans[3].tx_data[0] = y >> 8; //Start page high
trans[3].tx_data[1] = y & 0xFF; //start page low
trans[3].tx_data[2] = (y + dh - 1) >> 8; //end page high
trans[3].tx_data[3] = (y + dh - 1) & 0xFF; //end page low
trans[4].tx_data[0] = 0x2C; //memory write
trans[5].tx_buffer = buffer; //finally send the line data
trans[5].length = dw * 2 * 8 * dh; //Data length, in bits
trans[5].flags = 0; //undo SPI_TRANS_USE_TXDATA flag
for (int i = 0; i < 6; i++)
{
ret = spi_device_queue_trans(dmaHAL, &trans[i], portMAX_DELAY);
assert(ret == ESP_OK); assert(ret == ESP_OK);
}
spiBusyCheck = 6; spiBusyCheck++;
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
......
...@@ -307,7 +307,7 @@ ...@@ -307,7 +307,7 @@
// Code to check if DMA is busy, used by SPI bus transaction transaction and endWrite functions // Code to check if DMA is busy, used by SPI bus transaction transaction and endWrite functions
#ifdef ESP32_DMA #ifdef ESP32_DMA
// Code to check if DMA is busy, used by SPI DMA + transaction + endWrite functions // Code to check if DMA is busy, used by SPI DMA + transaction + endWrite functions
#define DMA_BUSY_CHECK { if (DMA_Enabled) dmaWait(); } #define DMA_BUSY_CHECK { if (spiBusyCheck) dmaWait(); }
#else #else
#define DMA_BUSY_CHECK #define DMA_BUSY_CHECK
#endif #endif
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#ifndef _TFT_eSPIH_ #ifndef _TFT_eSPIH_
#define _TFT_eSPIH_ #define _TFT_eSPIH_
#define TFT_ESPI_VERSION "2.2.4" #define TFT_ESPI_VERSION "2.2.5"
/*************************************************************************************** /***************************************************************************************
** Section 1: Load required header files ** Section 1: Load required header files
......
{ {
"name": "TFT_eSPI", "name": "TFT_eSPI",
"version": "2.2.4", "version": "2.2.5",
"keywords": "Arduino, tft, ePaper, display, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140", "keywords": "Arduino, tft, ePaper, display, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140",
"description": "A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32", "description": "A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32",
"repository": "repository":
......
name=TFT_eSPI name=TFT_eSPI
version=2.2.4 version=2.2.5
author=Bodmer author=Bodmer
maintainer=Bodmer maintainer=Bodmer
sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32 sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment