mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2025-07-31 11:17:32 +02:00
Fix #2297
The SSD1963 requires 18 bit colour in 3 bytes when an 8 bit parallel interface is used. Added new PIO parallel code
This commit is contained in:
@ -29,10 +29,15 @@
|
|||||||
#include "pio_SPI.pio.h"
|
#include "pio_SPI.pio.h"
|
||||||
#endif
|
#endif
|
||||||
#elif defined (TFT_PARALLEL_8_BIT)
|
#elif defined (TFT_PARALLEL_8_BIT)
|
||||||
// SPI PIO code for 8 bit parallel interface (16 bit colour)
|
#if defined (SSD1963_DRIVER)
|
||||||
|
// PIO code for 8 bit parallel interface (18 bit colour)
|
||||||
|
#include "pio_8bit_parallel_18bpp.pio.h"
|
||||||
|
#else
|
||||||
|
// PIO code for 8 bit parallel interface (16 bit colour)
|
||||||
#include "pio_8bit_parallel.pio.h"
|
#include "pio_8bit_parallel.pio.h"
|
||||||
|
#endif
|
||||||
#else // must be TFT_PARALLEL_16_BIT
|
#else // must be TFT_PARALLEL_16_BIT
|
||||||
// SPI PIO code for 16 bit parallel interface (16 bit colour)
|
// PIO code for 16 bit parallel interface (16 bit colour)
|
||||||
#include "pio_16bit_parallel.pio.h"
|
#include "pio_16bit_parallel.pio.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -279,7 +284,7 @@ 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)
|
#if defined (SPI_18BIT_DRIVER) || (defined (SSD1963_DRIVER) && defined (TFT_PARALLEL_8_BIT))
|
||||||
uint32_t col = ((color & 0xF800)<<8) | ((color & 0x07E0)<<5) | ((color & 0x001F)<<3);
|
uint32_t col = ((color & 0xF800)<<8) | ((color & 0x07E0)<<5) | ((color & 0x001F)<<3);
|
||||||
if (len) {
|
if (len) {
|
||||||
WAIT_FOR_STALL;
|
WAIT_FOR_STALL;
|
||||||
@ -327,7 +332,7 @@ 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)
|
#if defined (SPI_18BIT_DRIVER) || (defined (SSD1963_DRIVER) && defined (TFT_PARALLEL_8_BIT))
|
||||||
uint16_t *data = (uint16_t*)data_in;
|
uint16_t *data = (uint16_t*)data_in;
|
||||||
if (_swapBytes) {
|
if (_swapBytes) {
|
||||||
while ( len-- ) {
|
while ( len-- ) {
|
||||||
|
@ -408,7 +408,7 @@
|
|||||||
// Temporary - to be deleted
|
// Temporary - to be deleted
|
||||||
#define GPIO_DIR_MASK 0
|
#define GPIO_DIR_MASK 0
|
||||||
|
|
||||||
#if defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
|
#if defined (SPI_18BIT_DRIVER) || defined (SSD1963_DRIVER) // 18 bit colour (3 bytes)
|
||||||
// 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
|
||||||
|
73
Processors/pio_8bit_parallel_18bpp.pio.h
Normal file
73
Processors/pio_8bit_parallel_18bpp.pio.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// -------------------------------------------------- //
|
||||||
|
// This file is autogenerated by pioasm; do not edit! //
|
||||||
|
// -------------------------------------------------- //
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !PICO_NO_HARDWARE
|
||||||
|
#include "hardware/pio.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ------ //
|
||||||
|
// tft_io //
|
||||||
|
// ------ //
|
||||||
|
|
||||||
|
#define tft_io_wrap_target 11
|
||||||
|
#define tft_io_wrap 31
|
||||||
|
|
||||||
|
#define tft_io_offset_block_fill 0u
|
||||||
|
#define tft_io_offset_start_tx 11u
|
||||||
|
#define tft_io_offset_start_8 18u
|
||||||
|
#define tft_io_offset_set_addr_window 21u
|
||||||
|
|
||||||
|
static const uint16_t tft_io_program_instructions[] = {
|
||||||
|
0x98a0, // 0: pull block side 1
|
||||||
|
0xa027, // 1: mov x, osr
|
||||||
|
0x80a0, // 2: pull block
|
||||||
|
0xa047, // 3: mov y, osr
|
||||||
|
0xb8e1, // 4: mov osr, x side 1
|
||||||
|
0x7110, // 5: out pins, 16 side 0 [1]
|
||||||
|
0xb942, // 6: nop side 1 [1]
|
||||||
|
0x7108, // 7: out pins, 8 side 0 [1]
|
||||||
|
0xb942, // 8: nop side 1 [1]
|
||||||
|
0x7108, // 9: out pins, 8 side 0 [1]
|
||||||
|
0x1884, // 10: jmp y--, 4 side 1
|
||||||
|
// .wrap_target
|
||||||
|
0x98a0, // 11: pull block side 1
|
||||||
|
0x7110, // 12: out pins, 16 side 0 [1]
|
||||||
|
0xb942, // 13: nop side 1 [1]
|
||||||
|
0x7108, // 14: out pins, 8 side 0 [1]
|
||||||
|
0xb942, // 15: nop side 1 [1]
|
||||||
|
0x7108, // 16: out pins, 8 side 0 [1]
|
||||||
|
0x180b, // 17: jmp 11 side 1
|
||||||
|
0x98a0, // 18: pull block side 1
|
||||||
|
0x7100, // 19: out pins, 32 side 0 [1]
|
||||||
|
0x180b, // 20: jmp 11 side 1
|
||||||
|
0xf822, // 21: set x, 2 side 1
|
||||||
|
0xe000, // 22: set pins, 0
|
||||||
|
0x80a0, // 23: pull block
|
||||||
|
0x7000, // 24: out pins, 32 side 0
|
||||||
|
0x003e, // 25: jmp !x, 30
|
||||||
|
0x98a0, // 26: pull block side 1
|
||||||
|
0xe001, // 27: set pins, 1
|
||||||
|
0x7108, // 28: out pins, 8 side 0 [1]
|
||||||
|
0x19fc, // 29: jmp !osre, 28 side 1 [1]
|
||||||
|
0x1856, // 30: jmp x--, 22 side 1
|
||||||
|
0xe001, // 31: set pins, 1
|
||||||
|
// .wrap
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !PICO_NO_HARDWARE
|
||||||
|
static const struct pio_program tft_io_program = {
|
||||||
|
.instructions = tft_io_program_instructions,
|
||||||
|
.length = 32,
|
||||||
|
.origin = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline pio_sm_config tft_io_program_get_default_config(uint offset) {
|
||||||
|
pio_sm_config c = pio_get_default_sm_config();
|
||||||
|
sm_config_set_wrap(&c, offset + tft_io_wrap_target, offset + tft_io_wrap);
|
||||||
|
sm_config_set_sideset(&c, 2, true, false);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
#endif
|
29
TFT_eSPI.cpp
29
TFT_eSPI.cpp
@ -3640,7 +3640,7 @@ 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)
|
#if defined (SPI_18BIT_DRIVER) || (defined (SSD1963_DRIVER) && defined (TFT_PARALLEL_8_BIT))
|
||||||
TX_FIFO = ((color & 0xF800)<<8) | ((color & 0x07E0)<<5) | ((color & 0x001F)<<3);
|
TX_FIFO = ((color & 0xF800)<<8) | ((color & 0x07E0)<<5) | ((color & 0x001F)<<3);
|
||||||
#else
|
#else
|
||||||
TX_FIFO = color;
|
TX_FIFO = color;
|
||||||
@ -4031,13 +4031,13 @@ void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||||||
uint32_t slope = (fabscos/(fabssin + minDivisor)) * (float)(1<<16);
|
uint32_t slope = (fabscos/(fabssin + minDivisor)) * (float)(1<<16);
|
||||||
|
|
||||||
// Update slope table, add slope for arc start
|
// Update slope table, add slope for arc start
|
||||||
if (startAngle < 90) {
|
if (startAngle <= 90) {
|
||||||
startSlope[0] = slope;
|
startSlope[0] = slope;
|
||||||
}
|
}
|
||||||
else if (startAngle < 180) {
|
else if (startAngle <= 180) {
|
||||||
startSlope[1] = slope;
|
startSlope[1] = slope;
|
||||||
}
|
}
|
||||||
else if (startAngle < 270) {
|
else if (startAngle <= 270) {
|
||||||
startSlope[1] = 0xFFFFFFFF;
|
startSlope[1] = 0xFFFFFFFF;
|
||||||
startSlope[2] = slope;
|
startSlope[2] = slope;
|
||||||
}
|
}
|
||||||
@ -4055,16 +4055,16 @@ void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||||||
slope = (uint32_t)((fabscos/(fabssin + minDivisor)) * (float)(1<<16));
|
slope = (uint32_t)((fabscos/(fabssin + minDivisor)) * (float)(1<<16));
|
||||||
|
|
||||||
// Work out which quadrants will need to be drawn and add slope for arc end
|
// Work out which quadrants will need to be drawn and add slope for arc end
|
||||||
if (endAngle < 90) {
|
if (endAngle <= 90) {
|
||||||
endSlope[0] = slope;
|
endSlope[0] = slope;
|
||||||
endSlope[1] = 0;
|
endSlope[1] = 0;
|
||||||
endSlope[2] = 0xFFFFFFFF;
|
startSlope[2] = 0;
|
||||||
}
|
}
|
||||||
else if (endAngle < 180) {
|
else if (endAngle <= 180) {
|
||||||
endSlope[1] = slope;
|
endSlope[1] = slope;
|
||||||
endSlope[2] = 0xFFFFFFFF;
|
startSlope[2] = 0;
|
||||||
}
|
}
|
||||||
else if (endAngle < 270) {
|
else if (endAngle <= 270) {
|
||||||
endSlope[2] = slope;
|
endSlope[2] = slope;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -4093,6 +4093,7 @@ void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||||||
}
|
}
|
||||||
// If within arc fill zone, get line start and lengths for each quadrant
|
// If within arc fill zone, get line start and lengths for each quadrant
|
||||||
else if (hyp >= r3) {
|
else if (hyp >= r3) {
|
||||||
|
do {
|
||||||
// Calculate U16.16 slope
|
// Calculate U16.16 slope
|
||||||
slope = ((r - cy) << 16)/(r - cx);
|
slope = ((r - cy) << 16)/(r - cx);
|
||||||
if (slope <= startSlope[0] && slope >= endSlope[0]) { // slope hi -> lo
|
if (slope <= startSlope[0] && slope >= endSlope[0]) { // slope hi -> lo
|
||||||
@ -4107,10 +4108,13 @@ void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||||||
xst[2] = cx; // Bottom right line start
|
xst[2] = cx; // Bottom right line start
|
||||||
len[2]++;
|
len[2]++;
|
||||||
}
|
}
|
||||||
if (slope >= startSlope[3] && slope <= endSlope[3]) { // slope lo -> hi
|
if (slope <= endSlope[3] && slope >= startSlope[3]) { // slope lo -> hi
|
||||||
xst[3] = cx; // Top right line start
|
xst[3] = cx; // Top right line start
|
||||||
len[3]++;
|
len[3]++;
|
||||||
}
|
}
|
||||||
|
cx++;
|
||||||
|
} while ((r - cx) * (r - cx) + dy2 >= r3 && cx < r);
|
||||||
|
cx--;
|
||||||
continue; // Next x
|
continue; // Next x
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -4131,7 +4135,7 @@ void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
|
|||||||
drawPixel(x + cx - r, y + cy - r, pcol);
|
drawPixel(x + cx - r, y + cy - r, pcol);
|
||||||
if (slope <= startSlope[2] && slope >= endSlope[2]) // TR
|
if (slope <= startSlope[2] && slope >= endSlope[2]) // TR
|
||||||
drawPixel(x - cx + r, y + cy - r, pcol);
|
drawPixel(x - cx + r, y + cy - r, pcol);
|
||||||
if (slope >= startSlope[3] && slope <= endSlope[3]) // BR
|
if (slope <= endSlope[3] && slope >= startSlope[3]) // BR
|
||||||
drawPixel(x - cx + r, y - cy + r, pcol);
|
drawPixel(x - cx + r, y - cy + r, pcol);
|
||||||
}
|
}
|
||||||
// Add line in inner zone
|
// Add line in inner zone
|
||||||
@ -4905,10 +4909,13 @@ uint16_t TFT_eSPI::decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining)
|
|||||||
*************************************************************************************x*/
|
*************************************************************************************x*/
|
||||||
inline uint16_t TFT_eSPI::alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc)
|
inline uint16_t TFT_eSPI::alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc)
|
||||||
{
|
{
|
||||||
|
// Split out and blend 5 bit red and blue channels
|
||||||
uint32_t rxb = bgc & 0xF81F;
|
uint32_t rxb = bgc & 0xF81F;
|
||||||
rxb += ((fgc & 0xF81F) - rxb) * (alpha >> 2) >> 6;
|
rxb += ((fgc & 0xF81F) - rxb) * (alpha >> 2) >> 6;
|
||||||
|
// Split out and blend 6 bit green channel
|
||||||
uint32_t xgx = bgc & 0x07E0;
|
uint32_t xgx = bgc & 0x07E0;
|
||||||
xgx += ((fgc & 0x07E0) - xgx) * alpha >> 8;
|
xgx += ((fgc & 0x07E0) - xgx) * alpha >> 8;
|
||||||
|
// Recombine channels
|
||||||
return (rxb & 0xF81F) | (xgx & 0x07E0);
|
return (rxb & 0xF81F) | (xgx & 0x07E0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user