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){
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
bool loaded = false;
uint16_t colorBuf[64];
const uint16_t* colorPtr = colorBuf;
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);
while(len--)
{
while (!spi_is_writable(spi0)){};
spi_get_hw(spi0)->dr = (uint32_t)color;
}
}
......@@ -244,14 +232,23 @@ void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
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 {
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);
spi_set_format(spi0, 16, (spi_cpol_t)0, (spi_cpha_t)0, SPI_MSB_FIRST);
else
{
while(len--)
{
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 @@
// Include processor specific header
// None
// Processor specific code used by SPI bus transaction startWrite and endWrite functions
#define SET_BUS_WRITE_MODE // Not used
#define SET_BUS_READ_MODE // Not used
// Processor specific code used by SPI bus transaction begin/end_tft_write functions
#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 // 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
#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
#if !defined (SUPPORT_TRANSACTIONS)
......@@ -28,7 +32,7 @@
#endif
// 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
#ifdef SMOOTH_FONT
......@@ -150,18 +154,27 @@
spi.transfer(0); spi.transfer((C)>>0)
#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
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
Arduino TFT graphics library targeted at ESP8266
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
proportional fonts.
......@@ -16,7 +16,7 @@
#ifndef _TFT_eSPIH_
#define _TFT_eSPIH_
#define TFT_ESPI_VERSION "2.3.62"
#define TFT_ESPI_VERSION "2.3.63"
// Bit level feature flags
// Bit 0 set: viewport capability
......@@ -54,7 +54,7 @@
#include "Processors/TFT_eSPI_ESP8266.h"
#elif defined (STM32)
#include "Processors/TFT_eSPI_STM32.h"
#elif defined (RP2040)
#elif defined(ARDUINO_ARCH_RP2040)
#include "Processors/TFT_eSPI_RP2040.h"
#else
#include "Processors/TFT_eSPI_Generic.h"
......@@ -690,13 +690,13 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// New begin and end prototypes
// begin/end a TFT write transaction
// For SPI bus the transmit clock rate is set
inline void begin_tft_write() __attribute__((always_inline));
inline void end_tft_write() __attribute__((always_inline));
inline void begin_tft_write() __attribute__((always_inline));
inline void end_tft_write() __attribute__((always_inline));
// begin/end a TFT read transaction
// For SPI bus: begin lowers SPI clock rate, end reinstates transmit clock rate
inline void begin_tft_read() __attribute__((always_inline));
inline void end_tft_read() __attribute__((always_inline));
inline void begin_tft_read() __attribute__((always_inline));
inline void end_tft_read() __attribute__((always_inline));
// Temporary library development function TODO: remove need for this
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
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 _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
......@@ -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
uint32_t _lastColor; // Buffered value of last colour used
uint32_t _Cbuf; // SPI buffer for RP2040
#ifdef LOAD_GFXFF
GFXfont *gfxFont;
......
......@@ -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
......
......@@ -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)
//#define TFT_PARALLEL_8_BIT
......@@ -177,7 +174,7 @@
// #define SPI_FREQUENCY 10000000
// #define SPI_FREQUENCY 20000000
// #define SPI_FREQUENCY 32000000
#define SPI_FREQUENCY 63000000
#define SPI_FREQUENCY 70000000
// Optional reduced SPI frequency for reading TFT
#define SPI_READ_FREQUENCY 20000000
......@@ -185,11 +182,3 @@
// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
#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