mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2025-07-30 02:37:33 +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)
|
||||
|
||||
#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
|
||||
// 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"
|
||||
#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
|
||||
sm_config_set_out_shift(&c, false, false, 0);
|
||||
// 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.
|
||||
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
|
||||
sm_config_set_out_shift(&c, false, false, 0);
|
||||
// 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.
|
||||
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
|
||||
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) {
|
||||
WAIT_FOR_STALL;
|
||||
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 = --len; // Decrement first as PIO sends n+1
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
@ -300,7 +318,21 @@ 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){
|
||||
|
||||
#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;
|
||||
|
||||
// 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
|
||||
#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
|
||||
// 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
|
||||
@ -356,7 +383,7 @@
|
||||
#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)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef tft_Write_16N
|
||||
|
@ -38,7 +38,7 @@ next:
|
||||
|
||||
.wrap_target
|
||||
// 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.
|
||||
pull side 1
|
||||
// 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.
|
||||
out pins, 8 side 0 [1]
|
||||
// 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).
|
||||
public start_8:
|
||||
@ -59,7 +59,7 @@ public start_8:
|
||||
// shifts the unused top 24 bits through.
|
||||
out pins, 32 side 0 [1]
|
||||
// Jump to start
|
||||
jmp start_16 side 1
|
||||
jmp start_tx side 1
|
||||
|
||||
// Transmit a set window command sequence.
|
||||
public set_addr_window:
|
||||
@ -88,5 +88,5 @@ end_set_addr:
|
||||
jmp x--, pull_cmd side 1
|
||||
// Set DC high.
|
||||
set pins, 1
|
||||
// Auto-wrap back to start_16.
|
||||
// Auto-wrap back to start_tx.
|
||||
.wrap
|
@ -16,7 +16,7 @@
|
||||
#define tft_io_wrap 27
|
||||
|
||||
#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_set_addr_window 17u
|
||||
|
||||
|
@ -37,7 +37,7 @@ next_cmd_bit:
|
||||
// Set DC high
|
||||
set pins, 1 side 0
|
||||
// Finish if 3rd cmd byte ramwr sent (x == 0)
|
||||
jmp !x, start_16
|
||||
jmp !x, start_tx
|
||||
pull
|
||||
next_xy:
|
||||
// send 32 bit start and end coordinates
|
||||
@ -46,7 +46,7 @@ next_xy:
|
||||
// Loop back for next command
|
||||
jmp x--, pull_cmd side 0
|
||||
// End
|
||||
jmp start_16
|
||||
jmp start_tx
|
||||
|
||||
public block_fill:
|
||||
// Fetch colour value
|
||||
@ -73,7 +73,7 @@ next_bit:
|
||||
// Now drop back to 16 bit output
|
||||
|
||||
.wrap_target
|
||||
public start_16:
|
||||
public start_tx:
|
||||
// Pull the next 32 bit value from the TX FIFO.
|
||||
// Send the bottom 16 bits
|
||||
pull side 0
|
||||
|
@ -18,7 +18,7 @@
|
||||
#define tft_io_offset_start_8 0u
|
||||
#define tft_io_offset_set_addr_window 3u
|
||||
#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[] = {
|
||||
0x90a0, // 0: pull block side 0
|
||||
|
@ -1,8 +1,13 @@
|
||||
// Change the width and height if required (defined in portrait mode)
|
||||
// or use the constructor to over-ride defaults
|
||||
#define TFT_WIDTH 240
|
||||
#define TFT_HEIGHT 320
|
||||
|
||||
#if defined (ILI9341_DRIVER) || ILI9341_2_DRIVER
|
||||
#define TFT_WIDTH 240
|
||||
#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
|
||||
// use colour definitions like TFT_BLACK to make sketches more portable
|
||||
|
@ -5,7 +5,7 @@
|
||||
//
|
||||
// See ST7735_Setup.h file for an alternative format
|
||||
|
||||
#if defined (ILI9341_DRIVER)
|
||||
#if defined (ILI9341_DRIVER) | defined (ILI9342_DRIVER)
|
||||
{
|
||||
writecommand(0xEF);
|
||||
writedata(0x03);
|
||||
|
10
TFT_eSPI.cpp
10
TFT_eSPI.cpp
@ -685,7 +685,7 @@ void TFT_eSPI::init(uint8_t tc)
|
||||
tc = tc; // Suppress warning
|
||||
|
||||
// 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"
|
||||
|
||||
#elif defined (ST7735_DRIVER)
|
||||
@ -777,7 +777,7 @@ void TFT_eSPI::setRotation(uint8_t m)
|
||||
begin_tft_write();
|
||||
|
||||
// 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"
|
||||
|
||||
#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 = TFT_RAMWR;
|
||||
//DC set high by PIO
|
||||
TX_FIFO = color;
|
||||
#if defined (SPI_18BIT_DRIVER)
|
||||
TX_FIFO = ((color & 0xF800)<<8) | ((color & 0x07E0)<<5) | ((color & 0x001F)<<3);
|
||||
#else
|
||||
TX_FIFO = color;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user