mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2025-08-03 20:54:42 +02:00
Add DMA capability to ESP32 S3
DMA examples all tested and run as expected.
This commit is contained in:
@@ -43,11 +43,11 @@
|
||||
#endif
|
||||
#else
|
||||
#ifdef USE_HSPI_PORT
|
||||
#define DMA_CHANNEL 2
|
||||
spi_host_device_t spi_host = (spi_host_device_t) DMA_CHANNEL; // Draws once then freezes
|
||||
#define DMA_CHANNEL SPI_DMA_CH_AUTO
|
||||
spi_host_device_t spi_host = SPI3_HOST;
|
||||
#else // use FSPI port
|
||||
#define DMA_CHANNEL 1
|
||||
spi_host_device_t spi_host = (spi_host_device_t) DMA_CHANNEL; // Draws once then freezes
|
||||
#define DMA_CHANNEL SPI_DMA_CH_AUTO
|
||||
spi_host_device_t spi_host = SPI2_HOST;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
@@ -643,6 +643,15 @@ void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len)
|
||||
for (uint32_t i = 0; i < len; i++) (image[i] = image[i] << 8 | image[i] >> 8);
|
||||
}
|
||||
|
||||
// DMA byte count for transmit is 64Kbytes maximum, so to avoid this constraint
|
||||
// small transfers are performed using a blocking call until DMA capacity is reached.
|
||||
// User sketch can prevent blocking by managing pixel count and splitting into blocks
|
||||
// of 32768 pixels maximum. (equivalent to an area of ~320 x 100 pixels)
|
||||
while(len>0x4000) { // Transfer 16 bit pixels in blocks if len*2 over 65536 bytes
|
||||
pushPixels(image, 0x400);
|
||||
len -= 0x400; image+= 0x400; // Arbitrarily send 1K pixel blocks (2Kbytes)
|
||||
}
|
||||
|
||||
esp_err_t ret;
|
||||
static spi_transaction_t trans;
|
||||
|
||||
@@ -669,11 +678,20 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
|
||||
{
|
||||
if ((w == 0) || (h == 0) || (!DMA_Enabled)) return;
|
||||
|
||||
uint16_t *buffer = (uint16_t*)image;
|
||||
uint32_t len = w*h;
|
||||
|
||||
dmaWait();
|
||||
|
||||
setAddrWindow(x, y, w, h);
|
||||
// DMA byte count for transmit is 64Kbytes maximum, so to avoid this constraint
|
||||
// small transfers are performed using a blocking call until DMA capacity is reached.
|
||||
// User sketch can prevent blocking by managing pixel count and splitting into blocks
|
||||
// of 32768 pixels maximum. (equivalent to an area of ~320 x 100 pixels)
|
||||
while(len>0x4000) { // Transfer 16 bit pixels in blocks if len*2 over 65536 bytes
|
||||
pushPixels(buffer, 0x400);
|
||||
len -= 0x400; buffer+= 0x400; // Arbitrarily send 1K pixel blocks (2Kbytes)
|
||||
}
|
||||
|
||||
esp_err_t ret;
|
||||
static spi_transaction_t trans;
|
||||
@@ -681,7 +699,7 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
|
||||
memset(&trans, 0, sizeof(spi_transaction_t));
|
||||
|
||||
trans.user = (void *)1;
|
||||
trans.tx_buffer = image; //Data pointer
|
||||
trans.tx_buffer = buffer; //Data pointer
|
||||
trans.length = len * 16; //Data length, in bits
|
||||
trans.flags = 0; //SPI_TRANS_USE_TXDATA flag
|
||||
|
||||
@@ -751,6 +769,15 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
|
||||
|
||||
setAddrWindow(x, y, dw, dh);
|
||||
|
||||
// DMA byte count for transmit is 64Kbytes maximum, so to avoid this constraint
|
||||
// small transfers are performed using a blocking call until DMA capacity is reached.
|
||||
// User sketch can prevent blocking by managing pixel count and splitting into blocks
|
||||
// of 32768 pixels maximum. (equivalent to an area of ~320 x 100 pixels)
|
||||
while(len>0x4000) { // Transfer 16 bit pixels in blocks if len*2 over 65536 bytes
|
||||
pushPixels(buffer, 0x400);
|
||||
len -= 0x400; buffer+= 0x400; // Arbitrarily send 1K pixel blocks (2Kbytes)
|
||||
}
|
||||
|
||||
esp_err_t ret;
|
||||
static spi_transaction_t trans;
|
||||
|
||||
@@ -774,7 +801,7 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
|
||||
// The DMA functions here work with SPI only (not parallel)
|
||||
/***************************************************************************************
|
||||
** Function name: dc_callback
|
||||
** Description: Toggles DC line during transaction
|
||||
** Description: Toggles DC line during transaction (not used)
|
||||
***************************************************************************************/
|
||||
extern "C" void dc_callback();
|
||||
|
||||
@@ -784,6 +811,17 @@ void IRAM_ATTR dc_callback(spi_transaction_t *spi_tx)
|
||||
else {DC_C;}
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: dma_end_callback
|
||||
** Description: Clear DMA run flag to stop retransmission loop
|
||||
***************************************************************************************/
|
||||
extern "C" void dma_end_callback();
|
||||
|
||||
void IRAM_ATTR dma_end_callback(spi_transaction_t *spi_tx)
|
||||
{
|
||||
WRITE_PERI_REG(SPI_DMA_CONF_REG(spi_host), 0);
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: initDMA
|
||||
** Description: Initialise the DMA engine - returns true if init OK
|
||||
@@ -799,7 +837,7 @@ bool TFT_eSPI::initDMA(bool ctrl_cs)
|
||||
.sclk_io_num = TFT_SCLK,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
.max_transfer_sz = TFT_WIDTH * TFT_HEIGHT * 2 + 8, // TFT screen size
|
||||
.max_transfer_sz = 65536, // ESP32 S3 max size is 64Kbytes
|
||||
.flags = 0,
|
||||
.intr_flags = 0
|
||||
};
|
||||
@@ -819,9 +857,9 @@ bool TFT_eSPI::initDMA(bool ctrl_cs)
|
||||
.input_delay_ns = 0,
|
||||
.spics_io_num = pin,
|
||||
.flags = SPI_DEVICE_NO_DUMMY, //0,
|
||||
.queue_size = 1,
|
||||
.pre_cb = 0, //dc_callback, //Callback to handle D/C line
|
||||
.post_cb = 0
|
||||
.queue_size = 1, // Not using queues
|
||||
.pre_cb = 0, //dc_callback, //Callback to handle D/C line (not used)
|
||||
.post_cb = dma_end_callback //Callback to end transmission
|
||||
};
|
||||
ret = spi_bus_initialize(spi_host, &buscfg, DMA_CHANNEL);
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
@@ -134,7 +134,7 @@ SPI3_HOST = 2
|
||||
#if !defined(TFT_PARALLEL_8_BIT) && !defined(SPI_18BIT_DRIVER)
|
||||
#define ESP32_DMA
|
||||
// Code to check if DMA is busy, used by SPI DMA + transaction + endWrite functions
|
||||
#define DMA_BUSY_CHECK //dmaWait()
|
||||
#define DMA_BUSY_CHECK dmaWait()
|
||||
#else
|
||||
#define DMA_BUSY_CHECK
|
||||
#endif
|
||||
@@ -366,7 +366,7 @@ SPI3_HOST = 2
|
||||
#define PARALLEL_INIT_TFT_DATA_BUS \
|
||||
for (int32_t c = 0; c<256; c++) \
|
||||
{ \
|
||||
xset_mask[c] = 0; \
|
||||
xset_mask[c] = 0; \
|
||||
if ( c & 0x01 ) xset_mask[c] |= (1 << (TFT_D0-MASK_OFFSET)); \
|
||||
if ( c & 0x02 ) xset_mask[c] |= (1 << (TFT_D1-MASK_OFFSET)); \
|
||||
if ( c & 0x04 ) xset_mask[c] |= (1 << (TFT_D2-MASK_OFFSET)); \
|
||||
@@ -374,8 +374,8 @@ SPI3_HOST = 2
|
||||
if ( c & 0x10 ) xset_mask[c] |= (1 << (TFT_D4-MASK_OFFSET)); \
|
||||
if ( c & 0x20 ) xset_mask[c] |= (1 << (TFT_D5-MASK_OFFSET)); \
|
||||
if ( c & 0x40 ) xset_mask[c] |= (1 << (TFT_D6-MASK_OFFSET)); \
|
||||
if ( c & 0x80 ) xset_mask[c] |= (1 << (TFT_D7-MASK_OFFSET)); \
|
||||
} \
|
||||
if ( c & 0x80 ) xset_mask[c] |= (1 << (TFT_D7-MASK_OFFSET)); \
|
||||
} \
|
||||
|
||||
// Mask for the 8 data bits to set pin directions
|
||||
#define GPIO_DIR_MASK ((1 << (TFT_D0-MASK_OFFSET)) | (1 << (TFT_D1-MASK_OFFSET)) | (1 << (TFT_D2-MASK_OFFSET)) | (1 << (TFT_D3-MASK_OFFSET)) | (1 << (TFT_D4-MASK_OFFSET)) | (1 << (TFT_D5-MASK_OFFSET)) | (1 << (TFT_D6-MASK_OFFSET)) | (1 << (TFT_D7-MASK_OFFSET)))
|
||||
|
@@ -16,7 +16,7 @@
|
||||
#ifndef _TFT_eSPIH_
|
||||
#define _TFT_eSPIH_
|
||||
|
||||
#define TFT_ESPI_VERSION "2.5.1"
|
||||
#define TFT_ESPI_VERSION "2.5.2"
|
||||
|
||||
// Bit level feature flags
|
||||
// Bit 0 set: viewport capability
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "TFT_eSPI",
|
||||
"version": "2.5.1",
|
||||
"version": "2.5.2",
|
||||
"keywords": "Arduino, tft, display, ttgo, LilyPi, WT32-SC01, ePaper, display, Pico, RP2040 Nano Connect, RP2040, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9481, ILI9486, ILI9488, ST7789, ST7796, RM68140, SSD1351, SSD1963, ILI9225, HX8357D, GC9A01, R61581",
|
||||
"description": "A TFT and ePaper (SPI or parallel interface) graphics library with optimisation for Raspberry Pi Pico, RP2040, ESP8266, ESP32 and STM32 processors",
|
||||
"repository":
|
||||
|
@@ -1,5 +1,5 @@
|
||||
name=TFT_eSPI
|
||||
version=2.5.1
|
||||
version=2.5.2
|
||||
author=Bodmer
|
||||
maintainer=Bodmer
|
||||
sentence=TFT graphics library for Arduino processors with performance optimisation for RP2040, STM32, ESP8266 and ESP32
|
||||
|
Reference in New Issue
Block a user