Add support for Raspberry Pi Pico
Setup file "Setup60_RP2040_ILI9341.h" used for testing with ILI9341 SPI display.
This commit is contained in:
1 parent
1c36c2c933
commit
f6e90349d8
10 files changed
+789
-77
No files matched your search
@@ -0,0 +1,278 @@
|
||||
////////////////////////////////////////////////////
|
||||
// TFT_eSPI generic driver functions //
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Global variables
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Select the SPI port to use
|
||||
SPIClass& spi = SPI;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if defined (TFT_SDA_READ) && !defined (TFT_PARALLEL_8_BIT)
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: tft_Read_8
|
||||
** Description: Bit bashed SPI to read bidirectional SDA line
|
||||
***************************************************************************************/
|
||||
uint8_t TFT_eSPI::tft_Read_8(void)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++) { // read results
|
||||
ret <<= 1;
|
||||
SCLK_L;
|
||||
if (digitalRead(TFT_MOSI)) ret |= 1;
|
||||
SCLK_H;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: beginSDA
|
||||
** Description: Detach SPI from pin to permit software SPI
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::begin_SDA_Read(void)
|
||||
{
|
||||
// Release configured SPI port for SDA read
|
||||
spi.end();
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: endSDA
|
||||
** Description: Attach SPI pins after software SPI
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::end_SDA_Read(void)
|
||||
{
|
||||
// Configure SPI port ready for next TFT access
|
||||
spi.begin();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif // #if defined (TFT_SDA_READ)
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if defined (TFT_PARALLEL_8_BIT) // Code for generic (i.e. any) processor
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: pushBlock - for generic processor and parallel display
|
||||
** Description: Write a block of pixels of the same colour
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
|
||||
|
||||
while (len>1) {tft_Write_32D(color); len-=2;}
|
||||
if (len) {tft_Write_16(color);}
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: pushPixels - for gereric processor and parallel display
|
||||
** 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) {
|
||||
while (len>1) {tft_Write_16(*data); data++; tft_Write_16(*data); data++; len -=2;}
|
||||
if (len) {tft_Write_16(*data);}
|
||||
return;
|
||||
}
|
||||
|
||||
while (len>1) {tft_Write_16S(*data); data++; tft_Write_16S(*data); data++; len -=2;}
|
||||
if (len) {tft_Write_16S(*data);}
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: GPIO direction control - supports class functions
|
||||
** Description: Set parallel bus to INPUT or OUTPUT
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::busDir(uint32_t mask, uint8_t mode)
|
||||
{
|
||||
// mask is unused for generic processor
|
||||
// Arduino native functions suited well to a generic driver
|
||||
pinMode(TFT_D0, mode);
|
||||
pinMode(TFT_D1, mode);
|
||||
pinMode(TFT_D2, mode);
|
||||
pinMode(TFT_D3, mode);
|
||||
pinMode(TFT_D4, mode);
|
||||
pinMode(TFT_D5, mode);
|
||||
pinMode(TFT_D6, mode);
|
||||
pinMode(TFT_D7, mode);
|
||||
return;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: GPIO direction control - supports class functions
|
||||
** Description: Faster GPIO pin input/output switch
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::gpioMode(uint8_t gpio, uint8_t mode)
|
||||
{
|
||||
// No fast port based generic approach available
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: read byte - supports class functions
|
||||
** Description: Read a byte - parallel bus only
|
||||
***************************************************************************************/
|
||||
uint8_t TFT_eSPI::readByte(void)
|
||||
{
|
||||
uint8_t b = 0;
|
||||
|
||||
busDir(0, INPUT);
|
||||
digitalWrite(TFT_RD, LOW);
|
||||
|
||||
b |= digitalRead(TFT_D0) << 0;
|
||||
b |= digitalRead(TFT_D1) << 1;
|
||||
b |= digitalRead(TFT_D2) << 2;
|
||||
b |= digitalRead(TFT_D3) << 3;
|
||||
b |= digitalRead(TFT_D4) << 4;
|
||||
b |= digitalRead(TFT_D5) << 5;
|
||||
b |= digitalRead(TFT_D6) << 6;
|
||||
b |= digitalRead(TFT_D7) << 7;
|
||||
|
||||
digitalWrite(TFT_RD, HIGH);
|
||||
busDir(0, OUTPUT);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#elif defined (RPI_WRITE_STROBE) // For RPi TFT with write strobe
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: pushBlock - for ESP32 or RP2040 RPi TFT
|
||||
** Description: Write a block of pixels of the same colour
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
|
||||
|
||||
if(len) { tft_Write_16(color); len--; }
|
||||
while(len--) {WR_L; WR_H;}
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: pushPixels - for ESP32 or RP2040 RPi TFT
|
||||
** 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) while ( len-- ) {tft_Write_16S(*data); data++;}
|
||||
else while ( len-- ) {tft_Write_16(*data); data++;}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#elif defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: pushBlock - for RP2040 and 3 byte RGB display
|
||||
** Description: Write a block of pixels of the same colour
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
|
||||
{
|
||||
// Split out the colours
|
||||
uint8_t r = (color & 0xF800)>>8;
|
||||
uint8_t g = (color & 0x07E0)>>3;
|
||||
uint8_t b = (color & 0x001F)<<3;
|
||||
|
||||
while ( len-- ) {tft_Write_8(r); tft_Write_8(g); tft_Write_8(b);}
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: pushPixels - for RP2040 and 3 byte RGB display
|
||||
** 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) {
|
||||
while ( len-- ) {
|
||||
uint16_t color = *data >> 8 | *data << 8;
|
||||
tft_Write_8((color & 0xF800)>>8);
|
||||
tft_Write_8((color & 0x07E0)>>3);
|
||||
tft_Write_8((color & 0x001F)<<3);
|
||||
data++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while ( len-- ) {
|
||||
tft_Write_8((*data & 0xF800)>>8);
|
||||
tft_Write_8((*data & 0x07E0)>>3);
|
||||
tft_Write_8((*data & 0x001F)<<3);
|
||||
data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#else // Standard SPI 16 bit colour TFT
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: pushBlock - for RP2040
|
||||
** 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);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: pushPixels - for RP2040
|
||||
** Description: Write a sequence of pixels
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
|
||||
|
||||
if (_swapBytes) {
|
||||
spi_write16_blocking(spi0, (const uint16_t*)data_in, len);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif // End of display interface specific functions
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DMA FUNCTIONS
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Placeholder for DMA functions
|
||||
|
||||
/*
|
||||
Minimal function set to support DMA:
|
||||
|
||||
bool TFT_eSPI::initDMA(void)
|
||||
void TFT_eSPI::deInitDMA(void)
|
||||
bool TFT_eSPI::dmaBusy(void)
|
||||
void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len)
|
||||
void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t* image)
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,183 @@
|
||||
////////////////////////////////////////////////////
|
||||
// TFT_eSPI generic driver functions //
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
// This is a generic driver for Arduino boards, it supports SPI interface displays
|
||||
// 8 bit parallel interface to TFT is not supported for generic processors
|
||||
|
||||
#ifndef _TFT_eSPI_RP2040H_
|
||||
#define _TFT_eSPI_RP2040H_
|
||||
|
||||
// Processor ID reported by getSetup()
|
||||
#define PROCESSOR_ID 0x0000
|
||||
|
||||
// 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
|
||||
|
||||
// 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
|
||||
|
||||
// To be safe, SUPPORT_TRANSACTIONS is assumed mandatory
|
||||
#if !defined (SUPPORT_TRANSACTIONS)
|
||||
#define SUPPORT_TRANSACTIONS
|
||||
#endif
|
||||
|
||||
// Initialise processor specific SPI functions, used by init()
|
||||
#define INIT_TFT_DATA_BUS
|
||||
|
||||
// If smooth fonts are enabled the filing system may need to be loaded
|
||||
#ifdef SMOOTH_FONT
|
||||
// Call up the filing system for the anti-aliased fonts
|
||||
//#define FS_NO_GLOBALS
|
||||
//#include <FS.h>
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Define the DC (TFT Data/Command or Register Select (RS))pin drive code
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef TFT_DC
|
||||
#define DC_C // No macro allocated so it generates no code
|
||||
#define DC_D // No macro allocated so it generates no code
|
||||
#else
|
||||
#define DC_C sio_hw->gpio_clr = (1ul << TFT_DC)
|
||||
#define DC_D sio_hw->gpio_set = (1ul << TFT_DC)
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Define the CS (TFT chip select) pin drive code
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef TFT_CS
|
||||
#define CS_L // No macro allocated so it generates no code
|
||||
#define CS_H // No macro allocated so it generates no code
|
||||
#else
|
||||
#define CS_L sio_hw->gpio_clr = (1ul << TFT_CS)
|
||||
#define CS_H sio_hw->gpio_set = (1ul << TFT_CS)
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Make sure TFT_RD is defined if not used to avoid an error message
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef TFT_RD
|
||||
#define TFT_RD -1
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Define the WR (TFT Write) pin drive code
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef TFT_WR
|
||||
#define WR_L digitalWrite(TFT_WR, LOW)
|
||||
#define WR_H digitalWrite(TFT_WR, HIGH)
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Define the touch screen chip select pin drive code
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined TOUCH_CS || (TOUCH_CS < 0)
|
||||
#define T_CS_L // No macro allocated so it generates no code
|
||||
#define T_CS_H // No macro allocated so it generates no code
|
||||
#else
|
||||
#define T_CS_L digitalWrite(TOUCH_CS, LOW)
|
||||
#define T_CS_H digitalWrite(TOUCH_CS, HIGH)
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Make sure TFT_MISO is defined if not used to avoid an error message
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef TFT_MISO
|
||||
#define TFT_MISO -1
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Macros to write commands/pixel colour data to a SPI ILI948x TFT
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
|
||||
|
||||
// Write 8 bits to TFT
|
||||
#define tft_Write_8(C) spi.transfer(C)
|
||||
|
||||
// Convert 16 bit colour to 18 bit and write in 3 bytes
|
||||
#define tft_Write_16(C) spi.transfer(((C) & 0xF800)>>8); \
|
||||
spi.transfer(((C) & 0x07E0)>>3); \
|
||||
spi.transfer(((C) & 0x001F)<<3)
|
||||
|
||||
// Convert 16 bit colour to 18 bit and write in 3 bytes
|
||||
#define tft_Write_16N(C) spi.transfer(((C) & 0xF800)>>8); \
|
||||
spi.transfer(((C) & 0x07E0)>>3); \
|
||||
spi.transfer(((C) & 0x001F)<<3)
|
||||
|
||||
// Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes
|
||||
#define tft_Write_16S(C) spi.transfer((C) & 0xF8); \
|
||||
spi.transfer(((C) & 0xE000)>>11 | ((C) & 0x07)<<5); \
|
||||
spi.transfer(((C) & 0x1F00)>>5)
|
||||
// Write 32 bits to TFT
|
||||
#define tft_Write_32(C) spi.transfer16((C)>>16); spi.transfer16((uint16_t)(C))
|
||||
|
||||
// Write two address coordinates
|
||||
#define tft_Write_32C(C,D) spi.transfer16(C); spi.transfer16(D)
|
||||
|
||||
// Write same value twice
|
||||
#define tft_Write_32D(C) spi.transfer16(C); spi.transfer16(C)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Macros to write commands/pixel colour data to other displays
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#else
|
||||
#if defined (RPI_DISPLAY_TYPE) // RPi TFT type always needs 16 bit transfers
|
||||
#define tft_Write_8(C) spi.transfer(C); spi.transfer(C)
|
||||
#define tft_Write_16(C) spi.transfer((uint8_t)((C)>>8));spi.transfer((uint8_t)((C)>>0))
|
||||
#define tft_Write_16N(C) spi.transfer((uint8_t)((C)>>8));spi.transfer((uint8_t)((C)>>0))
|
||||
#define tft_Write_16S(C) spi.transfer((uint8_t)((C)>>0));spi.transfer((uint8_t)((C)>>8))
|
||||
|
||||
#define tft_Write_32(C) \
|
||||
tft_Write_16((uint16_t) ((C)>>16)); \
|
||||
tft_Write_16((uint16_t) ((C)>>0))
|
||||
|
||||
#define tft_Write_32C(C,D) \
|
||||
spi.transfer(0); spi.transfer((C)>>8); \
|
||||
spi.transfer(0); spi.transfer((C)>>0); \
|
||||
spi.transfer(0); spi.transfer((D)>>8); \
|
||||
spi.transfer(0); spi.transfer((D)>>0)
|
||||
|
||||
#define tft_Write_32D(C) \
|
||||
spi.transfer(0); spi.transfer((C)>>8); \
|
||||
spi.transfer(0); spi.transfer((C)>>0); \
|
||||
spi.transfer(0); spi.transfer((C)>>8); \
|
||||
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)
|
||||
|
||||
#define tft_Write_32C(C,D) _Cbuf = (C) | (D) << 16; spi_write16_blocking(spi0, (const uint16_t*)&(_Cbuf), 2)
|
||||
|
||||
#define tft_Write_32D(C) _Cbuf = (C) | (C) << 16; spi_write16_blocking(spi0, (const uint16_t*)&(_Cbuf), 2)
|
||||
|
||||
#endif // RPI_DISPLAY_TYPE
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Macros to read from display using SPI or software SPI
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if defined (TFT_SDA_READ)
|
||||
// Use a bit banged function call for STM32 and bi-directional SDA pin
|
||||
#define TFT_eSPI_ENABLE_8_BIT_READ // Enable tft_Read_8(void);
|
||||
#define SCLK_L digitalWrite(TFT_SCLK, LOW)
|
||||
#define SCLK_H digitalWrite(TFT_SCLK, LOW)
|
||||
#else
|
||||
// Use a SPI read transfer
|
||||
#define tft_Read_8() spi.transfer(0)
|
||||
#endif
|
||||
|
||||
|
||||
#endif // Header end
|
||||
Reference in new issue
Block a user