Compare commits

...

204 Commits

Author SHA1 Message Date
Bodmer 8c83eb84bd Add half duplex SDA read to ESP32 S2
Add half duplex SDA read to ESP32 S2 (tested)
Add new setup example for S2 and ST7735 with SDA pin
Remove commented out code
Raise version
2023-01-31 18:57:30 +00:00
Bodmer c08763ca44 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2023-01-30 20:14:07 +00:00
Bodmer 3670949658 Update TFT_eSPI_ESP32_S3.h 2023-01-30 20:13:57 +00:00
Dracir 326e4a722f
Fix minor bug (#2349)
The default configuration did not correspond to any of the possible choices.
2023-01-25 10:38:21 +00:00
Bodmer e94a7491a3
Update README.md 2023-01-24 05:28:12 +00:00
Bodmer 1db5f438b3
Update README.md 2023-01-24 03:38:40 +00:00
Bodmer 01f217fba1
Update README.md 2023-01-23 14:41:14 +00:00
Bodmer 5f5fef5419 Add DMA capability to ESP32 S3
DMA examples all tested and run as expected.
2023-01-23 14:32:01 +00:00
Bodmer 6e291a9176 Revert "Update iaw #2341"
This reverts commit c6bcfa9db9.
2023-01-22 18:18:08 +00:00
Bodmer c133cf1523 Revert "Update iaw #2341"
This reverts commit 21b27258f7.
2023-01-22 18:17:43 +00:00
Bodmer a6909486a4 Raise version to 2.5.1 2023-01-22 00:39:10 +00:00
Bodmer 21b27258f7
Update iaw #2341
16 bit shown to work with SPI and ILI9486
2023-01-22 00:13:01 +00:00
Bodmer c6bcfa9db9
Update iaw #2341
16 bit SPI shown to work with ILI9486
2023-01-22 00:10:50 +00:00
Bodmer d6064fe141
Fix #2326 2023-01-17 07:16:20 +00:00
Bodmer 01b8420b97
Update README.md 2023-01-16 16:04:07 +00:00
Bodmer c04fa09251
Update README.md 2023-01-16 16:01:29 +00:00
Bodmer 21ee26071c
Update README.md 2023-01-16 14:59:50 +00:00
Bodmer f35b4366ac
Update README.md 2023-01-16 14:58:07 +00:00
Bodmer 19c745e4f8
Update README.md 2023-01-16 13:59:11 +00:00
Bodmer 6545e032b0
Update README.md 2023-01-16 13:48:07 +00:00
Bodmer b2d20d6d39
Update README.md 2023-01-16 13:00:28 +00:00
Bodmer c6d600b4a1 Fix #2297
The SSD1963 requires 18 bit colour in 3 bytes when an 8 bit parallel interface is used.

Added new PIO parallel code
2023-01-16 12:37:32 +00:00
Bodmer 890f6ff2b9 Update drawArc, add new example 2023-01-14 22:40:17 +00:00
Bodmer 19eadee669 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2023-01-13 21:23:23 +00:00
Bodmer e6024025c0 Correct sketch name 2023-01-13 21:23:21 +00:00
Bodmer 6414f511c5
Update library.properties 2023-01-13 18:09:34 +00:00
Bodmer bd33fc3ff9 Update ST7789_Init.h 2023-01-13 16:45:59 +00:00
Bodmer c208a31a26 Revert "Update Setup206_LilyGo_T_Display_S3.h"
This reverts commit 7b67abc797.
2023-01-13 16:45:44 +00:00
Bodmer 7b67abc797
Update Setup206_LilyGo_T_Display_S3.h 2023-01-13 16:27:30 +00:00
Bodmer 90c3511913 Update for high GPIO 2023-01-13 16:20:11 +00:00
Bodmer 1a50a23561
Add LilyGo_T_HMI setup file 2023-01-13 16:06:58 +00:00
lbuque beaf30cc97
Added T-HMI support (#2318)
* Added T-HMI support

Signed-off-by: lbuque <1102390310@qq.com>

* Update Setup207_LilyGo_T_HMI.h

Signed-off-by: lbuque <1102390310@qq.com>
Co-authored-by: Bodmer <Bodmer@users.noreply.github.com>
2023-01-13 16:05:23 +00:00
Bodmer b5edd54f6e Add more examples
Transparent PNG
Smooth graphics
2023-01-13 15:17:02 +00:00
Bodmer 954a3a5ed3 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2023-01-13 02:12:05 +00:00
Bodmer 1549705b96 Update .gitignore 2023-01-13 02:11:55 +00:00
Bodmer 1a6aa0476b
Update User_Setup_Select.h 2023-01-13 02:09:57 +00:00
Bodmer 79345ca72d Delete spurious files 2023-01-13 01:51:00 +00:00
Bodmer 9f829679e7 Update README.md 2023-01-13 01:48:13 +00:00
Bodmer d6b868fe79 Raise version 2023-01-13 01:37:57 +00:00
Bodmer f33836faac
T display s3 (#2317)
* Added T-DISPLAY-S3 i8080 support for more than 33 data pins (#2296)

* Modified the ESP32-S3 I8080 interface's support for data pins above 33 pins.

* Added T-DISPLAY-S3 support

* Update Setup206_LilyGo_T_Display_S3.h

* Eliminate need for TFT_DATA_PIN_OFFSET_EN in setup file

* Update TFT_eSPI_ESP32_S3.h

* Update User_Setup_Select.h

* Add new init sequence for LilyGo T Display S3

Co-authored-by: Micky <513673326@qq.com>
2023-01-13 01:33:57 +00:00
Bodmer d37f202b94
Arc test (#2316)
* Add smooth arc drawing function

Update ESP8266 architecture reference
Add pushMaskedImage() to render 16bpp images with a 1bpp mask (used for transparent PNG images plus with sprites)

New functions added using drawArc:
drawSmoothArc
drawSmoothCircle
drawSmoothRoundRect
New sqrt_fraction() added to improve smooth graphics performance on processors without a FPU (e.g. RP2040)

Faster alphaBlend() function added which retains 6bpp for green

Rename swap_coord() to transpose()

* Update TFT_eSPI.cpp

* Add arc examples
2023-01-13 01:31:57 +00:00
Bodmer ea82a7c15a
Update Setup25_TTGO_T_Display.h 2023-01-06 10:29:52 +00:00
Bodmer 91b8e248d3 Remove example
The use of a setup file in sketches only works in certain circumstances.
2023-01-03 22:20:48 +00:00
Bodmer 024453fc1e
Update README.md 2023-01-03 22:14:58 +00:00
Bodmer cc1e00d663
Update README.md 2022-12-23 22:54:56 +00:00
Bodmer 0b5512727e
Update README.md 2022-12-18 03:25:00 +00:00
Bodmer 5ab29abf30
Typo 2022-12-12 11:04:08 +00:00
Bodmer b287023ac4
Update 2022-12-12 11:03:13 +00:00
Bodmer 92f980be85
Delete untested. 2022-12-09 12:14:58 +00:00
Bodmer 8013821ad8
Update README.md 2022-11-29 22:02:51 +00:00
Bodmer 31a5ccd02e Make ESP32 family handle SPIFFS and LittleFS consistently 2022-11-29 21:55:53 +00:00
Bodmer 0fd239c751
Update README.md 2022-11-24 14:09:20 +00:00
Bodmer 543c5a3b54
Update README.md 2022-11-24 14:08:53 +00:00
Bodmer 0490b94287
Merge pull request #2195 from supcik/discussion-2191
Enable HSPI configuration for ESP-IDF
2022-11-21 22:36:54 +00:00
Jacques Supcik 6ee13641cf Enable HSPI configuration for ESP-IDF 2022-11-21 13:39:16 +01:00
Bodmer ef7c020980
Update README.md 2022-11-11 04:09:37 +00:00
Bodmer 1b07eeb980
Update README.md 2022-11-11 03:27:26 +00:00
Bodmer 48d729c2e7
Update README.md 2022-11-11 03:26:10 +00:00
Bodmer 2b6833220a
Update README.md 2022-11-11 03:16:38 +00:00
Bodmer 15cedf1e24
Merge pull request #2142 from goutamreddy/patch-2
Update Using ESP-IDF.txt
2022-11-07 23:28:06 +00:00
goutamreddy bdeeb131ad
Update Using ESP-IDF.txt
clarified instructions for not using KConfig file
2022-11-06 08:24:29 -08:00
Bodmer 421377e8bc Update Using ESP-IDF.txt 2022-11-06 00:47:01 +00:00
Bodmer c23fffe414 Add ESP-IDF basic instructions to docs folder
Note: The library author (Bodmer) does not use the ESP-IDF and therefore does not provide support for that route!
2022-11-05 21:48:06 +00:00
Bodmer f02b09a380 Update ILI9481 init code as in #2120 2022-11-05 20:37:29 +00:00
Bodmer 3c6dab0a52 Add ability to set the RP2040 parallel interface speed
// For RP2040 processor and 8 or 16 bit parallel displays:
// The parallel interface write cycle period is derived from a division of the CPU clock
// speed so scales with the processor clock. This means that the divider ratio may need
// to be increased when overclocking. I may also need to be adjusted dependant on the
// display controller type (ILI94341, HX8357C etc). If RP2040_PIO_CLK_DIV is not defined
// the library will set default values which may not suit your display.
// The display controller data sheet will specify the minimum write cycle period. The
// controllers often work reliably for shorter periods, however if the period is too short
// the display may not initialise or graphics will become corrupted.
// PIO write cycle frequency = (CPU clock/(4 * RP2040_PIO_CLK_DIV))
//#define RP2040_PIO_CLK_DIV 1 // 32ns write cycle at 125MHz CPU clock
#define RP2040_PIO_CLK_DIV 2 // 64ns write cycle at 125MHz CPU clock
//#define RP2040_PIO_CLK_DIV 3 // 96ns write cycle at 125MHz CPU clock
2022-11-05 18:12:28 +00:00
Bodmer 64a31ef252 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2022-11-03 22:24:16 +00:00
Bodmer d3a715da1e Fix #2103 and update for latest ESP8266 board package
Fix H and V gradient use in sprite
New ESP8266 board package uses RDUINO_ARCH_ESP8266
old package defined ESP8266
2022-11-03 22:24:00 +00:00
Bodmer 3d2b9ae3a2
Merge pull request #2126 from goodsoft/patch-1
Fix typo and remove unnecessary error in TFT_config.h
2022-11-01 21:01:13 +00:00
Paul Tsupikoff 6c74d55292
Fix typo and remove unnecessary error in TFT_config.h
1. RGB configuration was configured incorrectly, and caused re-definition warnings.
2. MISO pin is not always set, so shouldn't trigger a compilation error (see e.g. `Setup25_TTGO_T_DISPLAY.h`).
2022-10-31 17:42:07 +01:00
Bodmer 67e41c75f2 Allow ESP32 DC pin to be >31 2022-10-19 23:05:25 +01:00
Bodmer 13e62a88d0
Merge pull request #2075 from xidameng/master
Create Setup301_BW16_ST7735.h for BW16-based Boards
2022-10-15 10:54:22 +01:00
SimonXI dd5f74c956
Update User_Setup_Select.h 2022-10-15 11:33:46 +08:00
Bodmer c15257ad00
Update library.json 2022-10-14 22:46:42 +01:00
Bodmer 5a493559d0
Update Setup301_BW16_ST7735.h 2022-10-14 00:09:05 +01:00
Bodmer f106fb03ac Fix #2080
Forgot to copy over updated file!
2022-10-13 23:21:03 +01:00
SimonXI f0889e11f0
Create Setup301_BW16_ST7735.h
This configuration works on all BW16 boards
2022-10-13 10:00:33 +08:00
Bodmer f94fb28737 Fix #1893
Problem has not been reproduced but names changes anyway.
2022-10-13 01:21:21 +01:00
Bodmer 7c9e1cbbd1 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2022-10-12 23:50:32 +01:00
Bodmer 49f44e41aa Fix #1960
TFT pixel reads for smooth graphics functions now supported.
2022-10-12 23:50:28 +01:00
Bodmer ca024b4514
Merge pull request #1974 from boul51/master
ST7735: fix RGB/BGR selection
2022-10-12 22:42:49 +01:00
Bodmer a3015f0090
Update pio_SPI_18bit.pio.h 2022-10-12 22:04:12 +01:00
Bodmer 7b529eef06
Update pio_SPI.pio.h 2022-10-12 22:03:14 +01:00
Bodmer 1e8eb39135
Update pio_SPI.pio.h 2022-10-12 22:02:49 +01:00
Bodmer 33be3070bf
Update pio_SPI.pio.h 2022-10-12 22:02:18 +01:00
Bodmer fc8228acae
Update pio_8bit_parallel.pio.h 2022-10-12 22:00:58 +01:00
Bodmer f1bae721c8
Update pio_16bit_parallel.pio.h 2022-10-12 22:00:19 +01:00
Bodmer 8b454bc19d
Delete pio_SPI_18bit.pio 2022-10-12 21:58:57 +01:00
Bodmer b2e0bd855c
Delete pio_16bit_parallel.pio 2022-10-12 21:58:42 +01:00
Bodmer 48499856ac
Delete pio_8bit_parallel.pio 2022-10-12 21:58:31 +01:00
Bodmer eea916d221
Delete pio_SPI.pio 2022-10-12 21:58:18 +01:00
Bodmer d1bb18bdde Various tweaks and bug fixes 2022-10-10 19:02:05 +01:00
Bodmer 385cb5423e
Update README.md 2022-10-09 23:08:42 +01:00
Bodmer f20b5ef55e
Update README.md 2022-10-09 23:07:25 +01:00
Bodmer 4573e30d59
Update README.md 2022-10-09 23:06:43 +01:00
Bodmer 83b501bd9d
Update README.md 2022-10-09 23:05:27 +01:00
Bodmer 967ccfcd3c
Update README.md 2022-10-09 23:04:23 +01:00
Bodmer 2b6a41c53a
Update issue-template.md 2022-10-09 16:26:02 +01:00
Bodmer 33e6c3580d
Update issue-template.md 2022-10-09 16:25:05 +01:00
Bodmer b3c8287114
Update issue-template.md 2022-10-09 16:24:38 +01:00
Bodmer 450941382b
Update issue-template.md 2022-10-09 16:24:02 +01:00
Bodmer db309cc407
Update issue-template.md 2022-10-09 16:22:11 +01:00
Bodmer 7562720dc9
Update issue-template.md 2022-10-09 16:18:07 +01:00
Bodmer 532efe4b02
Update issue-template.md 2022-10-09 16:17:24 +01:00
Bodmer 2b576dc614
Fix #2018 2022-09-14 12:07:39 +01:00
Bodmer de688f5ae7 Move sketch tft_setup.h checking code 2022-09-11 13:51:11 +01:00
Bodmer e446f65ff9 Add compiler __has_include macro check 2022-09-10 15:35:46 +01:00
Bodmer 5592f603dd tft_setup.h is included by library if it exists in sketch 2022-09-10 15:29:28 +01:00
Bodmer c35e73a9cc Another typo 2022-09-10 15:27:54 +01:00
Bodmer 7b2cb1dfbd Another typo 2022-09-10 15:26:40 +01:00
Bodmer a0dd2db654 Fix typo 2022-09-10 14:06:18 +01:00
Bodmer f9f9a4ba63 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2022-09-10 13:49:00 +01:00
Bodmer 55477b58b2 Update for setup within sketch option
The TFT configuration (user setup) can now be included inside an Arduino IDE sketch providing the instructions in the example Generic->Sketch_with_tft_setup are followed. See ReadMe tab in that sketch for the instructions.
2022-09-10 13:48:56 +01:00
Bodmer afd72efb5a
Fix #1983 2022-08-25 09:41:04 +01:00
Nicolas Boulicault 2882f1d794 ST7735: Add support for RobotLCD Arduino shield
Without this change, my LCD screen only displays some bars on the screen after init.
2022-08-23 18:17:56 +02:00
Nicolas Boulicault 0416870179 ST7735: fix RGB/BGR selection issue due to ST7735_XXX vs INITR_XXX confusion
Without this change, color order is always set to RGB,
no matter what ST7735_XXX value is defined in User_Setup.h
2022-08-21 19:20:23 +02:00
Bodmer 333f0f845c Correct Widget examples 2022-08-14 13:35:23 +01:00
Bodmer 90fe790ff9 Fix meters Widget example 2022-08-11 15:43:11 +01:00
Bodmer cc9787deaf Update for Pico W, update sprite smooth font rendering
Update example for Pico W

If a background colour is not specified for smooth font rendering in a sprite then read the sprite background pixel colour.
2022-07-22 20:16:56 +01:00
Bodmer ec23732c11 Update ReadMe and raise version to 2.4.73 2022-07-22 18:17:09 +01:00
Bodmer f2d8d2f26d Add new examples and ST7789 320x170 support
GUI examples require an extension library:

https://github.com/Bodmer/TFT_eWidget
2022-07-22 18:09:09 +01:00
Bodmer d94408bdaa Fix #1758
As proposed in #1914
2022-07-19 12:29:41 +01:00
Bodmer a0bfb52386
Update README.md 2022-07-09 11:24:41 +01:00
Bodmer 345f39127c
Merge pull request #1900 from ivankravets/patch-2
Fix dev-platform name for raspberrypi
2022-07-09 11:22:30 +01:00
Ivan Kravets 5efbb617ea
Fix dev-platform name for raspberrypi 2022-07-07 15:00:46 +03:00
Bodmer 23df2a9628 Update TFT_eSPI.h 2022-06-18 17:51:21 +01:00
Bodmer 0094ee744a Add setup for ESP32 with ILI9341 SPI display 2022-06-18 17:50:42 +01:00
Bodmer 483459ba9b Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2022-06-16 23:31:09 +01:00
Bodmer 781b0bc67c Fix #1877 2022-06-16 23:31:07 +01:00
Bodmer 27963e00cc
Merge pull request #1857 from DustinWatts/master
Added User Setups for ESP32 TouchDowns
2022-06-11 14:03:28 +01:00
Dustin Watts 2cfc5c5a52 Revert Back to original User_Setup.h 2022-05-30 11:19:53 +02:00
Dustin Watts ead97168ab Changed User_Setup.h for test compile 2022-05-30 09:25:08 +02:00
Dustin Watts d6974252f3 Added User Setups for ESP32 TouchDowns
- Added Setup204_ESP32_TouchDown.h
- Added Setup205_ESP32_TouchDown_S3.h
- Included those in User_Setup_Select.h
2022-05-29 21:39:37 +02:00
Bodmer 4ced37add4
Merge pull request #1838 from dracir9/master
Fix ESP-IDF header include issue
2022-05-21 14:02:25 +01:00
Dracir a9f435eced Fix ESP-IDF header include issue 2022-05-21 11:59:07 +02:00
Bodmer ba819765af Avoid warnings if fonts disabled in setup 2022-05-19 21:47:01 +01:00
Bodmer bed65958e5 Correct driver in setups 2022-05-16 23:34:07 +01:00
Bodmer 59d0e36d36 Update README.md 2022-05-16 20:02:27 +01:00
Bodmer 7bf48bb179 Add 16 bit parallel for RP2040 processor
Correct legacy comments
Add ESP32 S3 parallel setup 70d
Add setups 105-107 for RP2040 with 16 bit display
Add file conversion notes to PNG array example
2022-05-16 19:58:05 +01:00
Bodmer 84238dde70
Clarification 2022-05-10 09:44:02 +01:00
Bodmer 7d5fe20e43
Update issue-template.md 2022-05-04 02:57:13 +01:00
Bodmer 1f7ce88dbe
Fix #1812
Result of "fillheight = gFont.maxAscent - gdY[gNum];" can be negative.
2022-05-03 18:23:22 +01:00
Bodmer 24b0e88852
ESP32 C3 and S3 support tested
ESP32 C3 tested with SPI (8 bit parallel probably works - TBC)
ESP32 S3 tested with SPI and 8 bit parallel
2022-04-30 13:31:42 +01:00
Bodmer fe5609e367
Fix #1802 2022-04-30 12:48:41 +01:00
Bodmer d883856dc0 Update for HX8357B/C driver 2022-04-29 22:58:19 +01:00
Bodmer 8e0e7183c2 Add HX8357B/C drivers
Only tested with 16 bit parallel interface
2022-04-29 22:42:16 +01:00
Bodmer 7b5f98a638 Add RM68120 driver (UNTESTED!) 2022-04-29 22:39:24 +01:00
Bodmer 6b1b2006a2 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2022-04-29 22:26:42 +01:00
Bodmer 59dfae94b2 Associate setups with processor variant
Add ILI9342
Fix M5Stack setup name
2022-04-29 22:26:29 +01:00
Bodmer 073696d8c7
Update README.md 2022-04-29 22:05:10 +01:00
Bodmer fa1613f32e
Update README.md 2022-04-29 22:02:12 +01:00
Bodmer d9acc229bf Update README.md 2022-04-29 22:01:06 +01:00
Bodmer 7d3f4f21b1 Fix #1802 2022-04-29 20:59:25 +01:00
Bodmer 673de31fab Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2022-04-28 14:19:12 +01:00
Bodmer f7e9a91ead Fix #1800 Fix #1793
Added offsets for 170x320 ST7789 display
Added offsets for 240x280 display to ST7789_2 dirver
2022-04-28 14:19:05 +01:00
Bodmer 22901f5d6e
Fix #1802
setTextColor has a new parameter for smooth fonts to force background fill.
2022-04-28 10:26:11 +01:00
Bodmer 79b41bc833 Add #define to disable warnings (#1788)
// Define in setup to disable all #warnings in library (can be put in User_Setup_Select.h)
#define DISABLE_ALL_LIBRARY_WARNINGS
2022-04-27 22:28:52 +01:00
Bodmer f0ec6d22b3 Add ESP32 C3 support
Tested with Stamp C3
2022-04-27 21:57:11 +01:00
Bodmer 18a76f1c65 Support Adafruit 240x280 ST7789 screen 2022-04-26 21:57:42 +01:00
Bodmer e09230c9ac Raise version to 2.4.60 2022-04-25 02:29:08 +01:00
Bodmer d655e1383a
Merge pull request #1789 from Bodmer/ESP32_S3
ESP32 S3 (tested) plus ESP32 C3 (untested but compiles!) support added
2022-04-24 21:36:22 +01:00
Bodmer cfb4689c85 Patch for ESP32 C3 - may or may not work!
I do NOT have and ESP32 C3 to test with!
2022-04-24 04:00:36 +01:00
Bodmer d0cc0a89d8
Update issue templates 2022-04-24 01:43:27 +01:00
Bodmer 073b5233d4
Update issue templates 2022-04-24 01:31:48 +01:00
Bodmer 416a84e535 Update Setup70b_ESP32_S3_ILI9341.h 2022-04-24 00:53:05 +01:00
Bodmer 4e8af767bd Fix bug for ESP32 with 8 bit parallel SSD1963 2022-04-23 19:26:20 +01:00
Bodmer 89a2457ca9 Update to fix ESP32 S3 with ILI9488 2022-04-22 22:48:07 +01:00
Bodmer a1b6240370
Update TFT_eSPI_ESP32_S3.c 2022-04-22 21:54:13 +01:00
Bodmer 0141bf6842
Update TFT_eSPI.h 2022-04-22 21:33:03 +01:00
Bodmer f8c995ca11
Update library.json 2022-04-22 21:31:29 +01:00
Bodmer 908b46165b
Update library.properties 2022-04-22 21:30:53 +01:00
Bodmer f624d5059c
Update TFT_eSPI_ESP32.c 2022-04-22 21:27:33 +01:00
Bodmer 38b52a46a1
Update TFT_eSPI_ESP32.c 2022-04-22 21:26:22 +01:00
Bodmer 89c0028a36
Update Setup70b_ESP32_S3_ILI9341.h 2022-04-22 02:57:46 +01:00
Bodmer a815d77ec4 S3 update 2 2022-04-22 02:45:04 +01:00
Bodmer 338d56ca42 S3 update 2022-04-22 02:44:10 +01:00
Bodmer d6544c9cb4 Fix #1767 and update ILI9481 init code option 8 2022-04-21 18:32:26 +01:00
Bodmer 8582ff7e3e
Merge pull request #1786 from dracir9/master
Fix problem in PR #1770
2022-04-20 17:09:57 +01:00
Dracir 24a6a06a6b Merge upstream branch 'upstream/master' 2022-04-20 16:26:27 +02:00
dracir 433b9a5342 Merge branch 'master' of https://github.com/dracir9/TFT_eSPI 2022-04-20 13:52:18 +02:00
dracir 8dff74503f Add ESP32-S2 support 2022-04-20 13:52:15 +02:00
Bodmer 7f5b8a9181
Update README.md 2022-04-19 12:25:16 +01:00
Bodmer a0fa2c31bd Fill smooth font background if padding is set. 2022-04-18 22:57:47 +01:00
Bodmer 7fc8b99b64 Add new background fill approach to smooth fonts
A new background rendering approach is used for smooth fonts which almost eliminates flicker. tft.print... can now be used with a background rendered for smooth fonts. Font_Demo_1/2/3... examples have been updated.
A new "docs" folder has been created and files moved there. The Tools folder now only contains support tools.

#1757 fixed by using Arduino calls.

A new USER_SETUP_ID parameter can be added to setup files and checked via a new verifySetupID(id); function.

Version raised to v2.4.50
2022-04-18 19:15:40 +01:00
Bodmer d0494af057
Fix #1776 2022-04-14 15:14:45 +01:00
Bodmer f790c86818
Fix #1776 2022-04-14 15:12:14 +01:00
Dracir 42549673dc
Merge branch 'Bodmer:master' into master 2022-04-14 12:52:21 +02:00
dracir db15796b5d Merge branch 'master' of https://github.com/dracir9/TFT_eSPI 2022-04-14 12:51:16 +02:00
dracir c016ea65f0 Fix TFT_eSprite crash and improve menu 2022-04-14 12:51:11 +02:00
Bodmer 181a85f86f
Merge pull request #1770 from dracir9/master
ESP-IDF compatibility
2022-04-12 16:27:32 +01:00
Dracir 05d590e58c
Merge branch 'Bodmer:master' into master 2022-04-11 15:05:36 +02:00
dracir 1ab684e40d Add configuration defines 2022-04-11 12:20:38 +02:00
dracir 83cd940200 Add display configurations 2022-04-10 14:05:07 +02:00
Bodmer 8f0f8e517c
Fix #1764 2022-04-10 12:47:01 +01:00
dracir ff18c1b3b5 Add more displays 2022-04-10 13:35:08 +02:00
dracir 248c15d9e9 Add idf component files 2022-04-10 12:53:58 +02:00
Bodmer e52a0161e6 Fix #1760, fix #1763, fix #1764 2022-04-10 01:24:10 +01:00
Bodmer e4accc0d53
Update library.json 2022-04-10 00:44:12 +01:00
Bodmer 12fd90c345
Update Setup 62 2022-03-24 14:52:38 +00:00
Bodmer 652a26179e
Update link to adapted library pending pull. 2022-03-24 10:18:30 +00:00
Bodmer 6cd087ca7c Raise version to 2.4.44 2022-03-22 23:30:48 +00:00
Bodmer 0c935de08d 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.
2022-03-22 23:29:30 +00:00
Bodmer ba67e95f7c Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2022-03-22 23:10:24 +00:00
Bodmer 0b7c57fe0a Update User_Setup_Select.h
Correct missing RM68120_DRIVER
2022-03-22 23:10:13 +00:00
Bodmer 810aa98fc0
Fix #1735 2022-03-22 02:26:44 +00:00
177 changed files with 23268 additions and 7813 deletions

View File

@ -0,0 +1,36 @@
---
name: Issue template
about: Guide to content
title: ''
labels: ''
assignees: ''
---
Only raise issues for problems with the library and/or provided examples. Post questions, comments and useful tips etc in the "Discussions" section.
To minimise effort to resolve issues the following should be provided as a minimum:
1. A description of the problem and the conditions that cause it to occur
2. IDE (e.g. Arduino or PlatformIO)
3. TFT_eSPI library version (try the latest, the problem may have been resolved!) from the Manage Libraries... menu
4. Board package version (e.g. 2.0.3) available from the Boards Manager... menu
5. Procesor, e.g RP2040, ESP32 S3 etc
6. TFT driver (e.g. ILI9341), a link to the vendors product web page is useful too.
7. Interface type (SPI or parallel)
Plus further information as appropriate to the problem:
1. TFT to processor connections used
2. A zip file containing your setup file (just drag and drop in message window - do not paste in long files!)
3. A zip file containing a simple and complete example sketch that demonstrates the problem but needs no special hardware sensors or libraries.
4. Screen shot pictures showing the problem (just drag and drop in message window)
The idea is to provide sufficient information so I can setup the exact same (or sufficiently similar) scenario to investigate and resolve the issue without having a tedious ping-pong of Q&A.
DO NOT paste code directly into the issue. To correctly format code put three ticks ( ` character on key next to "1" key) at the start and end of short pasted code segments to avoid format/markup anomolies. [See here:](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#quoting-code)
Example output:
```
Serial.begin(115200);
tft.init();
```

5
.gitignore vendored
View File

@ -17,6 +17,11 @@ $RECYCLE.BIN/
# Windows shortcuts # Windows shortcuts
*.lnk *.lnk
# Arduino debug
debug.cfg
debug_custom.json
*.svd
# ========================= # =========================
# Operating System Files # Operating System Files
# ========================= # =========================

4
CMakeLists.txt Normal file
View File

@ -0,0 +1,4 @@
idf_component_register(SRCS "TFT_eSPI.cpp"
INCLUDE_DIRS "."
PRIV_REQUIRES arduino)

View File

@ -8,6 +8,8 @@ TFT_eSPI_Button::TFT_eSPI_Button(void) {
_yd = 0; _yd = 0;
_textdatum = MC_DATUM; _textdatum = MC_DATUM;
_label[9] = '\0'; _label[9] = '\0';
currstate = false;
laststate = false;
} }
// Classic initButton() function: pass center & size // Classic initButton() function: pass center & size

View File

@ -58,7 +58,7 @@ void TFT_eSPI::loadFont(String fontName, bool flash)
The bitmaps start next at 24 + (28 * gCount) bytes from the start of the file. The bitmaps start next at 24 + (28 * gCount) bytes from the start of the file.
Each pixel is 1 byte, an 8 bit Alpha value which represents the transparency from Each pixel is 1 byte, an 8 bit Alpha value which represents the transparency from
0xFF foreground colour, 0x00 background. The sketch uses a linear interpolation 0xFF foreground colour, 0x00 background. The library uses a linear interpolation
between the foreground and background RGB component colours. e.g. between the foreground and background RGB component colours. e.g.
pixelRed = ((fgRed * alpha) + (bgRed * (255 - alpha))/255 pixelRed = ((fgRed * alpha) + (bgRed * (255 - alpha))/255
To gain a performance advantage fixed point arithmetic is used with rounding and To gain a performance advantage fixed point arithmetic is used with rounding and
@ -86,7 +86,7 @@ void TFT_eSPI::loadFont(String fontName, bool flash)
// | gHeight ....@@@@@..@@ + + <-- baseline // | gHeight ....@@@@@..@@ + + <-- baseline
// | | ...........@@ | // | | ...........@@ |
// | | ...........@@ | gdY is the offset to the top edge of the bitmap // | | ...........@@ | gdY is the offset to the top edge of the bitmap
// | | .@@.......@@. descent plot top edge of bitmap at (cursorY + yAdvance - gdY) // | | .@@.......@@. descent plot top edge of bitmap at (cursorY + ascent - gdY)
// | + x..@@@@@@@..x | x marks the corner pixels of the bitmap // | + x..@@@@@@@..x | x marks the corner pixels of the bitmap
// | | // | |
// +---------------------------+ yAdvance is y delta for the next line, font size or (ascent + descent) // +---------------------------+ yAdvance is y delta for the next line, font size or (ascent + descent)
@ -206,7 +206,7 @@ void TFT_eSPI::loadMetrics(void)
// Different glyph sets have different ascent values not always based on "d", so we could get // Different glyph sets have different ascent values not always based on "d", so we could get
// the maximum glyph ascent by checking all characters. BUT this method can generate bad values // the maximum glyph ascent by checking all characters. BUT this method can generate bad values
// for non-existant glyphs, so we will reply on processing for the value and disable this code for now... // for non-existent glyphs, so we will reply on processing for the value and disable this code for now...
/* /*
if (gdY[gNum] > gFont.maxAscent) if (gdY[gNum] > gFont.maxAscent)
{ {
@ -316,7 +316,7 @@ uint32_t TFT_eSPI::readInt32(void)
#ifdef FONT_FS_AVAILABLE #ifdef FONT_FS_AVAILABLE
if (fs_font) { if (fs_font) {
val |= fontFile.read() << 24; val = fontFile.read() << 24;
val |= fontFile.read() << 16; val |= fontFile.read() << 16;
val |= fontFile.read() << 8; val |= fontFile.read() << 8;
val |= fontFile.read(); val |= fontFile.read();
@ -324,7 +324,7 @@ uint32_t TFT_eSPI::readInt32(void)
else else
#endif #endif
{ {
val |= pgm_read_byte(fontPtr++) << 24; val = pgm_read_byte(fontPtr++) << 24;
val |= pgm_read_byte(fontPtr++) << 16; val |= pgm_read_byte(fontPtr++) << 16;
val |= pgm_read_byte(fontPtr++) << 8; val |= pgm_read_byte(fontPtr++) << 8;
val |= pgm_read_byte(fontPtr++); val |= pgm_read_byte(fontPtr++);
@ -362,16 +362,27 @@ void TFT_eSPI::drawGlyph(uint16_t code)
uint16_t fg = textcolor; uint16_t fg = textcolor;
uint16_t bg = textbgcolor; uint16_t bg = textbgcolor;
// Check if cursor has moved
if (last_cursor_x != cursor_x)
{
bg_cursor_x = cursor_x;
last_cursor_x = cursor_x;
}
if (code < 0x21) if (code < 0x21)
{ {
if (code == 0x20) { if (code == 0x20) {
//if (fg!=bg) fillRect(cursor_x, cursor_y, gFont.spaceWidth, gFont.yAdvance, bg); if (_fillbg) fillRect(bg_cursor_x, cursor_y, (cursor_x + gFont.spaceWidth) - bg_cursor_x, gFont.yAdvance, bg);
cursor_x += gFont.spaceWidth; cursor_x += gFont.spaceWidth;
bg_cursor_x = cursor_x;
last_cursor_x = cursor_x;
return; return;
} }
if (code == '\n') { if (code == '\n') {
cursor_x = 0; cursor_x = 0;
bg_cursor_x = 0;
last_cursor_x = 0;
cursor_y += gFont.yAdvance; cursor_y += gFont.yAdvance;
if (textwrapY && (cursor_y >= height())) cursor_y = 0; if (textwrapY && (cursor_y >= height())) cursor_y = 0;
return; return;
@ -388,6 +399,7 @@ void TFT_eSPI::drawGlyph(uint16_t code)
{ {
cursor_y += gFont.yAdvance; cursor_y += gFont.yAdvance;
cursor_x = 0; cursor_x = 0;
bg_cursor_x = 0;
} }
if (textwrapY && ((cursor_y + gFont.yAdvance) >= height())) cursor_y = 0; if (textwrapY && ((cursor_y + gFont.yAdvance) >= height())) cursor_y = 0;
if (cursor_x == 0) cursor_x -= gdX[gNum]; if (cursor_x == 0) cursor_x -= gdX[gNum];
@ -398,7 +410,7 @@ void TFT_eSPI::drawGlyph(uint16_t code)
#ifdef FONT_FS_AVAILABLE #ifdef FONT_FS_AVAILABLE
if (fs_font) if (fs_font)
{ {
fontFile.seek(gBitmap[gNum], fs::SeekSet); // This is taking >30ms for a significant position shift fontFile.seek(gBitmap[gNum], fs::SeekSet);
pbuffer = (uint8_t*)malloc(gWidth[gNum]); pbuffer = (uint8_t*)malloc(gWidth[gNum]);
} }
#endif #endif
@ -406,15 +418,47 @@ void TFT_eSPI::drawGlyph(uint16_t code)
int16_t cy = cursor_y + gFont.maxAscent - gdY[gNum]; int16_t cy = cursor_y + gFont.maxAscent - gdY[gNum];
int16_t cx = cursor_x + gdX[gNum]; int16_t cx = cursor_x + gdX[gNum];
int16_t xs = cx; // if (cx > width() && bg_cursor_x > width()) return;
uint32_t dl = 0; // if (cursor_y > height()) return;
int16_t fxs = cx;
uint32_t fl = 0;
int16_t bxs = cx;
uint32_t bl = 0;
int16_t bx = 0;
uint8_t pixel; uint8_t pixel;
startWrite(); // Avoid slow ESP32 transaction overhead for every pixel startWrite(); // Avoid slow ESP32 transaction overhead for every pixel
//if (fg!=bg) fillRect(cursor_x, cursor_y, gxAdvance[gNum], gFont.yAdvance, bg); int16_t fillwidth = 0;
int16_t fillheight = 0;
for (int y = 0; y < gHeight[gNum]; y++) // Fill area above glyph
if (_fillbg) {
fillwidth = (cursor_x + gxAdvance[gNum]) - bg_cursor_x;
if (fillwidth > 0) {
fillheight = gFont.maxAscent - gdY[gNum];
// Could be negative
if (fillheight > 0) {
fillRect(bg_cursor_x, cursor_y, fillwidth, fillheight, textbgcolor);
}
}
else {
// Could be negative
fillwidth = 0;
}
// Fill any area to left of glyph
if (bg_cursor_x < cx) fillRect(bg_cursor_x, cy, cx - bg_cursor_x, gHeight[gNum], textbgcolor);
// Set x position in glyph area where background starts
if (bg_cursor_x > cx) bx = bg_cursor_x - cx;
// Fill any area to right of glyph
if (cx + gWidth[gNum] < cursor_x + gxAdvance[gNum]) {
fillRect(cx + gWidth[gNum], cy, (cursor_x + gxAdvance[gNum]) - (cx + gWidth[gNum]), gHeight[gNum], textbgcolor);
}
}
for (int32_t y = 0; y < gHeight[gNum]; y++)
{ {
#ifdef FONT_FS_AVAILABLE #ifdef FONT_FS_AVAILABLE
if (fs_font) { if (fs_font) {
@ -432,7 +476,8 @@ void TFT_eSPI::drawGlyph(uint16_t code)
} }
} }
#endif #endif
for (int x = 0; x < gWidth[gNum]; x++)
for (int32_t x = 0; x < gWidth[gNum]; x++)
{ {
#ifdef FONT_FS_AVAILABLE #ifdef FONT_FS_AVAILABLE
if (fs_font) pixel = pbuffer[x]; if (fs_font) pixel = pbuffer[x];
@ -442,28 +487,44 @@ void TFT_eSPI::drawGlyph(uint16_t code)
if (pixel) if (pixel)
{ {
if (bl) { drawFastHLine( bxs, y + cy, bl, bg); bl = 0; }
if (pixel != 0xFF) if (pixel != 0xFF)
{ {
if (dl) { if (fl) {
if (dl==1) drawPixel(xs, y + cy, fg); if (fl==1) drawPixel(fxs, y + cy, fg);
else drawFastHLine( xs, y + cy, dl, fg); else drawFastHLine( fxs, y + cy, fl, fg);
dl = 0; fl = 0;
} }
if (getColor) bg = getColor(x + cx, y + cy); if (getColor) bg = getColor(x + cx, y + cy);
drawPixel(x + cx, y + cy, alphaBlend(pixel, fg, bg)); drawPixel(x + cx, y + cy, alphaBlend(pixel, fg, bg));
} }
else else
{ {
if (dl==0) xs = x + cx; if (fl==0) fxs = x + cx;
dl++; fl++;
} }
} }
else else
{ {
if (dl) { drawFastHLine( xs, y + cy, dl, fg); dl = 0; } if (fl) { drawFastHLine( fxs, y + cy, fl, fg); fl = 0; }
if (_fillbg) {
if (x >= bx) {
if (bl==0) bxs = x + cx;
bl++;
}
}
} }
} }
if (dl) { drawFastHLine( xs, y + cy, dl, fg); dl = 0; } if (fl) { drawFastHLine( fxs, y + cy, fl, fg); fl = 0; }
if (bl) { drawFastHLine( bxs, y + cy, bl, bg); bl = 0; }
}
// Fill area below glyph
if (fillwidth > 0) {
fillheight = (cursor_y + gFont.yAdvance) - (cy + gHeight[gNum]);
if (fillheight > 0) {
fillRect(bg_cursor_x, cy + gHeight[gNum], fillwidth, fillheight, textbgcolor);
}
} }
if (pbuffer) free(pbuffer); if (pbuffer) free(pbuffer);
@ -472,10 +533,12 @@ void TFT_eSPI::drawGlyph(uint16_t code)
} }
else else
{ {
// Not a Unicode in font so draw a rectangle and move on cursor // Point code not in font so draw a rectangle and move on cursor
drawRect(cursor_x, cursor_y + gFont.maxAscent - gFont.ascent, gFont.spaceWidth, gFont.ascent, fg); drawRect(cursor_x, cursor_y + gFont.maxAscent - gFont.ascent, gFont.spaceWidth, gFont.ascent, fg);
cursor_x += gFont.spaceWidth + 1; cursor_x += gFont.spaceWidth + 1;
} }
bg_cursor_x = cursor_x;
last_cursor_x = cursor_x;
} }
/*************************************************************************************** /***************************************************************************************
@ -511,12 +574,9 @@ void TFT_eSPI::showFont(uint32_t td)
setCursor(cursorX, cursorY); setCursor(cursorX, cursorY);
drawGlyph(gUnicode[i]); drawGlyph(gUnicode[i]);
cursorX += gxAdvance[i]; cursorX += gxAdvance[i];
//cursorX += printToSprite( cursorX, cursorY, i );
yield(); yield();
} }
delay(timeDelay); delay(timeDelay);
fillScreen(textbgcolor); fillScreen(textbgcolor);
//fontFile.close();
} }

View File

@ -3,7 +3,7 @@
public: public:
// These are for the new antialiased fonts // These are for the new anti-aliased fonts
void loadFont(const uint8_t array[]); void loadFont(const uint8_t array[]);
#ifdef FONT_FS_AVAILABLE #ifdef FONT_FS_AVAILABLE
void loadFont(String fontName, fs::FS &ffs); void loadFont(String fontName, fs::FS &ffs);

View File

@ -335,6 +335,18 @@ int8_t TFT_eSprite::getColorDepth(void)
} }
/***************************************************************************************
** Function name: setBitmapColor
** Description: Set the 1bpp foreground foreground and background colour
***************************************************************************************/
void TFT_eSprite::setBitmapColor(uint16_t c, uint16_t b)
{
if (c == b) b = ~c;
_tft->bitmap_fg = c;
_tft->bitmap_bg = b;
}
/*************************************************************************************** /***************************************************************************************
** Function name: setPaletteColor ** Function name: setPaletteColor
** Description: Set the 4bpp palette color at the given index ** Description: Set the 4bpp palette color at the given index
@ -405,13 +417,13 @@ bool TFT_eSprite::pushRotated(int16_t angle, uint32_t transp)
int32_t yt = min_y - _tft->_yPivot; int32_t yt = min_y - _tft->_yPivot;
uint32_t xe = _dwidth << FP_SCALE; uint32_t xe = _dwidth << FP_SCALE;
uint32_t ye = _dheight << FP_SCALE; uint32_t ye = _dheight << FP_SCALE;
uint32_t tpcolor = transp; uint16_t tpcolor = (uint16_t)transp;
if (transp != 0x00FFFFFF) { if (transp != 0x00FFFFFF) {
if (_bpp == 4) tpcolor = _colorMap[transp & 0x0F]; if (_bpp == 4) tpcolor = _colorMap[transp & 0x0F];
tpcolor = tpcolor>>8 | tpcolor<<8; // Working with swapped color bytes tpcolor = tpcolor>>8 | tpcolor<<8; // Working with swapped color bytes
} }
_tft->startWrite(); // Avoid transaction overhead for every tft pixel _tft->startWrite(); // Avoid transaction overhead for every tft pixel
// Scan destination bounding box and fetch transformed pixels from source Sprite // Scan destination bounding box and fetch transformed pixels from source Sprite
for (int32_t y = min_y; y <= max_y; y++, yt++) { for (int32_t y = min_y; y <= max_y; y++, yt++) {
@ -429,7 +441,7 @@ bool TFT_eSprite::pushRotated(int16_t angle, uint32_t transp)
int32_t yp = ys >> FP_SCALE; int32_t yp = ys >> FP_SCALE;
if (_bpp == 16) {rp = _img[xp + yp * _iwidth]; } if (_bpp == 16) {rp = _img[xp + yp * _iwidth]; }
else { rp = readPixel(xp, yp); rp = (uint16_t)(rp>>8 | rp<<8); } else { rp = readPixel(xp, yp); rp = (uint16_t)(rp>>8 | rp<<8); }
if (tpcolor == rp) { if (transp != 0x00FFFFFF && tpcolor == rp) {
if (pixel_count) { if (pixel_count) {
// TFT window is already clipped, so this is faster than pushImage() // TFT window is already clipped, so this is faster than pushImage()
_tft->setWindow(x - pixel_count, y, x - 1, y); _tft->setWindow(x - pixel_count, y, x - 1, y);
@ -479,7 +491,7 @@ bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, uint32_t transp)
int32_t yt = min_y - spr->_yPivot; int32_t yt = min_y - spr->_yPivot;
uint32_t xe = _dwidth << FP_SCALE; uint32_t xe = _dwidth << FP_SCALE;
uint32_t ye = _dheight << FP_SCALE; uint32_t ye = _dheight << FP_SCALE;
uint32_t tpcolor = transp; uint16_t tpcolor = (uint16_t)transp;
if (transp != 0x00FFFFFF) { if (transp != 0x00FFFFFF) {
if (_bpp == 4) tpcolor = _colorMap[transp & 0x0F]; if (_bpp == 4) tpcolor = _colorMap[transp & 0x0F];
@ -505,7 +517,7 @@ bool TFT_eSprite::pushRotated(TFT_eSprite *spr, int16_t angle, uint32_t transp)
int32_t yp = ys >> FP_SCALE; int32_t yp = ys >> FP_SCALE;
if (_bpp == 16) rp = _img[xp + yp * _iwidth]; if (_bpp == 16) rp = _img[xp + yp * _iwidth];
else { rp = readPixel(xp, yp); rp = (uint16_t)(rp>>8 | rp<<8); } else { rp = readPixel(xp, yp); rp = (uint16_t)(rp>>8 | rp<<8); }
if (tpcolor == rp) { if (transp != 0x00FFFFFF && tpcolor == rp) {
if (pixel_count) { if (pixel_count) {
spr->pushImage(x - pixel_count, y, pixel_count, 1, sline_buffer); spr->pushImage(x - pixel_count, y, pixel_count, 1, sline_buffer);
pixel_count = 0; pixel_count = 0;
@ -705,7 +717,7 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
// 16bpp -> 16bpp // 16bpp -> 16bpp
// 16bpp -> 8bpp // 16bpp -> 8bpp
// 8bpp -> 8bpp // 8bpp -> 8bpp
// 4bpp -> 4bpp (note: color translation depends on the 2 sprites pallete colors) // 4bpp -> 4bpp (note: color translation depends on the 2 sprites palette colors)
// 1bpp -> 1bpp (note: color translation depends on the 2 sprites bitmap colors) // 1bpp -> 1bpp (note: color translation depends on the 2 sprites bitmap colors)
bool TFT_eSprite::pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y) bool TFT_eSprite::pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y)
@ -1245,8 +1257,8 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const u
// Intentionally not constrained to viewport area, does not manage 1bpp rotations // Intentionally not constrained to viewport area, does not manage 1bpp rotations
void TFT_eSprite::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1) void TFT_eSprite::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
{ {
if (x0 > x1) swap_coord(x0, x1); if (x0 > x1) transpose(x0, x1);
if (y0 > y1) swap_coord(y0, y1); if (y0 > y1) transpose(y0, y1);
int32_t w = width(); int32_t w = width();
int32_t h = height(); int32_t h = height();
@ -1543,7 +1555,7 @@ void TFT_eSprite::fillSprite(uint32_t color)
** Function name: width ** Function name: width
** Description: Return the width of sprite ** Description: Return the width of sprite
***************************************************************************************/ ***************************************************************************************/
// Return the size of the display // Return the size of the sprite
int16_t TFT_eSprite::width(void) int16_t TFT_eSprite::width(void)
{ {
if (!_created ) return 0; if (!_created ) return 0;
@ -1688,13 +1700,13 @@ void TFT_eSprite::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint3
bool steep = abs(y1 - y0) > abs(x1 - x0); bool steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) { if (steep) {
swap_coord(x0, y0); transpose(x0, y0);
swap_coord(x1, y1); transpose(x1, y1);
} }
if (x0 > x1) { if (x0 > x1) {
swap_coord(x0, x1); transpose(x0, x1);
swap_coord(y0, y1); transpose(y0, y1);
} }
int32_t dx = x1 - x0, dy = abs(y1 - y0);; int32_t dx = x1 - x0, dy = abs(y1 - y0);;
@ -1978,10 +1990,8 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
{ {
if ( _vpOoB || !_created ) return; if ( _vpOoB || !_created ) return;
if ((x >= _vpW - _xDatum) || // Clip right if ((x >= _vpW - _xDatum) || // Clip right
(y >= _vpH - _yDatum) || // Clip bottom (y >= _vpH - _yDatum)) // Clip bottom
((x + 6 * size - 1) < (_vpX - _xDatum)) || // Clip left
((y + 8 * size - 1) < (_vpY - _yDatum))) // Clip top
return; return;
if (c < 32) return; if (c < 32) return;
@ -1992,6 +2002,10 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
#endif #endif
//>>>>>>>>>>>>>>>>>> //>>>>>>>>>>>>>>>>>>
if (((x + 6 * size - 1) < (_vpX - _xDatum)) || // Clip left
((y + 8 * size - 1) < (_vpY - _yDatum))) // Clip top
return;
bool fillbg = (bg != color); bool fillbg = (bg != color);
if ((size==1) && fillbg) if ((size==1) && fillbg)
@ -2059,15 +2073,21 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
c -= pgm_read_word(&gfxFont->first); c -= pgm_read_word(&gfxFont->first);
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c]); GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c]);
uint8_t *bitmap = (uint8_t *)pgm_read_dword(&gfxFont->bitmap);
uint32_t bo = pgm_read_word(&glyph->bitmapOffset);
uint8_t w = pgm_read_byte(&glyph->width), uint8_t w = pgm_read_byte(&glyph->width),
h = pgm_read_byte(&glyph->height); h = pgm_read_byte(&glyph->height);
//xa = pgm_read_byte(&glyph->xAdvance);
int8_t xo = pgm_read_byte(&glyph->xOffset), int8_t xo = pgm_read_byte(&glyph->xOffset),
yo = pgm_read_byte(&glyph->yOffset); yo = pgm_read_byte(&glyph->yOffset);
if (((x + xo + w * size - 1) < (_vpX - _xDatum)) || // Clip left
((y + yo + h * size - 1) < (_vpY - _yDatum))) // Clip top
return;
uint8_t *bitmap = (uint8_t *)pgm_read_dword(&gfxFont->bitmap);
uint32_t bo = pgm_read_word(&glyph->bitmapOffset);
uint8_t xx, yy, bits=0, bit=0; uint8_t xx, yy, bits=0, bit=0;
//uint8_t xa = pgm_read_byte(&glyph->xAdvance);
int16_t xo16 = 0, yo16 = 0; int16_t xo16 = 0, yo16 = 0;
if(size > 1) { if(size > 1) {
@ -2107,6 +2127,12 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
#ifdef LOAD_GFXFF #ifdef LOAD_GFXFF
} // End classic vs custom font } // End classic vs custom font
#endif #endif
#else
#ifndef LOAD_GFXFF
color = color;
bg = bg;
size = size;
#endif
#endif #endif
} }
@ -2114,7 +2140,7 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uin
/*************************************************************************************** /***************************************************************************************
** Function name: drawChar ** Function name: drawChar
** Description: draw a unicode glyph onto the screen ** Description: draw a unicode glyph into the sprite
***************************************************************************************/ ***************************************************************************************/
// TODO: Rationalise with TFT_eSPI // TODO: Rationalise with TFT_eSPI
// Any UTF-8 decoding must be done before calling drawChar() // Any UTF-8 decoding must be done before calling drawChar()
@ -2366,6 +2392,17 @@ int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t fo
} }
// End of RLE font rendering // End of RLE font rendering
#endif #endif
#if !defined (LOAD_FONT2) && !defined (LOAD_RLE)
// Stop warnings
flash_address = flash_address;
w = w;
pX = pX;
pY = pY;
line = line;
clip = clip;
#endif
return width * textsize; // x + return width * textsize; // x +
} }
@ -2380,16 +2417,30 @@ void TFT_eSprite::drawGlyph(uint16_t code)
{ {
uint16_t fg = textcolor; uint16_t fg = textcolor;
uint16_t bg = textbgcolor; uint16_t bg = textbgcolor;
bool getBG = false;
if (fg == bg) getBG = true;
// Check if cursor has moved
if (last_cursor_x != cursor_x)
{
bg_cursor_x = cursor_x;
last_cursor_x = cursor_x;
}
if (code < 0x21) if (code < 0x21)
{ {
if (code == 0x20) { if (code == 0x20) {
if (_fillbg) fillRect(bg_cursor_x, cursor_y, (cursor_x + gFont.spaceWidth) - bg_cursor_x, gFont.yAdvance, bg);
cursor_x += gFont.spaceWidth; cursor_x += gFont.spaceWidth;
bg_cursor_x = cursor_x;
last_cursor_x = cursor_x;
return; return;
} }
if (code == '\n') { if (code == '\n') {
cursor_x = 0; cursor_x = 0;
bg_cursor_x = 0;
last_cursor_x = 0;
cursor_y += gFont.yAdvance; cursor_y += gFont.yAdvance;
if (textwrapY && (cursor_y >= height())) cursor_y = 0; if (textwrapY && (cursor_y >= height())) cursor_y = 0;
return; return;
@ -2409,6 +2460,8 @@ void TFT_eSprite::drawGlyph(uint16_t code)
createSprite(gWidth[gNum], gFont.yAdvance); createSprite(gWidth[gNum], gFont.yAdvance);
if(fg != bg) fillSprite(bg); if(fg != bg) fillSprite(bg);
cursor_x = -gdX[gNum]; cursor_x = -gdX[gNum];
bg_cursor_x = cursor_x;
last_cursor_x = cursor_x;
cursor_y = 0; cursor_y = 0;
} }
else else
@ -2416,10 +2469,11 @@ void TFT_eSprite::drawGlyph(uint16_t code)
if( textwrapX && ((cursor_x + gWidth[gNum] + gdX[gNum]) > width())) { if( textwrapX && ((cursor_x + gWidth[gNum] + gdX[gNum]) > width())) {
cursor_y += gFont.yAdvance; cursor_y += gFont.yAdvance;
cursor_x = 0; cursor_x = 0;
bg_cursor_x = 0;
last_cursor_x = 0;
} }
if( textwrapY && ((cursor_y + gFont.yAdvance) > height())) cursor_y = 0; if( textwrapY && ((cursor_y + gFont.yAdvance) > height())) cursor_y = 0;
if ( cursor_x == 0) cursor_x -= gdX[gNum]; if ( cursor_x == 0) cursor_x -= gdX[gNum];
} }
@ -2433,11 +2487,45 @@ void TFT_eSprite::drawGlyph(uint16_t code)
} }
#endif #endif
int16_t xs = 0; int16_t cy = cursor_y + gFont.maxAscent - gdY[gNum];
uint16_t dl = 0; int16_t cx = cursor_x + gdX[gNum];
// if (cx > width() && bg_cursor_x > width()) return;
// if (cursor_y > height()) return;
int16_t fxs = cx;
uint32_t fl = 0;
int16_t bxs = cx;
uint32_t bl = 0;
int16_t bx = 0;
uint8_t pixel = 0; uint8_t pixel = 0;
int32_t cgy = cursor_y + gFont.maxAscent - gdY[gNum];
int32_t cgx = cursor_x + gdX[gNum]; int16_t fillwidth = 0;
int16_t fillheight = 0;
// Fill area above glyph
if (_fillbg) {
fillwidth = (cursor_x + gxAdvance[gNum]) - bg_cursor_x;
if (fillwidth > 0) {
fillheight = gFont.maxAscent - gdY[gNum];
if (fillheight > 0) {
fillRect(bg_cursor_x, cursor_y, fillwidth, fillheight, textbgcolor);
}
}
else {
// Could be negative
fillwidth = 0;
}
// Fill any area to left of glyph
if (bg_cursor_x < cx) fillRect(bg_cursor_x, cy, cx - bg_cursor_x, gHeight[gNum], textbgcolor);
// Set x position in glyph area where background starts
if (bg_cursor_x > cx) bx = bg_cursor_x - cx;
// Fill any area to right of glyph
if (cx + gWidth[gNum] < cursor_x + gxAdvance[gNum]) {
fillRect(cx + gWidth[gNum], cy, (cursor_x + gxAdvance[gNum]) - (cx + gWidth[gNum]), gHeight[gNum], textbgcolor);
}
}
for (int32_t y = 0; y < gHeight[gNum]; y++) for (int32_t y = 0; y < gHeight[gNum]; y++)
{ {
@ -2446,49 +2534,65 @@ void TFT_eSprite::drawGlyph(uint16_t code)
fontFile.read(pbuffer, gWidth[gNum]); fontFile.read(pbuffer, gWidth[gNum]);
} }
#endif #endif
for (int32_t x = 0; x < gWidth[gNum]; x++) for (int32_t x = 0; x < gWidth[gNum]; x++)
{ {
#ifdef FONT_FS_AVAILABLE #ifdef FONT_FS_AVAILABLE
if (fs_font) { if (fs_font) pixel = pbuffer[x];
pixel = pbuffer[x];
}
else else
#endif #endif
pixel = pgm_read_byte(gPtr + gBitmap[gNum] + x + gWidth[gNum] * y); pixel = pgm_read_byte(gPtr + gBitmap[gNum] + x + gWidth[gNum] * y);
if (pixel) if (pixel)
{ {
if (bl) { drawFastHLine( bxs, y + cy, bl, bg); bl = 0; }
if (pixel != 0xFF) if (pixel != 0xFF)
{ {
if (dl) { drawFastHLine( xs, y + cgy, dl, fg); dl = 0; } if (fl) {
if (_bpp != 1) { if (fl==1) drawPixel(fxs, y + cy, fg);
if (fg == bg) drawPixel(x + cgx, y + cgy, alphaBlend(pixel, fg, readPixel(x + cgx, y + cgy))); else drawFastHLine( fxs, y + cy, fl, fg);
else drawPixel(x + cgx, y + cgy, alphaBlend(pixel, fg, bg)); fl = 0;
} }
else if (pixel>127) drawPixel(x + cgx, y + cgy, fg); if (getBG) bg = readPixel(x + cx, y + cy);
drawPixel(x + cx, y + cy, alphaBlend(pixel, fg, bg));
} }
else else
{ {
if (dl==0) xs = x + cgx; if (fl==0) fxs = x + cx;
dl++; fl++;
} }
} }
else else
{ {
if (dl) { drawFastHLine( xs, y + cgy, dl, fg); dl = 0; } if (fl) { drawFastHLine( fxs, y + cy, fl, fg); fl = 0; }
if (_fillbg) {
if (x >= bx) {
if (bl==0) bxs = x + cx;
bl++;
}
}
} }
} }
if (dl) { drawFastHLine( xs, y + cgy, dl, fg); dl = 0; } if (fl) { drawFastHLine( fxs, y + cy, fl, fg); fl = 0; }
if (bl) { drawFastHLine( bxs, y + cy, bl, bg); bl = 0; }
}
// Fill area below glyph
if (fillwidth > 0) {
fillheight = (cursor_y + gFont.yAdvance) - (cy + gHeight[gNum]);
if (fillheight > 0) {
fillRect(bg_cursor_x, cy + gHeight[gNum], fillwidth, fillheight, textbgcolor);
}
} }
if (pbuffer) free(pbuffer); if (pbuffer) free(pbuffer);
cursor_x += gxAdvance[gNum];
if (newSprite) if (newSprite)
{ {
pushSprite(cgx, cursor_y); pushSprite(cx, cursor_y);
deleteSprite(); deleteSprite();
} }
cursor_x += gxAdvance[gNum];
} }
else else
{ {
@ -2496,6 +2600,8 @@ void TFT_eSprite::drawGlyph(uint16_t code)
drawRect(cursor_x, cursor_y + gFont.maxAscent - gFont.ascent, gFont.spaceWidth, gFont.ascent, fg); drawRect(cursor_x, cursor_y + gFont.maxAscent - gFont.ascent, gFont.spaceWidth, gFont.ascent, fg);
cursor_x += gFont.spaceWidth + 1; cursor_x += gFont.spaceWidth + 1;
} }
bg_cursor_x = cursor_x;
last_cursor_x = cursor_x;
} }

View File

@ -16,9 +16,9 @@ class TFT_eSprite : public TFT_eSPI {
// Sketch can cast returned value to (uint16_t*) for 16 bit depth if needed // Sketch can cast returned value to (uint16_t*) for 16 bit depth if needed
// RAM required is: // RAM required is:
// - 1 bit per pixel for 1 bit colour depth // - 1 bit per pixel for 1 bit colour depth
// - 1 nibble per pixel for 4 bit colour // - 1 nibble per pixel for 4 bit colour (with palette table)
// - 1 byte per pixel for 8 bit colour // - 1 byte per pixel for 8 bit colour (332 RGB format)
// - 2 bytes per pixel for 16 bit color depth // - 2 bytes per pixel for 16 bit color depth (565 RGB format)
void* createSprite(int16_t width, int16_t height, uint8_t frames = 1); void* createSprite(int16_t width, int16_t height, uint8_t frames = 1);
// Returns a pointer to the sprite or nullptr if not created, user must cast to pointer type // Returns a pointer to the sprite or nullptr if not created, user must cast to pointer type
@ -34,7 +34,7 @@ class TFT_eSprite : public TFT_eSPI {
// Returns a pointer to the Sprite frame buffer // Returns a pointer to the Sprite frame buffer
void* frameBuffer(int8_t f); void* frameBuffer(int8_t f);
// Set or get the colour depth to 4, 8 or 16 bits. Can be used to change depth an existing // Set or get the colour depth to 1, 4, 8 or 16 bits. Can be used to change depth an existing
// sprite, but clears it to black, returns a new pointer if sprite is re-created. // sprite, but clears it to black, returns a new pointer if sprite is re-created.
void* setColorDepth(int8_t b); void* setColorDepth(int8_t b);
int8_t getColorDepth(void); int8_t getColorDepth(void);
@ -49,9 +49,14 @@ class TFT_eSprite : public TFT_eSPI {
// Get the color at the given palette index // Get the color at the given palette index
uint16_t getPaletteColor(uint8_t index); uint16_t getPaletteColor(uint8_t index);
// Set foreground and background colours for 1 bit per pixel Sprite
void setBitmapColor(uint16_t fg, uint16_t bg);
// Draw a single pixel at x,y
void drawPixel(int32_t x, int32_t y, uint32_t color); void drawPixel(int32_t x, int32_t y, uint32_t color);
void drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t font), // Draw a single character in the GLCD or GFXFF font
void drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size),
// Fill Sprite with a colour // Fill Sprite with a colour
fillSprite(uint32_t color), fillSprite(uint32_t color),
@ -59,18 +64,18 @@ class TFT_eSprite : public TFT_eSPI {
// Define a window to push 16 bit colour pixels into in a raster order // Define a window to push 16 bit colour pixels into in a raster order
// Colours are converted to the set Sprite colour bit depth // Colours are converted to the set Sprite colour bit depth
setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1), setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1),
// Push a color (aka singe pixel) to the screen // Push a color (aka singe pixel) to the sprite's set window area
pushColor(uint16_t color), pushColor(uint16_t color),
// Push len colors (pixels) to the screen // Push len colors (pixels) to the sprite's set window area
pushColor(uint16_t color, uint32_t len), pushColor(uint16_t color, uint32_t len),
// Push a pixel preformatted as a 8 or 16 bit colour (avoids conversion overhead) // Push a pixel pre-formatted as a 1, 4, 8 or 16 bit colour (avoids conversion overhead)
writeColor(uint16_t color), writeColor(uint16_t color),
// Set the scroll zone, top left corner at x,y with defined width and height // Set the scroll zone, top left corner at x,y with defined width and height
// The colour (optional, black is default) is used to fill the gap after the scroll // The colour (optional, black is default) is used to fill the gap after the scroll
setScrollRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t color = TFT_BLACK), setScrollRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t color = TFT_BLACK),
// Scroll the defined zone dx,dy pixels. Negative values left,up, positive right,down // Scroll the defined zone dx,dy pixels. Negative values left,up, positive right,down
// dy is optional (default is then no up/down scroll). // dy is optional (default is 0, so no up/down scroll).
// The sprite coordinate frame does not move because pixels are moved // The sprite coordinate frame does not move because pixels are moved
scroll(int16_t dx, int16_t dy = 0), scroll(int16_t dx, int16_t dy = 0),
@ -89,9 +94,9 @@ class TFT_eSprite : public TFT_eSPI {
uint8_t getRotation(void); uint8_t getRotation(void);
// Push a rotated copy of Sprite to TFT with optional transparent colour // Push a rotated copy of Sprite to TFT with optional transparent colour
bool pushRotated(int16_t angle, uint32_t transp = 0x00FFFFFF); // Using fixed point maths bool pushRotated(int16_t angle, uint32_t transp = 0x00FFFFFF);
// Push a rotated copy of Sprite to another different Sprite with optional transparent colour // Push a rotated copy of Sprite to another different Sprite with optional transparent colour
bool pushRotated(TFT_eSprite *spr, int16_t angle, uint32_t transp = 0x00FFFFFF); // Using fixed point maths bool pushRotated(TFT_eSprite *spr, int16_t angle, uint32_t transp = 0x00FFFFFF);
// Get the TFT bounding box for a rotated copy of this Sprite // Get the TFT bounding box for a rotated copy of this Sprite
bool getRotatedBounds(int16_t angle, int16_t *min_x, int16_t *min_y, int16_t *max_x, int16_t *max_y); bool getRotatedBounds(int16_t angle, int16_t *min_x, int16_t *min_y, int16_t *max_x, int16_t *max_y);
@ -122,10 +127,10 @@ class TFT_eSprite : public TFT_eSPI {
bool pushSprite(int32_t tx, int32_t ty, int32_t sx, int32_t sy, int32_t sw, int32_t sh); bool pushSprite(int32_t tx, int32_t ty, int32_t sx, int32_t sy, int32_t sw, int32_t sh);
// Push the sprite to another sprite at x,y. This fn calls pushImage() in the destination sprite (dspr) class. // Push the sprite to another sprite at x,y. This fn calls pushImage() in the destination sprite (dspr) class.
// >>>>>> Using a transparent color is not supported at the moment <<<<<<
bool pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y); bool pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y);
bool pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y, uint16_t transparent); bool pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y, uint16_t transparent);
// Draw a single character in the selected font
int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font), int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font),
drawChar(uint16_t uniCode, int32_t x, int32_t y); drawChar(uint16_t uniCode, int32_t x, int32_t y);
@ -134,9 +139,13 @@ class TFT_eSprite : public TFT_eSPI {
height(void); height(void);
// Functions associated with anti-aliased fonts // Functions associated with anti-aliased fonts
// Draw a single unicode character using the loaded font
void drawGlyph(uint16_t code); void drawGlyph(uint16_t code);
// Print string to sprite using loaded font at cursor position
void printToSprite(String string); void printToSprite(String string);
// Print char array to sprite using loaded font at cursor position
void printToSprite(char *cbuffer, uint16_t len); void printToSprite(char *cbuffer, uint16_t len);
// Print indexed glyph to sprite using loaded font at x,y
int16_t printToSprite(int16_t x, int16_t y, uint16_t index); int16_t printToSprite(int16_t x, int16_t y, uint16_t index);
private: private:
@ -152,19 +161,19 @@ class TFT_eSprite : public TFT_eSPI {
protected: protected:
uint8_t _bpp; // bits per pixel (1, 8 or 16) uint8_t _bpp; // bits per pixel (1, 4, 8 or 16)
uint16_t *_img; // pointer to 16 bit sprite uint16_t *_img; // pointer to 16 bit sprite
uint8_t *_img8; // pointer to 8 bit sprite frame 1 or frame 2 uint8_t *_img8; // pointer to 1 and 8 bit sprite frame 1 or frame 2
uint8_t *_img4; // pointer to 4 bit sprite (uses color map) uint8_t *_img4; // pointer to 4 bit sprite (uses color map)
uint8_t *_img8_1; // pointer to frame 1 uint8_t *_img8_1; // pointer to frame 1
uint8_t *_img8_2; // pointer to frame 2 uint8_t *_img8_2; // pointer to frame 2
uint16_t *_colorMap; // color map: 16 entries, used with 4 bit color map. uint16_t *_colorMap; // color map pointer: 16 entries, used with 4 bit color map.
int32_t _sinra; int32_t _sinra; // Sine of rotation angle in fixed point
int32_t _cosra; int32_t _cosra; // Cosine of rotation angle in fixed point
bool _created; // A Sprite has been created and memory reserved bool _created; // A Sprite has been created and memory reserved
bool _gFont = false; bool _gFont = false;
int32_t _xs, _ys, _xe, _ye, _xptr, _yptr; // for setWindow int32_t _xs, _ys, _xe, _ye, _xptr, _yptr; // for setWindow
@ -173,7 +182,7 @@ class TFT_eSprite : public TFT_eSPI {
uint32_t _scolor; // gap fill colour for scroll zone uint32_t _scolor; // gap fill colour for scroll zone
int32_t _iwidth, _iheight; // Sprite memory image bit width and height (swapped during rotations) int32_t _iwidth, _iheight; // Sprite memory image bit width and height (swapped during rotations)
int32_t _dwidth, _dheight; // Real display width and height (for <8bpp Sprites) int32_t _dwidth, _dheight; // Real sprite width and height (for <8bpp Sprites)
int32_t _bitwidth; // Sprite image bit width for drawPixel (for <8bpp Sprites, not swapped) int32_t _bitwidth; // Sprite image bit width for drawPixel (for <8bpp Sprites, not swapped)
}; };

View File

@ -107,6 +107,8 @@ uint16_t TFT_eSPI::getTouchRawZ(void){
end_touch_read_write(); end_touch_read_write();
if (tz == 4095) tz = 0;
return (uint16_t)tz; return (uint16_t)tz;
} }

390
Kconfig Normal file
View File

@ -0,0 +1,390 @@
menu "TFT_eSPI"
menu "Hidden menu"
visible if false
config TFT_eSPI_ESPIDF
bool "Enable Configuration"
default y
endmenu
choice TFT_DRIVER
prompt "Select TFT driver"
default TFT_ILI9341_DRIVER
help
Driver for the TFT LCD screen
config TFT_ILI9341_DRIVER
bool "ILI9341 - 1"
help
Generic driver for common displays
config TFT_ILI9341_2_DRIVER
bool "ILI9341 - 2"
help
Alternative ILI9341 driver, see https://github.com/Bodmer/TFT_eSPI/issues/1172
config TFT_ST7735_DRIVER
bool "ST7735"
help
Define additional parameters below for this display
config TFT_ILI9163_DRIVER
bool "ILI9163"
help
Define additional parameters below for this display
config TFT_S6D02A1_DRIVER
bool "S6D02A1"
config TFT_HX8357D_DRIVER
bool "HX8357D"
config TFT_ILI9481_DRIVER
bool "ILI9481"
config TFT_ILI9486_DRIVER
bool "ILI9486"
config TFT_ILI9488_DRIVER
bool "ILI9488"
help
WARNING: Do not connect ILI9488 display SDO to MISO if other devices
share the SPI bus (TFT SDO does NOT tristate when CS is high)
config TFT_ST7789_DRIVER
bool "ST7789 - 1"
help
Full configuration option, define additional parameters below for this display
config TFT_ST7789_2_DRIVER
bool "ST7789 - 2"
help
Minimal configuration option, define additional parameters below for this display
config TFT_R61581_DRIVER
bool "R61581"
config TFT_RM68140_DRIVER
bool "RM68140"
config TFT_ST7796_DRIVER
bool "ST7796"
config TFT_SSD1351_DRIVER
bool "SSD1351"
config TFT_SSD1963_480_DRIVER
bool "SSD1963_480"
config TFT_SSD1963_800_DRIVER
bool "SSD1963_800"
config TFT_SSD1963_800ALT_DRIVER
bool "SSD1963_800ALT"
config TFT_ILI9225_DRIVER
bool "ILI9225"
config TFT_GC9A01_DRIVER
bool "GC9A01"
endchoice
if TFT_ST7735_DRIVER || TFT_ST7789_DRIVER || TFT_ST7789_2_DRIVER || TFT_ILI9341_DRIVER || TFT_ILI9341_2_DRIVER
choice TFT_COLOR_ORDER
prompt "Define the colour order"
help
Define the colour order IF the blue and red are swapped on your display
config TFT_RGB_ORDER
bool "RGB"
config TFT_BGR_ORDER
bool "BGR"
endchoice
endif
config TFT_M5STACK
bool "M5Stack"
depends on TFT_ILI9341_DRIVER || TFT_ILI9341_2_DRIVER
help
Enable if using M5Stack module with integrated ILI9341
if TFT_ST7735_DRIVER || TFT_ST7789_DRIVER || TFT_ST7789_2_DRIVER || TFT_ILI9163_DRIVER || TFT_GC9A01_DRIVER
config TFT_WIDTH
int "LCD pixel width in portrait orientation"
default 128
range 0 1024
config TFT_HEIGHT
int "LCD pixel height in portrait orientation"
default 240
range 0 1024
endif
if TFT_ST7735_DRIVER
choice TFT_ST7735_TYPE
prompt "Define the type of display"
help
Try out the different options below if the screen does not display graphics
correctly,e.g. colours wrong, mirror images, or stray pixels at the edges.
config TFT_ST7735_INITB
bool "INITB"
config TFT_ST7735_GREENTAB
bool "GREENTAB"
config TFT_ST7735_GREENTAB2
bool "GREENTAB2"
config TFT_ST7735_GREENTAB3
bool "GREENTAB3"
config TFT_ST7735_GREENTAB128
bool "GREENTAB128"
help
For 128 x 128 display
config TFT_ST7735_GREENTAB160x80
bool "GREENTAB160x80"
help
For 160 x 80 display (BGR, inverted, 26 offset)
config TFT_ST7735_REDTAB
bool "REDTAB"
config TFT_ST7735_BLACKTAB
bool "BLACKTAB"
config TFT_ST7735_REDTAB160x80
bool "REDTAB160x80"
help
For 160 x 80 display with 24 pixel offset
endchoice
endif
choice TFT_COLOR_INVERSION
prompt "Color inversion correction"
help
If colours are inverted (white shows as black) then try changing this option."
config TFT_INVERSION_DISABLE
bool "None"
config TFT_INVERSION_ON
bool "On"
config TFT_INVERSION_OFF
bool "Off"
endchoice
config TFT_PARALLEL_8_BIT
bool "Enable 8-bit parallel mode (otherwise SPI is assumed)"
default "n"
depends on IDF_TARGET_ESP32
help
Use 8-bit parallel bus to send data to the LCD. If not set SPI will be used.
menu "Display Data pins"
depends on TFT_PARALLEL_8_BIT
config TFT_D0
int "Data 0 pin"
default -1
range -1 31
config TFT_D1
int "Data 1 pin"
default -1
range -1 31
config TFT_D2
int "Data 2 pin"
default -1
range -1 31
config TFT_D3
int "Data 3 pin"
default -1
range -1 31
config TFT_D4
int "Data 4 pin"
default -1
range -1 31
config TFT_D5
int "Data 5 pin"
default -1
range -1 31
config TFT_D6
int "Data 6 pin"
default -1
range -1 31
config TFT_D7
int "Data 7 pin"
default -1
range -1 31
config TFT_WR
int "Write strobe pin"
default -1
range -1 31
config TFT_RD
int "Read strobe pin"
default -1
range -1 33
endmenu
menu "Display SPI config"
depends on !TFT_PARALLEL_8_BIT
choice TFT_SPI_PORT
prompt "SPI port"
default TFT_VSPI_PORT
help
The ESP32 has 2 free SPI ports i.e. VSPI (SPI2) and HSPI (SPI3),
the VSPI is the default. If the VSPI port is in use and pins are
not accessible (e.g. TTGO T-Beam) then use the HSPI port for the
TFT display.
config TFT_VSPI_PORT
bool "VSPI (SPI2)"
config TFT_HSPI_PORT
bool "HSPI (SPI3)"
endchoice
config TFT_MISO
int "TFT MISO pin"
default -1
range -1 32 if IDF_TARGET_ESP32
range -1 45 if IDF_TARGET_ESP32S2
help
Master In Slave Out pin.
Can be labelled as SDO in some displays
config TFT_MOSI
int "TFT MOSI pin"
default -1
range -1 32 if IDF_TARGET_ESP32
range -1 45 if IDF_TARGET_ESP32S2
help
Master Out Slave In pin.
Can be labelled as SDA or SDI in some displays
config TFT_SCLK
int "TFT Clock pin"
default -1
range -1 32 if IDF_TARGET_ESP32
range -1 45 if IDF_TARGET_ESP32S2
help
Labelled in some displays as WR
config TFT_SDA_READ
bool "Use SDA line for reading"
default "n"
help
Some displays support SPI reads via the MISO pin, other displays have a single
bi-directional SDA pin and the library will try to read this via the MOSI line
config TFT_SPI_FREQUENCY
int "SPI Frequency (Hz)"
default 27000000
range 1 80000000
help
Define the SPI clock frequency, this affects the graphics rendering speed. Too
fast and the TFT driver will not keep up and display corruption appears.
With an ILI9341 display 40MHz works OK, 80MHz sometimes fails
With a ST7735 display more than 27MHz may not work (spurious pixels and lines)
With an ILI9163 display 27 MHz works OK.
config TFT_SPI_READ_FREQ
int "SPI Read Frequency (Hz)"
default 20000000
range -1 80000000
help
Optional reduced SPI frequency for reading TFT.
Set to -1 to use the default frequency
endmenu
menu "Control Pin configuration"
config TFT_CS
int "TFT Chip Select pin"
default -1
range -1 33 if IDF_TARGET_ESP32
range -1 45 if IDF_TARGET_ESP32S2
config TFT_DC
int "TFT Data/Command pin"
default -1
range -1 31
help
Labelled as DC or RS (Register Select) in some displays
config TFT_RST
int "TFT Reset pin"
default -1
range -1 33 if IDF_TARGET_ESP32
range -1 45 if IDF_TARGET_ESP32S2
config ENABLE_BL
bool "Enable backlight control"
default y
if ENABLE_BL
config TFT_BL
int "TFT Backlight pin"
default -1
range -1 33 if IDF_TARGET_ESP32
range -1 45 if IDF_TARGET_ESP32S2
help
Pin for the backlight control signal
choice TFT_BACKLIGHT_ON
bool "Pin state to activate backlight"
default TFT_BACKLIGHT_ON_HIGH
help
The backlight will be turned ON when tft.begin() is called, but the library
needs to know if the LEDs are ON with the pin HIGH or LOW.
config TFT_BACKLIGHT_ON_HIGH
bool "HIGH"
config TFT_BACKLIGHT_ON_LOW
bool "LOW"
endchoice
endif
config TFT_BACKLIGHT_ON
int
default 1 if TFT_BACKLIGHT_ON_HIGH
default 0 if TFT_BACKLIGHT_ON_LOW
endmenu
menu "Fonts"
config TFT_LOAD_GLCD
bool "Font 1: Original Adafruit 8 pixel font needs ~1820 bytes in FLASH"
default "y"
config TFT_LOAD_FONT2
bool "Font 2: Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters"
default "y"
config TFT_LOAD_FONT4
bool "Font 4: Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters"
default "y"
config TFT_LOAD_FONT6
bool "Font 6: Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm"
default "y"
config TFT_LOAD_FONT7
bool "Font 7: 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:."
default "y"
config TFT_LOAD_FONT8
bool "Font 8: Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-."
default "y"
config TFT_LOAD_GFXFF
bool "FreeFonts: Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts"
default "y"
config TFT_SMOOTH_FONT
bool "Smooth Fonts"
default "y"
endmenu
menu "Touch screen configuration"
config ENABLE_TOUCH
bool "Enable Touch"
default n
if ENABLE_TOUCH
config TOUCH_CS
int "Touch chip select pin"
default -1
range -1 33 if IDF_TARGET_ESP32
range -1 45 if IDF_TARGET_ESP32S2
config SPI_TOUCH_FREQUENCY
int "SPI frequency for XPT2046 chip (Hz)"
default 2500000
range 1 80000000
endif
endmenu
endmenu

View File

@ -64,29 +64,35 @@
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
/*************************************************************************************** /***************************************************************************************
** Function name: beginSDA ** Function name: beginSDA - VSPI port only, FPSI port only for S2
** Description: Detach SPI from pin to permit software SPI ** Description: Detach MOSI and attach MISO to SDA for reads
***************************************************************************************/ ***************************************************************************************/
void TFT_eSPI::begin_SDA_Read(void) void TFT_eSPI::begin_SDA_Read(void)
{ {
pinMatrixOutDetach(TFT_MOSI, false, false); gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_INPUT);
pinMode(TFT_MOSI, INPUT); #ifdef CONFIG_IDF_TARGET_ESP32
pinMatrixInAttach(TFT_MOSI, VSPIQ_IN_IDX, false); pinMatrixInAttach(TFT_MOSI, VSPIQ_IN_IDX, false);
#else // S2
pinMatrixInAttach(TFT_MOSI, FSPIQ_IN_IDX, false);
#endif
SET_BUS_READ_MODE; SET_BUS_READ_MODE;
} }
/*************************************************************************************** /***************************************************************************************
** Function name: endSDA ** Function name: endSDA - VSPI port only, FPSI port only for S2
** Description: Attach SPI pins after software SPI ** Description: Attach MOSI to SDA and detach MISO for writes
***************************************************************************************/ ***************************************************************************************/
void TFT_eSPI::end_SDA_Read(void) void TFT_eSPI::end_SDA_Read(void)
{ {
pinMode(TFT_MOSI, OUTPUT); gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_OUTPUT);
pinMatrixOutAttach(TFT_MOSI, VSPID_OUT_IDX, false, false); #ifdef CONFIG_IDF_TARGET_ESP32
pinMode(TFT_MISO, INPUT); pinMatrixOutAttach(TFT_MOSI, VSPID_OUT_IDX, false, false);
pinMatrixInAttach(TFT_MISO, VSPIQ_IN_IDX, false); #else // S2
pinMatrixOutAttach(TFT_MOSI, FSPID_OUT_IDX, false, false);
#endif
SET_BUS_WRITE_MODE; SET_BUS_WRITE_MODE;
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
#endif // #if defined (TFT_SDA_READ) #endif // #if defined (TFT_SDA_READ)
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@ -133,17 +139,7 @@ uint8_t TFT_eSPI::readByte(void)
***************************************************************************************/ ***************************************************************************************/
void TFT_eSPI::busDir(uint32_t mask, uint8_t mode) void TFT_eSPI::busDir(uint32_t mask, uint8_t mode)
{ {
gpioMode(TFT_D0, mode); // Arduino generic native function
gpioMode(TFT_D1, mode);
gpioMode(TFT_D2, mode);
gpioMode(TFT_D3, mode);
gpioMode(TFT_D4, mode);
gpioMode(TFT_D5, mode);
gpioMode(TFT_D6, mode);
gpioMode(TFT_D7, mode);
return;
/*
// Arduino generic native function, but slower
pinMode(TFT_D0, mode); pinMode(TFT_D0, mode);
pinMode(TFT_D1, mode); pinMode(TFT_D1, mode);
pinMode(TFT_D2, mode); pinMode(TFT_D2, mode);
@ -152,7 +148,6 @@ void TFT_eSPI::busDir(uint32_t mask, uint8_t mode)
pinMode(TFT_D5, mode); pinMode(TFT_D5, mode);
pinMode(TFT_D6, mode); pinMode(TFT_D6, mode);
pinMode(TFT_D7, mode); pinMode(TFT_D7, mode);
return; //*/
} }
/*************************************************************************************** /***************************************************************************************
@ -161,14 +156,8 @@ void TFT_eSPI::busDir(uint32_t mask, uint8_t mode)
***************************************************************************************/ ***************************************************************************************/
void TFT_eSPI::gpioMode(uint8_t gpio, uint8_t mode) void TFT_eSPI::gpioMode(uint8_t gpio, uint8_t mode)
{ {
if(mode == INPUT) GPIO.enable_w1tc = ((uint32_t)1 << gpio); pinMode(gpio, mode);
else GPIO.enable_w1ts = ((uint32_t)1 << gpio); digitalWrite(gpio, HIGH);
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[gpio].reg) // Register lookup
= ((uint32_t)2 << FUN_DRV_S) // Set drive strength 2
| (FUN_IE) // Input enable
| ((uint32_t)2 << MCU_SEL_S); // Function select 2
GPIO.pin[gpio].val = 1; // Set pin HIGH
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
#endif // #ifdef TFT_PARALLEL_8_BIT #endif // #ifdef TFT_PARALLEL_8_BIT
@ -531,7 +520,11 @@ void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
** Description: Write a block of pixels of the same colour ** Description: Write a block of pixels of the same colour
***************************************************************************************/ ***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){ void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
#if defined (SSD1963_DRIVER)
if ( ((color & 0xF800)>> 8) == ((color & 0x07E0)>> 3) && ((color & 0xF800)>> 8)== ((color & 0x001F)<< 3) )
#else
if ( (color >> 8) == (color & 0x00FF) ) if ( (color >> 8) == (color & 0x00FF) )
#endif
{ if (!len) return; { if (!len) return;
tft_Write_16(color); tft_Write_16(color);
#if defined (SSD1963_DRIVER) #if defined (SSD1963_DRIVER)

View File

@ -139,6 +139,7 @@ SPI3_HOST = 2
#define FONT_FS_AVAILABLE #define FONT_FS_AVAILABLE
#endif #endif
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// Define the DC (TFT Data/Command or Register Select (RS))pin drive code // Define the DC (TFT Data/Command or Register Select (RS))pin drive code
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@ -151,6 +152,9 @@ SPI3_HOST = 2
#if (TFT_DC >= 0) && (TFT_DC < 32) #if (TFT_DC >= 0) && (TFT_DC < 32)
#define DC_C GPIO.out_w1tc = (1 << TFT_DC) #define DC_C GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts = (1 << TFT_DC) #define DC_D GPIO.out_w1ts = (1 << TFT_DC)
#elif (TFT_DC >= 32)
#define DC_C GPIO.out1_w1tc.val = (1 << (TFT_DC- 32))
#define DC_D GPIO.out1_w1ts.val = (1 << (TFT_DC- 32))
#else #else
#define DC_C #define DC_C
#define DC_D #define DC_D
@ -317,6 +321,13 @@ SPI3_HOST = 2
#define TFT_SCLK 18 #define TFT_SCLK 18
#endif #endif
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
#if (TFT_MISO == -1)
#undef TFT_MISO
#define TFT_MISO TFT_MOSI
#endif
#endif
#endif #endif
#endif #endif
@ -343,16 +354,16 @@ SPI3_HOST = 2
} \ } \
// Mask for the 8 data bits to set pin directions // Mask for the 8 data bits to set pin directions
#define dir_mask ((1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7)) #define GPIO_DIR_MASK ((1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7))
#if (TFT_WR >= 32) #if (TFT_WR >= 32)
// Data bits and the write line are cleared sequentially // Data bits and the write line are cleared sequentially
#define clr_mask (dir_mask); WR_L #define GPIO_OUT_CLR_MASK (GPIO_DIR_MASK); WR_L
#elif (TFT_WR >= 0) #elif (TFT_WR >= 0)
// Data bits and the write line are cleared to 0 in one step (1.25x faster) // Data bits and the write line are cleared to 0 in one step (1.25x faster)
#define clr_mask (dir_mask | (1 << TFT_WR)) #define GPIO_OUT_CLR_MASK (GPIO_DIR_MASK | (1 << TFT_WR))
#else #else
#define clr_mask #define GPIO_OUT_CLR_MASK
#endif #endif
// A lookup table is used to set the different bit patterns, this uses 1kByte of RAM // A lookup table is used to set the different bit patterns, this uses 1kByte of RAM
@ -364,14 +375,14 @@ SPI3_HOST = 2
//*/ //*/
// Write 8 bits to TFT // Write 8 bits to TFT
#define tft_Write_8(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C)); WR_H #define tft_Write_8(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t)(C)); WR_H
#if defined (SSD1963_DRIVER) #if defined (SSD1963_DRIVER)
// Write 18 bit color to TFT // Write 18 bit color to TFT
#define tft_Write_16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0xF800)>> 8)); WR_H; \ #define tft_Write_16(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0xF800)>> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0x07E0)>> 3)); WR_H; \ GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0x07E0)>> 3)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0x001F)<< 3)); WR_H GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0x001F)<< 3)); WR_H
// 18 bit color write with swapped bytes // 18 bit color write with swapped bytes
#define tft_Write_16S(C) Cswap = ((C) >>8 | (C) << 8); tft_Write_16(Cswap) #define tft_Write_16S(C) Cswap = ((C) >>8 | (C) << 8); tft_Write_16(Cswap)
@ -380,37 +391,37 @@ SPI3_HOST = 2
#ifdef PSEUDO_16_BIT #ifdef PSEUDO_16_BIT
// One write strobe for both bytes // One write strobe for both bytes
#define tft_Write_16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H #define tft_Write_16(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H
#define tft_Write_16S(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H #define tft_Write_16S(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H
#else #else
// Write 16 bits to TFT // Write 16 bits to TFT
#define tft_Write_16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \ #define tft_Write_16(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H
// 16 bit write with swapped bytes // 16 bit write with swapped bytes
#define tft_Write_16S(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \ #define tft_Write_16S(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H
#endif #endif
#endif #endif
// Write 32 bits to TFT // Write 32 bits to TFT
#define tft_Write_32(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 24)); WR_H; \ #define tft_Write_32(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 24)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 16)); WR_H; \ GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 16)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \ GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H
// Write two concatenated 16 bit values to TFT // Write two concatenated 16 bit values to TFT
#define tft_Write_32C(C,D) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \ #define tft_Write_32C(C,D) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \ GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((D) >> 8)); WR_H; \ GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((D) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((D) >> 0)); WR_H GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((D) >> 0)); WR_H
// Write 16 bit value twice to TFT - used by drawPixel() // Write 16 bit value twice to TFT - used by drawPixel()
#define tft_Write_32D(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \ #define tft_Write_32D(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \ GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \ GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H
// Read pin // Read pin
#ifdef TFT_RD #ifdef TFT_RD

View File

@ -0,0 +1,857 @@
////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP32 processors //
////////////////////////////////////////////////////
// Temporarily a separate file to TFT_eSPI_ESP32.c until board package low level API stabilises
////////////////////////////////////////////////////////////////////////////////////////
// Global variables
////////////////////////////////////////////////////////////////////////////////////////
// Select the SPI port to use, ESP32 has 2 options
#if !defined (TFT_PARALLEL_8_BIT)
#ifdef CONFIG_IDF_TARGET_ESP32
#ifdef USE_HSPI_PORT
SPIClass spi = SPIClass(HSPI);
#elif defined(USE_FSPI_PORT)
SPIClass spi = SPIClass(FSPI);
#else // use default VSPI port
SPIClass spi = SPIClass(VSPI);
#endif
#else
#ifdef USE_HSPI_PORT
SPIClass spi = SPIClass(HSPI);
#elif defined(USE_FSPI_PORT)
SPIClass spi = SPIClass(FSPI);
#else // use FSPI port
SPIClass& spi = SPI;
#endif
#endif
#endif
#ifdef ESP32_DMA
// DMA SPA handle
spi_device_handle_t dmaHAL;
#ifdef CONFIG_IDF_TARGET_ESP32
#define DMA_CHANNEL 1
#ifdef USE_HSPI_PORT
spi_host_device_t spi_host = HSPI_HOST;
#elif defined(USE_FSPI_PORT)
spi_host_device_t spi_host = SPI_HOST;
#else // use VSPI port
spi_host_device_t spi_host = VSPI_HOST;
#endif
#else
#ifdef USE_HSPI_PORT
#define DMA_CHANNEL 2
spi_host_device_t spi_host = (spi_host_device_t) DMA_CHANNEL; // Draws once then freezes
#else // use FSPI port
#define DMA_CHANNEL 1
spi_host_device_t spi_host = (spi_host_device_t) DMA_CHANNEL; // Draws once then freezes
#endif
#endif
#endif
#if !defined (TFT_PARALLEL_8_BIT)
// Volatile for register reads:
volatile uint32_t* _spi_cmd = (volatile uint32_t*)(SPI_CMD_REG(SPI_PORT));
volatile uint32_t* _spi_user = (volatile uint32_t*)(SPI_USER_REG(SPI_PORT));
// Register writes only:
volatile uint32_t* _spi_mosi_dlen = (volatile uint32_t*)(SPI_MOSI_DLEN_REG(SPI_PORT));
volatile uint32_t* _spi_w = (volatile uint32_t*)(SPI_W0_REG(SPI_PORT));
#endif
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_SDA_READ) && !defined (TFT_PARALLEL_8_BIT)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: beginSDA - FPSI port only
** Description: Detach MOSI and attach MISO to SDA for reads
***************************************************************************************/
void TFT_eSPI::begin_SDA_Read(void)
{
gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_INPUT);
pinMatrixInAttach(TFT_MOSI, FSPIQ_IN_IDX, false);
SET_BUS_READ_MODE;
}
/***************************************************************************************
** Function name: endSDA - FPSI port only
** Description: Attach MOSI to SDA and detach MISO for writes
***************************************************************************************/
void TFT_eSPI::end_SDA_Read(void)
{
gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_OUTPUT);
pinMatrixOutAttach(TFT_MOSI, FSPID_OUT_IDX, false, false);
SET_BUS_WRITE_MODE;
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // #if defined (TFT_SDA_READ)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: read byte - supports class functions
** Description: Read a byte from ESP32 8 bit data port
***************************************************************************************/
// Parallel bus MUST be set to input before calling this function!
uint8_t TFT_eSPI::readByte(void)
{
uint8_t b = 0xAA;
#if defined (TFT_PARALLEL_8_BIT)
RD_L;
uint32_t reg; // Read all GPIO pins 0-31
reg = gpio_input_get(); // Read three times to allow for bus access time
reg = gpio_input_get();
reg = gpio_input_get(); // Data should be stable now
RD_H;
// Check GPIO bits used and build value
b = (((reg>>TFT_D0)&1) << 0);
b |= (((reg>>TFT_D1)&1) << 1);
b |= (((reg>>TFT_D2)&1) << 2);
b |= (((reg>>TFT_D3)&1) << 3);
b |= (((reg>>TFT_D4)&1) << 4);
b |= (((reg>>TFT_D5)&1) << 5);
b |= (((reg>>TFT_D6)&1) << 6);
b |= (((reg>>TFT_D7)&1) << 7);
#endif
return b;
}
////////////////////////////////////////////////////////////////////////////////////////
#ifdef TFT_PARALLEL_8_BIT
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** 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)
{
// Arduino generic native function
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);
}
/***************************************************************************************
** Function name: GPIO direction control - supports class functions
** Description: Set ESP32 GPIO pin to input or output (set high) ASAP
***************************************************************************************/
void TFT_eSPI::gpioMode(uint8_t gpio, uint8_t mode)
{
pinMode(gpio, mode);
digitalWrite(gpio, HIGH);
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // #ifdef TFT_PARALLEL_8_BIT
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
#if defined (RPI_WRITE_STROBE) && !defined (TFT_PARALLEL_8_BIT) // Code for RPi TFT
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 or ESP8266 RPi TFT
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color };
if(len) spi.writePattern(&colorBin[0], 2, 1); len--;
while(len--) {WR_L; WR_H;}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 or ESP8266 RPi TFT
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len)
{
uint8_t *data = (uint8_t*)data_in;
if(_swapBytes) {
while ( len-- ) {tft_Write_16(*data); data++;}
return;
}
while ( len >=64 ) {spi.writePattern(data, 64, 1); data += 64; len -= 64; }
if (len) spi.writePattern(data, len, 1);
}
////////////////////////////////////////////////////////////////////////////////////////
#elif !defined (SPI_18BIT_DRIVER) && !defined (TFT_PARALLEL_8_BIT) // Most SPI displays
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32
** Description: Write a block of pixels of the same colour
***************************************************************************************/
/*
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
uint32_t color32 = (color<<8 | color >>8)<<16 | (color<<8 | color >>8);
bool empty = true;
volatile uint32_t* spi_w = (volatile uint32_t*)_spi_w;
if (len > 31)
{
*_spi_mosi_dlen = 511;
spi_w[0] = color32;
spi_w[1] = color32;
spi_w[2] = color32;
spi_w[3] = color32;
spi_w[4] = color32;
spi_w[5] = color32;
spi_w[6] = color32;
spi_w[7] = color32;
spi_w[8] = color32;
spi_w[9] = color32;
spi_w[10] = color32;
spi_w[11] = color32;
spi_w[12] = color32;
spi_w[13] = color32;
spi_w[14] = color32;
spi_w[15] = color32;
while(len>31)
{
while ((*_spi_cmd)&SPI_USR);
*_spi_cmd = SPI_USR;
len -= 32;
}
empty = false;
}
if (len)
{
if(empty) {
for (uint32_t i=0; i <= len; i+=2) *spi_w++ = color32;
}
len = (len << 4) - 1;
while (*_spi_cmd&SPI_USR);
*_spi_mosi_dlen = len;
*_spi_cmd = SPI_USR;
}
while ((*_spi_cmd)&SPI_USR); // Move to later in code to use transmit time usefully?
}
//*/
//*
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
volatile uint32_t* spi_w = _spi_w;
uint32_t color32 = (color<<8 | color >>8)<<16 | (color<<8 | color >>8);
uint32_t i = 0;
uint32_t rem = len & 0x1F;
len = len - rem;
// Start with partial buffer pixels
if (rem)
{
while (*_spi_cmd&SPI_USR);
for (i=0; i < rem; i+=2) *spi_w++ = color32;
*_spi_mosi_dlen = (rem << 4) - 1;
#if CONFIG_IDF_TARGET_ESP32C3
*_spi_cmd = SPI_UPDATE;
while (*_spi_cmd & SPI_UPDATE);
#endif
*_spi_cmd = SPI_USR;
if (!len) return; //{while (*_spi_cmd&SPI_USR); return; }
i = i>>1; while(i++<16) *spi_w++ = color32;
}
while (*_spi_cmd&SPI_USR);
if (!rem) while (i++<16) *spi_w++ = color32;
*_spi_mosi_dlen = 511;
// End with full buffer to maximise useful time for downstream code
while(len)
{
while (*_spi_cmd&SPI_USR);
#if CONFIG_IDF_TARGET_ESP32C3
*_spi_cmd = SPI_UPDATE;
while (*_spi_cmd & SPI_UPDATE);
#endif
*_spi_cmd = SPI_USR;
len -= 32;
}
// Do not wait here
//while (*_spi_cmd&SPI_USR);
}
//*/
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP32
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint8_t* data = (uint8_t*)data_in;
uint32_t color[16];
if (len > 31)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 511);
while(len>31)
{
uint32_t i = 0;
while(i<16)
{
color[i++] = DAT8TO32(data);
data+=4;
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), color[0]);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), color[1]);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), color[2]);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), color[3]);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), color[4]);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), color[5]);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), color[6]);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), color[7]);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), color[8]);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), color[9]);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), color[10]);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), color[11]);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), color[12]);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), color[13]);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), color[14]);
WRITE_PERI_REG(SPI_W15_REG(SPI_PORT), color[15]);
#if CONFIG_IDF_TARGET_ESP32C3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 32;
}
}
if (len > 15)
{
uint32_t i = 0;
while(i<8)
{
color[i++] = DAT8TO32(data);
data+=4;
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 255);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), color[0]);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), color[1]);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), color[2]);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), color[3]);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), color[4]);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), color[5]);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), color[6]);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), color[7]);
#if CONFIG_IDF_TARGET_ESP32C3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 16;
}
if (len)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len << 4) - 1);
for (uint32_t i=0; i <= (len<<1); i+=4) {
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT)+i, DAT8TO32(data)); data+=4;
}
#if CONFIG_IDF_TARGET_ESP32C3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
/***************************************************************************************
** Function name: pushPixels - for ESP32
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
if(_swapBytes) {
pushSwapBytePixels(data_in, len);
return;
}
uint32_t *data = (uint32_t*)data_in;
if (len > 31)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 511);
while(len>31)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W15_REG(SPI_PORT), *data++);
#if CONFIG_IDF_TARGET_ESP32C3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 32;
}
}
if (len)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len << 4) - 1);
for (uint32_t i=0; i <= (len<<1); i+=4) WRITE_PERI_REG((SPI_W0_REG(SPI_PORT) + i), *data++);
#if CONFIG_IDF_TARGET_ESP32C3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 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
uint32_t r = (color & 0xF800)>>8;
uint32_t g = (color & 0x07E0)<<5;
uint32_t b = (color & 0x001F)<<19;
// Concatenate 4 pixels into three 32 bit blocks
uint32_t r0 = r<<24 | b | g | r;
uint32_t r1 = r0>>8 | g<<16;
uint32_t r2 = r1>>8 | b<<8;
if (len > 19)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 479);
while(len>19)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), r2);
#if CONFIG_IDF_TARGET_ESP32C3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 20;
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
if (len)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len * 24) - 1);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), r2);
if (len > 8 )
{
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), r2);
}
#if CONFIG_IDF_TARGET_ESP32C3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 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;
// ILI9488 write macro is not endianess dependant, hence !_swapBytes
if(!_swapBytes) { while ( len-- ) {tft_Write_16S(*data); data++;} }
else { while ( len-- ) {tft_Write_16(*data); data++;} }
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP32 and 3 byte RGB display
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
// ILI9488 write macro is not endianess dependant, so swap byte macro not used here
while ( len-- ) {tft_Write_16(*data); data++;}
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (TFT_PARALLEL_8_BIT) // Now the code for ESP32 8 bit parallel
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 and parallel display
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
if ( (color >> 8) == (color & 0x00FF) )
{ if (!len) return;
tft_Write_16(color);
#if defined (SSD1963_DRIVER)
while (--len) {WR_L; WR_H; WR_L; WR_H; WR_L; WR_H;}
#else
#ifdef PSEUDO_16_BIT
while (--len) {WR_L; WR_H;}
#else
while (--len) {WR_L; WR_H; WR_L; WR_H;}
#endif
#endif
}
else while (len--) {tft_Write_16(color);}
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP32 and parallel display
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
while ( len-- ) {tft_Write_16(*data); data++;}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 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-- ) {tft_Write_16(*data); data++; } }
else { while ( len-- ) {tft_Write_16S(*data); data++;} }
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // End of display interface specific functions
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
#if defined (ESP32_DMA) && !defined (TFT_PARALLEL_8_BIT) // DMA FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: dmaBusy
** Description: Check if DMA is busy
***************************************************************************************/
bool TFT_eSPI::dmaBusy(void)
{
if (!DMA_Enabled || !spiBusyCheck) return false;
spi_transaction_t *rtrans;
esp_err_t ret;
uint8_t checks = spiBusyCheck;
for (int i = 0; i < checks; ++i)
{
ret = spi_device_get_trans_result(dmaHAL, &rtrans, 0);
if (ret == ESP_OK) spiBusyCheck--;
}
//Serial.print("spiBusyCheck=");Serial.println(spiBusyCheck);
if (spiBusyCheck ==0) return false;
return true;
}
/***************************************************************************************
** Function name: dmaWait
** Description: Wait until DMA is over (blocking!)
***************************************************************************************/
void TFT_eSPI::dmaWait(void)
{
if (!DMA_Enabled || !spiBusyCheck) return;
spi_transaction_t *rtrans;
esp_err_t ret;
for (int i = 0; i < spiBusyCheck; ++i)
{
ret = spi_device_get_trans_result(dmaHAL, &rtrans, portMAX_DELAY);
assert(ret == ESP_OK);
}
spiBusyCheck = 0;
}
/***************************************************************************************
** Function name: pushPixelsDMA
** Description: Push pixels to TFT (len must be less than 32767)
***************************************************************************************/
// This will byte swap the original image if setSwapBytes(true) was called by sketch.
void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len)
{
if ((len == 0) || (!DMA_Enabled)) return;
dmaWait();
if(_swapBytes) {
for (uint32_t i = 0; i < len; i++) (image[i] = image[i] << 8 | image[i] >> 8);
}
esp_err_t ret;
static spi_transaction_t trans;
memset(&trans, 0, sizeof(spi_transaction_t));
trans.user = (void *)1;
trans.tx_buffer = image; //finally send the line data
trans.length = len * 16; //Data length, in bits
trans.flags = 0; //SPI_TRANS_USE_TXDATA flag
ret = spi_device_queue_trans(dmaHAL, &trans, portMAX_DELAY);
assert(ret == ESP_OK);
spiBusyCheck++;
}
/***************************************************************************************
** Function name: pushImageDMA
** Description: Push image to a window (w*h must be less than 65536)
***************************************************************************************/
// Fixed const data assumed, will NOT clip or swap bytes
void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t const* image)
{
if ((w == 0) || (h == 0) || (!DMA_Enabled)) return;
uint32_t len = w*h;
dmaWait();
setAddrWindow(x, y, w, h);
esp_err_t ret;
static spi_transaction_t trans;
memset(&trans, 0, sizeof(spi_transaction_t));
trans.user = (void *)1;
trans.tx_buffer = image; //Data pointer
trans.length = len * 16; //Data length, in bits
trans.flags = 0; //SPI_TRANS_USE_TXDATA flag
ret = spi_device_queue_trans(dmaHAL, &trans, portMAX_DELAY);
assert(ret == ESP_OK);
spiBusyCheck++;
}
/***************************************************************************************
** Function name: pushImageDMA
** Description: Push image to a window (w*h must be less than 65536)
***************************************************************************************/
// This will clip and also swap bytes if setSwapBytes(true) was called by sketch
void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t* image, uint16_t* buffer)
{
if ((x >= _vpW) || (y >= _vpH) || (!DMA_Enabled)) return;
int32_t dx = 0;
int32_t dy = 0;
int32_t dw = w;
int32_t dh = h;
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
if ((x + dw) > _vpW ) dw = _vpW - x;
if ((y + dh) > _vpH ) dh = _vpH - y;
if (dw < 1 || dh < 1) return;
uint32_t len = dw*dh;
if (buffer == nullptr) {
buffer = image;
dmaWait();
}
// If image is clipped, copy pixels into a contiguous block
if ( (dw != w) || (dh != h) ) {
if(_swapBytes) {
for (int32_t yb = 0; yb < dh; yb++) {
for (int32_t xb = 0; xb < dw; xb++) {
uint32_t src = xb + dx + w * (yb + dy);
(buffer[xb + yb * dw] = image[src] << 8 | image[src] >> 8);
}
}
}
else {
for (int32_t yb = 0; yb < dh; yb++) {
memcpy((uint8_t*) (buffer + yb * dw), (uint8_t*) (image + dx + w * (yb + dy)), dw << 1);
}
}
}
// else, if a buffer pointer has been provided copy whole image to the buffer
else if (buffer != image || _swapBytes) {
if(_swapBytes) {
for (uint32_t i = 0; i < len; i++) (buffer[i] = image[i] << 8 | image[i] >> 8);
}
else {
memcpy(buffer, image, len*2);
}
}
if (spiBusyCheck) dmaWait(); // In case we did not wait earlier
setAddrWindow(x, y, dw, dh);
esp_err_t ret;
static spi_transaction_t trans;
memset(&trans, 0, sizeof(spi_transaction_t));
trans.user = (void *)1;
trans.tx_buffer = buffer; //finally send the line data
trans.length = len * 16; //Data length, in bits
trans.flags = 0; //SPI_TRANS_USE_TXDATA flag
ret = spi_device_queue_trans(dmaHAL, &trans, portMAX_DELAY);
assert(ret == ESP_OK);
spiBusyCheck++;
}
////////////////////////////////////////////////////////////////////////////////////////
// Processor specific DMA initialisation
////////////////////////////////////////////////////////////////////////////////////////
// The DMA functions here work with SPI only (not parallel)
/***************************************************************************************
** Function name: dc_callback
** Description: Toggles DC line during transaction
***************************************************************************************/
extern "C" void dc_callback();
void IRAM_ATTR dc_callback(spi_transaction_t *spi_tx)
{
if ((bool)spi_tx->user) {DC_D;}
else {DC_C;}
}
/***************************************************************************************
** Function name: initDMA
** Description: Initialise the DMA engine - returns true if init OK
***************************************************************************************/
bool TFT_eSPI::initDMA(bool ctrl_cs)
{
if (DMA_Enabled) return false;
esp_err_t ret;
spi_bus_config_t buscfg = {
.mosi_io_num = TFT_MOSI,
.miso_io_num = TFT_MISO,
.sclk_io_num = TFT_SCLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = TFT_WIDTH * TFT_HEIGHT * 2 + 8, // TFT screen size
.flags = 0,
.intr_flags = 0
};
int8_t pin = -1;
if (ctrl_cs) pin = TFT_CS;
spi_device_interface_config_t devcfg = {
.command_bits = 0,
.address_bits = 0,
.dummy_bits = 0,
.mode = TFT_SPI_MODE,
.duty_cycle_pos = 0,
.cs_ena_pretrans = 0,
.cs_ena_posttrans = 0,
.clock_speed_hz = SPI_FREQUENCY,
.input_delay_ns = 0,
.spics_io_num = pin,
.flags = SPI_DEVICE_NO_DUMMY, //0,
.queue_size = 1,
.pre_cb = 0, //dc_callback, //Callback to handle D/C line
.post_cb = 0
};
ret = spi_bus_initialize(spi_host, &buscfg, DMA_CHANNEL);
ESP_ERROR_CHECK(ret);
ret = spi_bus_add_device(spi_host, &devcfg, &dmaHAL);
ESP_ERROR_CHECK(ret);
DMA_Enabled = true;
spiBusyCheck = 0;
return true;
}
/***************************************************************************************
** Function name: deInitDMA
** Description: Disconnect the DMA engine from SPI
***************************************************************************************/
void TFT_eSPI::deInitDMA(void)
{
if (!DMA_Enabled) return;
spi_bus_remove_device(dmaHAL);
spi_bus_free(spi_host);
DMA_Enabled = false;
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // End of DMA FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,597 @@
////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP32 processors //
////////////////////////////////////////////////////
// Temporarily a separate file to TFT_eSPI_ESP32.h until board package low level API stabilises
#ifndef _TFT_eSPI_ESP32H_
#define _TFT_eSPI_ESP32H_
#if !defined(DISABLE_ALL_LIBRARY_WARNINGS)
#warning >>>>------>> DMA is not supported on the ESP32 C3 (possible future update)
#endif
// Processor ID reported by getSetup()
#define PROCESSOR_ID 0x32
// Include processor specific header
#include "soc/spi_reg.h"
#include "driver/spi_master.h"
#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32)
#define CONFIG_IDF_TARGET_ESP32
#endif
#ifndef VSPI
#define VSPI FSPI
#endif
// Fix IDF problems with ESP32C3
#if CONFIG_IDF_TARGET_ESP32C3
// Fix ESP32C3 IDF bug for missing definition (VSPI/FSPI only tested at the moment)
#ifndef REG_SPI_BASE
#define REG_SPI_BASE(i) DR_REG_SPI2_BASE
#endif
// Fix ESP32C3 IDF bug for name change
#ifndef SPI_MOSI_DLEN_REG
#define SPI_MOSI_DLEN_REG(x) SPI_MS_DLEN_REG(x)
#endif
#endif
// SUPPORT_TRANSACTIONS is mandatory for ESP32 so the hal mutex is toggled
#if !defined (SUPPORT_TRANSACTIONS)
#define SUPPORT_TRANSACTIONS
#endif
/*
ESP32:
FSPI not defined
HSPI = 2, uses SPI2
VSPI = 3, uses SPI3
ESP32-S2:
FSPI = 1, uses SPI2
HSPI = 2, uses SPI3
VSPI not defined so have made VSPI = HSPI
ESP32 C3: Only 1 SPI port available
FSPI = 1, uses SPI2
HSPI = 1, uses SPI2
VSPI not defined so have made VSPI = HSPI
For ESP32/S2/C3:
SPI1_HOST = 0
SPI2_HOST = 1
SPI3_HOST = 2
*/
// ESP32 specific SPI port selection - only SPI2_HOST available on C3
#define SPI_PORT SPI2_HOST
#ifdef RPI_DISPLAY_TYPE
#define CMD_BITS (16-1)
#else
#define CMD_BITS (8-1)
#endif
// Initialise processor specific SPI functions, used by init()
#define INIT_TFT_DATA_BUS // Not used
// Define a generic flag for 8 bit parallel
#if defined (ESP32_PARALLEL) // Specific to ESP32 for backwards compatibility
#if !defined (TFT_PARALLEL_8_BIT)
#define TFT_PARALLEL_8_BIT // Generic parallel flag
#endif
#endif
// Ensure ESP32 specific flag is defined for 8 bit parallel
#if defined (TFT_PARALLEL_8_BIT)
#if !defined (ESP32_PARALLEL)
#define ESP32_PARALLEL
#endif
#endif
// Processor specific code used by SPI bus transaction startWrite and endWrite functions
#if !defined (ESP32_PARALLEL)
#if (TFT_SPI_MODE == SPI_MODE1) || (TFT_SPI_MODE == SPI_MODE2)
#define SET_BUS_WRITE_MODE *_spi_user = SPI_USR_MOSI | SPI_CK_OUT_EDGE
#define SET_BUS_READ_MODE *_spi_user = SPI_USR_MOSI | SPI_USR_MISO | SPI_DOUTDIN | SPI_CK_OUT_EDGE
#else
#define SET_BUS_WRITE_MODE *_spi_user = SPI_USR_MOSI
#define SET_BUS_READ_MODE *_spi_user = SPI_USR_MOSI | SPI_USR_MISO | SPI_DOUTDIN
#endif
#else
// Not applicable to parallel bus
#define SET_BUS_WRITE_MODE
#define SET_BUS_READ_MODE
#endif
// Code to check if DMA is busy, used by SPI bus transaction transaction and endWrite functions
#if !defined(TFT_PARALLEL_8_BIT) && !defined(SPI_18BIT_DRIVER)
#define ESP32_DMA
// Code to check if DMA is busy, used by SPI DMA + transaction + endWrite functions
#define DMA_BUSY_CHECK dmaWait()
#else
#define DMA_BUSY_CHECK
#endif
#if defined(TFT_PARALLEL_8_BIT)
#define SPI_BUSY_CHECK
#else
#define SPI_BUSY_CHECK while (*_spi_cmd&SPI_USR)
#endif
// If smooth font is used then it is likely SPIFFS will be needed
#ifdef SMOOTH_FONT
// Call up the SPIFFS (SPI FLASH Filing System) for the anti-aliased fonts
#define FS_NO_GLOBALS
#include <FS.h>
#include "SPIFFS.h" // ESP32 only
#define FONT_FS_AVAILABLE
#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
#if defined (TFT_PARALLEL_8_BIT)
// TFT_DC, by design, must be in range 0-31 for single register parallel write
#if (TFT_DC >= 0) && (TFT_DC < 32)
#define DC_C GPIO.out_w1tc.val = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts.val = (1 << TFT_DC)
#elif (TFT_DC >= 32)
#define DC_C GPIO.out_w1tc.val = (1 << (TFT_DC- 32))
#define DC_D GPIO.out_w1ts.val = (1 << (TFT_DC- 32))
#else
#define DC_C
#define DC_D
#endif
#else
#if (TFT_DC >= 32)
#ifdef RPI_DISPLAY_TYPE // RPi displays need a slower DC change
#define DC_C GPIO.out_w1ts.val = (1 << (TFT_DC - 32)); \
GPIO.out_w1tc.val = (1 << (TFT_DC - 32))
#define DC_D GPIO.out_w1tc.val = (1 << (TFT_DC - 32)); \
GPIO.out_w1ts.val = (1 << (TFT_DC - 32))
#else
#define DC_C GPIO.out_w1tc.val = (1 << (TFT_DC - 32))//;GPIO.out_w1tc.val = (1 << (TFT_DC - 32))
#define DC_D GPIO.out_w1ts.val = (1 << (TFT_DC - 32))//;GPIO.out_w1ts.val = (1 << (TFT_DC - 32))
#endif
#elif (TFT_DC >= 0)
#if defined (RPI_DISPLAY_TYPE)
#if defined (ILI9486_DRIVER)
// RPi ILI9486 display needs a slower DC change
#define DC_C GPIO.out_w1tc.val = (1 << TFT_DC); \
GPIO.out_w1tc.val = (1 << TFT_DC)
#define DC_D GPIO.out_w1tc.val = (1 << TFT_DC); \
GPIO.out_w1ts.val = (1 << TFT_DC)
#else
// Other RPi displays need a slower C->D change
#define DC_C GPIO.out_w1tc.val = (1 << TFT_DC)
#define DC_D GPIO.out_w1tc.val = (1 << TFT_DC); \
GPIO.out_w1ts.val = (1 << TFT_DC)
#endif
#else
#define DC_C GPIO.out_w1tc.val = (1 << TFT_DC)//;GPIO.out_w1tc.val = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts.val = (1 << TFT_DC)//;GPIO.out_w1ts.val = (1 << TFT_DC)
#endif
#else
#define DC_C
#define DC_D
#endif
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the CS (TFT chip select) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_CS
#define TFT_CS -1 // Keep DMA code happy
#define CS_L // No macro allocated so it generates no code
#define CS_H // No macro allocated so it generates no code
#else
#if defined (TFT_PARALLEL_8_BIT)
#if TFT_CS >= 32
#define CS_L GPIO.out_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out_w1ts.val = (1 << (TFT_CS - 32))
#elif TFT_CS >= 0
#define CS_L GPIO.out_w1tc.val = (1 << TFT_CS)
#define CS_H GPIO.out_w1ts.val = (1 << TFT_CS)
#else
#define CS_L
#define CS_H
#endif
#else
#if (TFT_CS >= 32)
#ifdef RPI_DISPLAY_TYPE // RPi display needs a slower CS change
#define CS_L GPIO.out_w1ts.val = (1 << (TFT_CS - 32)); \
GPIO.out_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out_w1tc.val = (1 << (TFT_CS - 32)); \
GPIO.out_w1ts.val = (1 << (TFT_CS - 32))
#else
#define CS_L GPIO.out_w1tc.val = (1 << (TFT_CS - 32)); GPIO.out_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out_w1ts.val = (1 << (TFT_CS - 32))//;GPIO.out_w1ts.val = (1 << (TFT_CS - 32))
#endif
#elif (TFT_CS >= 0)
#ifdef RPI_DISPLAY_TYPE // RPi display needs a slower CS change
#define CS_L GPIO.out_w1ts.val = (1 << TFT_CS); GPIO.out_w1tc.val = (1 << TFT_CS)
#define CS_H GPIO.out_w1tc.val = (1 << TFT_CS); GPIO.out_w1ts.val = (1 << TFT_CS)
#else
#define CS_L GPIO.out_w1tc.val = (1 << TFT_CS); GPIO.out_w1tc.val = (1 << TFT_CS)
#define CS_H GPIO.out_w1ts.val = (1 << TFT_CS)//;GPIO.out_w1ts.val = (1 << TFT_CS)
#endif
#else
#define CS_L
#define CS_H
#endif
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_WR)
#if (TFT_WR >= 32)
// Note: it will be ~1.25x faster if the TFT_WR pin uses a GPIO pin lower than 32
#define WR_L GPIO.out_w1tc.val = (1 << (TFT_WR - 32))
#define WR_H GPIO.out_w1ts.val = (1 << (TFT_WR - 32))
#elif (TFT_WR >= 0)
// TFT_WR, for best performance, should be in range 0-31 for single register parallel write
#define WR_L GPIO.out_w1tc.val = (1 << TFT_WR)
#define WR_H GPIO.out_w1ts.val = (1 << TFT_WR)
#else
#define WR_L
#define WR_H
#endif
#else
#define WR_L
#define WR_H
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the touch screen chip select pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TOUCH_CS
#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 // XPT2046 is slow, so use slower digitalWrite here
#define T_CS_L digitalWrite(TOUCH_CS, LOW)
#define T_CS_H digitalWrite(TOUCH_CS, HIGH)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Make sure SPI default pins are assigned if not specified by user or set to -1
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (TFT_PARALLEL_8_BIT)
#ifdef USE_HSPI_PORT
#ifndef TFT_MISO
#define TFT_MISO -1
#endif
#ifndef TFT_MOSI
#define TFT_MOSI 13
#endif
#if (TFT_MOSI == -1)
#undef TFT_MOSI
#define TFT_MOSI 13
#endif
#ifndef TFT_SCLK
#define TFT_SCLK 14
#endif
#if (TFT_SCLK == -1)
#undef TFT_SCLK
#define TFT_SCLK 14
#endif
#else // VSPI port
#ifndef TFT_MISO
#define TFT_MISO -1
#endif
#ifndef TFT_MOSI
#define TFT_MOSI 23
#endif
#if (TFT_MOSI == -1)
#undef TFT_MOSI
#define TFT_MOSI 23
#endif
#ifndef TFT_SCLK
#define TFT_SCLK 18
#endif
#if (TFT_SCLK == -1)
#undef TFT_SCLK
#define TFT_SCLK 18
#endif
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2)
#if (TFT_MISO == -1)
#undef TFT_MISO
#define TFT_MISO TFT_MOSI
#endif
#endif
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the parallel bus interface chip pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_PARALLEL_8_BIT)
// Create a bit set lookup table for data bus - wastes 1kbyte of RAM but speeds things up dramatically
// can then use e.g. GPIO.out_w1ts.val = set_mask(0xFF); to set data bus to 0xFF
#define PARALLEL_INIT_TFT_DATA_BUS \
for (int32_t c = 0; c<256; c++) \
{ \
xset_mask[c] = 0; \
if ( c & 0x01 ) xset_mask[c] |= (1 << TFT_D0); \
if ( c & 0x02 ) xset_mask[c] |= (1 << TFT_D1); \
if ( c & 0x04 ) xset_mask[c] |= (1 << TFT_D2); \
if ( c & 0x08 ) xset_mask[c] |= (1 << TFT_D3); \
if ( c & 0x10 ) xset_mask[c] |= (1 << TFT_D4); \
if ( c & 0x20 ) xset_mask[c] |= (1 << TFT_D5); \
if ( c & 0x40 ) xset_mask[c] |= (1 << TFT_D6); \
if ( c & 0x80 ) xset_mask[c] |= (1 << TFT_D7); \
} \
// Mask for the 8 data bits to set pin directions
#define GPIO_DIR_MASK ((1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7))
#if (TFT_WR >= 32)
// Data bits and the write line are cleared sequentially
#define GPIO_OUT_CLR_MASK (GPIO_DIR_MASK); WR_L
#elif (TFT_WR >= 0)
// Data bits and the write line are cleared to 0 in one step (1.25x faster)
#define GPIO_OUT_CLR_MASK (GPIO_DIR_MASK | (1 << TFT_WR))
#else
#define GPIO_OUT_CLR_MASK
#endif
// A lookup table is used to set the different bit patterns, this uses 1kByte of RAM
#define set_mask(C) xset_mask[C] // 63fps Sprite rendering test 33% faster, graphicstest only 1.8% faster than shifting in real time
// Real-time shifting alternative to above to save 1KByte RAM, 47 fps Sprite rendering test
/*#define set_mask(C) (((C)&0x80)>>7)<<TFT_D7 | (((C)&0x40)>>6)<<TFT_D6 | (((C)&0x20)>>5)<<TFT_D5 | (((C)&0x10)>>4)<<TFT_D4 | \
(((C)&0x08)>>3)<<TFT_D3 | (((C)&0x04)>>2)<<TFT_D2 | (((C)&0x02)>>1)<<TFT_D1 | (((C)&0x01)>>0)<<TFT_D0
//*/
// Write 8 bits to TFT
#define tft_Write_8(C) GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t)(C)); WR_H
#if defined (SSD1963_DRIVER)
// Write 18 bit color to TFT
#define tft_Write_16(C) GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) (((C) & 0xF800)>> 8)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) (((C) & 0x07E0)>> 3)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) (((C) & 0x001F)<< 3)); WR_H
// 18 bit color write with swapped bytes
#define tft_Write_16S(C) Cswap = ((C) >>8 | (C) << 8); tft_Write_16(Cswap)
#else
#ifdef PSEUDO_16_BIT
// One write strobe for both bytes
#define tft_Write_16(C) GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 0)); WR_H
#define tft_Write_16S(C) GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 8)); WR_H
#else
// Write 16 bits to TFT
#define tft_Write_16(C) GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 0)); WR_H
// 16 bit write with swapped bytes
#define tft_Write_16S(C) GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 8)); WR_H
#endif
#endif
// Write 32 bits to TFT
#define tft_Write_32(C) GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 24)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 16)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 0)); WR_H
// Write two concatenated 16 bit values to TFT
#define tft_Write_32C(C,D) GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((D) >> 8)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((D) >> 0)); WR_H
// Write 16 bit value twice to TFT - used by drawPixel()
#define tft_Write_32D(C) GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc.val = GPIO_OUT_CLR_MASK; GPIO.out_w1ts.val = set_mask((uint8_t) ((C) >> 0)); WR_H
// Read pin
#ifdef TFT_RD
#if (TFT_RD >= 32)
#define RD_L GPIO.out_w1tc.val = (1 << (TFT_RD - 32))
#define RD_H GPIO.out_w1ts.val = (1 << (TFT_RD - 32))
#elif (TFT_RD >= 0)
#define RD_L GPIO.out_w1tc.val = (1 << TFT_RD)
//#define RD_L digitalWrite(TFT_WR, LOW)
#define RD_H GPIO.out_w1ts.val = (1 << TFT_RD)
//#define RD_H digitalWrite(TFT_WR, HIGH)
#else
#define RD_L
#define RD_H
#endif
#else
#define TFT_RD -1
#define RD_L
#define RD_H
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to a SPI ILI948x TFT
////////////////////////////////////////////////////////////////////////////////////////
#elif 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)
// Future option for transfer without wait
#define tft_Write_16N(C) tft_Write_16(C)
// 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.write32(C)
// Write two concatenated 16 bit values to TFT
#define tft_Write_32C(C,D) spi.write32((C)<<16 | (D))
// Write 16 bit value twice to TFT
#define tft_Write_32D(C) spi.write32((C)<<16 | (C))
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to an Raspberry Pi TFT
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (RPI_DISPLAY_TYPE)
// ESP32 low level SPI writes for 8, 16 and 32 bit values
// to avoid the function call overhead
#define TFT_WRITE_BITS(D, B) \
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), B-1); \
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), D); \
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
// Write 8 bits
#define tft_Write_8(C) TFT_WRITE_BITS((C)<<8, 16)
// Write 16 bits with corrected endianness for 16 bit colours
#define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
// Future option for transfer without wait
#define tft_Write_16N(C) tft_Write_16(C)
// Write 16 bits
#define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
// Write 32 bits
#define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
// Write two address coordinates
#define tft_Write_32C(C,D) TFT_WRITE_BITS((C)<<24 | (C), 32); \
TFT_WRITE_BITS((D)<<24 | (D), 32)
// Write same value twice
#define tft_Write_32D(C) tft_Write_32C(C,C)
////////////////////////////////////////////////////////////////////////////////////////
// Macros for all other SPI displays
////////////////////////////////////////////////////////////////////////////////////////
#else
/* Old macros
// ESP32 low level SPI writes for 8, 16 and 32 bit values
// to avoid the function call overhead
#define TFT_WRITE_BITS(D, B) \
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), B-1); \
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), D); \
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
// Write 8 bits
#define tft_Write_8(C) TFT_WRITE_BITS(C, 8)
// Write 16 bits with corrected endianness for 16 bit colours
#define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
// Write 16 bits
#define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
// Write 32 bits
#define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
// Write two address coordinates
#define tft_Write_32C(C,D) TFT_WRITE_BITS((uint16_t)((D)<<8 | (D)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
// Write same value twice
#define tft_Write_32D(C) TFT_WRITE_BITS((uint16_t)((C)<<8 | (C)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
//*/
//* Replacement slimmer macros
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
#define TFT_WRITE_BITS(D, B) *_spi_mosi_dlen = B-1; \
*_spi_w = D; \
*_spi_cmd = SPI_USR; \
while (*_spi_cmd & SPI_USR);
#else
#define TFT_WRITE_BITS(D, B) *_spi_mosi_dlen = B-1; \
*_spi_w = D; \
*_spi_cmd = SPI_UPDATE; \
while (*_spi_cmd & SPI_UPDATE); \
*_spi_cmd = SPI_USR; \
while (*_spi_cmd & SPI_USR);
#endif
// Write 8 bits
#define tft_Write_8(C) TFT_WRITE_BITS(C, 8)
// Write 16 bits with corrected endianness for 16 bit colours
#define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
// Future option for transfer without wait
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
#define tft_Write_16N(C) *_spi_mosi_dlen = 16-1; \
*_spi_w = ((C)<<8 | (C)>>8); \
*_spi_cmd = SPI_USR;
#else
#define tft_Write_16N(C) *_spi_mosi_dlen = 16-1; \
*_spi_w = ((C)<<8 | (C)>>8); \
*_spi_cmd = SPI_UPDATE; \
while (*_spi_cmd & SPI_UPDATE); \
*_spi_cmd = SPI_USR;
#endif
// Write 16 bits
#define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
// Write 32 bits
#define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
// Write two address coordinates
#define tft_Write_32C(C,D) TFT_WRITE_BITS((uint16_t)((D)<<8 | (D)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
// Write same value twice
#define tft_Write_32D(C) TFT_WRITE_BITS((uint16_t)((C)<<8 | (C)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
//*/
#endif
#ifndef tft_Write_16N
#define tft_Write_16N tft_Write_16
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to read from display using SPI or software SPI
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (TFT_PARALLEL_8_BIT)
// Read from display using SPI or software SPI
// Use a SPI read transfer
#define tft_Read_8() spi.transfer(0)
#endif
// Concatenate a byte sequence A,B,C,D to CDAB, P is a uint8_t pointer
#define DAT8TO32(P) ( (uint32_t)P[0]<<8 | P[1] | P[2]<<24 | P[3]<<16 )
#endif // Header end

View File

@ -0,0 +1,885 @@
////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP32 processors //
////////////////////////////////////////////////////
// Temporarily a separate file to TFT_eSPI_ESP32.c until board package low level API stabilises
////////////////////////////////////////////////////////////////////////////////////////
// Global variables
////////////////////////////////////////////////////////////////////////////////////////
// Select the SPI port to use, ESP32 has 2 options
#if !defined (TFT_PARALLEL_8_BIT)
#ifdef CONFIG_IDF_TARGET_ESP32
#ifdef USE_HSPI_PORT
SPIClass spi = SPIClass(HSPI);
#elif defined(USE_FSPI_PORT)
SPIClass spi = SPIClass(FSPI);
#else // use default VSPI port
SPIClass spi = SPIClass(VSPI);
#endif
#else
#ifdef USE_HSPI_PORT
SPIClass spi = SPIClass(HSPI);
#elif defined(USE_FSPI_PORT)
SPIClass spi = SPIClass(FSPI);
#else // use FSPI port
SPIClass& spi = SPI;
#endif
#endif
#endif
#ifdef ESP32_DMA
// DMA SPA handle
spi_device_handle_t dmaHAL;
#ifdef CONFIG_IDF_TARGET_ESP32
#define DMA_CHANNEL 1
#ifdef USE_HSPI_PORT
spi_host_device_t spi_host = HSPI_HOST;
#elif defined(USE_FSPI_PORT)
spi_host_device_t spi_host = SPI_HOST;
#else // use VSPI port
spi_host_device_t spi_host = VSPI_HOST;
#endif
#else
#ifdef USE_HSPI_PORT
#define DMA_CHANNEL SPI_DMA_CH_AUTO
spi_host_device_t spi_host = SPI3_HOST;
#else // use FSPI port
#define DMA_CHANNEL SPI_DMA_CH_AUTO
spi_host_device_t spi_host = SPI2_HOST;
#endif
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_SDA_READ) && !defined (TFT_PARALLEL_8_BIT)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: beginSDA - FPSI port only
** Description: Detach MOSI and attach MISO to SDA for reads
***************************************************************************************/
void TFT_eSPI::begin_SDA_Read(void)
{
gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_INPUT);
pinMatrixInAttach(TFT_MOSI, FSPIQ_IN_IDX, false);
SET_BUS_READ_MODE;
}
/***************************************************************************************
** Function name: endSDA - FPSI port only
** Description: Attach MOSI to SDA and detach MISO for writes
***************************************************************************************/
void TFT_eSPI::end_SDA_Read(void)
{
gpio_set_direction((gpio_num_t)TFT_MOSI, GPIO_MODE_OUTPUT);
pinMatrixOutAttach(TFT_MOSI, FSPID_OUT_IDX, false, false);
SET_BUS_WRITE_MODE;
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // #if defined (TFT_SDA_READ)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: read byte - supports class functions
** Description: Read a byte from ESP32 8 bit data port
***************************************************************************************/
// Parallel bus MUST be set to input before calling this function!
uint8_t TFT_eSPI::readByte(void)
{
uint8_t b = 0xAA;
#if defined (TFT_PARALLEL_8_BIT)
RD_L;
b = gpio_get_level((gpio_num_t)(TFT_D0-MASK_OFFSET)); // Read three times to allow for bus access time
b = gpio_get_level((gpio_num_t)(TFT_D0-MASK_OFFSET));
b = gpio_get_level((gpio_num_t)(TFT_D0-MASK_OFFSET)); // Data should be stable now
RD_H;
// Check GPIO bits used and build value
b = (gpio_get_level((gpio_num_t)(TFT_D0-MASK_OFFSET)) << 0);
b |= (gpio_get_level((gpio_num_t)(TFT_D1-MASK_OFFSET)) << 1);
b |= (gpio_get_level((gpio_num_t)(TFT_D2-MASK_OFFSET)) << 2);
b |= (gpio_get_level((gpio_num_t)(TFT_D3-MASK_OFFSET)) << 3);
b |= (gpio_get_level((gpio_num_t)(TFT_D4-MASK_OFFSET)) << 4);
b |= (gpio_get_level((gpio_num_t)(TFT_D5-MASK_OFFSET)) << 5);
b |= (gpio_get_level((gpio_num_t)(TFT_D6-MASK_OFFSET)) << 6);
b |= (gpio_get_level((gpio_num_t)(TFT_D7-MASK_OFFSET)) << 7);
#endif
return b;
}
////////////////////////////////////////////////////////////////////////////////////////
#ifdef TFT_PARALLEL_8_BIT
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** 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)
{
// Arduino generic native function
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);
}
/***************************************************************************************
** Function name: GPIO direction control - supports class functions
** Description: Set ESP32 GPIO pin to input or output (set high) ASAP
***************************************************************************************/
void TFT_eSPI::gpioMode(uint8_t gpio, uint8_t mode)
{
pinMode(gpio, mode);
digitalWrite(gpio, HIGH);
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // #ifdef TFT_PARALLEL_8_BIT
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
#if defined (RPI_WRITE_STROBE) && !defined (TFT_PARALLEL_8_BIT) // Code for RPi TFT
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 or ESP8266 RPi TFT
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color };
if(len) spi.writePattern(&colorBin[0], 2, 1); len--;
while(len--) {WR_L; WR_H;}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 or ESP8266 RPi TFT
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len)
{
uint8_t *data = (uint8_t*)data_in;
if(_swapBytes) {
while ( len-- ) {tft_Write_16(*data); data++;}
return;
}
while ( len >=64 ) {spi.writePattern(data, 64, 1); data += 64; len -= 64; }
if (len) spi.writePattern(data, len, 1);
}
////////////////////////////////////////////////////////////////////////////////////////
#elif !defined (SPI_18BIT_DRIVER) && !defined (TFT_PARALLEL_8_BIT) // Most SPI displays
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32
** Description: Write a block of pixels of the same colour
***************************************************************************************/
/*
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
uint32_t color32 = (color<<8 | color >>8)<<16 | (color<<8 | color >>8);
bool empty = true;
volatile uint32_t* spi_w = (volatile uint32_t*)_spi_w;
if (len > 31)
{
*_spi_mosi_dlen = 511;
spi_w[0] = color32;
spi_w[1] = color32;
spi_w[2] = color32;
spi_w[3] = color32;
spi_w[4] = color32;
spi_w[5] = color32;
spi_w[6] = color32;
spi_w[7] = color32;
spi_w[8] = color32;
spi_w[9] = color32;
spi_w[10] = color32;
spi_w[11] = color32;
spi_w[12] = color32;
spi_w[13] = color32;
spi_w[14] = color32;
spi_w[15] = color32;
while(len>31)
{
while ((*_spi_cmd)&SPI_USR);
*_spi_cmd = SPI_USR;
len -= 32;
}
empty = false;
}
if (len)
{
if(empty) {
for (uint32_t i=0; i <= len; i+=2) *spi_w++ = color32;
}
len = (len << 4) - 1;
while (*_spi_cmd&SPI_USR);
*_spi_mosi_dlen = len;
*_spi_cmd = SPI_USR;
}
while ((*_spi_cmd)&SPI_USR); // Move to later in code to use transmit time usefully?
}
//*/
//*
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
volatile uint32_t* spi_w = _spi_w;
uint32_t color32 = (color<<8 | color >>8)<<16 | (color<<8 | color >>8);
uint32_t i = 0;
uint32_t rem = len & 0x1F;
len = len - rem;
// Start with partial buffer pixels
if (rem)
{
while (*_spi_cmd&SPI_USR);
for (i=0; i < rem; i+=2) *spi_w++ = color32;
*_spi_mosi_dlen = (rem << 4) - 1;
#if CONFIG_IDF_TARGET_ESP32S3
*_spi_cmd = SPI_UPDATE;
while (*_spi_cmd & SPI_UPDATE);
#endif
*_spi_cmd = SPI_USR;
if (!len) return; //{while (*_spi_cmd&SPI_USR); return; }
i = i>>1; while(i++<16) *spi_w++ = color32;
}
while (*_spi_cmd&SPI_USR);
if (!rem) while (i++<16) *spi_w++ = color32;
*_spi_mosi_dlen = 511;
// End with full buffer to maximise useful time for downstream code
while(len)
{
while (*_spi_cmd&SPI_USR);
#if CONFIG_IDF_TARGET_ESP32S3
*_spi_cmd = SPI_UPDATE;
while (*_spi_cmd & SPI_UPDATE);
#endif
*_spi_cmd = SPI_USR;
len -= 32;
}
// Do not wait here
//while (*_spi_cmd&SPI_USR);
}
//*/
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP32
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint8_t* data = (uint8_t*)data_in;
uint32_t color[16];
if (len > 31)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 511);
while(len>31)
{
uint32_t i = 0;
while(i<16)
{
color[i++] = DAT8TO32(data);
data+=4;
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), color[0]);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), color[1]);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), color[2]);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), color[3]);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), color[4]);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), color[5]);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), color[6]);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), color[7]);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), color[8]);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), color[9]);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), color[10]);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), color[11]);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), color[12]);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), color[13]);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), color[14]);
WRITE_PERI_REG(SPI_W15_REG(SPI_PORT), color[15]);
#if CONFIG_IDF_TARGET_ESP32S3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 32;
}
}
if (len > 15)
{
uint32_t i = 0;
while(i<8)
{
color[i++] = DAT8TO32(data);
data+=4;
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 255);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), color[0]);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), color[1]);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), color[2]);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), color[3]);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), color[4]);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), color[5]);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), color[6]);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), color[7]);
#if CONFIG_IDF_TARGET_ESP32S3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 16;
}
if (len)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len << 4) - 1);
for (uint32_t i=0; i <= (len<<1); i+=4) {
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT)+i, DAT8TO32(data)); data+=4;
}
#if CONFIG_IDF_TARGET_ESP32S3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
/***************************************************************************************
** Function name: pushPixels - for ESP32
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
if(_swapBytes) {
pushSwapBytePixels(data_in, len);
return;
}
uint32_t *data = (uint32_t*)data_in;
if (len > 31)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 511);
while(len>31)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), *data++);
WRITE_PERI_REG(SPI_W15_REG(SPI_PORT), *data++);
#if CONFIG_IDF_TARGET_ESP32S3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 32;
}
}
if (len)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len << 4) - 1);
for (uint32_t i=0; i <= (len<<1); i+=4) WRITE_PERI_REG((SPI_W0_REG(SPI_PORT) + i), *data++);
#if CONFIG_IDF_TARGET_ESP32S3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 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
uint32_t r = (color & 0xF800)>>8;
uint32_t g = (color & 0x07E0)<<5;
uint32_t b = (color & 0x001F)<<19;
// Concatenate 4 pixels into three 32 bit blocks
uint32_t r0 = r<<24 | b | g | r;
uint32_t r1 = r0>>8 | g<<16;
uint32_t r2 = r1>>8 | b<<8;
if (len > 19)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), 479);
while(len>19)
{
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), r2);
#if CONFIG_IDF_TARGET_ESP32S3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
len -= 20;
}
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
if (len)
{
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), (len * 24) - 1);
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W1_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W2_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W3_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W4_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W5_REG(SPI_PORT), r2);
if (len > 8 )
{
WRITE_PERI_REG(SPI_W6_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W7_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W8_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W9_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W10_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W11_REG(SPI_PORT), r2);
WRITE_PERI_REG(SPI_W12_REG(SPI_PORT), r0);
WRITE_PERI_REG(SPI_W13_REG(SPI_PORT), r1);
WRITE_PERI_REG(SPI_W14_REG(SPI_PORT), r2);
}
#if CONFIG_IDF_TARGET_ESP32S3
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_UPDATE);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_UPDATE);
#endif
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR);
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 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;
// ILI9488 write macro is not endianess dependant, hence !_swapBytes
if(!_swapBytes) { while ( len-- ) {tft_Write_16S(*data); data++;} }
else { while ( len-- ) {tft_Write_16(*data); data++;} }
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP32 and 3 byte RGB display
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
// ILI9488 write macro is not endianess dependant, so swap byte macro not used here
while ( len-- ) {tft_Write_16(*data); data++;}
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (TFT_PARALLEL_8_BIT) // Now the code for ESP32 8 bit parallel
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 and parallel display
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
if ( (color >> 8) == (color & 0x00FF) )
{ if (!len) return;
tft_Write_16(color);
#if defined (SSD1963_DRIVER)
while (--len) {WR_L; WR_H; WR_L; WR_H; WR_L; WR_H;}
#else
#ifdef PSEUDO_16_BIT
while (--len) {WR_L; WR_H;}
#else
while (--len) {WR_L; WR_H; WR_L; WR_H;}
#endif
#endif
}
else while (len--) {tft_Write_16(color);}
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP32 and parallel display
** Description: Write a sequence of pixels with swapped bytes
***************************************************************************************/
void TFT_eSPI::pushSwapBytePixels(const void* data_in, uint32_t len){
uint16_t *data = (uint16_t*)data_in;
while ( len-- ) {tft_Write_16(*data); data++;}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 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-- ) {tft_Write_16(*data); data++; } }
else { while ( len-- ) {tft_Write_16S(*data); data++;} }
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // End of display interface specific functions
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
#if defined (ESP32_DMA) && !defined (TFT_PARALLEL_8_BIT) // DMA FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: dmaBusy
** Description: Check if DMA is busy
***************************************************************************************/
bool TFT_eSPI::dmaBusy(void)
{
if (!DMA_Enabled || !spiBusyCheck) return false;
spi_transaction_t *rtrans;
esp_err_t ret;
uint8_t checks = spiBusyCheck;
for (int i = 0; i < checks; ++i)
{
ret = spi_device_get_trans_result(dmaHAL, &rtrans, 0);
if (ret == ESP_OK) spiBusyCheck--;
}
//Serial.print("spiBusyCheck=");Serial.println(spiBusyCheck);
if (spiBusyCheck ==0) return false;
return true;
}
/***************************************************************************************
** Function name: dmaWait
** Description: Wait until DMA is over (blocking!)
***************************************************************************************/
void TFT_eSPI::dmaWait(void)
{
if (!DMA_Enabled || !spiBusyCheck) return;
spi_transaction_t *rtrans;
esp_err_t ret;
for (int i = 0; i < spiBusyCheck; ++i)
{
ret = spi_device_get_trans_result(dmaHAL, &rtrans, portMAX_DELAY);
assert(ret == ESP_OK);
}
spiBusyCheck = 0;
}
/***************************************************************************************
** Function name: pushPixelsDMA
** Description: Push pixels to TFT (len must be less than 32767)
***************************************************************************************/
// This will byte swap the original image if setSwapBytes(true) was called by sketch.
void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len)
{
if ((len == 0) || (!DMA_Enabled)) return;
dmaWait();
if(_swapBytes) {
for (uint32_t i = 0; i < len; i++) (image[i] = image[i] << 8 | image[i] >> 8);
}
// DMA byte count for transmit is 64Kbytes maximum, so to avoid this constraint
// small transfers are performed using a blocking call until DMA capacity is reached.
// User sketch can prevent blocking by managing pixel count and splitting into blocks
// of 32768 pixels maximum. (equivalent to an area of ~320 x 100 pixels)
while(len>0x4000) { // Transfer 16 bit pixels in blocks if len*2 over 65536 bytes
pushPixels(image, 0x400);
len -= 0x400; image+= 0x400; // Arbitrarily send 1K pixel blocks (2Kbytes)
}
esp_err_t ret;
static spi_transaction_t trans;
memset(&trans, 0, sizeof(spi_transaction_t));
trans.user = (void *)1;
trans.tx_buffer = image; //finally send the line data
trans.length = len * 16; //Data length, in bits
trans.flags = 0; //SPI_TRANS_USE_TXDATA flag
ret = spi_device_queue_trans(dmaHAL, &trans, portMAX_DELAY);
assert(ret == ESP_OK);
spiBusyCheck++;
}
/***************************************************************************************
** Function name: pushImageDMA
** Description: Push image to a window (w*h must be less than 65536)
***************************************************************************************/
// Fixed const data assumed, will NOT clip or swap bytes
void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t const* image)
{
if ((w == 0) || (h == 0) || (!DMA_Enabled)) return;
uint16_t *buffer = (uint16_t*)image;
uint32_t len = w*h;
dmaWait();
setAddrWindow(x, y, w, h);
// DMA byte count for transmit is 64Kbytes maximum, so to avoid this constraint
// small transfers are performed using a blocking call until DMA capacity is reached.
// User sketch can prevent blocking by managing pixel count and splitting into blocks
// of 32768 pixels maximum. (equivalent to an area of ~320 x 100 pixels)
while(len>0x4000) { // Transfer 16 bit pixels in blocks if len*2 over 65536 bytes
pushPixels(buffer, 0x400);
len -= 0x400; buffer+= 0x400; // Arbitrarily send 1K pixel blocks (2Kbytes)
}
esp_err_t ret;
static spi_transaction_t trans;
memset(&trans, 0, sizeof(spi_transaction_t));
trans.user = (void *)1;
trans.tx_buffer = buffer; //Data pointer
trans.length = len * 16; //Data length, in bits
trans.flags = 0; //SPI_TRANS_USE_TXDATA flag
ret = spi_device_queue_trans(dmaHAL, &trans, portMAX_DELAY);
assert(ret == ESP_OK);
spiBusyCheck++;
}
/***************************************************************************************
** Function name: pushImageDMA
** Description: Push image to a window (w*h must be less than 65536)
***************************************************************************************/
// This will clip and also swap bytes if setSwapBytes(true) was called by sketch
void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t* image, uint16_t* buffer)
{
if ((x >= _vpW) || (y >= _vpH) || (!DMA_Enabled)) return;
int32_t dx = 0;
int32_t dy = 0;
int32_t dw = w;
int32_t dh = h;
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
if ((x + dw) > _vpW ) dw = _vpW - x;
if ((y + dh) > _vpH ) dh = _vpH - y;
if (dw < 1 || dh < 1) return;
uint32_t len = dw*dh;
if (buffer == nullptr) {
buffer = image;
dmaWait();
}
// If image is clipped, copy pixels into a contiguous block
if ( (dw != w) || (dh != h) ) {
if(_swapBytes) {
for (int32_t yb = 0; yb < dh; yb++) {
for (int32_t xb = 0; xb < dw; xb++) {
uint32_t src = xb + dx + w * (yb + dy);
(buffer[xb + yb * dw] = image[src] << 8 | image[src] >> 8);
}
}
}
else {
for (int32_t yb = 0; yb < dh; yb++) {
memcpy((uint8_t*) (buffer + yb * dw), (uint8_t*) (image + dx + w * (yb + dy)), dw << 1);
}
}
}
// else, if a buffer pointer has been provided copy whole image to the buffer
else if (buffer != image || _swapBytes) {
if(_swapBytes) {
for (uint32_t i = 0; i < len; i++) (buffer[i] = image[i] << 8 | image[i] >> 8);
}
else {
memcpy(buffer, image, len*2);
}
}
if (spiBusyCheck) dmaWait(); // In case we did not wait earlier
setAddrWindow(x, y, dw, dh);
// DMA byte count for transmit is 64Kbytes maximum, so to avoid this constraint
// small transfers are performed using a blocking call until DMA capacity is reached.
// User sketch can prevent blocking by managing pixel count and splitting into blocks
// of 32768 pixels maximum. (equivalent to an area of ~320 x 100 pixels)
while(len>0x4000) { // Transfer 16 bit pixels in blocks if len*2 over 65536 bytes
pushPixels(buffer, 0x400);
len -= 0x400; buffer+= 0x400; // Arbitrarily send 1K pixel blocks (2Kbytes)
}
esp_err_t ret;
static spi_transaction_t trans;
memset(&trans, 0, sizeof(spi_transaction_t));
trans.user = (void *)1;
trans.tx_buffer = buffer; //finally send the line data
trans.length = len * 16; //Data length, in bits
trans.flags = 0; //SPI_TRANS_USE_TXDATA flag
ret = spi_device_queue_trans(dmaHAL, &trans, portMAX_DELAY);
assert(ret == ESP_OK);
spiBusyCheck++;
}
////////////////////////////////////////////////////////////////////////////////////////
// Processor specific DMA initialisation
////////////////////////////////////////////////////////////////////////////////////////
// The DMA functions here work with SPI only (not parallel)
/***************************************************************************************
** Function name: dc_callback
** Description: Toggles DC line during transaction (not used)
***************************************************************************************/
extern "C" void dc_callback();
void IRAM_ATTR dc_callback(spi_transaction_t *spi_tx)
{
if ((bool)spi_tx->user) {DC_D;}
else {DC_C;}
}
/***************************************************************************************
** Function name: dma_end_callback
** Description: Clear DMA run flag to stop retransmission loop
***************************************************************************************/
extern "C" void dma_end_callback();
void IRAM_ATTR dma_end_callback(spi_transaction_t *spi_tx)
{
WRITE_PERI_REG(SPI_DMA_CONF_REG(spi_host), 0);
}
/***************************************************************************************
** Function name: initDMA
** Description: Initialise the DMA engine - returns true if init OK
***************************************************************************************/
bool TFT_eSPI::initDMA(bool ctrl_cs)
{
if (DMA_Enabled) return false;
esp_err_t ret;
spi_bus_config_t buscfg = {
.mosi_io_num = TFT_MOSI,
.miso_io_num = TFT_MISO,
.sclk_io_num = TFT_SCLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 65536, // ESP32 S3 max size is 64Kbytes
.flags = 0,
.intr_flags = 0
};
int8_t pin = -1;
if (ctrl_cs) pin = TFT_CS;
spi_device_interface_config_t devcfg = {
.command_bits = 0,
.address_bits = 0,
.dummy_bits = 0,
.mode = TFT_SPI_MODE,
.duty_cycle_pos = 0,
.cs_ena_pretrans = 0,
.cs_ena_posttrans = 0,
.clock_speed_hz = SPI_FREQUENCY,
.input_delay_ns = 0,
.spics_io_num = pin,
.flags = SPI_DEVICE_NO_DUMMY, //0,
.queue_size = 1, // Not using queues
.pre_cb = 0, //dc_callback, //Callback to handle D/C line (not used)
.post_cb = dma_end_callback //Callback to end transmission
};
ret = spi_bus_initialize(spi_host, &buscfg, DMA_CHANNEL);
ESP_ERROR_CHECK(ret);
ret = spi_bus_add_device(spi_host, &devcfg, &dmaHAL);
ESP_ERROR_CHECK(ret);
DMA_Enabled = true;
spiBusyCheck = 0;
return true;
}
/***************************************************************************************
** Function name: deInitDMA
** Description: Disconnect the DMA engine from SPI
***************************************************************************************/
void TFT_eSPI::deInitDMA(void)
{
if (!DMA_Enabled) return;
spi_bus_remove_device(dmaHAL);
spi_bus_free(spi_host);
DMA_Enabled = false;
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // End of DMA FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,640 @@
////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP32 processors //
////////////////////////////////////////////////////
// Temporarily a separate file to TFT_eSPI_ESP32.h until board package low level API stabilises
#ifndef _TFT_eSPI_ESP32H_
#define _TFT_eSPI_ESP32H_
// Processor ID reported by getSetup()
#define PROCESSOR_ID 0x32
// Include processor specific header
#include "soc/spi_reg.h"
#include "driver/spi_master.h"
#if !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32)
#define CONFIG_IDF_TARGET_ESP32
#endif
#ifndef VSPI
#define VSPI FSPI
#endif
// Fix IDF problems with ESP32S3
// Note illogical enumerations: FSPI_HOST=SPI2_HOST=1 HSPI_HOST=SPI3_HOST=2
#if CONFIG_IDF_TARGET_ESP32S3
// Fix ESP32C3 IDF bug for missing definition (FSPI only tested at the moment)
#ifndef REG_SPI_BASE // HSPI FSPI/VSPI
#define REG_SPI_BASE(i) (((i)>1) ? (DR_REG_SPI3_BASE) : (DR_REG_SPI2_BASE))
#endif
// Fix ESP32S3 IDF bug for name change
#ifndef SPI_MOSI_DLEN_REG
#define SPI_MOSI_DLEN_REG(x) SPI_MS_DLEN_REG(x)
#endif
#endif
// SUPPORT_TRANSACTIONS is mandatory for ESP32 so the hal mutex is toggled
#if !defined (SUPPORT_TRANSACTIONS)
#define SUPPORT_TRANSACTIONS
#endif
/*
ESP32:
FSPI not defined
HSPI = 2, uses SPI2
VSPI = 3, uses SPI3
ESP32-S2:
FSPI = 1, uses SPI2
HSPI = 2, uses SPI3
VSPI not defined
ESP32 C3:
FSPI = 0, uses SPI2 ???? To be checked
HSPI = 1, uses SPI3 ???? To be checked
VSPI not defined
For ESP32/S2/C3/S3:
SPI1_HOST = 0
SPI2_HOST = 1
SPI3_HOST = 2
*/
// ESP32 specific SPI port selection
#ifdef USE_HSPI_PORT
#ifdef CONFIG_IDF_TARGET_ESP32
#define SPI_PORT HSPI //HSPI is port 2 on ESP32
#else
#define SPI_PORT 3 //HSPI is port 3 on ESP32 S2
#endif
#elif defined(USE_FSPI_PORT)
#define SPI_PORT 2 //FSPI(ESP32 S2)
#else
#ifdef CONFIG_IDF_TARGET_ESP32
#define SPI_PORT VSPI
#elif CONFIG_IDF_TARGET_ESP32S2
#define SPI_PORT 2 //FSPI(ESP32 S2)
#elif CONFIG_IDF_TARGET_ESP32S3
#define SPI_PORT FSPI
#endif
#endif
#ifdef RPI_DISPLAY_TYPE
#define CMD_BITS (16-1)
#else
#define CMD_BITS (8-1)
#endif
// Initialise processor specific SPI functions, used by init()
#define INIT_TFT_DATA_BUS // Not used
// Define a generic flag for 8 bit parallel
#if defined (ESP32_PARALLEL) // Specific to ESP32 for backwards compatibility
#if !defined (TFT_PARALLEL_8_BIT)
#define TFT_PARALLEL_8_BIT // Generic parallel flag
#endif
#endif
// Ensure ESP32 specific flag is defined for 8 bit parallel
#if defined (TFT_PARALLEL_8_BIT)
#if !defined (ESP32_PARALLEL)
#define ESP32_PARALLEL
#endif
#endif
#if !defined(DISABLE_ALL_LIBRARY_WARNINGS) && defined (ESP32_PARALLEL)
#warning >>>>------>> DMA is not supported in parallel mode
#endif
// Processor specific code used by SPI bus transaction startWrite and endWrite functions
#if !defined (ESP32_PARALLEL)
#define _spi_cmd (volatile uint32_t*)(SPI_CMD_REG(SPI_PORT))
#define _spi_user (volatile uint32_t*)(SPI_USER_REG(SPI_PORT))
#define _spi_mosi_dlen (volatile uint32_t*)(SPI_MOSI_DLEN_REG(SPI_PORT))
#define _spi_w (volatile uint32_t*)(SPI_W0_REG(SPI_PORT))
#if (TFT_SPI_MODE == SPI_MODE1) || (TFT_SPI_MODE == SPI_MODE2)
#define SET_BUS_WRITE_MODE *_spi_user = SPI_USR_MOSI | SPI_CK_OUT_EDGE
#define SET_BUS_READ_MODE *_spi_user = SPI_USR_MOSI | SPI_USR_MISO | SPI_DOUTDIN | SPI_CK_OUT_EDGE
#else
#define SET_BUS_WRITE_MODE *_spi_user = SPI_USR_MOSI
#define SET_BUS_READ_MODE *_spi_user = SPI_USR_MOSI | SPI_USR_MISO | SPI_DOUTDIN
#endif
#else
// Not applicable to parallel bus
#define SET_BUS_WRITE_MODE
#define SET_BUS_READ_MODE
#endif
// Code to check if DMA is busy, used by SPI bus transaction transaction and endWrite functions
#if !defined(TFT_PARALLEL_8_BIT) && !defined(SPI_18BIT_DRIVER)
#define ESP32_DMA
// Code to check if DMA is busy, used by SPI DMA + transaction + endWrite functions
#define DMA_BUSY_CHECK dmaWait()
#else
#define DMA_BUSY_CHECK
#endif
#if defined(TFT_PARALLEL_8_BIT)
#define SPI_BUSY_CHECK
#else
#define SPI_BUSY_CHECK while (*_spi_cmd&SPI_USR)
#endif
// If smooth font is used then it is likely SPIFFS will be needed
#ifdef SMOOTH_FONT
// Call up the SPIFFS (SPI FLASH Filing System) for the anti-aliased fonts
#define FS_NO_GLOBALS
#include <FS.h>
#include "SPIFFS.h" // ESP32 only
#define FONT_FS_AVAILABLE
#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
#if defined (TFT_PARALLEL_8_BIT)
// TFT_DC, by design, must be in range 0-31 for single register parallel write
#if (TFT_DC >= 0) && (TFT_DC < 32)
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts = (1 << TFT_DC)
#elif (TFT_DC >= 32)
#define DC_C GPIO.out1_w1tc.val = (1 << (TFT_DC- 32))
#define DC_D GPIO.out1_w1ts.val = (1 << (TFT_DC- 32))
#else
#define DC_C
#define DC_D
#endif
#else
#if (TFT_DC >= 32)
#ifdef RPI_DISPLAY_TYPE // RPi displays need a slower DC change
#define DC_C GPIO.out1_w1ts.val = (1 << (TFT_DC - 32)); \
GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))
#define DC_D GPIO.out1_w1tc.val = (1 << (TFT_DC - 32)); \
GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))
#else
#define DC_C GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))//;GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))
#define DC_D GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))
#endif
#elif (TFT_DC >= 0)
#if defined (RPI_DISPLAY_TYPE)
#if defined (ILI9486_DRIVER)
// RPi ILI9486 display needs a slower DC change
#define DC_C GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1ts = (1 << TFT_DC)
#else
// Other RPi displays need a slower C->D change
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1ts = (1 << TFT_DC)
#endif
#else
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)//;GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts = (1 << TFT_DC)//;GPIO.out_w1ts = (1 << TFT_DC)
#endif
#else
#define DC_C
#define DC_D
#endif
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the CS (TFT chip select) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_CS
#define TFT_CS -1 // Keep DMA code happy
#define CS_L // No macro allocated so it generates no code
#define CS_H // No macro allocated so it generates no code
#else
#if defined (TFT_PARALLEL_8_BIT)
#if TFT_CS >= 32
#define CS_L GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
#elif TFT_CS >= 0
#define CS_L GPIO.out_w1tc = (1 << TFT_CS)
#define CS_H GPIO.out_w1ts = (1 << TFT_CS)
#else
#define CS_L
#define CS_H
#endif
#else
#if (TFT_CS >= 32)
#ifdef RPI_DISPLAY_TYPE // RPi display needs a slower CS change
#define CS_L GPIO.out1_w1ts.val = (1 << (TFT_CS - 32)); \
GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); \
GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
#else
#define CS_L GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
#endif
#elif (TFT_CS >= 0)
#ifdef RPI_DISPLAY_TYPE // RPi display needs a slower CS change
#define CS_L GPIO.out_w1ts = (1 << TFT_CS); GPIO.out_w1tc = (1 << TFT_CS)
#define CS_H GPIO.out_w1tc = (1 << TFT_CS); GPIO.out_w1ts = (1 << TFT_CS)
#else
#define CS_L GPIO.out_w1tc = (1 << TFT_CS); GPIO.out_w1tc = (1 << TFT_CS)
#define CS_H GPIO.out_w1ts = (1 << TFT_CS)//;GPIO.out_w1ts = (1 << TFT_CS)
#endif
#else
#define CS_L
#define CS_H
#endif
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_WR)
#if (TFT_WR >= 32)
// Note: it will be ~1.25x faster if the TFT_WR pin uses a GPIO pin lower than 32
#define WR_L GPIO.out1_w1tc.val = (1 << (TFT_WR - 32))
#define WR_H GPIO.out1_w1ts.val = (1 << (TFT_WR - 32))
#elif (TFT_WR >= 0)
// TFT_WR, for best performance, should be in range 0-31 for single register parallel write
#define WR_L GPIO.out_w1tc = (1 << TFT_WR)
#define WR_H GPIO.out_w1ts = (1 << TFT_WR)
#else
#define WR_L
#define WR_H
#endif
#else
#define WR_L
#define WR_H
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the touch screen chip select pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TOUCH_CS
#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 // XPT2046 is slow, so use slower digitalWrite here
#define T_CS_L digitalWrite(TOUCH_CS, LOW)
#define T_CS_H digitalWrite(TOUCH_CS, HIGH)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Make sure SPI default pins are assigned if not specified by user or set to -1
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (TFT_PARALLEL_8_BIT)
#ifdef USE_HSPI_PORT
#ifndef TFT_MISO
#define TFT_MISO -1
#endif
#ifndef TFT_MOSI
#define TFT_MOSI 13
#endif
#if (TFT_MOSI == -1)
#undef TFT_MOSI
#define TFT_MOSI 13
#endif
#ifndef TFT_SCLK
#define TFT_SCLK 14
#endif
#if (TFT_SCLK == -1)
#undef TFT_SCLK
#define TFT_SCLK 14
#endif
#else // VSPI port
#ifndef TFT_MISO
#define TFT_MISO -1
#endif
#ifndef TFT_MOSI
#define TFT_MOSI 23
#endif
#if (TFT_MOSI == -1)
#undef TFT_MOSI
#define TFT_MOSI 23
#endif
#ifndef TFT_SCLK
#define TFT_SCLK 18
#endif
#if (TFT_SCLK == -1)
#undef TFT_SCLK
#define TFT_SCLK 18
#endif
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32S2)
#if (TFT_MISO == -1)
#undef TFT_MISO
#define TFT_MISO TFT_MOSI
#endif
#endif
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the parallel bus interface chip pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_PARALLEL_8_BIT)
#if (TFT_D0 >= 32) // If D0 is a high GPIO assume all other data bits are high GPIO
#define MASK_OFFSET 32
#define GPIO_CLR_REG GPIO.out1_w1tc.val
#define GPIO_SET_REG GPIO.out1_w1ts.val
#else
#define MASK_OFFSET 0
#define GPIO_CLR_REG GPIO.out_w1tc
#define GPIO_SET_REG GPIO.out_w1ts
#endif
// Create a bit set lookup table for data bus - wastes 1kbyte of RAM but speeds things up dramatically
// can then use e.g. GPIO.out_w1ts = set_mask(0xFF); to set data bus to 0xFF
#define PARALLEL_INIT_TFT_DATA_BUS \
for (int32_t c = 0; c<256; c++) \
{ \
xset_mask[c] = 0; \
if ( c & 0x01 ) xset_mask[c] |= (1 << (TFT_D0-MASK_OFFSET)); \
if ( c & 0x02 ) xset_mask[c] |= (1 << (TFT_D1-MASK_OFFSET)); \
if ( c & 0x04 ) xset_mask[c] |= (1 << (TFT_D2-MASK_OFFSET)); \
if ( c & 0x08 ) xset_mask[c] |= (1 << (TFT_D3-MASK_OFFSET)); \
if ( c & 0x10 ) xset_mask[c] |= (1 << (TFT_D4-MASK_OFFSET)); \
if ( c & 0x20 ) xset_mask[c] |= (1 << (TFT_D5-MASK_OFFSET)); \
if ( c & 0x40 ) xset_mask[c] |= (1 << (TFT_D6-MASK_OFFSET)); \
if ( c & 0x80 ) xset_mask[c] |= (1 << (TFT_D7-MASK_OFFSET)); \
} \
// Mask for the 8 data bits to set pin directions
#define GPIO_DIR_MASK ((1 << (TFT_D0-MASK_OFFSET)) | (1 << (TFT_D1-MASK_OFFSET)) | (1 << (TFT_D2-MASK_OFFSET)) | (1 << (TFT_D3-MASK_OFFSET)) | (1 << (TFT_D4-MASK_OFFSET)) | (1 << (TFT_D5-MASK_OFFSET)) | (1 << (TFT_D6-MASK_OFFSET)) | (1 << (TFT_D7-MASK_OFFSET)))
#if (TFT_WR >= 32)
#if (TFT_D0 >= 32)
// Data bits and the write line are cleared to 0 in one step (1.25x faster)
#define GPIO_OUT_CLR_MASK (GPIO_DIR_MASK | (1 << (TFT_WR-32)))
#elif (TFT_D0 >= 0)
// Data bits and the write line are cleared sequentially
#define GPIO_OUT_CLR_MASK (GPIO_DIR_MASK); WR_L
#endif
#elif (TFT_WR >= 0)
#if (TFT_D0 >= 32)
// Data bits and the write line are cleared sequentially
#define GPIO_OUT_CLR_MASK (GPIO_DIR_MASK); WR_L
#elif (TFT_D0 >= 0)
// Data bits and the write line are cleared to 0 in one step (1.25x faster)
#define GPIO_OUT_CLR_MASK (GPIO_DIR_MASK | (1 << TFT_WR))
#endif
#else
#define GPIO_OUT_CLR_MASK
#endif
// A lookup table is used to set the different bit patterns, this uses 1kByte of RAM
#define set_mask(C) xset_mask[C] // 63fps Sprite rendering test 33% faster, graphicstest only 1.8% faster than shifting in real time
// Real-time shifting alternative to above to save 1KByte RAM, 47 fps Sprite rendering test
/*#define set_mask(C) (((C)&0x80)>>7)<<TFT_D7 | (((C)&0x40)>>6)<<TFT_D6 | (((C)&0x20)>>5)<<TFT_D5 | (((C)&0x10)>>4)<<TFT_D4 | \
(((C)&0x08)>>3)<<TFT_D3 | (((C)&0x04)>>2)<<TFT_D2 | (((C)&0x02)>>1)<<TFT_D1 | (((C)&0x01)>>0)<<TFT_D0
//*/
// Write 8 bits to TFT
#define tft_Write_8(C) GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t)(C)); WR_H
#if defined (SSD1963_DRIVER)
// Write 18 bit color to TFT
#define tft_Write_16(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0xF800)>> 8)); WR_H; \
GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0x07E0)>> 3)); WR_H; \
GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0x001F)<< 3)); WR_H
// 18 bit color write with swapped bytes
#define tft_Write_16S(C) Cswap = ((C) >>8 | (C) << 8); tft_Write_16(Cswap)
#else
#ifdef PSEUDO_16_BIT
// One write strobe for both bytes
#define tft_Write_16(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H
#define tft_Write_16S(C) GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H
#else
// Write 16 bits to TFT
#define tft_Write_16(C) GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 0)); WR_H
// 16 bit write with swapped bytes
#define tft_Write_16S(C) GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 8)); WR_H
#endif
#endif
// Write 32 bits to TFT
#define tft_Write_32(C) GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 24)); WR_H; \
GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 16)); WR_H; \
GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 0)); WR_H
// Write two concatenated 16 bit values to TFT
#define tft_Write_32C(C,D) GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((D) >> 8)); WR_H; \
GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((D) >> 0)); WR_H
// Write 16 bit value twice to TFT - used by drawPixel()
#define tft_Write_32D(C) GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO_CLR_REG = GPIO_OUT_CLR_MASK; GPIO_SET_REG = set_mask((uint8_t) ((C) >> 0)); WR_H
// Read pin
#ifdef TFT_RD
#if (TFT_RD >= 32)
#define RD_L GPIO.out1_w1tc.val = (1 << (TFT_RD - 32))
#define RD_H GPIO.out1_w1ts.val = (1 << (TFT_RD - 32))
#elif (TFT_RD >= 0)
#define RD_L GPIO.out_w1tc = (1 << TFT_RD)
//#define RD_L digitalWrite(TFT_WR, LOW)
#define RD_H GPIO.out_w1ts = (1 << TFT_RD)
//#define RD_H digitalWrite(TFT_WR, HIGH)
#else
#define RD_L
#define RD_H
#endif
#else
#define TFT_RD -1
#define RD_L
#define RD_H
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to a SPI ILI948x TFT
////////////////////////////////////////////////////////////////////////////////////////
#elif 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)
// Future option for transfer without wait
#define tft_Write_16N(C) tft_Write_16(C)
// 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.write32(C)
// Write two concatenated 16 bit values to TFT
#define tft_Write_32C(C,D) spi.write32((C)<<16 | (D))
// Write 16 bit value twice to TFT
#define tft_Write_32D(C) spi.write32((C)<<16 | (C))
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to an Raspberry Pi TFT
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (RPI_DISPLAY_TYPE)
// ESP32 low level SPI writes for 8, 16 and 32 bit values
// to avoid the function call overhead
#define TFT_WRITE_BITS(D, B) \
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), B-1); \
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), D); \
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
// Write 8 bits
#define tft_Write_8(C) TFT_WRITE_BITS((C)<<8, 16)
// Write 16 bits with corrected endianness for 16 bit colours
#define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
// Future option for transfer without wait
#define tft_Write_16N(C) tft_Write_16(C)
// Write 16 bits
#define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
// Write 32 bits
#define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
// Write two address coordinates
#define tft_Write_32C(C,D) TFT_WRITE_BITS((C)<<24 | (C), 32); \
TFT_WRITE_BITS((D)<<24 | (D), 32)
// Write same value twice
#define tft_Write_32D(C) tft_Write_32C(C,C)
////////////////////////////////////////////////////////////////////////////////////////
// Macros for all other SPI displays
////////////////////////////////////////////////////////////////////////////////////////
#else
/* Old macros
// ESP32 low level SPI writes for 8, 16 and 32 bit values
// to avoid the function call overhead
#define TFT_WRITE_BITS(D, B) \
WRITE_PERI_REG(SPI_MOSI_DLEN_REG(SPI_PORT), B-1); \
WRITE_PERI_REG(SPI_W0_REG(SPI_PORT), D); \
SET_PERI_REG_MASK(SPI_CMD_REG(SPI_PORT), SPI_USR); \
while (READ_PERI_REG(SPI_CMD_REG(SPI_PORT))&SPI_USR);
// Write 8 bits
#define tft_Write_8(C) TFT_WRITE_BITS(C, 8)
// Write 16 bits with corrected endianness for 16 bit colours
#define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
// Write 16 bits
#define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
// Write 32 bits
#define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
// Write two address coordinates
#define tft_Write_32C(C,D) TFT_WRITE_BITS((uint16_t)((D)<<8 | (D)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
// Write same value twice
#define tft_Write_32D(C) TFT_WRITE_BITS((uint16_t)((C)<<8 | (C)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
//*/
//* Replacement slimmer macros
#if !defined(CONFIG_IDF_TARGET_ESP32S3)
#define TFT_WRITE_BITS(D, B) *_spi_mosi_dlen = B-1; \
*_spi_w = D; \
*_spi_cmd = SPI_USR; \
while (*_spi_cmd & SPI_USR);
#else
#define TFT_WRITE_BITS(D, B) *_spi_mosi_dlen = B-1; \
*_spi_w = D; \
*_spi_cmd = SPI_UPDATE; \
while (*_spi_cmd & SPI_UPDATE); \
*_spi_cmd = SPI_USR; \
while (*_spi_cmd & SPI_USR);
#endif
// Write 8 bits
#define tft_Write_8(C) TFT_WRITE_BITS(C, 8)
// Write 16 bits with corrected endianness for 16 bit colours
#define tft_Write_16(C) TFT_WRITE_BITS((C)<<8 | (C)>>8, 16)
// Future option for transfer without wait
#if !defined(CONFIG_IDF_TARGET_ESP32S3)
#define tft_Write_16N(C) *_spi_mosi_dlen = 16-1; \
*_spi_w = ((C)<<8 | (C)>>8); \
*_spi_cmd = SPI_USR;
#else
#define tft_Write_16N(C) *_spi_mosi_dlen = 16-1; \
*_spi_w = ((C)<<8 | (C)>>8); \
*_spi_cmd = SPI_UPDATE; \
while (*_spi_cmd & SPI_UPDATE); \
*_spi_cmd = SPI_USR;
#endif
// Write 16 bits
#define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
// Write 32 bits
#define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
// Write two address coordinates
#define tft_Write_32C(C,D) TFT_WRITE_BITS((uint16_t)((D)<<8 | (D)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
// Write same value twice
#define tft_Write_32D(C) TFT_WRITE_BITS((uint16_t)((C)<<8 | (C)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32)
//*/
#endif
#ifndef tft_Write_16N
#define tft_Write_16N tft_Write_16
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to read from display using SPI or software SPI
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (TFT_PARALLEL_8_BIT)
// Read from display using SPI or software SPI
// Use a SPI read transfer
#define tft_Read_8() spi.transfer(0)
#endif
// Concatenate a byte sequence A,B,C,D to CDAB, P is a uint8_t pointer
#define DAT8TO32(P) ( (uint32_t)P[0]<<8 | P[1] | P[2]<<24 | P[3]<<16 )
#endif // Header end

View File

@ -19,7 +19,7 @@
#define DMA_BUSY_CHECK // DMA not available, leave blank #define DMA_BUSY_CHECK // DMA not available, leave blank
// Initialise processor specific SPI functions, used by init() // Initialise processor specific SPI functions, used by init()
#if (!defined (SUPPORT_TRANSACTIONS) && defined (ESP8266)) #if (!defined (SUPPORT_TRANSACTIONS) && defined (ARDUINO_ARCH_ESP8266))
#define INIT_TFT_DATA_BUS \ #define INIT_TFT_DATA_BUS \
spi.setBitOrder(MSBFIRST); \ spi.setBitOrder(MSBFIRST); \
spi.setDataMode(TFT_SPI_MODE); \ spi.setDataMode(TFT_SPI_MODE); \

View File

@ -21,9 +21,24 @@
#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)
#else // SPI PIO code for 18 bit colour transmit
#include "pio_8bit_parallel.pio.h" #include "pio_SPI_18bit.pio.h"
#else
// SPI PIO code for 16 bit colour transmit
#include "pio_SPI.pio.h"
#endif
#elif defined (TFT_PARALLEL_8_BIT)
#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"
#endif
#else // must be TFT_PARALLEL_16_BIT
// PIO code for 16 bit parallel interface (16 bit colour)
#include "pio_16bit_parallel.pio.h"
#endif #endif
// Board package specific differences // Board package specific differences
@ -166,7 +181,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);
@ -182,7 +197,7 @@ void pioinit(uint32_t clock_freq) {
pio_instr_set_dc = pio_encode_set((pio_src_dest)0, 1); pio_instr_set_dc = pio_encode_set((pio_src_dest)0, 1);
pio_instr_clr_dc = pio_encode_set((pio_src_dest)0, 0); pio_instr_clr_dc = pio_encode_set((pio_src_dest)0, 0);
} }
#else #else // 8 or 16 bit parallel
void pioinit(uint16_t clock_div, uint16_t fract_div) { void pioinit(uint16_t clock_div, uint16_t fract_div) {
// Find a free SM on one of the PIO's // Find a free SM on one of the PIO's
@ -205,21 +220,27 @@ void pioinit(uint16_t clock_div, uint16_t fract_div) {
} }
} }
*/ */
#if defined (TFT_PARALLEL_8_BIT)
uint8_t bits = 8;
#else // must be TFT_PARALLEL_16_BIT
uint8_t bits = 16;
#endif
// Load the PIO program // Load the PIO program
program_offset = pio_add_program(tft_pio, &tft_io_program); program_offset = pio_add_program(tft_pio, &tft_io_program);
// Associate pins with the PIO // Associate pins with the PIO
pio_gpio_init(tft_pio, TFT_DC); pio_gpio_init(tft_pio, TFT_DC);
pio_gpio_init(tft_pio, TFT_WR); pio_gpio_init(tft_pio, TFT_WR);
for (int i = 0; i < 8; i++) {
for (int i = 0; i < bits; i++) {
pio_gpio_init(tft_pio, TFT_D0 + i); pio_gpio_init(tft_pio, TFT_D0 + i);
} }
// Configure the pins to be outputs // Configure the pins to be outputs
pio_sm_set_consecutive_pindirs(tft_pio, pio_sm, TFT_DC, 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_WR, 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); pio_sm_set_consecutive_pindirs(tft_pio, pio_sm, TFT_D0, bits, true);
// Configure the state machine // Configure the state machine
pio_sm_config c = tft_io_program_get_default_config(program_offset); pio_sm_config c = tft_io_program_get_default_config(program_offset);
@ -227,8 +248,8 @@ void pioinit(uint16_t clock_div, uint16_t fract_div) {
sm_config_set_set_pins(&c, TFT_DC, 1); sm_config_set_set_pins(&c, TFT_DC, 1);
// Define the single side-set pin // Define the single side-set pin
sm_config_set_sideset_pins(&c, TFT_WR); sm_config_set_sideset_pins(&c, TFT_WR);
// Define the 8 consecutive pins that are used for data output // Define the consecutive pins that are used for data output
sm_config_set_out_pins(&c, TFT_D0, 8); sm_config_set_out_pins(&c, TFT_D0, bits);
// Set clock divider and fractional divider // Set clock divider and fractional divider
sm_config_set_clkdiv_int_frac(&c, clock_div, fract_div); sm_config_set_clkdiv_int_frac(&c, clock_div, fract_div);
// Make a single 8 words FIFO from the 4 words TX and RX FIFOs // Make a single 8 words FIFO from the 4 words TX and RX FIFOs
@ -236,7 +257,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 +284,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) || (defined (SSD1963_DRIVER) && defined (TFT_PARALLEL_8_BIT))
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 +301,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 +332,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) || (defined (SSD1963_DRIVER) && defined (TFT_PARALLEL_8_BIT))
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 +387,7 @@ void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
} }
} }
} }
#endif
} }
/*************************************************************************************** /***************************************************************************************
@ -535,7 +582,7 @@ void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
#ifdef RP2040_DMA // DMA functions for 16 bit SPI and 8 bit parallel displays #ifdef RP2040_DMA // DMA functions for 16 bit SPI and 8/16 bit parallel displays
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
/* /*
These are created in header file: These are created in header file:

View File

@ -22,10 +22,15 @@
// Processor ID reported by getSetup() // Processor ID reported by getSetup()
#define PROCESSOR_ID 0x2040 #define PROCESSOR_ID 0x2040
// Transactions always supported
#ifndef SUPPORT_TRANSACTIONS
#define SUPPORT_TRANSACTIONS
#endif
// Include processor specific header // Include processor specific header
// None // None
#if defined (TFT_PARALLEL_8_BIT) || defined (RP2040_PIO_SPI) #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RP2040_PIO_SPI)
#define RP2040_PIO_INTERFACE #define RP2040_PIO_INTERFACE
#define RP2040_PIO_PUSHBLOCK #define RP2040_PIO_PUSHBLOCK
#endif #endif
@ -60,9 +65,20 @@
#define DMA_BUSY_CHECK #define DMA_BUSY_CHECK
#endif #endif
// Handle high performance MHS RPi display type
#if defined (MHS_DISPLAY_TYPE) && !defined (RPI_DISPLAY_TYPE)
#define RPI_DISPLAY_TYPE
#endif
#if !defined (RP2040_PIO_INTERFACE) // SPI #if !defined (RP2040_PIO_INTERFACE) // SPI
// Initialise processor specific SPI functions, used by init()
#define INIT_TFT_DATA_BUS // Not used #if defined (MHS_DISPLAY_TYPE) // High speed RPi TFT type always needs 16 bit transfers
// This swaps to 16 bit mode, used for commands so wait avoids clash with DC timing
#define INIT_TFT_DATA_BUS hw_write_masked(&spi_get_hw(SPI_X)->cr0, (16 - 1) << SPI_SSPCR0_DSS_LSB, SPI_SSPCR0_DSS_BITS)
#else
// Initialise processor specific SPI functions, used by init()
#define INIT_TFT_DATA_BUS // Not used
#endif
// Wait for tx to end, flush rx FIFO, clear rx overrun // Wait for tx to end, flush rx FIFO, clear rx overrun
#define SPI_BUSY_CHECK while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \ #define SPI_BUSY_CHECK while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
@ -75,18 +91,37 @@
#endif #endif
#else #else
// ILI9481 needs a slower cycle time // Different controllers have different minimum write cycle periods, so the PIO clock is changed accordingly
// Byte rate = (CPU clock/(4 * divider)) // The PIO clock is a division of the CPU clock so scales when the processor is overclocked
#ifdef ILI9481_DRIVER // PIO write frequency = (CPU clock/(4 * RP2040_PIO_CLK_DIV))
#define DIV_UNITS 1 // The write cycle periods below assume a 125MHz CPU clock speed
#define DIV_FRACT 160 #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT)
#else #if defined (RP2040_PIO_CLK_DIV)
#define DIV_UNITS 1 #if (RP2040_PIO_CLK_DIV > 0)
#define DIV_FRACT 0 #define DIV_UNITS RP2040_PIO_CLK_DIV
#define DIV_FRACT 0
#else
#define DIV_UNITS 3
#define DIV_FRACT 0
#endif
#elif defined (TFT_PARALLEL_16_BIT)
// Different display drivers have different minimum write cycle times
#if defined (HX8357C_DRIVER) || defined (SSD1963_DRIVER)
#define DIV_UNITS 1 // 32ns write cycle time SSD1963, HX8357C (maybe HX8357D?)
#elif defined (ILI9486_DRIVER) || defined (HX8357B_DRIVER) || defined (HX8357D_DRIVER)
#define DIV_UNITS 2 // 64ns write cycle time ILI9486, HX8357D, HX8357B
#else // ILI9481 needs a slower cycle time
#define DIV_UNITS 3 // 96ns write cycle time
#endif
#define DIV_FRACT 0
#else // 8 bit parallel mode default 64ns write cycle time
#define DIV_UNITS 2
#define DIV_FRACT 0 // Note: Fractional values done with clock period dithering
#endif
#endif #endif
// Initialise TFT data bus // Initialise TFT data bus
#if defined (TFT_PARALLEL_8_BIT) #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT)
#define INIT_TFT_DATA_BUS pioinit(DIV_UNITS, DIV_FRACT); #define INIT_TFT_DATA_BUS pioinit(DIV_UNITS, DIV_FRACT);
#elif defined (RP2040_PIO_SPI) #elif defined (RP2040_PIO_SPI)
#define INIT_TFT_DATA_BUS pioinit(SPI_FREQUENCY); #define INIT_TFT_DATA_BUS pioinit(SPI_FREQUENCY);
@ -117,7 +152,7 @@
#if !defined (RP2040_PIO_INTERFACE)// SPI #if !defined (RP2040_PIO_INTERFACE)// SPI
//#define DC_C sio_hw->gpio_clr = (1ul << TFT_DC) //#define DC_C sio_hw->gpio_clr = (1ul << TFT_DC)
//#define DC_D sio_hw->gpio_set = (1ul << TFT_DC) //#define DC_D sio_hw->gpio_set = (1ul << TFT_DC)
#if defined (RPI_DISPLAY_TYPE) #if defined (RPI_DISPLAY_TYPE) && !defined (MHS_DISPLAY_TYPE)
#define DC_C digitalWrite(TFT_DC, LOW); #define DC_C digitalWrite(TFT_DC, LOW);
#define DC_D digitalWrite(TFT_DC, HIGH); #define DC_D digitalWrite(TFT_DC, HIGH);
#else #else
@ -143,7 +178,7 @@
#define CS_H // No macro allocated so it generates no code #define CS_H // No macro allocated so it generates no code
#else #else
#if !defined (RP2040_PIO_INTERFACE) // SPI #if !defined (RP2040_PIO_INTERFACE) // SPI
#if defined (RPI_DISPLAY_TYPE) #if defined (RPI_DISPLAY_TYPE) && !defined (MHS_DISPLAY_TYPE)
#define CS_L digitalWrite(TFT_CS, LOW); #define CS_L digitalWrite(TFT_CS, LOW);
#define CS_H digitalWrite(TFT_CS, HIGH); #define CS_H digitalWrite(TFT_CS, HIGH);
#else #else
@ -179,7 +214,7 @@
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code // Define the WR (TFT Write) pin drive code
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
#if !defined (TFT_PARALLEL_8_BIT) // SPI #if !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT) // SPI
#ifdef TFT_WR #ifdef TFT_WR
#define WR_L digitalWrite(TFT_WR, LOW) #define WR_L digitalWrite(TFT_WR, LOW)
#define WR_H digitalWrite(TFT_WR, HIGH) #define WR_H digitalWrite(TFT_WR, HIGH)
@ -263,7 +298,28 @@
// Macros to write commands/pixel colour data to other displays // Macros to write commands/pixel colour data to other displays
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
#else #else
#if defined (RPI_DISPLAY_TYPE) // RPi TFT type always needs 16 bit transfers #if defined (MHS_DISPLAY_TYPE) // High speed RPi TFT type always needs 16 bit transfers
// This swaps to 16 bit mode, used for commands so wait avoids clash with DC timing
#define tft_Write_8(C) while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
hw_write_masked(&spi_get_hw(SPI_X)->cr0, (16 - 1) << SPI_SSPCR0_DSS_LSB, SPI_SSPCR0_DSS_BITS); \
spi_get_hw(SPI_X)->dr = (uint32_t)((C) | ((C)<<8)); \
while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
// Note: the following macros do not wait for the end of transmission
#define tft_Write_16(C) while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)
#define tft_Write_16N(C) while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)
#define tft_Write_16S(C) while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = (uint32_t)(C)<<8 | (C)>>8
#define tft_Write_32(C) spi_get_hw(SPI_X)->dr = (uint32_t)((C)>>16); spi_get_hw(SPI_X)->dr = (uint32_t)(C)
#define tft_Write_32C(C,D) spi_get_hw(SPI_X)->dr = (uint32_t)(C); spi_get_hw(SPI_X)->dr = (uint32_t)(D)
#define tft_Write_32D(C) spi_get_hw(SPI_X)->dr = (uint32_t)(C); spi_get_hw(SPI_X)->dr = (uint32_t)(C)
#elif 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_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_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_16N(C) spi.transfer((uint8_t)((C)>>8));spi.transfer((uint8_t)((C)>>0))
@ -285,6 +341,23 @@
spi.transfer(0); spi.transfer((C)>>8); \ spi.transfer(0); spi.transfer((C)>>8); \
spi.transfer(0); spi.transfer((C)>>0) spi.transfer(0); spi.transfer((C)>>0)
#elif defined (ILI9225_DRIVER) // Needs gaps between commands + data bytes, so use slower transfer functions
// Warning: these all end in 8 bit SPI mode!
#define tft_Write_8(C) spi.transfer(C);
#define tft_Write_16(C) spi.transfer16(C)
#define tft_Write_16N(C) spi.transfer16(C)
#define tft_Write_16S(C) spi.transfer16((C)<<8 | (C)>>8)
#define tft_Write_32(C) spi.transfer16((C)>>16); spi.transfer16(C)
#define tft_Write_32C(C,D) spi.transfer16(C); spi.transfer16(D)
#define tft_Write_32D(C) spi.transfer16(C); spi.transfer16(C)
#else #else
// This swaps to 8 bit mode, then back to 16 bit mode // This swaps to 8 bit mode, then back to 16 bit mode
@ -333,9 +406,9 @@
#define TX_FIFO tft_pio->txf[pio_sm] #define TX_FIFO tft_pio->txf[pio_sm]
// Temporary - to be deleted // Temporary - to be deleted
#define dir_mask 0 #define GPIO_DIR_MASK 0
#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
@ -343,6 +416,38 @@
TX_FIFO = (C); \ TX_FIFO = (C); \
WAIT_FOR_STALL 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 // PIO interface, SPI or parallel
// 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
#if defined (TFT_PARALLEL_8_BIT) || defined (RP2040_PIO_SPI)
#define tft_Write_8(C) tft_pio->sm[pio_sm].instr = pio_instr_jmp8; \
TX_FIFO = (C); \
WAIT_FOR_STALL
#else // For 16 bit parallel 16 bits are always sent
#define tft_Write_8(C) TX_FIFO = (C); \
WAIT_FOR_STALL
#endif
// Note: the following macros do not wait for the end of transmission // Note: the following macros do not wait for the end of transmission
#define tft_Write_16(C) WAIT_FOR_FIFO_FREE(1); TX_FIFO = (C) #define tft_Write_16(C) WAIT_FOR_FIFO_FREE(1); TX_FIFO = (C)
@ -356,7 +461,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

View File

@ -306,7 +306,7 @@
#if defined (TFT_PARALLEL_8_BIT) #if defined (TFT_PARALLEL_8_BIT)
// Mask for the 8 data bits to set pin directions (not used) // Mask for the 8 data bits to set pin directions (not used)
#define dir_mask 0 #define GPIO_DIR_MASK 0
#define PARALLEL_INIT_TFT_DATA_BUS // None #define PARALLEL_INIT_TFT_DATA_BUS // None

View File

@ -0,0 +1,62 @@
// -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! //
// 16 bit parallel //
// -------------------------------------------------- //
#pragma once
#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif
// ------ //
// tft_io //
// ------ //
#define tft_io_wrap_target 7
#define tft_io_wrap 20
#define tft_io_offset_block_fill 0u
#define tft_io_offset_start_8 7u
#define tft_io_offset_start_tx 7u
#define tft_io_offset_set_addr_window 10u
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
0x7100, // 5: out pins, 32 side 0 [1]
0x1884, // 6: jmp y--, 4 side 1
// .wrap_target
0x98a0, // 7: pull block side 1
0x7100, // 8: out pins, 32 side 0 [1]
0x1807, // 9: jmp 7 side 1
0xf822, // 10: set x, 2 side 1
0xe000, // 11: set pins, 0
0x80a0, // 12: pull block
0x7000, // 13: out pins, 32 side 0
0x0033, // 14: jmp !x, 19
0x98a0, // 15: pull block side 1
0xe001, // 16: set pins, 1
0x7108, // 17: out pins, 8 side 0 [1]
0x19f1, // 18: jmp !osre, 17 side 1 [1]
0x184b, // 19: jmp x--, 11 side 1
0xe001, // 20: set pins, 1
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program tft_io_program = {
.instructions = tft_io_program_instructions,
.length = 21,
.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

View File

@ -1,92 +0,0 @@
// Raspberry Pi Pico PIO program to output data to a TFT
// controller via a 8 bit 8080 style data path.
// Original sourced from:
// https://github.com/zapta/pio_tft
// Side set: 1 output pin, TFT_WR. Active low.
// Data set: 8 consecutive output pins, TFT_D0 .. TFT_D7
.program tft_io
.side_set 1 opt ; The TFT_WR output.
// The C++ code switches between the different SM routines
// by waiting for the SM to be idle and setting its PC.
// The default SM routine is a 16 bit transfer
// Do a block fill of N+1 pixels.
public block_fill:
// Fetch colour value.
pull side 1
// Move colour to x.
mov x, osr
// Fetch pixel count N (sends N+1 pixels).
pull
// Move pixel count to y.
mov y, osr
next:
// Copy colour value into osr, colour in LS 16 bits.
mov osr, x side 1
// Output colour 8 MS bits, unwanted top 16 bits shifted through.
out pins, 24 side 0 [1]
// Write first colour byte.
nop side 1 [1]
// Write second colour byte.
out pins, 8 side 0 [1]
// Decrement pixel count and loop.
jmp y--, next side 1
.wrap_target
// Transmit a 16 bit value (LS 16 bits of 32 bits).
public start_16:
// 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
// shifts the unused top 16 bits through.
out pins, 24 side 0 [1]
// Set WR high and delay to next byte.
nop side 1 [1]
// 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
// Transmit an 8 bit value (LS 8 bits of 32 bits).
public start_8:
// Fetch the next 32 bit value from the TX FIFO and set TFT_WR high.
pull side 1
// Write the first byte (LSB) and sets WR low. This also
// shifts the unused top 24 bits through.
out pins, 32 side 0 [1]
// Jump to start
jmp start_16 side 1
// Transmit a set window command sequence.
public set_addr_window:
// Loop count in x (to send caset, paset and ramwr commands).
set x, 2 side 1
pull_cmd:
// Set TFT_DC low.
set pins, 0
// Fetch caset, paset or ramwr.
pull
// Output LS byte (caset, paset or ramwr), discarding top 24 bits, set TFT_WR low.
out pins, 32 side 0
// Jump to end if 3rd cmd byte ramwr sent (x == 0)
jmp !x, end_set_addr
// pull next start and end coordinates, TFT_WR high.
pull side 1
// Set TFT_DC high.
set pins, 1
send_xy:
// Output byte, TFT_WR low.
out pins, 8 side 0 [1]
// Loop until 4 bytes sent, TFT_WR high.
jmp !osre, send_xy side 1 [1]
end_set_addr:
// Loop back for next command and write last command.
jmp x--, pull_cmd side 1
// Set DC high.
set pins, 1
// Auto-wrap back to start_16.
.wrap

View File

@ -1,5 +1,6 @@
// -------------------------------------------------- // // -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! // // This file is autogenerated by pioasm; do not edit! //
// 8 bit parallel //
// -------------------------------------------------- // // -------------------------------------------------- //
#pragma once #pragma once
@ -16,7 +17,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

View 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

View File

@ -1,89 +0,0 @@
// Raspberry Pi Pico PIO program to output data to a TFT
// controller via a SPI output data path.
//"Set" set: 1 output pin, TFT_DC
// Side set: 1 output pin, TFT_SCLK
// Data set: 1 output pin, TFT_MOSI
.program tft_io
.side_set 1 opt ; The TFT_SCLK output.
// The C++ code switches between the 8 bits and 16 bits loops
// by waiting for the SM to be idle and setting its PC.
//
// 8 bit transfer
public start_8:
// Pull the next 32 bit value from the TX FIFO.
pull side 0
// Lose the top 24 bits, send 1st bit
out pins, 25
// Now send remaining bits
jmp spi_out side 1
public set_addr_window:
// Loop count in x for caset, paset and ramwr
set x, 2 side 0
pull_cmd:
// Set DC low
set pins, 0
// Fetch and output LS byte (caset, paset or ramwr), discarding top 24 bits, set WR low
pull side 0
out pins, 25
nop side 1
next_cmd_bit:
out pins, 1 side 0
jmp !osre, next_cmd_bit side 1
// Set DC high
set pins, 1 side 0
// Finish if 3rd cmd byte ramwr sent (x == 0)
jmp !x, start_16
pull
next_xy:
// send 32 bit start and end coordinates
out pins, 1 side 0
jmp !osre, next_xy side 1
// Loop back for next command
jmp x--, pull_cmd side 0
// End
jmp start_16
public block_fill:
// Fetch colour value
pull side 0
// Move colour to x
mov x, osr
// Fetch pixel count
pull
// Move pixel count to y
mov y, osr
next_16:
// Copy colour value back into osr
mov osr, x side 0
// Lose the top 16 bits, send 1st bit
out pins, 17 side 0
nop side 1
next_bit:
// Output next 15 colour bits
out pins, 1 side 0
// Set TFT_SCLK high and jump for next bit
jmp !osre, next_bit side 1
// Decrement count and loop
jmp y--, next_16 side 0
// Now drop back to 16 bit output
.wrap_target
public start_16:
// Pull the next 32 bit value from the TX FIFO.
// Send the bottom 16 bits
pull side 0
// 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 side 1
// Return to start
.wrap

View File

@ -1,5 +1,6 @@
// -------------------------------------------------- // // -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! // // This file is autogenerated by pioasm; do not edit! //
// 8 + 16 bit SPI - no auto colour conversion //
// -------------------------------------------------- // // -------------------------------------------------- //
#pragma once #pragma once
@ -18,7 +19,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

View File

@ -0,0 +1,74 @@
// -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! //
// 8 + 18 bit SPI - no auto colour conversion //
// -------------------------------------------------- //
#pragma once
#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif
// ------ //
// tft_io //
// ------ //
#define tft_io_wrap_target 27
#define tft_io_wrap 31
#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_tx 27u
static const uint16_t tft_io_program_instructions[] = {
0x90a0, // 0: pull block side 0
0x6019, // 1: out pins, 25
0x181e, // 2: jmp 30 side 1
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
0x7009, // 22: out pins, 9 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, // 27: pull block side 0
0x7009, // 28: out pins, 9 side 0
0xb842, // 29: nop side 1
0x7001, // 30: out pins, 1 side 0
0x18fe, // 31: jmp !osre, 30 side 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

View File

@ -1,12 +1,47 @@
A ["Discussions"](https://github.com/Bodmer/TFT_eSPI/discussions) facility has been added for Q&A etc. Use the ["Issues"](https://github.com/Bodmer/TFT_eSPI/issues) tab only for problems with the library. Thanks! A ["Discussions"](https://github.com/Bodmer/TFT_eSPI/discussions) facility has been added for Q&A etc. Use the ["Issues"](https://github.com/Bodmer/TFT_eSPI/issues) tab only for problems with the library. Thanks!
# News # News
1. New anti-aliased graphics functions to draw lines, wedge shaped lines, circles and rounded rectangles. [Examples are included](https://github.com/Bodmer/TFT_eSPI/tree/master/examples/Smooth%20Graphics). Examples have also been added to [display PNG compressed images](https://github.com/Bodmer/TFT_eSPI/tree/master/examples/PNG%20Images) (note: requires ~40kbytes RAM). 1. New functions have been added to draw smooth (antialiased) arcs, circles, and rounded rectangle outlines. New sketches are provided in the "Smooth Graphics" examples folder. Arcs can be drawn with or without anti-aliasing (which will then render faster). The arc ends can be straight or rounded. The arc drawing algorithm uses an optimised fixed point sqrt() function to improve performance on processors that do not have a hardware Floating Point Unit (e.g. RP2040). Here are two demo images, on the left smooth (anti-aliased) arcs with rounded ends, the image to the right is the same resolution (grabbed from the same 240x240 TFT) with the smoothing diasbled (no anti-aliasing):
2. Frank Boesing has created an extension library for TFT_eSPI that allows a large range of ready-built fonts to be used. Frank's library can be [downloaded here](https://github.com/FrankBoesing/TFT_eSPI_ext). More than 3300 additional Fonts are [available here](https://github.com/FrankBoesing/fonts/tree/master/ofl). The TFT_eSPI_ext library contains examples that demonstrate the use of the fonts. ![arcs](https://github.com/Bodmer/Github-images/blob/main/aa_arc_240x240.png) ![pixelated_arcs](https://github.com/Bodmer/Github-images/blob/main/no_aa_arc_240x240.png)
3. Users of PowerPoint experienced with running macros may be interested in the [pptm sketch generator here](https://github.com/Bodmer/PowerPoint_to_sketch), this converts graphics and tables drawn in PowerPoint slides into an Arduino sketch that renders the graphics on a 480x320 TFT. This is based on VB macros [created by Kris Kasprzak here](https://github.com/KrisKasprzak/Powerpoint-ILI9341_t3). Here the smooth arcs have been used to create anti-aliased meter gauges on a 320x240 TFT:
![arcs](https://github.com/Bodmer/Github-images/blob/main/xarc_meters_320x240.png)
4. The library contains two new functions for rectangles filled with a horizontal or vertical coloured gradient: 2. An excellent new compatible library is available which can render TrueType fonts on a TFT screen (or into a sprite). This has been developed by [takkaO](https://github.com/takkaO/OpenFontRender), I have created a branch with some bug fixes [here](https://github.com/Bodmer/OpenFontRender). The library provides access to compact font files, with fully scaleable anti-aliased glyphs. Left, middle and right justified text can also be printed to the screen. I have added TFT_eSPI specific examples to the OpenFontRender library and tested on RP2040 and ESP32 processors, the ESP8266 does not have sufficient RAM due to the glyph render complexity. Here is a demo screen where a single 12kbyte font file binary was used to render fully anti-aliased glyphs of gradually increasing size on a 320x480 TFT screen:
![ttf_font_demo](https://i.imgur.com/bKkilIb.png)
3. New GUI examples have been added for sliders, buttons, graphs and meters. These examples require a new support library here:
[TFT_eWidget](https://github.com/Bodmer/TFT_eWidget)
4. Support has been added in v2.4.70 for the RP2040 with 16 bit parallel displays. This has been tested and the screen update performance is very good (4ms to clear 320 x 480 screen with HC8357C). The use of the RP2040 PIO makes it easy to change the write cycle timing for different displays. DMA with 16 bit transfers is also supported.
5. Support for the ESP32-S2, ESP32-S3 and ESP32-C3 has been added (DMA only on ESP32 S3 at the moment). Tested with v2.0.3 RC1 of the ESP32 board package. Example setups:
[Setup70_ESP32_S2_ILI9341.h](https://github.com/Bodmer/TFT_eSPI/blob/master/User_Setups/Setup70_ESP32_S2_ILI9341.h)
[Setup70b_ESP32_S3_ILI9341.h](https://github.com/Bodmer/TFT_eSPI/blob/master/User_Setups/Setup70b_ESP32_S3_ILI9341.h)
[Setup70c_ESP32_C3_ILI9341.h](https://github.com/Bodmer/TFT_eSPI/blob/master/User_Setups/Setup70c_ESP32_C3_ILI9341.h)
[Setup70d_ILI9488_S3_Parallel.h](https://github.com/Bodmer/TFT_eSPI/blob/master/User_Setups/Setup70d_ILI9488_S3_Parallel.h)
6. Smooth fonts can now be rendered direct to the TFT with very little flicker for quickly changing values. This is achieved by a line-by-line and block-by-block update of the glyph area without drawing pixels twice. This is a "breaking" change for some sketches because a new true/false parameter is needed to render the background. The default is false if the parameter is missing, Examples:
tft.setTextColor(TFT_WHITE, TFT_BLUE, true);
spr.setTextColor(TFT_BLUE, TFT_BLACK, true);
Note: background rendering for Smooth fonts is also now available when using the print stream e.g. with: tft.println("Hello World");
7. New anti-aliased graphics functions to draw lines, wedge shaped lines, circles and rounded rectangles. [Examples are included](https://github.com/Bodmer/TFT_eSPI/tree/master/examples/Smooth%20Graphics). Examples have also been added to [display PNG compressed images](https://github.com/Bodmer/TFT_eSPI/tree/master/examples/PNG%20Images) (note: requires ~40kbytes RAM).
8. Frank Boesing has created an extension library for TFT_eSPI that allows a large range of ready-built fonts to be used. Frank's library (adapted to permit rendering in sprites as well as TFT) can be [downloaded here](https://github.com/Bodmer/TFT_eSPI_ext). More than 3300 additional Fonts are [available here](https://github.com/FrankBoesing/fonts/tree/master/ofl). The TFT_eSPI_ext library contains examples that demonstrate the use of the fonts.
9. Users of PowerPoint experienced with running macros may be interested in the [pptm sketch generator here](https://github.com/Bodmer/PowerPoint_to_sketch), this converts graphics and tables drawn in PowerPoint slides into an Arduino sketch that renders the graphics on a 480x320 TFT. This is based on VB macros [created by Kris Kasprzak here](https://github.com/KrisKasprzak/Powerpoint-ILI9341_t3).
10. The library contains two new functions for rectangles filled with a horizontal or vertical coloured gradient:
tft.fillRectHGradient(x, y, w, h, color1, color2); tft.fillRectHGradient(x, y, w, h, color1, color2);
@ -14,65 +49,61 @@ A ["Discussions"](https://github.com/Bodmer/TFT_eSPI/discussions) facility has b
![Gradient](https://i.imgur.com/atR0DmP.png) ![Gradient](https://i.imgur.com/atR0DmP.png)
5. The RP2040 8 bit parallel interface uses the PIO. The PIO now manages the "setWindow" and "block fill" actions, releasing the processor for other tasks when areas of the screen are being filled with a colour. The PIO can optionally be used for SPI interface displays if #define RP2040_PIO_SPI is put in the setup file. Touch screens and pixel read operations are not supported when the PIO interface is used. 11. The RP2040 8 bit parallel interface uses the PIO. The PIO now manages the "setWindow" and "block fill" actions, releasing the processor for other tasks when areas of the screen are being filled with a colour. The PIO can optionally be used for SPI interface displays if #define RP2040_PIO_SPI is put in the setup file. Touch screens and pixel read operations are not supported when the PIO interface is used.
The RP2040 PIO features only work with [Earle Philhower's board package](https://github.com/earlephilhower/arduino-pico), NOT the Arduino Mbed version. The RP2040 PIO features only work with [Earle Philhower's board package](https://github.com/earlephilhower/arduino-pico), NOT the Arduino Mbed version.
The use of PIO for SPI allows the RP2040 to be over-clocked (up to 250MHz works on my boards) in Earle's board package whilst still maintaining high SPI clock rates. The use of PIO for SPI allows the RP2040 to be over-clocked (up to 250MHz works on my boards) in Earle's board package whilst still maintaining high SPI clock rates.
6. DMA can now be used with the Raspberry Pi Pico (RP2040) when used with both 8 bit parallel and 16 bit colour SPI displays. See "Bouncy_Circles" sketch. 12. DMA can now be used with the Raspberry Pi Pico (RP2040) when used with 8/16 bit parallel and 16 bit colour SPI displays. See "Bouncy_Circles" sketch.
["Bouncing circles"](https://www.youtube.com/watch?v=njFXIzCTQ_Q&lc=UgymaUIwOIuihvYh-Qt4AaABAg) ["Bouncing circles"](https://www.youtube.com/watch?v=njFXIzCTQ_Q&lc=UgymaUIwOIuihvYh-Qt4AaABAg)
7. Support hase been added for the ESP32 S2 processor variant. A [new user setup](https://github.com/Bodmer/TFT_eSPI/blob/master/User_Setups/Setup70_ESP32_S2_ILI9341.h) file has been added as an example setup with an ILI9341 TFT.
8. The library now supports the Raspberry Pi Pico with both the [official Arduino board package](https://github.com/arduino/ArduinoCore-mbed) and the one provided by [Earle Philhower](https://github.com/earlephilhower/arduino-pico). The setup file "Setup60_RP2040_ILI9341.h" has been used for tests with an ILI9341 display. At the moment only SPI interface displays have been tested. SPI port 0 is the default but SPI port 1 can be specifed in the setup file if those SPI pins are used.
["Rotating cube demo"](https://www.youtube.com/watch?v=4fPxEN9ImVE)
9. The library now provides a "viewport" capability. See "Viewport_Demo" and "Viewport_graphicstest" examples. When a viewport is defined graphics will only appear within that window. The coordinate datum by default moves to the top left corner of the viewport, but can optionally remain at top left corner of TFT. The GUIslice library will make use of this feature to speed up the rendering of GUI objects ([see #769](https://github.com/Bodmer/TFT_eSPI/issues/769)).
10. The library now supports SSD1963 based screen, this has been tested on a [480x800 screen](https://www.buydisplay.com/7-tft-screen-touch-lcd-display-module-w-ssd1963-controller-board-mcu) with an ESP32. The interface is 8 bit parallel only as that controller does not support a SPI interface.
# TFT_eSPI # TFT_eSPI
An Arduino IDE compatible graphics and fonts library for 32 bit processors. The library is targeted at 32 bit processors, it has been performance optimised for STM32, ESP8266 and ESP32 types. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors to improve rendering performance. An Arduino IDE compatible graphics and fonts library for 32 bit processors. The library is targeted at 32 bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16 bit parallel) is only supported with the RP2040.
Optimised drivers are incorporated for the following processors: Optimised drivers have been tested with the following processors:
* RP2040, e.g. Raspberry Pi Pico * RP2040, e.g. Raspberry Pi Pico
* ESP32 and ESP32-S2 (ESP32C3 untested) * ESP32 and ESP32-S2, ESP32-C3, ESP32-S3
* ESP8266 * ESP8266
* STM32F1xx, STM32F2xx, STM32F4xx, STM32F767 (higher RAM processors recommended) * STM32F1xx, STM32F2xx, STM32F4xx, STM32F767 (higher RAM processors recommended)
Generic (non-optimised Arduino function calls) are used by the library for other processors. For other processors only SPI interface displays are supported and the slower Arduino SPI library functions are used by the library. Higher clock speed processors such as used for the Teensy 3.x and 4.x boards will still provide a very good performance with the generic Arduino SPI functions.
"Four wire" SPI and 8 bit parallel interfaces are supported. Due to lack of GPIO pins the 8 bit parallel interface is NOT supported on the ESP8266. 8 bit parallel interface TFTs (e.g. UNO format mcufriend shields) can used with the STM32 Nucleo 64/144 range or the UNO format ESP32 (see below for ESP32). "Four wire" SPI and 8 bit parallel interfaces are supported. Due to lack of GPIO pins the 8 bit parallel interface is NOT supported on the ESP8266. 8 bit parallel interface TFTs (e.g. UNO format mcufriend shields) can used with the STM32 Nucleo 64/144 range or the UNO format ESP32 (see below for ESP32).
Displays using the following controllers are supported: Displays using the following controllers are supported:
* GC9A01
* ILI9163 * ILI9163
* ILI9225 * ILI9225
* ILI9341 * ILI9341
* ILI9342
* ILI9481 (DMA not supported with SPI) * ILI9481 (DMA not supported with SPI)
* ILI9486 (DMA not supported with SPI) * ILI9486 (DMA not supported with SPI)
* ILI9488 (DMA not supported with SPI) * ILI9488 (DMA not supported with SPI)
* HX8357B (16 bit parallel tested with RP2040)
* HX8357C (16 bit parallel tested with RP2040)
* HX8357D * HX8357D
* R61581
* RM68120 (support files added but untested)
* RM68140
* S6D02A1 * S6D02A1
* SSD1351 * SSD1351
* SSD1963 * SSD1963
* ST7735 * ST7735
* ST7789 * ST7789
* ST7796 * ST7796
* GC9A01
ILI9341 and ST7796 SPI based displays are recommended as starting point for experimenting with this library. ILI9341 and ST7796 SPI based displays are recommended as starting point for experimenting with this library.
The library supports some TFT displays designed for the Raspberry Pi (RPi) that are based on a ILI9486 or ST7796 driver chip with a 480 x 320 pixel screen. The ILI9486 RPi display must be of the Waveshare design and use a 16 bit serial interface based on the 74HC04, 74HC4040 and 2 x 74HC4094 logic chips. Note that due to design variations between these displays not all RPi displays will work with this library, so purchasing a RPi display of these types solely for use with this library is not recommended. The library supports some TFT displays designed for the Raspberry Pi (RPi) that are based on a ILI9486 or ST7796 driver chip with a 480 x 320 pixel screen. The ILI9486 RPi display must be of the Waveshare design and use a 16 bit serial interface based on the 74HC04, 74HC4040 and 2 x 74HC4094 logic chips. Note that due to design variations between these displays not all RPi displays will work with this library, so purchasing a RPi display of these types solely for use with this library is NOT recommended.
A "good" RPi display is the [MHS-4.0 inch Display-B type ST7796](http://www.lcdwiki.com/MHS-4.0inch_Display-B) which provides good performance. This has a dedicated controller and can be clocked at up to 80MHz with the ESP32 (55MHz with STM32 and 40MHz with ESP8266). The [MHS-3.5 inch RPi ILI9486](http://www.lcdwiki.com/MHS-3.5inch_RPi_Display) based display is also supported. A "good" RPi display is the [MHS-4.0 inch Display-B type ST7796](http://www.lcdwiki.com/MHS-4.0inch_Display-B) which provides good performance. This has a dedicated controller and can be clocked at up to 80MHz with the ESP32 (125MHz with overclocked RP2040, 55MHz with STM32 and 40MHz with ESP8266). The [MHS-3.5 inch RPi ILI9486](http://www.lcdwiki.com/MHS-3.5inch_RPi_Display) based display is also supported, however the MHS ILI9341 based display of the same type does NOT work with this library.
Some displays permit the internal TFT screen RAM to be read, some of the examples use this feature. The TFT_Screen_Capture example allows full screens to be captured and sent to a PC, this is handy to create program documentation. Some displays permit the internal TFT screen RAM to be read, a few of the examples use this feature. The TFT_Screen_Capture example allows full screens to be captured and sent to a PC, this is handy to create program documentation.
The library supports Waveshare 2 and 3 colour ePaper displays using full frame buffers. This addition is relatively immature and thus only one example has been provided. The library supports Waveshare 2 and 3 colour ePaper displays using full frame buffers. This addition is relatively immature and thus only one example has been provided.
@ -119,7 +150,7 @@ Configuration of the library font selections, pins used to interface with the TF
Anti-aliased (smooth) font files in "vlw" format are generated by the free [Processing IDE](https://processing.org/) using a sketch included in the library Tools folder. This sketch with the Processing IDE can be used to generate font files from your computer's font set or any TrueType (.ttf) font, the font file can include **any** combination of 16 bit Unicode characters. This means Greek, Japanese and any other UCS-2 glyphs can be used. Character arrays and Strings in UTF-8 format are supported. Anti-aliased (smooth) font files in "vlw" format are generated by the free [Processing IDE](https://processing.org/) using a sketch included in the library Tools folder. This sketch with the Processing IDE can be used to generate font files from your computer's font set or any TrueType (.ttf) font, the font file can include **any** combination of 16 bit Unicode characters. This means Greek, Japanese and any other UCS-2 glyphs can be used. Character arrays and Strings in UTF-8 format are supported.
The .vlw files must be uploaded to the processors FLASH filing system (SPIFFS, LittleFS or SD card) for use. Alternatively the .vlw files can be converted to C arrays (see "Smooth Font -> FLASH_Array" examples) and stored directly in FLASH as part of the compile process. The array based approach is convenient, provides performance improvements and is suitable where: either use of a filing system is undesirable, or the processor type (e.g. STM32) does not support a FLASH based filing sytem. The .vlw files must be uploaded to the processors FLASH filing system (SPIFFS, LittleFS or SD card) for use. Alternatively the .vlw files can be converted to C arrays (see "Smooth Font -> FLASH_Array" examples) and stored directly in FLASH as part of the compile process. The array based approach is convenient, provides performance improvements and is suitable where: either use of a filing system is undesirable, or the processor type (e.g. STM32) does not support a FLASH based filing system.
Here is the Adafruit_GFX "FreeSans12pt" bitmap font compared to the same font drawn as anti-aliased: Here is the Adafruit_GFX "FreeSans12pt" bitmap font compared to the same font drawn as anti-aliased:
@ -176,10 +207,3 @@ You can take this one step further and have your own setup select file and then
#include <../TFT_eSPI_Setups/my_setup_select.h> #include <../TFT_eSPI_Setups/my_setup_select.h>
``` ```
To select a new setup you then edit your own my_setup_select.h file (which will not get overwritten during an upgrade). To select a new setup you then edit your own my_setup_select.h file (which will not get overwritten during an upgrade).
# ePaper displays
The library was intended to support only TFT displays but using a Sprite as a 1 bit per pixel screen buffer permits support for the Waveshare 2 and 3 colour SPI ePaper displays. This addition to the library is experimental and only one example is provided. Further examples will be added.
![Example](https://i.imgur.com/L2tV129.jpg?1)

View File

@ -1,7 +1,7 @@
This is a stand-alone library that contains both graphics functions This is a stand-alone library that contains both graphics functions
and the TFT chip driver library. It supports the ESP8266, ESP32 and and the TFT chip driver library. It supports the ESP8266, ESP32,
STM32 processors with performance optimised code. Other Arduino IDE STM32 and RP2040 processors with performance optimised code. Other
compatible boards are also supported but the library then uses Arduino IDE compatible boards are also supported but the library
generic functions which will be slower. The library uses 32 bit then uses generic functions which will be slower. The library uses
variables extensively so this will affect performance on 8 and 16 32 bit variables extensively so this will affect performance on 8
bit processors. and 16 bit processors.

View File

@ -0,0 +1,52 @@
// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
#define TFT_WIDTH 320
#define TFT_HEIGHT 480
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked
// Generic commands used by TFT_eSPar.cpp
#define TFT_NOP 0x00
#define TFT_SWRST 0x01
#define TFT_SLPIN 0x10
#define TFT_SLPOUT 0x11
#define TFT_INVOFF 0x20
#define TFT_INVON 0x21
#define TFT_DISPOFF 0x28
#define TFT_DISPON 0x29
#define TFT_CASET 0x2A
#define TFT_PASET 0x2B
#define TFT_RAMWR 0x2C
#define TFT_RAMRD 0x2E
#define TFT_MADCTL 0x36
#define TFT_MAD_MY 0x80
#define TFT_MAD_MX 0x40
#define TFT_MAD_MV 0x20
#define TFT_MAD_ML 0x10
#define TFT_MAD_RGB 0x00
#define TFT_MAD_BGR 0x08
#define TFT_MAD_MH 0x04
#define TFT_MAD_SS 0x02
#define TFT_MAD_GS 0x01
#ifdef TFT_RGB_ORDER
#if (TFT_RGB_ORDER == 1)
#define TFT_MAD_COLOR_ORDER TFT_MAD_RGB
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
#define TFT_IDXRD 0x00 // ILI9341 only, indexed control register read

View File

@ -0,0 +1,76 @@
// This is the command sequence that initialises the HX8357B driver
//
// This setup information uses simple 8 bit SPI writecommand() and writedata() functions
//
// See ST7735_Setup.h file for an alternative format
// Configure HX8357-B display
writecommand(0x11);
delay(20);
writecommand(0xD0);
writedata(0x07);
writedata(0x42);
writedata(0x18);
writecommand(0xD1);
writedata(0x00);
writedata(0x07);
writedata(0x10);
writecommand(0xD2);
writedata(0x01);
writedata(0x02);
writecommand(0xC0);
writedata(0x10);
writedata(0x3B);
writedata(0x00);
writedata(0x02);
writedata(0x11);
writecommand(0xC5);
writedata(0x08);
writecommand(0xC8);
writedata(0x00);
writedata(0x32);
writedata(0x36);
writedata(0x45);
writedata(0x06);
writedata(0x16);
writedata(0x37);
writedata(0x75);
writedata(0x77);
writedata(0x54);
writedata(0x0C);
writedata(0x00);
writecommand(0x36);
writedata(0x0a);
writecommand(0x3A);
writedata(0x55);
writecommand(0x2A);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);
writecommand(0x2B);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDF);
delay(120);
writecommand(0x29);
delay(25);
// End of HX8357B display configuration

View File

@ -0,0 +1,47 @@
// This is the command sequence that rotates the HX8357C driver coordinate frame
writecommand(TFT_MADCTL);
rotation = m % 8;
switch (rotation) {
case 0: // Portrait
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MX);
_width = _init_width;
_height = _init_height;
break;
case 1: // Landscape (Portrait + 90)
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MV);
_width = _init_height;
_height = _init_width;
break;
case 2: // Inverter portrait
writedata( TFT_MAD_COLOR_ORDER | TFT_MAD_MY);
_width = _init_width;
_height = _init_height;
break;
case 3: // Inverted landscape
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MV | TFT_MAD_MX | TFT_MAD_MY);
_width = _init_height;
_height = _init_width;
break;
case 4: // Portrait
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MX | TFT_MAD_MY);
_width = _init_width;
_height = _init_height;
break;
case 5: // Landscape (Portrait + 90)
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MV | TFT_MAD_MX);
_width = _init_height;
_height = _init_width;
break;
case 6: // Inverter portrait
writedata( TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 7: // Inverted landscape
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MV | TFT_MAD_MY);
_width = _init_height;
_height = _init_width;
break;
}

View File

@ -0,0 +1,52 @@
// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
#define TFT_WIDTH 320
#define TFT_HEIGHT 480
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked
// Generic commands used by TFT_eSPar.cpp
#define TFT_NOP 0x00
#define TFT_SWRST 0x01
#define TFT_SLPIN 0x10
#define TFT_SLPOUT 0x11
#define TFT_INVOFF 0x20
#define TFT_INVON 0x21
#define TFT_DISPOFF 0x28
#define TFT_DISPON 0x29
#define TFT_CASET 0x2A
#define TFT_PASET 0x2B
#define TFT_RAMWR 0x2C
#define TFT_RAMRD 0x2E
#define TFT_MADCTL 0x36
#define TFT_MAD_MY 0x80
#define TFT_MAD_MX 0x40
#define TFT_MAD_MV 0x20
#define TFT_MAD_ML 0x10
#define TFT_MAD_RGB 0x00
#define TFT_MAD_BGR 0x08
#define TFT_MAD_MH 0x04
#define TFT_MAD_SS 0x02
#define TFT_MAD_GS 0x01
#ifdef TFT_RGB_ORDER
#if (TFT_RGB_ORDER == 1)
#define TFT_MAD_COLOR_ORDER TFT_MAD_RGB
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
#define TFT_IDXRD 0x00 // ILI9341 only, indexed control register read

116
TFT_Drivers/HX8357C_Init.h Normal file
View File

@ -0,0 +1,116 @@
// This is the command sequence that initialises the HX8357C driver
//
// This setup information uses simple 8 bit SPI writecommand() and writedata() functions
//
// See ST7735_Setup.h file for an alternative format
// Configure HX8357C display
writecommand(0xB9); // Enable extension command
writedata(0xFF);
writedata(0x83);
writedata(0x57);
delay(50);
writecommand(0xB6); //Set VCOM voltage
writedata(0x2C); //0x52 for HSD 3.0"
writecommand(0x11); // Sleep off
delay(200);
writecommand(0x35); // Tearing effect on
writedata(0x00); // Added parameter
writecommand(0x3A); // Interface pixel format
writedata(0x55); // 16 bits per pixel
//writecommand(0xCC); // Set panel characteristic
//writedata(0x09); // S960>S1, G1>G480, R-G-B, normally black
//writecommand(0xB3); // RGB interface
//writedata(0x43);
//writedata(0x00);
//writedata(0x06);
//writedata(0x06);
writecommand(0xB1); // Power control
writedata(0x00);
writedata(0x15);
writedata(0x0D);
writedata(0x0D);
writedata(0x83);
writedata(0x48);
writecommand(0xC0); // Does this do anything?
writedata(0x24);
writedata(0x24);
writedata(0x01);
writedata(0x3C);
writedata(0xC8);
writedata(0x08);
writecommand(0xB4); // Display cycle
writedata(0x02);
writedata(0x40);
writedata(0x00);
writedata(0x2A);
writedata(0x2A);
writedata(0x0D);
writedata(0x4F);
writecommand(0xE0); // Gamma curve
writedata(0x00);
writedata(0x15);
writedata(0x1D);
writedata(0x2A);
writedata(0x31);
writedata(0x42);
writedata(0x4C);
writedata(0x53);
writedata(0x45);
writedata(0x40);
writedata(0x3B);
writedata(0x32);
writedata(0x2E);
writedata(0x28);
writedata(0x24);
writedata(0x03);
writedata(0x00);
writedata(0x15);
writedata(0x1D);
writedata(0x2A);
writedata(0x31);
writedata(0x42);
writedata(0x4C);
writedata(0x53);
writedata(0x45);
writedata(0x40);
writedata(0x3B);
writedata(0x32);
writedata(0x2E);
writedata(0x28);
writedata(0x24);
writedata(0x03);
writedata(0x00);
writedata(0x01);
writecommand(0x36); // MADCTL Memory access control
writedata(0x48);
delay(20);
writecommand(0x21); //Display inversion on
delay(20);
writecommand(0x29); // Display on
delay(120);
// End of HX8357C display configuration

View File

@ -0,0 +1,47 @@
// This is the command sequence that rotates the HX8357C driver coordinate frame
writecommand(TFT_MADCTL);
rotation = m % 8;
switch (rotation) {
case 0: // Portrait
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MX);
_width = _init_width;
_height = _init_height;
break;
case 1: // Landscape (Portrait + 90)
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MV);
_width = _init_height;
_height = _init_width;
break;
case 2: // Inverter portrait
writedata( TFT_MAD_COLOR_ORDER | TFT_MAD_MY);
_width = _init_width;
_height = _init_height;
break;
case 3: // Inverted landscape
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MV | TFT_MAD_MX | TFT_MAD_MY);
_width = _init_height;
_height = _init_width;
break;
case 4: // Portrait
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MX | TFT_MAD_MY);
_width = _init_width;
_height = _init_height;
break;
case 5: // Landscape (Portrait + 90)
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MV | TFT_MAD_MX);
_width = _init_height;
_height = _init_width;
break;
case 6: // Inverter portrait
writedata( TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 7: // Inverted landscape
writedata(TFT_MAD_COLOR_ORDER | TFT_MAD_MV | TFT_MAD_MY);
_width = _init_height;
_height = _init_width;
break;
}

View File

@ -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
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
#if defined (ILI9341_DRIVER) || defined (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 // 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

View File

@ -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);

View File

@ -11,6 +11,8 @@
//#define ILI9481_INIT_4 // AUO317 //#define ILI9481_INIT_4 // AUO317
//#define ILI9481_INIT_5 // CMO35 ***** //#define ILI9481_INIT_5 // CMO35 *****
//#define ILI9481_INIT_6 // RGB //#define ILI9481_INIT_6 // RGB
//#define ILI9481_INIT_7 // From #1774
//#define ILI9481_INIT_8 // From #1774
///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////
#ifdef ILI9481_INIT_1 #ifdef ILI9481_INIT_1
@ -61,13 +63,13 @@
writedata(0x0A); writedata(0x0A);
writecommand(0x3A); writecommand(0x3A);
#if defined (TFT_PARALLEL_8_BIT) || defined (RPI_DISPLAY_TYPE) #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writedata(0x55); // 16 bit colour interface writedata(0x55); // 16 bit colour interface
#else #else
writedata(0x66); // 18 bit colour interface writedata(0x66); // 18 bit colour interface
#endif #endif
#ifndef TFT_PARALLEL_8_BIT #if !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT)
writecommand(TFT_INVON); writecommand(TFT_INVON);
#endif #endif
@ -150,13 +152,13 @@
writedata(0x0A); writedata(0x0A);
writecommand(0x3A); writecommand(0x3A);
#if defined (TFT_PARALLEL_8_BIT) || defined (RPI_DISPLAY_TYPE) #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writedata(0x55); // 16 bit colour interface writedata(0x55); // 16 bit colour interface
#else #else
writedata(0x66); // 18 bit colour interface writedata(0x66); // 18 bit colour interface
#endif #endif
#ifndef TFT_PARALLEL_8_BIT #if !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT)
writecommand(TFT_INVON); writecommand(TFT_INVON);
#endif #endif
@ -239,13 +241,13 @@
writedata(0x0A); writedata(0x0A);
writecommand(0x3A); writecommand(0x3A);
#if defined (TFT_PARALLEL_8_BIT) || defined (RPI_DISPLAY_TYPE) #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writedata(0x55); // 16 bit colour interface writedata(0x55); // 16 bit colour interface
#else #else
writedata(0x66); // 18 bit colour interface writedata(0x66); // 18 bit colour interface
#endif #endif
#ifndef TFT_PARALLEL_8_BIT #if !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT)
writecommand(TFT_INVON); writecommand(TFT_INVON);
#endif #endif
@ -324,13 +326,13 @@
writedata(0x0A); writedata(0x0A);
writecommand(0x3A); writecommand(0x3A);
#if defined (TFT_PARALLEL_8_BIT) || defined (RPI_DISPLAY_TYPE) #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writedata(0x55); // 16 bit colour interface writedata(0x55); // 16 bit colour interface
#else #else
writedata(0x66); // 18 bit colour interface writedata(0x66); // 18 bit colour interface
#endif #endif
#ifndef TFT_PARALLEL_8_BIT #if !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT)
writecommand(TFT_INVON); writecommand(TFT_INVON);
#endif #endif
@ -412,13 +414,13 @@
writedata(0x0A); writedata(0x0A);
writecommand(0x3A); writecommand(0x3A);
#if defined (TFT_PARALLEL_8_BIT) || defined (RPI_DISPLAY_TYPE) #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writedata(0x55); // 16 bit colour interface writedata(0x55); // 16 bit colour interface
#else #else
writedata(0x66); // 18 bit colour interface writedata(0x66); // 18 bit colour interface
#endif #endif
#ifndef TFT_PARALLEL_8_BIT #if !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT)
writecommand(TFT_INVON); writecommand(TFT_INVON);
#endif #endif
@ -524,13 +526,13 @@
writedata(0x0A); writedata(0x0A);
writecommand(0x3A); writecommand(0x3A);
#if defined (TFT_PARALLEL_8_BIT) || defined (RPI_DISPLAY_TYPE) #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writedata(0x55); // 16 bit colour interface writedata(0x55); // 16 bit colour interface
#else #else
writedata(0x66); // 18 bit colour interface writedata(0x66); // 18 bit colour interface
#endif #endif
#ifndef TFT_PARALLEL_8_BIT #if !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT)
writecommand(TFT_INVON); writecommand(TFT_INVON);
#endif #endif
@ -552,4 +554,183 @@
delay(25); delay(25);
// End of ILI9481 display configuration // End of ILI9481 display configuration
///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////
// From #1774
#elif defined (ILI9481_INIT_7)
///ili9481+cmi3.5ips //效果不好
//************* Start Initial Sequence **********//
writecommand(0x11);
delay(20);
writecommand(0xD0);
writedata(0x07);
writedata(0x42);
writedata(0x1B);
writecommand(0xD1);
writedata(0x00);
writedata(0x14);
writedata(0x1B);
writecommand(0xD2);
writedata(0x01);
writedata(0x12);
writecommand(0xC0);
writedata(0x10);
writedata(0x3B);
writedata(0x00);
writedata(0x02);
writedata(0x01);
writecommand(0xC5);
writedata(0x03);
writecommand(0xC8);
writedata(0x00);
writedata(0x46);
writedata(0x44);
writedata(0x50);
writedata(0x04);
writedata(0x16);
writedata(0x33);
writedata(0x13);
writedata(0x77);
writedata(0x05);
writedata(0x0F);
writedata(0x00);
writecommand(0x36);
writedata(0x0A);
writecommand(0x3A);
#if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writedata(0x55); // 16 bit colour interface
#else
writedata(0x66); // 18 bit colour interface
#endif
#if !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT)
writecommand(TFT_INVON);
#endif
writecommand(0x22);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);
writecommand(0x2B);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xE0);
delay(120);
writecommand(0x29);
#elif defined (ILI9481_INIT_8)
//3.5IPS ILI9481+CMI
writecommand(0x01); //Soft_rese
delay(220);
writecommand(0x11);
delay(280);
writecommand(0xd0); //Power_Setting
writedata(0x07);//07 VC[2:0] Sets the ratio factor of Vci to generate the reference voltages Vci1
writedata(0x44);//41 BT[2:0] Sets the Step up factor and output voltage level from the reference voltages Vci1
writedata(0x1E);//1f 17 1C VRH[3:0]: Sets the factor to generate VREG1OUT from VCILVL
delay(220);
writecommand(0xd1); //VCOM Control
writedata(0x00);//00
writedata(0x0C);//1A VCM [6:0] is used to set factor to generate VCOMH voltage from the reference voltage VREG1OUT 15 09
writedata(0x1A);//1F VDV[4:0] is used to set the VCOM alternating amplitude in the range of VREG1OUT x 0.70 to VREG1OUT 1F 18
writecommand(0xC5); //Frame Rate
writedata(0x03); // 03 02
writecommand(0xd2); //Power_Setting for Normal Mode
writedata(0x01); //01
writedata(0x11); //11
writecommand(0xE4); //?
writedata(0xa0);
writecommand(0xf3);
writedata(0x00);
writedata(0x2a);
//1 OK
writecommand(0xc8);
writedata(0x00);
writedata(0x26);
writedata(0x21);
writedata(0x00);
writedata(0x00);
writedata(0x1f);
writedata(0x65);
writedata(0x23);
writedata(0x77);
writedata(0x00);
writedata(0x0f);
writedata(0x00);
//GAMMA SETTING
writecommand(0xC0); //Panel Driving Setting
writedata(0x00); //1//00 REV SM GS
writedata(0x3B); //2//NL[5:0]: Sets the number of lines to drive the LCD at an interval of 8 lines.
writedata(0x00); //3//SCN[6:0]
writedata(0x02); //4//PTV: Sets the Vcom output in non-display area drive period
writedata(0x11); //5//NDL: Sets the source output level in non-display area. PTG: Sets the scan mode in non-display area.
writecommand(0xc6); //Interface Control
writedata(0x83);
//GAMMA SETTING
writecommand(0xf0); //?
writedata(0x01);
writecommand(0xE4);//?
writedata(0xa0);
//////倒装设置 NG
writecommand(0x36);
writedata(0x0A); // 8C:出来两行 CA出来一个点
writecommand(0x3a);
#if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writedata(0x55); // 16 bit colour interface
#else
writedata(0x66); // 18 bit colour interface
#endif
#if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT)
writecommand(TFT_INVON);
#endif
writecommand(0xb4);//Display Mode and Frame Memory Write Mode Setting
writedata(0x02);
writedata(0x00); //?
writedata(0x00);
writedata(0x01);
delay(280);
writecommand(0x2a);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F); //3F
writecommand(0x2b);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDf); //DF
//writecommand(0x21);
writecommand(0x29);
writecommand(0x2c);
#endif #endif

View File

@ -15,14 +15,20 @@
delay(120); delay(120);
writecommand(0x3A); writecommand(0x3A);
#if defined (TFT_PARALLEL_8_BIT) || defined (RPI_DISPLAY_TYPE) #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writedata(0x55); // 16 bit colour interface writedata(0x55); // 16 bit colour interface
#else #else
writedata(0x66); // 18 bit colour interface writedata(0x66); // 18 bit colour interface
#endif #endif
writecommand(0xC2); writecommand(0xC0); // 1100.0000 Power Control 1
writedata(0x44); writedata(0x0E); // 0001.0111 ... VRH1
writedata(0x0E); // 0001.0101 ... VRH2
writecommand(0xC1); // 1100.0001 Power Control 2
writedata(0x41); // 0100.0001 . SAP BT
writedata(0x00); // 0000.0000 ..... VC
writecommand(0xC2); // 1100.0010 Power Control 3
writedata(0x55); // nb. was 0x44 0101.0101 . DCA1 . DCA0
writecommand(0xC5); writecommand(0xC5);
writedata(0x00); writedata(0x00);
@ -64,7 +70,7 @@
writedata(0x20); writedata(0x20);
writedata(0x00); writedata(0x00);
#if defined (TFT_PARALLEL_8_BIT) || defined (RPI_DISPLAY_TYPE) #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writecommand(TFT_INVOFF); writecommand(TFT_INVOFF);
#else #else
writecommand(TFT_INVON); writecommand(TFT_INVON);

View File

@ -58,7 +58,7 @@
writedata(0x48); // MX, BGR writedata(0x48); // MX, BGR
writecommand(0x3A); // Pixel Interface Format writecommand(0x3A); // Pixel Interface Format
#if defined (TFT_PARALLEL_8_BIT) || defined (RPI_DISPLAY_TYPE) #if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writedata(0x55); // 16 bit colour for parallel writedata(0x55); // 16 bit colour for parallel
#else #else
writedata(0x66); // 18 bit colour for SPI writedata(0x66); // 18 bit colour for SPI

View File

@ -0,0 +1,47 @@
// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
// RM68120_DRIVER
#define TFT_WIDTH 480
#define TFT_HEIGHT 800
//Set driver type common to all TBD initialisation options
#ifndef RM68120_DRIVER
#define RM68120_DRIVER
#endif
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked
// Generic commands used by TFT_eSPI.cpp
#define TFT_NOP 0x0000
#define TFT_SWRST 0x0100
#define TFT_CASET 0x2A00
#define TFT_PASET 0x2B00
#define TFT_RAMWR 0x2C00
#define TFT_RAMRD 0x2E00
#define TFT_IDXRD 0xDD00 // ILI9341 only, indexed control register read
#define TFT_MADCTL 0x3600
#define TFT_MAD_MY 0x80
#define TFT_MAD_MX 0x40
#define TFT_MAD_MV 0x20
#define TFT_MAD_ML 0x10
#define TFT_MAD_BGR 0x08
#define TFT_MAD_MH 0x04
#define TFT_MAD_RGB 0x00
#ifdef TFT_RGB_ORDER
#if (TFT_RGB_ORDER == 1)
#define TFT_MAD_COLOR_ORDER TFT_MAD_RGB
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_RGB
#endif
#define TFT_INVOFF 0x2000
#define TFT_INVON 0x2100

429
TFT_Drivers/RM68120_Init.h Normal file
View File

@ -0,0 +1,429 @@
writeRegister(0xF000, 0x55);
writeRegister(0xF001, 0xAA);
writeRegister(0xF002, 0x52);
writeRegister(0xF003, 0x08);
writeRegister(0xF004, 0x01);
//GAMMA SETING RED
writeRegister(0xD100, 0x00);
writeRegister(0xD101, 0x00);
writeRegister(0xD102, 0x1b);
writeRegister(0xD103, 0x44);
writeRegister(0xD104, 0x62);
writeRegister(0xD105, 0x00);
writeRegister(0xD106, 0x7b);
writeRegister(0xD107, 0xa1);
writeRegister(0xD108, 0xc0);
writeRegister(0xD109, 0xee);
writeRegister(0xD10A, 0x55);
writeRegister(0xD10B, 0x10);
writeRegister(0xD10C, 0x2c);
writeRegister(0xD10D, 0x43);
writeRegister(0xD10E, 0x57);
writeRegister(0xD10F, 0x55);
writeRegister(0xD110, 0x68);
writeRegister(0xD111, 0x78);
writeRegister(0xD112, 0x87);
writeRegister(0xD113, 0x94);
writeRegister(0xD114, 0x55);
writeRegister(0xD115, 0xa0);
writeRegister(0xD116, 0xac);
writeRegister(0xD117, 0xb6);
writeRegister(0xD118, 0xc1);
writeRegister(0xD119, 0x55);
writeRegister(0xD11A, 0xcb);
writeRegister(0xD11B, 0xcd);
writeRegister(0xD11C, 0xd6);
writeRegister(0xD11D, 0xdf);
writeRegister(0xD11E, 0x95);
writeRegister(0xD11F, 0xe8);
writeRegister(0xD120, 0xf1);
writeRegister(0xD121, 0xfa);
writeRegister(0xD122, 0x02);
writeRegister(0xD123, 0xaa);
writeRegister(0xD124, 0x0b);
writeRegister(0xD125, 0x13);
writeRegister(0xD126, 0x1d);
writeRegister(0xD127, 0x26);
writeRegister(0xD128, 0xaa);
writeRegister(0xD129, 0x30);
writeRegister(0xD12A, 0x3c);
writeRegister(0xD12B, 0x4A);
writeRegister(0xD12C, 0x63);
writeRegister(0xD12D, 0xea);
writeRegister(0xD12E, 0x79);
writeRegister(0xD12F, 0xa6);
writeRegister(0xD130, 0xd0);
writeRegister(0xD131, 0x20);
writeRegister(0xD132, 0x0f);
writeRegister(0xD133, 0x8e);
writeRegister(0xD134, 0xff);
//GAMMA SETING GREEN
writeRegister(0xD200, 0x00);
writeRegister(0xD201, 0x00);
writeRegister(0xD202, 0x1b);
writeRegister(0xD203, 0x44);
writeRegister(0xD204, 0x62);
writeRegister(0xD205, 0x00);
writeRegister(0xD206, 0x7b);
writeRegister(0xD207, 0xa1);
writeRegister(0xD208, 0xc0);
writeRegister(0xD209, 0xee);
writeRegister(0xD20A, 0x55);
writeRegister(0xD20B, 0x10);
writeRegister(0xD20C, 0x2c);
writeRegister(0xD20D, 0x43);
writeRegister(0xD20E, 0x57);
writeRegister(0xD20F, 0x55);
writeRegister(0xD210, 0x68);
writeRegister(0xD211, 0x78);
writeRegister(0xD212, 0x87);
writeRegister(0xD213, 0x94);
writeRegister(0xD214, 0x55);
writeRegister(0xD215, 0xa0);
writeRegister(0xD216, 0xac);
writeRegister(0xD217, 0xb6);
writeRegister(0xD218, 0xc1);
writeRegister(0xD219, 0x55);
writeRegister(0xD21A, 0xcb);
writeRegister(0xD21B, 0xcd);
writeRegister(0xD21C, 0xd6);
writeRegister(0xD21D, 0xdf);
writeRegister(0xD21E, 0x95);
writeRegister(0xD21F, 0xe8);
writeRegister(0xD220, 0xf1);
writeRegister(0xD221, 0xfa);
writeRegister(0xD222, 0x02);
writeRegister(0xD223, 0xaa);
writeRegister(0xD224, 0x0b);
writeRegister(0xD225, 0x13);
writeRegister(0xD226, 0x1d);
writeRegister(0xD227, 0x26);
writeRegister(0xD228, 0xaa);
writeRegister(0xD229, 0x30);
writeRegister(0xD22A, 0x3c);
writeRegister(0xD22B, 0x4a);
writeRegister(0xD22C, 0x63);
writeRegister(0xD22D, 0xea);
writeRegister(0xD22E, 0x79);
writeRegister(0xD22F, 0xa6);
writeRegister(0xD230, 0xd0);
writeRegister(0xD231, 0x20);
writeRegister(0xD232, 0x0f);
writeRegister(0xD233, 0x8e);
writeRegister(0xD234, 0xff);
//GAMMA SETING BLUE
writeRegister(0xD300, 0x00);
writeRegister(0xD301, 0x00);
writeRegister(0xD302, 0x1b);
writeRegister(0xD303, 0x44);
writeRegister(0xD304, 0x62);
writeRegister(0xD305, 0x00);
writeRegister(0xD306, 0x7b);
writeRegister(0xD307, 0xa1);
writeRegister(0xD308, 0xc0);
writeRegister(0xD309, 0xee);
writeRegister(0xD30A, 0x55);
writeRegister(0xD30B, 0x10);
writeRegister(0xD30C, 0x2c);
writeRegister(0xD30D, 0x43);
writeRegister(0xD30E, 0x57);
writeRegister(0xD30F, 0x55);
writeRegister(0xD310, 0x68);
writeRegister(0xD311, 0x78);
writeRegister(0xD312, 0x87);
writeRegister(0xD313, 0x94);
writeRegister(0xD314, 0x55);
writeRegister(0xD315, 0xa0);
writeRegister(0xD316, 0xac);
writeRegister(0xD317, 0xb6);
writeRegister(0xD318, 0xc1);
writeRegister(0xD319, 0x55);
writeRegister(0xD31A, 0xcb);
writeRegister(0xD31B, 0xcd);
writeRegister(0xD31C, 0xd6);
writeRegister(0xD31D, 0xdf);
writeRegister(0xD31E, 0x95);
writeRegister(0xD31F, 0xe8);
writeRegister(0xD320, 0xf1);
writeRegister(0xD321, 0xfa);
writeRegister(0xD322, 0x02);
writeRegister(0xD323, 0xaa);
writeRegister(0xD324, 0x0b);
writeRegister(0xD325, 0x13);
writeRegister(0xD326, 0x1d);
writeRegister(0xD327, 0x26);
writeRegister(0xD328, 0xaa);
writeRegister(0xD329, 0x30);
writeRegister(0xD32A, 0x3c);
writeRegister(0xD32B, 0x4A);
writeRegister(0xD32C, 0x63);
writeRegister(0xD32D, 0xea);
writeRegister(0xD32E, 0x79);
writeRegister(0xD32F, 0xa6);
writeRegister(0xD330, 0xd0);
writeRegister(0xD331, 0x20);
writeRegister(0xD332, 0x0f);
writeRegister(0xD333, 0x8e);
writeRegister(0xD334, 0xff);
//GAMMA SETING RED
writeRegister(0xD400, 0x00);
writeRegister(0xD401, 0x00);
writeRegister(0xD402, 0x1b);
writeRegister(0xD403, 0x44);
writeRegister(0xD404, 0x62);
writeRegister(0xD405, 0x00);
writeRegister(0xD406, 0x7b);
writeRegister(0xD407, 0xa1);
writeRegister(0xD408, 0xc0);
writeRegister(0xD409, 0xee);
writeRegister(0xD40A, 0x55);
writeRegister(0xD40B, 0x10);
writeRegister(0xD40C, 0x2c);
writeRegister(0xD40D, 0x43);
writeRegister(0xD40E, 0x57);
writeRegister(0xD40F, 0x55);
writeRegister(0xD410, 0x68);
writeRegister(0xD411, 0x78);
writeRegister(0xD412, 0x87);
writeRegister(0xD413, 0x94);
writeRegister(0xD414, 0x55);
writeRegister(0xD415, 0xa0);
writeRegister(0xD416, 0xac);
writeRegister(0xD417, 0xb6);
writeRegister(0xD418, 0xc1);
writeRegister(0xD419, 0x55);
writeRegister(0xD41A, 0xcb);
writeRegister(0xD41B, 0xcd);
writeRegister(0xD41C, 0xd6);
writeRegister(0xD41D, 0xdf);
writeRegister(0xD41E, 0x95);
writeRegister(0xD41F, 0xe8);
writeRegister(0xD420, 0xf1);
writeRegister(0xD421, 0xfa);
writeRegister(0xD422, 0x02);
writeRegister(0xD423, 0xaa);
writeRegister(0xD424, 0x0b);
writeRegister(0xD425, 0x13);
writeRegister(0xD426, 0x1d);
writeRegister(0xD427, 0x26);
writeRegister(0xD428, 0xaa);
writeRegister(0xD429, 0x30);
writeRegister(0xD42A, 0x3c);
writeRegister(0xD42B, 0x4A);
writeRegister(0xD42C, 0x63);
writeRegister(0xD42D, 0xea);
writeRegister(0xD42E, 0x79);
writeRegister(0xD42F, 0xa6);
writeRegister(0xD430, 0xd0);
writeRegister(0xD431, 0x20);
writeRegister(0xD432, 0x0f);
writeRegister(0xD433, 0x8e);
writeRegister(0xD434, 0xff);
//GAMMA SETING GREEN
writeRegister(0xD500, 0x00);
writeRegister(0xD501, 0x00);
writeRegister(0xD502, 0x1b);
writeRegister(0xD503, 0x44);
writeRegister(0xD504, 0x62);
writeRegister(0xD505, 0x00);
writeRegister(0xD506, 0x7b);
writeRegister(0xD507, 0xa1);
writeRegister(0xD508, 0xc0);
writeRegister(0xD509, 0xee);
writeRegister(0xD50A, 0x55);
writeRegister(0xD50B, 0x10);
writeRegister(0xD50C, 0x2c);
writeRegister(0xD50D, 0x43);
writeRegister(0xD50E, 0x57);
writeRegister(0xD50F, 0x55);
writeRegister(0xD510, 0x68);
writeRegister(0xD511, 0x78);
writeRegister(0xD512, 0x87);
writeRegister(0xD513, 0x94);
writeRegister(0xD514, 0x55);
writeRegister(0xD515, 0xa0);
writeRegister(0xD516, 0xac);
writeRegister(0xD517, 0xb6);
writeRegister(0xD518, 0xc1);
writeRegister(0xD519, 0x55);
writeRegister(0xD51A, 0xcb);
writeRegister(0xD51B, 0xcd);
writeRegister(0xD51C, 0xd6);
writeRegister(0xD51D, 0xdf);
writeRegister(0xD51E, 0x95);
writeRegister(0xD51F, 0xe8);
writeRegister(0xD520, 0xf1);
writeRegister(0xD521, 0xfa);
writeRegister(0xD522, 0x02);
writeRegister(0xD523, 0xaa);
writeRegister(0xD524, 0x0b);
writeRegister(0xD525, 0x13);
writeRegister(0xD526, 0x1d);
writeRegister(0xD527, 0x26);
writeRegister(0xD528, 0xaa);
writeRegister(0xD529, 0x30);
writeRegister(0xD52A, 0x3c);
writeRegister(0xD52B, 0x4a);
writeRegister(0xD52C, 0x63);
writeRegister(0xD52D, 0xea);
writeRegister(0xD52E, 0x79);
writeRegister(0xD52F, 0xa6);
writeRegister(0xD530, 0xd0);
writeRegister(0xD531, 0x20);
writeRegister(0xD532, 0x0f);
writeRegister(0xD533, 0x8e);
writeRegister(0xD534, 0xff);
//GAMMA SETING BLUE
writeRegister(0xD600, 0x00);
writeRegister(0xD601, 0x00);
writeRegister(0xD602, 0x1b);
writeRegister(0xD603, 0x44);
writeRegister(0xD604, 0x62);
writeRegister(0xD605, 0x00);
writeRegister(0xD606, 0x7b);
writeRegister(0xD607, 0xa1);
writeRegister(0xD608, 0xc0);
writeRegister(0xD609, 0xee);
writeRegister(0xD60A, 0x55);
writeRegister(0xD60B, 0x10);
writeRegister(0xD60C, 0x2c);
writeRegister(0xD60D, 0x43);
writeRegister(0xD60E, 0x57);
writeRegister(0xD60F, 0x55);
writeRegister(0xD610, 0x68);
writeRegister(0xD611, 0x78);
writeRegister(0xD612, 0x87);
writeRegister(0xD613, 0x94);
writeRegister(0xD614, 0x55);
writeRegister(0xD615, 0xa0);
writeRegister(0xD616, 0xac);
writeRegister(0xD617, 0xb6);
writeRegister(0xD618, 0xc1);
writeRegister(0xD619, 0x55);
writeRegister(0xD61A, 0xcb);
writeRegister(0xD61B, 0xcd);
writeRegister(0xD61C, 0xd6);
writeRegister(0xD61D, 0xdf);
writeRegister(0xD61E, 0x95);
writeRegister(0xD61F, 0xe8);
writeRegister(0xD620, 0xf1);
writeRegister(0xD621, 0xfa);
writeRegister(0xD622, 0x02);
writeRegister(0xD623, 0xaa);
writeRegister(0xD624, 0x0b);
writeRegister(0xD625, 0x13);
writeRegister(0xD626, 0x1d);
writeRegister(0xD627, 0x26);
writeRegister(0xD628, 0xaa);
writeRegister(0xD629, 0x30);
writeRegister(0xD62A, 0x3c);
writeRegister(0xD62B, 0x4A);
writeRegister(0xD62C, 0x63);
writeRegister(0xD62D, 0xea);
writeRegister(0xD62E, 0x79);
writeRegister(0xD62F, 0xa6);
writeRegister(0xD630, 0xd0);
writeRegister(0xD631, 0x20);
writeRegister(0xD632, 0x0f);
writeRegister(0xD633, 0x8e);
writeRegister(0xD634, 0xff);
//AVDD VOLTAGE SETTING
writeRegister(0xB000, 0x05);
writeRegister(0xB001, 0x05);
writeRegister(0xB002, 0x05);
//AVEE VOLTAGE SETTING
writeRegister(0xB100, 0x05);
writeRegister(0xB101, 0x05);
writeRegister(0xB102, 0x05);
//AVDD Boosting
writeRegister(0xB600, 0x34);
writeRegister(0xB601, 0x34);
writeRegister(0xB603, 0x34);
//AVEE Boosting
writeRegister(0xB700, 0x24);
writeRegister(0xB701, 0x24);
writeRegister(0xB702, 0x24);
//VCL Boosting
writeRegister(0xB800, 0x24);
writeRegister(0xB801, 0x24);
writeRegister(0xB802, 0x24);
//VGLX VOLTAGE SETTING
writeRegister(0xBA00, 0x14);
writeRegister(0xBA01, 0x14);
writeRegister(0xBA02, 0x14);
//VCL Boosting
writeRegister(0xB900, 0x24);
writeRegister(0xB901, 0x24);
writeRegister(0xB902, 0x24);
//Gamma Voltage
writeRegister(0xBc00, 0x00);
writeRegister(0xBc01, 0xa0);//vgmp=5.0
writeRegister(0xBc02, 0x00);
writeRegister(0xBd00, 0x00);
writeRegister(0xBd01, 0xa0);//vgmn=5.0
writeRegister(0xBd02, 0x00);
//VCOM Setting
writeRegister(0xBe01, 0x3d);//3
//ENABLE PAGE 0
writeRegister(0xF000, 0x55);
writeRegister(0xF001, 0xAA);
writeRegister(0xF002, 0x52);
writeRegister(0xF003, 0x08);
writeRegister(0xF004, 0x00);
//Vivid Color Function Control
writeRegister(0xB400, 0x10);
//Z-INVERSION
writeRegister(0xBC00, 0x05);
writeRegister(0xBC01, 0x05);
writeRegister(0xBC02, 0x05);
//*************** add on 20111021**********************//
writeRegister(0xB700, 0x22);//GATE EQ CONTROL
writeRegister(0xB701, 0x22);//GATE EQ CONTROL
writeRegister(0xC80B, 0x2A);//DISPLAY TIMING CONTROL
writeRegister(0xC80C, 0x2A);//DISPLAY TIMING CONTROL
writeRegister(0xC80F, 0x2A);//DISPLAY TIMING CONTROL
writeRegister(0xC810, 0x2A);//DISPLAY TIMING CONTROL
//*************** add on 20111021**********************//
//PWM_ENH_OE =1
writeRegister(0xd000, 0x01);
//DM_SEL =1
writeRegister(0xb300, 0x10);
//VBPDA=07h
writeRegister(0xBd02, 0x07);
//VBPDb=07h
writeRegister(0xBe02, 0x07);
//VBPDc=07h
writeRegister(0xBf02, 0x07);
//ENABLE PAGE 2
writeRegister(0xF000, 0x55);
writeRegister(0xF001, 0xAA);
writeRegister(0xF002, 0x52);
writeRegister(0xF003, 0x08);
writeRegister(0xF004, 0x02);
//SDREG0 =0
writeRegister(0xc301, 0xa9);
//DS=14
writeRegister(0xfe01, 0x94);
//OSC =60h
writeRegister(0xf600, 0x60);
//TE ON
writeRegister(0x3500, 0x00);
//SLEEP OUT
writecommand(0x1100);
delay(100);
//DISPLY ON
writecommand(0x2900);
delay(100);
writeRegister(0x3A00, 0x55);
writeRegister(0x3600, 0xA3);

View File

@ -0,0 +1,29 @@
// This is the command sequence that rotates the RM68120 driver coordinate frame
rotation = m % 4; // Limit the range of values to 0-3
writecommand(TFT_MADCTL);
switch (rotation) {
case 0:
writedata(TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 1:
writedata(TFT_MAD_MV | TFT_MAD_MX | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
case 2:
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 3:
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
}

View File

@ -17,6 +17,7 @@
#define INITR_GREENTAB128 0x5 // Use if you only get part of 128x128 screen in rotation 0 & 1 #define INITR_GREENTAB128 0x5 // Use if you only get part of 128x128 screen in rotation 0 & 1
#define INITR_GREENTAB160x80 0x6 // Use if you only get part of 128x128 screen in rotation 0 & 1 #define INITR_GREENTAB160x80 0x6 // Use if you only get part of 128x128 screen in rotation 0 & 1
#define INITR_REDTAB160x80 0x7 // Added for https://www.aliexpress.com/item/ShengYang-1pcs-IPS-0-96-inch-7P-SPI-HD-65K-Full-Color-OLED-Module-ST7735-Drive/32918394604.html #define INITR_REDTAB160x80 0x7 // Added for https://www.aliexpress.com/item/ShengYang-1pcs-IPS-0-96-inch-7P-SPI-HD-65K-Full-Color-OLED-Module-ST7735-Drive/32918394604.html
#define INITR_ROBOTLCD 0x8
#define INITB 0xB #define INITB 0xB
@ -44,6 +45,10 @@
#define TAB_COLOUR INITR_GREENTAB160x80 #define TAB_COLOUR INITR_GREENTAB160x80
#define CGRAM_OFFSET #define CGRAM_OFFSET
#elif defined (ST7735_ROBOTLCD)
#define TAB_COLOUR INITR_ROBOTLCD
#define CGRAM_OFFSET
#elif defined (ST7735_REDTAB160x80) #elif defined (ST7735_REDTAB160x80)
#define TAB_COLOUR INITR_REDTAB160x80 #define TAB_COLOUR INITR_REDTAB160x80
#define CGRAM_OFFSET #define CGRAM_OFFSET
@ -107,7 +112,7 @@
#define TFT_MAD_RGB 0x00 #define TFT_MAD_RGB 0x00
#ifndef TFT_RGB_ORDER #ifndef TFT_RGB_ORDER
#if defined(INITR_BLACKTAB) || defined(INITR_GREENTAB2) || defined(INITB) #if defined(ST7735_BLACKTAB) || defined(ST7735_GREENTAB2) || defined(ST7735_INITB)
#define TFT_MAD_COLOR_ORDER TFT_MAD_RGB #define TFT_MAD_COLOR_ORDER TFT_MAD_RGB
#else #else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR #define TFT_MAD_COLOR_ORDER TFT_MAD_BGR

View File

@ -123,6 +123,17 @@
0x00, 0x00, // XSTART = 0 0x00, 0x00, // XSTART = 0
0x00, 0x9F }, // XEND = 159 0x00, 0x9F }, // XEND = 159
// Frame control init for RobotLCD, taken from https://github.com/arduino-libraries/TFT, Adafruit_ST7735.cpp l. 263, commit 61b8a7e
Rcmd3RobotLCD[] = {
3,
ST7735_FRMCTR1, 2 , // 1: Frame rate ctrl - normal mode, 2 args
0x0B, 0x14,
ST7735_FRMCTR2, 2 , // 2: Frame rate ctrl - idle mode, 2 args
0x0B, 0x14,
ST7735_FRMCTR3, 4 , // 3: Frame rate ctrl - partial mode, 4 args
0x0B, 0x14,
0x0B, 0x14 },
Rcmd3[] = { // Init for 7735R, part 3 (red or green tab) Rcmd3[] = { // Init for 7735R, part 3 (red or green tab)
4, // 4 commands in list: 4, // 4 commands in list:
ST7735_GMCTRP1, 16 , // 1: 16 args, no delay: ST7735_GMCTRP1, 16 , // 1: 16 args, no delay:
@ -181,6 +192,11 @@
colstart = 26; colstart = 26;
rowstart = 1; rowstart = 1;
} }
else if (tabcolor == INITR_ROBOTLCD)
{
commandList(Rcmd2green);
commandList(Rcmd3RobotLCD);
}
else if (tabcolor == INITR_REDTAB160x80) else if (tabcolor == INITR_REDTAB160x80)
{ {
commandList(Rcmd2green); commandList(Rcmd2green);

View File

@ -20,6 +20,32 @@
#endif #endif
#endif #endif
// Adafruit 1.69 round corner TFT support
#if (TFT_HEIGHT == 280) && (TFT_WIDTH == 240)
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#endif
#endif
// 1.47" 172x320 Round Rectangle Color IPS TFT Display
#if (TFT_HEIGHT == 320) && (TFT_WIDTH == 172)
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#endif
#endif
#if (TFT_HEIGHT == 320) && (TFT_WIDTH == 170)
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#endif
#endif
#if (TFT_HEIGHT == 300) && (TFT_WIDTH == 240)
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#endif
#endif
// Delay between some initialisation commands // Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked #define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked

View File

@ -10,6 +10,21 @@
colstart = 52; colstart = 52;
rowstart = 40; rowstart = 40;
} }
else if(_init_height == 280)
{
colstart = 0;
rowstart = 20;
}
else if(_init_width == 172)
{
colstart = 34;
rowstart = 0;
}
else if(_init_width == 170)
{
colstart = 35;
rowstart = 0;
}
else else
{ {
colstart = 0; colstart = 0;
@ -29,6 +44,21 @@
colstart = 40; colstart = 40;
rowstart = 53; rowstart = 53;
} }
else if(_init_height == 280)
{
colstart = 20;
rowstart = 0;
}
else if(_init_width == 172)
{
colstart = 0;
rowstart = 34;
}
else if(_init_width == 170)
{
colstart = 0;
rowstart = 35;
}
else else
{ {
colstart = 0; colstart = 0;
@ -41,13 +71,28 @@
_height = _init_width; _height = _init_width;
break; break;
case 2: // Inverter portrait case 2: // Inverter portrait
#ifdef CGRAM_OFFSET #ifdef CGRAM_OFFSET
if (_init_width == 135) if (_init_width == 135)
{ {
colstart = 53; colstart = 53;
rowstart = 40; rowstart = 40;
} }
else if(_init_height == 280)
{
colstart = 0;
rowstart = 20;
}
else if(_init_width == 172)
{
colstart = 34;
rowstart = 0;
}
else if(_init_width == 170)
{
colstart = 35;
rowstart = 0;
}
else else
{ {
colstart = 0; colstart = 0;
@ -66,6 +111,21 @@
colstart = 40; colstart = 40;
rowstart = 52; rowstart = 52;
} }
else if(_init_height == 280)
{
colstart = 20;
rowstart = 0;
}
else if(_init_width == 172)
{
colstart = 0;
rowstart = 34;
}
else if(_init_width == 170)
{
colstart = 0;
rowstart = 35;
}
else else
{ {
colstart = 80; colstart = 80;

View File

@ -20,6 +20,13 @@
#endif #endif
#endif #endif
// Adafruit 1.69 round corner TFT support
#if (TFT_HEIGHT == 280) && (TFT_WIDTH == 240)
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#endif
#endif
// 1.47" 172x320 Round Rectangle Color IPS TFT Display // 1.47" 172x320 Round Rectangle Color IPS TFT Display
#if (TFT_HEIGHT == 320) && (TFT_WIDTH == 172) #if (TFT_HEIGHT == 320) && (TFT_WIDTH == 172)
#ifndef CGRAM_OFFSET #ifndef CGRAM_OFFSET
@ -27,6 +34,18 @@
#endif #endif
#endif #endif
#if (TFT_HEIGHT == 320) && (TFT_WIDTH == 170)
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#endif
#endif
#if (TFT_HEIGHT == 300) && (TFT_WIDTH == 240)
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#endif
#endif
// Delay between some initialisation commands // Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked #define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked

View File

@ -5,6 +5,7 @@
// //
// See ST7735_Setup.h file for an alternative format // See ST7735_Setup.h file for an alternative format
#ifndef INIT_SEQUENCE_3
{ {
writecommand(ST7789_SLPOUT); // Sleep out writecommand(ST7789_SLPOUT); // Sleep out
delay(120); delay(120);
@ -103,7 +104,7 @@
writedata(0x00); writedata(0x00);
writedata(0x00); writedata(0x00);
writedata(0x00); writedata(0x00);
writedata(0xE5); // 239 writedata(0xEF); // 239
writecommand(ST7789_RASET); // Row address set writecommand(ST7789_RASET); // Row address set
writedata(0x00); writedata(0x00);
@ -126,3 +127,111 @@
pinMode(TFT_BL, OUTPUT); pinMode(TFT_BL, OUTPUT);
#endif #endif
} }
#else
// TTGO ESP32 S3 T-Display
{
writecommand(ST7789_SLPOUT); // Sleep out
delay(120);
writecommand(ST7789_NORON); // Normal display mode on
//------------------------------display and color format setting--------------------------------//
writecommand(ST7789_MADCTL);
writedata(TFT_MAD_COLOR_ORDER);
// writecommand(ST7789_RAMCTRL);
// writedata(0x00);
// writedata(0xE0); // 5 to 6 bit conversion: r0 = r5, b0 = b5
writecommand(ST7789_COLMOD);
writedata(0x55);
delay(10);
//--------------------------------ST7789V Frame rate setting----------------------------------//
writecommand(ST7789_PORCTRL);
writedata(0x0b);
writedata(0x0b);
writedata(0x00);
writedata(0x33);
writedata(0x33);
writecommand(ST7789_GCTRL); // Voltages: VGH / VGL
writedata(0x75);
//---------------------------------ST7789V Power setting--------------------------------------//
writecommand(ST7789_VCOMS);
writedata(0x28); // JLX240 display datasheet
writecommand(ST7789_LCMCTRL);
writedata(0x2C);
writecommand(ST7789_VDVVRHEN);
writedata(0x01);
writecommand(ST7789_VRHS); // voltage VRHS
writedata(0x1F);
writecommand(ST7789_FRCTR2);
writedata(0x13);
writecommand(ST7789_PWCTRL1);
writedata(0xa7);
writecommand(ST7789_PWCTRL1);
writedata(0xa4);
writedata(0xa1);
writecommand(0xD6);
writedata(0xa1);
//--------------------------------ST7789V gamma setting---------------------------------------//
writecommand(ST7789_PVGAMCTRL);
writedata(0xf0);
writedata(0x05);
writedata(0x0a);
writedata(0x06);
writedata(0x06);
writedata(0x03);
writedata(0x2b);
writedata(0x32);
writedata(0x43);
writedata(0x36);
writedata(0x11);
writedata(0x10);
writedata(0x2b);
writedata(0x32);
writecommand(ST7789_NVGAMCTRL);
writedata(0xf0);
writedata(0x08);
writedata(0x0c);
writedata(0x0b);
writedata(0x09);
writedata(0x24);
writedata(0x2b);
writedata(0x22);
writedata(0x43);
writedata(0x38);
writedata(0x15);
writedata(0x16);
writedata(0x2f);
writedata(0x37);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
end_tft_write();
delay(120);
begin_tft_write();
writecommand(ST7789_DISPON); //Display on
delay(120);
#ifdef TFT_BL
// Turn on the back-light LED
digitalWrite(TFT_BL, HIGH);
pinMode(TFT_BL, OUTPUT);
#endif
}
#endif

View File

@ -20,6 +20,11 @@
colstart = 34; colstart = 34;
rowstart = 0; rowstart = 0;
} }
else if(_init_width == 170)
{
colstart = 35;
rowstart = 0;
}
else else
{ {
colstart = 0; colstart = 0;
@ -49,6 +54,11 @@
colstart = 0; colstart = 0;
rowstart = 34; rowstart = 34;
} }
else if(_init_width == 170)
{
colstart = 0;
rowstart = 35;
}
else else
{ {
colstart = 0; colstart = 0;
@ -78,6 +88,11 @@
colstart = 34; colstart = 34;
rowstart = 0; rowstart = 0;
} }
else if(_init_width == 170)
{
colstart = 35;
rowstart = 0;
}
else else
{ {
colstart = 0; colstart = 0;
@ -106,6 +121,11 @@
colstart = 0; colstart = 0;
rowstart = 34; rowstart = 34;
} }
else if(_init_width == 170)
{
colstart = 0;
rowstart = 35;
}
else else
{ {
colstart = 80; colstart = 80;

308
TFT_config.h Normal file
View File

@ -0,0 +1,308 @@
///////////////////////////////////////////////////////////
/* Support file for ESP32 IDF use */
/* See library docs folder */
/* */
/* DO NOT EDIT THIS FILE */
/* */
///////////////////////////////////////////////////////////
/**
* @file TFT_config.h
* @author Ricard Bitriá Ribes (https://github.com/dracir9)
* Created Date: 22-01-2022
* -----
* Last Modified: 14-04-2022
* Modified By: Ricard Bitriá Ribes
* -----
* @copyright (c) 2022 Ricard Bitriá Ribes
*/
#ifndef TFT_CONFIG_H
#define TFT_CONFIG_H
#include "sdkconfig.h"
/***************************************************************************************
** TFT_eSPI Configuration defines
***************************************************************************************/
// Override defaults
#define USER_SETUP_LOADED
/***************************************************************************************
** Section 1: Load TFT driver
***************************************************************************************/
#if defined (CONFIG_TFT_ILI9341_DRIVER)
#define ILI9341_DRIVER
#elif defined (CONFIG_TFT_ILI9341_2_DRIVER)
#define ILI9341_2_DRIVER
#elif defined (CONFIG_TFT_ST7735_DRIVER)
#define ST7735_DRIVER
#elif defined (CONFIG_TFT_ILI9163_DRIVER)
#define ILI9163_DRIVER
#elif defined (CONFIG_TFT_S6D02A1_DRIVER)
#define S6D02A1_DRIVER
#elif defined (CONFIG_TFT_HX8357D_DRIVER)
#define HX8357D_DRIVER
#elif defined (CONFIG_TFT_ILI9481_DRIVER)
#define ILI9481_DRIVER
#elif defined (CONFIG_TFT_ILI9486_DRIVER)
#define ILI9486_DRIVER
#elif defined (CONFIG_TFT_ILI9488_DRIVER)
#define ILI9488_DRIVER
#elif defined (CONFIG_TFT_ST7789_DRIVER)
#define ST7789_DRIVER
#elif defined (CONFIG_TFT_ST7789_2_DRIVER)
#define ST7789_2_DRIVER
#elif defined (CONFIG_TFT_R61581_DRIVER)
#define R61581_DRIVER
#elif defined (CONFIG_TFT_RM68140_DRIVER)
#define RM68140_DRIVER
#elif defined (CONFIG_TFT_ST7796_DRIVER)
#define ST7796_DRIVER
#elif defined (CONFIG_TFT_SSD1351_DRIVER)
#define SSD1351_DRIVER
#elif defined (CONFIG_TFT_SSD1963_480_DRIVER)
#define SSD1963_480_DRIVER
#elif defined (CONFIG_TFT_SSD1963_800_DRIVER)
#define SSD1963_800_DRIVER
#elif defined (CONFIG_TFT_SSD1963_800ALT_DRIVER)
#define SSD1963_800ALT_DRIVER
#elif defined (CONFIG_TFT_ILI9225_DRIVER)
#define ILI9225_DRIVER
#elif defined (CONFIG_TFT_GC9A01_DRIVER)
#define GC9A01_DRIVER
#endif
#ifdef CONFIG_TFT_RGB_ORDER
#define TFT_RGB_ORDER TFT_RGB
#endif
#ifdef CONFIG_TFT_BGR_ORDER
#define TFT_RGB_ORDER TFT_BGR
#endif
#ifdef CONFIG_TFT_M5STACK
#define M5STACK
#endif
#ifdef CONFIG_TFT_WIDTH
#define TFT_WIDTH CONFIG_TFT_WIDTH
#endif
#ifdef CONFIG_TFT_HEIGHT
#define TFT_HEIGHT CONFIG_TFT_HEIGHT
#endif
#if defined (CONFIG_TFT_ST7735_INITB)
#define ST7735_INITB
#elif defined (CONFIG_TFT_ST7735_GREENTAB)
#define ST7735_GREENTAB
#elif defined (CONFIG_TFT_ST7735_GREENTAB2)
#define ST7735_GREENTAB2
#elif defined (CONFIG_TFT_ST7735_GREENTAB3)
#define ST7735_GREENTAB3
#elif defined (CONFIG_TFT_ST7735_GREENTAB128)
#define ST7735_GREENTAB128
#elif defined (CONFIG_TFT_ST7735_GREENTAB160x80)
#define ST7735_GREENTAB160x80
#elif defined (CONFIG_TFT_ST7735_REDTAB)
#define ST7735_REDTAB
#elif defined (CONFIG_TFT_ST7735_BLACKTAB)
#define ST7735_BLACKTAB
#elif defined (CONFIG_TFT_ST7735_REDTAB160x80)
#define ST7735_REDTAB160x80
#endif
#if defined (CONFIG_TFT_INVERSION_ON)
#define TFT_INVERSION_ON
#elif defined (CONFIG_TFT_INVERSION_OFF)
#define TFT_INVERSION_OFF
#endif
/***************************************************************************************
** Section 2: General Pin configuration
***************************************************************************************/
// General pins
#if CONFIG_TFT_CS == -1
#error "Invalid Chip Select pin. Check TFT_eSPI configuration"
#else
#define TFT_CS CONFIG_TFT_CS
#endif
#if CONFIG_TFT_DC == -1
#error "Invalid Data/Command pin. Check TFT_eSPI configuration"
#else
#define TFT_DC CONFIG_TFT_DC
#endif
#if CONFIG_TFT_RST == -1
#error "Invalid Reset pin. Check TFT_eSPI configuration"
#else
#define TFT_RST CONFIG_TFT_RST
#endif
// Backlight config
#ifdef CONFIG_ENABLE_BL
#if CONFIG_TFT_BL == -1
#error "Invalid backlight control pin. Check TFT_eSPI configuration"
#else
#define TFT_BL CONFIG_TFT_BL
#endif
#define TFT_BACKLIGHT_ON CONFIG_TFT_BACKLIGHT_ON
#endif
/***************************************************************************************
** Section 3: Data bus Pin configuration
***************************************************************************************/
// 8 BIT PARALLEL BUS
#ifdef CONFIG_TFT_PARALLEL_8_BIT
#if CONFIG_TFT_D0 == -1
#error "Invalid Data 0 pin. Check TFT_eSPI configuration"
#else
#define TFT_D0 CONFIG_TFT_D0
#endif
#if CONFIG_TFT_D1 == -1
#error "Invalid Data 1 pin. Check TFT_eSPI configuration"
#else
#define TFT_D1 CONFIG_TFT_D1
#endif
#if CONFIG_TFT_D2 == -1
#error "Invalid Data 2 pin. Check TFT_eSPI configuration"
#else
#define TFT_D2 CONFIG_TFT_D2
#endif
#if CONFIG_TFT_D3 == -1
#error "Invalid Data 3 pin. Check TFT_eSPI configuration"
#else
#define TFT_D3 CONFIG_TFT_D3
#endif
#if CONFIG_TFT_D4 == -1
#error "Invalid Data 4 pin. Check TFT_eSPI configuration"
#else
#define TFT_D4 CONFIG_TFT_D4
#endif
#if CONFIG_TFT_D5 == -1
#error "Invalid Data 5 pin. Check TFT_eSPI configuration"
#else
#define TFT_D5 CONFIG_TFT_D5
#endif
#if CONFIG_TFT_D6 == -1
#error "Invalid Data 6 pin. Check TFT_eSPI configuration"
#else
#define TFT_D6 CONFIG_TFT_D6
#endif
#if CONFIG_TFT_D7 == -1
#error "Invalid Data 7 pin. Check TFT_eSPI configuration"
#else
#define TFT_D7 CONFIG_TFT_D7
#endif
#if CONFIG_TFT_WR == -1
#error "Invalid Write strobe pin. Check TFT_eSPI configuration"
#else
#define TFT_WR CONFIG_TFT_WR
#endif
#if CONFIG_TFT_RD == -1
#error "Invalid Read strobe pin. Check TFT_eSPI configuration"
#else
#define TFT_RD CONFIG_TFT_RD
#endif
// SPI BUS
#else
#if CONFIG_TFT_HSPI_PORT
#define USE_HSPI_PORT
#endif
#if CONFIG_TFT_MISO != -1
#define TFT_MISO CONFIG_TFT_MISO
#endif
#if CONFIG_TFT_MOSI == -1
#error "Invalid MOSI pin. Check TFT_eSPI configuration"
#else
#define TFT_MOSI CONFIG_TFT_MOSI
#endif
#if CONFIG_TFT_SCLK == -1
#error "Invalid Clock pin. Check TFT_eSPI configuration"
#else
#define TFT_SCLK CONFIG_TFT_SCLK
#endif
#define SPI_FREQUENCY CONFIG_TFT_SPI_FREQUENCY
#if CONFIG_TFT_SPI_READ_FREQ != -1
#define SPI_READ_FREQUENCY CONFIG_TFT_SPI_READ_FREQ
#endif
#ifdef CONFIG_TFT_SDA_READ
#define TFT_SDA_READ
#endif
#endif
/***************************************************************************************
** Section 4: Setup Fonts
***************************************************************************************/
#ifdef CONFIG_TFT_LOAD_GLCD
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#endif
#ifdef CONFIG_TFT_LOAD_FONT2
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#endif
#ifdef CONFIG_TFT_LOAD_FONT4
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#endif
#ifdef CONFIG_TFT_LOAD_FONT6
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#endif
#ifdef CONFIG_TFT_LOAD_FONT7
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
#endif
#ifdef CONFIG_TFT_LOAD_FONT8
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#endif
#ifdef CONFIG_TFT_LOAD_GFXFF
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#endif
#if CONFIG_TFT_SMOOTH_FONT
#define SMOOTH_FONT
#endif
/***************************************************************************************
** Section 5: Touchscreen configuration
***************************************************************************************/
#ifdef CONFIG_ENABLE_TOUCH
#if CONFIG_TOUCH_CS == -1
#error "Invalid Touch Chip Select pin. Check TFT_eSPI configuration"
#else
#define TOUCH_CS CONFIG_TOUCH_CS
#endif
#define SPI_TOUCH_FREQUENCY CONFIG_SPI_TOUCH_FREQUENCY
#endif
#endif // TFT_CONFIG_H

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@
#ifndef _TFT_eSPIH_ #ifndef _TFT_eSPIH_
#define _TFT_eSPIH_ #define _TFT_eSPIH_
#define TFT_ESPI_VERSION "2.4.43" #define TFT_ESPI_VERSION "2.5.21"
// Bit level feature flags // Bit level feature flags
// Bit 0 set: viewport capability // Bit 0 set: viewport capability
@ -36,6 +36,35 @@
***************************************************************************************/ ***************************************************************************************/
// Include header file that defines the fonts loaded, the TFT drivers // Include header file that defines the fonts loaded, the TFT drivers
// available and the pins to be used, etc, etc // available and the pins to be used, etc, etc
#ifdef CONFIG_TFT_eSPI_ESPIDF
#include "TFT_config.h"
#endif
// New ESP8266 board package uses ARDUINO_ARCH_ESP8266
// old package defined ESP8266
#if defined (ESP8266)
#ifndef ARDUINO_ARCH_ESP8266
#define ARDUINO_ARCH_ESP8266
#endif
#endif
// The following lines allow the user setup to be included in the sketch folder, see
// "Sketch_with_tft_setup" generic example.
#if !defined __has_include
#if !defined(DISABLE_ALL_LIBRARY_WARNINGS)
#warning Compiler does not support __has_include, so sketches cannot define the setup
#endif
#else
#if __has_include(<tft_setup.h>)
// Include the sketch setup file
#include <tft_setup.h>
#ifndef USER_SETUP_LOADED
// Prevent loading further setups
#define USER_SETUP_LOADED
#endif
#endif
#endif
#include <User_Setup_Select.h> #include <User_Setup_Select.h>
// Handle FLASH based storage e.g. PROGMEM // Handle FLASH based storage e.g. PROGMEM
@ -54,16 +83,22 @@
}) })
#elif defined(__AVR__) #elif defined(__AVR__)
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#elif defined(ESP8266) || defined(ESP32) #elif defined(ARDUINO_ARCH_ESP8266) || defined(ESP32)
#include <pgmspace.h> #include <pgmspace.h>
#else #else
#define PROGMEM #ifndef PROGMEM
#define PROGMEM
#endif
#endif #endif
// Include the processor specific drivers // Include the processor specific drivers
#if defined (ESP32) #if defined(CONFIG_IDF_TARGET_ESP32S3)
#include "Processors/TFT_eSPI_ESP32_S3.h"
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
#include "Processors/TFT_eSPI_ESP32_C3.h"
#elif defined (ESP32)
#include "Processors/TFT_eSPI_ESP32.h" #include "Processors/TFT_eSPI_ESP32.h"
#elif defined (ESP8266) #elif defined (ARDUINO_ARCH_ESP8266)
#include "Processors/TFT_eSPI_ESP8266.h" #include "Processors/TFT_eSPI_ESP8266.h"
#elif defined (STM32) #elif defined (STM32)
#include "Processors/TFT_eSPI_STM32.h" #include "Processors/TFT_eSPI_STM32.h"
@ -91,10 +126,12 @@
#endif #endif
// Some ST7789 boards do not work with Mode 0 // Some ST7789 boards do not work with Mode 0
#if defined(ST7789_DRIVER) || defined(ST7789_2_DRIVER) #ifndef TFT_SPI_MODE
#define TFT_SPI_MODE SPI_MODE3 #if defined(ST7789_DRIVER) || defined(ST7789_2_DRIVER)
#else #define TFT_SPI_MODE SPI_MODE3
#define TFT_SPI_MODE SPI_MODE0 #else
#define TFT_SPI_MODE SPI_MODE0
#endif
#endif #endif
// If the XPT2046 SPI frequency is not defined, set a default // If the XPT2046 SPI frequency is not defined, set a default
@ -106,6 +143,17 @@
#define SPI_BUSY_CHECK #define SPI_BUSY_CHECK
#endif #endif
// If half duplex SDA mode is defined then MISO pin should be -1
#ifdef TFT_SDA_READ
#ifdef TFT_MISO
#if TFT_MISO != -1
#undef TFT_MISO
#define TFT_MISO -1
#warning TFT_MISO set to -1
#endif
#endif
#endif
/*************************************************************************************** /***************************************************************************************
** Section 4: Setup fonts ** Section 4: Setup fonts
***************************************************************************************/ ***************************************************************************************/
@ -270,7 +318,7 @@ const PROGMEM fontinfo fontdata [] = {
#define TFT_WHITE 0xFFFF /* 255, 255, 255 */ #define TFT_WHITE 0xFFFF /* 255, 255, 255 */
#define TFT_ORANGE 0xFDA0 /* 255, 180, 0 */ #define TFT_ORANGE 0xFDA0 /* 255, 180, 0 */
#define TFT_GREENYELLOW 0xB7E0 /* 180, 255, 0 */ #define TFT_GREENYELLOW 0xB7E0 /* 180, 255, 0 */
#define TFT_PINK 0xFE19 /* 255, 192, 203 */ //Lighter pink, was 0xFC9F #define TFT_PINK 0xFE19 /* 255, 192, 203 */ //Lighter pink, was 0xFC9F
#define TFT_BROWN 0x9A60 /* 150, 75, 0 */ #define TFT_BROWN 0x9A60 /* 150, 75, 0 */
#define TFT_GOLD 0xFEA0 /* 255, 215, 0 */ #define TFT_GOLD 0xFEA0 /* 255, 215, 0 */
#define TFT_SILVER 0xC618 /* 192, 192, 192 */ #define TFT_SILVER 0xC618 /* 192, 192, 192 */
@ -313,23 +361,15 @@ static const uint16_t default_4bit_palette[] PROGMEM = {
typedef struct typedef struct
{ {
String version = TFT_ESPI_VERSION; String version = TFT_ESPI_VERSION;
String setup_info; // Setup reference name available to use in a user setup
uint32_t setup_id; // ID available to use in a user setup
int32_t esp; // Processor code int32_t esp; // Processor code
uint8_t trans; // SPI transaction support uint8_t trans; // SPI transaction support
uint8_t serial; // Serial (SPI) or parallel uint8_t serial; // Serial (SPI) or parallel
uint8_t port; // SPI port
uint8_t overlap; // ESP8266 overlap mode uint8_t overlap; // ESP8266 overlap mode
/* uint8_t interface; // Interface type
#if defined (ESP32) // TODO: make generic for other processors
#if defined (USE_HSPI_PORT)
uint8_t port = HSPI;
#else
#ifdef CONFIG_IDF_TARGET_ESP32
uint8_t port = VSPI;
#else
uint8_t port = FSPI;
#endif
#endif
#endif
*/
uint16_t tft_driver; // Hexadecimal code uint16_t tft_driver; // Hexadecimal code
uint16_t tft_width; // Rotation 0 width and height uint16_t tft_width; // Rotation 0 width and height
uint16_t tft_height; uint16_t tft_height;
@ -375,9 +415,6 @@ int16_t tch_spi_freq;// Touch controller read/write SPI frequency
/*************************************************************************************** /***************************************************************************************
** Section 8: Class member and support functions ** Section 8: Class member and support functions
***************************************************************************************/ ***************************************************************************************/
// Swap any type
template <typename T> static inline void
swap_coord(T& a, T& b) { T t = a; a = b; b = t; }
// Callback prototype for smooth font pixel colour read // Callback prototype for smooth font pixel colour read
typedef uint16_t (*getColorCallback)(uint16_t x, uint16_t y); typedef uint16_t (*getColorCallback)(uint16_t x, uint16_t y);
@ -407,7 +444,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
height(void), height(void),
width(void); width(void);
// Read the colour of a pixel at x,y and return value in 565 format // Read the colour of a pixel at x,y and return value in 565 format
virtual uint16_t readPixel(int32_t x, int32_t y); virtual uint16_t readPixel(int32_t x, int32_t y);
virtual void setWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye); // Note: start + end coordinates virtual void setWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye); // Note: start + end coordinates
@ -422,6 +459,12 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
void setRotation(uint8_t r); // Set the display image orientation to 0, 1, 2 or 3 void setRotation(uint8_t r); // Set the display image orientation to 0, 1, 2 or 3
uint8_t getRotation(void); // Read the current rotation uint8_t getRotation(void); // Read the current rotation
// Change the origin position from the default top left
// Note: setRotation, setViewport and resetViewport will revert origin to top left corner of screen/sprite
void setOrigin(int32_t x, int32_t y);
int32_t getOriginX(void);
int32_t getOriginY(void);
void invertDisplay(bool i); // Tell TFT to invert all displayed colours void invertDisplay(bool i); // Tell TFT to invert all displayed colours
@ -464,6 +507,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
void end_SDA_Read(void); // Restore MOSI to output void end_SDA_Read(void); // Restore MOSI to output
#endif #endif
// Graphics drawing // Graphics drawing
void fillScreen(uint32_t color), void fillScreen(uint32_t color),
drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color), drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color),
@ -473,28 +517,6 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
void fillRectVGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2); void fillRectVGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2);
void fillRectHGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2); void fillRectHGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2);
// Draw a pixel blended with the pixel colour on the TFT or sprite, return blended colour
// If bg_color is not included the background pixel colour will be read from TFT or sprite
uint16_t drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha, uint32_t bg_color = 0x00FFFFFF);
// Draw a small anti-aliased filled circle at ax,ay with radius r (uses drawWideLine)
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawSpot(float ax, float ay, float r, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased filled circle at x, y with radius r
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color, uint32_t bg_color = 0x00FFFFFF);
void fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased wide line from ax,ay to bx,by width wd with radiused ends (radius is wd/2)
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawWideLine(float ax, float ay, float bx, float by, float wd, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased wide line from ax,ay to bx,by with different width at each end aw, bw and with radiused ends
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawWedgeLine(float ax, float ay, float bx, float by, float aw, float bw, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
void drawCircle(int32_t x, int32_t y, int32_t r, uint32_t color), void drawCircle(int32_t x, int32_t y, int32_t r, uint32_t color),
drawCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, uint32_t color), drawCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, uint32_t color),
fillCircle(int32_t x, int32_t y, int32_t r, uint32_t color), fillCircle(int32_t x, int32_t y, int32_t r, uint32_t color),
@ -507,6 +529,53 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
drawTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color), drawTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color),
fillTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color); fillTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color);
// Smooth (anti-aliased) graphics drawing
// Draw a pixel blended with the background pixel colour (bg_color) specified, return blended colour
// If the bg_color is not specified, the background pixel colour will be read from TFT or sprite
uint16_t drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased (smooth) arc between start and end angles. Arc ends are anti-aliased.
// By default the arc is drawn with square ends unless the "roundEnds" parameter is included and set true
// Angle = 0 is at 6 o'clock position, 90 at 9 o'clock etc. The angles must be in range 0-360 or they will be clipped to these limits
// The start angle may be larger than the end angle. Arcs are always drawn clockwise from the start angle.
void drawSmoothArc(int32_t x, int32_t y, int32_t r, int32_t ir, uint32_t startAngle, uint32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool roundEnds = false);
// As per "drawSmoothArc" except the ends of the arc are NOT anti-aliased, this facilitates dynamic arc length changes with
// arc segments and ensures clean segment joints.
// The sides of the arc are anti-aliased by default. If smoothArc is false sides will NOT be anti-aliased
void drawArc(int32_t x, int32_t y, int32_t r, int32_t ir, uint32_t startAngle, uint32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool smoothArc = true);
// Draw an anti-aliased filled circle at x, y with radius r
// Note: The thickness of line is 3 pixels to reduce the visible "braiding" effect of anti-aliasing narrow lines
// this means the inner anti-alias zone is always at r-1 and the outer zone at r+1
void drawSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t fg_color, uint32_t bg_color);
// Draw an anti-aliased filled circle at x, y with radius r
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color, uint32_t bg_color = 0x00FFFFFF);
// Draw a rounded rectangle that has a line thickness of r-ir+1 and bounding box defined by x,y and w,h
// The outer corner radius is r, inner corner radius is ir
// The inside and outside of the border are anti-aliased
void drawSmoothRoundRect(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t w, int32_t h, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF, uint8_t quadrants = 0xF);
// Draw a filled rounded rectangle , corner radius r and bounding box defined by x,y and w,h
void fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color, uint32_t bg_color = 0x00FFFFFF);
// Draw a small anti-aliased filled circle at ax,ay with radius r (uses drawWideLine)
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawSpot(float ax, float ay, float r, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased wide line from ax,ay to bx,by width wd with radiused ends (radius is wd/2)
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawWideLine(float ax, float ay, float bx, float by, float wd, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
// Draw an anti-aliased wide line from ax,ay to bx,by with different width at each end aw, bw and with radiused ends
// If bg_color is not included the background pixel colour will be read from TFT or sprite
void drawWedgeLine(float ax, float ay, float bx, float by, float aw, float bw, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF);
// Image rendering // Image rendering
// Swap the byte order for pushImage() and pushPixels() - corrects endianness // Swap the byte order for pushImage() and pushPixels() - corrects endianness
void setSwapBytes(bool swap); void setSwapBytes(bool swap);
@ -545,15 +614,20 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, uint8_t transparent, bool bpp8 = true, uint16_t *cmap = nullptr); void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, uint8_t transparent, bool bpp8 = true, uint16_t *cmap = nullptr);
// FLASH version // FLASH version
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint8_t *data, bool bpp8, uint16_t *cmap = nullptr); void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint8_t *data, bool bpp8, uint16_t *cmap = nullptr);
// Render a 16 bit colour image with a 1bpp mask
void pushMaskedImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *img, uint8_t *mask);
// This next function has been used successfully to dump the TFT screen to a PC for documentation purposes // This next function has been used successfully to dump the TFT screen to a PC for documentation purposes
// It reads a screen area and returns the 3 RGB 8 bit colour values of each pixel in the buffer // It reads a screen area and returns the 3 RGB 8 bit colour values of each pixel in the buffer
// Set w and h to 1 to read 1 pixel's colour. The data buffer must be at least w * h * 3 bytes // Set w and h to 1 to read 1 pixel's colour. The data buffer must be at least w * h * 3 bytes
void readRectRGB(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data); void readRectRGB(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data);
// Text rendering - value returned is the pixel width of the rendered text // Text rendering - value returned is the pixel width of the rendered text
int16_t drawNumber(long intNumber, int32_t x, int32_t y, uint8_t font), // Draw integer using specified font number int16_t drawNumber(long intNumber, int32_t x, int32_t y, uint8_t font), // Draw integer using specified font number
drawNumber(long intNumber, int32_t x, int32_t y), // Draw integer using current font drawNumber(long intNumber, int32_t x, int32_t y), // Draw integer using current font
// Decimal is the number of decimal places to render // Decimal is the number of decimal places to render
// Use with setTextDatum() to position values on TFT, and setTextPadding() to blank old displayed values // Use with setTextDatum() to position values on TFT, and setTextPadding() to blank old displayed values
drawFloat(float floatNumber, uint8_t decimal, int32_t x, int32_t y, uint8_t font), // Draw float using specified font number drawFloat(float floatNumber, uint8_t decimal, int32_t x, int32_t y, uint8_t font), // Draw float using specified font number
@ -571,20 +645,21 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
drawCentreString(const String& string, int32_t x, int32_t y, uint8_t font),// Deprecated, use setTextDatum() and drawString() drawCentreString(const String& string, int32_t x, int32_t y, uint8_t font),// Deprecated, use setTextDatum() and drawString()
drawRightString(const String& string, int32_t x, int32_t y, uint8_t font); // Deprecated, use setTextDatum() and drawString() drawRightString(const String& string, int32_t x, int32_t y, uint8_t font); // Deprecated, use setTextDatum() and drawString()
// Text rendering and font handling support funtions // Text rendering and font handling support funtions
void setCursor(int16_t x, int16_t y), // Set cursor for tft.print() void setCursor(int16_t x, int16_t y), // Set cursor for tft.print()
setCursor(int16_t x, int16_t y, uint8_t font); // Set cursor and font number for tft.print() setCursor(int16_t x, int16_t y, uint8_t font); // Set cursor and font number for tft.print()
int16_t getCursorX(void), // Read current cursor x position (moves with tft.print()) int16_t getCursorX(void), // Read current cursor x position (moves with tft.print())
getCursorY(void); // Read current cursor y position getCursorY(void); // Read current cursor y position
void setTextColor(uint16_t color), // Set character (glyph) color only (background not over-written) void setTextColor(uint16_t color), // Set character (glyph) color only (background not over-written)
setTextColor(uint16_t fgcolor, uint16_t bgcolor),// Set character (glyph) foreground and backgorund colour setTextColor(uint16_t fgcolor, uint16_t bgcolor, bool bgfill = false), // Set character (glyph) foreground and background colour, optional background fill for smooth fonts
setTextSize(uint8_t size); // Set character size multiplier (this increases pixel size) setTextSize(uint8_t size); // Set character size multiplier (this increases pixel size)
void setTextWrap(bool wrapX, bool wrapY = false); // Turn on/off wrapping of text in TFT width and/or height void setTextWrap(bool wrapX, bool wrapY = false); // Turn on/off wrapping of text in TFT width and/or height
void setTextDatum(uint8_t datum); // Set text datum position (default is top left), see Section 6 above void setTextDatum(uint8_t datum); // Set text datum position (default is top left), see Section 6 above
uint8_t getTextDatum(void); uint8_t getTextDatum(void);
void setTextPadding(uint16_t x_width); // Set text padding (background blanking/over-write) width in pixels void setTextPadding(uint16_t x_width); // Set text padding (background blanking/over-write) width in pixels
@ -611,13 +686,14 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Support function to UTF8 decode and draw characters piped through print stream // Support function to UTF8 decode and draw characters piped through print stream
size_t write(uint8_t); size_t write(uint8_t);
// size_t write(const uint8_t *buf, size_t len); // size_t write(const uint8_t *buf, size_t len);
// Used by Smooth font class to fetch a pixel colour for the anti-aliasing // Used by Smooth font class to fetch a pixel colour for the anti-aliasing
void setCallback(getColorCallback getCol); void setCallback(getColorCallback getCol);
uint16_t fontsLoaded(void); // Each bit in returned value represents a font type that is loaded - used for debug/error handling only uint16_t fontsLoaded(void); // Each bit in returned value represents a font type that is loaded - used for debug/error handling only
// Low level read/write // Low level read/write
void spiwrite(uint8_t); // legacy support only void spiwrite(uint8_t); // legacy support only
#ifndef RM68120_DRIVER #ifndef RM68120_DRIVER
@ -651,14 +727,15 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Alpha blend 2 colours, see generic "alphaBlend_Test" example // Alpha blend 2 colours, see generic "alphaBlend_Test" example
// alpha = 0 = 100% background colour // alpha = 0 = 100% background colour
// alpha = 255 = 100% foreground colour // alpha = 255 = 100% foreground colour
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc); inline uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc);
// 16 bit colour alphaBlend with alpha dither (dither reduces colour banding) // 16 bit colour alphaBlend with alpha dither (dither reduces colour banding)
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc, uint8_t dither); uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc, uint8_t dither);
// 24 bit colour alphaBlend with optional alpha dither // 24 bit colour alphaBlend with optional alpha dither
uint32_t alphaBlend24(uint8_t alpha, uint32_t fgc, uint32_t bgc, uint8_t dither = 0); uint32_t alphaBlend24(uint8_t alpha, uint32_t fgc, uint32_t bgc, uint8_t dither = 0);
// Direct Memory Access (DMA) support functions
// DMA support functions - these are currently just for SPI writes when using the ESP32 or STM32 processors // These can be used for SPI writes when using the ESP32 (original) or STM32 processors.
// DMA also works on a RP2040 processor with PIO based SPI and parallel (8 and 16 bit) interfaces
// Bear in mind DMA will only be of benefit in particular circumstances and can be tricky // Bear in mind DMA will only be of benefit in particular circumstances and can be tricky
// to manage by noobs. The functions have however been designed to be noob friendly and // to manage by noobs. The functions have however been designed to be noob friendly and
// avoid a few DMA behaviour "gotchas". // avoid a few DMA behaviour "gotchas".
@ -687,11 +764,16 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Parameter "true" enables DMA engine control of TFT chip select (ESP32 only) // Parameter "true" enables DMA engine control of TFT chip select (ESP32 only)
// For ESP32 only, TFT reads will not work if parameter is true // For ESP32 only, TFT reads will not work if parameter is true
void deInitDMA(void); // De-initialise the DMA engine and detach from SPI bus - typically not used void deInitDMA(void); // De-initialise the DMA engine and detach from SPI bus - typically not used
// Push an image to the TFT using DMA, buffer is optional and grabs (double buffers) a copy of the image // Push an image to the TFT using DMA, buffer is optional and grabs (double buffers) a copy of the image
// Use the buffer if the image data will get over-written or destroyed while DMA is in progress // Use the buffer if the image data will get over-written or destroyed while DMA is in progress
// If swapping colour bytes is defined, and the double buffer option is NOT used, then the bytes //
// in the original data image will be swapped by the function before DMA is initiated. // Note 1: If swapping colour bytes is defined, and the double buffer option is NOT used, then the bytes
// in the original image buffer content will be byte swapped by the function before DMA is initiated.
//
// Note 2: If part of the image will be off screen or outside of a set viewport, then the the original
// image buffer content will be altered to a correctly clipped image before DMA is initiated.
//
// The function will wait for the last DMA to complete if it is called while a previous DMA is still // The function will wait for the last DMA to complete if it is called while a previous DMA is still
// in progress, this simplifies the sketch and helps avoid "gotchas". // in progress, this simplifies the sketch and helps avoid "gotchas".
void pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t* data, uint16_t* buffer = nullptr); void pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t* data, uint16_t* buffer = nullptr);
@ -729,6 +811,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Used for diagnostic sketch to see library setup adopted by compiler, see Section 7 above // Used for diagnostic sketch to see library setup adopted by compiler, see Section 7 above
void getSetup(setup_t& tft_settings); // Sketch provides the instance to populate void getSetup(setup_t& tft_settings); // Sketch provides the instance to populate
bool verifySetupID(uint32_t id);
// Global variables // Global variables
static SPIClass& getSPIinstance(void); // Get SPI class handle static SPIClass& getSPIinstance(void); // Get SPI class handle
@ -783,6 +866,9 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Single GPIO input/output direction control // Single GPIO input/output direction control
void gpioMode(uint8_t gpio, uint8_t mode); void gpioMode(uint8_t gpio, uint8_t mode);
// Smooth graphics helper
uint8_t sqrt_fraction(uint32_t num);
// Helper function: calculate distance of a point from a finite length line between two points // Helper function: calculate distance of a point from a finite length line between two points
float wedgeLineDistance(float pax, float pay, float bax, float bay, float dr); float wedgeLineDistance(float pax, float pay, float bax, float bay, float dr);
@ -831,6 +917,8 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
bool _vpOoB; bool _vpOoB;
int32_t cursor_x, cursor_y, padX; // Text cursor x,y and padding setting int32_t cursor_x, cursor_y, padX; // Text cursor x,y and padding setting
int32_t bg_cursor_x; // Background fill cursor
int32_t last_cursor_x; // Previous text cursor position when fill used
uint32_t fontsloaded; // Bit field of fonts loaded uint32_t fontsloaded; // Bit field of fonts loaded
@ -842,7 +930,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
bool _swapBytes; // Swap the byte order for TFT pushImage() bool _swapBytes; // Swap the byte order for TFT pushImage()
bool _booted; // init() or begin() has already run once bool _booted; // init() or begin() has already run once
// User sketch manages these via set/getAttribute() // User sketch manages these via set/getAttribute()
bool _cp437; // If set, use correct CP437 charset (default is ON) bool _cp437; // If set, use correct CP437 charset (default is ON)
bool _utf8; // If set, use UTF-8 decoder in print stream 'write()' function (default ON) bool _utf8; // If set, use UTF-8 decoder in print stream 'write()' function (default ON)
@ -850,7 +938,9 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
uint32_t _lastColor; // Buffered value of last colour used uint32_t _lastColor; // Buffered value of last colour used
#if defined (SSD1963_DRIVER) bool _fillbg; // Fill background flag (just for for smooth fonts at the moment)
#if defined (SSD1963_DRIVER)
uint16_t Cswap; // Swap buffer for SSD1963 uint16_t Cswap; // Swap buffer for SSD1963
uint8_t r6, g6, b6; // RGB buffer for SSD1963 uint8_t r6, g6, b6; // RGB buffer for SSD1963
#endif #endif
@ -864,7 +954,17 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
***************************************************************************************/ ***************************************************************************************/
// Load the Touch extension // Load the Touch extension
#ifdef TOUCH_CS #ifdef TOUCH_CS
#include "Extensions/Touch.h" // Loaded if TOUCH_CS is defined by user #if defined (TFT_PARALLEL_8_BIT) || defined (RP2040_PIO_INTERFACE)
#if !defined(DISABLE_ALL_LIBRARY_WARNINGS)
#error >>>>------>> Touch functions not supported in 8/16 bit parallel mode or with RP2040 PIO.
#endif
#else
#include "Extensions/Touch.h" // Loaded if TOUCH_CS is defined by user
#endif
#else
#if !defined(DISABLE_ALL_LIBRARY_WARNINGS)
#warning >>>>------>> TOUCH_CS pin not defined, TFT_eSPI touch functions will not be available!
#endif
#endif #endif
// Load the Anti-aliased font extension // Load the Anti-aliased font extension
@ -874,6 +974,10 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
}; // End of class TFT_eSPI }; // End of class TFT_eSPI
// Swap any type
template <typename T> static inline void
transpose(T& a, T& b) { T t = a; a = b; b = t; }
/*************************************************************************************** /***************************************************************************************
** Section 10: Additional extension classes ** Section 10: Additional extension classes
***************************************************************************************/ ***************************************************************************************/

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -8,6 +8,11 @@
// run without the need to make any more changes for a particular hardware setup! // run without the need to make any more changes for a particular hardware setup!
// Note that some sketches are designed for a particular TFT pixel width/height // Note that some sketches are designed for a particular TFT pixel width/height
// User defined information reported by "Read_User_Setup" test & diagnostics example
#define USER_SETUP_INFO "User_Setup"
// Define to disable all #warnings in library (can be put in User_Setup_Select.h)
//#define DISABLE_ALL_LIBRARY_WARNINGS
// ################################################################################## // ##################################################################################
// //
@ -29,8 +34,9 @@
//#define STM_PORTA_DATA_BUS //#define STM_PORTA_DATA_BUS
//#define STM_PORTB_DATA_BUS //#define STM_PORTB_DATA_BUS
// Tell the library to use 8 bit parallel mode (otherwise SPI is assumed) // Tell the library to use parallel mode (otherwise SPI is assumed)
//#define TFT_PARALLEL_8_BIT //#define TFT_PARALLEL_8_BIT
//#defined TFT_PARALLEL_16_BIT // **** 16 bit parallel ONLY for RP2040 processor ****
// Display type - only define if RPi display // Display type - only define if RPi display
//#define RPI_DISPLAY_TYPE // 20MHz maximum SPI //#define RPI_DISPLAY_TYPE // 20MHz maximum SPI
@ -98,6 +104,7 @@
// #define ST7735_GREENTAB3 // #define ST7735_GREENTAB3
// #define ST7735_GREENTAB128 // For 128 x 128 display // #define ST7735_GREENTAB128 // For 128 x 128 display
// #define ST7735_GREENTAB160x80 // For 160 x 80 display (BGR, inverted, 26 offset) // #define ST7735_GREENTAB160x80 // For 160 x 80 display (BGR, inverted, 26 offset)
// #define ST7735_ROBOTLCD // For some RobotLCD arduino shields (128x160, BGR, https://docs.arduino.cc/retired/getting-started-guides/TFT)
// #define ST7735_REDTAB // #define ST7735_REDTAB
// #define ST7735_BLACKTAB // #define ST7735_BLACKTAB
// #define ST7735_REDTAB160x80 // For 160 x 80 display with 24 pixel offset // #define ST7735_REDTAB160x80 // For 160 x 80 display with 24 pixel offset
@ -317,6 +324,20 @@
// For RP2040 processor and SPI displays, uncomment the following line to use the PIO interface. // For RP2040 processor and SPI displays, uncomment the following line to use the PIO interface.
//#define RP2040_PIO_SPI // Leave commented out to use standard RP2040 SPI port interface //#define RP2040_PIO_SPI // Leave commented out to use standard RP2040 SPI port interface
// For RP2040 processor and 8 or 16 bit parallel displays:
// The parallel interface write cycle period is derived from a division of the CPU clock
// speed so scales with the processor clock. This means that the divider ratio may need
// to be increased when overclocking. I may also need to be adjusted dependant on the
// display controller type (ILI94341, HX8357C etc). If RP2040_PIO_CLK_DIV is not defined
// the library will set default values which may not suit your display.
// The display controller data sheet will specify the minimum write cycle period. The
// controllers often work reliably for shorter periods, however if the period is too short
// the display may not initialise or graphics will become corrupted.
// PIO write cycle frequency = (CPU clock/(4 * RP2040_PIO_CLK_DIV))
//#define RP2040_PIO_CLK_DIV 1 // 32ns write cycle at 125MHz CPU clock
//#define RP2040_PIO_CLK_DIV 2 // 64ns write cycle at 125MHz CPU clock
//#define RP2040_PIO_CLK_DIV 3 // 96ns write cycle at 125MHz CPU clock
// For the RP2040 processor define the SPI port channel used (default 0 if undefined) // For the RP2040 processor define the SPI port channel used (default 0 if undefined)
//#define TFT_SPI_PORT 1 // Set to 0 if SPI0 pins are used, or 1 if spi1 pins used //#define TFT_SPI_PORT 1 // Set to 0 if SPI0 pins are used, or 1 if spi1 pins used

View File

@ -1,45 +1,53 @@
// This header file contains a list of user setup files and defines which one the // This header file contains a list of user setup files and defines which one the
// compiler uses when the IDE performs a Verify/Compile or Upload. // compiler uses when the IDE performs a Verify/Compile or Upload.
// //
// Users can create configurations for different Espressif boards and TFT displays. // Users can create configurations for different boards and TFT displays.
// This makes selecting between hardware setups easy by "uncommenting" one line. // This makes selecting between hardware setups easy by "uncommenting" one line.
// The advantage of this hardware configuration method is that the examples provided // The advantage of this hardware configuration method is that the examples provided
// with the library should work with different setups immediately without any other // with the library should work with immediately without any other changes being
// changes being needed. It also improves the portability of users sketches to other // needed. It also improves the portability of users sketches to other hardware
// hardware configurations and compatible libraries. // configurations and compatible libraries.
// //
// Create a shortcut to this file on your desktop to permit quick access for editing. // Create a shortcut to this file on your desktop to permit quick access for editing.
// Re-compile and upload after making and saving any changes to this file. // Re-compile and upload after making and saving any changes to this file.
// Customised User_Setup files are stored in the "User_Setups" folder. // Customised User_Setup files are stored in the "User_Setups" folder.
// It is also possible for the user tft settings to be included with the sketch, see
// the "Sketch_with_tft_setup" generic example. This may be more convenient for
// multiple projects.
#ifndef USER_SETUP_LOADED // Lets PlatformIO users define settings in #ifndef USER_SETUP_LOADED // Lets PlatformIO users define settings in
// platformio.ini, see notes in "Tools" folder. // platformio.ini, see notes in "Tools" folder.
// Only ONE line below should be uncommented. Add extra lines and files as needed. ///////////////////////////////////////////////////////
// User configuration selection lines are below //
///////////////////////////////////////////////////////
// Only ONE line below should be uncommented to define your setup. Add extra lines and files as needed.
#include <User_Setup.h> // Default setup is root library folder #include <User_Setup.h> // Default setup is root library folder
//#include <User_Setups/Setup1_ILI9341.h> // Setup file configured for my ILI9341 //#include <User_Setups/Setup1_ILI9341.h> // Setup file for ESP8266 configured for my ILI9341
//#include <User_Setups/Setup2_ST7735.h> // Setup file configured for my ST7735 //#include <User_Setups/Setup2_ST7735.h> // Setup file for ESP8266 configured for my ST7735
//#include <User_Setups/Setup3_ILI9163.h> // Setup file configured for my ILI9163 //#include <User_Setups/Setup3_ILI9163.h> // Setup file for ESP8266 configured for my ILI9163
//#include <User_Setups/Setup4_S6D02A1.h> // Setup file configured for my S6D02A1 //#include <User_Setups/Setup4_S6D02A1.h> // Setup file for ESP8266 configured for my S6D02A1
//#include <User_Setups/Setup5_RPi_ILI9486.h> // Setup file configured for my stock RPi TFT //#include <User_Setups/Setup5_RPi_ILI9486.h> // Setup file for ESP8266 configured for my stock RPi TFT
//#include <User_Setups/Setup6_RPi_Wr_ILI9486.h> // Setup file configured for my modified RPi TFT //#include <User_Setups/Setup6_RPi_Wr_ILI9486.h> // Setup file for ESP8266 configured for my modified RPi TFT
//#include <User_Setups/Setup7_ST7735_128x128.h> // Setup file configured for my ST7735 128x128 display //#include <User_Setups/Setup7_ST7735_128x128.h> // Setup file for ESP8266 configured for my ST7735 128x128 display
//#include <User_Setups/Setup8_ILI9163_128x128.h> // Setup file configured for my ILI9163 128x128 display //#include <User_Setups/Setup8_ILI9163_128x128.h> // Setup file for ESP8266 configured for my ILI9163 128x128 display
//#include <User_Setups/Setup9_ST7735_Overlap.h> // Setup file configured for my ST7735 //#include <User_Setups/Setup9_ST7735_Overlap.h> // Setup file for ESP8266 configured for my ST7735
//#include <User_Setups/Setup10_RPi_touch_ILI9486.h> // Setup file configured for ESP8266 and RPi TFT with touch //#include <User_Setups/Setup10_RPi_touch_ILI9486.h> // Setup file for ESP8266 configured for ESP8266 and RPi TFT with touch
//#include <User_Setups/Setup11_RPi_touch_ILI9486.h> // Setup file configured for ESP32 and RPi TFT with touch //#include <User_Setups/Setup11_RPi_touch_ILI9486.h> // Setup file configured for ESP32 and RPi TFT with touch
//#include <User_Setups/Setup12_M5Stack.h> // Setup file for the ESP32 based M5Stack //#include <User_Setups/Setup12_M5Stack_Basic_Core.h>// Setup file for the ESP32 based M5Stack (Basic Core only)
//#include <User_Setups/Setup13_ILI9481_Parallel.h> // Setup file for the ESP32 with parallel bus TFT //#include <User_Setups/Setup13_ILI9481_Parallel.h> // Setup file for the ESP32 with parallel bus TFT
//#include <User_Setups/Setup14_ILI9341_Parallel.h> // Setup file for the ESP32 with parallel bus TFT //#include <User_Setups/Setup14_ILI9341_Parallel.h> // Setup file for the ESP32 with parallel bus TFT
//#include <User_Setups/Setup15_HX8357D.h> // Setup file configured for HX8357D (untested) //#include <User_Setups/Setup15_HX8357D.h> // Setup file for ESP8266 configured for HX8357D
//#include <User_Setups/Setup16_ILI9488_Parallel.h> // Setup file for the ESP32 with parallel bus TFT //#include <User_Setups/Setup16_ILI9488_Parallel.h> // Setup file for the ESP32 with parallel bus TFT
//#include <User_Setups/Setup17_ePaper.h> // Setup file for any Waveshare ePaper display //#include <User_Setups/Setup17_ePaper.h> // Setup file for ESP8266 and any Waveshare ePaper display
//#include <User_Setups/Setup18_ST7789.h> // Setup file configured for ST7789 //#include <User_Setups/Setup18_ST7789.h> // Setup file for ESP8266 configured for ST7789
//#include <User_Setups/Setup19_RM68140_Parallel.h> // Setup file configured for RM68140 with parallel bus //#include <User_Setups/Setup19_RM68140_Parallel.h> // Setup file configured for RM68140 with parallel bus
@ -49,7 +57,7 @@
//#include <User_Setups/Setup22_TTGO_T4.h> // Setup file for ESP32 and TTGO T4 version 1.2 //#include <User_Setups/Setup22_TTGO_T4.h> // Setup file for ESP32 and TTGO T4 version 1.2
//#include <User_Setups/Setup22_TTGO_T4_v1.3.h> // Setup file for ESP32 and TTGO T4 version 1.3 //#include <User_Setups/Setup22_TTGO_T4_v1.3.h> // Setup file for ESP32 and TTGO T4 version 1.3
//#include <User_Setups/Setup23_TTGO_TM.h> // Setup file for ESP32 and TTGO TM ST7789 SPI bus TFT //#include <User_Setups/Setup23_TTGO_TM.h> // Setup file for ESP32 and TTGO TM ST7789 SPI bus TFT
//#include <User_Setups/Setup24_ST7789.h> // Setup file configured for ST7789 240 x 240 //#include <User_Setups/Setup24_ST7789.h> // Setup file for DSTIKE/ESP32/ESP8266 configured for ST7789 240 x 240
//#include <User_Setups/Setup25_TTGO_T_Display.h> // Setup file for ESP32 and TTGO T-Display ST7789V SPI bus TFT //#include <User_Setups/Setup25_TTGO_T_Display.h> // Setup file for ESP32 and TTGO T-Display ST7789V SPI bus TFT
//#include <User_Setups/Setup26_TTGO_T_Wristband.h> // Setup file for ESP32 and TTGO T-Wristband ST7735 SPI bus TFT //#include <User_Setups/Setup26_TTGO_T_Wristband.h> // Setup file for ESP32 and TTGO T-Wristband ST7735 SPI bus TFT
@ -68,11 +76,13 @@
//#include <User_Setups/Setup36_RPi_touch_ST7796.h> // Setup file configured for ESP32 and RPi ST7796 TFT with touch //#include <User_Setups/Setup36_RPi_touch_ST7796.h> // Setup file configured for ESP32 and RPi ST7796 TFT with touch
//#include <User_Setups/Setup43_ST7735.h> // Setup file configured for my ST7735S 80x160 //#include <User_Setups/Setup42_ILI9341_ESP32.h> // Setup file for ESP32 and SPI ILI9341 240x320
//#include <User_Setups/Setup43_ST7735.h> // Setup file for ESP8266 & ESP32 configured for my ST7735S 80x160
//#include <User_Setups/Setup44_TTGO_CameraPlus.h> // Setup file for ESP32 and TTGO T-CameraPlus ST7789 SPI bus TFT 240x240 //#include <User_Setups/Setup44_TTGO_CameraPlus.h> // Setup file for ESP32 and TTGO T-CameraPlus ST7789 SPI bus TFT 240x240
//#include <User_Setups/Setup45_TTGO_T_Watch.h> // Setup file for ESP32 and TTGO T-Watch ST7789 SPI bus TFT 240x240 //#include <User_Setups/Setup45_TTGO_T_Watch.h> // Setup file for ESP32 and TTGO T-Watch ST7789 SPI bus TFT 240x240
//#include <User_Setups/Setup46_GC9A01_ESP32.h> // Setup file for ESP32 and GC9A01 SPI bus TFT 240x240
//#include <User_Setups/Setup47_ST7735.h> // Setup file configured for ST7735 128 x 128 animated eyes //#include <User_Setups/Setup47_ST7735.h> // Setup file for ESP32 configured for ST7735 128 x 128 animated eyes
//#include <User_Setups/Setup50_SSD1963_Parallel.h> // Setup file for ESP32 and SSD1963 TFT display //#include <User_Setups/Setup50_SSD1963_Parallel.h> // Setup file for ESP32 and SSD1963 TFT display
@ -83,17 +93,23 @@
//#include <User_Setups/Setup61_RP2040_ILI9341_PIO_SPI.h> // Setup file for RP2040 with PIO SPI ILI9341 //#include <User_Setups/Setup61_RP2040_ILI9341_PIO_SPI.h> // Setup file for RP2040 with PIO SPI ILI9341
//#include <User_Setups/Setup62_RP2040_Nano_Connect_ILI9341.h> // Setup file for RP2040 with SPI ILI9341 //#include <User_Setups/Setup62_RP2040_Nano_Connect_ILI9341.h> // Setup file for RP2040 with SPI ILI9341
//#include <User_Setups/Setup70_ESP32_S2_ILI9341.h> // Setup file for ESP32 S2 with SPI ILI9341 //#include <User_Setups/Setup70_ESP32_S2_ILI9341.h> // Setup file for ESP32 S2 with SPI ILI9341
//#include <User_Setups/Setup70b_ESP32_S3_ILI9341.h> // Setup file for ESP32 S3 with SPI ILI9341
//#include <User_Setups/Setup70c_ESP32_C3_ILI9341.h> // Setup file for ESP32 C3 with SPI ILI9341
//#include <User_Setups/Setup70d_ILI9488_S3_Parallel.h> // Setup file for ESP32 S3 with SPI ILI9488
//#include <User_Setups/Setup71_ESP32_S2_ST7789.h> // Setup file for ESP32 S2 with ST7789 //#include <User_Setups/Setup71_ESP32_S2_ST7789.h> // Setup file for ESP32 S2 with ST7789
//#include <User_Setups/Setup72_ESP32_ST7789_172x320.h> // Setup file for ESP32 with ST7789 1.47" 172x320 //#include <User_Setups/Setup72_ESP32_ST7789_172x320.h> // Setup file for ESP32 with ST7789 1.47" 172x320
//#include <User_Setups/Setup100_RP2040_ILI9488_parallel.h> //#include <User_Setups/Setup100_RP2040_ILI9488_parallel.h> // Setup file for Pico/RP2040 with 8 bit parallel ILI9488
//#include <User_Setups/Setup101_RP2040_ILI9481_parallel.h> //#include <User_Setups/Setup101_RP2040_ILI9481_parallel.h> // Setup file for Pico/RP2040 with 8 bit parallel ILI9481
//#include <User_Setups/Setup102_RP2040_ILI9341_parallel.h> //#include <User_Setups/Setup102_RP2040_ILI9341_parallel.h> // Setup file for Pico/RP2040 with 8 bit parallel ILI9341
//#include <User_Setups/Setup103_RP2040_ILI9486_parallel.h> //#include <User_Setups/Setup103_RP2040_ILI9486_parallel.h> // Setup file for Pico/RP2040 with 8 bit parallel ILI9486
//#include <User_Setups/Setup104_RP2040_ST7796_parallel.h> //#include <User_Setups/Setup104_RP2040_ST7796_parallel.h> // Setup file for Pico/RP2040 with 8 bit parallel ST7796
//#include <User_Setups/Setup105_RP2040_ILI9341_PIO_SPI.h> // Setup file for Raspberry Pi Pico with SPI PIO interface and ILI9341
//#include <User_Setups/Setup105_RP2040_ST7796_16bit_parallel.h> // Setup file for RP2040 16 bit parallel display
//#include <User_Setups/Setup106_RP2040_ILI9481_16bit_parallel.h> // Setup file for RP2040 16 bit parallel display
//#include <User_Setups/Setup107_RP2040_ILI9341_16bit_parallel.h> // Setup file for RP2040 16 bit parallel display
//#include <User_Setups/Setup135_ST7789.h> // Setup file for ESP8266 and ST7789 135 x 240 TFT //#include <User_Setups/Setup135_ST7789.h> // Setup file for ESP8266 and ST7789 135 x 240 TFT
@ -108,8 +124,27 @@
//#include <User_Setups/Setup203_ST7789.h> // Setup file for ESP32/ESP8266 based ST7789 240X280 1.69inch TFT //#include <User_Setups/Setup203_ST7789.h> // Setup file for ESP32/ESP8266 based ST7789 240X280 1.69inch TFT
//#include <User_Setups/SetupX_Template.h> //#include <User_Setups/Setup204_ESP32_TouchDown.h> // Setup file for the ESP32 TouchDown based on ILI9488 480 x 320 TFT
//#include <User_Setups/Setup205_ESP32_TouchDown_S3.h> // Setup file for the ESP32 TouchDown S3 based on ILI9488 480 x 320 TFT
//#include <User_Setups/Setup206_LilyGo_T_Display_S3.h>
//#include <User_Setups/Setup207_LilyGo_T_HMI.h>
//#include <User_Setups/Setup301_BW16_ST7735.h> // Setup file for Bw16-based boards with ST7735 160 x 80 TFT
//#include <User_Setups/SetupX_Template.h> // Template file for a setup
//#include <User_Setups/Dustin_ILI9488.h> // Setup file for Dustin Watts PCB with ILI9488
//#include <User_Setups/Dustin_ST7796.h> // Setup file for Dustin Watts PCB with ST7796
//#include <User_Setups/Dustin_ILI9488_Pico.h> // Setup file for Dustin Watts Pico PCB with ST7796
//#include <User_Setups/Dustin_ST7789_Pico.h> // Setup file for Dustin Watts PCB with ST7789 240 x 240 on 3.3V adapter board
//#include <User_Setups/Dustin_GC9A01_Pico.h> // Setup file for Dustin Watts PCB with GC9A01 240 x 240 on 3.3V adapter board
//#include <User_Setups/Dustin_GC9A01_ESP32.h> // Setup file for Dustin Watts PCB with GC9A01 240 x 240 on 3.3V adapter board
//#include <User_Setups/Dustin_STT7789_ESP32.h> // Setup file for Dustin Watts PCB with ST7789 240 x 240 on 3.3V adapter board
//#include <User_Setups/Dustin_ILI9341_ESP32.h> // Setup file for Dustin Watts PCB with ILI9341
//#include <User_Setups/ILI9225.h>
#endif // USER_SETUP_LOADED #endif // USER_SETUP_LOADED
@ -146,14 +181,14 @@
#endif #endif
// Invoke 18 bit colour for selected displays // Invoke 18 bit colour for selected displays
#if !defined (RPI_DISPLAY_TYPE) && !defined (TFT_PARALLEL_8_BIT) && !defined (ESP32_PARALLEL) #if !defined (RPI_DISPLAY_TYPE) && !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT) && !defined (ESP32_PARALLEL)
#if defined (ILI9481_DRIVER) || defined (ILI9486_DRIVER) || defined (ILI9488_DRIVER) #if defined (ILI9481_DRIVER) || defined (ILI9486_DRIVER) || defined (ILI9488_DRIVER)
#define SPI_18BIT_DRIVER #define SPI_18BIT_DRIVER
#endif #endif
#endif #endif
// Load the right driver definition - do not tinker here ! // Load the right driver definition - do not tinker here !
#if defined (ILI9341_DRIVER) || defined(ILI9341_2_DRIVER) #if defined (ILI9341_DRIVER) || defined(ILI9341_2_DRIVER) || defined (ILI9342_DRIVER)
#include <TFT_Drivers/ILI9341_Defines.h> #include <TFT_Drivers/ILI9341_Defines.h>
#define TFT_DRIVER 0x9341 #define TFT_DRIVER 0x9341
#elif defined (ST7735_DRIVER) #elif defined (ST7735_DRIVER)
@ -216,6 +251,16 @@
#elif defined (ILI9225_DRIVER) #elif defined (ILI9225_DRIVER)
#include "TFT_Drivers/ILI9225_Defines.h" #include "TFT_Drivers/ILI9225_Defines.h"
#define TFT_DRIVER 0x9225 #define TFT_DRIVER 0x9225
#elif defined (RM68120_DRIVER)
#include "TFT_Drivers/RM68120_Defines.h"
#define TFT_DRIVER 0x6812
#elif defined (HX8357B_DRIVER)
#include "TFT_Drivers/HX8357B_Defines.h"
#define TFT_DRIVER 0x835B
#elif defined (HX8357C_DRIVER)
#include "TFT_Drivers/HX8357C_Defines.h"
#define TFT_DRIVER 0x835C
// <<<<<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVER HERE // <<<<<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVER HERE
// XYZZY_init.h and XYZZY_rotation.h must also be added in TFT_eSPI.cpp // XYZZY_init.h and XYZZY_rotation.h must also be added in TFT_eSPI.cpp
#elif defined (XYZZY_DRIVER) #elif defined (XYZZY_DRIVER)

View File

@ -1,5 +1,6 @@
// This setup is for the RP2040 processor only when used with 8 bit parallel displays // This setup is for the RP2040 processor only when used with 8 bit parallel displays
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 100
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
// Interface // Interface

View File

@ -1,5 +1,6 @@
// This setup is for the RP2040 processor only when used with 8 bit parallel displays // This setup is for the RP2040 processor only when used with 8 bit parallel displays
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 101
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
// Interface // Interface

View File

@ -1,5 +1,6 @@
// This setup is for the RP2040 processor only when used with 8 bit parallel displays // This setup is for the RP2040 processor only when used with 8 bit parallel displays
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 102
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
// Interface // Interface

View File

@ -1,5 +1,6 @@
// This setup is for the RP2040 processor only when used with 8 bit parallel displays // This setup is for the RP2040 processor only when used with 8 bit parallel displays
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 103
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
// Interface // Interface

View File

@ -1,5 +1,6 @@
// This setup is for the RP2040 processor only when used with 8 bit parallel displays // This setup is for the RP2040 processor only when used with 8 bit parallel displays
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 104
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
// Interface // Interface

View File

@ -0,0 +1,60 @@
// This setup is for the RP2040 processor only when used with 8 bit parallel displays
// See SetupX_Template.h for all options available
#define USER_SETUP_ID 105
////////////////////////////////////////////////////////////////////////////////////////////
// Interface
////////////////////////////////////////////////////////////////////////////////////////////
#define TFT_PARALLEL_16_BIT
////////////////////////////////////////////////////////////////////////////////////////////
// Display driver type
////////////////////////////////////////////////////////////////////////////////////////////
#define ST7796_DRIVER
////////////////////////////////////////////////////////////////////////////////////////////
// RP2040 pins used
////////////////////////////////////////////////////////////////////////////////////////////
//#define TFT_CS -1 // Do not define, chip select control pin permanently connected to 0V
// These pins can be moved and are controlled directly by the library software
#define TFT_DC 3 // Data Command control pin
#define TFT_RST 2 // Reset pin
//#define TFT_RD -1 // Do not define, read pin must be permanently connected to 3V3
#define TFT_WR 4
// PIO requires these to be sequentially increasing GPIO with no gaps
#define TFT_D0 6
#define TFT_D1 7
#define TFT_D2 8
#define TFT_D3 9
#define TFT_D4 10
#define TFT_D5 11
#define TFT_D6 12
#define TFT_D7 13
#define TFT_D8 14
#define TFT_D9 15
#define TFT_D10 16
#define TFT_D11 17
#define TFT_D12 18
#define TFT_D13 19
#define TFT_D14 20
#define TFT_D15 21
////////////////////////////////////////////////////////////////////////////////////////////
// Fonts to be available
////////////////////////////////////////////////////////////////////////////////////////////
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT
////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,64 @@
// This setup is for the RP2040 processor when used with 8 bit parallel displays
// See SetupX_Template.h for all options available
#define USER_SETUP_ID 106
////////////////////////////////////////////////////////////////////////////////////////////
// Interface
////////////////////////////////////////////////////////////////////////////////////////////
//#define TFT_PARALLEL_8_BIT
#define TFT_PARALLEL_16_BIT
////////////////////////////////////////////////////////////////////////////////////////////
// Display driver type
////////////////////////////////////////////////////////////////////////////////////////////
#define ILI9481_DRIVER
//#define HX8357B_DRIVER
//#define HX8357C_DRIVER
////////////////////////////////////////////////////////////////////////////////////////////
// RP2040 pins used
////////////////////////////////////////////////////////////////////////////////////////////
// These pins can be moved and are controlled directly by the library software
#define TFT_RST 18 // Reset pin
#define TFT_CS 19 // Do not define if chip select control pin permanently connected to 0V
//#define TFT_RD -1 // Do not define, read pin must be permanently connected to 3V3
// Note: All the following pins are PIO hardware configured and driven
#define TFT_WR 16 // Write strobe pin
#define TFT_DC 17 // Data Command control pin
// PIO requires these to be sequentially increasing
#define TFT_D0 0
#define TFT_D1 1
#define TFT_D2 2
#define TFT_D3 3
#define TFT_D4 4
#define TFT_D5 5
#define TFT_D6 6
#define TFT_D7 7
#define TFT_D8 8
#define TFT_D9 9
#define TFT_D10 10
#define TFT_D11 11
#define TFT_D12 12
#define TFT_D13 13
#define TFT_D14 14
#define TFT_D15 15
//*/
////////////////////////////////////////////////////////////////////////////////////////////
// Fonts to be available
////////////////////////////////////////////////////////////////////////////////////////////
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT
////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,65 @@
// This setup is for the RP2040 processor only when used with 8 bit parallel displays
// See SetupX_Template.h for all options available
#define USER_SETUP_ID 107
////////////////////////////////////////////////////////////////////////////////////////////
// Interface
////////////////////////////////////////////////////////////////////////////////////////////
//#define TFT_PARALLEL_8_BIT
#define TFT_PARALLEL_16_BIT
////////////////////////////////////////////////////////////////////////////////////////////
// Display driver type
////////////////////////////////////////////////////////////////////////////////////////////
#define ILI9341_DRIVER
//#define ILI9481_DRIVER // Tested
//#define HX8357B_DRIVER // Tested
//#define HX8357C_DRIVER // Tested
//#define SSD1963_800_DRIVER
////////////////////////////////////////////////////////////////////////////////////////////
// RP2040 pins used
////////////////////////////////////////////////////////////////////////////////////////////
// These pins can be moved and are controlled directly by the library software
#define TFT_RST 18 // Reset pin
#define TFT_CS 19 // Do not define if chip select control pin permanently connected to 0V
//#define TFT_RD -1 // Do not define, read pin must be permanently connected to 3V3
// Note: All the following pins are PIO hardware configured and driven
#define TFT_WR 16 // Write strobe pin
#define TFT_DC 17 // Data Command control pin
// PIO requires these to be sequentially increasing
#define TFT_D0 0
#define TFT_D1 1
#define TFT_D2 2
#define TFT_D3 3
#define TFT_D4 4
#define TFT_D5 5
#define TFT_D6 6
#define TFT_D7 7
#define TFT_D8 8
#define TFT_D9 9
#define TFT_D10 10
#define TFT_D11 11
#define TFT_D12 12
#define TFT_D13 13
#define TFT_D14 14
#define TFT_D15 15
//*/
////////////////////////////////////////////////////////////////////////////////////////////
// Fonts to be available
////////////////////////////////////////////////////////////////////////////////////////////
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT
////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -1,5 +1,6 @@
// For ESP8266 // For ESP8266
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 10
#define RPI_DISPLAY_TYPE #define RPI_DISPLAY_TYPE
#define ILI9486_DRIVER #define ILI9486_DRIVER

View File

@ -1,5 +1,7 @@
// For ESP32 // For ESP32
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 11
#define RPI_DISPLAY_TYPE #define RPI_DISPLAY_TYPE
#define ILI9486_DRIVER #define ILI9486_DRIVER

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 12
//Setup file for the M5Stack Basic Core //Setup file for the M5Stack Basic Core

View File

@ -1,4 +1,5 @@
// ST7789 135 x 240 display with no chip select line // ST7789 135 x 240 display with no chip select line
#define USER_SETUP_ID 135
#define ST7789_DRIVER // Configure all registers #define ST7789_DRIVER // Configure all registers

View File

@ -1,4 +1,5 @@
// ST7789 135 x 240 display with no chip select line // ST7789 135 x 240 display with no chip select line
#define USER_SETUP_ID 136
#define ST7789_DRIVER // Configure all registers #define ST7789_DRIVER // Configure all registers

View File

@ -1,4 +1,5 @@
// LilyGo T-Display RP2040 (ST7789 135 x 240 display) // LilyGo T-Display RP2040 (ST7789 135 x 240 display)
#define USER_SETUP_ID 137
#define ST7789_DRIVER // Configure all registers #define ST7789_DRIVER // Configure all registers

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 13
#define ESP32_PARALLEL #define ESP32_PARALLEL

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 14
#define TFT_PARALLEL_8_BIT #define TFT_PARALLEL_8_BIT

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 15
#define HX8357D_DRIVER #define HX8357D_DRIVER

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 16
#define ESP32_PARALLEL #define ESP32_PARALLEL

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 17
#define EPD_DRIVER // ePaper driver #define EPD_DRIVER // ePaper driver

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 18
#define ST7789_DRIVER #define ST7789_DRIVER

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 19
#define ESP32_PARALLEL #define ESP32_PARALLEL

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 1
#define ILI9341_DRIVER #define ILI9341_DRIVER

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 200
#define GC9A01_DRIVER #define GC9A01_DRIVER

View File

@ -7,6 +7,7 @@
// If this file is edited correctly then all the library example sketches should // If this file is edited correctly then all the library example sketches should
// run without the need to make any more changes for a particular hardware setup! // run without the need to make any more changes for a particular hardware setup!
// Note that some sketches are designed for a particular TFT pixel width/height // Note that some sketches are designed for a particular TFT pixel width/height
#define USER_SETUP_ID 201
// User defined setup // User defined setup
#define ST7796_DRIVER #define ST7796_DRIVER

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 202
#define SSD1351_DRIVER #define SSD1351_DRIVER

View File

@ -1,4 +1,5 @@
// ST7789 240 x 280 display with no chip select line // ST7789 240 x 280 display with no chip select line
#define USER_SETUP_ID 203
#define ST7789_DRIVER // Configure all registers #define ST7789_DRIVER // Configure all registers

View File

@ -0,0 +1,32 @@
// User Setup for the ESP32 TouchDown V1.0 and V1.1
// ILI9488 using 4-wire SPI and using an FT6206 touch controller
#define USER_SETUP_ID 204
#define ILI9488_DRIVER
#define TFT_BL 32
#define TFT_BACKLIGHT_ON HIGH
#define TFT_MISO 19
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4
#define TOUCH_CS 21
#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF
#define SMOOTH_FONT
#define SPI_FREQUENCY 27000000
#define SPI_READ_FREQUENCY 20000000
#define SPI_TOUCH_FREQUENCY 2500000

View File

@ -0,0 +1,36 @@
// User Setup for the ESP32 TouchDown S3 V1.1
// ILI9488 using 8-bit Parallel and using an FT6206 touch controller
#define USER_SETUP_ID 205
#define ESP32_PARALLEL
#define ILI9488_DRIVER
#define TFT_DC 5
#define TFT_RST 46
#define TFT_WR 7
#define TFT_RD 6
#define TFT_D0 21
#define TFT_D1 14
#define TFT_D2 13
#define TFT_D3 12
#define TFT_D4 11
#define TFT_D5 10
#define TFT_D6 9
#define TFT_D7 8
#define TFT_BL 48
#define TFT_BACKLIGHT_ON HIGH
#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF
#define SMOOTH_FONT

View File

@ -0,0 +1,46 @@
// ST7789 using 8-bit Parallel
#define USER_SETUP_ID 206
#define ST7789_DRIVER
#define INIT_SEQUENCE_3 // Using this initialisation sequence improves the display image
#define CGRAM_OFFSET
#define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
//#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
#define TFT_INVERSION_ON
// #define TFT_INVERSION_OFF
#define TFT_PARALLEL_8_BIT
#define TFT_WIDTH 170
#define TFT_HEIGHT 320
#define TFT_DC 7
#define TFT_RST 5
#define TFT_WR 8
#define TFT_RD 9
#define TFT_D0 39
#define TFT_D1 40
#define TFT_D2 41
#define TFT_D3 42
#define TFT_D4 45
#define TFT_D5 46
#define TFT_D6 47
#define TFT_D7 48
#define TFT_BL 38
#define TFT_BACKLIGHT_ON HIGH
#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF
#define SMOOTH_FONT

View File

@ -0,0 +1,48 @@
// ST7789 240 x 240 display with no chip select line
#define USER_SETUP_ID 207
#define ST7789_DRIVER // Configure all registers
// #define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
#define CGRAM_OFFSET
// #define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
// #define TFT_INVERSION_ON
#define TFT_INVERSION_OFF
#define TFT_PARALLEL_8_BIT
// The ESP32 and TFT the pins used for testing are:
#define TFT_CS 6 // Chip select control pin (library pulls permanently low
#define TFT_DC 7 // Data Command control pin
#define TFT_RST -1 // Reset pin, toggles on startup
#define TFT_WR 8 // Write strobe control pin
#define TFT_RD -1 // Read strobe control pin
#define TFT_D0 48 // Must use pins in the range 0-31 or alternatively 32-48
#define TFT_D1 47 // so a single register write sets/clears all bits.
#define TFT_D2 39 // Pins can be randomly assigned, this does not affect
#define TFT_D3 40 // TFT screen update performance.
#define TFT_D4 41
#define TFT_D5 42
#define TFT_D6 45
#define TFT_D7 46
#define TFT_BL 38 // LED back-light
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 20
#define ILI9488_DRIVER #define ILI9488_DRIVER

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 21
#define ILI9488_DRIVER #define ILI9488_DRIVER

View File

@ -1,4 +1,5 @@
// Setup for the TTGO T4 v1.1 ("Bitcoin Tracker") ESP32 board with 2.2" ILI9341 display // Setup for the TTGO T4 v1.1 ("Bitcoin Tracker") ESP32 board with 2.2" ILI9341 display
#define USER_SETUP_ID 22
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
@ -15,6 +16,8 @@
#define TFT_DC 26 // pin 32 for TTGO T4 v1.3 #define TFT_DC 26 // pin 32 for TTGO T4 v1.3
#define TFT_RST 5 #define TFT_RST 5
#define TOUCH_CS -1
#define LOAD_GLCD #define LOAD_GLCD
#define LOAD_FONT2 #define LOAD_FONT2
#define LOAD_FONT4 #define LOAD_FONT4

View File

@ -1,4 +1,5 @@
// Setup for the TTGO T4 v1.3 ESP32 board with 2.2" ILI9341 display // Setup for the TTGO T4 v1.3 ESP32 board with 2.2" ILI9341 display
#define USER_SETUP_ID 99922
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
@ -12,7 +13,7 @@
#define TFT_SCLK 18 #define TFT_SCLK 18
#define TFT_CS 27 #define TFT_CS 27
#define TFT_DC 32 // pin 26 for TTGO T4 v1.1 #define TFT_DC 32 // pin 26 for TTGO T4 v1.3
#define TFT_RST 5 #define TFT_RST 5
#define LOAD_GLCD #define LOAD_GLCD

View File

@ -1,4 +1,5 @@
// Setup for the TTGO TM (Music) ESP32 board with 2.4" ST7789V display // Setup for the TTGO TM (Music) ESP32 board with 2.4" ST7789V display
#define USER_SETUP_ID 23
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
@ -14,6 +15,8 @@
#define TFT_DC 16 #define TFT_DC 16
#define TFT_RST 17 #define TFT_RST 17
#define TOUCH_CS -1
#define TFT_WIDTH 240 #define TFT_WIDTH 240
#define TFT_HEIGHT 320 #define TFT_HEIGHT 320

View File

@ -1,4 +1,5 @@
// ST7789 240 x 240 display with no chip select line // ST7789 240 x 240 display with no chip select line
#define USER_SETUP_ID 24
#define ST7789_DRIVER // Configure all registers #define ST7789_DRIVER // Configure all registers

View File

@ -1,4 +1,5 @@
// Setup for the TTGO T Display // Setup for the TTGO T Display
#define USER_SETUP_ID 25
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available

View File

@ -1,3 +1,5 @@
#define USER_SETUP_ID 26
#define ST7735_DRIVER #define ST7735_DRIVER
#define TFT_WIDTH 80 #define TFT_WIDTH 80

View File

@ -7,6 +7,8 @@
// If this file is edited correctly then all the library example sketches should // If this file is edited correctly then all the library example sketches should
// run without the need to make any more changes for a particular hardware setup! // run without the need to make any more changes for a particular hardware setup!
#define USER_SETUP_ID 27
// ################################################################################## // ##################################################################################
// //
// Section 0. Call up the right driver file and any options for it // Section 0. Call up the right driver file and any options for it

View File

@ -6,6 +6,7 @@
// //
// If this file is edited correctly then all the library example sketches should // If this file is edited correctly then all the library example sketches should
// run without the need to make any more changes for a particular hardware setup! // run without the need to make any more changes for a particular hardware setup!
#define USER_SETUP_ID 28
// ################################################################################## // ##################################################################################
// //

View File

@ -2,6 +2,7 @@
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
// Setup for STM32 Nucleo and ILI9341 display // // Setup for STM32 Nucleo and ILI9341 display //
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
#define USER_SETUP_ID 29
// Last update by Bodmer: 28/11/19 // Last update by Bodmer: 28/11/19

View File

@ -1,4 +1,5 @@
// See SetupX_Template.h for all options available // See SetupX_Template.h for all options available
#define USER_SETUP_ID 2
#define ST7735_DRIVER #define ST7735_DRIVER

Some files were not shown because too many files have changed in this diff Show More