Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
TFT_eSPI
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
TFT_eSPI
Commits
284893c3
Commit
284893c3
authored
Feb 22, 2022
by
Bodmer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update RP2040 PIO and smooth graphics fns
parent
d1e6637b
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
183 additions
and
126 deletions
+183
-126
Processors/TFT_eSPI_ESP8266.h
Processors/TFT_eSPI_ESP8266.h
+5
-0
Processors/TFT_eSPI_RP2040.c
Processors/TFT_eSPI_RP2040.c
+63
-33
Processors/TFT_eSPI_RP2040.h
Processors/TFT_eSPI_RP2040.h
+10
-10
Processors/pio_SPI.pio
Processors/pio_SPI.pio
+12
-14
Processors/pio_SPI.pio.h
Processors/pio_SPI.pio.h
+32
-32
TFT_eSPI.cpp
TFT_eSPI.cpp
+58
-34
TFT_eSPI.h
TFT_eSPI.h
+1
-1
library.json
library.json
+1
-1
library.properties
library.properties
+1
-1
No files found.
Processors/TFT_eSPI_ESP8266.h
View file @
284893c3
...
...
@@ -191,6 +191,11 @@
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_16N(C) \
SPI1U1 = (15 << SPILMOSI) | (15 << SPILMISO); \
SPI1W0 = ((C)<<8 | (C)>>8); \
SPI1CMD |= SPIBUSY
#define tft_Write_16S(C) \
SPI1U1 = (15 << SPILMOSI) | (15 << SPILMISO); \
SPI1W0 = C; \
...
...
Processors/TFT_eSPI_RP2040.c
View file @
284893c3
...
...
@@ -33,7 +33,7 @@
#endif
// Community RP2040 board package by Earle Philhower
PIO
pio
=
pio0
;
// Code will try both pio's to find a free SM
PIO
tft_
pio
=
pio0
;
// Code will try both pio's to find a free SM
int8_t
pio_sm
=
0
;
// pioinit will claim a free one
// Updated later with the loading offset of the PIO program.
uint32_t
program_offset
=
0
;
...
...
@@ -53,7 +53,7 @@
#endif
#ifdef RP2040_DMA
uint32_t
dma_tx_channel
;
int32_t
dma_tx_channel
;
dma_channel_config
dma_tx_config
;
#endif
...
...
@@ -114,26 +114,41 @@ void TFT_eSPI::end_SDA_Read(void)
void
pioinit
(
uint32_t
clock_freq
)
{
// Find a free SM on one of the PIO's
pio
=
pio0
;
pio_sm
=
pio_claim_unused_sm
(
pio
,
false
);
// false means don't panic
tft_pio
=
pio0
;
/*
pio_sm = pio_claim_unused_sm(tft_pio, false); // false means don't panic
// Try pio1 if SM not found
if (pio_sm < 0) {
pio
=
pio1
;
pio_sm
=
pio_claim_unused_sm
(
pio
,
true
);
// panic this time if no SM is free
tft_pio = pio1;
pio_sm = pio_claim_unused_sm(tft_pio, true); // panic this time if no SM is free
}
*/
// Find enough free space on one of the PIO's
tft_pio
=
pio0
;
if
(
!
pio_can_add_program
(
tft_pio
,
&
tft_io_program
))
{
tft_pio
=
pio1
;
if
(
!
pio_can_add_program
(
tft_pio
,
&
tft_io_program
))
{
Serial
.
println
(
"No room for PIO program!"
);
return
;
}
}
pio_sm
=
pio_claim_unused_sm
(
tft_pio
,
false
);
// Load the PIO program
program_offset
=
pio_add_program
(
pio
,
&
tft_io_program
);
program_offset
=
pio_add_program
(
tft_
pio
,
&
tft_io_program
);
// Associate pins with the PIO
pio_gpio_init
(
pio
,
TFT_DC
);
pio_gpio_init
(
pio
,
TFT_SCLK
);
pio_gpio_init
(
pio
,
TFT_MOSI
);
pio_gpio_init
(
tft_
pio
,
TFT_DC
);
pio_gpio_init
(
tft_
pio
,
TFT_SCLK
);
pio_gpio_init
(
tft_
pio
,
TFT_MOSI
);
// Configure the pins to be outputs
pio_sm_set_consecutive_pindirs
(
pio
,
pio_sm
,
TFT_DC
,
1
,
true
);
pio_sm_set_consecutive_pindirs
(
pio
,
pio_sm
,
TFT_SCLK
,
1
,
true
);
pio_sm_set_consecutive_pindirs
(
pio
,
pio_sm
,
TFT_MOSI
,
1
,
true
);
pio_sm_set_consecutive_pindirs
(
tft_
pio
,
pio_sm
,
TFT_DC
,
1
,
true
);
pio_sm_set_consecutive_pindirs
(
tft_
pio
,
pio_sm
,
TFT_SCLK
,
1
,
true
);
pio_sm_set_consecutive_pindirs
(
tft_
pio
,
pio_sm
,
TFT_MOSI
,
1
,
true
);
// Configure the state machine
pio_sm_config
c
=
tft_io_program_get_default_config
(
program_offset
);
...
...
@@ -151,10 +166,10 @@ 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
(
pio
,
pio_sm
,
program_offset
+
tft_io_offset_start_16
,
&
c
);
pio_sm_init
(
tft_
pio
,
pio_sm
,
program_offset
+
tft_io_offset_start_16
,
&
c
);
// Start the state machine.
pio_sm_set_enabled
(
pio
,
pio_sm
,
true
);
pio_sm_set_enabled
(
tft_
pio
,
pio_sm
,
true
);
// Create the pull stall bit mask
pull_stall_mask
=
1u
<<
(
PIO_FDEBUG_TXSTALL_LSB
+
pio_sm
);
...
...
@@ -171,28 +186,40 @@ void pioinit(uint32_t clock_freq) {
void
pioinit
(
uint16_t
clock_div
,
uint16_t
fract_div
)
{
// Find a free SM on one of the PIO's
pio
=
pio0
;
pio_sm
=
pio_claim_unused_sm
(
pio
,
false
);
// false means don't panic
tft_
pio
=
pio0
;
pio_sm
=
pio_claim_unused_sm
(
tft_
pio
,
false
);
// false means don't panic
// Try pio1 if SM not found
if
(
pio_sm
<
0
)
{
pio
=
pio1
;
pio_sm
=
pio_claim_unused_sm
(
pio
,
true
);
// panic this time if no SM is free
tft_pio
=
pio1
;
pio_sm
=
pio_claim_unused_sm
(
tft_pio
,
true
);
// panic this time if no SM is free
}
/*
// Find enough free space on one of the PIO's
tft_pio = pio0;
if (!pio_can_add_program(tft_pio, &tft_io_program) {
tft_pio = pio1;
if (!pio_can_add_program(tft_pio, &tft_io_program) {
Serial.println("No room for PIO program!");
while(1) delay(100);
return;
}
}
*/
// Load the PIO program
program_offset
=
pio_add_program
(
pio
,
&
tft_io_program
);
program_offset
=
pio_add_program
(
tft_
pio
,
&
tft_io_program
);
// Associate pins with the PIO
pio_gpio_init
(
pio
,
TFT_DC
);
pio_gpio_init
(
pio
,
TFT_WR
);
pio_gpio_init
(
tft_
pio
,
TFT_DC
);
pio_gpio_init
(
tft_
pio
,
TFT_WR
);
for
(
int
i
=
0
;
i
<
8
;
i
++
)
{
pio_gpio_init
(
pio
,
TFT_D0
+
i
);
pio_gpio_init
(
tft_
pio
,
TFT_D0
+
i
);
}
// Configure the pins to be outputs
pio_sm_set_consecutive_pindirs
(
pio
,
pio_sm
,
TFT_DC
,
1
,
true
);
pio_sm_set_consecutive_pindirs
(
pio
,
pio_sm
,
TFT_WR
,
1
,
true
);
pio_sm_set_consecutive_pindirs
(
pio
,
pio_sm
,
TFT_D0
,
8
,
true
);
pio_sm_set_consecutive_pindirs
(
tft_
pio
,
pio_sm
,
TFT_DC
,
1
,
true
);
pio_sm_set_consecutive_pindirs
(
tft_
pio
,
pio_sm
,
TFT_WR
,
1
,
true
);
pio_sm_set_consecutive_pindirs
(
tft_
pio
,
pio_sm
,
TFT_D0
,
8
,
true
);
// Configure the state machine
pio_sm_config
c
=
tft_io_program_get_default_config
(
program_offset
);
...
...
@@ -209,10 +236,10 @@ 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
(
pio
,
pio_sm
,
program_offset
+
tft_io_offset_start_16
,
&
c
);
pio_sm_init
(
tft_
pio
,
pio_sm
,
program_offset
+
tft_io_offset_start_16
,
&
c
);
// Start the state machine.
pio_sm_set_enabled
(
pio
,
pio_sm
,
true
);
pio_sm_set_enabled
(
tft_
pio
,
pio_sm
,
true
);
// Create the pull stall bit mask
pull_stall_mask
=
1u
<<
(
PIO_FDEBUG_TXSTALL_LSB
+
pio_sm
);
...
...
@@ -238,7 +265,7 @@ void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
if
(
len
)
{
WAIT_FOR_STALL
;
pio
->
sm
[
pio_sm
].
instr
=
pio_instr_fill
;
tft_
pio
->
sm
[
pio_sm
].
instr
=
pio_instr_fill
;
TX_FIFO
=
color
;
TX_FIFO
=
--
len
;
// Decrement first as PIO sends n+1
...
...
@@ -564,7 +591,7 @@ void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len)
#if !defined (RP2040_PIO_INTERFACE)
dma_channel_configure
(
dma_tx_channel
,
&
dma_tx_config
,
&
spi_get_hw
(
SPI_X
)
->
dr
,
(
uint16_t
*
)
image
,
len
,
true
);
#else
dma_channel_configure
(
dma_tx_channel
,
&
dma_tx_config
,
&
pio
->
txf
[
pio_sm
],
(
uint16_t
*
)
image
,
len
,
true
);
dma_channel_configure
(
dma_tx_channel
,
&
dma_tx_config
,
&
tft_
pio
->
txf
[
pio_sm
],
(
uint16_t
*
)
image
,
len
,
true
);
#endif
}
...
...
@@ -617,7 +644,7 @@ void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t
#if !defined (RP2040_PIO_INTERFACE)
dma_channel_configure
(
dma_tx_channel
,
&
dma_tx_config
,
&
spi_get_hw
(
SPI_X
)
->
dr
,
(
uint16_t
*
)
buffer
,
len
,
true
);
#else
dma_channel_configure
(
dma_tx_channel
,
&
dma_tx_config
,
&
pio
->
txf
[
pio_sm
],
(
uint16_t
*
)
buffer
,
len
,
true
);
dma_channel_configure
(
dma_tx_channel
,
&
dma_tx_config
,
&
tft_
pio
->
txf
[
pio_sm
],
(
uint16_t
*
)
buffer
,
len
,
true
);
#endif
}
...
...
@@ -631,14 +658,17 @@ bool TFT_eSPI::initDMA(bool ctrl_cs)
ctrl_cs
=
ctrl_cs
;
// stop unused parameter warning
dma_tx_channel
=
dma_claim_unused_channel
(
true
);
dma_tx_channel
=
dma_claim_unused_channel
(
false
);
if
(
dma_tx_channel
<
0
)
return
false
;
dma_tx_config
=
dma_channel_get_default_config
(
dma_tx_channel
);
channel_config_set_transfer_data_size
(
&
dma_tx_config
,
DMA_SIZE_16
);
#if !defined (RP2040_PIO_INTERFACE)
channel_config_set_dreq
(
&
dma_tx_config
,
spi_get_index
(
SPI_X
)
?
DREQ_SPI1_TX
:
DREQ_SPI0_TX
);
#else
channel_config_set_dreq
(
&
dma_tx_config
,
pio_get_dreq
(
pio
,
pio_sm
,
true
));
channel_config_set_dreq
(
&
dma_tx_config
,
pio_get_dreq
(
tft_
pio
,
pio_sm
,
true
));
#endif
DMA_Enabled
=
true
;
...
...
Processors/TFT_eSPI_RP2040.h
View file @
284893c3
...
...
@@ -101,7 +101,7 @@
// If smooth fonts are enabled the filing system may need to be loaded
#if
def SMOOTH_FONT
#if
defined (SMOOTH_FONT) && !defined (ARDUINO_ARCH_MBED)
// Call up the filing system for the anti-aliased fonts
//#define FS_NO_GLOBALS
#include <FS.h>
...
...
@@ -128,10 +128,10 @@
// PIO takes control of TFT_DC
// Must wait for data to flush through before changing DC line
#define DC_C WAIT_FOR_STALL; \
pio->sm[pio_sm].instr = pio_instr_clr_dc
tft_
pio->sm[pio_sm].instr = pio_instr_clr_dc
// Flush has happened before this and mode changed back to 16 bit
#define DC_D pio->sm[pio_sm].instr = pio_instr_set_dc
#define DC_D
tft_
pio->sm[pio_sm].instr = pio_instr_set_dc
#endif
#endif
...
...
@@ -315,22 +315,22 @@
// Wait for the PIO to stall (SM pull request finds no data in TX FIFO)
// This is used to detect when the SM is idle and hence ready for a jump instruction
#define WAIT_FOR_STALL
pio->fdebug = pull_stall_mask; while (!(
pio->fdebug & pull_stall_mask))
#define WAIT_FOR_STALL
tft_pio->fdebug = pull_stall_mask; while (!(tft_
pio->fdebug & pull_stall_mask))
// Wait until at least "S" locations free
#define WAIT_FOR_FIFO_FREE(S) while (((pio->flevel >> (pio_sm * 8)) & 0x000F) > (8-S)){}
#define WAIT_FOR_FIFO_FREE(S) while (((
tft_
pio->flevel >> (pio_sm * 8)) & 0x000F) > (8-S)){}
// Wait until at least 5 locations free
#define WAIT_FOR_FIFO_5_FREE while ((pio->flevel) & (0x000c << (pio_sm * 8))){}
#define WAIT_FOR_FIFO_5_FREE while ((
tft_
pio->flevel) & (0x000c << (pio_sm * 8))){}
// Wait until at least 1 location free
#define WAIT_FOR_FIFO_1_FREE while ((pio->flevel) & (0x0008 << (pio_sm * 8))){}
#define WAIT_FOR_FIFO_1_FREE while ((
tft_
pio->flevel) & (0x0008 << (pio_sm * 8))){}
// Wait for FIFO to empty (use before swapping to 8 bits)
#define WAIT_FOR_FIFO_EMPTY while(!(pio->fstat & (1u << (PIO_FSTAT_TXEMPTY_LSB + pio_sm))))
#define WAIT_FOR_FIFO_EMPTY while(!(
tft_
pio->fstat & (1u << (PIO_FSTAT_TXEMPTY_LSB + pio_sm))))
// The write register of the TX FIFO.
#define TX_FIFO pio->txf[pio_sm]
#define TX_FIFO
tft_
pio->txf[pio_sm]
// Temporary - to be deleted
#define dir_mask 0
...
...
@@ -339,7 +339,7 @@
// 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) pio->sm[pio_sm].instr = pio_instr_jmp8; \
#define tft_Write_8(C)
tft_
pio->sm[pio_sm].instr = pio_instr_jmp8; \
TX_FIFO = (C); \
WAIT_FOR_STALL
...
...
Processors/pio_SPI.pio
View file @
284893c3
...
...
@@ -15,16 +15,11 @@
// 8 bit transfer
public start_8:
// Pull the next 32 bit value from the TX FIFO.
// Lose the top 24 bits
pull side 0
// Lose the top 24 bits
out null, 24
spi_out_8:
// Output the next 8 bits
out pins, 1 side 0
// Set TFT_SCLK high and jump for next bit
jmp !osre, spi_out_8 side 1
// Return to start
jmp start_16 side 0
// Now send remaining bits
jmp spi_out side 0
public set_addr_window:
// Loop count in x for caset, paset and ramwr
...
...
@@ -34,7 +29,8 @@ pull_cmd:
set pins, 0
// Fetch and output LS byte (caset, paset or ramwr), discarding top 24 bits, set WR low
pull side 0
out null, 24
out pins, 25
nop side 1
next_cmd_bit:
out pins, 1 side 0
jmp !osre, next_cmd_bit side 1
...
...
@@ -79,13 +75,15 @@ next_bit:
.wrap_target
public start_16:
// Pull the next 32 bit value from the TX FIFO.
//
Write the top
16 bits
//
Send the bottom
16 bits
pull side 0
out null, 16
spi_out_16:
// Output the next 16 bits
// Drop the first 16 bits, write first bit
out pins, 17 side 0
nop side 1
spi_out:
// Output the next 15 bits
out pins, 1 side 0
// Set TFT_SCLK high and jump for next bit
jmp !osre, spi_out
_16
side 1
jmp !osre, spi_out side 1
// Return to start
.wrap
Processors/pio_SPI.pio.h
View file @
284893c3
...
...
@@ -12,46 +12,46 @@
// tft_io //
// ------ //
#define tft_io_wrap_target 2
8
#define tft_io_wrap_target 2
7
#define tft_io_wrap 31
#define tft_io_offset_start_8 0u
#define tft_io_offset_set_addr_window
5
u
#define tft_io_offset_block_fill 1
8
u
#define tft_io_offset_start_16 2
8
u
#define tft_io_offset_set_addr_window
3
u
#define tft_io_offset_block_fill 1
7
u
#define tft_io_offset_start_16 2
7
u
static
const
uint16_t
tft_io_program_instructions
[]
=
{
0x90a0
,
// 0: pull block side 0
0x6078
,
// 1: out null, 24
0x7001
,
// 2: out pins, 1 side 0
0x18e2
,
// 3: jmp !osre, 2 side 1
0x101c
,
// 4: jmp 28 side 0
0xf022
,
// 5: set x, 2 side 0
0xe000
,
// 6: set pins, 0
0x90a0
,
// 7: pull block side 0
0x6078
,
// 8: out null, 24
0x7001
,
// 9: out pins, 1 side 0
0x18e9
,
// 10: jmp !osre, 9 side 1
0xf001
,
// 11: set pins, 1 side 0
0x003c
,
// 12: jmp !x, 28
0x80a0
,
// 13: pull block
0x7001
,
// 14: out pins, 1 side 0
0x18ee
,
// 15: jmp !osre, 14 side 1
0x1046
,
// 16: jmp x--, 6 side 0
0x001c
,
// 17: jmp 28
0x90a0
,
// 18: pull block side 0
0xa027
,
// 19: mov x, osr
0x80a0
,
// 20: pull block
0xa047
,
// 21: mov y, osr
0xb0e1
,
// 22: mov osr, x side 0
0x7011
,
// 23: out pins, 17 side 0
0xb842
,
// 24: nop side 1
0x7001
,
// 25: out pins, 1 side 0
0x18f9
,
// 26: jmp !osre, 25 side 1
0x1096
,
// 27: jmp y--, 22 side 0
0x101e
,
// 2: jmp 30 side 0
0xf022
,
// 3: set x, 2 side 0
0xe000
,
// 4: set pins, 0
0x90a0
,
// 5: pull block side 0
0x6019
,
// 6: out pins, 25
0xb842
,
// 7: nop side 1
0x7001
,
// 8: out pins, 1 side 0
0x18e8
,
// 9: jmp !osre, 8 side 1
0xf001
,
// 10: set pins, 1 side 0
0x003b
,
// 11: jmp !x, 27
0x80a0
,
// 12: pull block
0x7001
,
// 13: out pins, 1 side 0
0x18ed
,
// 14: jmp !osre, 13 side 1
0x1044
,
// 15: jmp x--, 4 side 0
0x001b
,
// 16: jmp 27
0x90a0
,
// 17: pull block side 0
0xa027
,
// 18: mov x, osr
0x80a0
,
// 19: pull block
0xa047
,
// 20: mov y, osr
0xb0e1
,
// 21: mov osr, x side 0
0x7011
,
// 22: out pins, 17 side 0
0xb842
,
// 23: nop side 1
0x7001
,
// 24: out pins, 1 side 0
0x18f8
,
// 25: jmp !osre, 24 side 1
0x1095
,
// 26: jmp y--, 21 side 0
// .wrap_target
0x90a0
,
// 28: pull block side 0
0x6070
,
// 29: out null, 16
0x90a0
,
// 27: pull block side 0
0x7011
,
// 28: out pins, 17 side 0
0xb842
,
// 29: nop side 1
0x7001
,
// 30: out pins, 1 side 0
0x18fe
,
// 31: jmp !osre, 30 side 1
// .wrap
...
...
TFT_eSPI.cpp
View file @
284893c3
...
...
@@ -3214,7 +3214,7 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
#else
// This is for the RP2040 and PIO interface (SPI or parallel)
WAIT_FOR_STALL
;
pio->sm[pio_sm].instr = pio_instr_addr;
tft_
pio
->
sm
[
pio_sm
].
instr
=
pio_instr_addr
;
TX_FIFO
=
TFT_CASET
;
TX_FIFO
=
(
x0
<<
16
)
|
x1
;
...
...
@@ -3441,14 +3441,15 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
#else
// This is for the RP2040 and PIO interface (SPI or parallel)
WAIT_FOR_STALL
;
pio->sm[pio_sm].instr = pio_instr_addr;
tft_
pio
->
sm
[
pio_sm
].
instr
=
pio_instr_addr
;
TX_FIFO
=
TFT_CASET
;
TX_FIFO
=
(
x
<<
16
)
|
x
;
TX_FIFO
=
TFT_PASET
;
TX_FIFO
=
(
y
<<
16
)
|
y
;
TX_FIFO
=
TFT_RAMWR
;
//DC set high by PIO
tft_Write_16((uint16_t)color);
TX_FIFO
=
color
;
#endif
#else
...
...
@@ -3667,7 +3668,7 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t
** Description: Constants for anti-aliased line drawing on TFT and in Sprites
***************************************************************************************/
constexpr
float
PixelAlphaGain
=
255.0
;
constexpr float LoAlphaTheshold = 1.0/3
1
.0;
constexpr
float
LoAlphaTheshold
=
1.0
/
3
2
.0
;
constexpr
float
HiAlphaTheshold
=
1.0
-
LoAlphaTheshold
;
/***************************************************************************************
...
...
@@ -3677,9 +3678,9 @@ constexpr float HiAlphaTheshold = 1.0 - LoAlphaTheshold;
uint16_t
TFT_eSPI
::
drawPixel
(
int32_t
x
,
int32_t
y
,
uint32_t
color
,
uint8_t
alpha
,
uint32_t
bg_color
)
{
if
(
bg_color
==
0x00FFFFFF
)
bg_color
=
readPixel
(
x
,
y
);
bg_
color = alphaBlend(alpha, color, bg_color);
drawPixel(x, y,
bg_
color);
return
bg_
color;
color
=
alphaBlend
(
alpha
,
color
,
bg_color
);
drawPixel
(
x
,
y
,
color
);
return
color
;
}
/***************************************************************************************
...
...
@@ -3688,27 +3689,45 @@ uint16_t TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha
***************************************************************************************/
void
TFT_eSPI
::
fillSmoothCircle
(
int32_t
x
,
int32_t
y
,
int32_t
r
,
uint32_t
color
,
uint32_t
bg_color
)
{
if
(
r
<=
0
)
return
;
inTransaction
=
true
;
int16_t xs = 0;
int16_t cx;
drawFastHLine
(
x
-
r
,
y
,
2
*
r
+
1
,
color
);
int32_t
xs
=
1
;
int32_t
cx
=
0
;
int32_t
r1
=
r
*
r
;
r
++
;
for (int16_t cy = r; cy > 0; cy--)
int32_t
r2
=
r
*
r
;
for
(
int32_t
cy
=
r
-
1
;
cy
>
0
;
cy
--
)
{
for (cx = xs; cx <= xs + 1 && cx < r; cx++)
int32_t
dy2
=
(
r
-
cy
)
*
(
r
-
cy
);
for
(
cx
=
xs
;
cx
<
r
;
cx
++
)
{
float deltaX = r - cx;
float deltaY = r - cy;
float alphaf = r - sqrtf(deltaX * deltaX + deltaY * deltaY);
if (alphaf > 1.0) continue;
int32_t
hyp2
=
(
r
-
cx
)
*
(
r
-
cx
)
+
dy2
;
if
(
hyp2
<=
r1
)
break
;
if
(
hyp2
>=
r2
)
continue
;
float
alphaf
=
(
float
)
r
-
sqrtf
(
hyp2
);
if
(
alphaf
>
HiAlphaTheshold
)
break
;
xs
=
cx
;
if
(
alphaf
<
LoAlphaTheshold
)
continue
;
uint8_t
alpha
=
alphaf
*
255
;
if
(
bg_color
==
0x00FFFFFF
)
{
drawPixel
(
x
+
cx
-
r
,
y
+
cy
-
r
,
color
,
alpha
,
bg_color
);
drawPixel
(
x
-
cx
+
r
,
y
+
cy
-
r
,
color
,
alpha
,
bg_color
);
drawPixel
(
x
-
cx
+
r
,
y
-
cy
+
r
,
color
,
alpha
,
bg_color
);
drawPixel
(
x
+
cx
-
r
,
y
-
cy
+
r
,
color
,
alpha
,
bg_color
);
}
cx--;
else
{
uint16_t
pcol
=
drawPixel
(
x
+
cx
-
r
,
y
+
cy
-
r
,
color
,
alpha
,
bg_color
);
drawPixel
(
x
-
cx
+
r
,
y
+
cy
-
r
,
pcol
);
drawPixel
(
x
-
cx
+
r
,
y
-
cy
+
r
,
pcol
);
drawPixel
(
x
+
cx
-
r
,
y
-
cy
+
r
,
pcol
);
}
}
drawFastHLine
(
x
+
cx
-
r
,
y
+
cy
-
r
,
2
*
(
r
-
cx
)
+
1
,
color
);
drawFastHLine
(
x
+
cx
-
r
,
y
-
cy
+
r
,
2
*
(
r
-
cx
)
+
1
,
color
);
}
...
...
@@ -3716,40 +3735,45 @@ void TFT_eSPI::fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color,
end_tft_write
();
}
/***************************************************************************************
** Function name: fillSmooth
Circle
** Description: Draw a filled anti-aliased
circ
le
** Function name: fillSmooth
RoundRect
** Description: Draw a filled anti-aliased
rounded corner rectang
le
***************************************************************************************/
void
TFT_eSPI
::
fillSmoothRoundRect
(
int32_t
x
,
int32_t
y
,
int32_t
w
,
int32_t
h
,
int32_t
r
,
uint32_t
color
,
uint32_t
bg_color
)
{
inTransaction
=
true
;
int
16
_t xs = 0;
int
16_t cx
;
int
32
_t
xs
=
0
;
int
32_t
cx
=
0
;
y
+=
r
;
h
-=
2
*
r
;
fillRect(x, y, w, h, color);
fillRect
(
x
,
y
,
w
,
h
+
1
,
color
);
x
+=
r
;
w
-=
2
*
r
+
1
;
int32_t
r1
=
r
*
r
;
r
++
;
int32_t
r2
=
r
*
r
;
for (int
16_t cy = r
; cy > 0; cy--)
for
(
int
32_t
cy
=
r
-
1
;
cy
>
0
;
cy
--
)
{
for (cx = xs; cx <= xs + 1 && cx < r; cx++)
int32_t
dy2
=
(
r
-
cy
)
*
(
r
-
cy
);
for
(
cx
=
xs
;
cx
<
r
;
cx
++
)
{
float deltaX = r - cx;
float deltaY = r - cy;
float weight = r - sqrtf(deltaX * deltaX + deltaY * deltaY);
if (weight > 1.0) continue;
int32_t
hyp2
=
(
r
-
cx
)
*
(
r
-
cx
)
+
dy2
;
if
(
hyp2
<=
r1
)
break
;
if
(
hyp2
>=
r2
)
continue
;
float
alphaf
=
(
float
)
r
-
sqrtf
(
hyp2
);
if
(
alphaf
>
HiAlphaTheshold
)
break
;
xs
=
cx
;
if (weight < LoAlphaTheshold) continue;
uint8_t alpha = weight * 255;
if
(
alphaf
<
LoAlphaTheshold
)
continue
;
uint8_t
alpha
=
alphaf
*
255
;
drawPixel
(
x
+
cx
-
r
,
y
+
cy
-
r
,
color
,
alpha
,
bg_color
);
drawPixel
(
x
-
cx
+
r
+
w
,
y
+
cy
-
r
,
color
,
alpha
,
bg_color
);
drawPixel
(
x
-
cx
+
r
+
w
,
y
-
cy
+
r
+
h
,
color
,
alpha
,
bg_color
);
drawPixel
(
x
+
cx
-
r
,
y
-
cy
+
r
+
h
,
color
,
alpha
,
bg_color
);
}
cx--;
drawFastHLine
(
x
+
cx
-
r
,
y
+
cy
-
r
,
2
*
(
r
-
cx
)
+
1
+
w
,
color
);
drawFastHLine
(
x
+
cx
-
r
,
y
-
cy
+
r
+
h
,
2
*
(
r
-
cx
)
+
1
+
w
,
color
);
}
...
...
TFT_eSPI.h
View file @
284893c3
...
...
@@ -16,7 +16,7 @@
#ifndef _TFT_eSPIH_
#define _TFT_eSPIH_
#define TFT_ESPI_VERSION "2.4.4
0
"
#define TFT_ESPI_VERSION "2.4.4
1
"
// Bit level feature flags
// Bit 0 set: viewport capability
...
...
library.json
View file @
284893c3
{
"name"
:
"TFT_eSPI"
,
"version"
:
"2.4.4
0
"
,
"version"
:
"2.4.4
1
"
,
"keywords"
:
"Arduino, tft, ePaper, display, Pico, RP2040, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9481, ILI9486, ILI9488, ST7789, RM68140, SSD1351, SSD1963, ILI9225, HX8357D"
,
"description"
:
"A TFT and ePaper SPI graphics library with optimisation for Raspberry Pi Pico, ESP8266, ESP32 and STM32"
,
"repository"
:
...
...
library.properties
View file @
284893c3
name
=
TFT_eSPI
version
=
2.4.4
0
version
=
2.4.4
1
author
=
Bodmer
maintainer
=
Bodmer
sentence
=
TFT graphics library for Arduino processors with performance optimisation for RP2040, STM32, ESP8266 and ESP32
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment