mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2025-07-31 11:17:32 +02:00
RP2040 18bit PIO SPI update
Update RP2040 18bit PIO SPI code for 18 bit SPI displays (tested on ILI9488) Add ILI9342_DRIVER option for default landscape display.
This commit is contained in:
@ -21,8 +21,15 @@
|
|||||||
#else // PIO interface used (8 bit parallel or SPI)
|
#else // PIO interface used (8 bit parallel or SPI)
|
||||||
|
|
||||||
#ifdef RP2040_PIO_SPI
|
#ifdef RP2040_PIO_SPI
|
||||||
#include "pio_SPI.pio.h"
|
#if defined (SPI_18BIT_DRIVER)
|
||||||
|
// SPI PIO code for 18 bit colour transmit
|
||||||
|
#include "pio_SPI_18bit.pio.h"
|
||||||
#else
|
#else
|
||||||
|
// SPI PIO code for 16 bit colour transmit
|
||||||
|
#include "pio_SPI.pio.h"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// SPI PIO code for 8 bit parallel interface (16 bit colour)
|
||||||
#include "pio_8bit_parallel.pio.h"
|
#include "pio_8bit_parallel.pio.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -166,7 +173,7 @@ void pioinit(uint32_t clock_freq) {
|
|||||||
// The OSR register shifts to the left, sm designed to send MS byte of a colour first, autopull off
|
// The OSR register shifts to the left, sm designed to send MS byte of a colour first, autopull off
|
||||||
sm_config_set_out_shift(&c, false, false, 0);
|
sm_config_set_out_shift(&c, false, false, 0);
|
||||||
// Now load the configuration
|
// Now load the configuration
|
||||||
pio_sm_init(tft_pio, pio_sm, program_offset + tft_io_offset_start_16, &c);
|
pio_sm_init(tft_pio, pio_sm, program_offset + tft_io_offset_start_tx, &c);
|
||||||
|
|
||||||
// Start the state machine.
|
// Start the state machine.
|
||||||
pio_sm_set_enabled(tft_pio, pio_sm, true);
|
pio_sm_set_enabled(tft_pio, pio_sm, true);
|
||||||
@ -236,7 +243,7 @@ void pioinit(uint16_t clock_div, uint16_t fract_div) {
|
|||||||
// The OSR register shifts to the left, sm designed to send MS byte of a colour first
|
// The OSR register shifts to the left, sm designed to send MS byte of a colour first
|
||||||
sm_config_set_out_shift(&c, false, false, 0);
|
sm_config_set_out_shift(&c, false, false, 0);
|
||||||
// Now load the configuration
|
// Now load the configuration
|
||||||
pio_sm_init(tft_pio, pio_sm, program_offset + tft_io_offset_start_16, &c);
|
pio_sm_init(tft_pio, pio_sm, program_offset + tft_io_offset_start_tx, &c);
|
||||||
|
|
||||||
// Start the state machine.
|
// Start the state machine.
|
||||||
pio_sm_set_enabled(tft_pio, pio_sm, true);
|
pio_sm_set_enabled(tft_pio, pio_sm, true);
|
||||||
@ -263,6 +270,16 @@ void pioinit(uint16_t clock_div, uint16_t fract_div) {
|
|||||||
// PIO handles pixel block fill writes
|
// PIO handles pixel block fill writes
|
||||||
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
|
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
|
||||||
{
|
{
|
||||||
|
#if defined (SPI_18BIT_DRIVER)
|
||||||
|
uint32_t col = ((color & 0xF800)<<8) | ((color & 0x07E0)<<5) | ((color & 0x001F)<<3);
|
||||||
|
if (len) {
|
||||||
|
WAIT_FOR_STALL;
|
||||||
|
tft_pio->sm[pio_sm].instr = pio_instr_fill;
|
||||||
|
|
||||||
|
TX_FIFO = col;
|
||||||
|
TX_FIFO = --len; // Decrement first as PIO sends n+1
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (len) {
|
if (len) {
|
||||||
WAIT_FOR_STALL;
|
WAIT_FOR_STALL;
|
||||||
tft_pio->sm[pio_sm].instr = pio_instr_fill;
|
tft_pio->sm[pio_sm].instr = pio_instr_fill;
|
||||||
@ -270,6 +287,7 @@ void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
|
|||||||
TX_FIFO = color;
|
TX_FIFO = color;
|
||||||
TX_FIFO = --len; // Decrement first as PIO sends n+1
|
TX_FIFO = --len; // Decrement first as PIO sends n+1
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -300,7 +318,21 @@ 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){
|
||||||
|
#if defined (SPI_18BIT_DRIVER)
|
||||||
|
uint16_t *data = (uint16_t*)data_in;
|
||||||
|
if (_swapBytes) {
|
||||||
|
while ( len-- ) {
|
||||||
|
uint32_t col = *data++;
|
||||||
|
tft_Write_16(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while ( len-- ) {
|
||||||
|
uint32_t col = *data++;
|
||||||
|
tft_Write_16S(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
const uint16_t *data = (uint16_t*)data_in;
|
const uint16_t *data = (uint16_t*)data_in;
|
||||||
|
|
||||||
// PIO sends MS byte first, so bytes are already swapped on transmit
|
// PIO sends MS byte first, so bytes are already swapped on transmit
|
||||||
@ -341,6 +373,7 @@ void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
|
@ -335,7 +335,34 @@
|
|||||||
// Temporary - to be deleted
|
// Temporary - to be deleted
|
||||||
#define dir_mask 0
|
#define dir_mask 0
|
||||||
|
|
||||||
|
#if defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
|
||||||
|
// This writes 8 bits, then switches back to 16 bit mode automatically
|
||||||
|
// Have already waited for pio stalled (last data write complete) when DC switched to command mode
|
||||||
|
// The wait for stall allows DC to be changed immediately afterwards
|
||||||
|
#define tft_Write_8(C) tft_pio->sm[pio_sm].instr = pio_instr_jmp8; \
|
||||||
|
TX_FIFO = (C); \
|
||||||
|
WAIT_FOR_STALL
|
||||||
|
|
||||||
|
// Used to send last byte for 32 bit macros below since PIO sends 24 bits
|
||||||
|
#define tft_Write_8L(C) WAIT_FOR_STALL; \
|
||||||
|
tft_pio->sm[pio_sm].instr = pio_instr_jmp8; \
|
||||||
|
TX_FIFO = (C)
|
||||||
|
|
||||||
|
// Note: the following macros do not wait for the end of transmission
|
||||||
|
|
||||||
|
#define tft_Write_16(C) WAIT_FOR_FIFO_FREE(1); TX_FIFO = ((((uint32_t)(C) & 0xF800)<<8) | (((C) & 0x07E0)<<5) | (((C) & 0x001F)<<3))
|
||||||
|
|
||||||
|
#define tft_Write_16N(C) WAIT_FOR_FIFO_FREE(1); TX_FIFO = ((((uint32_t)(C) & 0xF800)<<8) | (((C) & 0x07E0)<<5) | (((C) & 0x001F)<<3))
|
||||||
|
|
||||||
|
#define tft_Write_16S(C) WAIT_FOR_FIFO_FREE(1); TX_FIFO = ((((uint32_t)(C) & 0xF8) << 16) | (((C) & 0xE000)>>3) | (((C) & 0x07)<<13) | (((C) & 0x1F00)>>5))
|
||||||
|
|
||||||
|
#define tft_Write_32(C) WAIT_FOR_FIFO_FREE(2); TX_FIFO = ((C)>>8); WAIT_FOR_STALL; tft_Write_8(C)
|
||||||
|
|
||||||
|
#define tft_Write_32C(C,D) WAIT_FOR_FIFO_FREE(2); TX_FIFO = (((C)<<8) | ((D)>>8)); tft_Write_8L(D)
|
||||||
|
|
||||||
|
#define tft_Write_32D(C) WAIT_FOR_FIFO_FREE(2); TX_FIFO = (((C)<<8) | ((C)>>8)); tft_Write_8L(C)
|
||||||
|
|
||||||
|
#else
|
||||||
// This writes 8 bits, then switches back to 16 bit mode automatically
|
// This writes 8 bits, then switches back to 16 bit mode automatically
|
||||||
// Have already waited for pio stalled (last data write complete) when DC switched to command mode
|
// Have already waited for pio stalled (last data write complete) when DC switched to command mode
|
||||||
// The wait for stall allows DC to be changed immediately afterwards
|
// The wait for stall allows DC to be changed immediately afterwards
|
||||||
@ -356,7 +383,7 @@
|
|||||||
#define tft_Write_32C(C,D) WAIT_FOR_FIFO_FREE(2); TX_FIFO = (C); TX_FIFO = (D)
|
#define tft_Write_32C(C,D) WAIT_FOR_FIFO_FREE(2); TX_FIFO = (C); TX_FIFO = (D)
|
||||||
|
|
||||||
#define tft_Write_32D(C) WAIT_FOR_FIFO_FREE(2); TX_FIFO = (C); TX_FIFO = (C)
|
#define tft_Write_32D(C) WAIT_FOR_FIFO_FREE(2); TX_FIFO = (C); TX_FIFO = (C)
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef tft_Write_16N
|
#ifndef tft_Write_16N
|
||||||
|
@ -38,7 +38,7 @@ next:
|
|||||||
|
|
||||||
.wrap_target
|
.wrap_target
|
||||||
// Transmit a 16 bit value (LS 16 bits of 32 bits).
|
// Transmit a 16 bit value (LS 16 bits of 32 bits).
|
||||||
public start_16:
|
public start_tx:
|
||||||
// Fetch the next 32 bit value from the TX FIFO and set TFT_WR high.
|
// Fetch the next 32 bit value from the TX FIFO and set TFT_WR high.
|
||||||
pull side 1
|
pull side 1
|
||||||
// Write the first byte (MSB) and set WR low. This also
|
// Write the first byte (MSB) and set WR low. This also
|
||||||
@ -49,7 +49,7 @@ public start_16:
|
|||||||
// Output the second byte and set TFT_WRITE low.
|
// Output the second byte and set TFT_WRITE low.
|
||||||
out pins, 8 side 0 [1]
|
out pins, 8 side 0 [1]
|
||||||
// Set WR high and jump back to start.
|
// Set WR high and jump back to start.
|
||||||
jmp start_16 side 1
|
jmp start_tx side 1
|
||||||
|
|
||||||
// Transmit an 8 bit value (LS 8 bits of 32 bits).
|
// Transmit an 8 bit value (LS 8 bits of 32 bits).
|
||||||
public start_8:
|
public start_8:
|
||||||
@ -59,7 +59,7 @@ public start_8:
|
|||||||
// shifts the unused top 24 bits through.
|
// shifts the unused top 24 bits through.
|
||||||
out pins, 32 side 0 [1]
|
out pins, 32 side 0 [1]
|
||||||
// Jump to start
|
// Jump to start
|
||||||
jmp start_16 side 1
|
jmp start_tx side 1
|
||||||
|
|
||||||
// Transmit a set window command sequence.
|
// Transmit a set window command sequence.
|
||||||
public set_addr_window:
|
public set_addr_window:
|
||||||
@ -88,5 +88,5 @@ end_set_addr:
|
|||||||
jmp x--, pull_cmd side 1
|
jmp x--, pull_cmd side 1
|
||||||
// Set DC high.
|
// Set DC high.
|
||||||
set pins, 1
|
set pins, 1
|
||||||
// Auto-wrap back to start_16.
|
// Auto-wrap back to start_tx.
|
||||||
.wrap
|
.wrap
|
@ -16,7 +16,7 @@
|
|||||||
#define tft_io_wrap 27
|
#define tft_io_wrap 27
|
||||||
|
|
||||||
#define tft_io_offset_block_fill 0u
|
#define tft_io_offset_block_fill 0u
|
||||||
#define tft_io_offset_start_16 9u
|
#define tft_io_offset_start_tx 9u
|
||||||
#define tft_io_offset_start_8 14u
|
#define tft_io_offset_start_8 14u
|
||||||
#define tft_io_offset_set_addr_window 17u
|
#define tft_io_offset_set_addr_window 17u
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ next_cmd_bit:
|
|||||||
// Set DC high
|
// Set DC high
|
||||||
set pins, 1 side 0
|
set pins, 1 side 0
|
||||||
// Finish if 3rd cmd byte ramwr sent (x == 0)
|
// Finish if 3rd cmd byte ramwr sent (x == 0)
|
||||||
jmp !x, start_16
|
jmp !x, start_tx
|
||||||
pull
|
pull
|
||||||
next_xy:
|
next_xy:
|
||||||
// send 32 bit start and end coordinates
|
// send 32 bit start and end coordinates
|
||||||
@ -46,7 +46,7 @@ next_xy:
|
|||||||
// Loop back for next command
|
// Loop back for next command
|
||||||
jmp x--, pull_cmd side 0
|
jmp x--, pull_cmd side 0
|
||||||
// End
|
// End
|
||||||
jmp start_16
|
jmp start_tx
|
||||||
|
|
||||||
public block_fill:
|
public block_fill:
|
||||||
// Fetch colour value
|
// Fetch colour value
|
||||||
@ -73,7 +73,7 @@ next_bit:
|
|||||||
// Now drop back to 16 bit output
|
// Now drop back to 16 bit output
|
||||||
|
|
||||||
.wrap_target
|
.wrap_target
|
||||||
public start_16:
|
public start_tx:
|
||||||
// Pull the next 32 bit value from the TX FIFO.
|
// Pull the next 32 bit value from the TX FIFO.
|
||||||
// Send the bottom 16 bits
|
// Send the bottom 16 bits
|
||||||
pull side 0
|
pull side 0
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#define tft_io_offset_start_8 0u
|
#define tft_io_offset_start_8 0u
|
||||||
#define tft_io_offset_set_addr_window 3u
|
#define tft_io_offset_set_addr_window 3u
|
||||||
#define tft_io_offset_block_fill 17u
|
#define tft_io_offset_block_fill 17u
|
||||||
#define tft_io_offset_start_16 27u
|
#define tft_io_offset_start_tx 27u
|
||||||
|
|
||||||
static const uint16_t tft_io_program_instructions[] = {
|
static const uint16_t tft_io_program_instructions[] = {
|
||||||
0x90a0, // 0: pull block side 0
|
0x90a0, // 0: pull block side 0
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
// Change the width and height if required (defined in portrait mode)
|
// Change the width and height if required (defined in portrait mode)
|
||||||
// or use the constructor to over-ride defaults
|
// or use the constructor to over-ride defaults
|
||||||
|
|
||||||
|
#if defined (ILI9341_DRIVER) || ILI9341_2_DRIVER
|
||||||
#define TFT_WIDTH 240
|
#define TFT_WIDTH 240
|
||||||
#define TFT_HEIGHT 320
|
#define TFT_HEIGHT 320
|
||||||
|
#elif defined (ILI9342_DRIVER)
|
||||||
|
#define TFT_WIDTH 320
|
||||||
|
#define TFT_HEIGHT 240
|
||||||
|
#endif
|
||||||
|
|
||||||
// Color definitions for backwards compatibility with old sketches
|
// Color definitions for backwards compatibility with old sketches
|
||||||
// use colour definitions like TFT_BLACK to make sketches more portable
|
// use colour definitions like TFT_BLACK to make sketches more portable
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
//
|
//
|
||||||
// See ST7735_Setup.h file for an alternative format
|
// See ST7735_Setup.h file for an alternative format
|
||||||
|
|
||||||
#if defined (ILI9341_DRIVER)
|
#if defined (ILI9341_DRIVER) | defined (ILI9342_DRIVER)
|
||||||
{
|
{
|
||||||
writecommand(0xEF);
|
writecommand(0xEF);
|
||||||
writedata(0x03);
|
writedata(0x03);
|
||||||
|
@ -685,7 +685,7 @@ void TFT_eSPI::init(uint8_t tc)
|
|||||||
tc = tc; // Suppress warning
|
tc = tc; // Suppress warning
|
||||||
|
|
||||||
// This loads the driver specific initialisation code <<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVERS TO THE LIST HERE <<<<<<<<<<<<<<<<<<<<<<<
|
// This loads the driver specific initialisation code <<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVERS TO THE LIST HERE <<<<<<<<<<<<<<<<<<<<<<<
|
||||||
#if defined (ILI9341_DRIVER) || defined(ILI9341_2_DRIVER)
|
#if defined (ILI9341_DRIVER) || defined(ILI9341_2_DRIVER) || defined (ILI9342_DRIVER)
|
||||||
#include "TFT_Drivers/ILI9341_Init.h"
|
#include "TFT_Drivers/ILI9341_Init.h"
|
||||||
|
|
||||||
#elif defined (ST7735_DRIVER)
|
#elif defined (ST7735_DRIVER)
|
||||||
@ -777,7 +777,7 @@ void TFT_eSPI::setRotation(uint8_t m)
|
|||||||
begin_tft_write();
|
begin_tft_write();
|
||||||
|
|
||||||
// This loads the driver specific rotation code <<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVERS TO THE LIST HERE <<<<<<<<<<<<<<<<<<<<<<<
|
// This loads the driver specific rotation code <<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVERS TO THE LIST HERE <<<<<<<<<<<<<<<<<<<<<<<
|
||||||
#if defined (ILI9341_DRIVER) || defined(ILI9341_2_DRIVER)
|
#if defined (ILI9341_DRIVER) || defined(ILI9341_2_DRIVER) || defined (ILI9342_DRIVER)
|
||||||
#include "TFT_Drivers/ILI9341_Rotation.h"
|
#include "TFT_Drivers/ILI9341_Rotation.h"
|
||||||
|
|
||||||
#elif defined (ST7735_DRIVER)
|
#elif defined (ST7735_DRIVER)
|
||||||
@ -3484,7 +3484,11 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
|
|||||||
TX_FIFO = (y<<16) | y;
|
TX_FIFO = (y<<16) | y;
|
||||||
TX_FIFO = TFT_RAMWR;
|
TX_FIFO = TFT_RAMWR;
|
||||||
//DC set high by PIO
|
//DC set high by PIO
|
||||||
|
#if defined (SPI_18BIT_DRIVER)
|
||||||
|
TX_FIFO = ((color & 0xF800)<<8) | ((color & 0x07E0)<<5) | ((color & 0x001F)<<3);
|
||||||
|
#else
|
||||||
TX_FIFO = color;
|
TX_FIFO = color;
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user