Commit fce86c0f authored by Bodmer's avatar Bodmer

Improve RPi Pico (RP2040) rendering performance

parent 356095bd
...@@ -220,22 +220,10 @@ void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){ ...@@ -220,22 +220,10 @@ void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
** Description: Write a block of pixels of the same colour ** Description: Write a block of pixels of the same colour
***************************************************************************************/ ***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){ void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
while(len--)
bool loaded = false; {
uint16_t colorBuf[64]; while (!spi_is_writable(spi0)){};
const uint16_t* colorPtr = colorBuf; spi_get_hw(spi0)->dr = (uint32_t)color;
if (len>63) {
loaded = true;
for (uint32_t i = 0; i < 64; i++) colorBuf[i] = color;
while(len>63) {
spi_write16_blocking(spi0, (const uint16_t*)colorPtr, 64);
len -=64;
}
}
if (len) {
if (!loaded) for (uint32_t i = 0; i < len; i++) colorBuf[i] = color;
spi_write16_blocking(spi0, (const uint16_t*)colorPtr, len);
} }
} }
...@@ -244,14 +232,23 @@ void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){ ...@@ -244,14 +232,23 @@ void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
** Description: Write a sequence of pixels ** Description: Write a sequence of pixels
***************************************************************************************/ ***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){ void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
if (_swapBytes) { if (_swapBytes) {
spi_write16_blocking(spi0, (const uint16_t*)data_in, len); while(len--)
{
while (!spi_is_writable(spi0)){};
spi_get_hw(spi0)->dr = (uint32_t)(*data++);
}
} }
else { else
spi_set_format(spi0, 8, (spi_cpol_t)0, (spi_cpha_t)0, SPI_MSB_FIRST); {
spi_write_blocking(spi0, (const uint8_t*)data_in, len * 2); while(len--)
spi_set_format(spi0, 16, (spi_cpol_t)0, (spi_cpha_t)0, SPI_MSB_FIRST); {
uint16_t color = *data++;
color = color >> 8 | color << 8;
while (!spi_is_writable(spi0)){};
spi_get_hw(spi0)->dr = (uint32_t)color;
}
} }
} }
......
...@@ -14,13 +14,17 @@ ...@@ -14,13 +14,17 @@
// Include processor specific header // Include processor specific header
// None // None
// Processor specific code used by SPI bus transaction startWrite and endWrite functions // Processor specific code used by SPI bus transaction begin/end_tft_write functions
#define SET_BUS_WRITE_MODE // Not used #define SET_BUS_WRITE_MODE spi_set_format(spi0, 16, (spi_cpol_t)0, (spi_cpha_t)0, SPI_MSB_FIRST)
#define SET_BUS_READ_MODE // Not used #define SET_BUS_READ_MODE // spi_set_format(spi0, 8, (spi_cpol_t)0, (spi_cpha_t)0, SPI_MSB_FIRST)
// Code to check if SPI or DMA is busy, used by SPI bus transaction startWrite and/or endWrite functions // Code to check if SPI or DMA is busy, used by SPI bus transaction startWrite and/or endWrite functions
#define DMA_BUSY_CHECK // Not used so leave blank #define DMA_BUSY_CHECK // Not used so leave blank
#define SPI_BUSY_CHECK // Not used so leave blank
// Wait for tx to end, flush rx FIFO, clear rx overrun
#define SPI_BUSY_CHECK while (spi_get_hw(spi0)->sr & SPI_SSPSR_BSY_BITS) {}; \
while (spi_is_readable(spi0)) (void)spi_get_hw(spi0)->dr; \
spi_get_hw(spi0)->icr = SPI_SSPICR_RORIC_BITS
// To be safe, SUPPORT_TRANSACTIONS is assumed mandatory // To be safe, SUPPORT_TRANSACTIONS is assumed mandatory
#if !defined (SUPPORT_TRANSACTIONS) #if !defined (SUPPORT_TRANSACTIONS)
...@@ -28,7 +32,7 @@ ...@@ -28,7 +32,7 @@
#endif #endif
// Initialise processor specific SPI functions, used by init() // Initialise processor specific SPI functions, used by init()
#define INIT_TFT_DATA_BUS #define INIT_TFT_DATA_BUS // Not used
// If smooth fonts are enabled the filing system may need to be loaded // If smooth fonts are enabled the filing system may need to be loaded
#ifdef SMOOTH_FONT #ifdef SMOOTH_FONT
...@@ -150,18 +154,27 @@ ...@@ -150,18 +154,27 @@
spi.transfer(0); spi.transfer((C)>>0) spi.transfer(0); spi.transfer((C)>>0)
#else #else
#define tft_Write_8(C) spi_set_format(spi0, 8, (spi_cpol_t)0, (spi_cpha_t)0, SPI_MSB_FIRST); \
_Cbuf = (C); spi_write_blocking(spi0, (const uint8_t*)&(_Cbuf), 1); \
spi_set_format(spi0, 16, (spi_cpol_t)0, (spi_cpha_t)0, SPI_MSB_FIRST)
#define tft_Write_16(C) _Cbuf = (C); spi_write16_blocking(spi0, (const uint16_t*)&(_Cbuf), 1)
#define tft_Write_16N(C) _Cbuf = (C); spi_write16_blocking(spi0, (const uint16_t*)&(_Cbuf), 1)
#define tft_Write_16S(C) _Cbuf = (C)<<8 | (C)>>8; spi_write16_blocking(spi0, (const uint16_t*)&(_Cbuf), 1)
#define tft_Write_32(C) _Cbuf = (C); spi_write16_blocking(spi0, (const uint16_t*)&(_Cbuf), 2) // This swaps to 8 bit mode, then back to 16 bit mode
#define tft_Write_8(C) while (spi_get_hw(spi0)->sr & SPI_SSPSR_BSY_BITS) {}; \
spi_set_format(spi0, 8, (spi_cpol_t)0, (spi_cpha_t)0, SPI_MSB_FIRST); \
spi_get_hw(spi0)->dr = (uint32_t)(C); \
while (spi_get_hw(spi0)->sr & SPI_SSPSR_BSY_BITS) {}; \
spi_set_format(spi0, 16, (spi_cpol_t)0, (spi_cpha_t)0, SPI_MSB_FIRST)
// Note: the following macros do not wait for the end of transmission
#define tft_Write_16(C) while (!spi_is_writable(spi0)){}; spi_get_hw(spi0)->dr = (uint32_t)(C)
#define tft_Write_16N(C) while (!spi_is_writable(spi0)){}; spi_get_hw(spi0)->dr = (uint32_t)(C)
#define tft_Write_16S(C) while (!spi_is_writable(spi0)){}; spi_get_hw(spi0)->dr = (uint32_t)(C)<<8 | (C)>>8
#define tft_Write_32(C) while (!spi_is_writable(spi0)){}; spi_get_hw(spi0)->dr = (uint32_t)((C)>>8);spi_get_hw(spi0)->dr = (uint32_t)(C)
#define tft_Write_32C(C,D) _Cbuf = (C) | (D) << 16; spi_write16_blocking(spi0, (const uint16_t*)&(_Cbuf), 2) #define tft_Write_32C(C,D) while (!spi_is_writable(spi0)){}; spi_get_hw(spi0)->dr = (uint32_t)(C);spi_get_hw(spi0)->dr = (uint32_t)(D)
#define tft_Write_32D(C) _Cbuf = (C) | (C) << 16; spi_write16_blocking(spi0, (const uint16_t*)&(_Cbuf), 2) #define tft_Write_32D(C) while (!spi_is_writable(spi0)){}; spi_get_hw(spi0)->dr = (uint32_t)(C);spi_get_hw(spi0)->dr = (uint32_t)(C)
#endif // RPI_DISPLAY_TYPE #endif // RPI_DISPLAY_TYPE
#endif #endif
......
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Arduino TFT graphics library targeted at ESP8266 Arduino TFT graphics library targeted at ESP8266
and ESP32 based boards. and ESP32 based boards.
This is a standalone library that contains the This is a stand-alone library that contains the
hardware driver, the graphics functions and the hardware driver, the graphics functions and the
proportional fonts. proportional fonts.
...@@ -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.3.62" #define TFT_ESPI_VERSION "2.3.63"
// Bit level feature flags // Bit level feature flags
// Bit 0 set: viewport capability // Bit 0 set: viewport capability
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
#include "Processors/TFT_eSPI_ESP8266.h" #include "Processors/TFT_eSPI_ESP8266.h"
#elif defined (STM32) #elif defined (STM32)
#include "Processors/TFT_eSPI_STM32.h" #include "Processors/TFT_eSPI_STM32.h"
#elif defined (RP2040) #elif defined(ARDUINO_ARCH_RP2040)
#include "Processors/TFT_eSPI_RP2040.h" #include "Processors/TFT_eSPI_RP2040.h"
#else #else
#include "Processors/TFT_eSPI_Generic.h" #include "Processors/TFT_eSPI_Generic.h"
...@@ -690,13 +690,13 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac ...@@ -690,13 +690,13 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// New begin and end prototypes // New begin and end prototypes
// begin/end a TFT write transaction // begin/end a TFT write transaction
// For SPI bus the transmit clock rate is set // For SPI bus the transmit clock rate is set
inline void begin_tft_write() __attribute__((always_inline)); inline void begin_tft_write() __attribute__((always_inline));
inline void end_tft_write() __attribute__((always_inline)); inline void end_tft_write() __attribute__((always_inline));
// begin/end a TFT read transaction // begin/end a TFT read transaction
// For SPI bus: begin lowers SPI clock rate, end reinstates transmit clock rate // For SPI bus: begin lowers SPI clock rate, end reinstates transmit clock rate
inline void begin_tft_read() __attribute__((always_inline)); inline void begin_tft_read() __attribute__((always_inline));
inline void end_tft_read() __attribute__((always_inline)); inline void end_tft_read() __attribute__((always_inline));
// Temporary library development function TODO: remove need for this // Temporary library development function TODO: remove need for this
void pushSwapBytePixels(const void* data_in, uint32_t len); void pushSwapBytePixels(const void* data_in, uint32_t len);
...@@ -765,7 +765,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac ...@@ -765,7 +765,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
bool isDigits; // adjust bounding box for numbers to reduce visual jiggling bool isDigits; // adjust bounding box for numbers to reduce visual jiggling
bool textwrapX, textwrapY; // If set, 'wrap' text at right and optionally bottom edge of display bool textwrapX, textwrapY; // If set, 'wrap' text at right and optionally bottom edge of display
bool _swapBytes; // Swap the byte order for TFT pushImage() bool _swapBytes; // Swap the byte order for TFT pushImage()
bool locked, inTransaction; // SPI transaction and mutex lock flags bool locked, inTransaction, lockTransaction; // SPI transaction and mutex lock flags
bool _booted; // init() or begin() has already run once bool _booted; // init() or begin() has already run once
...@@ -775,7 +775,6 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac ...@@ -775,7 +775,6 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
bool _psram_enable; // Enable PSRAM use for library functions (TBD) and Sprites bool _psram_enable; // Enable PSRAM use for library functions (TBD) and Sprites
uint32_t _lastColor; // Buffered value of last colour used uint32_t _lastColor; // Buffered value of last colour used
uint32_t _Cbuf; // SPI buffer for RP2040
#ifdef LOAD_GFXFF #ifdef LOAD_GFXFF
GFXfont *gfxFont; GFXfont *gfxFont;
......
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
// //
// ################################################################################## // ##################################################################################
// Define RP2040 to invoke optimised processor support (only for RP2040)
//#define RP2040
// Define STM32 to invoke optimised processor support (only for STM32) // Define STM32 to invoke optimised processor support (only for STM32)
//#define STM32 //#define STM32
......
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
// //
// ################################################################################## // ##################################################################################
// Define RP2040 to invoke optimised processor support (only for RP2040)
#define RP2040
// Tell the library to use 8 bit parallel mode (otherwise SPI is assumed) // Tell the library to use 8 bit parallel mode (otherwise SPI is assumed)
//#define TFT_PARALLEL_8_BIT //#define TFT_PARALLEL_8_BIT
...@@ -177,7 +174,7 @@ ...@@ -177,7 +174,7 @@
// #define SPI_FREQUENCY 10000000 // #define SPI_FREQUENCY 10000000
// #define SPI_FREQUENCY 20000000 // #define SPI_FREQUENCY 20000000
// #define SPI_FREQUENCY 32000000 // #define SPI_FREQUENCY 32000000
#define SPI_FREQUENCY 63000000 #define SPI_FREQUENCY 70000000
// Optional reduced SPI frequency for reading TFT // Optional reduced SPI frequency for reading TFT
#define SPI_READ_FREQUENCY 20000000 #define SPI_READ_FREQUENCY 20000000
...@@ -185,11 +182,3 @@ ...@@ -185,11 +182,3 @@
// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here: // The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
#define SPI_TOUCH_FREQUENCY 2500000 #define SPI_TOUCH_FREQUENCY 2500000
// Comment out the following #define if "SPI Transactions" do not need to be
// supported. When commented out the code size will be smaller and sketches will
// run slightly faster, so leave it commented out unless you need it!
// Transaction support is needed to work with SD library but not needed with TFT_SdFat
// Transaction support is required if other SPI devices are connected.
// #define SUPPORT_TRANSACTIONS
// Walking 1 write and read pixel test
#include <TFT_eSPI.h>
#include <SPI.h>
#define TDELAY 500
TFT_eSPI tft = TFT_eSPI();
void setup() {
Serial.begin(115200);
tft.init();
tft.fillScreen(0xF81F);
}
void loop() {
static uint32_t wr = 1;
static uint32_t rd = 0xFFFFFFFF;
delay(TDELAY);
tft.drawPixel(30,30,wr);
Serial.print(" Pixel value written = ");Serial.println(wr,HEX);
rd = tft.readPixel(30,30);
Serial.print(" Pixel value read = ");Serial.println(rd,HEX);
if (rd!=wr) {
Serial.println(" ERROR ^^^^");
//while(1) yield();
}
else Serial.println(" PASS ");
// Walking 1 test
wr = wr<<1;
if (wr >= 0x10000) wr = 1;
}
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