Compare commits

...

680 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
Bodmer c92c82bed5
Fix #1601
A simple typo was the problem!
2022-03-20 20:14:42 +00:00
Bodmer 8480f39a9c Various updates - raise to version 2.4.43
Sprite class uses TFT_eSPI setBitmapColor - fn deleted
Small performance improvement to RP2040 SPI PIO
Typo corrections
Correct (unused) tft_Write_32 for STM32
Update HX8357D rotation code
Enable software reset for ILI9486
Add preliminary RM68120 support
2022-03-17 14:12:10 +00:00
Bodmer 3b63aa9e63 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2022-03-16 16:52:27 +00:00
Bodmer 896bbf62de Update Flash_PNG.ino 2022-03-16 16:52:24 +00:00
Bodmer 25e74fe90c
Update README.md 2022-03-16 16:23:07 +00:00
Bodmer 352d1e007c
Update ILI9486_Init.h
SW reset needed for RPi display
2022-03-15 01:21:11 +00:00
Bodmer 34d450dd90
Update library.json 2022-03-14 23:36:08 +00:00
Bodmer bc75274625
Update library.json 2022-03-14 23:34:41 +00:00
Bodmer 395b44dd34
Update library.json 2022-03-14 23:32:37 +00:00
Bodmer 1be1b4b05b
Always load button class 2022-03-13 00:12:27 +00:00
Bodmer 31b2de56c1 Update HX8357D driver to support RGB and BGR displays
In setup add the following lines:
// If green and blue swapped on display then change the RGB colour order
// Only uncomment ONE of the following options
#define TFT_RGB_ORDER TFT_RGB    //   Red-Green-Blue
//#define TFT_RGB_ORDER TFT_BGR    //   Blue-Green-RED
2022-03-12 20:04:41 +00:00
Bodmer 39b0d6ab9a
Update README.md 2022-03-10 12:01:50 +00:00
Bodmer e7767d1a8b
Merge pull request #1693 from limingjie/ST7789_172x320_driver
Add ST7789 172x320 display support
2022-03-09 17:25:28 +00:00
Bodmer ee59bd0ae9
Update README.md 2022-03-09 14:53:57 +00:00
Mingjie Li 40306ae615 Add ST7789 172x320 display 2022-03-09 22:20:58 +08:00
Bodmer cb37ae0aba
Merge pull request #1682 from Frogomeli/fix-SPICOM
Allow generic driver to use a custom SPI port
2022-03-05 00:23:27 +00:00
Bodmer 6f4cf86834
Make compatible with existing port define 2022-03-05 00:22:32 +00:00
Frogomeli 4fd8aa8bd4
Allow generic driver to use a custom SPI port
I have a SeeedStudio Wio Terminal.
I'm using this lib in VS Code with PlatformIO but the lib
don't use the `SPICOM` variable when it's a generic device.

Steps to reproduce (using a Wio Terminal):
* Create a project using PlatformIO
* Add the TFT_eSPI lib to the project
* Add in the build flags these lines
```
build_flags = 
	-DUSER_SETUP_LOADED=1
	-DILI9341_DRIVER=1
	-DHASSPI=1
	-DSPICOM=LCD_SPI
	-DTFT_CS=LCD_SS_PIN
	-DTFT_DC=LCD_DC
	-DTFT_RST=LCD_RESET
	-DTFT_BL=LCD_BACKLIGHT
	-DTFT_BACKLIGHT_ON=HIGH
	-DTFT_BACKLINGT_V=2000
```
* Compile and transfer to the device
=> only backlight works
2022-03-04 17:31:42 +01:00
Bodmer e83383c69a
Fix #1680 2022-03-04 00:59:38 +00:00
Bodmer 90804c33fb Rename setup file 2022-03-01 23:31:31 +00:00
Bodmer a23a2df977
Merge pull request #1675 from moion/add-1.69inch-TFT
add ST7789 240X280 1.69inch TFT Setup file
2022-03-01 23:29:58 +00:00
Bodmer 5d9b09bc2d
Comment out by default
Renumbered to Setup203
2022-03-01 23:27:43 +00:00
moion b911c86572 add ST7789 240X280 1.69inch TFT Setup file 2022-02-28 11:47:19 +08:00
Bodmer ec504067c1 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2022-02-26 16:48:30 +00:00
Bodmer b6708b65ae Fix #1667 2022-02-26 16:48:27 +00:00
Bodmer d50b7f6c13
Revert HX8357D change #1356
Change #1356 caused issues.
2022-02-24 12:10:19 +00:00
Bodmer 284893c374 Update RP2040 PIO and smooth graphics fns 2022-02-22 21:12:33 +00:00
Bodmer d1e6637b88
Update README.md 2022-02-22 00:53:36 +00:00
Bodmer 6823025758
Update README.md 2022-02-22 00:49:08 +00:00
Bodmer 4fae4fa6cb
Fix #1656 2022-02-21 20:10:05 +00:00
Bodmer 92d51413aa Fix #1653 2022-02-21 14:32:02 +00:00
Bodmer 97a9455e63 Add PNG image render examples 2022-02-19 15:10:49 +00:00
Bodmer 032e54dd10 Allow drawFloat with decimal places = 0
See #1639
2022-02-16 20:16:30 +00:00
Bodmer 86101770ac Not all processors support buffered write() 2022-02-16 19:52:52 +00:00
Bodmer 4f7f8f7d7e
Update library.json 2022-02-12 19:14:31 +00:00
Bodmer 5f35a28db4
Update library.properties 2022-02-12 19:14:06 +00:00
Bodmer f0e080165a
Update TFT_eSPI.h 2022-02-12 19:13:39 +00:00
Bodmer de3c7490c2
Update TFT_eSPI_STM32.h 2022-02-12 19:11:17 +00:00
Bodmer f576040a32
Update TFT_eSPI_Generic.h 2022-02-12 19:09:57 +00:00
Bodmer 5b1b49f8ea
Update TFT_eSPI_ESP8266.h 2022-02-12 19:08:33 +00:00
Bodmer 51a6e25151
Update TFT_eSPI_ESP32.h 2022-02-12 19:06:55 +00:00
Bodmer 2aa4df5133
Update TFT_eSPI_RP2040.h 2022-02-12 19:05:33 +00:00
Bodmer efd7cc517c
Update library.json 2022-02-09 14:07:00 +00:00
Bodmer d5ba4a1886
Update library.properties 2022-02-09 14:06:07 +00:00
Bodmer 25f1398564
Update TFT_eSPI.h 2022-02-09 14:05:24 +00:00
Bodmer 3086fad767
Update TFT_eSPI_STM32.h 2022-02-09 14:04:01 +00:00
Bodmer 78685d48b8
Update TFT_eSPI_RP2040.h 2022-02-09 14:02:41 +00:00
Bodmer b7b0660fb9
Update TFT_eSPI_Generic.h 2022-02-09 14:01:17 +00:00
Bodmer 2ee3f36f68
Update TFT_eSPI_ESP8266.h 2022-02-09 14:00:13 +00:00
Bodmer a4a149405f
Update TFT_eSPI_ESP32.h 2022-02-09 13:59:00 +00:00
Bodmer 1ce36a801e
Merge pull request #1625 from Bodmer/revert-1624-master
Revert "Support esp32 - c3"
2022-02-08 19:43:10 +01:00
Bodmer 9cfcf7cbfe
Revert "Support esp32 - c3" 2022-02-08 18:42:27 +00:00
Bodmer ca6c2ecd19
Merge pull request #1624 from gongqilin0001/master
Support esp32 - c3
2022-02-08 19:33:46 +01:00
gql19950701 8a1d91652f Support esp32 - c3 2022-02-08 11:31:32 +08:00
Bodmer 10fbeece04
Update TFT_eSPI.h 2022-02-06 16:11:38 +01:00
Bodmer 31d845b1c5
Update library.json 2022-02-06 16:10:27 +01:00
Bodmer 6ca074446f
Update library.properties 2022-02-06 16:09:41 +01:00
Bodmer 29094c9c07
Update TFT_eSPI_Generic.h 2022-02-06 15:54:50 +01:00
Bodmer 0dc68c45b8
Update TFT_eSPI_RP2040.h 2022-02-06 15:53:00 +01:00
Bodmer 4dd4cb678d
Update TFT_eSPI_ESP8266.h 2022-02-06 15:50:03 +01:00
Bodmer 3b50740a29
Update TFT_eSPI_ESP32.h 2022-02-06 15:48:42 +01:00
Bodmer 48da363c68
Update README.md 2022-02-05 23:20:58 +01:00
Bodmer 7522d6b41b
Update README.md 2022-02-05 23:17:26 +01:00
Bodmer 8c5f269a32
Merge pull request #1613 from LeFauve/Fix-transparency-bug-in-sprites
Prevent TFT_eSprite::pushToSprite() to skips pixels when dealing with…
2022-02-05 22:04:32 +01:00
LeFauve 64afd184dc Prevent TFT_eSprite::pushToSprite() to skips pixels when dealing with transparency. 2022-02-05 11:40:55 +10:00
Bodmer 9ff32bf501 Resolve compile error for STM32F parallel interface 2022-02-04 10:54:47 +00:00
Bodmer d819c2e89e Add smooth graphics examples for new functions 2022-02-04 01:08:04 +00:00
Bodmer b6db90ada4 Add new anit-aliased graphics functions
Examples to follow.
2022-02-03 15:37:44 +00:00
Bodmer 97ca3fdbe2
Merge pull request #1602 from Brezensalzer/master
added USE_FSPI_PORT flag to support more ESP32-S2 boards
2022-02-03 15:17:40 +00:00
Dr. Stefan Labich 14ff368d5f added USE_FSPI_PORT flag to support more ESP32-S2 boards 2022-02-02 16:52:09 +01:00
Bodmer 32d9914254
Update README.md 2022-01-29 19:01:38 +00:00
Bodmer cb2f5be6c8 Allow use of older (pre 2.0.0) ESP32 board packages 2022-01-29 18:52:00 +00:00
Bodmer 3528ac1457 Update PlatformIO example ini file 2022-01-29 16:43:42 +00:00
Bodmer de1682667e Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2022-01-28 22:19:48 +00:00
Bodmer 2434cb515b
Merge pull request #1587 from LeFauve/Add-LilyGo-TDisplay-RP2040-Support
Add user setup file for LilyGo T-Display RP2040
2022-01-28 22:17:49 +00:00
Bodmer 984bd42896
Update Setup137_LilyGo_TDisplay_RP2040.h 2022-01-28 22:13:18 +00:00
Bodmer 0c18297d77 Update setup 70 with optional touch 2022-01-28 22:07:21 +00:00
LeFauve 10d0471345 Add user setup file for LilyGo T-Display RP2040 2022-01-28 15:31:37 +10:00
Bodmer a2140a4d04 Add Gradient_Fill example 2022-01-27 22:24:04 +00:00
Bodmer 80730ff9c4 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2022-01-27 22:15:08 +00:00
Bodmer 47895f1e7b Allow RP2040 to read from SPI TFT 2022-01-27 22:15:04 +00:00
Bodmer cd9f68313a
Update README.md 2022-01-27 13:22:31 +00:00
Bodmer 2de16b2bba
Update README.md 2022-01-27 12:48:09 +00:00
Bodmer 4b3928cb55
Update README.md 2022-01-27 12:45:02 +00:00
Bodmer 7f6e256e37
Update README.md 2022-01-27 12:44:46 +00:00
Bodmer e742a41ce2
Update README.md 2022-01-27 12:44:26 +00:00
Bodmer d0ef07d7f6 Update README.md 2022-01-27 12:42:50 +00:00
Bodmer 3cc1e2e20a Raise version 2022-01-26 23:08:21 +00:00
Bodmer 0d12646909 Fix RP2040 PIO pin override 2022-01-26 22:47:18 +00:00
Bodmer 230463317f Update TFT_eSPI_RP2040.h 2022-01-26 22:37:27 +00:00
Bodmer c9997f8dc5 Update User_Setup_Select.h 2022-01-26 22:23:55 +00:00
Bodmer e61fb8c78d Fix #1547 for RP2040 processor with ST7789 TFT
Add Arduino Nano Connect setup example 62
2022-01-26 22:20:34 +00:00
Bodmer 420165904c Fix #1578 2022-01-26 21:30:52 +00:00
Bodmer 0daee5d502 Add filled rectangles with gradient 2022-01-08 20:01:42 +00:00
Bodmer 73ff86b85b Support external font classes in button class
Original Adafruit button rendering code can be used with an external font class if "textFont" is set to 255.

See #1536
2022-01-08 14:50:44 +00:00
Bodmer bb2424f168 Raise version 2022-01-08 02:03:49 +00:00
Bodmer 1242ba14d1 Bug fix 2022-01-08 02:02:29 +00:00
Bodmer 6df79d020b
Update README.md 2022-01-05 17:12:43 +00:00
Bodmer 3f6f0bd779 Update User_Setup_Select.h 2022-01-05 14:44:52 +00:00
Bodmer 04af1d11ea Update README.md 2022-01-05 00:24:25 +00:00
Bodmer 1dd7b4ec6c Update README.md 2022-01-05 00:21:27 +00:00
Bodmer 493b1a7fe5 Update RP2040 PIO support
Add example user setup 61
2022-01-05 00:19:19 +00:00
Bodmer 553307aa63
Fix typo 2022-01-03 23:29:31 +00:00
Bodmer c725f201ee
Update TFT_eSPI_RP2040.c 2022-01-02 19:50:04 +00:00
Bodmer 8a2398451b RP2040: add SPI PIO interface option, enhance 8 bit parallel PIO
The RP2040 processors can now drive 8 bit parallel and SPI displays using the PIO hardware.

The PIO offloads the processor by providing:
1. PIO managed setWindow sequence
2. PIO managed block and screen fill
2022-01-02 01:08:22 +00:00
Bodmer 681eb9dfec Raise version for release 2022-01-01 22:49:34 +00:00
Bodmer 5e7394f485
Update Bouncy_Circles.ino 2022-01-01 00:44:57 +00:00
Bodmer d9573fe10f
Update README.md 2021-12-21 01:32:18 +00:00
Bodmer 77a39370a3
Update TFT_eSPI.h 2021-12-20 11:29:06 +00:00
Bodmer 4b841c03e3
Update library.json 2021-12-20 11:27:06 +00:00
Bodmer 7060d0cd6f
Update library.properties 2021-12-20 11:26:20 +00:00
Bodmer 40cd5bfe7b Bump version 2021-12-19 11:08:23 +00:00
Bodmer e66d0f4069
Fix #1499 2021-12-19 10:57:36 +00:00
Bodmer eee56b2cec Add RP2040 8 bit parallel support with DMA
The RP2040 can now be used with 8 bit parallel TFT interface displays. DMA is also supported for both SPI and 8 bit parallel displays.
2021-12-18 17:06:16 +00:00
Bodmer 20ad7e2cc1
Update README.md 2021-12-18 12:51:20 +00:00
Bodmer 48ad4c98fc Add new RP2040 branch link 2021-12-16 16:29:08 +00:00
Bodmer 174414f726 Update processing sketch bool -> boolean 2021-12-16 01:47:11 +00:00
Bodmer ebdc2dead9 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2021-12-16 01:42:30 +00:00
Bodmer dd8fc20cb4 Fix 1bpp pushSprite with transparent colour 2021-12-16 01:42:23 +00:00
Bodmer 3129fbf296
Update Setup52_LilyPi_ST7796.h
Reduce SPI read clock frequency to avoid bit errors on reading CGRAM.
2021-12-12 20:55:44 +00:00
Bodmer 61608a7ca2 Raise version 2021-12-12 01:34:11 +00:00
Bodmer 2aa554f072 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2021-12-12 01:33:31 +00:00
Bodmer a474f4cd23 Fix #1313 2021-12-12 01:33:27 +00:00
Bodmer 64a45f6e07
Merge pull request #1241 from matixan/master
Add option to use SPI3 in STM32F4 (and possibly also in F2)
2021-12-11 22:51:23 +00:00
Bodmer bcce0fc7ce
Update README.md 2021-12-09 11:33:38 +00:00
Bodmer 77fc9baea7
Update README.md 2021-12-08 00:54:36 +00:00
Bodmer f42daecdb8 Update notes in response to #1475
On ESP8266 when using overlap, only one SPI device can share the FLASH SPI bus .
2021-12-08 00:22:53 +00:00
Bodmer 2e626b0d7e Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2021-12-06 00:41:28 +00:00
Bodmer 52f3186da9 #1314 Re-instate $ symbol with options to replace with £
In setup add:
#define FONT_4_GBP
To replace $ with £ in font 4
2021-12-06 00:41:23 +00:00
Bodmer 289eb7a255
Update README.md 2021-12-05 22:57:05 +00:00
Bodmer 4dd15657bf
Update README.md 2021-12-05 22:55:30 +00:00
Bodmer 5959550dd7 Allow RP2040 SPI 0 or SPI 1 ports to be used
Auto set of CGRAM offset for 135 x 240 ST7789 display
2021-12-05 22:34:37 +00:00
Bodmer 12f9ce8691 Update Read_User_Setup example for RP2040 2021-12-04 16:36:31 +00:00
Bodmer 84a6945716 Updates for ESP32C3 2021-12-01 15:55:15 +00:00
Bodmer 9bf9c0940f Update for GC9A01 display
Correct sprite rendering
GC9A01 expects exact number of pixels to fill setWindow area.
2021-11-28 13:57:15 +00:00
Bodmer 07e77ad051 Fix generic driver
tft_Write_16N was missing.
2021-11-27 23:26:47 +00:00
Bodmer ee7955b34d
Merge pull request #1446 from sbonaime/master
Setup for the ESP32 S2 with Adafruit ST7789 display
2021-11-27 17:42:34 +00:00
Bodmer dff20fd77d
Update Setup71_ESP32_S2_ST7789.h 2021-11-27 17:40:10 +00:00
bonaime e17ad53809 Setup for the ESP32 S2 with ST7789 display 2021-11-24 11:07:24 +01:00
Bodmer f60425d52b
Merge pull request #1440 from ivankravets/patch-1
Declare header files for PlatformIO
2021-11-21 12:25:43 +00:00
Bodmer b955571a60
Update README.md 2021-11-21 11:55:51 +00:00
Ivan Kravets d73057a39c
Declare header files for PlatformIO 2021-11-19 12:18:36 +02:00
Bodmer a2822e6d99 Fix VSPI port for ESP32
ESP32 S2 edits caused a problem
2021-11-18 22:03:49 +00:00
Bodmer c8c5dd7cbb Update README.md 2021-11-18 17:15:38 +00:00
Bodmer 26e1f80be9 Update README.md 2021-11-18 16:50:05 +00:00
Bodmer 9a084839bd Add ESP32 S2 support
Tested with ESP32 board package 2.0.1

Additional boards manager URL may need to be updated to load the latest ESP32 board package!
2021-11-18 16:44:32 +00:00
Bodmer 11b006e1d9 Correct various inconsequential typos 2021-11-05 23:55:27 +00:00
Bodmer aa7bad45d3
Merge pull request #1356 from DaveBben/hx8357D-rotation
Fix HX8375D rotation values
2021-11-05 23:10:50 +00:00
Bodmer 0ad6de9161 Fix RP2040 with RPi type display
RPi display requires 16 bit commands and slower DC and CS strobe timings.
2021-11-05 00:09:42 +00:00
Bodmer 9d33b3eac2 RP2040 DMA image copy bug fix
memcpy should be memmove since areas overlap.
2021-11-04 21:44:15 +00:00
Bodmer e23d8e083b Correct comments 2021-11-03 23:45:16 +00:00
Dave Bennett f3135aea29 Changing the rotation file so that text is not flipped. Rotation values from
the ILI9486 driver work well with this
2021-10-07 08:25:27 -04:00
Bodmer 9e64092f58 Update User_Setup_Select.h 2021-09-18 21:45:39 +01:00
Bodmer e240947d08
Merge pull request #1341 from c-logic/patch-3
Create Setup52_LilyPi_ST7796.h
2021-09-18 21:28:59 +01:00
Dennis Heynlein c6773cc1f7
Create Setup52_LilyPi_ST7796.h 2021-09-18 21:32:13 +02:00
Bodmer 0992770d3d M5Stack setup renamed
Setup file example is for original M5Stack Basic Core module.
2021-09-14 13:18:33 +01:00
Mateusz Czarnecki afd78101e5
Merge pull request #1 from matixan/matixan-patch-1
Added option to use SPI3 in STM32F4
2021-06-23 14:54:32 +02:00
Mateusz Czarnecki 28be85212e
Added option to use SPI3 in STM32F4 2021-06-23 14:53:42 +02:00
Bodmer 58f457ba97 Raise issue 2021-05-24 12:04:03 +01:00
Bodmer c7a3f464c3
Fix #1204
This include can now be used with either the latest versions of Arduino official or Earle Philhower's board package.
2021-05-24 11:58:31 +01:00
Bodmer 8efb988cda Over-ride SPI pin defaults for RP2040
See #1188
2021-05-16 13:11:11 +01:00
Bodmer 5a6ef1d05d Fix #1188
Support debugged for ILI9488 TFT with RP2040 processors.
Minor improvements to ESP32 code.
2021-05-15 19:45:33 +01:00
Bodmer 8164629397 Fix #1168 2021-05-11 21:38:26 +01:00
Bodmer 612e76343e Remove unused macros 2021-05-11 01:29:56 +01:00
Bodmer 6b40880375 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2021-05-11 00:22:46 +01:00
Bodmer 9fc8fa6956 Add 2nd init sequence for ILI9341, see #1172
Use:
  #define ILI9341_2_DRIVER
in the setup file to invoke new initicode, instead of:
  #define ILI9341_DRIVER
2021-05-11 00:22:38 +01:00
Bodmer 01b99a50d9
Merge pull request #1154 from arduino12/master
Add support for SSD1351! (128*128 OLED)
2021-04-28 00:47:35 +01:00
arduino12 d121a84d5a Update Setup202_SSD1351_128.h 2021-04-27 10:20:01 +03:00
arduino12 25d84a977a Add Setup202_SSD1351_128 and remove tft_Write_16C/D macros 2021-04-27 10:16:12 +03:00
arduino12 e1161c17f4 Add support for SSD1351! (128*128 OLED)
TODO:
Implement read functions as well..
2021-04-26 20:40:18 +03:00
Bodmer fa8ff798e1
Update Setup201_WT32_SC01.h 2021-04-25 14:37:31 +01:00
Bodmer 1cc39dfa2b
Update User_Setup_Select.h 2021-04-25 14:33:21 +01:00
Bodmer c627b6e31a
Merge pull request #1153 from nuvious/master
Added device support for the WT32-SC01
2021-04-25 14:31:34 +01:00
David Cheeseman 0560cf4df3 Added device support for the WT32-SC01 2021-04-24 22:20:32 -04:00
Bodmer 481c7abc9c Update README.md 2021-04-24 12:10:52 +01:00
Bodmer 637f7f1fe3 Add DMA Bouncy_Circles sketch 2021-04-24 12:09:47 +01:00
Bodmer ff3a888212
Fix error 2021-04-24 09:54:13 +01:00
Bodmer 079d7f6ee5 Use RP2040 built-in byte swap for DMA 2021-04-24 01:12:55 +01:00
Bodmer a0703e7880
Update README.md 2021-04-23 16:55:32 +01:00
Bodmer 233b98aa05 Implement UTF8 switch #1108 2021-04-23 16:51:18 +01:00
Bodmer 018c884312
Update news 2021-04-22 11:21:38 +01:00
Bodmer fe580e9fe6
Update news 2021-04-22 11:19:38 +01:00
Bodmer 3b07cfa81b
Update link 2021-04-22 11:09:51 +01:00
Bodmer af25b79faa
Update README.md 2021-04-22 11:07:36 +01:00
Bodmer 83fd35a6d5 Raise version 2021-04-21 22:49:31 +01:00
Bodmer 715b4de525 Fix #1148 (RP2040 pgmspace.h warnings) 2021-04-21 22:48:21 +01:00
Bodmer f33674c1a2 Fix #1144 (RP2040 SPI pin settings)
Library now uses setup defined pins for SPI instead of defaults set by board package.
2021-04-19 00:30:28 +01:00
Bodmer 8a8ad47521 Add DMA for RP2040 with SPI displays 2021-04-18 23:21:38 +01:00
Bodmer 168a73fea9
Merge pull request #1143 from Bodmer/STM32_Port_D_test
Add Port C and D option for 8 bit parallel on STM32 processors
2021-04-16 23:09:35 +01:00
Bodmer add47960b1 Port D test 2021-04-15 01:35:28 +01:00
Bodmer f96efe5d59 Remove Dxx pins for RP2040
Dxx pin names are not used with RPi Pico
Note: A0-3 are defined for pins 26-29
2021-04-12 23:22:27 +01:00
Bodmer 534372ef99 Fix errors with "Arduino Mbed OS RP2040 Boards"
Arduino RP2040 support introduces a new issue.

This is a temporary fix.
2021-04-12 19:39:23 +01:00
Bodmer fd99db4354 Fix #1094
Allow ESP8266 and RP2040 to use FLASH for pushImage () and 4bpp
2021-04-06 19:38:19 +01:00
Bodmer 16f144ff76 Fix missing macro 2021-04-06 15:16:05 +01:00
Bodmer d0619b0527 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2021-04-05 16:39:49 +01:00
Bodmer fce86c0f2e Improve RPi Pico (RP2040) rendering performance 2021-04-05 16:39:33 +01:00
Bodmer d9c7d4a923
Update README.md 2021-04-05 01:39:13 +01:00
Bodmer 6c29d8e29b
Update README.md 2021-04-05 01:35:25 +01:00
Bodmer c06c10edb9
Update README.md 2021-04-05 01:34:55 +01:00
Bodmer 71b1d090c4
Update README.md 2021-04-05 01:34:06 +01:00
Bodmer 356095bdf3
Update Setup60_RP2040_ILI9341.h 2021-03-31 21:51:30 +01:00
Bodmer 4e8497c159 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2021-03-31 13:52:46 +01:00
Bodmer 91c34afc49 Replace deprecated boolean type
Note that Processing sketches (pde type) do not accept bool, so boolean is correct.
2021-03-31 13:52:42 +01:00
Bodmer dba2ef1855
Correct leftover from testing 2021-03-30 23:05:29 +01:00
Bodmer 135610b00d
Update TFT_eSPI_RP2040.h 2021-03-30 08:02:55 +01:00
Bodmer f6e90349d8 Add support for Raspberry Pi Pico
Setup file "Setup60_RP2040_ILI9341.h" used for testing with ILI9341 SPI display.
2021-03-30 01:53:27 +01:00
Bodmer 1c36c2c933 Support pseudo 16 bit
See #299
2021-03-27 22:27:09 +00:00
Bodmer 4cc57699fa Fix #1100
Fix STM32 + SSD1963 combination
2021-03-27 00:35:55 +00:00
Bodmer c11ecd6932 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2021-03-20 23:10:37 +00:00
Bodmer 865983e39c Correct typos 2021-03-20 23:10:33 +00:00
Bodmer e6df924f10
Typo 2021-03-17 23:36:48 +00:00
Bodmer 3c6ea1f594
See #1081 2021-03-17 23:07:26 +00:00
Bodmer 107b2dd4ed
Update Touch_calibrate.ino 2021-03-15 13:20:25 +00:00
Bodmer cd025dbc79 Fix #1046
ESP32 DMA did not work if MISO pin is not defined in setup file (affected TTGO T-Display setup 21)
2021-03-13 15:03:21 +00:00
Bodmer c47d6e2d09
Merge pull request #1062 from u4mzu4/master
add LilyGo LilyPi variant
2021-03-13 02:20:27 +00:00
andrew911 c8c1af627c
Merge pull request #2 from u4mzu4/LilyGo_LilyPi-1
add LilyGo LilyPi variant
2021-03-09 16:26:19 +01:00
andrew911 68e314f8f7
add LilyGo LilyPi variant
Based on 
https://github.com/Bodmer/TFT_eSPI/discussions/956
2021-03-09 16:22:16 +01:00
andrew911 82b0aebded
add LilyGo LilyPi variant
Based on 
https://github.com/Bodmer/TFT_eSPI/discussions/956
2021-03-09 16:19:34 +01:00
Bodmer 1e9dda3fb1
Merge pull request #1060 from lewisxhe/master
Added LilyGo TTV variants
2021-03-09 11:20:04 +00:00
lewisxhe bd434c6a3c Added LilyGo TTV variants 2021-03-09 16:05:28 +08:00
Bodmer 85539606e1 Correct typos 2021-03-06 20:16:38 +00:00
Bodmer a7a19be467 Correct typos 2021-03-06 20:05:34 +00:00
Bodmer c0054aaadf
Update Setup36_RPi_touch_ST7796.h
Delete comment
2021-03-06 18:39:47 +00:00
Bodmer 040d76f1a2
Update User_Setup_Select.h
RPi ILI9431 board reference incorrect, should be ST7796
See #1049
2021-03-06 18:35:05 +00:00
Bodmer fef40d9c8b Raise version 2021-02-23 22:48:50 +00:00
Bodmer 2bf4d15b02 Fix #1022 2021-02-23 22:38:03 +00:00
Bodmer 190fe54266
Merge pull request #1008 from ch1y4/master
add GC9A01 option
2021-02-22 22:04:23 +00:00
unknown 3307110b00 Fix #1012 & #1013 2021-02-20 10:15:21 +08:00
Bodmer 66bcbb2669 Fix #1013 2021-02-19 22:49:19 +00:00
Bodmer a40e053662 Fix #1012 2021-02-19 22:04:24 +00:00
Bodmer 602525a2ab
Update Setup44_TTGO_CameraPlus.h
See #1007
2021-02-16 08:12:56 +00:00
unknown 4780bd2fee add GC9A01 option and set ILI9341 as default 2021-02-16 10:16:12 +08:00
unknown f19e98c192 add GC9A01 option 2021-02-16 00:21:08 +08:00
Bodmer 6f2c5f7301
Add Beta test link 2021-01-30 15:59:51 +00:00
Bodmer b1fb969e86
Update TFT_eSPI_ESP32.c 2021-01-27 05:20:31 +00:00
Bodmer e829dcac21
Avoid compiler optimising out register writes
Precautionary change to avoid potential issues in future developments and during debug
2021-01-27 05:10:53 +00:00
Bodmer 25362ee893 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2021-01-25 14:18:50 +00:00
Bodmer e8843111ba Correct typos 2021-01-25 14:18:46 +00:00
Bodmer 9f083c0b2d
Update library.json 2021-01-22 01:43:57 +00:00
Bodmer 0899be91df
Update TFT_eSPI.h 2021-01-22 01:42:58 +00:00
Bodmer 9e08131add
Update library.properties 2021-01-22 01:41:41 +00:00
Bodmer 3942471ab5
Update README.md 2021-01-18 01:29:25 +00:00
Bodmer 22c514cce9 #940 - Extend allowed TFT_WR pin allocation for ESP32
TFT_WR is 8 bit parallel mode can now be allocated to GPIO >31
Note: allocating a GPIO higher than 31 has a small perfomance impact (~1.23x slower) since signle register write with the data mask cannot be performed.
2021-01-17 12:03:21 +00:00
Bodmer f6ee102619
Merge pull request #939 from maxgerhardt/patch-1
Fix uncompilable TFT_eSPI_ESP32.h when TFT_RD >= 32
2021-01-17 11:25:55 +00:00
Maximilian Gerhardt b3dab67178
Fix uncompilable TFT_eSPI_ESP32.h when TFT_RD >= 32 2021-01-17 03:13:10 +01:00
Bodmer 5f171eeefd
Fix #923 and #915 2021-01-08 23:53:28 +00:00
Bodmer 64239999e4 Fix #893 2020-12-31 19:44:33 +00:00
Bodmer 9fec44b6ea Implement #896 plus minor changes
When rendering a smooth font in a sprite the anti-aliasing will pick up the sprite background colour if the text background colour is not set.
2020-12-31 17:58:28 +00:00
Bodmer 9a7958ed28 Update ILI9481_Init.h 2020-12-31 00:18:14 +00:00
Bodmer 8e75cfa83f Fix #893 2020-12-31 00:15:26 +00:00
Bodmer e48059a6d6 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2020-12-29 13:47:42 +00:00
Bodmer 1c4860dec3 Fix RPI display issue #892
Prevent 18 bit display serial driver being invoked for RPi display
2020-12-29 13:47:28 +00:00
Bodmer a4e94634a6
Update TFT_eSPI_STM32.c 2020-12-28 01:03:56 +00:00
Bodmer 16eefd6ada
Update Setup23_TTGO_TM.h 2020-12-26 16:34:11 +00:00
Bodmer 95d1cd89c2 Update Setup25_TTGO_T_Display.h 2020-12-23 01:14:27 +00:00
Bodmer acdfeb0b36 Fix #873
Minor performance boost to ESP32 block write
2020-12-23 01:10:11 +00:00
Bodmer 974cd7d9cb
Allow DMA for RPi displays 2020-12-19 13:56:02 +00:00
Bodmer 63dc212061
Correct white=transparent bug 2020-12-15 16:50:12 +00:00
Bodmer 1b54ce87e9 Optional ESP32 DMA engine control of TFT_CS
This change has no impact on examples
See also #850
2020-12-11 21:10:12 +00:00
Bodmer 53c3fcaa05
Update README.md 2020-12-11 15:48:43 +00:00
Bodmer 2162936b40 Enable ESP32 DMA controlled TFT_CS
ESP32 DMA will hold TFT_CS low automatically.
STM32 will not do this and requires bracketing DMA transfers with startWrite and endWrite as in examples.
2020-12-07 17:43:40 +00:00
Bodmer 04b8ae9096
Correct missing ; 2020-12-04 20:15:45 +00:00
Bodmer ad0130309c Add pushToSprite with transparent colour
New function:
pushToSprite(TFT_eSprite *spr, int32_t x, int32_t y, uint16_t transp)
// Note: The following sprite to sprite colour depths are currently supported:
//    Source    Destination
//    16bpp  -> 16bpp
//    16bpp  ->  8bpp
//     8bpp  ->  8bpp
//     1bpp  ->  1bpp
2020-12-02 13:39:19 +00:00
Bodmer 42e6fc87ff Feature update
Add ILI9225 support
Add viewport feature to Sprites
Rationalise common TFT_eSPI and Sprite functions and variables to use inherited functions width(), height(), rotation(), write(), pivot, cursor, swapBytes.
2020-12-01 20:06:32 +00:00
Bodmer 27216f89cc Raise version 2020-12-01 13:25:08 +00:00
Bodmer 3b39bf10c3 Fix #846 2020-12-01 02:07:14 +00:00
Bodmer 4bb3712a04
Fix #844 2020-11-30 01:09:08 +00:00
Bodmer fd16a6066d Update ILI9486 driver for SPI 2020-11-26 14:18:28 +00:00
Bodmer 0de102f3ac Add ILI9481 init sequence options
Choosing to a different option to improve colour balance.

init options from mcufriend_kbv added.
2020-11-26 13:12:07 +00:00
Bodmer d6be490735 Add ILI9255 driver 2020-11-25 23:18:54 +00:00
Bodmer d6e573c230 Fix SPI ILI9481
ILI9481 with 8 bit parallel worked OK but SPI needs an 18 bit colour interface.
2020-11-25 22:54:30 +00:00
Bodmer abe5a442b6 Allow DMA for RPi MHS 4.0 ST7796 display
Plus minor comment tweaks
2020-11-19 15:35:14 +00:00
Bodmer df23e14675 Make DMA wait handling consistent for ESP32 and STM32 2020-11-19 00:36:59 +00:00
Bodmer bf5bf1852e Add dmaWait() for STM32 2020-11-19 00:15:21 +00:00
Bodmer 788048155c
Fix #827 (function ambiguity with Arduino DUE) 2020-11-17 18:40:39 +00:00
Bodmer 579961bd5d
Fix #630 2020-11-15 15:26:19 +00:00
Bodmer cd98515f1f Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2020-11-14 01:38:14 +00:00
Bodmer de8619027d Add ESP8266 LittleFS examples
The ESP8266 has the LittleFS Flash filing system which is significantly faster than SPIFFS. New Smooth Font examples have been added that use LittleFS.
2020-11-14 01:38:09 +00:00
Bodmer 54f6e730b5
Stop ESP32 warning 2020-11-12 17:57:41 +00:00
Bodmer 45eb2d38e5 Update TFT_eSPI_Generic.h 2020-11-10 11:28:22 +00:00
Bodmer b0edefb39d Add Setup47 2020-11-10 11:24:41 +00:00
Bodmer 68869aa171 Add Setup47 for animated eyes 2020-11-10 11:22:06 +00:00
Bodmer 2c01c41c02
Disable DMA as default 2020-11-09 12:15:26 +00:00
Bodmer aa4a32bc6b
Update Animated_Eyes_1.ino 2020-11-09 12:13:11 +00:00
Bodmer 24b0eca084 Add 2 animated eyes examples
Animated_Eyes_1 is an example for a single display
Animated_Eyes_2 is an example for two displays
2020-11-08 22:53:23 +00:00
Bodmer 975347d5de Update Floyd_Steinberg.ino 2020-11-02 23:22:04 +00:00
Bodmer 9cfc86839f Update EPD_Support.h 2020-11-02 23:18:04 +00:00
Bodmer c9490f91b5 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2020-11-02 23:16:13 +00:00
Bodmer 7eb365fcf5
Update EPD_Support.h 2020-11-02 23:15:10 +00:00
Bodmer e49e546d2c Update ePaper example
Corrections as in #729 plus others of same ilk.
2020-11-02 23:12:33 +00:00
Bodmer 5f272751f7
Update EPD_Support.h 2020-11-02 22:42:17 +00:00
Bodmer f96c42253c Add support for choosing colour order on ST7735
See #639
2020-11-02 17:59:04 +00:00
Bodmer c8c6317241 Add off-screen support to readRect()
See #803
2020-10-25 15:56:13 +00:00
Bodmer 1c1ec8cfa3 #774 add GC9A01 driver
Driver added
Setup46 added
2020-10-25 12:52:37 +00:00
Bodmer ce3f0e219c Update Setup36_RPi_touch_ST7796.h 2020-10-25 12:46:40 +00:00
Bodmer 0c4bedc681 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2020-10-25 12:45:23 +00:00
Bodmer 35126bcc4d #802
File name was wrong
2020-10-25 12:45:12 +00:00
Bodmer e41e869851
Correct as per #802 2020-10-25 12:07:06 +00:00
Bodmer aaf96fa870
Update TFT_Clock_Digital.ino
Fix #795
2020-10-21 16:16:06 +01:00
Bodmer 0d31c9f1a5 Add Orrery example
Uses sprites for flicker free animation
2020-10-20 00:53:08 +01:00
Bodmer 482e559b26 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2020-10-19 16:21:03 +01:00
Bodmer e4e17b9af1 Correct fillCircle function 2020-10-19 16:21:00 +01:00
Bodmer 126aa7dff5
Update Viewport_Demo.ino
Viewport does not need to be constrained to be within TFT area.
2020-10-14 09:09:40 +01:00
Bodmer 6a839479a7
Update README.md 2020-10-13 13:53:49 +01:00
Bodmer 9bd670be45
Update README.md 2020-10-13 13:38:36 +01:00
Bodmer d495b268c2
Merge pull request #778 from Bodmer/Viewport
Add viewport feature
2020-10-13 13:37:23 +01:00
Bodmer b1f8cae069 Finalise viewport changes 2020-10-13 13:35:03 +01:00
Bodmer 505ca81a70 Complete viewport update 2020-10-11 22:36:02 +01:00
Bodmer ee91f723e7 Update DMA fn clipping for viewport 2020-10-06 20:00:59 +01:00
Bodmer 39fe01afa3 Update Animated_dial.ino
Correct error in example that became apparent with recent library updates.
2020-10-06 14:26:13 +01:00
Bodmer c0f14b2f99 Move viewport examples
Moved to generic
2020-10-06 12:51:22 +01:00
Bodmer 27cf479e55
Update Viewport_Demo.ino 2020-10-06 11:58:33 +01:00
Bodmer 26ffe75a0e
Update Viewport_Demo.ino 2020-10-06 11:55:51 +01:00
Bodmer dfba4633ad
Update Viewport_Demo.ino 2020-10-06 11:54:53 +01:00
Bodmer 13d217dc89 Add viewport feature
2 new example sketches added for viewport demonstration
2020-10-06 00:51:41 +01:00
Bodmer 22ca8193c5 Improve RLE font rendering
See #766
2020-10-02 22:00:03 +01:00
Bodmer ef93dbe687 Make ST7789 drivers consistent
Simplified driver ST7789_2_DRIVER not supports 135 x 240 display.
This will not fix #763 since user specifies alternative ST7789_DRIVER which already supports 135x240 displays.
2020-10-02 20:47:00 +01:00
Bodmer 49cef1f35d Support for SSD1963 and ST7706 SPI read
The SSD1963 support has been tested with a 480x800 pixel display from Buy Display.
Support for reading an ST7796 SPI display has been added.
pushToSprite added to keywords list.
2020-10-02 01:07:15 +01:00
Bodmer 0c49b71dd4
Fix #751 2020-09-14 21:40:20 +01:00
Bodmer d7fdcc0991 Fix #740 and #704
#740: To avoid ambiguity the pushSprite for writing a sprite to another sprite has been renamed pushToSprite

#704: Change to 18 bit colurs for SSD1963 with SPI interface

Remove outdated TFT_SPIFFS_Jpeg example
2020-09-07 22:04:42 +01:00
Bodmer aaebc18844
Merge pull request #745 from Bodmer/revert-741-fix/ambigous_pushSprite
Revert "Resolve ambigous pushSprite(int int int) methods"
2020-09-07 13:06:18 +01:00
Bodmer 4c314c5c33
Revert "Resolve ambigous pushSprite(int int int) methods" 2020-09-07 13:05:59 +01:00
Bodmer 27657bcb9a
Merge pull request #741 from QrackEE/fix/ambigous_pushSprite
Resolve ambigous pushSprite(int int int) methods
2020-09-07 12:43:10 +01:00
QrackEE ddf03d43ea Resolve ambigous pushSprite(int int int) methods 2020-09-05 16:54:24 +02:00
Bodmer 731228d13a Fix deleteSprite
Fixes #736 and also delete color map even if the sprite has not been created.
2020-08-28 21:18:26 +01:00
Bodmer 1c66d306d5 Add SSD1963 for #704
Remove setWindow optimisation clash with TFT_eFEX
2020-08-15 00:19:03 +01:00
Bodmer a8cd5c5d91 Correct TFT_eFEX issue 24 2020-08-06 12:51:10 +01:00
Bodmer 787893f949
Update README.md 2020-08-05 23:55:54 +01:00
Bodmer 47baa19645 Update README.md 2020-08-05 23:52:02 +01:00
Bodmer 52ee45b30b Correct medium warnings #702 2020-08-05 23:37:24 +01:00
Bodmer cfcb9c6632 Revert "Elimnate some warnings #702"
This reverts commit 31125ca5ac.
2020-08-05 23:13:59 +01:00
Bodmer 31125ca5ac Elimnate some warnings #702 2020-08-05 23:01:59 +01:00
Bodmer dc114db01b Srite class updates + others
Add 2 new pushSprite functions:
1. Sprite to sprite
2. windowed are of sprite to screen
Examples to follow
Bug fixes to sprite class
2020-08-05 20:06:44 +01:00
Bodmer c124688ab1
Fix #697
Untested but looks correct!
2020-07-19 10:45:36 +01:00
Bodmer 90cabab91a Update to aid use of ESP32 with multiple displays #687
Fix issue when using ESP32 & using multiple TFT displays & not defining TFT_CS.

Note: Future support for multiple displays in all possible hardware combinations may not be practical.
2020-07-09 14:20:34 +01:00
Bodmer a6d50ea5ef #682 Add created() function for sprites
New function added:
  bool created(void);
to check if sprite has been rotated. Example:

if ( !spr.created() ) Serial.println("Sprite has not been created");
2020-07-07 00:52:55 +01:00
Bodmer 8fc52dc1f5 Update ReadMe
Update news, move tips towards end.
2020-06-27 21:37:03 +01:00
Bodmer a3fea4299e
Raise version 2020-06-19 10:07:59 +01:00
Bodmer af5aba3aae
Raise version 2020-06-19 10:07:08 +01:00
Bodmer c7383df1a3
Raise version 2020-06-19 10:06:28 +01:00
Bodmer 61f1c5f98e
Merge pull request #641 from kamorris/kamorris-patch-1
Add 4bit images to sprites, with an example and a tool to produce the images from bmp files.
2020-06-19 10:05:01 +01:00
kamorris a7be0c0ebe delete extraneous ino file 2020-06-18 20:29:10 -07:00
Bodmer 7861a0206e Add missing // 2020-06-15 13:54:45 +01:00
Bodmer 8cb59566d4 Add multi TFT option support for issue #663
Avoid coordinate optimisation for sketch controlled multiple TFT displays. Add #define MULTI_TFT_SUPPORT
to prevent setAddr optimisation that relies on coordinate transfer minimisation.
2020-06-15 12:22:38 +01:00
Bodmer 24750c605d Add option to use STM32 SPI port 2
See new #define options in "Setup29_ILI9341_STM32.h"
2020-06-13 21:05:47 +01:00
Bodmer 284f52b009 Allow partially of screen RLE fonts 2020-06-11 22:34:22 +01:00
Bodmer fb86ae4d1b Update Read_User_Setup add #648
Read_User_Setup now includes backlight settings
2020-06-06 14:55:02 +01:00
Bodmer 21aa38b87f Update version 2020-06-05 16:43:48 +01:00
Bodmer b5826586fc Allow 4bpp Sprites to be rotated
4bpp Sprites can now be pushed to the TFT with a rotation
2020-06-05 16:05:04 +01:00
Kate Morris 110128b055
updated with formatting and links 2020-05-25 17:29:39 -07:00
Kate Morris 3a2157805e
Rename readme.txt to readme.md 2020-05-25 17:12:24 -07:00
kamorris 5ffd4feac4 prepare for merging. 2020-05-25 17:09:56 -07:00
kamorris 0db6eed9e0 add 4bit image support, tools and examples 2020-05-25 15:29:41 -07:00
Bodmer 960ff6c7b9 Ensure ESP32_PARALLEL defined 2020-05-14 15:33:03 +01:00
Bodmer 232330d5cd
Correct typo 2020-05-13 22:32:54 +01:00
Bodmer cd10a92f11 Allow ESP32 SPI pins to be undefined
See #618
2020-05-13 18:28:44 +01:00
Bodmer 1314a34c3d Fix #625
pushRect() reinstated to pair with readRect() so swapBytes does not need to be changed from true to false before calling.
2020-05-13 16:33:12 +01:00
Bodmer 7e4566f3f2 Raise version to 2.2.6 2020-05-10 00:19:12 +01:00
Bodmer cc3a1084fb Fix #617 2020-05-09 19:51:03 +01:00
Bodmer cc4f35f8c1 ESP32 DMA update
dmaBusy() checks and is no longer blocking
pushImageDMA() faster if setAddrWindow is not built into transaction list.
2020-05-08 21:25:38 +01:00
Bodmer fc8d912f52 Update Read_User_Setup.ino 2020-05-05 21:40:24 +01:00
Bodmer 00ac129667 Update Sprite.cpp 2020-05-05 21:36:05 +01:00
Bodmer 489d90c935 Update README.md 2020-05-05 21:28:11 +01:00
Bodmer f6748bf906 Add ESP32 SPI DMA capability
DMA test examples now work on ESP32
2020-05-05 21:21:28 +01:00
Bodmer fb2e669d37 1,4,8 bpp Sprites requite different default swapBytes settings 2020-05-01 22:38:14 +01:00
Bodmer 1f2d4b0a75 Issue #510 part STM32F103 workaround 2020-05-01 20:57:03 +01:00
Bodmer cf979d40b7
Merge pull request #607 from lovyan03/master
Fix: Font7srle  Character '1' is missing two dots.
2020-04-28 13:55:25 +01:00
lovyan03 c01ee2c4f7 Fix: Font7srle Character '1' is missing two dots. 2020-04-27 21:05:01 +09:00
Bodmer 90af737fa1 Fix #606 inconsistency + others
TFT_eFEX also needs updating so Rotated_Sprite_3 example renders correctly.

pushImage for FLASH images updated so partly off-screen images are correctly rendered.
2020-04-26 17:05:19 +01:00
Bodmer 353d80a78e
Support SPI variant of ST7796
See #499
2020-04-17 14:48:24 +01:00
Bodmer e937a3496f Diagnostic sketch update + others
Read_User_Setup updated to be compatible with STM32 and new structure format.
Reduction in compiler warnings
Update Sprite destructor
Update version to 2.2.1
2020-04-16 14:33:42 +01:00
Bodmer 875b451590 Fix Sprite 1bpp scroll bug
Sprite scroll function fixed for 1bpp
readPixelValue() updated

Performance of circle drawing functions improved.

Version raised to 2.2.0
2020-03-30 21:51:26 +01:00
Bodmer 5ab0a08d1d Fix #588 2020-03-29 18:42:25 +01:00
Bodmer 5ff03cd2e9 Support STM32F1xx
STM32F1xx processors do not have MODER direction configuration.
2020-03-29 14:18:14 +01:00
Bodmer 1bd0b96c6c
Update README.md 2020-03-28 20:23:57 +00:00
Bodmer 557f2ac883
Update README.md 2020-03-28 20:22:28 +00:00
Bodmer 222e95f672 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2020-03-28 13:47:27 +00:00
Bodmer 1917e8f542 Add fast STM32 parallel mode 2020-03-28 13:47:22 +00:00
Bodmer ef38ae9b2b
Merge pull request #586 from lewisxhe/master
Add TTGO CameraPlus and T-Watch setup files
2020-03-28 12:40:15 +00:00
Bodmer e27ee952f1
Update Setup45_TTGO_T_Watch.h
80MHz is unreliable for some code sequences.
2020-03-28 12:39:22 +00:00
Bodmer 8bdb3ea63e Add new setup for TTGO T4 v1.3
See #585
2020-03-28 12:35:15 +00:00
lewis he dd897e6560 Add TTGO CameraPlus,T-Watch configure file 2020-03-28 09:08:54 +08:00
Bodmer 732bdd32eb Port A+B and BRR update
PortA and Port B direction control now works on all STM processors.
Correct BRR to BSRR to support all STM processors.
2020-03-27 21:59:18 +00:00
Bodmer fa2727b511
Update ILI9488_Init.h 2020-03-27 11:13:39 +00:00
Bodmer 1015c564f4 Fix STM32 parallel read on port A or B 2020-03-27 02:14:12 +00:00
Bodmer 919febefd6 Fix #581 2020-03-27 01:31:10 +00:00
Bodmer f71df4ffe5 #581 fallout update 2020-03-25 16:57:59 +00:00
Bodmer d1b0bab912 Fix #581 2020-03-25 15:29:53 +00:00
Bodmer 89bf0ce6c1 Fix #581 plus
Update 4 bit Sprite code
Update Animate_Dial example to use italic font with minimised character set, add original jpeg graphic.
Raise to 2.1.8
2020-03-25 14:27:38 +00:00
Bodmer 611ca4b223
Update Sprite.cpp 2020-03-20 02:30:26 +00:00
Bodmer cb87759bad
Update README.md 2020-03-20 00:50:56 +00:00
Bodmer 16b717d006 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2020-03-20 00:49:06 +00:00
Bodmer 1118b45470 Update README.md 2020-03-20 00:48:50 +00:00
Bodmer b3db931dc5
Move label 2020-03-20 00:34:26 +00:00
Bodmer 7f7cc24b00 Add new animated dial example
See Sprite "Animated_dial" example.
2020-03-20 00:30:12 +00:00
Bodmer bdf2c9ba75
Fix #572 2020-03-19 22:20:48 +00:00
Bodmer ac8845d589 Fix #566 plus others
Fix image rendering issue.
Deprecate use of pushColors.
Improve ES8266 image rendering performance for ESP8266 and ILI9488.
Add getTextPadding().
2020-03-07 16:26:44 +00:00
Bodmer 65ccbf0139 STM32 update
Boost performance for ILI9488 display with STM32 processors.
Enable smooth fonts in setup files (smooth fonts for STM32 processors is now supported with fonts in program memory)
2020-03-02 22:25:39 +00:00
Bodmer ed160f6476 Raise version 2020-03-01 18:42:01 +00:00
Bodmer 0161814c9a Add smooth font wrapping in a Sprite
See #558
2020-03-01 18:40:54 +00:00
Bodmer ef21c44a28 Add more smooth font examples
The extra examples use smooth fonts stored in arrays and thus can run on STM32 processors which do not support SPIFFS.
2020-02-18 01:41:34 +00:00
Bodmer 8d163618bb Add parallel TFT readRectRGB(), fix #548 2020-02-17 21:43:13 +00:00
Bodmer 55e97ffe33
Fix #539 2020-02-16 18:50:39 +00:00
Bodmer da9de94fb1 Raise version 2020-02-16 17:07:55 +00:00
Bodmer db7a9987d3 Increase precision for Sprite to Sprite rotations
Based on pull request #543
2020-02-16 17:06:58 +00:00
Bodmer 83d202dd08
Merge pull request #543 from lovyan03/master
update: pushRotated tweak.
2020-02-16 16:57:28 +00:00
Bodmer 0fd8803ba2 Add smooth fonts in program memory for ESP32/8266
The 4 new smooth font  "Font_Demo_1/2/3/4_Array" examples now work on ESP32 and ESP8266.
2020-02-15 23:58:21 +00:00
Bodmer 771b52f841
Fix #546 2020-02-15 11:28:31 +00:00
Bodmer eac96793a1 Update ReadMe
Delete data folders.
Ass missing headers to Font_Demo_1_Array example.
2020-02-15 00:02:01 +00:00
Bodmer c689b4211d Add FLASH based anti-aliased fonts
Processors (such as STM32) that are not supported by a SPIFFS library can now use anti-aliased (smooth) fonts stored in FLASH (program) memory.
2020-02-14 23:54:37 +00:00
lovyan03 39fe08f987 update: pushRotated tweak. 2020-02-11 12:50:04 +09:00
Bodmer d2270c3611
Update Setup29_ILI9341_STM32.h 2020-02-09 06:48:15 +00:00
Bodmer 91574c87e9
Update Setup30_ILI9341_Parallel_STM32.h 2020-02-09 06:28:29 +00:00
Bodmer 4941ae55ed Update Setup31_ST7796_Parallel_STM32.h 2020-02-09 06:26:12 +00:00
Bodmer 73ff949364 Update Setup32_ILI9341_STM32F103.h 2020-02-09 06:23:21 +00:00
Bodmer 938d2ee5d2
Correct comment 2020-02-09 06:18:47 +00:00
Bodmer 443be934a7 Add PSRAM switch
Typical use to disable use of PSRAM for the sprite storage:
sprite.setAttribute(PSRAM_ENABLE, false); // true to enable
Minor update for recent button class update
2020-02-06 20:34:36 +00:00
Bodmer 87aca91218 Merge branch 'master' of https://github.com/Bodmer/TFT_eSPI 2020-02-06 13:38:13 +00:00
Bodmer 15c137633a Raise version add comments for button update 2020-02-06 13:38:03 +00:00
Bodmer 135604b59c
Merge pull request #541 from justcallmekoko/master
Fixes button text alignment and added keyword
2020-02-06 13:20:53 +00:00
Bodmer 7841015043 Revert "Revert "Merge pull request #540 from justcallmekoko/master""
This reverts commit 38a057762f.
2020-02-06 13:20:17 +00:00
Just Call Me Koko ec6739c013 Add setLabelDatum to keywords 2020-02-05 22:24:33 -05:00
Just Call Me Koko b734b81e6b Fix center aligned button text 2020-02-05 22:21:02 -05:00
Bodmer 38a057762f Revert "Merge pull request #540 from justcallmekoko/master"
This reverts commit 6dec790e8d, reversing
changes made to 8146ac3015.
2020-02-06 01:43:42 +00:00
Bodmer 6dec790e8d
Merge pull request #540 from justcallmekoko/master
Add setLabelDatum
2020-02-05 20:05:31 +00:00
justcallmekoko 2b1147c6e8 Add setLabelDatum 2020-02-05 14:13:58 -05:00
Bodmer 8146ac3015
Move include for User_Setup_Select.h (#537)
Requested change in #537
2020-02-02 17:32:46 +00:00
Bodmer c8530d7ae4 4 bpp Sprite bug fix
OR has precedence over AND so brackets needed.
Remove unused varaible.
2020-02-01 01:43:16 +00:00
Bodmer 8209c00316 Add new alphaBlend functions
Added 24 bit colour handling alphaBlend to reduce precision loss in multiple blend stages (e.g. in 2D colour gradients). Added option for alpha dither to reduce colour banding in gradients with 16 bit colours.

Get rid of compile warnings.
2020-01-30 16:01:36 +00:00
Bodmer 0e0fd75277 Raise to version 2.0.0
The library has been cleaned up as it has got a bit untidy due to the large number of small incremental changes.

4bit Sprite examples renaed to be consistent with others.

alphaBlend example moved to generic folder (alphaBlend fn was moved to TFT_eSPI class).
Added sections + explanatory comments to functions prototypes.

Temporary comments added for potential gotchas for noobs when using DMA.

spi_begin/end functions renamed to reflect functionality. Old fns  retained for backwards compatibility with user setup.h files.
2020-01-26 21:17:49 +00:00
Bodmer b954372859
Merge pull request #528 from kamorris/add_color_maps
Add Sprite 4 bit color depth option with a defined palette of 16 colors. Add new Sprite examples.
2020-01-25 23:01:42 +00:00
kamorris 7fd29d509f Suggested changes from code review
Set font for Transparent_Sprite_Demo_Colormap to correct value (4)
renamed setColorMap to createPalette
renamed cmpPixel to readPixelValue
added setPaletteColor / getPaletteColor
added error check to createPalette
2020-01-25 12:49:29 -08:00
kamorris e019b6dcf6 added color maps and examples 2020-01-24 22:07:45 -08:00
Bodmer 04eacf56c9
Update library.json 2020-01-19 23:55:20 +00:00
Bodmer d129512a2c
Update library.json 2020-01-19 23:50:15 +00:00
Bodmer b6a8f6a8a4
Update library.json 2020-01-14 01:45:02 +00:00
Bodmer 811ee7b8ed
Remove STM32 branch news item 2020-01-12 23:53:34 +00:00
Bodmer 561b488b3c
Remove test setups 2020-01-12 00:10:30 +00:00
Bodmer 7f53a571f4 Add STM32 and generic processor support 2020-01-11 23:32:10 +00:00
Bodmer 8342507233 Remove scrap drivers, fix Sprite destructor 2020-01-11 01:27:51 +00:00
Bodmer 3e82aafd2d
Typo 2020-01-11 01:14:32 +00:00
Bodmer 1476da56ba Restructured code, added ST7796
RPi MHS-4.0 inch Display-B type display now supported.
2020-01-11 00:58:38 +00:00
Bodmer b6574ff373
Typo 2020-01-07 17:09:46 +00:00
Bodmer cb59388353
Amend 2020-01-06 22:28:30 +00:00
Bodmer 0d7d8e06ce
Typo 2020-01-06 22:27:01 +00:00
Bodmer 39f859f6e2
Add further tip 2020-01-06 22:25:46 +00:00
Bodmer e94c24e303
Edit tips format 2020-01-05 12:28:21 +00:00
Bodmer fbf4592fc1
Tips typo 2020-01-05 12:26:16 +00:00
Bodmer c54131d9f0
Add tips 2020-01-05 12:23:45 +00:00
Bodmer 6459ddbeea
#503 additional update 2020-01-02 12:38:50 +00:00
Bodmer d02fe55c46
Fix #503
The s60sc Adafruit_Touch library fork for the ESP32 parallel mode uses the TFT_WR pin as an analogue input to read the screen resistance.  The TFT_eSPI library kept TFT_CS low permanently for performance reasons, but when used with the touch library a low analogue value on the TFT_WR pin will write spurious data to the display. 

This change toggle TFT_CS so it is only low during TFT parallel bus writes. The performance reduction is small.
2020-01-02 11:53:50 +00:00
Bodmer 308b46e125
edit 2020-01-02 01:03:02 +00:00
Bodmer bfd6287f19
edit 2020-01-02 01:02:34 +00:00
Bodmer c7af5dd304
Update news 2020-01-02 01:01:05 +00:00
Bodmer 3115285b05
Issue #505
ILI9488 not compliant to datasheet with extra clock pulse?
2020-01-02 00:50:49 +00:00
Bodmer 962cec85aa
Merge pull request #488 from lewisxhe/master
Add TTGO T-Wristband config
2019-12-06 10:34:01 +00:00
lewis 6f972dc980 Add T-Wristband headfile to User_Setup_Select.h 2019-12-05 10:00:04 +08:00
lewis de787e669e Add TTGO T-Wristband config 2019-12-05 09:15:10 +08:00
Bodmer 10078c8325
Fix #473
Update to accommodate smooth font rendering, which need a background colour specified.
2019-11-27 02:36:17 +00:00
Bodmer 34117e4830
Merge pull request #475 from lovyan03/master
Add: Destructor of TFT_eSprite.
2019-11-26 19:10:27 +00:00
lovyan03 7b71a3d8b5 Add: TFT_eSprite destructor. 2019-11-21 15:19:33 +09:00
Bodmer c6faa24494 Update notes for #268 2019-11-11 22:17:14 +00:00
Bodmer 27cde1520d Add #define to set font 2 character 0x60
By default the grave accent will be drawn as a degree symbol, a #define
has been added so it can be swapped back to the grave accent.
2019-11-11 21:53:37 +00:00
Bodmer 7a9c5a8e7d
Merge pull request #469 from lovyan03/lovyan03
Fix TextFont 2 (Font16.c) backslash(0x5c) looks like slash.
2019-11-11 21:30:27 +00:00
lovyan03 943b95ec79 Fix TextFont 2 (Font16.c) backslash(0x5c) looks like slash. 2019-11-11 11:43:18 +09:00
Bodmer 4fcebdcc62
Another typo 2019-11-11 01:23:17 +00:00
Bodmer e335481e5e
Update news 2019-11-10 03:06:23 +00:00
Bodmer 251f341812
Correct typos 2019-11-10 02:59:28 +00:00
Bodmer 9679523db3
Add gradient antialiased font image 2019-11-10 02:57:55 +00:00
Bodmer 5bb14ba2d8 Add new callback for smooth font antialiasing
Callback allows anitaliased fonts to be rendered over colour gradients
or images.
"Smooth_font_reading_TFT" example added
"Smooth_font_gradient" example added
Minor changes to avoid signed/unsigned comparison warnings.
2019-11-10 02:23:22 +00:00
Bodmer d28e43574b Fix #406 2019-11-02 15:14:20 +00:00
Bodmer d3a1ecedc3 Incorporate #453 with option 2019-11-02 14:33:57 +00:00
Bodmer 5d280f998c Fix #346 2019-11-02 14:18:33 +00:00
Bodmer 425a4744a7 Revert pin references #456 2019-11-02 13:24:58 +00:00
Bodmer 27b6509f27 Raise version 2019-10-22 23:02:41 +01:00
Bodmer bd23626b53 Correct coordinate cropping in Sprite 2019-10-22 23:01:33 +01:00
452 changed files with 352939 additions and 6108 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
*.lnk
# Arduino debug
debug.cfg
debug_custom.json
*.svd
# =========================
# 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

@ -3,7 +3,13 @@
** Grabbed from Adafruit_GFX library and enhanced to handle any label font
***************************************************************************************/
TFT_eSPI_Button::TFT_eSPI_Button(void) {
_gfx = 0;
_gfx = nullptr;
_xd = 0;
_yd = 0;
_textdatum = MC_DATUM;
_label[9] = '\0';
currstate = false;
laststate = false;
}
// Classic initButton() function: pass center & size
@ -35,7 +41,15 @@ void TFT_eSPI_Button::initButtonUL(
strncpy(_label, label, 9);
}
void TFT_eSPI_Button::drawButton(boolean inverted) {
// Adjust text datum and x, y deltas
void TFT_eSPI_Button::setLabelDatum(int16_t x_delta, int16_t y_delta, uint8_t datum)
{
_xd = x_delta;
_yd = y_delta;
_textdatum = datum;
}
void TFT_eSPI_Button::drawButton(bool inverted, String long_name) {
uint16_t fill, outline, text;
if(!inverted) {
@ -52,25 +66,42 @@ void TFT_eSPI_Button::drawButton(boolean inverted) {
_gfx->fillRoundRect(_x1, _y1, _w, _h, r, fill);
_gfx->drawRoundRect(_x1, _y1, _w, _h, r, outline);
_gfx->setTextColor(text);
_gfx->setTextSize(_textsize);
if (_gfx->textfont == 255) {
_gfx->setCursor(_x1 + (_w / 8),
_y1 + (_h / 4));
_gfx->setTextColor(text);
_gfx->setTextSize(_textsize);
_gfx->print(_label);
}
else {
_gfx->setTextColor(text, fill);
_gfx->setTextSize(_textsize);
uint8_t tempdatum = _gfx->getTextDatum();
_gfx->setTextDatum(MC_DATUM);
_gfx->drawString(_label, _x1 + (_w/2), _y1 + (_h/2));
_gfx->setTextDatum(tempdatum);
uint8_t tempdatum = _gfx->getTextDatum();
_gfx->setTextDatum(_textdatum);
uint16_t tempPadding = _gfx->getTextPadding();
_gfx->setTextPadding(0);
if (long_name == "")
_gfx->drawString(_label, _x1 + (_w/2) + _xd, _y1 + (_h/2) - 4 + _yd);
else
_gfx->drawString(long_name, _x1 + (_w/2) + _xd, _y1 + (_h/2) - 4 + _yd);
_gfx->setTextDatum(tempdatum);
_gfx->setTextPadding(tempPadding);
}
}
boolean TFT_eSPI_Button::contains(int16_t x, int16_t y) {
bool TFT_eSPI_Button::contains(int16_t x, int16_t y) {
return ((x >= _x1) && (x < (_x1 + _w)) &&
(y >= _y1) && (y < (_y1 + _h)));
}
void TFT_eSPI_Button::press(boolean p) {
void TFT_eSPI_Button::press(bool p) {
laststate = currstate;
currstate = p;
}
boolean TFT_eSPI_Button::isPressed() { return currstate; }
boolean TFT_eSPI_Button::justPressed() { return (currstate && !laststate); }
boolean TFT_eSPI_Button::justReleased() { return (!currstate && laststate); }
bool TFT_eSPI_Button::isPressed() { return currstate; }
bool TFT_eSPI_Button::justPressed() { return (currstate && !laststate); }
bool TFT_eSPI_Button::justReleased() { return (!currstate && laststate); }

View File

@ -2,14 +2,15 @@
// The following button class has been ported over from the Adafruit_GFX library so
// should be compatible.
// A slightly different implementation in this TFT_eSPI library allows the button
// legends to be in any font
// legends to be in any font, allow longer labels and to adjust text positioning
// within button
***************************************************************************************/
class TFT_eSPI_Button {
class TFT_eSPI_Button : public TFT_eSPI {
public:
TFT_eSPI_Button(void);
// "Classic" initButton() uses center & size
// "Classic" initButton() uses centre & size
void initButton(TFT_eSPI *gfx, int16_t x, int16_t y,
uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
uint16_t textcolor, char *label, uint8_t textsize);
@ -18,21 +19,26 @@ class TFT_eSPI_Button {
void initButtonUL(TFT_eSPI *gfx, int16_t x1, int16_t y1,
uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
uint16_t textcolor, char *label, uint8_t textsize);
void drawButton(boolean inverted = false);
boolean contains(int16_t x, int16_t y);
// Adjust text datum and x, y deltas
void setLabelDatum(int16_t x_delta, int16_t y_delta, uint8_t datum = MC_DATUM);
void drawButton(bool inverted = false, String long_name = "");
bool contains(int16_t x, int16_t y);
void press(boolean p);
boolean isPressed();
boolean justPressed();
boolean justReleased();
void press(bool p);
bool isPressed();
bool justPressed();
bool justReleased();
private:
TFT_eSPI *_gfx;
int16_t _x1, _y1; // Coordinates of top-left corner
uint16_t _w, _h;
uint8_t _textsize;
int16_t _x1, _y1; // Coordinates of top-left corner of button
int16_t _xd, _yd; // Button text datum offsets (wrt centre of button)
uint16_t _w, _h; // Width and height of button
uint8_t _textsize, _textdatum; // Text size multiplier and text datum for button
uint16_t _outlinecolor, _fillcolor, _textcolor;
char _label[10];
char _label[10]; // Button text is 9 chars maximum unless long_name used
boolean currstate, laststate;
bool currstate, laststate; // Button states
};

View File

@ -8,16 +8,30 @@
/***************************************************************************************
** Function name: loadFont
** Description: loads parameters from a new font vlw file
** Description: loads parameters from a font vlw array in memory
*************************************************************************************x*/
void TFT_eSPI::loadFont(const uint8_t array[])
{
if (array == nullptr) return;
fontPtr = (uint8_t*) array;
loadFont("", false);
}
#ifdef FONT_FS_AVAILABLE
/***************************************************************************************
** Function name: loadFont
** Description: loads parameters from a font vlw file
*************************************************************************************x*/
void TFT_eSPI::loadFont(String fontName, fs::FS &ffs)
{
fontFS = ffs;
loadFont(fontName, false);
}
#endif
/***************************************************************************************
** Function name: loadFont
** Description: loads parameters from a new font vlw file
** Description: loads parameters from a font vlw file
*************************************************************************************x*/
void TFT_eSPI::loadFont(String fontName, bool flash)
{
@ -44,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.
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.
pixelRed = ((fgRed * alpha) + (bgRed * (255 - alpha))/255
To gain a performance advantage fixed point arithmetic is used with rounding and
@ -57,9 +71,6 @@ void TFT_eSPI::loadFont(String fontName, bool flash)
a zero/one terminated character string giving the font name
last byte is 0 for non-anti-aliased and 1 for anti-aliased (smoothed)
Then the font name seen by Java when it's created
Then the postscript name of the font
Then a boolean to tell if smoothing is on or not.
Glyph bitmap example is:
// Cursor coordinate positions for this and next character are marked by 'C'
@ -75,31 +86,44 @@ void TFT_eSPI::loadFont(String fontName, bool flash)
// | gHeight ....@@@@@..@@ + + <-- baseline
// | | ...........@@ |
// | | ...........@@ | 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
// | |
// +---------------------------+ yAdvance is y delta for the next line, font size or (ascent + descent)
// some fonts can overlay in y direction so may need a user adjust value
// some fonts can overlay in y direction so may need a user adjust value
*/
spiffs = flash;
if (fontLoaded) unloadFont();
if(spiffs) fontFS = SPIFFS;
#ifdef FONT_FS_AVAILABLE
if (fontName == "") fs_font = false;
else { fontPtr = nullptr; fs_font = true; }
unloadFont();
if (fs_font) {
spiffs = flash; // true if font is in SPIFFS
// Avoid a crash on the ESP32 if the file does not exist
if (fontFS.exists("/" + fontName + ".vlw") == false) {
Serial.println("Font file " + fontName + " not found!");
return;
if(spiffs) fontFS = SPIFFS;
// Avoid a crash on the ESP32 if the file does not exist
if (fontFS.exists("/" + fontName + ".vlw") == false) {
Serial.println("Font file " + fontName + " not found!");
return;
}
fontFile = fontFS.open( "/" + fontName + ".vlw", "r");
if(!fontFile) return;
fontFile.seek(0, fs::SeekSet);
}
#else
// Avoid unused varaible warning
fontName = fontName;
flash = flash;
#endif
fontFile = fontFS.open( "/" + fontName + ".vlw", "r");
if(!fontFile) return;
fontFile.seek(0, fs::SeekSet);
gFont.gArray = (const uint8_t*)fontPtr;
gFont.gCount = (uint16_t)readInt32(); // glyph count in file
readInt32(); // vlw encoder version - discard
@ -117,9 +141,7 @@ void TFT_eSPI::loadFont(String fontName, bool flash)
fontLoaded = true;
// Fetch the metrics for each glyph
loadMetrics(gFont.gCount);
//fontFile.close();
loadMetrics();
}
@ -128,32 +150,32 @@ void TFT_eSPI::loadFont(String fontName, bool flash)
** Description: Get the metrics for each glyph and store in RAM
*************************************************************************************x*/
//#define SHOW_ASCENT_DESCENT
void TFT_eSPI::loadMetrics(uint16_t gCount)
void TFT_eSPI::loadMetrics(void)
{
uint32_t headerPtr = 24;
uint32_t bitmapPtr = 24 + gCount * 28;
uint32_t bitmapPtr = headerPtr + gFont.gCount * 28;
#if defined (ESP32) && defined (CONFIG_SPIRAM_SUPPORT)
if ( psramFound() )
{
gUnicode = (uint16_t*)ps_malloc( gCount * 2); // Unicode 16 bit Basic Multilingual Plane (0-FFFF)
gHeight = (uint8_t*)ps_malloc( gCount ); // Height of glyph
gWidth = (uint8_t*)ps_malloc( gCount ); // Width of glyph
gxAdvance = (uint8_t*)ps_malloc( gCount ); // xAdvance - to move x cursor
gdY = (int16_t*)ps_malloc( gCount * 2); // offset from bitmap top edge from lowest point in any character
gdX = (int8_t*)ps_malloc( gCount ); // offset for bitmap left edge relative to cursor X
gBitmap = (uint32_t*)ps_malloc( gCount * 4); // seek pointer to glyph bitmap in the file
gUnicode = (uint16_t*)ps_malloc( gFont.gCount * 2); // Unicode 16 bit Basic Multilingual Plane (0-FFFF)
gHeight = (uint8_t*)ps_malloc( gFont.gCount ); // Height of glyph
gWidth = (uint8_t*)ps_malloc( gFont.gCount ); // Width of glyph
gxAdvance = (uint8_t*)ps_malloc( gFont.gCount ); // xAdvance - to move x cursor
gdY = (int16_t*)ps_malloc( gFont.gCount * 2); // offset from bitmap top edge from lowest point in any character
gdX = (int8_t*)ps_malloc( gFont.gCount ); // offset for bitmap left edge relative to cursor X
gBitmap = (uint32_t*)ps_malloc( gFont.gCount * 4); // seek pointer to glyph bitmap in the file
}
else
#endif
{
gUnicode = (uint16_t*)malloc( gCount * 2); // Unicode 16 bit Basic Multilingual Plane (0-FFFF)
gHeight = (uint8_t*)malloc( gCount ); // Height of glyph
gWidth = (uint8_t*)malloc( gCount ); // Width of glyph
gxAdvance = (uint8_t*)malloc( gCount ); // xAdvance - to move x cursor
gdY = (int16_t*)malloc( gCount * 2); // offset from bitmap top edge from lowest point in any character
gdX = (int8_t*)malloc( gCount ); // offset for bitmap left edge relative to cursor X
gBitmap = (uint32_t*)malloc( gCount * 4); // seek pointer to glyph bitmap in the file
gUnicode = (uint16_t*)malloc( gFont.gCount * 2); // Unicode 16 bit Basic Multilingual Plane (0-FFFF)
gHeight = (uint8_t*)malloc( gFont.gCount ); // Height of glyph
gWidth = (uint8_t*)malloc( gFont.gCount ); // Width of glyph
gxAdvance = (uint8_t*)malloc( gFont.gCount ); // xAdvance - to move x cursor
gdY = (int16_t*)malloc( gFont.gCount * 2); // offset from bitmap top edge from lowest point in any character
gdX = (int8_t*)malloc( gFont.gCount ); // offset for bitmap left edge relative to cursor X
gBitmap = (uint32_t*)malloc( gFont.gCount * 4); // seek pointer to glyph bitmap in the file
}
#ifdef SHOW_ASCENT_DESCENT
@ -161,9 +183,13 @@ void TFT_eSPI::loadMetrics(uint16_t gCount)
Serial.print("descent = "); Serial.println(gFont.descent);
#endif
#ifdef FONT_FS_AVAILABLE
if (fs_font) fontFile.seek(headerPtr, fs::SeekSet);
#endif
uint16_t gNum = 0;
fontFile.seek(headerPtr, fs::SeekSet);
while (gNum < gCount)
while (gNum < gFont.gCount)
{
gUnicode[gNum] = (uint16_t)readInt32(); // Unicode code point value
gHeight[gNum] = (uint8_t)readInt32(); // Height of glyph
@ -180,7 +206,7 @@ void TFT_eSPI::loadMetrics(uint16_t gCount)
// 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
// 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)
{
@ -210,8 +236,6 @@ void TFT_eSPI::loadMetrics(uint16_t gCount)
gBitmap[gNum] = bitmapPtr;
headerPtr += 28;
bitmapPtr += gWidth[gNum] * gHeight[gNum];
gNum++;
@ -272,132 +296,16 @@ void TFT_eSPI::unloadFont( void )
gBitmap = NULL;
}
if(fontFile) fontFile.close();
gFont.gArray = nullptr;
#ifdef FONT_FS_AVAILABLE
if (fs_font && fontFile) fontFile.close();
#endif
fontLoaded = false;
}
/***************************************************************************************
** Function name: decodeUTF8
** Description: Line buffer UTF-8 decoder with fall-back to extended ASCII
*************************************************************************************x*/
/* Function moved to TFT_eSPI.cpp
#define DECODE_UTF8
uint16_t TFT_eSPI::decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining)
{
byte c = buf[(*index)++];
//Serial.print("Byte from string = 0x"); Serial.println(c, HEX);
#ifdef DECODE_UTF8
// 7 bit Unicode
if ((c & 0x80) == 0x00) return c;
// 11 bit Unicode
if (((c & 0xE0) == 0xC0) && (remaining > 1))
return ((c & 0x1F)<<6) | (buf[(*index)++]&0x3F);
// 16 bit Unicode
if (((c & 0xF0) == 0xE0) && (remaining > 2))
{
c = ((c & 0x0F)<<12) | ((buf[(*index)++]&0x3F)<<6);
return c | ((buf[(*index)++]&0x3F));
}
// 21 bit Unicode not supported so fall-back to extended ASCII
// if ((c & 0xF8) == 0xF0) return c;
#endif
return c; // fall-back to extended ASCII
}
*/
/***************************************************************************************
** Function name: decodeUTF8
** Description: Serial UTF-8 decoder with fall-back to extended ASCII
*************************************************************************************x*/
/* Function moved to TFT_eSPI.cpp
uint16_t TFT_eSPI::decodeUTF8(uint8_t c)
{
#ifdef DECODE_UTF8
// 7 bit Unicode
if ((c & 0x80) == 0x00) {
decoderState = 0;
return (uint16_t)c;
}
if (decoderState == 0)
{
// 11 bit Unicode
if ((c & 0xE0) == 0xC0)
{
decoderBuffer = ((c & 0x1F)<<6);
decoderState = 1;
return 0;
}
// 16 bit Unicode
if ((c & 0xF0) == 0xE0)
{
decoderBuffer = ((c & 0x0F)<<12);
decoderState = 2;
return 0;
}
// 21 bit Unicode not supported so fall-back to extended ASCII
if ((c & 0xF8) == 0xF0) return (uint16_t)c;
}
else
{
if (decoderState == 2)
{
decoderBuffer |= ((c & 0x3F)<<6);
decoderState--;
return 0;
}
else
{
decoderBuffer |= (c & 0x3F);
decoderState = 0;
return decoderBuffer;
}
}
#endif
decoderState = 0;
return (uint16_t)c; // fall-back to extended ASCII
}
*/
/***************************************************************************************
** Function name: alphaBlend
** Description: Blend foreground and background and return new colour
*************************************************************************************x*/
uint16_t TFT_eSPI::alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc)
{
// For speed use fixed point maths and rounding to permit a power of 2 division
uint16_t fgR = ((fgc >> 10) & 0x3E) + 1;
uint16_t fgG = ((fgc >> 4) & 0x7E) + 1;
uint16_t fgB = ((fgc << 1) & 0x3E) + 1;
uint16_t bgR = ((bgc >> 10) & 0x3E) + 1;
uint16_t bgG = ((bgc >> 4) & 0x7E) + 1;
uint16_t bgB = ((bgc << 1) & 0x3E) + 1;
// Shift right 1 to drop rounding bit and shift right 8 to divide by 256
uint16_t r = (((fgR * alpha) + (bgR * (255 - alpha))) >> 9);
uint16_t g = (((fgG * alpha) + (bgG * (255 - alpha))) >> 9);
uint16_t b = (((fgB * alpha) + (bgB * (255 - alpha))) >> 9);
// Combine RGB565 colours into 16 bits
//return ((r&0x18) << 11) | ((g&0x30) << 5) | ((b&0x18) << 0); // 2 bit greyscale
//return ((r&0x1E) << 11) | ((g&0x3C) << 5) | ((b&0x1E) << 0); // 4 bit greyscale
return (r << 11) | (g << 5) | (b << 0);
}
/***************************************************************************************
** Function name: readInt32
** Description: Get a 32 bit integer from the font file
@ -405,10 +313,23 @@ uint16_t TFT_eSPI::alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc)
uint32_t TFT_eSPI::readInt32(void)
{
uint32_t val = 0;
val |= fontFile.read() << 24;
val |= fontFile.read() << 16;
val |= fontFile.read() << 8;
val |= fontFile.read();
#ifdef FONT_FS_AVAILABLE
if (fs_font) {
val = fontFile.read() << 24;
val |= fontFile.read() << 16;
val |= fontFile.read() << 8;
val |= fontFile.read();
}
else
#endif
{
val = pgm_read_byte(fontPtr++) << 24;
val |= pgm_read_byte(fontPtr++) << 16;
val |= pgm_read_byte(fontPtr++) << 8;
val |= pgm_read_byte(fontPtr++);
}
return val;
}
@ -438,17 +359,32 @@ bool TFT_eSPI::getUnicodeIndex(uint16_t unicode, uint16_t *index)
// Expects file to be open
void TFT_eSPI::drawGlyph(uint16_t code)
{
uint16_t fg = textcolor;
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 == 0x20) {
if (_fillbg) fillRect(bg_cursor_x, cursor_y, (cursor_x + gFont.spaceWidth) - bg_cursor_x, gFont.yAdvance, bg);
cursor_x += gFont.spaceWidth;
bg_cursor_x = cursor_x;
last_cursor_x = cursor_x;
return;
}
if (code == '\n') {
cursor_x = 0;
bg_cursor_x = 0;
last_cursor_x = 0;
cursor_y += gFont.yAdvance;
if (cursor_y >= _height) cursor_y = 0;
if (textwrapY && (cursor_y >= height())) cursor_y = 0;
return;
}
}
@ -456,84 +392,153 @@ void TFT_eSPI::drawGlyph(uint16_t code)
uint16_t gNum = 0;
bool found = getUnicodeIndex(code, &gNum);
uint16_t fg = textcolor;
uint16_t bg = textbgcolor;
if (found)
{
if (textwrapX && (cursor_x + gWidth[gNum] + gdX[gNum] > _width))
if (textwrapX && (cursor_x + gWidth[gNum] + gdX[gNum] > width()))
{
cursor_y += gFont.yAdvance;
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];
fontFile.seek(gBitmap[gNum], fs::SeekSet); // This is taking >30ms for a significant position shift
uint8_t* pbuffer = nullptr;
const uint8_t* gPtr = (const uint8_t*) gFont.gArray;
uint8_t pbuffer[gWidth[gNum]];
int16_t xs = 0;
uint32_t dl = 0;
#ifdef FONT_FS_AVAILABLE
if (fs_font)
{
fontFile.seek(gBitmap[gNum], fs::SeekSet);
pbuffer = (uint8_t*)malloc(gWidth[gNum]);
}
#endif
int16_t cy = cursor_y + gFont.maxAscent - gdY[gNum];
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;
startWrite(); // Avoid slow ESP32 transaction overhead for every pixel
for (int y = 0; y < gHeight[gNum]; y++)
{
if (spiffs)
{
fontFile.read(pbuffer, gWidth[gNum]);
//Serial.println("SPIFFS");
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];
// Could be negative
if (fillheight > 0) {
fillRect(bg_cursor_x, cursor_y, fillwidth, fillheight, textbgcolor);
}
}
else
{
endWrite(); // Release SPI for SD card transaction
fontFile.read(pbuffer, gWidth[gNum]);
startWrite(); // Re-start SPI for TFT transaction
//Serial.println("Not SPIFFS");
else {
// Could be negative
fillwidth = 0;
}
for (int x = 0; x < gWidth[gNum]; x++)
// 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
if (fs_font) {
if (spiffs)
{
fontFile.read(pbuffer, gWidth[gNum]);
//Serial.println("SPIFFS");
}
else
{
endWrite(); // Release SPI for SD card transaction
fontFile.read(pbuffer, gWidth[gNum]);
startWrite(); // Re-start SPI for TFT transaction
//Serial.println("Not SPIFFS");
}
}
#endif
for (int32_t x = 0; x < gWidth[gNum]; x++)
{
uint8_t pixel = pbuffer[x]; //<//
#ifdef FONT_FS_AVAILABLE
if (fs_font) pixel = pbuffer[x];
else
#endif
pixel = pgm_read_byte(gPtr + gBitmap[gNum] + x + gWidth[gNum] * y);
if (pixel)
{
if (bl) { drawFastHLine( bxs, y + cy, bl, bg); bl = 0; }
if (pixel != 0xFF)
{
if (dl) {
if (dl==1) drawPixel(xs, y + cy, fg);
else drawFastHLine( xs, y + cy, dl, fg);
dl = 0;
if (fl) {
if (fl==1) drawPixel(fxs, y + cy, fg);
else drawFastHLine( fxs, y + cy, fl, fg);
fl = 0;
}
if (getColor) bg = getColor(x + cx, y + cy);
drawPixel(x + cx, y + cy, alphaBlend(pixel, fg, bg));
}
else
{
if (dl==0) xs = x + cx;
dl++;
if (fl==0) fxs = x + cx;
fl++;
}
}
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);
cursor_x += gxAdvance[gNum];
endWrite();
}
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);
cursor_x += gFont.spaceWidth + 1;
}
bg_cursor_x = cursor_x;
last_cursor_x = cursor_x;
}
/***************************************************************************************
@ -544,12 +549,6 @@ void TFT_eSPI::showFont(uint32_t td)
{
if(!fontLoaded) return;
if(!fontFile)
{
fontLoaded = false;
return;
}
int16_t cursorX = width(); // Force start of new page to initialise cursor
int16_t cursorY = height();// for the first character
uint32_t timeDelay = 0; // No delay before first page
@ -575,12 +574,9 @@ void TFT_eSPI::showFont(uint32_t td)
setCursor(cursorX, cursorY);
drawGlyph(gUnicode[i]);
cursorX += gxAdvance[i];
//cursorX += printToSprite( cursorX, cursorY, i );
yield();
}
delay(timeDelay);
fillScreen(textbgcolor);
//fontFile.close();
}

View File

@ -3,14 +3,15 @@
public:
// These are for the new antialiased fonts
// These are for the new anti-aliased fonts
void loadFont(const uint8_t array[]);
#ifdef FONT_FS_AVAILABLE
void loadFont(String fontName, fs::FS &ffs);
#endif
void loadFont(String fontName, bool flash = true);
void unloadFont( void );
bool getUnicodeIndex(uint16_t unicode, uint16_t *index);
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc);
virtual void drawGlyph(uint16_t code);
void showFont(uint32_t td);
@ -18,16 +19,17 @@
// This is for the whole font
typedef struct
{
uint16_t gCount; // Total number of characters
uint16_t yAdvance; // Line advance
uint16_t spaceWidth; // Width of a space character
int16_t ascent; // Height of top of 'd' above baseline, other characters may be taller
int16_t descent; // Offset to bottom of 'p', other characters may have a larger descent
uint16_t maxAscent; // Maximum ascent found in font
uint16_t maxDescent; // Maximum descent found in font
const uint8_t* gArray; //array start pointer
uint16_t gCount; // Total number of characters
uint16_t yAdvance; // Line advance
uint16_t spaceWidth; // Width of a space character
int16_t ascent; // Height of top of 'd' above baseline, other characters may be taller
int16_t descent; // Offset to bottom of 'p', other characters may have a larger descent
uint16_t maxAscent; // Maximum ascent found in font
uint16_t maxDescent; // Maximum descent found in font
} fontMetrics;
fontMetrics gFont = { 0, 0, 0, 0, 0, 0, 0 };
fontMetrics gFont = { nullptr, 0, 0, 0, 0, 0, 0, 0 };
// These are for the metrics for each individual glyph (so we don't need to seek this in file and waste time)
uint16_t* gUnicode = NULL; //UTF-16 code, the codes are searched so do not need to be sequential
@ -39,12 +41,21 @@ fontMetrics gFont = { 0, 0, 0, 0, 0, 0, 0 };
uint32_t* gBitmap = NULL; //file pointer to greyscale bitmap
bool fontLoaded = false; // Flags when a anti-aliased font is loaded
#ifdef FONT_FS_AVAILABLE
fs::File fontFile;
fs::FS &fontFS = SPIFFS;
bool spiffs = true;
bool fs_font = false; // For ESP32/8266 use smooth font file or FLASH (PROGMEM) array
#else
bool fontFile = true;
#endif
private:
void loadMetrics(uint16_t gCount);
void loadMetrics(void);
uint32_t readInt32(void);
fs::FS &fontFS = SPIFFS;
bool spiffs = true;
uint8_t* fontPtr = nullptr;

File diff suppressed because it is too large Load Diff

View File

@ -9,90 +9,128 @@ class TFT_eSprite : public TFT_eSPI {
public:
TFT_eSprite(TFT_eSPI *tft);
explicit TFT_eSprite(TFT_eSPI *tft);
~TFT_eSprite(void);
// Create a sprite of width x height pixels, return a pointer to the RAM area
// Sketch can cast returned value to (uint16_t*) for 16 bit depth if needed
// RAM required is 1 byte per pixel for 8 bit colour depth, 2 bytes for 16 bit
void* createSprite(int16_t width, int16_t height, uint8_t frames = 1);
// RAM required is:
// - 1 bit per pixel for 1 bit colour depth
// - 1 nibble per pixel for 4 bit colour (with palette table)
// - 1 byte per pixel for 8 bit colour (332 RGB format)
// - 2 bytes per pixel for 16 bit color depth (565 RGB format)
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
void* getPointer(void);
// Returns true if sprite has been created
bool created(void);
// Delete the sprite to free up the RAM
void deleteSprite(void);
// Select the frame buffer for graphics
// Select the frame buffer for graphics write (for 2 colour ePaper and DMA toggle buffer)
// Returns a pointer to the Sprite frame buffer
void* frameBuffer(int8_t f);
// Set or get the colour depth to 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.
void* setColorDepth(int8_t b);
int8_t getColorDepth(void);
void setBitmapColor(uint16_t c, uint16_t b);
// Set the palette for a 4 bit depth sprite. Only the first 16 colours in the map are used.
void createPalette(uint16_t *palette = nullptr, uint8_t colors = 16); // Palette in RAM
void createPalette(const uint16_t *palette = nullptr, uint8_t colors = 16); // Palette in FLASH
// Set a single palette index to the given color
void setPaletteColor(uint8_t index, uint16_t color);
// Get the color at the given palette 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);
// 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
fillSprite(uint32_t color),
// Define a window to push 16 bit colour pixels into in a raster order
// Colours are converted to 8 bit if depth is set to 8
// Colours are converted to the set Sprite colour bit depth
setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1),
pushColor(uint32_t color),
pushColor(uint32_t color, uint16_t len),
// Push a pixel preformatted as a 8 or 16 bit colour (avoids conversion overhead)
// Push a color (aka singe pixel) to the sprite's set window area
pushColor(uint16_t color),
// Push len colors (pixels) to the sprite's set window area
pushColor(uint16_t color, uint32_t len),
// Push a pixel pre-formatted as a 1, 4, 8 or 16 bit colour (avoids conversion overhead)
writeColor(uint16_t color),
// 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
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
// 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
scroll(int16_t dx, int16_t dy = 0),
// Draw lines
drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color),
drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color),
drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color),
// Fill a rectangular area with a color (aka draw a filled rectangle)
fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
// Set the sprite text cursor position for print class (does not change the TFT screen cursor)
//setCursor(int16_t x, int16_t y);
// Set the rotation of the Sprite (for 1bpp Sprites only)
// Set the coordinate rotation of the Sprite (for 1bpp Sprites only)
// Note: this uses coordinate rotation and is primarily for ePaper which does not support
// CGRAM rotation (like TFT drivers do) within the displays internal hardware
void setRotation(uint8_t rotation);
uint8_t getRotation(void);
// Push a rotated copy of Sprite to TFT with optional transparent colour
bool pushRotated(int16_t angle, int32_t transp = -1);
bool pushRotated(int16_t angle, uint32_t transp = 0x00FFFFFF);
// Push a rotated copy of Sprite to another different Sprite with optional transparent colour
bool pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp = -1);
// Set and get the pivot point for this Sprite
void setPivot(int16_t x, int16_t y);
int16_t getPivotX(void),
getPivotY(void);
bool pushRotated(TFT_eSprite *spr, int16_t angle, uint32_t transp = 0x00FFFFFF);
// Get the bounding box for a rotated copy of this Sprite
void getRotatedBounds(float sina, float cosa, int16_t w, int16_t h, int16_t xp, int16_t yp,
int16_t *min_x, int16_t *min_y, int16_t *max_x, int16_t *max_y);
// 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);
// Get the destination Sprite bounding box for a rotated copy of this Sprite
bool getRotatedBounds(TFT_eSprite *spr, int16_t angle, int16_t *min_x, int16_t *min_y,
int16_t *max_x, int16_t *max_y);
// Bounding box support function
void getRotatedBounds(int16_t angle, int16_t w, int16_t h, int16_t xp, int16_t yp,
int16_t *min_x, int16_t *min_y, int16_t *max_x, int16_t *max_y);
// Read the colour of a pixel at x,y and return value in 565 format
uint16_t readPixel(int32_t x0, int32_t y0);
// Write an image (colour bitmap) to the sprite
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, const uint16_t *data);
// return the numerical value of the pixel at x,y (used when scrolling)
// 16bpp = colour, 8bpp = byte, 4bpp = colour index, 1bpp = 1 or 0
uint16_t readPixelValue(int32_t x, int32_t y);
// Swap the byte order for pushImage() - corrects different image endianness
void setSwapBytes(bool swap);
bool getSwapBytes(void);
// Write an image (colour bitmap) to the sprite.
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data, uint8_t sbpp = 0);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, const uint16_t *data);
// Push the sprite to the TFT screen, this fn calls pushImage() in the TFT class.
// Optionally a "transparent" colour can be defined, pixels of that colour will not be rendered
void pushSprite(int32_t x, int32_t y);
void pushSprite(int32_t x, int32_t y, uint16_t transparent);
// Push a windowed area of the sprite to the TFT at tx, ty
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.
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);
// Draw a single character in the selected 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);
@ -100,13 +138,14 @@ class TFT_eSprite : public TFT_eSPI {
int16_t width(void),
height(void);
// Used by print class to print text to cursor position
size_t write(uint8_t);
// Functions associated with anti-aliased fonts
// Draw a single unicode character using the loaded font
void drawGlyph(uint16_t code);
// Print string to sprite using loaded font at cursor position
void printToSprite(String string);
// Print char array to sprite using loaded font at cursor position
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);
private:
@ -116,31 +155,34 @@ class TFT_eSprite : public TFT_eSPI {
// Reserve memory for the Sprite and return a pointer
void* callocSprite(int16_t width, int16_t height, uint8_t frames = 1);
// Override the non-inlined TFT_eSPI functions
void begin_nin_write(void) { ; }
void end_nin_write(void) { ; }
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
uint8_t *_img8; // pointer to 8 bit sprite
uint8_t *_img8_1; // pointer to frame 1
uint8_t *_img8_2; // pointer to 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 *_img8_1; // pointer to frame 1
uint8_t *_img8_2; // pointer to frame 2
int16_t _xpivot; // x pivot point coordinate
int16_t _ypivot; // y pivot point coordinate
uint16_t *_colorMap; // color map pointer: 16 entries, used with 4 bit color map.
bool _created; // A Sprite has been created and memory reserved
int32_t _sinra; // Sine of rotation angle in fixed point
int32_t _cosra; // Cosine of rotation angle in fixed point
bool _created; // A Sprite has been created and memory reserved
bool _gFont = false;
// int32_t _icursor_x, _icursor_y;
uint8_t _rotation = 0;
int32_t _xs, _ys, _xe, _ye, _xptr, _yptr; // for setWindow
int32_t _sx, _sy; // x,y for scroll zone
uint32_t _sw, _sh; // w,h for scroll zone
uint32_t _scolor; // gap fill colour for scroll zone
boolean _iswapBytes; // Swap the byte order for Sprite pushImage()
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)
};

View File

@ -10,6 +10,44 @@
// See license in root directory.
/***************************************************************************************
** Function name: begin_touch_read_write - was spi_begin_touch
** Description: Start transaction and select touch controller
***************************************************************************************/
// The touch controller has a low SPI clock rate
inline void TFT_eSPI::begin_touch_read_write(void){
DMA_BUSY_CHECK;
CS_H; // Just in case it has been left low
#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS)
if (locked) {locked = false; spi.beginTransaction(SPISettings(SPI_TOUCH_FREQUENCY, MSBFIRST, SPI_MODE0));}
#else
spi.setFrequency(SPI_TOUCH_FREQUENCY);
#endif
SET_BUS_READ_MODE;
T_CS_L;
}
/***************************************************************************************
** Function name: end_touch_read_write - was spi_end_touch
** Description: End transaction and deselect touch controller
***************************************************************************************/
inline void TFT_eSPI::end_touch_read_write(void){
T_CS_H;
#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS)
if(!inTransaction) {if (!locked) {locked = true; spi.endTransaction();}}
#else
spi.setFrequency(SPI_FREQUENCY);
#endif
//SET_BUS_WRITE_MODE;
}
/***************************************************************************************
** Function name: Legacy - deprecated
** Description: Start/end transaction
***************************************************************************************/
void TFT_eSPI::spi_begin_touch() {begin_touch_read_write();}
void TFT_eSPI::spi_end_touch() { end_touch_read_write();}
/***************************************************************************************
** Function name: getTouchRaw
** Description: read raw touch position. Always returns true.
@ -17,7 +55,7 @@
uint8_t TFT_eSPI::getTouchRaw(uint16_t *x, uint16_t *y){
uint16_t tmp;
spi_begin_touch();
begin_touch_read_write();
// Start YP sample request for x position, read 4 times and keep last sample
spi.transfer(0xd0); // Start new YP conversion
@ -48,7 +86,7 @@ uint8_t TFT_eSPI::getTouchRaw(uint16_t *x, uint16_t *y){
*y = tmp;
spi_end_touch();
end_touch_read_write();
return true;
}
@ -59,7 +97,7 @@ uint8_t TFT_eSPI::getTouchRaw(uint16_t *x, uint16_t *y){
***************************************************************************************/
uint16_t TFT_eSPI::getTouchRawZ(void){
spi_begin_touch();
begin_touch_read_write();
// Z sample request
int16_t tz = 0xFFF;
@ -67,7 +105,9 @@ uint16_t TFT_eSPI::getTouchRawZ(void){
tz += spi.transfer16(0xc0) >> 3; // Read Z1 and start Z2 conversion
tz -= spi.transfer16(0x00) >> 3; // Read Z2
spi_end_touch();
end_touch_read_write();
if (tz == 4095) tz = 0;
return (uint16_t)tz;
}

View File

@ -9,7 +9,9 @@
// Convert raw x,y values to calibrated and correctly rotated screen coordinates
void convertRawXY(uint16_t *x, uint16_t *y);
// Get the screen touch coordinates, returns true if screen has been touched
// if the touch cordinates are off screen then x and y are not updated
// if the touch coordinates are off screen then x and y are not updated
// The returned value can be treated as a bool type, false or 0 means touch not detected
// In future the function may return an 8 "quality" (jitter) value.
uint8_t getTouch(uint16_t *x, uint16_t *y, uint16_t threshold = 600);
// Run screen calibration and test, report calibration values to the serial port
@ -18,9 +20,13 @@
void setTouch(uint16_t *data);
private:
// Handlers for the SPI settings and clock speed change
inline void spi_begin_touch() __attribute__((always_inline));
inline void spi_end_touch() __attribute__((always_inline));
// Legacy support only - deprecated TODO: delete
void spi_begin_touch();
void spi_end_touch();
// Handlers for the touch controller bus settings
inline void begin_touch_read_write() __attribute__((always_inline));
inline void end_touch_read_write() __attribute__((always_inline));
// Private function to validate a touch, allow settle time and reduce spurious coordinates
uint8_t validTouch(uint16_t *x, uint16_t *y, uint16_t threshold = 600);

View File

@ -1,6 +1,11 @@
// Font 2
#include <pgmspace.h>
// Comment out for £ sign for character 24
#define TFT_ESPI_FONT2_DOLLAR
// The grave ( ` ) diacritical mark will show as a degree ( ° ) symbol
// Comment out next line to return character 0x60 to the grave accent:
#define TFT_ESPI_GRAVE_IS_DEGREE
// Width has been increased by 1 pixel so pixel lengths are calculated correctly
// for the displayed string
@ -15,8 +20,11 @@ PROGMEM const unsigned char widtbl_f16[96] = // character width table
8, 4, 8, 8, 7, 10, 8, 8, // char 72 - 79
8, 8, 8, 8, 8, 8, 8, 10, // char 80 - 87
8, 8, 8, 4, 7, 4, 7, 9, // char 88 - 95
// 4, 7, 7, 7, 7, 7, 6, 7, // char 96 - 103 grave see lines 411-414
5, 7, 7, 7, 7, 7, 6, 7, // char 96 - 103 celcius
#ifdef TFT_ESPI_GRAVE_IS_DEGREE
5, 7, 7, 7, 7, 7, 6, 7, // char 96 - 103 0x60 is degree symbol
#else
4, 7, 7, 7, 7, 7, 6, 7, // char 96 - 103 0x60 is grave
#endif
7, 4, 5, 6, 4, 8, 7, 8, // char 104 - 111
7, 8, 6, 6, 5, 7, 8, 8, // char 112 - 119
6, 7, 7, 5, 3, 5, 8, 6 // char 120 - 127
@ -50,8 +58,13 @@ PROGMEM const unsigned char chr_f16_23[16] = // 1 unsigned char per row
PROGMEM const unsigned char chr_f16_24[16] = // 1 unsigned char per row
{
#ifdef TFT_ESPI_FONT2_DOLLAR
0x00, 0x00, 0x28, 0x38, 0x6C, 0xAA, 0xA8, 0x68, 0x3C, 0x2A, 0xAA, // row 1 - 11
0x6C, 0x38, 0x28, 0x00, 0x00 // row 12 - 16
#else // GBP sign
0x00, 0x00, 0x00, 0x3C, 0x42, 0x40, 0x40, 0x70, 0x40, 0x70, 0x40, // row 1 - 11
0x40, 0xFE, 0x00, 0x00, 0x00 // row 12 - 16
#endif
};
PROGMEM const unsigned char chr_f16_25[16] = // 1 unsigned char per row
@ -384,8 +397,8 @@ PROGMEM const unsigned char chr_f16_5B[16] = // 1 unsigned char per row
PROGMEM const unsigned char chr_f16_5C[16] = // 1 unsigned char per row
{
0x00, 0x00, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, // row 1 - 11
0x40, 0x80, 0x80, 0x00, 0x00 // row 12 - 16
0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, // row 1 - 11
0x08, 0x04, 0x04, 0x00, 0x00 // row 12 - 16
};
PROGMEM const unsigned char chr_f16_5D[16] = // 1 unsigned char per row
@ -408,10 +421,13 @@ PROGMEM const unsigned char chr_f16_5F[32] = // 1 unsigned chars per row
PROGMEM const unsigned char chr_f16_60[16] = // 1 unsigned char per row
{
// 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, // row 1 - 11 grave
// 0x00, 0x00, 0x00, 0x00, 0x00 // row 12 - 16
0x00, 0x00, 0x00, 0x60, 0x90, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00, // row 1 - 11 Celcius
0x00, 0x00, 0x00, 0x00, 0x00
#ifdef TFT_ESPI_GRAVE_IS_DEGREE
0x00, 0x00, 0x00, 0x60, 0x90, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00, // row 1 - 11 Degree symbol
0x00, 0x00, 0x00, 0x00, 0x00
#else
0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, // row 1 - 11 Grave accent
0x00, 0x00, 0x00, 0x00, 0x00 // row 12 - 16
#endif
};
PROGMEM const unsigned char chr_f16_61[16] = // 1 unsigned char per row

View File

@ -4,8 +4,8 @@
//
// This font contains 96 ASCII characters
#include <pgmspace.h>
// Use the #define below to select a GBP sign instead of a dollar sign
//#define FONT_4_GBP
PROGMEM const unsigned char widtbl_f32[96] = // character width table
{
@ -60,6 +60,8 @@ PROGMEM const unsigned char chr_f32_23[] =
0x7F, 0xD
};
#ifdef FONT_4_GBP
// GBP symbol
PROGMEM const unsigned char chr_f32_24[] =
{
0x1F, 0x85, 0x05, 0x89, 0x03, 0x82, 0x03, 0x82,
@ -69,6 +71,21 @@ PROGMEM const unsigned char chr_f32_24[] =
0x0A, 0x81, 0x0B, 0x86, 0x02, 0x80, 0x01, 0x8B,
0x01, 0x81, 0x04, 0x83, 0x63
};
#else
// Dollar symbol
PROGMEM const unsigned char chr_f32_24[] =
{
0x14, 0x80, 0x0A, 0x83, 0x07, 0x87, 0x04, 0x82,
0x01, 0x80, 0x00, 0x82, 0x03, 0x81, 0x02, 0x80,
0x01, 0x81, 0x03, 0x81, 0x02, 0x80, 0x01, 0x82,
0x02, 0x82, 0x01, 0x80, 0x08, 0x84, 0x09, 0x84,
0x0B, 0x83, 0x09, 0x84, 0x08, 0x80, 0x01, 0x82,
0x01, 0x82, 0x02, 0x80, 0x02, 0x81, 0x02, 0x81,
0x02, 0x80, 0x02, 0x81, 0x02, 0x83, 0x00, 0x80,
0x01, 0x82, 0x03, 0x88, 0x06, 0x84, 0x0A, 0x80,
0x67
};
#endif
PROGMEM const unsigned char chr_f32_25[] =
{

View File

@ -7,9 +7,6 @@
// All other characters print as a space
#include <pgmspace.h>
PROGMEM const unsigned char widtbl_f64[96] = // character width table
{
12, 12, 12, 12, 12, 12, 12, 12, // char 32 - 39

View File

@ -6,8 +6,6 @@
// This font only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : - .
// All other characters print as a space
#include <pgmspace.h>
PROGMEM const unsigned char widtbl_f72[96] = // character width table
{

View File

@ -7,8 +7,6 @@
// This font only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : - .
// All other characters print as a space
#include <pgmspace.h>
PROGMEM const unsigned char widtbl_f72[96] = // character width table
{

View File

@ -6,8 +6,6 @@
// This font only contains characters [space] 0 1 2 3 4 5 6 7 8 9 : . -
// All other characters print as a space
#include <pgmspace.h>
PROGMEM const unsigned char widtbl_f7s[96] = // character width table
{
@ -78,7 +76,7 @@ PROGMEM const unsigned char chr_f7s_31[] =
0x85, 0x19, 0x85, 0x19, 0x85, 0x19, 0x85, 0x19,
0x85, 0x19, 0x85, 0x19, 0x85, 0x19, 0x85, 0x19,
0x85, 0x19, 0x85, 0x19, 0x85, 0x19, 0x85, 0x19,
0x85, 0x1B, 0x83, 0x1D, 0x81, 0x1E, 0x80, 0x5D,
0x85, 0x1A, 0x84, 0x1C, 0x82, 0x1E, 0x80, 0x5D,
0x81, 0x1B, 0x83, 0x19, 0x85, 0x19, 0x85, 0x19,
0x85, 0x19, 0x85, 0x19, 0x85, 0x19, 0x85, 0x19,
0x85, 0x19, 0x85, 0x19, 0x85, 0x19, 0x85, 0x19,

View File

@ -1,4 +1,4 @@
// Adopted by Bodmer to support TFT_HX8357_Due library.
// Adopted by Bodmer to support TFT_eSPI library.
// Font structures for newer Adafruit_GFX (1.1 and later).
// Example fonts are included in 'Fonts' directory.
@ -25,6 +25,71 @@ typedef struct { // Data stored for FONT AS A WHOLE:
uint8_t yAdvance; // Newline distance (y axis)
} GFXfont;
// Original Adafruit_GFX "Free Fonts"
#include <Fonts/GFXFF/TomThumb.h> // TT1
#include <Fonts/GFXFF/FreeMono9pt7b.h> // FF1 or FM9
#include <Fonts/GFXFF/FreeMono12pt7b.h> // FF2 or FM12
#include <Fonts/GFXFF/FreeMono18pt7b.h> // FF3 or FM18
#include <Fonts/GFXFF/FreeMono24pt7b.h> // FF4 or FM24
#include <Fonts/GFXFF/FreeMonoOblique9pt7b.h> // FF5 or FMO9
#include <Fonts/GFXFF/FreeMonoOblique12pt7b.h> // FF6 or FMO12
#include <Fonts/GFXFF/FreeMonoOblique18pt7b.h> // FF7 or FMO18
#include <Fonts/GFXFF/FreeMonoOblique24pt7b.h> // FF8 or FMO24
#include <Fonts/GFXFF/FreeMonoBold9pt7b.h> // FF9 or FMB9
#include <Fonts/GFXFF/FreeMonoBold12pt7b.h> // FF10 or FMB12
#include <Fonts/GFXFF/FreeMonoBold18pt7b.h> // FF11 or FMB18
#include <Fonts/GFXFF/FreeMonoBold24pt7b.h> // FF12 or FMB24
#include <Fonts/GFXFF/FreeMonoBoldOblique9pt7b.h> // FF13 or FMBO9
#include <Fonts/GFXFF/FreeMonoBoldOblique12pt7b.h> // FF14 or FMBO12
#include <Fonts/GFXFF/FreeMonoBoldOblique18pt7b.h> // FF15 or FMBO18
#include <Fonts/GFXFF/FreeMonoBoldOblique24pt7b.h> // FF16 or FMBO24
// Sans serif fonts
#include <Fonts/GFXFF/FreeSans9pt7b.h> // FF17 or FSS9
#include <Fonts/GFXFF/FreeSans12pt7b.h> // FF18 or FSS12
#include <Fonts/GFXFF/FreeSans18pt7b.h> // FF19 or FSS18
#include <Fonts/GFXFF/FreeSans24pt7b.h> // FF20 or FSS24
#include <Fonts/GFXFF/FreeSansOblique9pt7b.h> // FF21 or FSSO9
#include <Fonts/GFXFF/FreeSansOblique12pt7b.h> // FF22 or FSSO12
#include <Fonts/GFXFF/FreeSansOblique18pt7b.h> // FF23 or FSSO18
#include <Fonts/GFXFF/FreeSansOblique24pt7b.h> // FF24 or FSSO24
#include <Fonts/GFXFF/FreeSansBold9pt7b.h> // FF25 or FSSB9
#include <Fonts/GFXFF/FreeSansBold12pt7b.h> // FF26 or FSSB12
#include <Fonts/GFXFF/FreeSansBold18pt7b.h> // FF27 or FSSB18
#include <Fonts/GFXFF/FreeSansBold24pt7b.h> // FF28 or FSSB24
#include <Fonts/GFXFF/FreeSansBoldOblique9pt7b.h> // FF29 or FSSBO9
#include <Fonts/GFXFF/FreeSansBoldOblique12pt7b.h> // FF30 or FSSBO12
#include <Fonts/GFXFF/FreeSansBoldOblique18pt7b.h> // FF31 or FSSBO18
#include <Fonts/GFXFF/FreeSansBoldOblique24pt7b.h> // FF32 or FSSBO24
// Serif fonts
#include <Fonts/GFXFF/FreeSerif9pt7b.h> // FF33 or FS9
#include <Fonts/GFXFF/FreeSerif12pt7b.h> // FF34 or FS12
#include <Fonts/GFXFF/FreeSerif18pt7b.h> // FF35 or FS18
#include <Fonts/GFXFF/FreeSerif24pt7b.h> // FF36 or FS24
#include <Fonts/GFXFF/FreeSerifItalic9pt7b.h> // FF37 or FSI9
#include <Fonts/GFXFF/FreeSerifItalic12pt7b.h> // FF38 or FSI12
#include <Fonts/GFXFF/FreeSerifItalic18pt7b.h> // FF39 or FSI18
#include <Fonts/GFXFF/FreeSerifItalic24pt7b.h> // FF40 or FSI24
#include <Fonts/GFXFF/FreeSerifBold9pt7b.h> // FF41 or FSB9
#include <Fonts/GFXFF/FreeSerifBold12pt7b.h> // FF42 or FSB12
#include <Fonts/GFXFF/FreeSerifBold18pt7b.h> // FF43 or FSB18
#include <Fonts/GFXFF/FreeSerifBold24pt7b.h> // FF44 or FSB24
#include <Fonts/GFXFF/FreeSerifBoldItalic9pt7b.h> // FF45 or FSBI9
#include <Fonts/GFXFF/FreeSerifBoldItalic12pt7b.h> // FF46 or FSBI12
#include <Fonts/GFXFF/FreeSerifBoldItalic18pt7b.h> // FF47 or FSBI18
#include <Fonts/GFXFF/FreeSerifBoldItalic24pt7b.h> // FF48 or FSBI24
#endif // LOAD_GFXFF
#endif // _GFXFONT_H_

View File

@ -3,8 +3,6 @@
#ifndef FONT5X7_H
#define FONT5X7_H
#include <pgmspace.h>
// Standard ASCII 5x7 font
static const unsigned char font[] PROGMEM = {

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

833
Processors/TFT_eSPI_ESP32.c Normal file
View File

@ -0,0 +1,833 @@
////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP32 processors //
////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
// 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 - VSPI port only, FPSI port only for S2
** 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);
#ifdef CONFIG_IDF_TARGET_ESP32
pinMatrixInAttach(TFT_MOSI, VSPIQ_IN_IDX, false);
#else // S2
pinMatrixInAttach(TFT_MOSI, FSPIQ_IN_IDX, false);
#endif
SET_BUS_READ_MODE;
}
/***************************************************************************************
** Function name: endSDA - VSPI port only, FPSI port only for S2
** 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);
#ifdef CONFIG_IDF_TARGET_ESP32
pinMatrixOutAttach(TFT_MOSI, VSPID_OUT_IDX, false, false);
#else // S2
pinMatrixOutAttach(TFT_MOSI, FSPID_OUT_IDX, false, false);
#endif
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;
*_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);
*_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]);
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]);
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;
}
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++);
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++);
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)
{
SET_PERI_REG_BITS(SPI_MOSI_DLEN_REG(SPI_PORT), SPI_USR_MOSI_DBITLEN, 479, SPI_USR_MOSI_DBITLEN_S);
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);
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)
{
SET_PERI_REG_BITS(SPI_MOSI_DLEN_REG(SPI_PORT), SPI_USR_MOSI_DBITLEN, (len * 24) - 1, SPI_USR_MOSI_DBITLEN_S);
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);
}
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 defined (SSD1963_DRIVER)
if ( ((color & 0xF800)>> 8) == ((color & 0x07E0)>> 3) && ((color & 0xF800)>> 8)== ((color & 0x001F)<< 3) )
#else
if ( (color >> 8) == (color & 0x00FF) )
#endif
{ 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
////////////////////////////////////////////////////////////////////////////////////////

590
Processors/TFT_eSPI_ESP32.h Normal file
View File

@ -0,0 +1,590 @@
////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP32 processors //
////////////////////////////////////////////////////
#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_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32)
#define CONFIG_IDF_TARGET_ESP32
#endif
// Fix IDF problems with ESP32C3
#if CONFIG_IDF_TARGET_ESP32C3
// Fix ESP32C3 IDF bug for missing definition
#ifndef REG_SPI_BASE
#define REG_SPI_BASE(i) (DR_REG_SPI1_BASE + (((i)>1) ? (((i)* 0x1000) + 0x20000) : (((~(i)) & 1)* 0x1000 )))
#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
// Fix ESP32C3 specific register reference
#define out_w1tc out_w1tc.val
#define out_w1ts out_w1ts.val
#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:
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
#else
#define SPI_PORT 2 //FSPI(ESP32 S2)
#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
// 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 = (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_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 = 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 = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = 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.out_w1tc = GPIO_OUT_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) >> 0)); WR_H
// 16 bit write with swapped bytes
#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 = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H
#endif
#endif
// Write 32 bits to TFT
#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 = GPIO_OUT_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) >> 8)); 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
#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 = GPIO_OUT_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) ((D) >> 8)); 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()
#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 = GPIO_OUT_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) >> 8)); WR_H; \
GPIO.out_w1tc = GPIO_OUT_CLR_MASK; GPIO.out_w1ts = 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
#define TFT_WRITE_BITS(D, B) *_spi_mosi_dlen = B-1; \
*_spi_w = D; \
*_spi_cmd = SPI_USR; \
while (*_spi_cmd & 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)
// Future option for transfer without wait
#define tft_Write_16N(C) *_spi_mosi_dlen = 16-1; \
*_spi_w = ((C)<<8 | (C)>>8); \
*_spi_cmd = SPI_USR;
// 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,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

@ -0,0 +1,447 @@
//////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP8266 processors //
//////////////////////////////////////////////////////
// Select the SPI port to use
// ESP8266 default (FLASH port also available via overlap mode)
SPIClass& spi = SPI;
// Buffer for SPI transmit byte padding and byte order manipulation
uint8_t spiBuffer[8] = {0,0,0,0,0,0,0,0};
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_SDA_READ) && !defined (TFT_PARALLEL_8_BIT)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: tft_Read_8
** Description: ESP8266 software SPI to read bidirectional SDA line
***************************************************************************************/
uint8_t TFT_eSPI::tft_Read_8(void)
{
uint8_t ret = 0;
uint32_t reg = 0;
for (uint8_t i = 0; i < 8; i++) { // read results
ret <<= 1;
SCLK_L;
if (digitalRead(TFT_MOSI)) ret |= 1;
SCLK_H;
}
return ret;
}
/***************************************************************************************
** Function name: beginSDA
** Description: Detach SPI from pin to permit software SPI
***************************************************************************************/
void TFT_eSPI::begin_SDA_Read(void)
{
#ifdef TFT_SPI_OVERLAP
// Reads in overlap mode not supported
#else
spi.end();
#endif
}
/***************************************************************************************
** Function name: endSDA
** Description: Attach SPI pins after software SPI
***************************************************************************************/
void TFT_eSPI::end_SDA_Read(void)
{
#ifdef TFT_SPI_OVERLAP
spi.pins(6, 7, 8, 0);
#else
spi.begin();
#endif
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // #if defined (TFT_SDA_READ)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: read byte - supports class functions
** Description: Parallel bus only - dummy function - not used
***************************************************************************************/
uint8_t TFT_eSPI::readByte(void)
{
uint8_t b = 0xAA;
return b;
}
////////////////////////////////////////////////////////////////////////////////////////
#if defined (RPI_WRITE_STROBE)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** 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;
while ( len >=64 ) {spi.writePattern(data, 64, 1); data += 64; len -= 64; }
if (len) spi.writePattern(data, len, 1);
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP32 or ESP8266 RPi TFT
** 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++;}
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP8266 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
uint8_t r = (color & 0xF800)>>8;
uint8_t g = (color & 0x07E0)>>3;
uint8_t b = (color & 0x001F)<<3;
// Concatenate 4 pixels into three 32 bit blocks
uint32_t r0 = r<<24 | b<<16 | g<<8 | r;
uint32_t r1 = g<<24 | r<<16 | b<<8 | g;
uint32_t r2 = b<<24 | g<<16 | r<<8 | b;
SPI1W0 = r0;
SPI1W1 = r1;
SPI1W2 = r2;
if (len > 4)
{
SPI1W3 = r0;
SPI1W4 = r1;
SPI1W5 = r2;
}
if (len > 8)
{
SPI1W6 = r0;
SPI1W7 = r1;
SPI1W8 = r2;
}
if (len > 12)
{
SPI1W9 = r0;
SPI1W10 = r1;
SPI1W11 = r2;
SPI1W12 = r0;
SPI1W13 = r1;
SPI1W14 = r2;
SPI1W15 = r0;
}
if (len > 20)
{
SPI1U1 = (503 << SPILMOSI);
while(len>20)
{
while(SPI1CMD & SPIBUSY) {}
SPI1CMD |= SPIBUSY;
len -= 21;
}
while(SPI1CMD & SPIBUSY) {}
}
if (len)
{
len = (len * 24) - 1;
SPI1U1 = (len << SPILMOSI);
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
}
/***************************************************************************************
** Function name: pushPixels - for ESP8266 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;
// Send groups of 4 concatenated pixels
if (len > 3) {
SPI1U1 = ((4 * 24 - 1) << SPILMOSI);
while (len > 3) {
uint8_t r[4];
uint8_t g[4];
uint8_t b[4];
if (!_swapBytes) {
// Split out the colours
for (uint16_t i = 0; i < 4; i++) {
uint16_t col = *data++;
r[i] = (col & 0xF8);
g[i] = (col & 0xE000)>>11 | (col & 0x07)<<5;
b[i] = (col & 0x1F00)>>5;
}
}
else {
for (uint16_t i = 0; i < 4; i++) {
uint16_t col = *data++;
r[i] = (col & 0xF800)>>8;
g[i] = (col & 0x07E0)>>3;
b[i] = (col & 0x001F)<<3;
}
}
uint32_t r0 = r[1]<<24 | b[0]<<16 | g[0]<<8 | r[0];
uint32_t r1 = g[2]<<24 | r[2]<<16 | b[1]<<8 | g[1];
uint32_t r2 = b[3]<<24 | g[3]<<16 | r[3]<<8 | b[2];
while(SPI1CMD & SPIBUSY) {}
SPI1W0 = r0;
SPI1W1 = r1;
SPI1W2 = r2;
SPI1CMD |= SPIBUSY;
len -= 4;
}
while(SPI1CMD & SPIBUSY) {}
}
// 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 ESP8266 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++;}
}
////////////////////////////////////////////////////////////////////////////////////////
#else
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP8266
** Description: Write a block of pixels of the same colour
***************************************************************************************/
//Clear screen test 76.8ms theoretical. 81.5ms TFT_eSPI, 967ms Adafruit_ILI9341
//Performance 26.15Mbps@26.66MHz, 39.04Mbps@40MHz, 75.4Mbps@80MHz SPI clock
//Efficiency:
// TFT_eSPI 98.06% 97.59% 94.24%
// Adafruit_GFX 19.62% 14.31% 7.94%
//
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
/*
while (len>1) { tft_Write_32(color<<16 | color); len-=2;}
if (len) tft_Write_16(color);
return;
//*/
uint16_t color16 = (color >> 8) | (color << 8);
uint32_t color32 = color16 | color16 << 16;
/*
while(len--) {
SPI1U1 = ((16-1) << SPILMOSI) | ((16-1) << SPILMISO);
SPI1W0 = color16;
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
return;
//*/
SPI1W0 = color32;
SPI1W1 = color32;
SPI1W2 = color32;
SPI1W3 = color32;
if (len > 8)
{
SPI1W4 = color32;
SPI1W5 = color32;
SPI1W6 = color32;
SPI1W7 = color32;
}
if (len > 16)
{
SPI1W8 = color32;
SPI1W9 = color32;
SPI1W10 = color32;
SPI1W11 = color32;
}
if (len > 24)
{
SPI1W12 = color32;
SPI1W13 = color32;
SPI1W14 = color32;
SPI1W15 = color32;
}
if (len > 31)
{
SPI1U1 = (511 << SPILMOSI);
while(len>31)
{
#if (defined (SPI_FREQUENCY) && (SPI_FREQUENCY == 80000000))
if(SPI1CMD & SPIBUSY) // added to sync with flag change
#endif
while(SPI1CMD & SPIBUSY) {}
SPI1CMD |= SPIBUSY;
len -= 32;
}
while(SPI1CMD & SPIBUSY) {}
}
if (len)
{
len = (len << 4) - 1;
SPI1U1 = (len << SPILMOSI);
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
}
/***************************************************************************************
** Function name: pushPixels - for ESP8266
** Description: Write a sequence of pixels
***************************************************************************************/
void TFT_eSPI::pushPixels(const void* data_in, uint32_t len){
if(_swapBytes) {
pushSwapBytePixels(data_in, len);
return;
}
uint16_t *data = (uint16_t*) data_in;
uint32_t color[8];
SPI1U1 = (255 << SPILMOSI) | (255 << SPILMISO);
while(len>15)
{
memcpy(color,data,32);
data+=16;
len -= 16;
// ESP8266 wait time here at 40MHz SPI is ~5.45us
while(SPI1CMD & SPIBUSY) {}
SPI1W0 = color[0];
SPI1W1 = color[1];
SPI1W2 = color[2];
SPI1W3 = color[3];
SPI1W4 = color[4];
SPI1W5 = color[5];
SPI1W6 = color[6];
SPI1W7 = color[7];
SPI1CMD |= SPIBUSY;
}
if(len)
{
uint32_t bits = (len*16-1); // bits left to shift - 1
memcpy(color,data,len<<1);
while(SPI1CMD & SPIBUSY) {}
SPI1U1 = (bits << SPILMOSI) | (bits << SPILMISO);
SPI1W0 = color[0];
SPI1W1 = color[1];
SPI1W2 = color[2];
SPI1W3 = color[3];
SPI1W4 = color[4];
SPI1W5 = color[5];
SPI1W6 = color[6];
SPI1W7 = color[7];
SPI1CMD |= SPIBUSY;
}
while(SPI1CMD & SPIBUSY) {}
}
/***************************************************************************************
** Function name: pushSwapBytePixels - for ESP8266
** 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;
//uint16_t* data = (uint16_t*)data_in;
uint32_t color[8];
SPI1U1 = (255 << SPILMOSI) | (255 << SPILMISO);
while(len>15)
{
uint32_t i = 0;
while(i<8) { color[i++] = DAT8TO32(data); data+=4; }
len -= 16;
// ESP8266 wait time here at 40MHz SPI is ~5.45us
while(SPI1CMD & SPIBUSY) {}
SPI1W0 = color[0];
SPI1W1 = color[1];
SPI1W2 = color[2];
SPI1W3 = color[3];
SPI1W4 = color[4];
SPI1W5 = color[5];
SPI1W6 = color[6];
SPI1W7 = color[7];
SPI1CMD |= SPIBUSY;
}
if(len)
{
uint32_t i = 0;
uint32_t bits = (len*16-1); // bits left to shift - 1
len = (len+1)>>1;
while(len--) { color[i++] = DAT8TO32(data); data+=4; }
while(SPI1CMD & SPIBUSY) {}
SPI1U1 = (bits << SPILMOSI) | (bits << SPILMISO);
SPI1W0 = color[0];
SPI1W1 = color[1];
SPI1W2 = color[2];
SPI1W3 = color[3];
SPI1W4 = color[4];
SPI1W5 = color[5];
SPI1W6 = color[6];
SPI1W7 = color[7];
SPI1CMD |= SPIBUSY;
}
while(SPI1CMD & SPIBUSY) {}
}
////////////////////////////////////////////////////////////////////////////////////////
#endif
////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,245 @@
//////////////////////////////////////////////////////
// TFT_eSPI driver functions for ESP8266 processors //
//////////////////////////////////////////////////////
#ifndef _TFT_eSPI_ESP8266H_
#define _TFT_eSPI_ESP8266H_
// Processor ID reported by getSetup()
#define PROCESSOR_ID 0x8266
// Include processor specific header
// None
// Processor specific code used by SPI bus transaction startWrite and endWrite functions
#define SET_BUS_WRITE_MODE SPI1U=SPI1U_WRITE
#define SET_BUS_READ_MODE SPI1U=SPI1U_READ
// Code to check if DMA is busy, used by SPI bus transaction transaction and endWrite functions
#define DMA_BUSY_CHECK // DMA not available, leave blank
// Initialise processor specific SPI functions, used by init()
#if (!defined (SUPPORT_TRANSACTIONS) && defined (ARDUINO_ARCH_ESP8266))
#define INIT_TFT_DATA_BUS \
spi.setBitOrder(MSBFIRST); \
spi.setDataMode(TFT_SPI_MODE); \
spi.setFrequency(SPI_FREQUENCY);
#else
#define INIT_TFT_DATA_BUS
#endif
// If smooth fonts are enabled the filing system may need to be loaded
#ifdef SMOOTH_FONT
// Call up the SPIFFS FLASH filing system for the anti-aliased fonts
#define FS_NO_GLOBALS
#include <FS.h>
#define FONT_FS_AVAILABLE
#endif
// Do not allow parallel mode for ESP8266
#ifdef ESP32_PARALLEL
#undef ESP32_PARALLEL
#endif
#ifdef TFT_PARALLEL_8_BIT
#undef TFT_PARALLEL_8_BIT
#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 (TFT_DC == 16)
#define DC_C digitalWrite(TFT_DC, LOW)
#define DC_D digitalWrite(TFT_DC, HIGH)
#else
#define DC_C GPOC=dcpinmask
#define DC_D GPOS=dcpinmask
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the CS (TFT chip select) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_CS
#define CS_L // No macro allocated so it generates no code
#define CS_H // No macro allocated so it generates no code
#else
#if (TFT_CS == 16)
#define CS_L digitalWrite(TFT_CS, LOW)
#define CS_H digitalWrite(TFT_CS, HIGH)
#else
#define CS_L GPOC=cspinmask
#define CS_H GPOS=cspinmask
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifdef TFT_WR
#define WR_L GPOC=wrpinmask
#define WR_H GPOS=wrpinmask
#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
#define T_CS_L digitalWrite(TOUCH_CS, LOW)
#define T_CS_H digitalWrite(TOUCH_CS, HIGH)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Make sure TFT_MISO is defined if not used to avoid an error message
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_MISO
#define TFT_MISO -1
#endif
////////////////////////////////////////////////////////////////////////////////////////
// ESP8266 specific SPI macros
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_SPI_OVERLAP)
#undef TFT_CS
#define SPI1U_WRITE (SPIUMOSI | SPIUSSE | SPIUCSSETUP | SPIUCSHOLD)
#define SPI1U_READ (SPIUMOSI | SPIUSSE | SPIUCSSETUP | SPIUCSHOLD | SPIUDUPLEX)
#else
#define SPI1U_WRITE (SPIUMOSI | SPIUSSE)
#define SPI1U_READ (SPIUMOSI | SPIUSSE | SPIUDUPLEX)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to a SPI ILI948x TFT
////////////////////////////////////////////////////////////////////////////////////////
#if 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)
// 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 address coordinates
#define tft_Write_32C(C,D) spi.write32((C)<<16 | (D))
// Write same value twice
#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)
// Command is 16 bits
#define CMD_BITS 16
// ESP8266 low level SPI writes for 8, 16 and 32 bit values
// to avoid the function call overhead
#define TFT_WRITE_BITS(D, B) \
SPI1U1 = ((B-1) << SPILMOSI); \
SPI1W0 = D; \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {}
#define tft_Write_8(C) TFT_WRITE_BITS((uint16_t)(C)<<8, CMD_BITS)
#define tft_Write_16(C) TFT_WRITE_BITS((C)>>8 | (C)<<8, 16)
#define tft_Write_16S(C) TFT_WRITE_BITS(C, 16)
#define tft_Write_32(C) TFT_WRITE_BITS(C, 32)
#define tft_Write_32C(C,D) SPI1U1 = ((64-1) << SPILMOSI); \
SPI1W0 = ((C)<<24) | (C); \
SPI1W1 = ((D)<<24) | (D); \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_32D(C) tft_Write_32C(C,C)
////////////////////////////////////////////////////////////////////////////////////////
// Macros for all other SPI displays
////////////////////////////////////////////////////////////////////////////////////////
#else
// Command is 8 bits
#define CMD_BITS 8
#define tft_Write_8(C) \
SPI1U1 = ((CMD_BITS-1) << SPILMOSI) | ((CMD_BITS-1) << SPILMISO); \
SPI1W0 = (C)<<(CMD_BITS - 8); \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_16(C) \
SPI1U1 = (15 << SPILMOSI) | (15 << SPILMISO); \
SPI1W0 = ((C)<<8 | (C)>>8); \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_16N(C) \
SPI1U1 = (15 << SPILMOSI) | (15 << SPILMISO); \
SPI1W0 = ((C)<<8 | (C)>>8); \
SPI1CMD |= SPIBUSY
#define tft_Write_16S(C) \
SPI1U1 = (15 << SPILMOSI) | (15 << SPILMISO); \
SPI1W0 = C; \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_32(C) \
SPI1U1 = (31 << SPILMOSI) | (31 << SPILMISO); \
SPI1W0 = C; \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_32C(C,D) \
SPI1U1 = (31 << SPILMOSI) | (31 << SPILMISO); \
SPI1W0 = ((D)>>8 | (D)<<8)<<16 | ((C)>>8 | (C)<<8); \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#define tft_Write_32D(C) \
SPI1U1 = (31 << SPILMOSI) | (31 << SPILMISO); \
SPI1W0 = ((C)>>8 | (C)<<8)<<16 | ((C)>>8 | (C)<<8); \
SPI1CMD |= SPIBUSY; \
while(SPI1CMD & SPIBUSY) {;}
#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_SDA_READ)
// Use a bit banged function call for ESP8266 and bi-directional SDA pin
#define TFT_eSPI_ENABLE_8_BIT_READ // Enable tft_Read_8(void);
#define SCLK_L GPOC=sclkpinmask
#define SCLK_H GPOS=sclkpinmask
#else
// 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,263 @@
////////////////////////////////////////////////////
// TFT_eSPI generic driver functions //
////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
// Global variables
////////////////////////////////////////////////////////////////////////////////////////
// Select the SPI port to use
#ifdef TFT_SPI_PORT
SPIClass& spi = TFT_SPI_PORT;
#else
SPIClass& spi = SPI;
#endif
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_SDA_READ) && !defined (TFT_PARALLEL_8_BIT)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: tft_Read_8
** Description: Bit bashed SPI to read bidirectional SDA line
***************************************************************************************/
uint8_t TFT_eSPI::tft_Read_8(void)
{
uint8_t ret = 0;
for (uint8_t i = 0; i < 8; i++) { // read results
ret <<= 1;
SCLK_L;
if (digitalRead(TFT_MOSI)) ret |= 1;
SCLK_H;
}
return ret;
}
/***************************************************************************************
** Function name: beginSDA
** Description: Detach SPI from pin to permit software SPI
***************************************************************************************/
void TFT_eSPI::begin_SDA_Read(void)
{
// Release configured SPI port for SDA read
spi.end();
}
/***************************************************************************************
** Function name: endSDA
** Description: Attach SPI pins after software SPI
***************************************************************************************/
void TFT_eSPI::end_SDA_Read(void)
{
// Configure SPI port ready for next TFT access
spi.begin();
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // #if defined (TFT_SDA_READ)
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_PARALLEL_8_BIT) // Code for generic (i.e. any) processor
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for generic processor and parallel display
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
while (len>1) {tft_Write_32D(color); len-=2;}
if (len) {tft_Write_16(color);}
}
/***************************************************************************************
** Function name: pushPixels - for gereric processor 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>1) {tft_Write_16(*data); data++; tft_Write_16(*data); data++; len -=2;}
if (len) {tft_Write_16(*data);}
return;
}
while (len>1) {tft_Write_16S(*data); data++; tft_Write_16S(*data); data++; len -=2;}
if (len) {tft_Write_16S(*data);}
}
/***************************************************************************************
** 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)
{
// mask is unused for generic processor
// Arduino native functions suited well to a generic driver
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);
return;
}
/***************************************************************************************
** Function name: GPIO direction control - supports class functions
** Description: Faster GPIO pin input/output switch
***************************************************************************************/
void TFT_eSPI::gpioMode(uint8_t gpio, uint8_t mode)
{
// No fast port based generic approach available
}
/***************************************************************************************
** Function name: read byte - supports class functions
** Description: Read a byte - parallel bus only
***************************************************************************************/
uint8_t TFT_eSPI::readByte(void)
{
uint8_t b = 0;
busDir(0, INPUT);
digitalWrite(TFT_RD, LOW);
b |= digitalRead(TFT_D0) << 0;
b |= digitalRead(TFT_D1) << 1;
b |= digitalRead(TFT_D2) << 2;
b |= digitalRead(TFT_D3) << 3;
b |= digitalRead(TFT_D4) << 4;
b |= digitalRead(TFT_D5) << 5;
b |= digitalRead(TFT_D6) << 6;
b |= digitalRead(TFT_D7) << 7;
digitalWrite(TFT_RD, HIGH);
busDir(0, OUTPUT);
return b;
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (RPI_WRITE_STROBE) // For RPi TFT with write strobe
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 or STM32 RPi TFT
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
if(len) { tft_Write_16(color); len--; }
while(len--) {WR_L; WR_H;}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 or STM32 RPi TFT
** 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_16S(*data); data++;}
else while ( len-- ) {tft_Write_16(*data); data++;}
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for STM32 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
uint8_t r = (color & 0xF800)>>8;
uint8_t g = (color & 0x07E0)>>3;
uint8_t b = (color & 0x001F)<<3;
while ( len-- ) {tft_Write_8(r); tft_Write_8(g); tft_Write_8(b);}
}
/***************************************************************************************
** Function name: pushPixels - for STM32 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;
if (_swapBytes) {
while ( len-- ) {
uint16_t color = *data >> 8 | *data << 8;
tft_Write_8((color & 0xF800)>>8);
tft_Write_8((color & 0x07E0)>>3);
tft_Write_8((color & 0x001F)<<3);
data++;
}
}
else {
while ( len-- ) {
tft_Write_8((*data & 0xF800)>>8);
tft_Write_8((*data & 0x07E0)>>3);
tft_Write_8((*data & 0x001F)<<3);
data++;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////
#else // Standard SPI 16 bit colour TFT
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for STM32
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
while ( len-- ) {tft_Write_16(color);}
}
/***************************************************************************************
** Function name: pushPixels - for STM32
** 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
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
// DMA FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////
// Placeholder for DMA functions
/*
Minimal function set to support DMA:
bool TFT_eSPI::initDMA(void)
void TFT_eSPI::deInitDMA(void)
bool TFT_eSPI::dmaBusy(void)
void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len)
void TFT_eSPI::pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t* image)
*/

View File

@ -0,0 +1,188 @@
////////////////////////////////////////////////////
// TFT_eSPI generic driver functions //
////////////////////////////////////////////////////
// This is a generic driver for Arduino boards, it supports SPI interface displays
// 8 bit parallel interface to TFT is not supported for generic processors
#ifndef _TFT_eSPI_GENERICH_
#define _TFT_eSPI_GENERICH_
// Processor ID reported by getSetup()
#define PROCESSOR_ID 0x0000
// Include processor specific header
// None
// Processor specific code used by SPI bus transaction startWrite and endWrite functions
#define SET_BUS_WRITE_MODE // Not used
#define SET_BUS_READ_MODE // Not used
// Code to check if DMA is busy, used by SPI bus transaction startWrite and endWrite functions
#define DMA_BUSY_CHECK // Not used so leave blank
// To be safe, SUPPORT_TRANSACTIONS is assumed mandatory
#if !defined (SUPPORT_TRANSACTIONS)
#define SUPPORT_TRANSACTIONS
#endif
// Initialise processor specific SPI functions, used by init()
#define INIT_TFT_DATA_BUS
// If smooth fonts are enabled the filing system may need to be loaded
#ifdef SMOOTH_FONT
// Call up the filing system for the anti-aliased fonts
//#define FS_NO_GLOBALS
//#include <FS.h>
#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
#define DC_C digitalWrite(TFT_DC, LOW)
#define DC_D digitalWrite(TFT_DC, HIGH)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the CS (TFT chip select) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_CS
#define CS_L // No macro allocated so it generates no code
#define CS_H // No macro allocated so it generates no code
#else
#define CS_L digitalWrite(TFT_CS, LOW)
#define CS_H digitalWrite(TFT_CS, HIGH)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Make sure TFT_RD is defined if not used to avoid an error message
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_RD
#define TFT_RD -1
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifdef TFT_WR
#define WR_L digitalWrite(TFT_WR, LOW)
#define WR_H digitalWrite(TFT_WR, HIGH)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the touch screen chip select pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#if !defined TOUCH_CS || (TOUCH_CS < 0)
#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
#define T_CS_L digitalWrite(TOUCH_CS, LOW)
#define T_CS_H digitalWrite(TOUCH_CS, HIGH)
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Make sure TFT_MISO is defined if not used to avoid an error message
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_MISO
#define TFT_MISO -1
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to a SPI ILI948x TFT
////////////////////////////////////////////////////////////////////////////////////////
#if 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)
// 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.transfer16((C)>>16); spi.transfer16((uint16_t)(C))
// Write two address coordinates
#define tft_Write_32C(C,D) spi.transfer16(C); spi.transfer16(D)
// Write same value twice
#define tft_Write_32D(C) spi.transfer16(C); spi.transfer16(C)
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to other displays
////////////////////////////////////////////////////////////////////////////////////////
#else
#if 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_16(C) spi.transfer((uint8_t)((C)>>8));spi.transfer((uint8_t)((C)>>0))
#define tft_Write_16S(C) spi.transfer((uint8_t)((C)>>0));spi.transfer((uint8_t)((C)>>8))
#define tft_Write_32(C) \
tft_Write_16((uint16_t) ((C)>>16)); \
tft_Write_16((uint16_t) ((C)>>0))
#define tft_Write_32C(C,D) \
spi.transfer(0); spi.transfer((C)>>8); \
spi.transfer(0); spi.transfer((C)>>0); \
spi.transfer(0); spi.transfer((D)>>8); \
spi.transfer(0); spi.transfer((D)>>0)
#define tft_Write_32D(C) \
spi.transfer(0); spi.transfer((C)>>8); \
spi.transfer(0); spi.transfer((C)>>0); \
spi.transfer(0); spi.transfer((C)>>8); \
spi.transfer(0); spi.transfer((C)>>0)
#else
#ifdef __AVR__ // AVR processors do not have 16 bit transfer
#define tft_Write_8(C) {SPDR=(C); while (!(SPSR&_BV(SPIF)));}
#define tft_Write_16(C) tft_Write_8((uint8_t)((C)>>8));tft_Write_8((uint8_t)((C)>>0))
#define tft_Write_16S(C) tft_Write_8((uint8_t)((C)>>0));tft_Write_8((uint8_t)((C)>>8))
#else
#define tft_Write_8(C) spi.transfer(C)
#define tft_Write_16(C) spi.transfer16(C)
#define tft_Write_16S(C) spi.transfer16(((C)>>8) | ((C)<<8))
#endif // AVR
#define tft_Write_32(C) \
tft_Write_16((uint16_t) ((C)>>16)); \
tft_Write_16((uint16_t) ((C)>>0))
#define tft_Write_32C(C,D) \
tft_Write_16((uint16_t) (C)); \
tft_Write_16((uint16_t) (D))
#define tft_Write_32D(C) \
tft_Write_16((uint16_t) (C)); \
tft_Write_16((uint16_t) (C))
#endif // RPI_DISPLAY_TYPE
#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_SDA_READ)
// Use a bit banged function call for STM32 and bi-directional SDA pin
#define TFT_eSPI_ENABLE_8_BIT_READ // Enable tft_Read_8(void);
#define SCLK_L digitalWrite(TFT_SCLK, LOW)
#define SCLK_H digitalWrite(TFT_SCLK, LOW)
#else
// Use a SPI read transfer
#define tft_Read_8() spi.transfer(0)
#endif
#endif // Header end

View File

@ -0,0 +1,738 @@
////////////////////////////////////////////////////
// TFT_eSPI generic driver functions //
////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
// Global variables
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (RP2040_PIO_INTERFACE) // SPI
// Select the SPI port and board package to use
#ifdef ARDUINO_ARCH_MBED
// Arduino RP2040 board package
MbedSPI spi = MbedSPI(TFT_MISO, TFT_MOSI, TFT_SCLK);
#else
// Community RP2040 board package by Earle Philhower
//SPIClass& spi = SPI; // will use board package default pins
SPIClassRP2040 spi = SPIClassRP2040(SPI_X, TFT_MISO, -1, TFT_SCLK, TFT_MOSI);
#endif
#else // PIO interface used (8 bit parallel or SPI)
#ifdef RP2040_PIO_SPI
#if defined (SPI_18BIT_DRIVER)
// SPI PIO code for 18 bit colour transmit
#include "pio_SPI_18bit.pio.h"
#else
// SPI PIO code for 16 bit colour transmit
#include "pio_SPI.pio.h"
#endif
#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
// Board package specific differences
#ifdef ARDUINO_ARCH_MBED
// Not supported at the moment
#error The Arduino RP2040 MBED board package is not supported when PIO is used. Use the community package by Earle Philhower.
#endif
// Community RP2040 board package by Earle Philhower
PIO tft_pio = pio0; // Code will try both pio's to find a free SM
int8_t pio_sm = 0; // pioinit will claim a free one
// Updated later with the loading offset of the PIO program.
uint32_t program_offset = 0;
// SM stalled mask
uint32_t pull_stall_mask = 0;
// SM jump instructions to change SM behaviour
uint32_t pio_instr_jmp8 = 0;
uint32_t pio_instr_fill = 0;
uint32_t pio_instr_addr = 0;
// SM "set" instructions to control DC control signal
uint32_t pio_instr_set_dc = 0;
uint32_t pio_instr_clr_dc = 0;
#endif
#ifdef RP2040_DMA
int32_t dma_tx_channel;
dma_channel_config dma_tx_config;
#endif
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_SDA_READ) && !defined (RP2040_PIO_INTERFACE)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: tft_Read_8
** Description: Bit bashed SPI to read bidirectional SDA line
***************************************************************************************/
uint8_t TFT_eSPI::tft_Read_8(void)
{
uint8_t ret = 0;
/*
for (uint8_t i = 0; i < 8; i++) { // read results
ret <<= 1;
SCLK_L;
if (digitalRead(TFT_MOSI)) ret |= 1;
SCLK_H;
}
*/
ret = spi.transfer(0x00);
return ret;
}
/***************************************************************************************
** Function name: beginSDA
** Description: Detach SPI from pin to permit software SPI
***************************************************************************************/
void TFT_eSPI::begin_SDA_Read(void)
{
// Release configured SPI port for SDA read
spi.end();
}
/***************************************************************************************
** Function name: endSDA
** Description: Attach SPI pins after software SPI
***************************************************************************************/
void TFT_eSPI::end_SDA_Read(void)
{
// Configure SPI port ready for next TFT access
spi.begin();
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // #if defined (TFT_SDA_READ)
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
#if defined (RP2040_PIO_INTERFACE)
////////////////////////////////////////////////////////////////////////////////////////
#ifdef RP2040_PIO_SPI
void pioinit(uint32_t clock_freq) {
// Find a free SM on one of the PIO's
tft_pio = pio0;
/*
pio_sm = pio_claim_unused_sm(tft_pio, false); // false means don't panic
// Try pio1 if SM not found
if (pio_sm < 0) {
tft_pio = pio1;
pio_sm = pio_claim_unused_sm(tft_pio, true); // panic this time if no SM is free
}
*/
// Find enough free space on one of the PIO's
tft_pio = pio0;
if (!pio_can_add_program(tft_pio, &tft_io_program)) {
tft_pio = pio1;
if (!pio_can_add_program(tft_pio, &tft_io_program)) {
Serial.println("No room for PIO program!");
return;
}
}
pio_sm = pio_claim_unused_sm(tft_pio, false);
// Load the PIO program
program_offset = pio_add_program(tft_pio, &tft_io_program);
// Associate pins with the PIO
pio_gpio_init(tft_pio, TFT_DC);
pio_gpio_init(tft_pio, TFT_SCLK);
pio_gpio_init(tft_pio, TFT_MOSI);
// Configure the pins to be outputs
pio_sm_set_consecutive_pindirs(tft_pio, pio_sm, TFT_DC, 1, true);
pio_sm_set_consecutive_pindirs(tft_pio, pio_sm, TFT_SCLK, 1, true);
pio_sm_set_consecutive_pindirs(tft_pio, pio_sm, TFT_MOSI, 1, true);
// Configure the state machine
pio_sm_config c = tft_io_program_get_default_config(program_offset);
sm_config_set_set_pins(&c, TFT_DC, 1);
// Define the single side-set pin
sm_config_set_sideset_pins(&c, TFT_SCLK);
// Define the pin used for data output
sm_config_set_out_pins(&c, TFT_MOSI, 1);
// Set clock divider, frequency is set up to 2% faster than specified, or next division down
uint16_t clock_div = 0.98 + clock_get_hz(clk_sys) / (clock_freq * 2.0); // 2 cycles per bit
sm_config_set_clkdiv(&c, clock_div);
// Make a single 8 words FIFO from the 4 words TX and RX FIFOs
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
// The OSR register shifts to the left, sm designed to send MS byte of a colour first, autopull off
sm_config_set_out_shift(&c, false, false, 0);
// Now load the configuration
pio_sm_init(tft_pio, pio_sm, program_offset + tft_io_offset_start_tx, &c);
// Start the state machine.
pio_sm_set_enabled(tft_pio, pio_sm, true);
// Create the pull stall bit mask
pull_stall_mask = 1u << (PIO_FDEBUG_TXSTALL_LSB + pio_sm);
// Create the assembler instruction for the jump to byte send routine
pio_instr_jmp8 = pio_encode_jmp(program_offset + tft_io_offset_start_8);
pio_instr_fill = pio_encode_jmp(program_offset + tft_io_offset_block_fill);
pio_instr_addr = pio_encode_jmp(program_offset + tft_io_offset_set_addr_window);
pio_instr_set_dc = pio_encode_set((pio_src_dest)0, 1);
pio_instr_clr_dc = pio_encode_set((pio_src_dest)0, 0);
}
#else // 8 or 16 bit parallel
void pioinit(uint16_t clock_div, uint16_t fract_div) {
// Find a free SM on one of the PIO's
tft_pio = pio0;
pio_sm = pio_claim_unused_sm(tft_pio, false); // false means don't panic
// Try pio1 if SM not found
if (pio_sm < 0) {
tft_pio = pio1;
pio_sm = pio_claim_unused_sm(tft_pio, true); // panic this time if no SM is free
}
/*
// Find enough free space on one of the PIO's
tft_pio = pio0;
if (!pio_can_add_program(tft_pio, &tft_io_program) {
tft_pio = pio1;
if (!pio_can_add_program(tft_pio, &tft_io_program) {
Serial.println("No room for PIO program!");
while(1) delay(100);
return;
}
}
*/
#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
program_offset = pio_add_program(tft_pio, &tft_io_program);
// Associate pins with the PIO
pio_gpio_init(tft_pio, TFT_DC);
pio_gpio_init(tft_pio, TFT_WR);
for (int i = 0; i < bits; i++) {
pio_gpio_init(tft_pio, TFT_D0 + i);
}
// 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_WR, 1, true);
pio_sm_set_consecutive_pindirs(tft_pio, pio_sm, TFT_D0, bits, true);
// Configure the state machine
pio_sm_config c = tft_io_program_get_default_config(program_offset);
// Define the set pin
sm_config_set_set_pins(&c, TFT_DC, 1);
// Define the single side-set pin
sm_config_set_sideset_pins(&c, TFT_WR);
// Define the consecutive pins that are used for data output
sm_config_set_out_pins(&c, TFT_D0, bits);
// Set clock divider and fractional divider
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
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
// The OSR register shifts to the left, sm designed to send MS byte of a colour first
sm_config_set_out_shift(&c, false, false, 0);
// Now load the configuration
pio_sm_init(tft_pio, pio_sm, program_offset + tft_io_offset_start_tx, &c);
// Start the state machine.
pio_sm_set_enabled(tft_pio, pio_sm, true);
// Create the pull stall bit mask
pull_stall_mask = 1u << (PIO_FDEBUG_TXSTALL_LSB + pio_sm);
// Create the instructions for the jumps to send routines
pio_instr_jmp8 = pio_encode_jmp(program_offset + tft_io_offset_start_8);
pio_instr_fill = pio_encode_jmp(program_offset + tft_io_offset_block_fill);
pio_instr_addr = pio_encode_jmp(program_offset + tft_io_offset_set_addr_window);
// Create the instructions to set and clear the DC signal
pio_instr_set_dc = pio_encode_set((pio_src_dest)0, 1);
pio_instr_clr_dc = pio_encode_set((pio_src_dest)0, 0);
}
#endif
/***************************************************************************************
** Function name: pushBlock - for generic processor and parallel display
** Description: Write a block of pixels of the same colour
***************************************************************************************/
#ifdef RP2040_PIO_PUSHBLOCK
// PIO handles pixel block fill writes
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) {
WAIT_FOR_STALL;
tft_pio->sm[pio_sm].instr = pio_instr_fill;
TX_FIFO = color;
TX_FIFO = --len; // Decrement first as PIO sends n+1
}
#endif
}
#else
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
while (len > 4) {
// 5 seems to be the optimum for maximum transfer rate
WAIT_FOR_FIFO_FREE(5);
TX_FIFO = color;
TX_FIFO = color;
TX_FIFO = color;
TX_FIFO = color;
TX_FIFO = color;
len -= 5;
}
if (len) {
// There could be a maximum of 4 words left to send
WAIT_FOR_FIFO_FREE(4);
while (len--) TX_FIFO = color;
}
}
#endif
/***************************************************************************************
** Function name: pushPixels - for generic processor and parallel display
** Description: Write a sequence of pixels
***************************************************************************************/
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;
// PIO sends MS byte first, so bytes are already swapped on transmit
if(_swapBytes) {
while (len > 4) {
WAIT_FOR_FIFO_FREE(5);
TX_FIFO = data[0];
TX_FIFO = data[1];
TX_FIFO = data[2];
TX_FIFO = data[3];
TX_FIFO = data[4];
data += 5;
len -= 5;
}
if (len) {
WAIT_FOR_FIFO_FREE(4);
while(len--) TX_FIFO = *data++;
}
}
else {
while (len > 4) {
WAIT_FOR_FIFO_FREE(5);
TX_FIFO = data[0] << 8 | data[0] >> 8;
TX_FIFO = data[1] << 8 | data[1] >> 8;
TX_FIFO = data[2] << 8 | data[2] >> 8;
TX_FIFO = data[3] << 8 | data[3] >> 8;
TX_FIFO = data[4] << 8 | data[4] >> 8;
data += 5;
len -= 5;
}
if (len) {
WAIT_FOR_FIFO_FREE(4);
while(len--) {
TX_FIFO = *data << 8 | *data >> 8;
data++;
}
}
}
#endif
}
/***************************************************************************************
** 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)
{
// Avoid warnings
mask = mask;
mode = mode;
/*
// mask is unused for generic processor
// Arduino native functions suited well to a generic driver
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: Faster GPIO pin input/output switch
***************************************************************************************/
void TFT_eSPI::gpioMode(uint8_t gpio, uint8_t mode)
{
// Avoid warnings
gpio = gpio;
mode = mode;
}
/***************************************************************************************
** Function name: read byte - supports class functions
** Description: Read a byte - parallel bus only - not supported yet
***************************************************************************************/
uint8_t TFT_eSPI::readByte(void)
{
uint8_t b = 0;
/*
busDir(0, INPUT);
digitalWrite(TFT_RD, LOW);
b |= digitalRead(TFT_D0) << 0;
b |= digitalRead(TFT_D1) << 1;
b |= digitalRead(TFT_D2) << 2;
b |= digitalRead(TFT_D3) << 3;
b |= digitalRead(TFT_D4) << 4;
b |= digitalRead(TFT_D5) << 5;
b |= digitalRead(TFT_D6) << 6;
b |= digitalRead(TFT_D7) << 7;
digitalWrite(TFT_RD, HIGH);
busDir(0, OUTPUT);
*/
return b;
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (RPI_WRITE_STROBE) // For RPi TFT with write strobe
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 or RP2040 RPi TFT
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
if(len) { tft_Write_16(color); len--; }
while(len--) {WR_L; WR_H;}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 or RP2040 RPi TFT
** 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_16S(*data); data++;}
else while ( len-- ) {tft_Write_16(*data); data++;}
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for RP2040 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)
{
uint16_t r = (color & 0xF800)>>8;
uint16_t g = (color & 0x07E0)>>3;
uint16_t b = (color & 0x001F)<<3;
// If more than 32 pixels then change to 16 bit transfers with concatenated pixels
if (len > 32) {
uint32_t rg = r<<8 | g;
uint32_t br = b<<8 | r;
uint32_t gb = g<<8 | b;
// Must wait before changing to 16 bit
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);
while ( len > 1 ) {
while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = rg;
while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = br;
while (!spi_is_writable(SPI_X)){}; spi_get_hw(SPI_X)->dr = gb;
len -= 2;
}
// Must wait before changing back to 8 bit
while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {};
hw_write_masked(&spi_get_hw(SPI_X)->cr0, (8 - 1) << SPI_SSPCR0_DSS_LSB, SPI_SSPCR0_DSS_BITS);
}
// Mop up the remaining pixels
while ( len-- ) {tft_Write_8N(r);tft_Write_8N(g);tft_Write_8N(b);}
}
/***************************************************************************************
** Function name: pushPixels - for RP2040 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;
if (_swapBytes) {
while ( len-- ) {
uint32_t col = *data++;
tft_Write_16(col);
}
}
else {
while ( len-- ) {
uint32_t col = *data++;
tft_Write_16S(col);
}
}
}
////////////////////////////////////////////////////////////////////////////////////////
#else // Standard SPI 16 bit colour TFT
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for RP2040
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len){
while(len--)
{
while (!spi_is_writable(SPI_X)){};
spi_get_hw(SPI_X)->dr = (uint32_t)color;
}
}
/***************************************************************************************
** Function name: pushPixels - for RP2040
** 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--)
{
while (!spi_is_writable(SPI_X)){};
spi_get_hw(SPI_X)->dr = (uint32_t)(*data++);
}
}
else
{
while(len--)
{
uint16_t color = *data++;
color = color >> 8 | color << 8;
while (!spi_is_writable(SPI_X)){};
spi_get_hw(SPI_X)->dr = (uint32_t)color;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // End of display interface specific functions
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
#ifdef RP2040_DMA // DMA functions for 16 bit SPI and 8/16 bit parallel displays
////////////////////////////////////////////////////////////////////////////////////////
/*
These are created in header file:
uint32_t dma_tx_channel;
dma_channel_config dma_tx_config;
*/
/***************************************************************************************
** Function name: dmaBusy
** Description: Check if DMA is busy
***************************************************************************************/
bool TFT_eSPI::dmaBusy(void) {
if (!DMA_Enabled) return false;
if (dma_channel_is_busy(dma_tx_channel)) return true;
#if !defined (RP2040_PIO_INTERFACE)
// For SPI must also wait for FIFO to flush and reset format
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);
#endif
return false;
}
/***************************************************************************************
** Function name: dmaWait
** Description: Wait until DMA is over (blocking!)
***************************************************************************************/
void TFT_eSPI::dmaWait(void)
{
while (dma_channel_is_busy(dma_tx_channel));
#if !defined (RP2040_PIO_INTERFACE)
// For SPI must also wait for FIFO to flush and reset format
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);
#endif
}
/***************************************************************************************
** Function name: pushPixelsDMA
** Description: Push pixels to TFT
***************************************************************************************/
void TFT_eSPI::pushPixelsDMA(uint16_t* image, uint32_t len)
{
if ((len == 0) || (!DMA_Enabled)) return;
dmaWait();
channel_config_set_bswap(&dma_tx_config, !_swapBytes);
#if !defined (RP2040_PIO_INTERFACE)
dma_channel_configure(dma_tx_channel, &dma_tx_config, &spi_get_hw(SPI_X)->dr, (uint16_t*)image, len, true);
#else
dma_channel_configure(dma_tx_channel, &dma_tx_config, &tft_pio->txf[pio_sm], (uint16_t*)image, len, true);
#endif
}
/***************************************************************************************
** Function name: pushImageDMA
** Description: Push image to a window
***************************************************************************************/
// This will clip to the viewport
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) ) {
for (int32_t yb = 0; yb < dh; yb++) {
memmove((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) {
memcpy(buffer, image, len*2);
}
dmaWait(); // In case we did not wait earlier
setAddrWindow(x, y, dw, dh);
channel_config_set_bswap(&dma_tx_config, !_swapBytes);
#if !defined (RP2040_PIO_INTERFACE)
dma_channel_configure(dma_tx_channel, &dma_tx_config, &spi_get_hw(SPI_X)->dr, (uint16_t*)buffer, len, true);
#else
dma_channel_configure(dma_tx_channel, &dma_tx_config, &tft_pio->txf[pio_sm], (uint16_t*)buffer, len, true);
#endif
}
/***************************************************************************************
** 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;
ctrl_cs = ctrl_cs; // stop unused parameter warning
dma_tx_channel = dma_claim_unused_channel(false);
if (dma_tx_channel < 0) return false;
dma_tx_config = dma_channel_get_default_config(dma_tx_channel);
channel_config_set_transfer_data_size(&dma_tx_config, DMA_SIZE_16);
#if !defined (RP2040_PIO_INTERFACE)
channel_config_set_dreq(&dma_tx_config, spi_get_index(SPI_X) ? DREQ_SPI1_TX : DREQ_SPI0_TX);
#else
channel_config_set_dreq(&dma_tx_config, pio_get_dreq(tft_pio, pio_sm, true));
#endif
DMA_Enabled = true;
return true;
}
/***************************************************************************************
** Function name: deInitDMA
** Description: Disconnect the DMA engine from SPI
***************************************************************************************/
void TFT_eSPI::deInitDMA(void)
{
if (!DMA_Enabled) return;
dma_channel_unclaim(dma_tx_channel);
DMA_Enabled = false;
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // End of DMA FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,494 @@
////////////////////////////////////////////////////
// TFT_eSPI generic driver functions //
////////////////////////////////////////////////////
// This is a generic driver for Arduino boards, it supports SPI interface displays
// 8 bit parallel interface to TFT is not supported for generic processors
#ifndef _TFT_eSPI_RP2040H_
#define _TFT_eSPI_RP2040H_
#ifndef ARDUINO_ARCH_MBED
#include <LittleFS.h>
#define FONT_FS_AVAILABLE
#define SPIFFS LittleFS
#endif
// Required for both the official and community board packages
#include "hardware/dma.h"
#include "hardware/pio.h"
#include "hardware/clocks.h"
// Processor ID reported by getSetup()
#define PROCESSOR_ID 0x2040
// Transactions always supported
#ifndef SUPPORT_TRANSACTIONS
#define SUPPORT_TRANSACTIONS
#endif
// Include processor specific header
// None
#if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RP2040_PIO_SPI)
#define RP2040_PIO_INTERFACE
#define RP2040_PIO_PUSHBLOCK
#endif
#if !defined (RP2040_PIO_INTERFACE)// SPI
// Use SPI0 as default if not defined
#ifndef TFT_SPI_PORT
#define TFT_SPI_PORT 0
#endif
#if (TFT_SPI_PORT == 0)
#define SPI_X spi0
#else
#define SPI_X spi1
#endif
// Processor specific code used by SPI bus transaction begin/end_tft_write functions
#define SET_BUS_WRITE_MODE spi_set_format(SPI_X, 8, (spi_cpol_t)(TFT_SPI_MODE >> 1), (spi_cpha_t)(TFT_SPI_MODE & 0x1), SPI_MSB_FIRST)
#define SET_BUS_READ_MODE // spi_set_format(SPI_X, 8, (spi_cpol_t)0, (spi_cpha_t)0, SPI_MSB_FIRST)
#else
// Processor specific code used by SPI bus transaction begin/end_tft_write functions
#define SET_BUS_WRITE_MODE
#define SET_BUS_READ_MODE
#endif
// Code to check if SPI or DMA is busy, used by SPI bus transaction startWrite and/or endWrite functions
#if !defined(SPI_18BIT_DRIVER)
#define RP2040_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
// 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 (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
#define SPI_BUSY_CHECK while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
while (spi_is_readable(SPI_X)) (void)spi_get_hw(SPI_X)->dr; \
spi_get_hw(SPI_X)->icr = SPI_SSPICR_RORIC_BITS
// To be safe, SUPPORT_TRANSACTIONS is assumed mandatory
#if !defined (SUPPORT_TRANSACTIONS)
#define SUPPORT_TRANSACTIONS
#endif
#else
// Different controllers have different minimum write cycle periods, so the PIO clock is changed accordingly
// The PIO clock is a division of the CPU clock so scales when the processor is overclocked
// PIO write frequency = (CPU clock/(4 * RP2040_PIO_CLK_DIV))
// The write cycle periods below assume a 125MHz CPU clock speed
#if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT)
#if defined (RP2040_PIO_CLK_DIV)
#if (RP2040_PIO_CLK_DIV > 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
// Initialise TFT data bus
#if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT)
#define INIT_TFT_DATA_BUS pioinit(DIV_UNITS, DIV_FRACT);
#elif defined (RP2040_PIO_SPI)
#define INIT_TFT_DATA_BUS pioinit(SPI_FREQUENCY);
#endif
#define SPI_BUSY_CHECK
// Set the state machine clock divider (from integer and fractional parts - 16:8)
#define PARALLEL_INIT_TFT_DATA_BUS // Not used
#endif
// If smooth fonts are enabled the filing system may need to be loaded
#if defined (SMOOTH_FONT) && !defined (ARDUINO_ARCH_MBED)
// Call up the filing system for the anti-aliased fonts
//#define FS_NO_GLOBALS
#include <FS.h>
#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 (RP2040_PIO_INTERFACE)// SPI
//#define DC_C sio_hw->gpio_clr = (1ul << TFT_DC)
//#define DC_D sio_hw->gpio_set = (1ul << TFT_DC)
#if defined (RPI_DISPLAY_TYPE) && !defined (MHS_DISPLAY_TYPE)
#define DC_C digitalWrite(TFT_DC, LOW);
#define DC_D digitalWrite(TFT_DC, HIGH);
#else
#define DC_C sio_hw->gpio_clr = (1ul << TFT_DC)
#define DC_D sio_hw->gpio_set = (1ul << TFT_DC)
#endif
#else
// PIO takes control of TFT_DC
// Must wait for data to flush through before changing DC line
#define DC_C WAIT_FOR_STALL; \
tft_pio->sm[pio_sm].instr = pio_instr_clr_dc
// Flush has happened before this and mode changed back to 16 bit
#define DC_D tft_pio->sm[pio_sm].instr = pio_instr_set_dc
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the CS (TFT chip select) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_CS
#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 (RP2040_PIO_INTERFACE) // SPI
#if defined (RPI_DISPLAY_TYPE) && !defined (MHS_DISPLAY_TYPE)
#define CS_L digitalWrite(TFT_CS, LOW);
#define CS_H digitalWrite(TFT_CS, HIGH);
#else
#define CS_L sio_hw->gpio_clr = (1ul << TFT_CS)
#define CS_H sio_hw->gpio_set = (1ul << TFT_CS)
#endif
#else // PIO interface display
#define CS_L sio_hw->gpio_clr = (1ul << TFT_CS)
#define CS_H WAIT_FOR_STALL; sio_hw->gpio_set = (1ul << TFT_CS)
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Make sure TFT_RD is defined if not used to avoid an error message
////////////////////////////////////////////////////////////////////////////////////////
// At the moment read is not supported for parallel mode, tie TFT signal high
#ifdef TFT_RD
#if (TFT_RD >= 0)
#define RD_L sio_hw->gpio_clr = (1ul << TFT_RD)
//#define RD_L digitalWrite(TFT_WR, LOW)
#define RD_H sio_hw->gpio_set = (1ul << 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
////////////////////////////////////////////////////////////////////////////////////////
// Define the WR (TFT Write) pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (TFT_PARALLEL_8_BIT) && !defined (TFT_PARALLEL_16_BIT) // SPI
#ifdef TFT_WR
#define WR_L digitalWrite(TFT_WR, LOW)
#define WR_H digitalWrite(TFT_WR, HIGH)
#endif
#else
// The PIO manages the write line
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Define the touch screen chip select pin drive code
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (RP2040_PIO_INTERFACE)// SPI
#if !defined TOUCH_CS || (TOUCH_CS < 0)
#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
#define T_CS_L digitalWrite(TOUCH_CS, LOW)
#define T_CS_H digitalWrite(TOUCH_CS, HIGH)
#endif
#else
#ifdef TOUCH_CS
#error Touch screen not supported in parallel or SPI PIO mode, use a separate library.
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Make sure TFT_MISO is defined if not used to avoid an error message
////////////////////////////////////////////////////////////////////////////////////////
#ifndef TFT_MISO
#define TFT_MISO -1
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to a SPI ILI948x TFT
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (RP2040_PIO_INTERFACE) // SPI
#if defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
// Write 8 bits to TFT
#define tft_Write_8(C) spi_get_hw(SPI_X)->dr = (uint32_t)(C); \
while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {}; \
//#define tft_Write_8(C) spi.transfer(C);
#define tft_Write_8N(B) while (!spi_is_writable(SPI_X)){}; \
spi_get_hw(SPI_X)->dr = (uint8_t)(B)
// Convert 16 bit colour to 18 bit and write in 3 bytes
#define tft_Write_16(C) tft_Write_8N(((C) & 0xF800)>>8); \
tft_Write_8N(((C) & 0x07E0)>>3); \
tft_Write_8N(((C) & 0x001F)<<3)
// Convert 16 bit colour to 18 bit and write in 3 bytes
#define tft_Write_16N(C) tft_Write_8N(((C) & 0xF800)>>8); \
tft_Write_8N(((C) & 0x07E0)>>3); \
tft_Write_8N(((C) & 0x001F)<<3)
// Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes
#define tft_Write_16S(C) tft_Write_8N((C) & 0xF8); \
tft_Write_8N(((C) & 0xE000)>>11 | ((C) & 0x07)<<5); \
tft_Write_8N(((C) & 0x1F00)>>5)
// Write 32 bits to TFT
#define tft_Write_32(C) tft_Write_8N(C>>24); \
tft_Write_8N(C>>16); \
tft_Write_8N(C>>8); \
tft_Write_8N(C)
// Write two address coordinates
#define tft_Write_32C(C,D) tft_Write_8N(C>>8); \
tft_Write_8N(C); \
tft_Write_8N(D>>8); \
tft_Write_8N(D)
// Write same value twice
#define tft_Write_32D(C) tft_Write_8N(C>>8); \
tft_Write_8N(C); \
tft_Write_8N(C>>8); \
tft_Write_8N(C)
////////////////////////////////////////////////////////////////////////////////////////
// Macros to write commands/pixel colour data to other displays
////////////////////////////////////////////////////////////////////////////////////////
#else
#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_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_16S(C) spi.transfer((uint8_t)((C)>>0));spi.transfer((uint8_t)((C)>>8))
#define tft_Write_32(C) \
tft_Write_16((uint16_t) ((C)>>16)); \
tft_Write_16((uint16_t) ((C)>>0))
#define tft_Write_32C(C,D) \
spi.transfer(0); spi.transfer((C)>>8); \
spi.transfer(0); spi.transfer((C)>>0); \
spi.transfer(0); spi.transfer((D)>>8); \
spi.transfer(0); spi.transfer((D)>>0)
#define tft_Write_32D(C) \
spi.transfer(0); spi.transfer((C)>>8); \
spi.transfer(0); spi.transfer((C)>>0); \
spi.transfer(0); spi.transfer((C)>>8); \
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
// This swaps to 8 bit mode, then back to 16 bit mode
#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, (8 - 1) << SPI_SSPCR0_DSS_LSB, SPI_SSPCR0_DSS_BITS); \
spi_get_hw(SPI_X)->dr = (uint32_t)(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)
// 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)
#endif // RPI_DISPLAY_TYPE
#endif
#else // Parallel 8 bit or PIO SPI
// Wait for the PIO to stall (SM pull request finds no data in TX FIFO)
// This is used to detect when the SM is idle and hence ready for a jump instruction
#define WAIT_FOR_STALL tft_pio->fdebug = pull_stall_mask; while (!(tft_pio->fdebug & pull_stall_mask))
// Wait until at least "S" locations free
#define WAIT_FOR_FIFO_FREE(S) while (((tft_pio->flevel >> (pio_sm * 8)) & 0x000F) > (8-S)){}
// Wait until at least 5 locations free
#define WAIT_FOR_FIFO_5_FREE while ((tft_pio->flevel) & (0x000c << (pio_sm * 8))){}
// Wait until at least 1 location free
#define WAIT_FOR_FIFO_1_FREE while ((tft_pio->flevel) & (0x0008 << (pio_sm * 8))){}
// Wait for FIFO to empty (use before swapping to 8 bits)
#define WAIT_FOR_FIFO_EMPTY while(!(tft_pio->fstat & (1u << (PIO_FSTAT_TXEMPTY_LSB + pio_sm))))
// The write register of the TX FIFO.
#define TX_FIFO tft_pio->txf[pio_sm]
// Temporary - to be deleted
#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
// Have already waited for pio stalled (last data write complete) when DC switched to command mode
// The wait for stall allows DC to be changed immediately afterwards
#define tft_Write_8(C) tft_pio->sm[pio_sm].instr = pio_instr_jmp8; \
TX_FIFO = (C); \
WAIT_FOR_STALL
// Used to send last byte for 32 bit macros below since PIO sends 24 bits
#define tft_Write_8L(C) WAIT_FOR_STALL; \
tft_pio->sm[pio_sm].instr = pio_instr_jmp8; \
TX_FIFO = (C)
// Note: the following macros do not wait for the end of transmission
#define tft_Write_16(C) WAIT_FOR_FIFO_FREE(1); TX_FIFO = ((((uint32_t)(C) & 0xF800)<<8) | (((C) & 0x07E0)<<5) | (((C) & 0x001F)<<3))
#define tft_Write_16N(C) WAIT_FOR_FIFO_FREE(1); TX_FIFO = ((((uint32_t)(C) & 0xF800)<<8) | (((C) & 0x07E0)<<5) | (((C) & 0x001F)<<3))
#define tft_Write_16S(C) WAIT_FOR_FIFO_FREE(1); TX_FIFO = ((((uint32_t)(C) & 0xF8) << 16) | (((C) & 0xE000)>>3) | (((C) & 0x07)<<13) | (((C) & 0x1F00)>>5))
#define tft_Write_32(C) WAIT_FOR_FIFO_FREE(2); TX_FIFO = ((C)>>8); WAIT_FOR_STALL; tft_Write_8(C)
#define tft_Write_32C(C,D) WAIT_FOR_FIFO_FREE(2); TX_FIFO = (((C)<<8) | ((D)>>8)); tft_Write_8L(D)
#define tft_Write_32D(C) WAIT_FOR_FIFO_FREE(2); TX_FIFO = (((C)<<8) | ((C)>>8)); tft_Write_8L(C)
#else // 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
#define tft_Write_16(C) WAIT_FOR_FIFO_FREE(1); TX_FIFO = (C)
#define tft_Write_16N(C) WAIT_FOR_FIFO_FREE(1); TX_FIFO = (C)
#define tft_Write_16S(C) WAIT_FOR_FIFO_FREE(1); TX_FIFO = ((C)<<8) | ((C)>>8)
#define tft_Write_32(C) WAIT_FOR_FIFO_FREE(2); TX_FIFO = ((C)>>16); TX_FIFO = (C)
#define tft_Write_32C(C,D) WAIT_FOR_FIFO_FREE(2); TX_FIFO = (C); TX_FIFO = (D)
#define tft_Write_32D(C) WAIT_FOR_FIFO_FREE(2); TX_FIFO = (C); TX_FIFO = (C)
#endif
#endif
#ifndef tft_Write_16N
#define tft_Write_16N tft_Write_16
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Macros to read from display using SPI or software SPI
////////////////////////////////////////////////////////////////////////////////////////
#if !defined (RP2040_PIO_INTERFACE)// SPI
#if defined (TFT_SDA_READ)
// Use a bit banged function call for STM32 and bi-directional SDA pin
#define TFT_eSPI_ENABLE_8_BIT_READ // Enable tft_Read_8(void);
#define SCLK_L digitalWrite(TFT_SCLK, LOW)
#define SCLK_H digitalWrite(TFT_SCLK, LOW)
#else
// Use a SPI read transfer
#define tft_Read_8() spi.transfer(0)
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////////
// Temporary to keep the "Arduino Mbed OS RP2040 Boards" support package happy
////////////////////////////////////////////////////////////////////////////////////////
#if defined(ARDUINO_ARCH_RP2040)
#define ltoa itoa
#endif
#endif // Header end

675
Processors/TFT_eSPI_STM32.c Normal file
View File

@ -0,0 +1,675 @@
////////////////////////////////////////////////////
// TFT_eSPI Driver functions for STM32 processors //
////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
// Global variables
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_PARALLEL_8_BIT)
// No globals
#else
// Use STM32 default SPI port
#if !defined (TFT_MOSI) || !defined (TFT_MISO) || !defined (TFT_SCLK)
SPIClass& spi = SPI;
#else
SPIClass spi(TFT_MOSI, TFT_MISO, TFT_SCLK);
#endif
// SPI HAL peripheral handle
SPI_HandleTypeDef spiHal;
#endif
#ifdef STM32_DMA
// DMA HAL handle
DMA_HandleTypeDef dmaHal;
#endif
// Buffer for SPI transmit byte padding and byte order manipulation
uint8_t spiBuffer[8];
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_SDA_READ) && !defined (TFT_PARALLEL_8_BIT)
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************############# UNTESTED ###################
** Function name: tft_Read_8
** Description: STM32 software SPI to read bidirectional SDA line
***************************************************************************************/
uint8_t TFT_eSPI::tft_Read_8(void)
{
uint8_t ret = 0;
uint32_t reg = 0;
for (uint8_t i = 0; i < 8; i++) { // read results
ret <<= 1;
SCLK_L;
if (digitalRead(TFT_MOSI)) ret |= 1;
SCLK_H;
}
return ret;
}
/***************************************************************************************############# UNTESTED ###################
** Function name: beginSDA
** Description: Detach SPI from pin to permit software SPI
***************************************************************************************/
void TFT_eSPI::begin_SDA_Read(void)
{
// Release configured SPI port for SDA read
spi.end();// Code missing here! <<<<<<<<<<<<<<Missing code<<<<<<<<<<<<<<<<<
}
/***************************************************************************************############# UNTESTED ###################
** Function name: endSDA
** Description: Attach SPI pins after software SPI
***************************************************************************************/
void TFT_eSPI::end_SDA_Read(void)
{
// Configure SPI port ready for next TFT access
spi.begin();// Code missing here! <<<<<<<<<<<<<<Missing code<<<<<<<<<<<<<<<<<
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // #if defined (TFT_SDA_READ)
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
#if defined (TFT_PARALLEL_8_BIT) // Code for STM32 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){
// Loop unrolling improves speed dramatically graphics test 0.634s => 0.374s
while (len>31) {
#if !defined (SSD1963_DRIVER)
// 32D macro writes 16 bits twice
tft_Write_32D(color); tft_Write_32D(color);
tft_Write_32D(color); tft_Write_32D(color);
tft_Write_32D(color); tft_Write_32D(color);
tft_Write_32D(color); tft_Write_32D(color);
tft_Write_32D(color); tft_Write_32D(color);
tft_Write_32D(color); tft_Write_32D(color);
tft_Write_32D(color); tft_Write_32D(color);
tft_Write_32D(color); tft_Write_32D(color);
#else
tft_Write_16(color); tft_Write_16(color); tft_Write_16(color); tft_Write_16(color);
tft_Write_16(color); tft_Write_16(color); tft_Write_16(color); tft_Write_16(color);
tft_Write_16(color); tft_Write_16(color); tft_Write_16(color); tft_Write_16(color);
tft_Write_16(color); tft_Write_16(color); tft_Write_16(color); tft_Write_16(color);
tft_Write_16(color); tft_Write_16(color); tft_Write_16(color); tft_Write_16(color);
tft_Write_16(color); tft_Write_16(color); tft_Write_16(color); tft_Write_16(color);
tft_Write_16(color); tft_Write_16(color); tft_Write_16(color); tft_Write_16(color);
tft_Write_16(color); tft_Write_16(color); tft_Write_16(color); tft_Write_16(color);
#endif
len-=32;
}
while (len>7) {
#if !defined (SSD1963_DRIVER)
tft_Write_32D(color); tft_Write_32D(color);
tft_Write_32D(color); tft_Write_32D(color);
#else
tft_Write_16(color); tft_Write_16(color); tft_Write_16(color); tft_Write_16(color);
tft_Write_16(color); tft_Write_16(color); tft_Write_16(color); tft_Write_16(color);
#endif
len-=8;
}
while (len--) {tft_Write_16(color);}
}
/***************************************************************************************
** 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>1) {tft_Write_16(*data); data++; tft_Write_16(*data); data++; len -=2;}
if (len) {tft_Write_16(*data);}
return;
}
while (len>1) {tft_Write_16S(*data); data++; tft_Write_16S(*data); data++; len -=2;}
if (len) {tft_Write_16S(*data);}
}
/***************************************************************************************
** 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)
{
#if defined (STM_PORTA_DATA_BUS)
#if defined (STM32F1xx)
if (mode == OUTPUT) GPIOA->CRL = 0x33333333;
else GPIOA->CRL = 0x88888888;
#else
if (mode == OUTPUT) GPIOA->MODER = (GPIOA->MODER & 0xFFFF0000) | 0x00005555;
else GPIOA->MODER &= 0xFFFF0000;
#endif
#elif defined (STM_PORTB_DATA_BUS)
#if defined (STM32F1xx)
if (mode == OUTPUT) GPIOB->CRL = 0x33333333;
else GPIOB->CRL = 0x88888888;
#else
if (mode == OUTPUT) GPIOB->MODER = (GPIOB->MODER & 0xFFFF0000) | 0x00005555;
else GPIOB->MODER &= 0xFFFF0000;
#endif
#elif defined (STM_PORTC_DATA_BUS)
#if defined (STM32F1xx)
if (mode == OUTPUT) GPIOC->CRL = 0x33333333;
else GPIOC->CRL = 0x88888888;
#else
if (mode == OUTPUT) GPIOC->MODER = (GPIOC->MODER & 0xFFFF0000) | 0x00005555;
else GPIOC->MODER &= 0xFFFF0000;
#endif
#elif defined (STM_PORTD_DATA_BUS)
#if defined (STM32F1xx)
if (mode == OUTPUT) GPIOD->CRL = 0x33333333;
else GPIOD->CRL = 0x88888888;
#else
if (mode == OUTPUT) GPIOD->MODER = (GPIOD->MODER & 0xFFFF0000) | 0x00005555;
else GPIOD->MODER &= 0xFFFF0000;
#endif
#else
if (mode == OUTPUT) {
LL_GPIO_SetPinMode(D0_PIN_PORT, D0_PIN_MASK, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinMode(D1_PIN_PORT, D1_PIN_MASK, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinMode(D2_PIN_PORT, D2_PIN_MASK, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinMode(D3_PIN_PORT, D3_PIN_MASK, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinMode(D4_PIN_PORT, D4_PIN_MASK, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinMode(D5_PIN_PORT, D5_PIN_MASK, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinMode(D6_PIN_PORT, D6_PIN_MASK, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinMode(D7_PIN_PORT, D7_PIN_MASK, LL_GPIO_MODE_OUTPUT);
}
else {
LL_GPIO_SetPinMode(D0_PIN_PORT, D0_PIN_MASK, LL_GPIO_MODE_INPUT);
LL_GPIO_SetPinMode(D1_PIN_PORT, D1_PIN_MASK, LL_GPIO_MODE_INPUT);
LL_GPIO_SetPinMode(D2_PIN_PORT, D2_PIN_MASK, LL_GPIO_MODE_INPUT);
LL_GPIO_SetPinMode(D3_PIN_PORT, D3_PIN_MASK, LL_GPIO_MODE_INPUT);
LL_GPIO_SetPinMode(D4_PIN_PORT, D4_PIN_MASK, LL_GPIO_MODE_INPUT);
LL_GPIO_SetPinMode(D5_PIN_PORT, D5_PIN_MASK, LL_GPIO_MODE_INPUT);
LL_GPIO_SetPinMode(D6_PIN_PORT, D6_PIN_MASK, LL_GPIO_MODE_INPUT);
LL_GPIO_SetPinMode(D7_PIN_PORT, D7_PIN_MASK, LL_GPIO_MODE_INPUT);
}
#endif
}
/***************************************************************************************
** Function name: GPIO direction control - supports class functions
** Description: Set STM32 GPIO pin to input or output (set high) ASAP
***************************************************************************************/
void TFT_eSPI::gpioMode(uint8_t gpio, uint8_t mode)
{
PinName pn = digitalPinToPinName(gpio);
// Push-pull output with no pullup
if (mode == OUTPUT) pin_function(pn, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
// Input with pullup
else pin_function(pn, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, 0));
}
/***************************************************************************************############# UNTESTED ###################
** Function name: read byte - supports class functions
** Description: Read a byte - parallel bus only
***************************************************************************************/
uint8_t TFT_eSPI::readByte(void)
{
uint8_t b = 0;
RD_L;
#if defined (STM_PORTA_DATA_BUS)
b = GPIOA->IDR;
b = GPIOA->IDR;
b = GPIOA->IDR;
b = (GPIOA->IDR) & 0xFF;
#elif defined (STM_PORTB_DATA_BUS)
b = GPIOB->IDR;
b = GPIOB->IDR;
b = GPIOB->IDR;
b = (GPIOB->IDR) & 0xFF;
#elif defined (STM_PORTC_DATA_BUS)
b = GPIOC->IDR;
b = GPIOC->IDR;
b = GPIOC->IDR;
b = (GPIOC->IDR) & 0xFF;
#elif defined (STM_PORTD_DATA_BUS)
b = GPIOD->IDR;
b = GPIOD->IDR;
b = GPIOD->IDR;
b = (GPIOD->IDR) & 0xFF;
#else
b = RD_TFT_D0 | RD_TFT_D0 | RD_TFT_D0 | RD_TFT_D0; //Delay for bits to settle
b = RD_TFT_D0 | RD_TFT_D1 | RD_TFT_D2 | RD_TFT_D3;
b |= RD_TFT_D4 | RD_TFT_D5 | RD_TFT_D6 | RD_TFT_D7;
#endif
RD_H;
return b;
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (RPI_WRITE_STROBE) // For RPi TFT with write strobe ############# UNTESTED ###################
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for ESP32 or STM32 RPi TFT
** Description: Write a block of pixels of the same colour
***************************************************************************************/
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
if(len) { tft_Write_16(color); len--; }
while(len--) {WR_L; WR_H;}
}
/***************************************************************************************
** Function name: pushPixels - for ESP32 or STM32 RPi TFT
** 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_16S(*data); data++;}
else while ( len-- ) {tft_Write_16(*data); data++;}
}
////////////////////////////////////////////////////////////////////////////////////////
#elif defined (SPI_18BIT_DRIVER) // SPI 18 bit colour
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for STM32 and 3 byte RGB display
** Description: Write a block of pixels of the same colour
***************************************************************************************/
#define BUF_SIZE 240*3
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
uint8_t col[BUF_SIZE];
// Always using swapped bytes is a peculiarity of this function...
//color = color>>8 | color<<8;
uint8_t r = (color & 0xF800)>>8; // Red
uint8_t g = (color & 0x07E0)>>3; // Green
uint8_t b = (color & 0x001F)<<3; // Blue
if (len<BUF_SIZE/3) {
for (uint32_t i = 0; i < len*3; i++) {
col[i] = r;
col[++i] = g;
col[++i] = b;
}
HAL_SPI_Transmit(&spiHal, col, len*3, HAL_MAX_DELAY);
return;
}
for (uint32_t i = 0; i < BUF_SIZE; i++) {
col[i] = r;
col[++i] = g;
col[++i] = b;
}
do {
HAL_SPI_Transmit(&spiHal, col, BUF_SIZE, HAL_MAX_DELAY);
len -= BUF_SIZE/3;
} while ( len>=BUF_SIZE/3 ) ;
// Send remaining pixels
if (len) HAL_SPI_Transmit(&spiHal, col, len*3, HAL_MAX_DELAY); //*/
}
/***************************************************************************************
** Function name: pushPixels - for STM32 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;
if(_swapBytes) {
while ( len-- ) {
// Split out the colours
spiBuffer[0] = (*data & 0xF8); // Red
spiBuffer[1] = (*data & 0xE000)>>11 | (*data & 0x07)<<5; // Green
spiBuffer[2] = (*data & 0x1F00)>>5; // Blue
data++;
HAL_SPI_Transmit(&spiHal, spiBuffer, 3, HAL_MAX_DELAY);
}
}
else {
while ( len-- ) {
// Split out the colours
spiBuffer[0] = (*data & 0xF800)>>8; // Red
spiBuffer[1] = (*data & 0x07E0)>>3; // Green
spiBuffer[2] = (*data & 0x001F)<<3; // Blue
data++;
HAL_SPI_Transmit(&spiHal, spiBuffer, 3, HAL_MAX_DELAY);
}
}
}
////////////////////////////////////////////////////////////////////////////////////////
#else // Standard SPI 16 bit colour TFT All Tested
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: pushBlock - for STM32
** Description: Write a block of pixels of the same colour
***************************************************************************************/
#define BUF_SIZE 480
void TFT_eSPI::pushBlock(uint16_t color, uint32_t len)
{
uint16_t col[BUF_SIZE];
// Always using swapped bytes is a peculiarity of this function...
uint16_t swapColor = color>>8 | color<<8;
if (len<BUF_SIZE) {
for (uint32_t i = 0; i < len; i++) col[i] = swapColor;
HAL_SPI_Transmit(&spiHal, (uint8_t*)col, len<<1, HAL_MAX_DELAY);
return;
}
for (uint32_t i = 0; i < BUF_SIZE; i++) col[i] = swapColor;
do {
HAL_SPI_Transmit(&spiHal, (uint8_t*)col, BUF_SIZE<<1, HAL_MAX_DELAY);
len -= BUF_SIZE;
} while ( len>=BUF_SIZE ) ;
// Send remaining pixels
if (len) HAL_SPI_Transmit(&spiHal, (uint8_t*)col, len<<1, HAL_MAX_DELAY); //*/
}
/***************************************************************************************
** Function name: pushPixels - for STM32
** 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) {
uint16_t col[BUF_SIZE]; // Buffer for swapped bytes
while ( len>=BUF_SIZE ) {
for (uint32_t i = 0; i < BUF_SIZE; i++) { col[i] = (*data>>8) | (*data<<8); data++; }
HAL_SPI_Transmit(&spiHal, (uint8_t*)col, BUF_SIZE<<1, HAL_MAX_DELAY);
len -= BUF_SIZE;
}
for (uint32_t i = 0; i < len; i++) { col[i] = (*data>>8) | (*data<<8); data++; }
HAL_SPI_Transmit(&spiHal, (uint8_t*)col, len<<1, HAL_MAX_DELAY);
}
else {
// HAL byte count for transmit is only 16 bits maximum so to avoid this constraint
// transfers of small blocks are performed until HAL capacity is reached.
while(len>0x7FFF) { // Transfer 16 bit pixels in blocks if len*2 over 65534 bytes
HAL_SPI_Transmit(&spiHal, (uint8_t*)data, 0x800<<1, HAL_MAX_DELAY);
len -= 0x800; data+= 0x800; // Arbitrarily use 2KByte blocks
}
// Send remaining pixels (max 65534 bytes)
HAL_SPI_Transmit(&spiHal, (uint8_t*)data, len<<1, HAL_MAX_DELAY);
}
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // End of display interface specific functions
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
#if defined STM32_DMA && !defined (TFT_PARALLEL_8_BIT) // DMA FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************************************
** Function name: dmaBusy
** Description: Check if DMA is busy (usefully non-blocking!)
***************************************************************************************/
// Use while( tft.dmaBusy() ) {Do-something-useful;}"
bool TFT_eSPI::dmaBusy(void)
{
//return (dmaHal.State == HAL_DMA_STATE_BUSY); // Do not use, SPI may still be busy
return (spiHal.State == HAL_SPI_STATE_BUSY_TX); // Check if SPI Tx is busy
}
/***************************************************************************************
** Function name: dmaWait
** Description: Wait until DMA is over (blocking!)
***************************************************************************************/
void TFT_eSPI::dmaWait(void)
{
//return (dmaHal.State == HAL_DMA_STATE_BUSY); // Do not use, SPI may still be busy
while (spiHal.State == HAL_SPI_STATE_BUSY_TX); // Check if SPI Tx is busy
}
/***************************************************************************************
** 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) return;
// Wait for any current DMA transaction to end
while (spiHal.State == HAL_SPI_STATE_BUSY_TX); // Check if SPI Tx is busy
if(_swapBytes) {
for (uint32_t i = 0; i < len; i++) (image[i] = image[i] << 8 | image[i] >> 8);
}
HAL_SPI_Transmit_DMA(&spiHal, (uint8_t*)image, len << 1);
}
/***************************************************************************************
** 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)) 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;
while (spiHal.State == HAL_SPI_STATE_BUSY_TX); // Check if SPI Tx is busy
}
// 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);
}
}
setWindow(x, y, x + dw - 1, y + dh - 1);
// DMA byte count for transmit is only 16 bits 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 32767 pixels maximum. (equivalent to an area of ~320 x 100 pixels)
while(len>0x7FFF) { // Transfer 16 bit pixels in blocks if len*2 over 65534 bytes
HAL_SPI_Transmit(&spiHal, (uint8_t*)buffer, 0x800<<1, HAL_MAX_DELAY);
len -= 0x800; buffer+= 0x800; // Arbitrarily send 1K pixel blocks (2Kbytes)
}
// Send remaining pixels using DMA (max 65534 bytes)
HAL_SPI_Transmit_DMA(&spiHal, (uint8_t*)buffer, len << 1);
}
////////////////////////////////////////////////////////////////////////////////////////
// Processor specific DMA initialisation
////////////////////////////////////////////////////////////////////////////////////////
// The DMA functions here work with SPI only (not parallel)
#if defined (STM32F2xx) || defined (STM32F4xx) || defined (STM32F7xx)
/***************************************************************************************
** Function name: DMAX_StreamX_IRQHandler
** Description: Override the default HAL stream X interrupt handler
***************************************************************************************/
#if (TFT_SPI_PORT == 1)
extern "C" void DMA2_Stream3_IRQHandler();
void DMA2_Stream3_IRQHandler(void)
#elif (TFT_SPI_PORT == 2)
extern "C" void DMA1_Stream4_IRQHandler();
void DMA1_Stream4_IRQHandler(void)
#elif (TFT_SPI_PORT == 3)
extern "C" void DMA1_Stream5_IRQHandler();
void DMA1_Stream5_IRQHandler(void)
#endif
{
// Call the default end of buffer handler
HAL_DMA_IRQHandler(&dmaHal);
}
/***************************************************************************************
** Function name: initDMA
** Description: Initialise the DMA engine - returns true if init OK
***************************************************************************************/
// This initialisation is for STM32F2xx/4xx/7xx processors and may not work on others
// Dual core H7xx series not supported yet, they are different and have a DMA MUX:
// https://electronics.stackexchange.com/questions/379813/configuring-the-dma-request-multiplexer-on-a-stm32h7-mcu
bool TFT_eSPI::initDMA(bool ctrl_cs)
{
ctrl_cs = ctrl_cs; // Not used for STM32, so stop compiler warning
#if (TFT_SPI_PORT == 1)
__HAL_RCC_DMA2_CLK_ENABLE(); // Enable DMA2 clock
dmaHal.Init.Channel = DMA_CHANNEL_3; // DMA channel 3 is for SPI1 TX
#elif (TFT_SPI_PORT == 2)
__HAL_RCC_DMA1_CLK_ENABLE(); // Enable DMA1 clock
dmaHal.Init.Channel = DMA_CHANNEL_0; // DMA channel 0 is for SPI2 TX
#elif (TFT_SPI_PORT == 3)
__HAL_RCC_DMA1_CLK_ENABLE(); // Enable DMA1 clock
dmaHal.Init.Channel = DMA_CHANNEL_0; // DMA channel 0 is for SPI3 TX
#endif
dmaHal.Init.Mode = DMA_NORMAL; //DMA_CIRCULAR; // // Normal = send buffer once
dmaHal.Init.Direction = DMA_MEMORY_TO_PERIPH; // Copy memory to the peripheral
dmaHal.Init.PeriphInc = DMA_PINC_DISABLE; // Don't increment peripheral address
dmaHal.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; // Peripheral is byte aligned
dmaHal.Init.MemInc = DMA_MINC_ENABLE; // Increment memory address
dmaHal.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; // Memory is byte aligned
if (HAL_DMA_Init(&dmaHal) != HAL_OK){ // Init DMA with settings
// Insert error message here?
return DMA_Enabled = false;
};
#if (TFT_SPI_PORT == 1)
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn); // Enable DMA end interrupt handler
#elif (TFT_SPI_PORT == 2)
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn); // Enable DMA end interrupt handler
#endif
__HAL_LINKDMA(&spiHal, hdmatx, dmaHal); // Attach DMA engine to SPI peripheral
return DMA_Enabled = true;
}
#elif defined (STM32F1xx) // Supports "Blue Pill" boards
/***************************************************************************************
** Function name: DMA1_ChannelX_IRQHandler
** Description: Override the default HAL stream 3 interrupt handler
***************************************************************************************/
#if (TFT_SPI_PORT == 1)
extern "C" void DMA1_Channel3_IRQHandler();
void DMA1_Channel3_IRQHandler(void)
#elif (TFT_SPI_PORT == 2)
extern "C" void DMA1_Channel5_IRQHandler();
void DMA1_Channel5_IRQHandler(void)
#endif
{
// Call the default end of buffer handler
HAL_DMA_IRQHandler(&dmaHal);
}
//*/
/***************************************************************************************
** Function name: initDMA
** Description: Initialise the DMA engine - returns true if init OK
***************************************************************************************/
bool TFT_eSPI::initDMA(bool ctrl_cs)
{
ctrl_cs = ctrl_cs; // Not used for STM32, so stop compiler warning
__HAL_RCC_DMA1_CLK_ENABLE(); // Enable DMA1 clock
dmaHal.Init.Mode = DMA_NORMAL; //DMA_CIRCULAR; // // Normal = send buffer once
dmaHal.Init.Direction = DMA_MEMORY_TO_PERIPH; // Copy memory to the peripheral
dmaHal.Init.PeriphInc = DMA_PINC_DISABLE; // Don't increment peripheral address
dmaHal.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; // Peripheral is byte aligned
dmaHal.Init.MemInc = DMA_MINC_ENABLE; // Increment memory address
dmaHal.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; // Memory is byte aligned
dmaHal.Init.Priority = DMA_PRIORITY_LOW; // Added this line - needed ?
__HAL_LINKDMA(&spiHal, hdmatx, dmaHal); // Attach DMA engine to SPI peripheral
if (HAL_DMA_Init(&dmaHal) != HAL_OK){ // Init DMA with settings
// Insert error message here?
return DMA_Enabled = false;
};
#if (TFT_SPI_PORT == 1)
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn); // Enable DMA end interrupt handler
#elif (TFT_SPI_PORT == 2)
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn); // Enable DMA end interrupt handler
#endif
return DMA_Enabled = true;
}
#endif // End of STM32F1/2/4/7xx
/***************************************************************************************
** Function name: deInitDMA
** Description: Disconnect the DMA engine from SPI
***************************************************************************************/
void TFT_eSPI::deInitDMA(void)
{
HAL_DMA_DeInit(&dmaHal);
DMA_Enabled = false;
}
////////////////////////////////////////////////////////////////////////////////////////
#endif // End of DMA FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////

1078
Processors/TFT_eSPI_STM32.h Normal file

File diff suppressed because it is too large Load Diff

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

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

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

74
Processors/pio_SPI.pio.h Normal file
View File

@ -0,0 +1,74 @@
// -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! //
// 8 + 16 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
0x7011, // 22: out pins, 17 side 0
0xb842, // 23: nop side 1
0x7001, // 24: out pins, 1 side 0
0x18f8, // 25: jmp !osre, 24 side 1
0x1095, // 26: jmp y--, 21 side 0
// .wrap_target
0x90a0, // 27: pull block side 0
0x7011, // 28: out pins, 17 side 0
0xb842, // 29: nop side 1
0x7001, // 30: out pins, 1 side 0
0x18fe, // 31: jmp !osre, 30 side 1
// .wrap
};
#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

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

167
README.md
View File

@ -1,38 +1,117 @@
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
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):
1. Sprites can now by pushed to the screen (or another Sprite) with a rotation angle. The new function is pushRotated(). Three new examples (Rotate_Sprite_1/2/3) have been added to show how the functions can be used to rotate text, images and to draw animated dials with moving needles.
![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)
2. A new TFT_eFEX support library has been created which includes extra functions such as drawing a BMP or Jpeg to the screen. This library will simplify the examples. It will be expanded at a future date to include meters, dials and GUI elements like progress bars, graphs and animated buttons:
https://github.com/Bodmer/TFT_eFEX
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)
3. androdlang has published a really nice companion library to extend the graphics capabilities of TFT_eSPI, you can find this here:
https://github.com/androdlang/TFTShape
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:
4. I have created a user updateable graphics extension library template that can be used to create your own graphics extensions. The Library contains examples and is commented so it should be clear what you need to do to add functions. You can find it here:
https://github.com/Bodmer/TFT_eFX
![ttf_font_demo](https://i.imgur.com/bKkilIb.png)
5. The capability to read from an ST7789V TFT with a single bidirectional SDA pin has been added. At the moment this **ONLY** works with an ESP32. It is enabled with a #define TFT_SDA_READ in the setup file.
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.fillRectVGradient(x, y, w, h, color1, color2);
![Gradient](https://i.imgur.com/atR0DmP.png)
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 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.
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)
6. ST7789V and ILI9341 displays are manufactured in two variants that have the red and blue pixels swapped, this is catered for by a new option in the setup file:
//#define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
//#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
# TFT_eSPI
An Arduino IDE compatible graphics and fonts library for ESP8266 and ESP32 processors with drivers for ILI9341, ILI9163, ST7735, S6D02A1, ILI9481, ILI9486, ILI9488, HX8357D and ST7789 based TFT displays that support SPI. The library can be loaded using the Arduino IDE's Library Manager.
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.
8 bit parallel interface TFTs (e.g. UNO format mcufriend shields) can used with an ESP32.
Optimised drivers have been tested with the following processors:
The library supports TFT displays designed for the Raspberry Pi that are based on a ILI9486 driver chip with a 480 x 320 pixel screen. This 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. A modification to these displays is possible (see mod image in Tools folder) to make many graphics functions much faster (e.g. 23ms to clear the screen, 1.2ms to draw a 72 pixel high numeral).
* RP2040, e.g. Raspberry Pi Pico
* ESP32 and ESP32-S2, ESP32-C3, ESP32-S3
* ESP8266
* STM32F1xx, STM32F2xx, STM32F4xx, STM32F767 (higher RAM processors recommended)
Some displays permit the internal TFT screen RAM to be read. The library supports reading from ILI9341, ST7789 and ILI9488 SPI displays for the ESP32 and ESP8266. The 8 bit parallel displays used with the ESP32 can usually can be read too. The TFT_Screen_Capture example allows full screens to be captured and sent to a PC, this is handy to create program documentation.
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.
Support has been added recently for Waveshare 2 and 3 colour ePaper displays using full frame buffers. This addition is currently relatively immature and thus only one example has been provided. Further examples will be added soon.
"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:
* GC9A01
* ILI9163
* ILI9225
* ILI9341
* ILI9342
* ILI9481 (DMA not supported with SPI)
* ILI9486 (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
* R61581
* RM68120 (support files added but untested)
* RM68140
* S6D02A1
* SSD1351
* SSD1963
* ST7735
* ST7789
* ST7796
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.
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, 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 includes a "Sprite" class, this enables flicker free updates of complex graphics. Direct writes to the TFT with graphics functions are still available, so existing sketches do not need to be changed.
A Sprite is notionally an invisible graphics screen that is kept in the processors RAM. Graphics can be drawn into the Sprite just as they can be drawn directly to the screen. Once the Sprite is completed it can be plotted onto the screen in any position. If there is sufficient RAM then the Sprite can be the same size as the screen and used as a frame buffer. Sprites by default use 16 bit colours, the bit depth can be set to 8 bits (256 colours) , or 1 bit (any 2 colours) to reduce the RAM needed. On an ESP8266 the largest 16 bit colour Sprite that can be created is about 160x128 pixels, this consumes 40Kbytes of RAM. On an ESP32 the workspace RAM is more limited than the datsheet implies so a 16 bit colour Sprite is limited to about 200x200 pixels (~80Kbytes), an 8 bit sprite to 320x240 pixels (~76kbytes). A 1 bit per pixel Sprite requires only 9600 bytes for a full 320 x 240 screen buffer, this is ideal for supporting use with 2 colour bitmap fonts.
# Sprites
A Sprite is notionally an invisible graphics screen that is kept in the processors RAM. Graphics can be drawn into the Sprite just as they can be drawn directly to the screen. Once the Sprite is completed it can be plotted onto the screen in any position. If there is sufficient RAM then the Sprite can be the same size as the screen and used as a frame buffer. Sprites by default use 16 bit colours, the bit depth can be set to 8 bits (256 colours) , or 1 bit (any 2 colours) to reduce the RAM needed. On an ESP8266 the largest 16 bit colour Sprite that can be created is about 160x128 pixels, this consumes 40Kbytes of RAM. On an ESP32 the workspace RAM is more limited than the datasheet implies so a 16 bit colour Sprite is limited to about 200x200 pixels (~80Kbytes), an 8 bit sprite to 320x240 pixels (~76kbytes). A 1 bit per pixel Sprite requires only 9600 bytes for a full 320 x 240 screen buffer, this is ideal for supporting use with 2 colour bitmap fonts.
One or more sprites can be created, a sprite can be any pixel width and height, limited only by available RAM. The RAM needed for a 16 bit colour depth Sprite is (2 x width x height) bytes, for a Sprite with 8 bit colour depth the RAM needed is (width x height) bytes. Sprites can be created and deleted dynamically as needed in the sketch, this means RAM can be freed up after the Sprite has been plotted on the screen, more RAM intensive WiFi based code can then be run and normal graphics operations still work.
@ -42,23 +121,37 @@ Sprites can be plotted to the TFT with one colour being specified as "transparen
If an ESP32 board has SPIRAM (i.e. PSRAM) fitted then Sprites will use the PSRAM memory and large full screen buffer Sprites can be created. Full screen Sprites take longer to render (~45ms for a 320 x 240 16 bit Sprite), so bear that in mind.
The XPT2046 touch screen controller is supported. The SPI bus for the touch controller is shared with the TFT and only an additional chip select line is needed.
The "Animated_dial" example shows how dials can be created using a rotated Sprite for the needle. To run this example the TFT interface must support reading from the screen RAM (not all do). The dial rim and scale is a jpeg image, created using a paint program.
![Animated_dial](https://i.imgur.com/S736Rg6.png)
# Touch controller support
The XPT2046 touch screen controller is supported for SPI based displays only. The SPI bus for the touch controller is shared with the TFT and only an additional chip select line is needed. This support will eventually be deprecated when a suitable touch screen library is available.
The Button class from Adafruit_GFX is incorporated, with the enhancement that the button labels can be in any font.
The library supports SPI overlap on the ESP8266 so the TFT screen can share MOSI, MISO and SCLK pins with the program FLASH, this frees up GPIO pins for other uses.
# ESP8266 overlap mode
The library contains proportional fonts, different sizes can be enabled/disabled at compile time to optimise the use of FLASH memory. Anti-alased (smooth) font files in vlw format stored in SPIFFS are supported. Any 16 bit Unicode character can be included and rendered, this means many language specific characters can be rendered to the screen.
The library supports SPI overlap on the ESP8266 so the TFT screen can share MOSI, MISO and SCLK pins with the program FLASH, this frees up GPIO pins for other uses. Only one SPI device can be connected to the FLASH pins and the chips select for the TFT must be on pin D3 (GPIO0).
The library is based on the Adafruit GFX and Adafruit driver libraries and the aim is to retain compatibility. Significant additions have been made to the library to boost the speed for ESP8266/ESP32 processors (it is typically 3 to 10 times faster) and to add new features. The new graphics functions include different size proportional fonts and formatting features. There are lots of example sketches to demonstrate the different features and included functions.
Configuration of the library font selections, pins used to interface with the TFT and other features is made by editting the User_Setup.h file in the library folder, or by selecting your own configuration in the "User_Setup_Selet,h" file. Fonts and features can easily be enabled/disabled by commenting out lines.
# Fonts
The library contains proportional fonts, different sizes can be enabled/disabled at compile time to optimise the use of FLASH memory. Anti-aliased (smooth) font files in vlw format stored in SPIFFS are supported. Any 16 bit Unicode character can be included and rendered, this means many language specific characters can be rendered to the screen.
The library is based on the Adafruit GFX and Adafruit driver libraries and the aim is to retain compatibility. Significant additions have been made to the library to boost the speed for the different processors (it is typically 3 to 10 times faster) and to add new features. The new graphics functions include different size proportional fonts and formatting features. There are lots of example sketches to demonstrate the different features and included functions.
Configuration of the library font selections, pins used to interface with the TFT and other features is made by editing the User_Setup.h file in the library folder, or by selecting your own configuration in the "User_Setup_Selet,h" file. Fonts and features can easily be enabled/disabled by commenting out lines.
# Anti-aliased Fonts
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 system.
Here is the Adafruit_GFX "FreeSans12pt" bitmap font compared to the same font drawn as anti-aliased:
![Smooth_font](https://i.imgur.com/gAeDPFY.png)
@ -67,21 +160,25 @@ The smooth font example displays the following screen:
![Example](https://i.imgur.com/xJF0Oz7.png)
It would be possible to compress the vlw font files but the rendering performance to a TFT is still good when storing the font file(s) in SPIFFS.
It would be possible to compress the vlw font files but the rendering performance to a TFT is still good when storing the font file(s) in SPIFFS, LittleFS or FLASH arrays.
Here is an example screenshot showing the anti-aliased Hiragana character Unicode block (0x3041 to 0x309F) in 24pt from the Microsoft Yahei font:
![Hiragana glyphs](https://i.imgur.com/jeXf2st.png)
Anti-aliased fonts can also be drawn over a gradient background with a callback to fetch the background colour of each pixel. This pixel colour can be set by the gradient algorithm or by reading back the TFT screen memory (if reading the display is supported).
Anti-aliased fonts cannot be scaled with setTextSize so you need to create a font for each size you need. See examples.
# ESP32 with 8 bit Mcufriend UNO shields
# 8 bit parallel support
The common 8 bit "Mcufriend" shields are supported for the STM Nucleo 64/144 boards and ESP32 UNO style board. The STM32 "Blue/Black Pill" boards can also be used with 8 bit parallel displays.
The ESP32 board I have been using for testing has the following pinout:
![Example](https://i.imgur.com/bvM6leE.jpg)
UNO style boards with a Wemos R32(ESP32) label are also available at low cost with the same pin-out.
UNO style boards with a Wemos R32(ESP32) label are also available at low cost with the same pinout.
Unfortunately the typical UNO/mcufriend TFT display board maps LCD_RD, LCD_CS and LCD_RST signals to the ESP32 analogue pins 35, 34 and 36 which are input only. To solve this I linked in the 3 spare pins IO15, IO33 and IO32 by adding wires to the bottom of the board as follows:
@ -91,14 +188,22 @@ IO33 wired to IO34
IO32 wired to IO36
This is an [example setup file](https://github.com/Bodmer/TFT_eSPI/blob/master/User_Setups/Setup14_ILI9341_Parallel.h) with the correct GPIO for this UNO board.
![Example](https://i.imgur.com/pUZn6lF.jpg)
If the display board is fitted with a resistance based touch screen then this can be used by performing the modifications described here and the fork of the Adafruit library:
https://github.com/s60sc/Adafruit_TouchScreen
# 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)
# Tips
If you load a new copy of TFT_eSPI then it will overwrite your setups if they are kept within the TFT_eSPI folder. One way around this is to create a new folder in your Arduino library folder called "TFT_eSPI_Setups". You then place your custom setup.h files in there. After an upgrade simply edit the User_Setup_Select.h file to point to your custom setup file e.g.:
```
#include <../TFT_eSPI_Setups/my_custom_setup.h>
```
You must make sure only one setup file is called. In the custom setup file I add the file path as a commented out first line that can be cut and pasted back into the upgraded User_Setup_Select.h file. The ../ at the start of the path means go up one directory level. Clearly you could use different file paths or directory names as long as it does not clash with another library or folder name.
You can take this one step further and have your own setup select file and then you only need to replace the Setup.h line reference in User_Setup_Select.h to, for example:
```
#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).

View File

@ -1,18 +1,7 @@
This is a standalone library that contains both graphics functions
and the TFT chip driver library.
This library has been derived from the Adafruit_GFX and driver library with
further code from other authors.
It is not compatible with legacy versions of the IDE (e.g. 1.0.6 and
older. Use the latest version.
New functions have been added in particular it contains proportional fonts
in addition to the original Adafruit font.
A sprite class has been added to aid the generation of flicker free complex
graphics.
Note: This version of the library might not be fully compatible with the
original.
This is a stand-alone library that contains both graphics functions
and the TFT chip driver library. It supports the ESP8266, ESP32,
STM32 and RP2040 processors with performance optimised code. Other
Arduino IDE compatible boards are also supported but the library
then uses generic functions which will be slower. The library uses
32 bit variables extensively so this will affect performance on 8
and 16 bit processors.

View File

@ -0,0 +1,34 @@
// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
#ifndef TFT_WIDTH
#define TFT_WIDTH 240
#endif
#ifndef TFT_HEIGHT
#define TFT_HEIGHT 320
#endif
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80
// Generic commands used by TFT_eSPI.cpp
#define TFT_NOP 0x00
#define TFT_SWRST 0x01
#define TFT_CASET 0x2A
#define TFT_PASET 0x2B
#define TFT_RAMWR 0x2C
#define TFT_RAMRD 0x2E
#define TFT_IDXRD 0x00 //0xDD // ILI9341 only, indexed control register read
#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_BGR 0x08
#define TFT_MAD_MH 0x04
#define TFT_MAD_RGB 0x00
#define TFT_INVOFF 0x20
#define TFT_INVON 0x21

232
TFT_Drivers/GC9A01_Init.h Normal file
View File

@ -0,0 +1,232 @@
// This is the command sequence that initialises the GC9A01 driver
{
writecommand(0xEF);
writecommand(0xEB);
writedata(0x14);
writecommand(0xFE);
writecommand(0xEF);
writecommand(0xEB);
writedata(0x14);
writecommand(0x84);
writedata(0x40);
writecommand(0x85);
writedata(0xFF);
writecommand(0x86);
writedata(0xFF);
writecommand(0x87);
writedata(0xFF);
writecommand(0x88);
writedata(0x0A);
writecommand(0x89);
writedata(0x21);
writecommand(0x8A);
writedata(0x00);
writecommand(0x8B);
writedata(0x80);
writecommand(0x8C);
writedata(0x01);
writecommand(0x8D);
writedata(0x01);
writecommand(0x8E);
writedata(0xFF);
writecommand(0x8F);
writedata(0xFF);
writecommand(0xB6);
writedata(0x00);
writedata(0x20);
writecommand(0x3A);
writedata(0x05);
writecommand(0x90);
writedata(0x08);
writedata(0x08);
writedata(0x08);
writedata(0x08);
writecommand(0xBD);
writedata(0x06);
writecommand(0xBC);
writedata(0x00);
writecommand(0xFF);
writedata(0x60);
writedata(0x01);
writedata(0x04);
writecommand(0xC3);
writedata(0x13);
writecommand(0xC4);
writedata(0x13);
writecommand(0xC9);
writedata(0x22);
writecommand(0xBE);
writedata(0x11);
writecommand(0xE1);
writedata(0x10);
writedata(0x0E);
writecommand(0xDF);
writedata(0x21);
writedata(0x0c);
writedata(0x02);
writecommand(0xF0);
writedata(0x45);
writedata(0x09);
writedata(0x08);
writedata(0x08);
writedata(0x26);
writedata(0x2A);
writecommand(0xF1);
writedata(0x43);
writedata(0x70);
writedata(0x72);
writedata(0x36);
writedata(0x37);
writedata(0x6F);
writecommand(0xF2);
writedata(0x45);
writedata(0x09);
writedata(0x08);
writedata(0x08);
writedata(0x26);
writedata(0x2A);
writecommand(0xF3);
writedata(0x43);
writedata(0x70);
writedata(0x72);
writedata(0x36);
writedata(0x37);
writedata(0x6F);
writecommand(0xED);
writedata(0x1B);
writedata(0x0B);
writecommand(0xAE);
writedata(0x77);
writecommand(0xCD);
writedata(0x63);
writecommand(0x70);
writedata(0x07);
writedata(0x07);
writedata(0x04);
writedata(0x0E);
writedata(0x0F);
writedata(0x09);
writedata(0x07);
writedata(0x08);
writedata(0x03);
writecommand(0xE8);
writedata(0x34);
writecommand(0x62);
writedata(0x18);
writedata(0x0D);
writedata(0x71);
writedata(0xED);
writedata(0x70);
writedata(0x70);
writedata(0x18);
writedata(0x0F);
writedata(0x71);
writedata(0xEF);
writedata(0x70);
writedata(0x70);
writecommand(0x63);
writedata(0x18);
writedata(0x11);
writedata(0x71);
writedata(0xF1);
writedata(0x70);
writedata(0x70);
writedata(0x18);
writedata(0x13);
writedata(0x71);
writedata(0xF3);
writedata(0x70);
writedata(0x70);
writecommand(0x64);
writedata(0x28);
writedata(0x29);
writedata(0xF1);
writedata(0x01);
writedata(0xF1);
writedata(0x00);
writedata(0x07);
writecommand(0x66);
writedata(0x3C);
writedata(0x00);
writedata(0xCD);
writedata(0x67);
writedata(0x45);
writedata(0x45);
writedata(0x10);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writecommand(0x67);
writedata(0x00);
writedata(0x3C);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x54);
writedata(0x10);
writedata(0x32);
writedata(0x98);
writecommand(0x74);
writedata(0x10);
writedata(0x85);
writedata(0x80);
writedata(0x00);
writedata(0x00);
writedata(0x4E);
writedata(0x00);
writecommand(0x98);
writedata(0x3e);
writedata(0x07);
writecommand(0x35);
writecommand(0x21);
writecommand(0x11);
delay(120);
writecommand(0x29);
delay(20);
}

View File

@ -0,0 +1,28 @@
// This is the command sequence that rotates the GC9A01 driver coordinate frame
rotation = m % 4;
writecommand(TFT_MADCTL);
switch (rotation) {
case 0: // Portrait
writedata(TFT_MAD_BGR);
_width = _init_width;
_height = _init_height;
break;
case 1: // Landscape (Portrait + 90)
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);
_width = _init_height;
_height = _init_width;
break;
case 2: // Inverter portrait
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_BGR);
_width = _init_width;
_height = _init_height;
break;
case 3: // Inverted landscape
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_BGR);
_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

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

@ -39,6 +39,16 @@
#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_RGB
#endif
#define TFT_IDXRD 0x00 // ILI9341 only, indexed control register read

View File

@ -97,7 +97,7 @@
writedata(0x55); // 16 bit
writecommand(HX8357_MADCTL);
writedata(0xC0);
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
writecommand(HX8357_TEON); // TE off
writedata(0x00);

View File

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

View File

@ -0,0 +1,84 @@
// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
#define TFT_WIDTH 176
#define TFT_HEIGHT 220
// Generic commands used by TFT_eSPI.cpp
#define TFT_NOP 0x00
#define TFT_SWRST 0x28
#define TFT_CASET 0
#define TFT_PASET 0
#define TFT_CASET1 ILI9225_HORIZONTAL_WINDOW_ADDR2
#define TFT_CASET2 ILI9225_HORIZONTAL_WINDOW_ADDR1
#define TFT_PASET1 ILI9225_VERTICAL_WINDOW_ADDR2
#define TFT_PASET2 ILI9225_VERTICAL_WINDOW_ADDR1
#define TFT_RAM_ADDR1 ILI9225_RAM_ADDR_SET1
#define TFT_RAM_ADDR2 ILI9225_RAM_ADDR_SET2
#define TFT_RAMWR ILI9225_GRAM_DATA_REG
#define TFT_MAD_BGR 0x10
#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_BGR
#endif
// Not used
#define TFT_INVOFF 0x00
#define TFT_INVON 0x00
#define TFT_RAMRD 0x00
#define TFT_IDXRD 0x00
/* ILI9225 Registers */
#define ILI9225_DRIVER_OUTPUT_CTRL 0x01 // Driver Output Control
#define ILI9225_LCD_AC_DRIVING_CTRL 0x02 // LCD AC Driving Control
#define ILI9225_ENTRY_MODE 0x03 // Entry Mode
#define ILI9225_DISP_CTRL1 0x07 // Display Control 1
#define ILI9225_BLANK_PERIOD_CTRL1 0x08 // Blank Period Control
#define ILI9225_FRAME_CYCLE_CTRL 0x0B // Frame Cycle Control
#define ILI9225_INTERFACE_CTRL 0x0C // Interface Control
#define ILI9225_OSC_CTRL 0x0F // Osc Control
#define ILI9225_POWER_CTRL1 0x10 // Power Control 1
#define ILI9225_POWER_CTRL2 0x11 // Power Control 2
#define ILI9225_POWER_CTRL3 0x12 // Power Control 3
#define ILI9225_POWER_CTRL4 0x13 // Power Control 4
#define ILI9225_POWER_CTRL5 0x14 // Power Control 5
#define ILI9225_VCI_RECYCLING 0x15 // VCI Recycling
#define ILI9225_RAM_ADDR_SET1 0x20 // Horizontal GRAM Address Set
#define ILI9225_RAM_ADDR_SET2 0x21 // Vertical GRAM Address Set
#define ILI9225_GRAM_DATA_REG 0x22 // GRAM Data Register
#define ILI9225_GATE_SCAN_CTRL 0x30 // Gate Scan Control Register
#define ILI9225_VERTICAL_SCROLL_CTRL1 0x31 // Vertical Scroll Control 1 Register
#define ILI9225_VERTICAL_SCROLL_CTRL2 0x32 // Vertical Scroll Control 2 Register
#define ILI9225_VERTICAL_SCROLL_CTRL3 0x33 // Vertical Scroll Control 3 Register
#define ILI9225_PARTIAL_DRIVING_POS1 0x34 // Partial Driving Position 1 Register
#define ILI9225_PARTIAL_DRIVING_POS2 0x35 // Partial Driving Position 2 Register
#define ILI9225_HORIZONTAL_WINDOW_ADDR1 0x36 // Horizontal Address Start Position
#define ILI9225_HORIZONTAL_WINDOW_ADDR2 0x37 // Horizontal Address End Position
#define ILI9225_VERTICAL_WINDOW_ADDR1 0x38 // Vertical Address Start Position
#define ILI9225_VERTICAL_WINDOW_ADDR2 0x39 // Vertical Address End Position
#define ILI9225_GAMMA_CTRL1 0x50 // Gamma Control 1
#define ILI9225_GAMMA_CTRL2 0x51 // Gamma Control 2
#define ILI9225_GAMMA_CTRL3 0x52 // Gamma Control 3
#define ILI9225_GAMMA_CTRL4 0x53 // Gamma Control 4
#define ILI9225_GAMMA_CTRL5 0x54 // Gamma Control 5
#define ILI9225_GAMMA_CTRL6 0x55 // Gamma Control 6
#define ILI9225_GAMMA_CTRL7 0x56 // Gamma Control 7
#define ILI9225_GAMMA_CTRL8 0x57 // Gamma Control 8
#define ILI9225_GAMMA_CTRL9 0x58 // Gamma Control 9
#define ILI9225_GAMMA_CTRL10 0x59 // Gamma Control 10
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x00 // Not used unless commandlist invoked

105
TFT_Drivers/ILI9225_Init.h Normal file
View File

@ -0,0 +1,105 @@
// This is the command sequence that initialises the ILI9225 driver
{
writecommand(ILI9225_POWER_CTRL1);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_POWER_CTRL2);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_POWER_CTRL3);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_POWER_CTRL4);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_POWER_CTRL5);
writedata(0x00);writedata(0x00);
delay(40);
writecommand(ILI9225_POWER_CTRL2);
writedata(0x00);writedata(0x18);
writecommand(ILI9225_POWER_CTRL3);
writedata(0x61);writedata(0x21);
writecommand(ILI9225_POWER_CTRL4);
writedata(0x00);writedata(0x6F);
writecommand(ILI9225_POWER_CTRL5);
writedata(0x49);writedata(0x5F);
writecommand(ILI9225_POWER_CTRL1);
writedata(0x08);writedata(0x00);
delay(10);
writecommand(ILI9225_POWER_CTRL2);
writedata(0x10);writedata(0x3B);
delay(50);
writecommand(ILI9225_LCD_AC_DRIVING_CTRL);
writedata(0x01);writedata(0x00);
writecommand(ILI9225_DISP_CTRL1);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_BLANK_PERIOD_CTRL1);
writedata(0x08);writedata(0x08);
writecommand(ILI9225_FRAME_CYCLE_CTRL);
writedata(0x11);writedata(0x00);
writecommand(ILI9225_INTERFACE_CTRL);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_OSC_CTRL);
writedata(0x0D);writedata(0x01);
writecommand(ILI9225_VCI_RECYCLING);
writedata(0x00);writedata(0x20);
writecommand(ILI9225_RAM_ADDR_SET1);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_RAM_ADDR_SET2);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_GATE_SCAN_CTRL);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_VERTICAL_SCROLL_CTRL1);
writedata(0x00);writedata(0xDB);
writecommand(ILI9225_VERTICAL_SCROLL_CTRL2);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_VERTICAL_SCROLL_CTRL3);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_PARTIAL_DRIVING_POS1);
writedata(0x00);writedata(0xDB);
writecommand(ILI9225_PARTIAL_DRIVING_POS2);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_HORIZONTAL_WINDOW_ADDR1);
writedata(0x00);writedata(0xAF);
writecommand(ILI9225_HORIZONTAL_WINDOW_ADDR2);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_VERTICAL_WINDOW_ADDR1);
writedata(0x00);writedata(0xDB);
writecommand(ILI9225_VERTICAL_WINDOW_ADDR2);
writedata(0x00);writedata(0x00);
/* Set GAMMA curve */
writecommand(ILI9225_GAMMA_CTRL1);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_GAMMA_CTRL2);
writedata(0x08);writedata(0x08);
writecommand(ILI9225_GAMMA_CTRL3);
writedata(0x08);writedata(0x0A);
writecommand(ILI9225_GAMMA_CTRL4);
writedata(0x00);writedata(0x0A);
writecommand(ILI9225_GAMMA_CTRL5);
writedata(0x0A);writedata(0x08);
writecommand(ILI9225_GAMMA_CTRL6);
writedata(0x08);writedata(0x08);
writecommand(ILI9225_GAMMA_CTRL7);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_GAMMA_CTRL8);
writedata(0x0A);writedata(0x00);
writecommand(ILI9225_GAMMA_CTRL9);
writedata(0x07);writedata(0x10);
writecommand(ILI9225_GAMMA_CTRL10);
writedata(0x07);writedata(0x10);
writecommand(ILI9225_DISP_CTRL1);
writedata(0x00);writedata(0x12);
delay(50);
writecommand(ILI9225_DISP_CTRL1);
writedata(0x10);writedata(0x17);
}

View File

@ -0,0 +1,39 @@
// This is the command sequence that rotates the ILI9225 driver coordinate frame
rotation = m % 4; // Limit the range of values to 0-3
switch (rotation) {
case 0:
writecommand(ILI9225_DRIVER_OUTPUT_CTRL);
writedata(0x01);writedata(0x1C);
writecommand(ILI9225_ENTRY_MODE);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x30);
_width = _init_width;
_height = _init_height;
break;
case 1:
writecommand(ILI9225_DRIVER_OUTPUT_CTRL);
writedata(0x00);writedata(0x1C);
writecommand(ILI9225_ENTRY_MODE);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x38);
_width = _init_height;
_height = _init_width;
break;
case 2:
writecommand(ILI9225_DRIVER_OUTPUT_CTRL);
writedata(0x02);writedata(0x1C);
writecommand(ILI9225_ENTRY_MODE);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x30);
_width = _init_width;
_height = _init_height;
break;
case 3:
writecommand(ILI9225_DRIVER_OUTPUT_CTRL);
writedata(0x03);writedata(0x1C);
writecommand(ILI9225_ENTRY_MODE);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x38);
_width = _init_height;
_height = _init_width;
break;
}

View File

@ -1,8 +1,13 @@
// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
#if defined (ILI9341_DRIVER) || 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
// use colour definitions like TFT_BLACK to make sketches more portable

View File

@ -5,6 +5,7 @@
//
// See ST7735_Setup.h file for an alternative format
#if defined (ILI9341_DRIVER) || defined (ILI9342_DRIVER)
{
writecommand(0xEF);
writedata(0x03);
@ -115,10 +116,133 @@
writecommand(ILI9341_SLPOUT); //Exit Sleep
spi_end();
end_tft_write();
delay(120);
spi_begin();
begin_tft_write();
writecommand(ILI9341_DISPON); //Display on
}
}
#elif defined (ILI9341_2_DRIVER) // Alternative init sequence, see https://github.com/Bodmer/TFT_eSPI/issues/1172
{
writecommand(0xCF);
writedata(0x00);
writedata(0XC1);
writedata(0X30);
writecommand(0xED);
writedata(0x64);
writedata(0x03);
writedata(0X12);
writedata(0X81);
writecommand(0xE8);
writedata(0x85);
writedata(0x00);
writedata(0x78);
writecommand(0xCB);
writedata(0x39);
writedata(0x2C);
writedata(0x00);
writedata(0x34);
writedata(0x02);
writecommand(0xF7);
writedata(0x20);
writecommand(0xEA);
writedata(0x00);
writedata(0x00);
writecommand(ILI9341_PWCTR1); //Power control
writedata(0x10); //VRH[5:0]
writecommand(ILI9341_PWCTR2); //Power control
writedata(0x00); //SAP[2:0];BT[3:0]
writecommand(ILI9341_VMCTR1); //VCM control
writedata(0x30);
writedata(0x30);
writecommand(ILI9341_VMCTR2); //VCM control2
writedata(0xB7); //--
writecommand(ILI9341_PIXFMT);
writedata(0x55);
writecommand(0x36); // Memory Access Control
writedata(0x08); // Rotation 0 (portrait mode)
writecommand(ILI9341_FRMCTR1);
writedata(0x00);
writedata(0x1A);
writecommand(ILI9341_DFUNCTR); // Display Function Control
writedata(0x08);
writedata(0x82);
writedata(0x27);
writecommand(0xF2); // 3Gamma Function Disable
writedata(0x00);
writecommand(0x26); //Gamma curve selected
writedata(0x01);
writecommand(0xE0); //Set Gamma
writedata(0x0F);
writedata(0x2A);
writedata(0x28);
writedata(0x08);
writedata(0x0E);
writedata(0x08);
writedata(0x54);
writedata(0xA9);
writedata(0x43);
writedata(0x0A);
writedata(0x0F);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writecommand(0XE1); //Set Gamma
writedata(0x00);
writedata(0x15);
writedata(0x17);
writedata(0x07);
writedata(0x11);
writedata(0x06);
writedata(0x2B);
writedata(0x56);
writedata(0x3C);
writedata(0x05);
writedata(0x10);
writedata(0x0F);
writedata(0x3F);
writedata(0x3F);
writedata(0x0F);
writecommand(0x2B);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3f);
writecommand(0x2A);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0xef);
writecommand(ILI9341_SLPOUT); //Exit Sleep
end_tft_write();
delay(120);
begin_tft_write();
writecommand(ILI9341_DISPON); //Display on
}
#endif

View File

@ -5,7 +5,17 @@
//
// See ST7735_Setup.h file for an alternative format
#define ILI9481_INIT_1 // Original default
//#define ILI9481_INIT_2 // CPT29
//#define ILI9481_INIT_3 // PVI35
//#define ILI9481_INIT_4 // AUO317
//#define ILI9481_INIT_5 // CMO35 *****
//#define ILI9481_INIT_6 // RGB
//#define ILI9481_INIT_7 // From #1774
//#define ILI9481_INIT_8 // From #1774
/////////////////////////////////////////////////////////////////////////////////////////
#ifdef ILI9481_INIT_1
// Configure ILI9481 display
writecommand(TFT_SLPOUT);
@ -53,7 +63,15 @@
writedata(0x0A);
writecommand(0x3A);
writedata(0x55);
#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(TFT_CASET);
writedata(0x00);
@ -72,6 +90,647 @@
delay(25);
// End of ILI9481 display configuration
/////////////////////////////////////////////////////////////////////////////////////////
#elif defined (ILI9481_INIT_2)
// Configure ILI9481 display
writecommand(TFT_SLPOUT);
delay(20);
writecommand(0xD0);
writedata(0x07);
writedata(0x41);
writedata(0x1D);
writecommand(0xD1);
writedata(0x00);
writedata(0x2B);
writedata(0x1F);
writecommand(0xD2);
writedata(0x01);
writedata(0x11);
writecommand(0xC0);
writedata(0x10);
writedata(0x3B);
writedata(0x00);
writedata(0x02);
writedata(0x11);
writecommand(0xC5);
writedata(0x03);
writecommand(0xC8);
writedata(0x00);
writedata(0x14);
writedata(0x33);
writedata(0x10);
writedata(0x00);
writedata(0x16);
writedata(0x44);
writedata(0x36);
writedata(0x77);
writedata(0x00);
writedata(0x0F);
writedata(0x00);
writecommand(0xB0);
writedata(0x00);
writecommand(0xE4);
writedata(0xA0);
writecommand(0xF0);
writedata(0x01);
writecommand(0xF3);
writedata(0x02);
writedata(0x1A);
writecommand(TFT_MADCTL);
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(TFT_CASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);
writecommand(TFT_PASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDF);
delay(120);
writecommand(TFT_DISPON);
delay(25);
// End of ILI9481 display configuration
/////////////////////////////////////////////////////////////////////////////////////////
#elif defined (ILI9481_INIT_3)
// Configure ILI9481 display
writecommand(TFT_SLPOUT);
delay(20);
writecommand(0xD0);
writedata(0x07);
writedata(0x41);
writedata(0x1D);
writecommand(0xD1);
writedata(0x00);
writedata(0x2B);
writedata(0x1F);
writecommand(0xD2);
writedata(0x01);
writedata(0x11);
writecommand(0xC0);
writedata(0x10);
writedata(0x3B);
writedata(0x00);
writedata(0x02);
writedata(0x11);
writecommand(0xC5);
writedata(0x03);
writecommand(0xC8);
writedata(0x00);
writedata(0x14);
writedata(0x33);
writedata(0x10);
writedata(0x00);
writedata(0x16);
writedata(0x44);
writedata(0x36);
writedata(0x77);
writedata(0x00);
writedata(0x0F);
writedata(0x00);
writecommand(0xB0);
writedata(0x00);
writecommand(0xE4);
writedata(0xA0);
writecommand(0xF0);
writedata(0x01);
writecommand(0xF3);
writedata(0x40);
writedata(0x0A);
writecommand(TFT_MADCTL);
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(TFT_CASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);
writecommand(TFT_PASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDF);
delay(120);
writecommand(TFT_DISPON);
delay(25);
// End of ILI9481 display configuration
/////////////////////////////////////////////////////////////////////////////////////////
#elif defined (ILI9481_INIT_4)
// Configure ILI9481 display
writecommand(TFT_SLPOUT);
delay(20);
writecommand(0xD0);
writedata(0x07);
writedata(0x40);
writedata(0x1D);
writecommand(0xD1);
writedata(0x00);
writedata(0x18);
writedata(0x13);
writecommand(0xD2);
writedata(0x01);
writedata(0x11);
writecommand(0xC0);
writedata(0x10);
writedata(0x3B);
writedata(0x00);
writedata(0x02);
writedata(0x11);
writecommand(0xC5);
writedata(0x03);
writecommand(0xC8);
writedata(0x00);
writedata(0x44);
writedata(0x06);
writedata(0x44);
writedata(0x0A);
writedata(0x08);
writedata(0x17);
writedata(0x33);
writedata(0x77);
writedata(0x44);
writedata(0x08);
writedata(0x0C);
writecommand(0xB0);
writedata(0x00);
writecommand(0xE4);
writedata(0xA0);
writecommand(0xF0);
writedata(0x01);
writecommand(TFT_MADCTL);
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(TFT_CASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);
writecommand(TFT_PASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDF);
delay(120);
writecommand(TFT_DISPON);
delay(25);
// End of ILI9481 display configuration
/////////////////////////////////////////////////////////////////////////////////////////
#elif defined (ILI9481_INIT_5)
// Configure ILI9481 display
writecommand(TFT_SLPOUT);
delay(20);
writecommand(0xD0);
writedata(0x07);
writedata(0x41);
writedata(0x1D);
writecommand(0xD1);
writedata(0x00);
writedata(0x1C);
writedata(0x1F);
writecommand(0xD2);
writedata(0x01);
writedata(0x11);
writecommand(0xC0);
writedata(0x10);
writedata(0x3B);
writedata(0x00);
writedata(0x02);
writedata(0x11);
writecommand(0xC5);
writedata(0x03);
writecommand(0xC6);
writedata(0x83);
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);
writecommand(0xB0);
writedata(0x00);
writecommand(0xE4);
writedata(0xA0);
writecommand(0xF0);
writedata(0x01);
writecommand(TFT_MADCTL);
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(TFT_CASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);
writecommand(TFT_PASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDF);
delay(120);
writecommand(TFT_DISPON);
delay(25);
// End of ILI9481 display configuration
/////////////////////////////////////////////////////////////////////////////////////////
#elif defined (ILI9481_INIT_6)
// Configure ILI9481 display
writecommand(TFT_SLPOUT);
delay(20);
writecommand(0xD0);
writedata(0x07);
writedata(0x41);
writedata(0x1D);
writecommand(0xD1);
writedata(0x00);
writedata(0x2B);
writedata(0x1F);
writecommand(0xD2);
writedata(0x01);
writedata(0x11);
writecommand(0xC0);
writedata(0x10);
writedata(0x3B);
writedata(0x00);
writedata(0x02);
writedata(0x11);
writedata(0x00);
writecommand(0xC5);
writedata(0x03);
writecommand(0xC6);
writedata(0x80);
writecommand(0xC8);
writedata(0x00);
writedata(0x14);
writedata(0x33);
writedata(0x10);
writedata(0x00);
writedata(0x16);
writedata(0x44);
writedata(0x36);
writedata(0x77);
writedata(0x00);
writedata(0x0F);
writedata(0x00);
writecommand(0xB0);
writedata(0x00);
writecommand(0xE4);
writedata(0xA0);
writecommand(0xF0);
writedata(0x08);
writecommand(0xF3);
writedata(0x40);
writedata(0x0A);
writecommand(0xF6);
writedata(0x84);
writecommand(0xF7);
writedata(0x80);
writecommand(0xB3);
writedata(0x00);
writedata(0x01);
writedata(0x06);
writedata(0x30);
writecommand(0xB4);
writedata(0x00);
writecommand(0x0C);
writedata(0x00);
writedata(0x55);
writecommand(TFT_MADCTL);
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(TFT_CASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);
writecommand(TFT_PASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDF);
delay(120);
writecommand(TFT_DISPON);
delay(25);
// 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

View File

@ -8,17 +8,27 @@
{
// From https://github.com/notro/fbtft/blob/master/fb_ili9486.c
//writecommand(0x01); // SW reset
//delay(120);
writecommand(0x01); // SW reset
delay(120);
writecommand(0x11); // Sleep out, also SW reset
delay(120);
writecommand(0x3A);
writedata(0x55);
writecommand(0xC2);
writedata(0x44);
#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
writecommand(0xC0); // 1100.0000 Power Control 1
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);
writedata(0x00);
@ -60,8 +70,12 @@
writedata(0x20);
writedata(0x00);
writecommand(0x20); // display inversion OFF
#if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writecommand(TFT_INVOFF);
#else
writecommand(TFT_INVON);
#endif
writecommand(0x36);
writedata(0x48);

View File

@ -58,7 +58,7 @@
writedata(0x48); // MX, BGR
writecommand(0x3A); // Pixel Interface Format
#if defined (ESP32_PARALLEL)
#if defined (TFT_PARALLEL_8_BIT) || defined (TFT_PARALLEL_16_BIT) || defined (RPI_DISPLAY_TYPE)
writedata(0x55); // 16 bit colour for parallel
#else
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

@ -0,0 +1,20 @@
#ifndef TFT_WIDTH
#define TFT_WIDTH 128
#endif
#ifndef TFT_HEIGHT
#define TFT_HEIGHT 128
#endif
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80
// Generic commands used by TFT_eSPI.cpp
#define TFT_NOP 0x00
#define TFT_SWRST TFT_NOP
#define TFT_CASET 0x15 // SETCOLUMN
#define TFT_PASET 0x75 // SETROW
#define TFT_RAMWR 0x5C // WRITERAM
#define TFT_RAMRD 0x5D // READRAM
#define TFT_IDXRD TFT_NOP
#define TFT_INVOFF 0xA6 // NORMALDISPLAY
#define TFT_INVON 0xA7 // INVERTDISPLAY

View File

@ -0,0 +1,35 @@
{
writecommand(0xFD); // COMMANDLOCK
writedata(0x12);
writecommand(0xFD); // COMMANDLOCK
writedata(0xB1);
writecommand(0xAE); // DISPLAYOFF
writecommand(0xB3); // CLOCKDIV
writedata(0xF1);
writecommand(0xCA); // MUXRATIO
writedata(127);
writecommand(0xA2); // DISPLAYOFFSET
writedata(0x00);
writecommand(0xB5); // SETGPIO
writedata(0x00);
writecommand(0xAB); // FUNCTIONSELECT
writedata(0x01);
writecommand(0xB1); // PRECHARGE
writedata(0x32);
writecommand(0xBE); // VCOMH
writedata(0x05);
writecommand(0xA6); // NORMALDISPLAY
writecommand(0xC1); // CONTRASTABC
writedata(0xC8);
writedata(0x80);
writedata(0xC8);
writecommand(0xC7); // CONTRASTMASTER
writedata(0x0F);
writecommand(0xB4); // SETVSL
writedata(0xA0);
writedata(0xB5);
writedata(0x55);
writecommand(0xB6); // PRECHARGE2
writedata(0x01);
writecommand(0xAF); // DISPLAYON
}

View File

@ -0,0 +1,34 @@
// This is the command sequence that rotates the SSD1351 driver coordinate frame
rotation = m % 4; // Limit the range of values to 0-3
uint8_t madctl = 0x64;
switch (rotation) {
case 0:
madctl |= 0x10;
_width = _init_width;
_height = _init_height;
break;
case 1:
madctl |= 0x13;
_width = _init_height;
_height = _init_width;
break;
case 2:
madctl |= 0x02;
_width = _init_width;
_height = _init_height;
break;
case 3:
madctl |= 0x01;
_width = _init_height;
_height = _init_width;
break;
}
writecommand(0xA0); // SETREMAP
writedata(madctl);
writecommand(0xA1); // STARTLINE
writedata(rotation < 2 ? TFT_HEIGHT : 0);

View File

@ -0,0 +1,56 @@
// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
#if defined (SSD1963_480_DRIVER)
#define TFT_WIDTH 272
#define TFT_HEIGHT 480
#elif defined (SSD1963_800_DRIVER)
#define TFT_WIDTH 480
#define TFT_HEIGHT 800
#elif defined (SSD1963_800ALT_DRIVER)
#define TFT_WIDTH 480
#define TFT_HEIGHT 800
#elif defined (SSD1963_800BD_DRIVER)
#define TFT_WIDTH 480
#define TFT_HEIGHT 800
#endif
//Set driver type common to all initialisation options
#ifndef SSD1963_DRIVER
#define SSD1963_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 0x00
#define TFT_SWRST 0x01
#define TFT_CASET 0x2A
#define TFT_PASET 0x2B
#define TFT_RAMWR 0x2C
#define TFT_RAMRD 0x2E
#define TFT_IDXRD 0xDD // ILI9341 only, indexed control register read
#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_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_BGR
#endif
#define TFT_INVOFF 0x20
#define TFT_INVON 0x21

398
TFT_Drivers/SSD1963_Init.h Normal file
View File

@ -0,0 +1,398 @@
#if defined (SSD1963_480_DRIVER)
writecommand(0xE2); //PLL multiplier, set PLL clock to 120M
writedata(0x23); //N=0x36 for 6.5M, 0x23 for 10M crystal
writedata(0x02);
writedata(0x54);
writecommand(0xE0); // PLL enable
writedata(0x01);
delay(10);
writecommand(0xE0);
writedata(0x03);
delay(10);
writecommand(0x01); // software reset
delay(100);
writecommand(0xE6); //PLL setting for PCLK, depends on resolution
writedata(0x01);
writedata(0x1F);
writedata(0xFF);
writecommand(0xB0); //LCD SPECIFICATION
writedata(0x20);
writedata(0x00);
writedata(0x01); //Set HDP 479
writedata(0xDF);
writedata(0x01); //Set VDP 271
writedata(0x0F);
writedata(0x00);
writecommand(0xB4); //HSYNC
writedata(0x02); //Set HT 531
writedata(0x13);
writedata(0x00); //Set HPS 8
writedata(0x08);
writedata(0x2B); //Set HPW 43
writedata(0x00); //Set LPS 2
writedata(0x02);
writedata(0x00);
writecommand(0xB6); //VSYNC
writedata(0x01); //Set VT 288
writedata(0x20);
writedata(0x00); //Set VPS 4
writedata(0x04);
writedata(0x0c); //Set VPW 12
writedata(0x00); //Set FPS 2
writedata(0x02);
writecommand(0xBA);
writedata(0x0F); //GPIO[3:0] out 1
writecommand(0xB8);
writedata(0x07); //GPIO3=input, GPIO[2:0]=output
writedata(0x01); //GPIO0 normal
writecommand(0x36); //rotation
writedata(0x21 | TFT_MAD_COLOR_ORDER);
writecommand(0xF0); //pixel data interface
writedata(0x00); //8 bit bus
delay(1);
writecommand(0xB8);
writedata(0x0f); //GPIO is controlled by host GPIO[3:0]=output GPIO[0]=1 LCD ON GPIO[0]=1 LCD OFF
writedata(0x01); //GPIO0 normal
writecommand(0xBA);
writedata(0x01); //GPIO[0] out 1 --- LCD display on/off control PIN
writecommand(0x2A);
writedata(0);
writedata(0);
writedata((271 & 0xFF00)>>8);
writedata(271 & 0xFF);
writecommand(0x2B);
writedata(0);
writedata(0);
writedata((479 & 0xFF00)>>8);
writedata(479 & 0xFF);
writecommand(0x2C);
writecommand(0x29); //display on
writecommand(0xBE); //set PWM for B/L
writedata(0x06);
writedata(0xf0);
writedata(0x01);
writedata(0xf0);
writedata(0x00);
writedata(0x00);
writecommand(0xd0);
writedata(0x0d);
writecommand(0x2C);
#elif defined (SSD1963_800_DRIVER)
writecommand(0xE2); //PLL multiplier, set PLL clock to 120M
writedata(0x1E); //N=0x36 for 6.5M, 0x23 for 10M crystal
writedata(0x02);
writedata(0x54);
writecommand(0xE0); // PLL enable
writedata(0x01);
delay(10);
writecommand(0xE0);
writedata(0x03);
delay(10);
writecommand(0x01); // software reset
delay(100);
writecommand(0xE6); //PLL setting for PCLK, depends on resolution
writedata(0x03);
writedata(0xFF);
writedata(0xFF);
writecommand(0xB0); //LCD SPECIFICATION
writedata(0x20);
writedata(0x00);
writedata(0x03); //Set HDP 799
writedata(0x1F);
writedata(0x01); //Set VDP 479
writedata(0xDF);
writedata(0x00);
writecommand(0xB4); //HSYNC
writedata(0x03); //Set HT 928
writedata(0xA0);
writedata(0x00); //Set HPS 46
writedata(0x2E);
writedata(0x30); //Set HPW 48
writedata(0x00); //Set LPS 15
writedata(0x0F);
writedata(0x00);
writecommand(0xB6); //VSYNC
writedata(0x02); //Set VT 525
writedata(0x0D);
writedata(0x00); //Set VPS 16
writedata(0x10);
writedata(0x10); //Set VPW 16
writedata(0x00); //Set FPS 8
writedata(0x08);
writecommand(0xBA);
writedata(0x0F); //GPIO[3:0] out 1
writecommand(0xB8);
writedata(0x07); //GPIO3=input, GPIO[2:0]=output
writedata(0x01); //GPIO0 normal
writecommand(0x36); //rotation
writedata(0x21 | TFT_MAD_COLOR_ORDER);
writecommand(0xF0); //pixel data interface
writedata(0x00); //8 bit bus
delay(1);
writecommand(0xB8);
writedata(0x0f); //GPIO is controlled by host GPIO[3:0]=output GPIO[0]=1 LCD ON GPIO[0]=1 LCD OFF
writedata(0x01); //GPIO0 normal
writecommand(0xBA);
writedata(0x01); //GPIO[0] out 1 --- LCD display on/off control PIN
writecommand(0x2A);
writedata(0);
writedata(0);
writedata((479 & 0xFF00)>>8);
writedata(479 & 0xFF);
writecommand(0x2B);
writedata(0);
writedata(0);
writedata((799 & 0xFF00)>>8);
writedata(799 & 0xFF);
writecommand(0x2C);
writecommand(0x29); //display on
writecommand(0xBE); //set PWM for B/L
writedata(0x06);
writedata(0xf0);
writedata(0x01);
writedata(0xf0);
writedata(0x00);
writedata(0x00);
writecommand(0xd0);
writedata(0x0d);
writecommand(0x2C);
#elif defined (SSD1963_800ALT_DRIVER)
writecommand(0xE2); //PLL multiplier, set PLL clock to 120M
writedata(0x23); //N=0x36 for 6.5M, 0x23 for 10M crystal
writedata(0x02);
writedata(0x04);
writecommand(0xE0); // PLL enable
writedata(0x01);
delay(10);
writecommand(0xE0);
writedata(0x03);
delay(10);
writecommand(0x01); // software reset
delay(100);
writecommand(0xE6); //PLL setting for PCLK, depends on resolution
writedata(0x04);
writedata(0x93);
writedata(0xE0);
writecommand(0xB0); //LCD SPECIFICATION
writedata(0x00); // 0x24
writedata(0x00);
writedata(0x03); //Set HDP 799
writedata(0x1F);
writedata(0x01); //Set VDP 479
writedata(0xDF);
writedata(0x00);
writecommand(0xB4); //HSYNC
writedata(0x03); //Set HT 928
writedata(0xA0);
writedata(0x00); //Set HPS 46
writedata(0x2E);
writedata(0x30); //Set HPW 48
writedata(0x00); //Set LPS 15
writedata(0x0F);
writedata(0x00);
writecommand(0xB6); //VSYNC
writedata(0x02); //Set VT 525
writedata(0x0D);
writedata(0x00); //Set VPS 16
writedata(0x10);
writedata(0x10); //Set VPW 16
writedata(0x00); //Set FPS 8
writedata(0x08);
writecommand(0xBA);
writedata(0x05); //GPIO[3:0] out 1
writecommand(0xB8);
writedata(0x07); //GPIO3=input, GPIO[2:0]=output
writedata(0x01); //GPIO0 normal
writecommand(0x36); //rotation
writedata(0x21 | TFT_MAD_COLOR_ORDER); // -- Set rotation
writecommand(0xF0); //pixel data interface
writedata(0x00); //8 bit bus
delay(10);
writecommand(0x2A);
writedata(0);
writedata(0);
writedata((479 & 0xFF00)>>8);
writedata(479 & 0xFF);
writecommand(0x2B);
writedata(0);
writedata(0);
writedata((799 & 0xFF00)>>8);
writedata(799 & 0xFF);
writecommand(0x2C);
writecommand(0x29); //display on
writecommand(0xBE); //set PWM for B/L
writedata(0x06);
writedata(0xF0);
writedata(0x01);
writedata(0xF0);
writedata(0x00);
writedata(0x00);
writecommand(0xD0);
writedata(0x0D);
writecommand(0x2C);
#elif defined (SSD1963_800BD_DRIVER) // Copied from Buy Display code
writecommand(0xE2); //PLL multiplier, set PLL clock to 120M
writedata(0x23); //N=0x36 for 6.5M, 0x23 for 10M crystal
writedata(0x02);
writedata(0x54);
writecommand(0xE0); // PLL enable
writedata(0x01);
delay(10);
writecommand(0xE0);
writedata(0x03);
delay(10);
writecommand(0x01); // software reset
delay(100);
writecommand(0xE6); //PLL setting for PCLK, depends on resolution
writedata(0x03);
writedata(0x33);
writedata(0x33);
writecommand(0xB0); //LCD SPECIFICATION
writedata(0x20);
writedata(0x00);
writedata(799 >> 8); //Set HDP 799
writedata(799 & 0xFF);
writedata(479 >> 8); //Set VDP 479
writedata(479 & 0xFF);
writedata(0x00);
writecommand(0xB4); //HSYNC
writedata(0x04); //Set HT
writedata(0x1F);
writedata(0x00); //Set HPS
writedata(0xD2);
writedata(0x00); //Set HPW
writedata(0x00); //Set LPS
writedata(0x00);
writedata(0x00);
writecommand(0xB6); //VSYNC
writedata(0x02); //Set VT
writedata(0x0C);
writedata(0x00); //Set VPS
writedata(0x22);
writedata(0x00); //Set VPW
writedata(0x00); //Set FPS
writedata(0x00);
writecommand(0xB8);
writedata(0x0F); //GPIO3=input, GPIO[2:0]=output
writedata(0x01); //GPIO0 normal
writecommand(0xBA);
writedata(0x01); //GPIO[0] out 1 --- LCD display on/off control PIN
writecommand(0x36); //rotation
writedata(0x21 | TFT_MAD_COLOR_ORDER); //set to rotate
//writecommand(0x003A); //Set the current pixel format for RGB image data
//writedata(0x0050); //16-bit/pixel
writecommand(0xF0); //pixel data interface
writedata(0x00); //000 = 8 bit bus, 011 = 16 bit, 110 = 9 bit
writecommand(0xBC);
writedata(0x40); //contrast value
writedata(0x80); //brightness value
writedata(0x40); //saturation value
writedata(0x01); //Post Processor Enable
delay(10);
writecommand(0x29); //display on
writecommand(0xBE); //set PWM for B/L
writedata(0x06);
writedata(0x80);
writedata(0x01);
writedata(0xF0);
writedata(0x00);
writedata(0x00);
writecommand(0xD0);
writedata(0x0D);
#endif

View File

@ -0,0 +1,29 @@
// This is the command sequence that rotates the SSD1963 driver coordinate frame
rotation = m % 4; // Limit the range of values to 0-3
writecommand(TFT_MADCTL);
switch (rotation) {
case 0:
writedata(0x21 | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 1:
writedata(0x00 | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
case 2:
writedata(0x22 | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 3:
writedata(0x03 | 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_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_ROBOTLCD 0x8
#define INITB 0xB
@ -44,6 +45,10 @@
#define TAB_COLOUR INITR_GREENTAB160x80
#define CGRAM_OFFSET
#elif defined (ST7735_ROBOTLCD)
#define TAB_COLOUR INITR_ROBOTLCD
#define CGRAM_OFFSET
#elif defined (ST7735_REDTAB160x80)
#define TAB_COLOUR INITR_REDTAB160x80
#define CGRAM_OFFSET
@ -106,6 +111,20 @@
#define TFT_MAD_MH 0x04
#define TFT_MAD_RGB 0x00
#ifndef TFT_RGB_ORDER
#if defined(ST7735_BLACKTAB) || defined(ST7735_GREENTAB2) || defined(ST7735_INITB)
#define TFT_MAD_COLOR_ORDER TFT_MAD_RGB
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
#else
#if (TFT_RGB_ORDER == 1)
#define TFT_MAD_COLOR_ORDER TFT_MAD_RGB
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
#endif
#define TFT_INVOFF 0x20
#define TFT_INVON 0x21

View File

@ -24,7 +24,7 @@
0x03, // 3 lines back porch
10, // 10 ms delay
ST7735_MADCTL , 1 , // 5: Memory access ctrl (directions), 1 arg:
0x40, // Row addr/col addr, bottom to top refresh
0x40 | TFT_MAD_COLOR_ORDER, // Row addr/col addr, bottom to top refresh
ST7735_DISSET5, 2 , // 6: Display settings #5, 2 args, no delay:
0x15, // 1 clk cycle nonoverlap, 2 cycle gate
// rise, 3 cycle osc equalize
@ -101,7 +101,7 @@
0x0E,
ST7735_INVOFF , 0 , // 13: Don't invert display, no args, no delay
ST7735_MADCTL , 1 , // 14: Memory access control (directions), 1 arg:
0xC8, // row addr/col addr, bottom to top refresh
0xC0 | TFT_MAD_COLOR_ORDER, // row addr/col addr, bottom to top refresh
ST7735_COLMOD , 1 , // 15: set color mode, 1 arg, no delay:
0x05 }, // 16-bit color
@ -123,6 +123,17 @@
0x00, 0x00, // XSTART = 0
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)
4, // 4 commands in list:
ST7735_GMCTRP1, 16 , // 1: 16 args, no delay:
@ -146,7 +157,8 @@
}
else
{
commandList(Rcmd1);
commandList(Rcmd1);
if (tabcolor == INITR_GREENTAB)
{
commandList(Rcmd2green);
@ -157,7 +169,7 @@
{
commandList(Rcmd2green);
writecommand(ST7735_MADCTL);
writedata(0xC0);
writedata(0xC0 | TFT_MAD_COLOR_ORDER);
colstart = 2;
rowstart = 1;
}
@ -180,6 +192,11 @@
colstart = 26;
rowstart = 1;
}
else if (tabcolor == INITR_ROBOTLCD)
{
commandList(Rcmd2green);
commandList(Rcmd3RobotLCD);
}
else if (tabcolor == INITR_REDTAB160x80)
{
commandList(Rcmd2green);
@ -193,8 +210,9 @@
else if (tabcolor == INITR_BLACKTAB)
{
writecommand(ST7735_MADCTL);
writedata(0xC0);
writedata(0xC0 | TFT_MAD_COLOR_ORDER);
}
commandList(Rcmd3);
}
}

View File

@ -7,149 +7,126 @@
switch (rotation) {
case 0:
if (tabcolor == INITR_BLACKTAB) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_RGB);
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
} else if(tabcolor == INITR_GREENTAB2) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_RGB);
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
colstart = 2;
rowstart = 1;
} else if(tabcolor == INITR_GREENTAB3) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_BGR);
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
colstart = 2;
rowstart = 3;
} else if(tabcolor == INITR_GREENTAB128) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_BGR);
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_COLOR_ORDER);
colstart = 0;
rowstart = 32;
} else if(tabcolor == INITR_GREENTAB160x80) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_BGR);
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_COLOR_ORDER);
colstart = 26;
rowstart = 1;
} else if(tabcolor == INITR_REDTAB160x80) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_BGR);
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_COLOR_ORDER);
colstart = 24;
rowstart = 0;
} else if(tabcolor == INITB) {
writedata(TFT_MAD_MX | TFT_MAD_RGB);
writedata(TFT_MAD_MX | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_BGR);
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
}
_width = _init_width;
_height = _init_height;
break;
case 1:
if (tabcolor == INITR_BLACKTAB) {
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_RGB);
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
} else if(tabcolor == INITR_GREENTAB2) {
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_RGB);
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
colstart = 1;
rowstart = 2;
} else if(tabcolor == INITR_GREENTAB3) {
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_BGR);
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
colstart = 3;
rowstart = 2;
} else if(tabcolor == INITR_GREENTAB128) {
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_BGR);
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
colstart = 32;
rowstart = 0;
} else if(tabcolor == INITR_GREENTAB160x80) {
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_BGR);
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
colstart = 1;
rowstart = 26;
} else if(tabcolor == INITR_REDTAB160x80) {
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_BGR);
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
colstart = 0;
rowstart = 24;
} else if(tabcolor == INITB) {
writedata(TFT_MAD_MV | TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_RGB);
writedata(TFT_MAD_MV | TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_BGR);
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
}
_width = _init_height;
_height = _init_width;
break;
case 2:
if (tabcolor == INITR_BLACKTAB) {
writedata(TFT_MAD_RGB);
writedata(TFT_MAD_COLOR_ORDER);
} else if(tabcolor == INITR_GREENTAB2) {
writedata(TFT_MAD_RGB);
writedata(TFT_MAD_COLOR_ORDER);
colstart = 2;
rowstart = 1;
} else if(tabcolor == INITR_GREENTAB3) {
writedata(TFT_MAD_BGR);
writedata(TFT_MAD_COLOR_ORDER);
colstart = 2;
rowstart = 1;
} else if(tabcolor == INITR_GREENTAB128) {
writedata(TFT_MAD_BGR);
writedata(TFT_MAD_COLOR_ORDER);
colstart = 0;
rowstart = 0;
} else if(tabcolor == INITR_GREENTAB160x80) {
writedata(TFT_MAD_BGR);
colstart = 0;
rowstart = 0;
writedata(TFT_MAD_COLOR_ORDER);
colstart = 26;
rowstart = 1;
} else if(tabcolor == INITR_REDTAB160x80) {
writedata(TFT_MAD_BGR);
writedata(TFT_MAD_COLOR_ORDER);
colstart = 24;
rowstart = 0;
} else if(tabcolor == INITB) {
writedata(TFT_MAD_MY | TFT_MAD_RGB);
writedata(TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_BGR);
writedata(TFT_MAD_COLOR_ORDER);
}
_width = _init_width;
_height = _init_height;
break;
case 3:
if (tabcolor == INITR_BLACKTAB) {
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_RGB);
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
} else if(tabcolor == INITR_GREENTAB2) {
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_RGB);
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
colstart = 1;
rowstart = 2;
} else if(tabcolor == INITR_GREENTAB3) {
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
colstart = 1;
rowstart = 2;
} else if(tabcolor == INITR_GREENTAB128) {
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
colstart = 0;
rowstart = 0;
} else if(tabcolor == INITR_GREENTAB160x80) {
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
colstart = 1;
rowstart = 26;
} else if(tabcolor == INITR_REDTAB160x80) {
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
colstart = 0;
rowstart = 24;
} else if(tabcolor == INITB) {
writedata(TFT_MAD_MV | TFT_MAD_RGB);
writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
}
_width = _init_height;
_height = _init_width;
break;
// These next rotations are for bottum up BMP drawing
/* case 4:
writedata(ST7735_TFT_MAD_MX | ST7735_TFT_MAD_MY | ST7735_TFT_MAD_BGR);
_width = _init_width;
_height = _init_height;
break;
case 5:
writedata(ST7735_TFT_MAD_MV | ST7735_TFT_MAD_MX | ST7735_TFT_MAD_BGR);
_width = _init_height;
_height = _init_width;
break;
case 6:
writedata(ST7735_TFT_MAD_BGR);
_width = _init_width;
_height = _init_height;
break;
case 7:
writedata(ST7735_TFT_MAD_MY | ST7735_TFT_MAD_MV | ST7735_TFT_MAD_BGR);
_width = _init_height;
_height = _init_width;
break;
*/
}

View File

@ -8,7 +8,42 @@
#endif
#if (TFT_HEIGHT == 240) && (TFT_WIDTH == 240)
#define CGRAM_OFFSET
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#endif
#endif
// Adafruit 1.44 TFT support
#if (TFT_HEIGHT == 240) && (TFT_WIDTH == 135)
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#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

View File

@ -5,8 +5,31 @@
switch (rotation) {
case 0: // Portrait
#ifdef CGRAM_OFFSET
colstart = 0;
rowstart = 0;
if (_init_width == 135)
{
colstart = 52;
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
{
colstart = 0;
rowstart = 0;
}
#endif
writedata(TFT_MAD_COLOR_ORDER);
@ -16,8 +39,31 @@
case 1: // Landscape (Portrait + 90)
#ifdef CGRAM_OFFSET
colstart = 0;
rowstart = 0;
if (_init_width == 135)
{
colstart = 40;
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
{
colstart = 0;
rowstart = 0;
}
#endif
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
@ -25,10 +71,33 @@
_height = _init_width;
break;
case 2: // Inverter portrait
case 2: // Inverter portrait
#ifdef CGRAM_OFFSET
colstart = 0;
rowstart = 80;
if (_init_width == 135)
{
colstart = 53;
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
{
colstart = 0;
rowstart = 80;
}
#endif
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
@ -37,8 +106,31 @@
break;
case 3: // Inverted landscape
#ifdef CGRAM_OFFSET
colstart = 80;
rowstart = 0;
if (_init_width == 135)
{
colstart = 40;
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
{
colstart = 80;
rowstart = 0;
}
#endif
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);

View File

@ -8,7 +8,42 @@
#endif
#if (TFT_HEIGHT == 240) && (TFT_WIDTH == 240)
#define CGRAM_OFFSET
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#endif
#endif
// Adafruit 1.44 TFT support
#if (TFT_HEIGHT == 240) && (TFT_WIDTH == 135)
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#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
@ -95,6 +130,7 @@
#define ST7789_TEOFF 0x34 // Tearing effect line off
#define ST7789_TEON 0x35 // Tearing effect line on
#define ST7789_MADCTL 0x36 // Memory data access control
#define ST7789_VSCRSADD 0x37 // Vertical screoll address
#define ST7789_IDMOFF 0x38 // Idle mode off
#define ST7789_IDMON 0x39 // Idle mode on
#define ST7789_RAMWRC 0x3C // Memory write continue (ST7789V)

View File

@ -5,6 +5,7 @@
//
// See ST7735_Setup.h file for an alternative format
#ifndef INIT_SEQUENCE_3
{
writecommand(ST7789_SLPOUT); // Sleep out
delay(120);
@ -21,6 +22,10 @@
writedata(0x0A);
writedata(0x82);
writecommand(ST7789_RAMCTRL);
writedata(0x00);
writedata(0xE0); // 5 to 6 bit conversion: r0 = r5, b0 = b5
writecommand(ST7789_COLMOD);
writedata(0x55);
delay(10);
@ -99,7 +104,7 @@
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0xE5); // 239
writedata(0xEF); // 239
writecommand(ST7789_RASET); // Row address set
writedata(0x00);
@ -109,9 +114,9 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
spi_end();
end_tft_write();
delay(120);
spi_begin();
begin_tft_write();
writecommand(ST7789_DISPON); //Display on
delay(120);
@ -122,3 +127,111 @@
pinMode(TFT_BL, OUTPUT);
#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

@ -10,6 +10,21 @@
colstart = 52;
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
{
colstart = 0;
@ -29,6 +44,21 @@
colstart = 40;
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
{
colstart = 0;
@ -48,6 +78,21 @@
colstart = 53;
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
{
colstart = 0;
@ -66,6 +111,21 @@
colstart = 40;
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
{
colstart = 80;

View File

@ -0,0 +1,100 @@
// 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
// Generic commands used by TFT_eSPI.cpp
#define TFT_NOP 0x00
#define TFT_SWRST 0x01
#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_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_BGR
#endif
#define TFT_INVOFF 0x20
#define TFT_INVON 0x21
// ST7796 specific commands
#define ST7796_NOP 0x00
#define ST7796_SWRESET 0x01
#define ST7796_RDDID 0x04
#define ST7796_RDDST 0x09
#define ST7796_SLPIN 0x10
#define ST7796_SLPOUT 0x11
#define ST7796_PTLON 0x12
#define ST7796_NORON 0x13
#define ST7796_RDMODE 0x0A
#define ST7796_RDMADCTL 0x0B
#define ST7796_RDPIXFMT 0x0C
#define ST7796_RDIMGFMT 0x0A
#define ST7796_RDSELFDIAG 0x0F
#define ST7796_INVOFF 0x20
#define ST7796_INVON 0x21
#define ST7796_DISPOFF 0x28
#define ST7796_DISPON 0x29
#define ST7796_CASET 0x2A
#define ST7796_PASET 0x2B
#define ST7796_RAMWR 0x2C
#define ST7796_RAMRD 0x2E
#define ST7796_PTLAR 0x30
#define ST7796_VSCRDEF 0x33
#define ST7796_MADCTL 0x36
#define ST7796_VSCRSADD 0x37
#define ST7796_PIXFMT 0x3A
#define ST7796_WRDISBV 0x51
#define ST7796_RDDISBV 0x52
#define ST7796_WRCTRLD 0x53
#define ST7796_FRMCTR1 0xB1
#define ST7796_FRMCTR2 0xB2
#define ST7796_FRMCTR3 0xB3
#define ST7796_INVCTR 0xB4
#define ST7796_DFUNCTR 0xB6
#define ST7796_PWCTR1 0xC0
#define ST7796_PWCTR2 0xC1
#define ST7796_PWCTR3 0xC2
#define ST7796_VMCTR1 0xC5
#define ST7796_VMCOFF 0xC6
#define ST7796_RDID4 0xD3
#define ST7796_GMCTRP1 0xE0
#define ST7796_GMCTRN1 0xE1
#define ST7796_MADCTL_MY 0x80
#define ST7796_MADCTL_MX 0x40
#define ST7796_MADCTL_MV 0x20
#define ST7796_MADCTL_ML 0x10
#define ST7796_MADCTL_RGB 0x00
#define ST7796_MADCTL_BGR 0x08
#define ST7796_MADCTL_MH 0x04

107
TFT_Drivers/ST7796_Init.h Normal file
View File

@ -0,0 +1,107 @@
// This is the command sequence that initialises the ST7796 driver
//
// This setup information uses simple 8 bit SPI writecommand() and writedata() functions
//
// See ST7735_Setup.h file for an alternative format
#define TFT_INIT_DELAY 0
{
delay(120);
writecommand(0x01); //Software reset
delay(120);
writecommand(0x11); //Sleep exit
delay(120);
writecommand(0xF0); //Command Set control
writedata(0xC3); //Enable extension command 2 partI
writecommand(0xF0); //Command Set control
writedata(0x96); //Enable extension command 2 partII
writecommand(0x36); //Memory Data Access Control MX, MY, RGB mode
writedata(0x48); //X-Mirror, Top-Left to right-Buttom, RGB
writecommand(0x3A); //Interface Pixel Format
writedata(0x55); //Control interface color format set to 16
writecommand(0xB4); //Column inversion
writedata(0x01); //1-dot inversion
writecommand(0xB6); //Display Function Control
writedata(0x80); //Bypass
writedata(0x02); //Source Output Scan from S1 to S960, Gate Output scan from G1 to G480, scan cycle=2
writedata(0x3B); //LCD Drive Line=8*(59+1)
writecommand(0xE8); //Display Output Ctrl Adjust
writedata(0x40);
writedata(0x8A);
writedata(0x00);
writedata(0x00);
writedata(0x29); //Source eqaulizing period time= 22.5 us
writedata(0x19); //Timing for "Gate start"=25 (Tclk)
writedata(0xA5); //Timing for "Gate End"=37 (Tclk), Gate driver EQ function ON
writedata(0x33);
writecommand(0xC1); //Power control2
writedata(0x06); //VAP(GVDD)=3.85+( vcom+vcom offset), VAN(GVCL)=-3.85+( vcom+vcom offset)
writecommand(0xC2); //Power control 3
writedata(0xA7); //Source driving current level=low, Gamma driving current level=High
writecommand(0xC5); //VCOM Control
writedata(0x18); //VCOM=0.9
delay(120);
//ST7796 Gamma Sequence
writecommand(0xE0); //Gamma"+"
writedata(0xF0);
writedata(0x09);
writedata(0x0b);
writedata(0x06);
writedata(0x04);
writedata(0x15);
writedata(0x2F);
writedata(0x54);
writedata(0x42);
writedata(0x3C);
writedata(0x17);
writedata(0x14);
writedata(0x18);
writedata(0x1B);
writecommand(0xE1); //Gamma"-"
writedata(0xE0);
writedata(0x09);
writedata(0x0B);
writedata(0x06);
writedata(0x04);
writedata(0x03);
writedata(0x2B);
writedata(0x43);
writedata(0x42);
writedata(0x3B);
writedata(0x16);
writedata(0x14);
writedata(0x17);
writedata(0x1B);
delay(120);
writecommand(0xF0); //Command Set control
writedata(0x3C); //Disable extension command 2 partI
writecommand(0xF0); //Command Set control
writedata(0x69); //Disable extension command 2 partII
end_tft_write();
delay(120);
begin_tft_write();
writecommand(0x29); //Display on
}

View File

@ -0,0 +1,50 @@
// This is the command sequence that rotates the ST7796 driver coordinate frame
rotation = m % 8; // Limit the range of values to 0-7
writecommand(TFT_MADCTL);
switch (rotation) {
case 0:
writedata(TFT_MAD_MX | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 1:
writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
case 2:
writedata(TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 3:
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
// These next rotations are for bottom up BMP drawing
case 4:
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 5:
writedata(TFT_MAD_MV | TFT_MAD_MX | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
case 6:
writedata(TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 7:
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
}

View File

@ -1,988 +0,0 @@
// These are various test setups and are not used by the library!
// This is the command sequence that initialises the ????? driver
//
// This setup information uses simple 8 bit SPI writecommand() and writedata() functions
{
#if defined (TINYLCD)
//ILI9486 wave share 3.5 A B is ILI9340?
writecommand(0x01);
writedata(0x00);
delay(50);
writecommand(0x28);
writedata(0x00);
//writecommand(0xB0); // Power Control 1
//writedata(0x00);
//writecommand(0x11); // Sleep OUT
//delay(50);
/*
writecommand(0xC5); // VCOM Control
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x00);
//writedata(0x48); was 00 48
*/
/*
writecommand(0xF2); // ?????
writedata(0x1C);
writedata(0xA3);
writedata(0x32);
writedata(0x02);
writedata(0xb2);
writedata(0x12);
writedata(0xFF);
writedata(0x12);
writedata(0x00);
writecommand(0xF1); // ?????
writedata(0x36);
writedata(0xA4);
writecommand(0xF8); // ?????
writedata(0x21);
writedata(0x04);
writecommand(0xF9); // ?????
writedata(0x00);
writedata(0x08);
*/
writecommand(0xC0); // Power Control 1
writedata(0x0d);
writedata(0x0d);
writecommand(0xC1); // Power Control 2
writedata(0x43);
writedata(0x00);
writecommand(0xC2); // Power Control 3
writedata(0x00); // was 0x44
writecommand(0xC5); // VCOM Control
writedata(0x00);
writedata(0x48);
writecommand(0xB6); // Display Function Control
writedata(0x00);
writedata(0x22); // 0x42 = Rotate display 180 deg.
writedata(0x3B);
writecommand(0xE0); // PGAMCTRL (Positive Gamma Control)
writedata(0x0f);
writedata(0x24);
writedata(0x1c);
writedata(0x0a);
writedata(0x0f);
writedata(0x08);
writedata(0x43);
writedata(0x88);
writedata(0x32);
writedata(0x0f);
writedata(0x10);
writedata(0x06);
writedata(0x0f);
writedata(0x07);
writedata(0x00);
writecommand(0xE1); // NGAMCTRL (Negative Gamma Control)
writedata(0x0F);
writedata(0x38);
writedata(0x30);
writedata(0x09);
writedata(0x0f);
writedata(0x0f);
writedata(0x4e);
writedata(0x77);
writedata(0x3c);
writedata(0x07);
writedata(0x10);
writedata(0x05);
writedata(0x23);
writedata(0x1b);
writedata(0x00);
/*
writecommand(0xE2); // NGAMCTRL (Negative Gamma Control)
writedata(0x0F);
writedata(0x38);
writedata(0x30);
writedata(0x09);
writedata(0x0f);
writedata(0x0f);
writedata(0x4e);
writedata(0x77);
writedata(0x3c);
writedata(0x07);
writedata(0x10);
writedata(0x05);
writedata(0x23);
writedata(0x1b);
writedata(0x00);
*/
writecommand(0x20); // Display Inversion OFF, 0x21 = ON
writecommand(0x3A); // Interface Pixel Format
writedata(0x55);
writecommand(0x36); // Memory Access Control
writedata(0x0A);
writecommand(0x11); // Sleep OUT
delay(50);
writecommand(0x29); // Display ON
delay(25);
#elif defined ILI9486
// from https://developer.mbed.org/teams/GraphicsDisplay/code/UniGraphic/file/12ba0ecc2c1f/Inits/ILI9486.cpp
/*
writecommand(0xF1);
writedata(0x36);
writedata(0x04);
writedata(0x00);
writedata(0x3C);
writedata(0x0F);
writedata(0x8F);
writecommand(0xF2);
writedata(0x18);
writedata(0xA3);
writedata(0x12);
writedata(0x02);
writedata(0xb2);
writedata(0x12);
writedata(0xFF);
writedata(0x10);
writedata(0x00);
writecommand(0xF8);
writedata(0x21);
writedata(0x04);
writecommand(0xF9);
writedata(0x00);
writedata(0x08);
*/
writecommand(0xC0);
writedata(0x0f); //13
writedata(0x0f); //10
writecommand(0xC1);
writedata(0x42); //43
writecommand(0xC2);
writedata(0x22);
writecommand(0xC5);
writedata(0x01); //00
writedata(0x29); //4D
writedata(0x80);
writecommand(0xB6);
writedata(0x00);
writedata(0x02); //42
writedata(0x3b);
writecommand(0xB1);
writedata(0xB0); //C0
writedata(0x11);
writecommand(0xB4);
writedata(0x02); //01
writecommand(0xE0);
writedata(0x0F);
writedata(0x18);
writedata(0x15);
writedata(0x09);
writedata(0x0B);
writedata(0x04);
writedata(0x49);
writedata(0x64);
writedata(0x3D);
writedata(0x08);
writedata(0x15);
writedata(0x06);
writedata(0x12);
writedata(0x07);
writedata(0x00);
writecommand(0xE1);
writedata(0x0F);
writedata(0x38);
writedata(0x35);
writedata(0x0a);
writedata(0x0c);
writedata(0x03);
writedata(0x4A);
writedata(0x42);
writedata(0x36);
writedata(0x04);
writedata(0x0F);
writedata(0x03);
writedata(0x1F);
writedata(0x1B);
writedata(0x00);
writecommand(0x20); // display inversion OFF
writecommand(0x36); // MEMORY_ACCESS_CONTROL (orientation stuff)
writedata(0x48);
writecommand(0x3A); // COLMOD_PIXEL_FORMAT_SET
writedata(0x55); // 16 bit pixel
writecommand(0x13); // Nomal Displaymode
writecommand(0x11); // sleep out
delay(150);
writecommand(0x29); // display on
delay(150);
#elif defined (ILI9486_2)
// From https://github.com/notro/fbtft/blob/master/fb_ili9486.c
//writecommand(0x01); // SW reset
//delay(120);
writecommand(0x11); // Sleep out, also SW reset
delay(120);
writecommand(0x3A);
writedata(0x55);
writecommand(0xC2);
writedata(0x44);
writecommand(0xC5);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writecommand(0xE0);
writedata(0x0F);
writedata(0x1F);
writedata(0x1C);
writedata(0x0C);
writedata(0x0F);
writedata(0x08);
writedata(0x48);
writedata(0x98);
writedata(0x37);
writedata(0x0A);
writedata(0x13);
writedata(0x04);
writedata(0x11);
writedata(0x0D);
writedata(0x00);
writecommand(0xE1);
writedata(0x0F);
writedata(0x32);
writedata(0x2E);
writedata(0x0B);
writedata(0x0D);
writedata(0x05);
writedata(0x47);
writedata(0x75);
writedata(0x37);
writedata(0x06);
writedata(0x10);
writedata(0x03);
writedata(0x24);
writedata(0x20);
writedata(0x00);
writecommand(0x20); // display inversion OFF
writecommand(0x36);
writedata(0x0A);
writecommand(0x29); // display on
delay(150);
#elif defined (R61581)
// R61581:
writecommand(0xB0);
writedata(0x1E);
writecommand(0xB0);
writedata(0x00);
writecommand(0xB3);
writedata(0x02);
writedata(0x00);
writedata(0x00);
writedata(0x10);
writecommand(0xB4);
writedata(0x00);//0X10
// writecommand(0xB9); //PWM Settings for Brightness Control
// writedata(0x01);// Disabled by default.
// writedata(0xFF); //0xFF = Max brightness
// writedata(0xFF);
// writedata(0x18);
writecommand(0xC0);
writedata(0x03);
writedata(0x3B);//
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x00);//NW
writedata(0x43);
writecommand(0xC1);
writedata(0x08);
writedata(0x15);//CLOCK
writedata(0x08);
writedata(0x08);
writecommand(0xC4);
writedata(0x15);
writedata(0x03);
writedata(0x03);
writedata(0x01);
writecommand(0xC6);
writedata(0x02);
writecommand(0xC8);
writedata(0x0c);
writedata(0x05);
writedata(0x0A);//0X12
writedata(0x6B);//0x7D
writedata(0x04);
writedata(0x06);//0x08
writedata(0x15);//0x0A
writedata(0x10);
writedata(0x00);
writedata(0x60);//0x23
writecommand(0x36);
writedata(0x0A);
writecommand(0x0C);
writedata(0x55);
writecommand(0x3A);
writedata(0x55);
writecommand(0x38);
writecommand(0xD0);
writedata(0x07);
writedata(0x07);//VCI1
writedata(0x14);//VRH 0x1D
writedata(0xA2);//BT 0x06
writecommand(0xD1);
writedata(0x03);
writedata(0x5A);//VCM 0x5A
writedata(0x10);//VDV
writecommand(0xD2);
writedata(0x03);
writedata(0x04);//0x24
writedata(0x04);
writecommand(0x11);
delay(150);
writecommand(0x2A);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDF);//320
writecommand(0x2B);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);//480
delay(100);
writecommand(0x29);
delay(30);
writecommand(0x2C);
delay(30);
#elif defined (HX8357B)
//Serial.println("linux HX8357B");
// seqpower
writecommand(HX8357B_SETPOWER);
writedata(0x44);
writedata(0x41);
writedata(0x06);
// seq_vcom
writecommand(HX8357B_SETVCOM);
writedata(0x40);
writedata(0x10);
// seq_power_normal
writecommand(HX8357B_SETPWRNORMAL);
writedata(0x05);
writedata(0x12);
// seq_panel_driving
writecommand(HX8357B_SET_PANEL_DRIVING);
writedata(0x14);
writedata(0x3b);
writedata(0x00);
writedata(0x02);
writedata(0x11);
// seq_display_frame
writecommand(HX8357B_SETDISPLAYFRAME);
writedata(0x0c); // 6.8mhz
// seq_panel_related
writecommand(HX8357B_SETPANELRELATED);
writedata(0x01); // BGR
// seq_undefined1
writecommand(0xEA);
writedata(0x03);
writedata(0x00);
writedata(0x00);
// undef2
writecommand(0xEB);
writedata(0x40);
writedata(0x54);
writedata(0x26);
writedata(0xdb);
// seq_gamma
writecommand(HX8357B_SETGAMMA); // 0xC8
writedata(0x00);
writedata(0x15);
writedata(0x00);
writedata(0x22);
writedata(0x00);
writedata(0x08);
writedata(0x77);
writedata(0x26);
writedata(0x66);
writedata(0x22);
writedata(0x04);
writedata(0x00);
// seq_addr mode
writecommand(HX8357_MADCTL);
writedata(0xC0);
// pixel format
writecommand(HX8357_COLMOD);
writedata(0x55);
// set up whole address box
// paddr
writecommand(HX8357_PASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDF);
// caddr
writecommand(HX8357_CASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);
// display mode
writecommand(HX8357B_SETDISPMODE);
writedata(0x00); // CPU (DBI) and internal oscillation ??
// exit sleep
writecommand(HX8357_SLPOUT);
delay(120);
// main screen turn on
writecommand(HX8357_DISPON);
delay(10);
#elif defined (HX8257D)
writecommand(HX8357_SWRESET);
delay(10);
// setextc
writecommand(HX8357D_SETC);
writedata(0xFF);
writedata(0x83);
writedata(0x57);
delay(300);
// setRGB which also enables SDO
writecommand(HX8357_SETRGB);
writedata(0x80); //enable SDO pin!
// writedata(0x00); //disable SDO pin!
writedata(0x0);
writedata(0x06);
writedata(0x06);
writecommand(HX8357D_SETCOM);
writedata(0x25); // -1.52V
writecommand(HX8357_SETOSC);
writedata(0x68); // Normal mode 70Hz, Idle mode 55 Hz
writecommand(HX8357_SETPANEL); //Set Panel
writedata(0x05); // BGR, Gate direction swapped
writecommand(HX8357_SETPWR1);
writedata(0x00); // Not deep standby
writedata(0x15); //BT
writedata(0x1C); //VSPR
writedata(0x1C); //VSNR
writedata(0x83); //AP
writedata(0xAA); //FS
writecommand(HX8357D_SETSTBA);
writedata(0x50); //OPON normal
writedata(0x50); //OPON idle
writedata(0x01); //STBA
writedata(0x3C); //STBA
writedata(0x1E); //STBA
writedata(0x08); //GEN
writecommand(HX8357D_SETCYC);
writedata(0x02); //NW 0x02
writedata(0x40); //RTN
writedata(0x00); //DIV
writedata(0x2A); //DUM
writedata(0x2A); //DUM
writedata(0x0D); //GDON
writedata(0x78); //GDOFF
writecommand(HX8357D_SETGAMMA);
writedata(0x02);
writedata(0x0A);
writedata(0x11);
writedata(0x1d);
writedata(0x23);
writedata(0x35);
writedata(0x41);
writedata(0x4b);
writedata(0x4b);
writedata(0x42);
writedata(0x3A);
writedata(0x27);
writedata(0x1B);
writedata(0x08);
writedata(0x09);
writedata(0x03);
writedata(0x02);
writedata(0x0A);
writedata(0x11);
writedata(0x1d);
writedata(0x23);
writedata(0x35);
writedata(0x41);
writedata(0x4b);
writedata(0x4b);
writedata(0x42);
writedata(0x3A);
writedata(0x27);
writedata(0x1B);
writedata(0x08);
writedata(0x09);
writedata(0x03);
writedata(0x00);
writedata(0x01);
writecommand(HX8357_COLMOD);
writedata(0x55); // 16 bit
writecommand(HX8357_MADCTL);
writedata(0xC0);
writecommand(HX8357_TEON); // TE off
writedata(0x00);
writecommand(HX8357_TEARLINE); // tear line
writedata(0x00);
writedata(0x02);
writecommand(HX8357_SLPOUT); //Exit Sleep
delay(150);
writecommand(HX8357_DISPON); // display on
delay(50);
#elif defined(WAVESHARE32B)
// Waveshare32b
writecommand(0xCB);
writedata(0x39);
writedata(0x2C);
writedata(0x00);
writedata(0x34);
writedata(0x02);
writecommand(0xCF);
writedata(0x00);
writedata(0xC1);
writedata(0x30);
writecommand(0xE8);
writedata(0x85);
writedata(0x00);
writedata(0x78);
writecommand(0xEA);
writedata(0x00);
writedata(0x00);
writecommand(0xED);
writedata(0x64);
writedata(0x03);
writedata(0x12);
writedata(0x81);
writecommand(0xF7);
writedata(0x20);
writecommand(0xC0);
writedata(0x23);
writecommand(0xC1);
writedata(0x10);
writecommand(0xC5);
writedata(0x3E);
writedata(0x28);
writecommand(0xC7);
writedata(0x86);
writecommand(0x36);
writedata(0x28);
writecommand(0x3A);
writedata(0x55);
writecommand(0xB1);
writedata(0x00);
writedata(0x18);
writecommand(0xB6);
writedata(0x08);
writedata(0x82);
writedata(0x27);
writecommand(0xF2);
writedata(0x00);
writecommand(0x26);
writedata(0x01);
writecommand(0xE0);
writedata(0x0F);
writedata(0x31);
writedata(0x2B);
writedata(0x0C);
writedata(0x0E);
writedata(0x08);
writedata(0x4E);
writedata(0xF1);
writedata(0x37);
writedata(0x07);
writedata(0x10);
writedata(0x03);
writedata(0x0E);
writedata(0x09);
writedata(0x00);
writecommand(0xE1);
writedata(0x00);
writedata(0x0E);
writedata(0x14);
writedata(0x03);
writedata(0x11);
writedata(0x07);
writedata(0x31);
writedata(0xC1);
writedata(0x48);
writedata(0x08);
writedata(0x0F);
writedata(0x0C);
writedata(0x31);
writedata(0x36);
writedata(0x0F);
writecommand(0x11);
delay(120);
writecommand(0x29);
//writecommand(0x2C);
delay(25);
#elif defined (TINYLCD2)
// Configure TINYLCD display
writecommand(0x11);
delay(20);
writecommand(0xB0);
writedata(0x80);
writecommand(0xC0);
writedata(0x0A);
writedata(0x0A);
writecommand(0xC1);
writedata(0x45);
writedata(0x07);
writecommand(0xC2);
writedata(0x33);
writecommand(0xC5);
writedata(0x00);
writedata(0x42);
writedata(0x80);
writecommand(0xB1);
writedata(0xD0);
writedata(0x11);
writecommand(0xB4);
writedata(0x02);
writecommand(0xB6);
writedata(0x00);
writedata(0x22);
writedata(0x3B);
writecommand(0xB7);
writedata(0x07);
writecommand(0x36);
writedata(0x58);
writecommand(0xF0);
writedata(0x36);
writedata(0xA5);
writedata(0xD3);
writecommand(0xE5);
writedata(0x80);
writecommand(0xE5);
writedata(0x01);
writecommand(0xB3);
writedata(0x00);
writecommand(0xE5);
writedata(0x00);
writecommand(0xF0);
writedata(0x36);
writedata(0xA5);
writedata(0x53);
writecommand(0xE0);
writedata(0x00);
writedata(0x35);
writedata(0x33);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x35);
writedata(0x33);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writecommand(0x3A);
writedata(0x55);
delay(120);
writecommand(0x29);
delay(25);
// End of TINYLCD display configuration
#elif defined (HX8357C)
// HX8357-C display initialisation
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);
#elif defined (ILI9481) // Must be an ILI9481
// Configure ILI9481 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(0x03);
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 ILI9481 display configuration
#endif
}

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

1380
TFT_eSPI.h

File diff suppressed because it is too large Load Diff

View File

@ -147,7 +147,7 @@ int displayFontSize = 28;
static final int[] unicodeBlocks = {
// The list below has been created from the table here: https://en.wikipedia.org/wiki/Unicode_block
// Remove // at start of lines below to include that unicode block, different code ranges can also be specified by
// editting the start and end-of-range values. Multiple lines from the list below can be included, limited only by
// editing the start and end-of-range values. Multiple lines from the list below can be included, limited only by
// the final font file size!
// Block range, //Block name, Code points, Assigned characters, Scripts

View File

@ -1,33 +0,0 @@
PlatformIO User notes:
It is possible to load settings from the calling program rather than modifying
the library for each project by modifying the "platformio.ini" file.
The User_Setup_Select.h file will not load the user setting header files if
USER_SETUP_LOADED is defined.
Instead of using #define, use the -D prefix, for example:
[env:esp32dev]
platform = https://github.com/platformio/platform-espressif32.git#feature/stage
board = esp32dev
framework = arduino
upload_port = ESP32-Test-2481CE9C.local
build_flags =
-Os
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-DUSER_SETUP_LOADED=1
-DILI9163_DRIVER=1
-DTFT_WIDTH=128
-DTFT_HEIGHT=160
-DTFT_MISO=19
-DTFT_MOSI=23
-DTFT_SCLK=18
-DTFT_CS=5
-DTFT_DC=19
-DTFT_RST=-1
-DLOAD_GLCD=1
-DSPI_FREQUENCY=27000000
lib_extra_dirs = B:\Projects\ESP32\ESP32Lib

View File

@ -0,0 +1,26 @@
## bmp2array4bit
bmp2array4bit.py reads a bmp file, and creates C (or C++) code that contains two arrays for adding images to four-bit sprites. See [Sprite_image_4bit](../../examples/Sprite/Sprite_image_4bit) for an example.
It is loosely based on Spark Fun's bmp2array script, https://github.com/sparkfun/BMPtoArray/blob/master/bmp2array.py. The bmp file format is documented in https://en.wikipedia.org/wiki/BMP_file_format.
You'll need python 3.6 (the original uses Python 2.7)
`usage: python bmp2array4bit.py [-v] star.bmp [-o myfile.c]`
Create the bmp file in Gimp (www.gimp.org) from any image as follows:
* Remove the alpha channel (if it has one)
Layer -> Transparency -> Remove Alpha Channel
* Set the mode to indexed.
Image -> Mode -> Indexed...
* Select Generate optimum palette with 16 colors (max)
* Export the file with a .bmp extension. Do **NOT** select options:
* Run-Length Encoded
* Compatibility Options: "Do not write color space information"
* There are no Advanced Options available with these settings
(There are other tools that will produce bmp files, and these should work provided you don't use run-length encoding or other advanced features).
The first array produced is the palette for the image.
The second is the image itself.

View File

@ -0,0 +1,251 @@
'''
This script takes in a bitmap and outputs a text file that is a
byte array used in Arduino files.
It is loosely based on Spark Fun's bmp2array script.
You'll need python 3.6 (the original use Python 2.7)
usage: python fourbitbmp2array.py [-v] star.bmp [-o myfile.c]
Create the bmp file in Gimp by :
. Remove the alpha channel (if it has one) Layer -> Transparency -> Remove Alpha Channel
. Set the mode to indexed. Image -> Mode -> Indexed...
. Select Generate optimum palette with 16 colors (max)
. Export the file with a .bmp extension. Options are:
. Run-Length Encoded: not selected
. Compatibility Options: "Do not write color space information" not selected
. There are no Advanced Options available with these settings
'''
import sys
import struct
import math
import argparse
import os
debug = None
def debugOut(s):
if debug:
print(s)
# look at arguments
parser = argparse.ArgumentParser(description="Convert bmp file to C array")
parser.add_argument("-v", "--verbose", help="debug output", action="store_true")
parser.add_argument("input", help="input file name")
parser.add_argument("-o", "--output", help="output file name")
args = parser.parse_args()
if not os.path.exists(args.input):
parser.print_help()
print("The input file {} does not exist".format(args.input))
sys.exit(1)
if args.output == None:
output = os.path.basename(args.input).replace(".bmp", ".c")
else:
output = args.output
debug = args.verbose
try:
#Open our input file which is defined by the first commandline argument
#then dump it into a list of bytes
infile = open(args.input,"rb") #b is for binary
contents = bytearray(infile.read())
infile.close()
except:
print("could not read input file {}".format(args.input))
sys.exit(1)
# first two bytes should be "BM"
upto = 2
#Get the size of this image
data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
fileSize = struct.unpack("I", bytearray(data))
upto += 4
# four bytes are reserved
upto += 4
debugOut("Size of file: {}".format(fileSize[0]))
#Get the header offset amount
data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
offset = struct.unpack("I", bytearray(data))
debugOut("Offset: {}".format(offset[0]))
upto += 4
data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
headersize = struct.unpack("I", bytearray(data))
headerLength = headersize[0]
startOfDefinitions = headerLength + upto
debugOut("header size: {}, up to {}, startOfDefinitions {}".format(headersize[0], upto, startOfDefinitions))
upto += 4
data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
t = struct.unpack("I", bytearray(data))
debugOut("width: {}".format(t[0]))
width = t[0]
upto += 4
data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
t = struct.unpack("I", bytearray(data))
debugOut("height: {}".format(t[0]))
height = t[0]
# 26
upto += 4
data = struct.pack("BB", contents[upto], contents[upto+1])
t = struct.unpack("H", bytearray(data))
debugOut("planes: {}".format(t[0]))
upto = upto + 2
data = struct.pack("BB", contents[upto], contents[upto+1])
t = struct.unpack("H", bytearray(data))
debugOut("bits per pixel: {}".format(t[0]))
bitsPerPixel = t[0]
upto = upto + 2
data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
t = struct.unpack("I", bytearray(data))
debugOut("biCompression: {}".format(t[0]))
upto = upto + 4
data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
t = struct.unpack("I", bytearray(data))
debugOut("biSizeImage: {}".format(t[0]))
upto = upto + 4
data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
t = struct.unpack("I", bytearray(data))
debugOut("biXPelsPerMeter: {}".format(t[0]))
upto = upto + 4
data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
t = struct.unpack("I", bytearray(data))
debugOut("biYPelsPerMeter: {}".format(t[0]))
upto = upto + 4
data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
t = struct.unpack("I", bytearray(data))
debugOut("biClrUsed: {}".format(t[0]))
colorsUsed = t
upto = upto + 4
data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
t = struct.unpack("I", bytearray(data))
debugOut("biClrImportant: {}".format(t[0]))
upto += 4
debugOut("Upto: {} Number of colors used: {} definitions start at: {}".format(upto, colorsUsed[0], startOfDefinitions))
#Create color definition array and init the array of color values
colorIndex = [] #(colorsUsed[0])
for i in range(colorsUsed[0]):
colorIndex.append(0)
#Assign the colors to the array. upto = 54
# startOfDefinitions = upto
for i in range(colorsUsed[0]):
upto = startOfDefinitions + (i * 4)
blue = contents[upto]
green = contents[upto + 1]
red = contents[upto + 2]
# ignore the alpha channel.
# data = struct.pack("BBBB", contents[upto], contents[upto+1], contents[upto+2], contents[upto+3])
# t = struct.unpack("I", bytearray(data))
# colorIndex[i] = t[0]
colorIndex[i] = (((red & 0xf8)<<8) + ((green & 0xfc)<<3)+(blue>>3))
debugOut("color at index {0} is {1:04x}, (r,g,b,a) = ({2:02x}, {3:02x}, {4:02x}, {5:02x})".format(i, colorIndex[i], red, green, blue, contents[upto+3]))
#debugOut(the color definitions
# for i in range(colorsUsed[0]):
# print hex(colorIndex[i])
# perfect, except upside down.
#Make a string to hold the output of our script
arraySize = (len(contents) - offset[0])
outputString = "/* This was generated using a script based on the SparkFun BMPtoArray python script" + '\n'
outputString += " See https://github.com/sparkfun/BMPtoArray for more info */" + '\n\n'
outputString += "static const uint16_t palette[" + str(colorsUsed[0]) + "] = {";
for i in range(colorsUsed[0]):
# print hexlify(colorIndex[i])
if i % 4 == 0:
outputString += "\n\t"
outputString += "0x{:04x}, ".format(colorIndex[i])
outputString = outputString[:-2]
outputString += "\n};\n\n"
outputString += "// width is " + str(width) + ", height is " + str(height) + "\n"
outputString += "static const uint8_t myGraphic[" + str(arraySize) + "] PROGMEM = {" + '\n'
if bitsPerPixel != 4:
print("Expected 4 bits per pixel; found {}".format(bitsPerPixel))
sys.exit(1)
#Start converting spots to values
#Start at the offset and go to the end of the file
dropLastNumber = True #(width % 4) == 2 or (width % 4) == 1
paddedWidth = int(math.ceil(bitsPerPixel * width / 32.0) * 4)
debugOut("array range is {} {} len(contents) is {} paddedWidth is {} width is {}".format(offset[0], fileSize[0], len(contents), paddedWidth, width))
r = 0
width = int(width / 2)
#for i in range(offset[0], fileSize[0]): # close but image is upside down. Each row is correct but need to swap columns.
#for i in range(fileSize[0], offset[0], -1):
for col in range(height-1, -1, -1):
i = 0
for row in range(width):
colorCode1 = contents[row + col*paddedWidth + offset[0]]
if r > 0 and r % width == 0:
i = 0
outputString += '\n\n'
elif (i + 1) % 12 == 0 :
outputString += '\n'
i = 0
#debugOut("cell ({0}, {1})".format(row, col)
r = r + 1
i = i + 1
outputString += "0x{:02x}, ".format(colorCode1)
#Once we've reached the end of our input string, pull the last two
#characters off (the last comma and space) since we don't need
#them. Top it off with a closing bracket and a semicolon.
outputString = outputString[:-2]
outputString += "};"
try:
#Write the output string to our output file
outfile = open(output, "w")
outfile.write(outputString)
outfile.close()
except:
print("could not write output to file {}".format(output))
sys.exit(1)
debugOut("{} complete".format(output))
debugOut("Copy and paste this array into a image.h or other header file")
if not debug:
print("Completed; the output is in {}".format(output))

Binary file not shown.

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!
// 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
// ##################################################################################
//
@ -15,8 +20,30 @@
//
// ##################################################################################
// Define STM32 to invoke optimised processor support (only for STM32)
//#define STM32
// Defining the STM32 board allows the library to optimise the performance
// for UNO compatible "MCUfriend" style shields
//#define NUCLEO_64_TFT
//#define NUCLEO_144_TFT
// STM32 8 bit parallel only:
// If STN32 Port A or B pins 0-7 are used for 8 bit parallel data bus bits 0-7
// then this will improve rendering performance by a factor of ~8x
//#define STM_PORTA_DATA_BUS
//#define STM_PORTB_DATA_BUS
// Tell the library to use parallel mode (otherwise SPI is assumed)
//#define TFT_PARALLEL_8_BIT
//#defined TFT_PARALLEL_16_BIT // **** 16 bit parallel ONLY for RP2040 processor ****
// Display type - only define if RPi display
//#define RPI_DISPLAY_TYPE // 20MHz maximum SPI
// Only define one driver, the other ones must be commented out
#define ILI9341_DRIVER
#define ILI9341_DRIVER // Generic driver for common displays
//#define ILI9341_2_DRIVER // Alternative ILI9341 driver, see https://github.com/Bodmer/TFT_eSPI/issues/1172
//#define ST7735_DRIVER // Define additional parameters below for this display
//#define ILI9163_DRIVER // Define additional parameters below for this display
//#define S6D02A1_DRIVER
@ -29,14 +56,21 @@
//#define ST7789_2_DRIVER // Minimal configuration option, define additional parameters below for this display
//#define R61581_DRIVER
//#define RM68140_DRIVER
//#define ST7796_DRIVER
//#define SSD1351_DRIVER
//#define SSD1963_480_DRIVER
//#define SSD1963_800_DRIVER
//#define SSD1963_800ALT_DRIVER
//#define ILI9225_DRIVER
//#define GC9A01_DRIVER
// 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.
// To use the SDA line for reading data from the TFT uncomment the following line:
// #define TFT_SDA_READ // This option is for ESP32 ONLY, tested with ST7789 display only
// #define TFT_SDA_READ // This option is for ESP32 ONLY, tested with ST7789 and GC9A01 display only
// For ST7789 and ILI9341 ONLY, define the colour order IF the blue and red are swapped on your display
// For ST7735, ST7789 and ILI9341 ONLY, define the colour order IF the blue and red are swapped on your display
// Try ONE option at a time to find the correct colour order for your display
// #define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
@ -46,19 +80,21 @@
// #define M5STACK
// For ST7789, ST7735 and ILI9163 ONLY, define the pixel width and height in portrait orientation
// For ST7789, ST7735, ILI9163 and GC9A01 ONLY, define the pixel width and height in portrait orientation
// #define TFT_WIDTH 80
// #define TFT_WIDTH 128
// #define TFT_WIDTH 172 // ST7789 172 x 320
// #define TFT_WIDTH 240 // ST7789 240 x 240 and 240 x 320
// #define TFT_HEIGHT 160
// #define TFT_HEIGHT 128
// #define TFT_HEIGHT 240 // ST7789 240 x 240
// #define TFT_HEIGHT 320 // ST7789 240 x 320
// #define TFT_HEIGHT 240 // GC9A01 240 x 240
// For ST7735 ONLY, define the type of display, originally this was based on the
// colour of the tab on the screen protector film but this is not always true, so try
// out the different options below if the screen does not display graphics correctly,
// e.g. colours wrong, mirror images, or tray pixels at the edges.
// e.g. colours wrong, mirror images, or stray pixels at the edges.
// Comment out ALL BUT ONE of these options for a ST7735 display driver, save this
// this User_Setup file, then rebuild and upload the sketch to the board again:
@ -68,6 +104,7 @@
// #define ST7735_GREENTAB3
// #define ST7735_GREENTAB128 // For 128 x 128 display
// #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_BLACKTAB
// #define ST7735_REDTAB160x80 // For 160 x 80 display with 24 pixel offset
@ -78,13 +115,6 @@
// #define TFT_INVERSION_ON
// #define TFT_INVERSION_OFF
// If a backlight control signal is available then define the TFT_BL pin in Section 2
// below. 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. If the LEDs are to be
// driven with a PWM signal or turned OFF/ON then this must be handled by the user
// sketch. e.g. with digitalWrite(TFT_BL, LOW);
// #define TFT_BACKLIGHT_ON HIGH // HIGH or LOW are options
// ##################################################################################
//
@ -92,6 +122,17 @@
//
// ##################################################################################
// If a backlight control signal is available then define the TFT_BL pin in Section 2
// below. 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. If the LEDs are to be
// driven with a PWM signal or turned OFF/ON then this must be handled by the user
// sketch. e.g. with digitalWrite(TFT_BL, LOW);
// #define TFT_BL 32 // LED back-light control pin
// #define TFT_BACKLIGHT_ON HIGH // Level to turn ON back-light (HIGH or LOW)
// We must use hardware SPI, a minimum of 3 GPIO pins is needed.
// Typical setup for ESP8266 NodeMCU ESP-12 is :
//
@ -107,7 +148,7 @@
//
// The TFT RESET pin can be connected to the NodeMCU RST pin or 3.3V to free up a control pin
//
// The DC (Data Command) pin may be labeled AO or RS (Register Select)
// The DC (Data Command) pin may be labelled AO or RS (Register Select)
//
// With some displays such as the ILI9341 the TFT CS pin can be connected to GND if no more
// SPI devices (e.g. an SD Card) are connected, in this case comment out the #define TFT_CS
@ -140,10 +181,14 @@
// ###### FOR ESP8266 OVERLAP MODE EDIT THE PIN NUMBERS IN THE FOLLOWING LINES ######
// Overlap mode shares the ESP8266 FLASH SPI bus with the TFT so has a performance impact
// but saves pins for other functions.
// Use NodeMCU SD0=MISO, SD1=MOSI, CLK=SCLK to connect to TFT in overlap mode
// but saves pins for other functions. It is best not to connect MISO as some displays
// do not tristate that line when chip select is high!
// Note: Only one SPI device can share the FLASH SPI lines, so a SPI touch controller
// cannot be connected as well to the same SPI signals.
// On NodeMCU 1.0 SD0=MISO, SD1=MOSI, CLK=SCLK to connect to TFT in overlap mode
// On NodeMCU V3 S0 =MISO, S1 =MOSI, S2 =SCLK
// In ESP8266 overlap mode the following must be defined
//#define TFT_SPI_OVERLAP
// In ESP8266 overlap mode the TFT chip select MUST connect to pin D3
@ -166,7 +211,15 @@
//#define TFT_RST 4 // Reset pin (could connect to RST pin)
//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
//#define TFT_BL 32 // LED back-light (only for ST7789 with backlight control pin)
// For ESP32 Dev board (only tested with GC9A01 display)
// The hardware SPI can be mapped to any pins
//#define TFT_MOSI 15 // In some display driver board, it might be written as "SDA" and so on.
//#define TFT_SCLK 14
//#define TFT_CS 5 // Chip select control pin
//#define TFT_DC 27 // Data Command control pin
//#define TFT_RST 33 // Reset pin (could connect to Arduino RESET pin)
//#define TFT_BL 22 // LED back-light
//#define TOUCH_CS 21 // Chip select pin (T_CS) of touch screen
@ -188,10 +241,11 @@
// Wemos D32 boards need to be modified, see diagram in Tools folder.
// Only ILI9481 and ILI9341 based displays have been tested!
// Parallel bus is only supported on ESP32
// Uncomment line below to use ESP32 Parallel interface instead of SPI
// Parallel bus is only supported for the STM32 and ESP32
// Example below is for ESP32 Parallel interface with UNO displays
//#define ESP32_PARALLEL
// Tell the library to use 8 bit parallel mode (otherwise SPI is assumed)
//#define TFT_PARALLEL_8_BIT
// The ESP32 and TFT the pins used for testing are:
//#define TFT_CS 33 // Chip select control pin (library pulls permanently low
@ -210,6 +264,31 @@
//#define TFT_D6 27
//#define TFT_D7 14
// ###### EDIT THE PINs BELOW TO SUIT YOUR STM32 SPI TFT SETUP ######
// The TFT can be connected to SPI port 1 or 2
//#define TFT_SPI_PORT 1 // SPI port 1 maximum clock rate is 55MHz
//#define TFT_MOSI PA7
//#define TFT_MISO PA6
//#define TFT_SCLK PA5
//#define TFT_SPI_PORT 2 // SPI port 2 maximum clock rate is 27MHz
//#define TFT_MOSI PB15
//#define TFT_MISO PB14
//#define TFT_SCLK PB13
// Can use Ardiuno pin references, arbitrary allocation, TFT_eSPI controls chip select
//#define TFT_CS D5 // Chip select control pin to TFT CS
//#define TFT_DC D6 // Data Command control pin to TFT DC (may be labelled RS = Register Select)
//#define TFT_RST D7 // Reset pin to TFT RST (or RESET)
// OR alternatively, we can use STM32 port reference names PXnn
//#define TFT_CS PE11 // Nucleo-F767ZI equivalent of D5
//#define TFT_DC PE9 // Nucleo-F767ZI equivalent of D6
//#define TFT_RST PF13 // Nucleo-F767ZI equivalent of D7
//#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to processor reset
// Use an Arduino pin for initial testing as connecting to processor reset
// may not work (pulse too short at power up?)
// ##################################################################################
//
@ -242,19 +321,42 @@
//
// ##################################################################################
// 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
// 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)
//#define TFT_SPI_PORT 1 // Set to 0 if SPI0 pins are used, or 1 if spi1 pins used
// For the STM32 processor define the SPI port channel used (default 1 if undefined)
//#define TFT_SPI_PORT 2 // Set to 1 for SPI port 1, or 2 for SPI port 2
// 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.
// The RPi typically only works at 20MHz maximum.
// #define SPI_FREQUENCY 1000000
// #define SPI_FREQUENCY 5000000
// #define SPI_FREQUENCY 10000000
// #define SPI_FREQUENCY 20000000
#define SPI_FREQUENCY 27000000 // Actually sets it to 26.67MHz = 80/3
// #define SPI_FREQUENCY 40000000 // Maximum to use SPIFFS
#define SPI_FREQUENCY 27000000
// #define SPI_FREQUENCY 40000000
// #define SPI_FREQUENCY 55000000 // STM32 SPI1 only (SPI2 maximum is 27MHz)
// #define SPI_FREQUENCY 80000000
// Optional reduced SPI frequency for reading TFT

View File

@ -1,62 +1,150 @@
// 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.
//
// 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.
// The advantage of this hardware configuration method is that the examples provided
// with the library should work with different setups immediately without any other
// changes being needed. It also improves the portability of users sketches to other
// hardware configurations and compatible libraries.
// with the library should work with immediately without any other changes being
// needed. It also improves the portability of users sketches to other hardware
// configurations and compatible libraries.
//
// 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.
// 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
// 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_Setups/Setup1_ILI9341.h> // Setup file configured for my ILI9341
//#include <User_Setups/Setup2_ST7735.h> // Setup file configured for my ST7735
//#include <User_Setups/Setup3_ILI9163.h> // Setup file configured for my ILI9163
//#include <User_Setups/Setup4_S6D02A1.h> // Setup file configured for my S6D02A1
//#include <User_Setups/Setup5_RPi_ILI9486.h> // Setup file 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/Setup7_ST7735_128x128.h> // Setup file configured for my ST7735 128x128 display
//#include <User_Setups/Setup8_ILI9163_128x128.h> // Setup file configured for my ILI9163 128x128 display
//#include <User_Setups/Setup9_ST7735_Overlap.h> // Setup file 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/Setup1_ILI9341.h> // Setup file for ESP8266 configured for my ILI9341
//#include <User_Setups/Setup2_ST7735.h> // Setup file for ESP8266 configured for my ST7735
//#include <User_Setups/Setup3_ILI9163.h> // Setup file for ESP8266 configured for my ILI9163
//#include <User_Setups/Setup4_S6D02A1.h> // Setup file for ESP8266 configured for my S6D02A1
//#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 for ESP8266 configured for my modified RPi TFT
//#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 for ESP8266 configured for my ILI9163 128x128 display
//#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 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/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/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/Setup17_ePaper.h> // Setup file for any Waveshare ePaper display
//#include <User_Setups/Setup18_ST7789.h> // Setup file configured for ST7789
//#include <User_Setups/Setup17_ePaper.h> // Setup file for ESP8266 and any Waveshare ePaper display
//#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/Setup20_ILI9488.h> // Setup file for ESP8266 and ILI9488 SPI bus TFT
//#include <User_Setups/Setup21_ILI9488.h> // Setup file for ESP32 and ILI9488 SPI bus TFT
//#include <User_Setups/Setup22_TTGO_T4.h> // Setup file for ESP32 and TTGO T4 (BTC) ILI9341 SPI bus TFT
//#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/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/Setup26_TTGO_T_Wristband.h> // Setup file for ESP32 and TTGO T-Wristband ST7735 SPI bus TFT
//#include <User_Setups/Setup43_ST7735.h> // Setup file configured for my ST7735S 80x160
//#include <User_Setups/Setup27_RPi_ST7796_ESP32.h> // ESP32 RPi MHS-4.0 inch Display-B
//#include <User_Setups/Setup28_RPi_ST7796_ESP8266.h> // ESP8266 RPi MHS-4.0 inch Display-B
//#include <User_Setups/Setup135_ST7789.h> // Setup file for ESP8266 and ST7789 125 x 240 TFT
//#include <User_Setups/Setup29_ILI9341_STM32.h> // Setup for Nucleo board
//#include <User_Setups/Setup30_ILI9341_Parallel_STM32.h> // Setup for Nucleo board and parallel display
//#include <User_Setups/Setup31_ST7796_Parallel_STM32.h> // Setup for Nucleo board and parallel display
//#include <User_Setups/Setup32_ILI9341_STM32F103.h> // Setup for "Blue/Black Pill"
//#include <User_Setups/SetupX_Template.h>
//#include <User_Setups/Setup33_RPi_ILI9486_STM32.h> // Setup for Nucleo board
//#include <User_Setups/Setup34_ILI9481_Parallel_STM32.h> // Setup for Nucleo board and parallel display
//#include <User_Setups/Setup35_ILI9341_STM32_Port_Bus.h> // Setup for STM32 port A parallel display
//#include <User_Setups/Setup36_RPi_touch_ST7796.h> // Setup file configured for ESP32 and RPi ST7796 TFT with touch
//#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/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 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/Setup51_LilyPi_ILI9481.h> // Setup file for LilyGo LilyPi with ILI9481 display
//#include <User_Setups/Setup52_LilyPi_ST7796.h> // Setup file for LilyGo LilyPi with ST7796 display
//#include <User_Setups/Setup60_RP2040_ILI9341.h> // Setup file for RP2040 with 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/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/Setup72_ESP32_ST7789_172x320.h> // Setup file for ESP32 with ST7789 1.47" 172x320
//#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> // Setup file for Pico/RP2040 with 8 bit parallel ILI9481
//#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> // Setup file for Pico/RP2040 with 8 bit parallel ILI9486
//#include <User_Setups/Setup104_RP2040_ST7796_parallel.h> // Setup file for Pico/RP2040 with 8 bit parallel ST7796
//#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/Setup136_LilyGo_TTV.h> // Setup file for ESP32 and Lilygo TTV ST7789 SPI bus TFT 135x240
//#include <User_Setups/Setup137_LilyGo_TDisplay_RP2040.h> // Setup file for Lilygo T-Display RP2040 (ST7789 on SPI bus with 135x240 TFT)
//#include <User_Setups/Setup200_GC9A01.h> // Setup file for ESP32 and GC9A01 240 x 240 TFT
//#include <User_Setups/Setup201_WT32_SC01.h> // Setup file for ESP32 based WT32_SC01 from Seeed
//#include <User_Setups/Setup202_SSD1351_128.h> // Setup file for ESP32/ESP8266 based SSD1351 128x128 1.5inch OLED display
//#include <User_Setups/Setup203_ST7789.h> // Setup file for ESP32/ESP8266 based ST7789 240X280 1.69inch TFT
//#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
@ -65,7 +153,7 @@
/////////////////////////////////////////////////////////////////////////////////////
// //
// DON'T TINKER WITH ANY OF THE FOLLOWING LINES, THESE ADD THE TFT DRIVERS //
// AND ESP8266 PIN DEFINITONS THEY ARE HERE FOR BODMER'S CONVENIENCE! //
// AND ESP8266 PIN DEFINITONS, THEY ARE HERE FOR BODMER'S CONVENIENCE! //
// //
/////////////////////////////////////////////////////////////////////////////////////
@ -74,9 +162,33 @@
#define TFT_BGR 0 // Colour order Blue-Green-Red
#define TFT_RGB 1 // Colour order Red-Green-Blue
// Legacy setup support, RPI_DISPLAY_TYPE replaces RPI_DRIVER
#if defined (RPI_DRIVER)
#if !defined (RPI_DISPLAY_TYPE)
#define RPI_DISPLAY_TYPE
#endif
#endif
// Legacy setup support, RPI_ILI9486_DRIVER form is deprecated
// Instead define RPI_DISPLAY_TYPE and also define driver (e.g. ILI9486_DRIVER)
#if defined (RPI_ILI9486_DRIVER)
#if !defined (ILI9486_DRIVER)
#define ILI9486_DRIVER
#endif
#if !defined (RPI_DISPLAY_TYPE)
#define RPI_DISPLAY_TYPE
#endif
#endif
// Invoke 18 bit colour for selected displays
#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)
#define SPI_18BIT_DRIVER
#endif
#endif
// Load the right driver definition - do not tinker here !
#if defined (ILI9341_DRIVER)
#if defined (ILI9341_DRIVER) || defined(ILI9341_2_DRIVER) || defined (ILI9342_DRIVER)
#include <TFT_Drivers/ILI9341_Defines.h>
#define TFT_DRIVER 0x9341
#elif defined (ST7735_DRIVER)
@ -88,9 +200,9 @@
#elif defined (S6D02A1_DRIVER)
#include <TFT_Drivers/S6D02A1_Defines.h>
#define TFT_DRIVER 0x6D02
#elif defined (RPI_ILI9486_DRIVER)
#include <TFT_Drivers/ILI9486_Defines.h>
#define TFT_DRIVER 0x9486
#elif defined (ST7796_DRIVER)
#include "TFT_Drivers/ST7796_Defines.h"
#define TFT_DRIVER 0x7796
#elif defined (ILI9486_DRIVER)
#include <TFT_Drivers/ILI9486_Defines.h>
#define TFT_DRIVER 0x9486
@ -116,27 +228,59 @@
#include "TFT_Drivers/ST7789_2_Defines.h"
#define TFT_DRIVER 0x778B
#elif defined (RM68140_DRIVER)
#include "TFT_Drivers/RM68140_Defines.h"
#define TFT_DRIVER 0x6814
#elif defined (XYZZY_DRIVER) // <<<<<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVER HERE
#include "TFT_Drivers/RM68140_Defines.h"
#define TFT_DRIVER 0x6814
#elif defined (SSD1351_DRIVER)
#include "TFT_Drivers/SSD1351_Defines.h"
#define TFT_DRIVER 0x1351
#elif defined (SSD1963_480_DRIVER)
#include "TFT_Drivers/SSD1963_Defines.h"
#define TFT_DRIVER 0x1963
#elif defined (SSD1963_800_DRIVER)
#include "TFT_Drivers/SSD1963_Defines.h"
#define TFT_DRIVER 0x1963
#elif defined (SSD1963_800ALT_DRIVER)
#include "TFT_Drivers/SSD1963_Defines.h"
#define TFT_DRIVER 0x1963
#elif defined (SSD1963_800BD_DRIVER)
#include "TFT_Drivers/SSD1963_Defines.h"
#define TFT_DRIVER 0x1963
#elif defined (GC9A01_DRIVER)
#include "TFT_Drivers/GC9A01_Defines.h"
#define TFT_DRIVER 0x9A01
#elif defined (ILI9225_DRIVER)
#include "TFT_Drivers/ILI9225_Defines.h"
#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
// XYZZY_init.h and XYZZY_rotation.h must also be added in TFT_eSPI.cpp
#elif defined (XYZZY_DRIVER)
#include "TFT_Drivers/XYZZY_Defines.h"
#define TFT_DRIVER 0x0000
#else
#define TFT_DRIVER 0x0000
#endif
// These are the pins for ESP8266 boards
// Name GPIO NodeMCU Function
#define PIN_D0 D0 // GPIO16 WAKE
#define PIN_D1 D1 // GPIO5 User purpose
#define PIN_D2 D2 // GPIO4 User purpose
#define PIN_D3 D3 // GPIO0 Low on boot means enter FLASH mode
#define PIN_D4 D4 // GPIO2 TXD1 (must be high on boot to go to UART0 FLASH mode)
#define PIN_D5 D5 // GPIO14 HSCLK
#define PIN_D6 D6 // GPIO12 HMISO
#define PIN_D7 D7 // GPIO13 HMOSI RXD2
#define PIN_D8 D8 // GPIO15 HCS TXD0 (must be low on boot to enter UART0 FLASH mode)
#define PIN_D0 16 // GPIO16 WAKE
#define PIN_D1 5 // GPIO5 User purpose
#define PIN_D2 4 // GPIO4 User purpose
#define PIN_D3 0 // GPIO0 Low on boot means enter FLASH mode
#define PIN_D4 2 // GPIO2 TXD1 (must be high on boot to go to UART0 FLASH mode)
#define PIN_D5 14 // GPIO14 HSCLK
#define PIN_D6 12 // GPIO12 HMISO
#define PIN_D7 13 // GPIO13 HMOSI RXD2
#define PIN_D8 15 // GPIO15 HCS TXD0 (must be low on boot to enter UART0 FLASH mode)
#define PIN_D9 3 // RXD0
#define PIN_D10 1 // TXD0

View File

@ -0,0 +1,56 @@
// 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 100
////////////////////////////////////////////////////////////////////////////////////////////
// Interface
////////////////////////////////////////////////////////////////////////////////////////////
#define TFT_PARALLEL_8_BIT
////////////////////////////////////////////////////////////////////////////////////////////
// Display driver type
////////////////////////////////////////////////////////////////////////////////////////////
#define ILI9488_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 28 // Data Command control pin
#define TFT_RST 2 // Reset pin
//#define TFT_RD -1 // Do not define, read pin permanently connected to 3V3
// Note: All the following pins are PIO hardware configured and driven
// The pins are hard-coded at the moment and must not be changed here
// Connections MUST use the pins below
#define TFT_WR 22
// PIO requires these to be sequentially increasing - do not change
#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
//*/
////////////////////////////////////////////////////////////////////////////////////////////
// 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,56 @@
// 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 101
////////////////////////////////////////////////////////////////////////////////////////////
// Interface
////////////////////////////////////////////////////////////////////////////////////////////
#define TFT_PARALLEL_8_BIT
////////////////////////////////////////////////////////////////////////////////////////////
// Display driver type
////////////////////////////////////////////////////////////////////////////////////////////
#define ILI9481_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 28 // Data Command control pin
#define TFT_RST 2 // Reset pin
//#define TFT_RD -1 // Do not define, read pin permanently connected to 3V3
// Note: All the following pins are PIO hardware configured and driven
// The pins are hard-coded at the moment and must not be changed here
// Connections MUST use the pins below
#define TFT_WR 22
// PIO requires these to be sequentially increasing - do not change
#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
//*/
////////////////////////////////////////////////////////////////////////////////////////////
// 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,56 @@
// 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 102
////////////////////////////////////////////////////////////////////////////////////////////
// Interface
////////////////////////////////////////////////////////////////////////////////////////////
#define TFT_PARALLEL_8_BIT
////////////////////////////////////////////////////////////////////////////////////////////
// Display driver type
////////////////////////////////////////////////////////////////////////////////////////////
#define ILI9341_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 28 // Data Command control pin
#define TFT_RST 2 // Reset pin
//#define TFT_RD -1 // Do not define, read pin permanently connected to 3V3
// Note: All the following pins are PIO hardware configured and driven
// The pins are hard-coded at the moment and must not be changed here
// Connections MUST use the pins below
#define TFT_WR 22
// PIO requires these to be sequentially increasing - do not change
#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
//*/
////////////////////////////////////////////////////////////////////////////////////////////
// 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,56 @@
// 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 103
////////////////////////////////////////////////////////////////////////////////////////////
// Interface
////////////////////////////////////////////////////////////////////////////////////////////
#define TFT_PARALLEL_8_BIT
////////////////////////////////////////////////////////////////////////////////////////////
// Display driver type
////////////////////////////////////////////////////////////////////////////////////////////
#define ILI9486_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 28 // Data Command control pin
#define TFT_RST 2 // Reset pin
//#define TFT_RD -1 // Do not define, read pin permanently connected to 3V3
// Note: All the following pins are PIO hardware configured and driven
// The pins are hard-coded at the moment and must not be changed here
// Connections MUST use the pins below
#define TFT_WR 22
// PIO requires these to be sequentially increasing - do not change
#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
//*/
////////////////////////////////////////////////////////////////////////////////////////////
// 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,56 @@
// 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 104
////////////////////////////////////////////////////////////////////////////////////////////
// Interface
////////////////////////////////////////////////////////////////////////////////////////////
#define TFT_PARALLEL_8_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 28 // Data Command control pin
#define TFT_RST 2 // Reset pin
//#define TFT_RD -1 // Do not define, read pin permanently connected to 3V3
// Note: All the following pins are PIO hardware configured and driven
// The pins are hard-coded at the moment and must not be changed here
// Connections MUST use the pins below
#define TFT_WR 22
// PIO requires these to be sequentially increasing - do not change
#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
//*/
////////////////////////////////////////////////////////////////////////////////////////////
// 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,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
////////////////////////////////////////////////////////////////////////////////////////////

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