mirror of
https://github.com/smartykit/apple1.git
synced 2025-04-06 17:39:37 +00:00
Refactored version of Video driver with support of custom colors & Made by...
Refactored version of Video driver with support of custom colors & Made with love by...
This commit is contained in:
parent
e3c9c1f1a0
commit
26e273ce95
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,702 @@
|
||||
/* SmartyKit 1 - 2.8" TFT 320x240 Display driver
|
||||
* http://www.smartykit.io/
|
||||
* Copyright (C) 2019-2022, Sergey Panarin <contact@smartykit.io>
|
||||
*
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Smarty_TFT.h"
|
||||
|
||||
int tftPortrait = TFT_PORTRAIT;
|
||||
|
||||
volatile int screenRow = 0;
|
||||
volatile int screenCol = 0;
|
||||
|
||||
// TO-DO: blinking cursor (driver function)
|
||||
|
||||
|
||||
SmartyKit_DisplayDriver::SmartyKit_DisplayDriver(int cs, int dc, int mosi, int clk, int rst, int miso)
|
||||
{
|
||||
_dc = dc;
|
||||
_rst = rst;
|
||||
_cs = cs;
|
||||
_sck = clk;
|
||||
_mosi = mosi;
|
||||
_miso = miso;
|
||||
|
||||
connection = TFT_SOFT_SPI;
|
||||
}
|
||||
|
||||
|
||||
void SmartyKit_DisplayDriver::setup(uint16_t setupColor, uint16_t setupBgColor, char* madeWithLoveString)
|
||||
{
|
||||
initSPI();
|
||||
|
||||
uint8_t cmd, x, numArgs;
|
||||
const uint8_t *addr = initcmd;
|
||||
while ((cmd = pgm_read_byte(addr++)) > 0) {
|
||||
x = pgm_read_byte(addr++);
|
||||
numArgs = x & 0x7F;
|
||||
|
||||
#if defined(_SMARTY_DEBUG_)
|
||||
Serial.print(F("Initcmd: cmd = "));Serial.print(cmd, HEX);
|
||||
Serial.print(F(", x = "));Serial.print(x, HEX);
|
||||
Serial.print(F(", addr = "));Serial.print((uint8_t)addr, HEX);
|
||||
Serial.print(F(", numArgs = "));Serial.print(numArgs, HEX);
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
sendCommand(cmd, addr, numArgs);
|
||||
delay(10);
|
||||
addr += numArgs;
|
||||
if (x & 0x80)
|
||||
delay(150);
|
||||
}
|
||||
|
||||
clipScreen = SCREEN_FULL_SCREEN;
|
||||
scrollLine = 0;
|
||||
cursor_x = 0;
|
||||
cursor_y = 0;
|
||||
textsize_x = 1;
|
||||
textsize_y = 1;
|
||||
_TFTwidth = ILI9341_TFTWIDTH;
|
||||
_TFTheight = ILI9341_TFTHEIGHT;
|
||||
_workingScreenWidth = SCREEN_WIDTH;
|
||||
_workingScreenHeight = SCREEN_HEIGHT;
|
||||
screen_col = 0;
|
||||
screen_row = 0;
|
||||
|
||||
color = setupColor;
|
||||
bgColor = setupBgColor;
|
||||
|
||||
if (tftPortrait == TFT_PORTRAIT)
|
||||
{
|
||||
setRotation(0);
|
||||
clearFullScreen(bgColor);
|
||||
//start right from the top-left corner
|
||||
_workingScreenTopMargin = 0;
|
||||
_workingScreenLeftMargin = 0;
|
||||
}
|
||||
if (tftPortrait == TFT_LANDSCAPE)
|
||||
{
|
||||
setRotation(3);
|
||||
clearFullScreen(bgColor);
|
||||
_workingScreenTopMargin = (_TFTheight - SCREEN_ROWS*LINE_HEIGHT)/2;
|
||||
_workingScreenLeftMargin = (_TFTwidth - SCREEN_COLS*LINE_WIDTH)/2;
|
||||
}
|
||||
//drawing splash screen
|
||||
strcpy(madeWithLove, madeWithLoveString);
|
||||
splashScreen();
|
||||
|
||||
if (tftPortrait == TFT_PORTRAIT)
|
||||
{
|
||||
//set built-in hardware scrolling
|
||||
setScrollMargins(0, ILI9341_TFTHEIGHT - SCREEN_HEIGHT);
|
||||
clipScreen = SCREEN_CLIPPED;
|
||||
}
|
||||
|
||||
bCursorOn = false;
|
||||
setCursor(0,0);
|
||||
clearScreen(bgColor);
|
||||
// startup ASCII art
|
||||
print(' ',color);print('o', color);print(' ', color); print('\n', color);
|
||||
print('/',color);print('|', color);print('\\', color); print('\n', color);
|
||||
print('/',color);print(' ', color);print('\\', color); print('\n', color);
|
||||
}
|
||||
|
||||
|
||||
void SmartyKit_DisplayDriver::initSPI(void)
|
||||
{
|
||||
if (_cs >= 0) {
|
||||
pinMode(_cs, OUTPUT);
|
||||
digitalWrite(_cs, HIGH); // Deselect
|
||||
delay(100);
|
||||
}
|
||||
|
||||
pinMode(_dc, OUTPUT);
|
||||
digitalWrite(_dc, HIGH); // Data mode
|
||||
|
||||
if (connection == TFT_HARD_SPI)
|
||||
{
|
||||
pinMode(SS, OUTPUT);
|
||||
// SPI.begin();
|
||||
spiClass = &SPI;
|
||||
|
||||
#if defined(_SMARTY_DEBUG_)
|
||||
Serial.print(F("SmartyKit TFT_HARD_SPI freq = "));Serial.println(DEFAULT_SPI_FREQ, DEC);
|
||||
#endif
|
||||
|
||||
spiSettings = SPISettings(DEFAULT_SPI_FREQ, MSBFIRST, SPI_MODE0);
|
||||
spiClass->begin();
|
||||
spiClass->beginTransaction(spiSettings);
|
||||
pinMode(SS, OUTPUT);
|
||||
}
|
||||
else if (connection == TFT_SOFT_SPI)
|
||||
{
|
||||
#if defined(_SMARTY_DEBUG_)
|
||||
Serial.println(F("SmartyKit TFT_SOFT_SPI"));
|
||||
#endif
|
||||
pinMode(_mosi, OUTPUT);
|
||||
digitalWrite(_mosi, LOW);
|
||||
pinMode(_sck, OUTPUT);
|
||||
digitalWrite(_sck, LOW);
|
||||
if (_miso >= 0) {
|
||||
pinMode(_miso, INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
if (_rst >= 0) {
|
||||
// Toggle _rst low to reset
|
||||
pinMode(_rst, OUTPUT);
|
||||
digitalWrite(_rst, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(_rst, LOW);
|
||||
delay(100);
|
||||
digitalWrite(_rst, HIGH);
|
||||
delay(200);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SmartyKit_DisplayDriver::splashScreen()
|
||||
{
|
||||
int logoWidth = 19;
|
||||
//draw Smarty logo in the center
|
||||
if (rotation == 0 || rotation == 3)
|
||||
{
|
||||
startWrite();
|
||||
setAddrWindow(_TFTwidth / 2 - logoWidth/2, _TFTheight / 2 - logoWidth/2, logoWidth, logoWidth);
|
||||
//white filled square
|
||||
for (uint16_t i = 0; i < logoWidth; i++)
|
||||
{
|
||||
for (int x = 0; x < logoWidth; x++)
|
||||
SPI_WRITE16(ILI9341_WHITE);
|
||||
}
|
||||
|
||||
int logoInnerWidth = logoWidth/2;
|
||||
setAddrWindow(_TFTwidth / 2 - logoInnerWidth/2, _TFTheight / 2 - logoInnerWidth/2, logoInnerWidth, logoInnerWidth);
|
||||
//black filled square inside the white one
|
||||
for (uint16_t i = 0; i < logoInnerWidth; i++)
|
||||
{
|
||||
for (int x = 0; x < logoInnerWidth; x++)
|
||||
SPI_WRITE16(ILI9341_BLACK);
|
||||
}
|
||||
endWrite();
|
||||
|
||||
delay(1000);
|
||||
|
||||
//print 'Made with love by...'
|
||||
int madeWithLoveLength = strlen(madeWithLove);
|
||||
setCursor(_TFTwidth / 2 - (madeWithLoveLength*LINE_WIDTH)/2, _TFTheight - LINE_HEIGHT- 4, CURSOR_ABSOLUTE);
|
||||
for (int i = 0; i < madeWithLoveLength; i++)
|
||||
{
|
||||
if (madeWithLove[i] == '\x03') //heart
|
||||
print(madeWithLove[i], ILI9341_RED);
|
||||
else
|
||||
print(madeWithLove[i], ILI9341_WHITE);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
delay(500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void SmartyKit_DisplayDriver::startWrite(void) {
|
||||
SPI_BEGIN_TRANSACTION();
|
||||
if (_cs >= 0)
|
||||
SPI_CS_LOW();
|
||||
}
|
||||
|
||||
inline void SmartyKit_DisplayDriver::endWrite(void) {
|
||||
if (_cs >= 0)
|
||||
SPI_CS_HIGH();
|
||||
SPI_END_TRANSACTION();
|
||||
}
|
||||
void SmartyKit_DisplayDriver::writeCommand(uint8_t cmd) {
|
||||
SPI_DC_LOW();
|
||||
spiWrite(cmd);
|
||||
SPI_DC_HIGH();
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::sendCommand(uint8_t commandByte, const uint8_t *dataBytes,
|
||||
uint8_t numDataBytes) {
|
||||
startWrite();
|
||||
|
||||
#if defined(_SMARTY_DEBUG_)
|
||||
Serial.print(F("PGM -> "));
|
||||
#endif
|
||||
|
||||
writeCommand(commandByte);
|
||||
|
||||
for (int i = 0; i < numDataBytes; i++) {
|
||||
#if defined(_SMARTY_DEBUG_)
|
||||
Serial.print(F("arg")); Serial.print(i+1, DEC); Serial.print(F(" = "));
|
||||
#endif
|
||||
uint8_t dataByte = pgm_read_byte(dataBytes++);
|
||||
dataByte &= 0xFF;
|
||||
spiWrite(dataByte);
|
||||
}
|
||||
|
||||
endWrite();
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::sendCommand(uint8_t commandByte, uint8_t *dataBytes,
|
||||
uint8_t numDataBytes) {
|
||||
startWrite();
|
||||
|
||||
writeCommand(commandByte);
|
||||
|
||||
for (int i = 0; i < numDataBytes; i++) {
|
||||
spiWrite(*dataBytes); // Send the data bytes
|
||||
dataBytes++;
|
||||
}
|
||||
|
||||
endWrite();
|
||||
}
|
||||
|
||||
|
||||
void SmartyKit_DisplayDriver::spiWrite(uint8_t b) {
|
||||
if (connection == TFT_HARD_SPI) {
|
||||
#if defined(__AVR__)
|
||||
AVR_WRITESPI(b);
|
||||
#else
|
||||
char c = spiClass->transfer(b);
|
||||
#if defined(_SMARTY_DEBUG_)
|
||||
Serial.print(F("spiWrite = "));Serial.println(c, HEX);
|
||||
#endif
|
||||
#endif
|
||||
} else if (connection == TFT_SOFT_SPI)
|
||||
{
|
||||
for (uint8_t bit = 0; bit < 8; bit++) {
|
||||
if (b & 0x80)
|
||||
SPI_MOSI_HIGH();
|
||||
else
|
||||
SPI_MOSI_LOW();
|
||||
SPI_SCK_HIGH();
|
||||
b <<= 1;
|
||||
SPI_SCK_LOW();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::setAddrWindow(uint16_t x1, uint16_t y1, uint16_t w,
|
||||
uint16_t h) {
|
||||
uint16_t x2 = (x1 + w - 1), y2 = (y1 + h - 1);
|
||||
writeCommand(ILI9341_CASET); // Column address set
|
||||
SPI_WRITE16(x1);
|
||||
SPI_WRITE16(x2);
|
||||
writeCommand(ILI9341_PASET); // Row address set
|
||||
SPI_WRITE16(y1);
|
||||
SPI_WRITE16(y2);
|
||||
writeCommand(ILI9341_RAMWR); // Write to RAM
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::SPI_WRITE16(uint16_t w) {
|
||||
|
||||
if (connection == TFT_HARD_SPI) {
|
||||
#if defined(__AVR__)
|
||||
AVR_WRITESPI(w >> 8);
|
||||
AVR_WRITESPI(w);
|
||||
#endif
|
||||
} else if (connection == TFT_SOFT_SPI) {
|
||||
for (uint8_t bit = 0; bit < 16; bit++) {
|
||||
if (w & 0x8000)
|
||||
SPI_MOSI_HIGH();
|
||||
else
|
||||
SPI_MOSI_LOW();
|
||||
SPI_SCK_HIGH();
|
||||
SPI_SCK_LOW();
|
||||
w <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void SmartyKit_DisplayDriver::writeColor(uint16_t color, uint32_t len)
|
||||
{
|
||||
for (uint16_t i = 0; i < len; i++)
|
||||
SPI_WRITE16(color);
|
||||
}
|
||||
|
||||
/* user functions */
|
||||
void SmartyKit_DisplayDriver::setCursor(int16_t x, int16_t y, uint8_t relative = CURSOR_RELATIVE) {
|
||||
if (relative == CURSOR_RELATIVE)
|
||||
{
|
||||
cursor_x = _workingScreenLeftMargin + x;
|
||||
cursor_y = _workingScreenTopMargin + y;
|
||||
}
|
||||
else if (relative == CURSOR_ABSOLUTE)
|
||||
{
|
||||
cursor_x = x;
|
||||
cursor_y = y;
|
||||
}
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::print(uint8_t c, uint16_t color = ILI9341_GREEN)
|
||||
{
|
||||
|
||||
if (c == '\n') { // Newline?
|
||||
cursor_x = _workingScreenLeftMargin; // Reset x to zero,
|
||||
cursor_y += textsize_y * 8; // advance y one line
|
||||
|
||||
int maxHeight = _TFTheight;
|
||||
if (clipScreen == SCREEN_CLIPPED)
|
||||
maxHeight = _workingScreenHeight + _workingScreenTopMargin;
|
||||
if (cursor_y >= maxHeight )
|
||||
{
|
||||
scrollToNextLine();
|
||||
cursor_y -= textsize_y * 8;
|
||||
}
|
||||
} else if (c != '\r') { // Ignore carriage returns
|
||||
if ((cursor_x + textsize_x * 6) > _workingScreenLeftMargin + _workingScreenWidth) { // Off right?
|
||||
cursor_x = _workingScreenLeftMargin; // Reset x to zero,
|
||||
cursor_y += textsize_y * 8; // advance y one line
|
||||
}
|
||||
|
||||
//autoscroll mode
|
||||
int maxHeight = _TFTheight;
|
||||
if (clipScreen == SCREEN_CLIPPED)
|
||||
maxHeight = _workingScreenHeight + _workingScreenTopMargin;
|
||||
if (cursor_y >= maxHeight)
|
||||
{
|
||||
scrollToNextLine();
|
||||
cursor_y -= textsize_y * 8;
|
||||
}
|
||||
|
||||
//converting screen coordinates to memory coordinates
|
||||
int yLine;
|
||||
if ((scrollLine + cursor_y) < maxHeight)
|
||||
yLine = scrollLine + cursor_y;
|
||||
else
|
||||
yLine = (scrollLine + cursor_y) - maxHeight;
|
||||
|
||||
drawChar(cursor_x, yLine, c, color, bgColor, textsize_x);
|
||||
cursor_x += textsize_x * 6; // Advance x one char
|
||||
|
||||
//TO-DO: set blinking cursor position next to printed char
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)
|
||||
{
|
||||
uint8_t size_x = size;
|
||||
uint8_t size_y = size;
|
||||
|
||||
if ((x >= _TFTwidth) || // Clip right
|
||||
(y >= _TFTheight) || // Clip bottom
|
||||
((x + 6 * size_x - 1) < 0) || // Clip left
|
||||
((y + 8 * size_y - 1) < 0)) // Clip top
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
startWrite();
|
||||
|
||||
for (int8_t i = 0; i < 5; i++) { // Char bitmap = 5 columns
|
||||
uint8_t line = pgm_read_byte(&font[c * 5 + i]);
|
||||
|
||||
for (int8_t j = 0; j < 8; j++, line >>= 1) {
|
||||
if (line & 1) {
|
||||
if (size_x == 1 && size_y == 1)
|
||||
writePixel(x + i, y + j, color);
|
||||
else
|
||||
writeFillRect(x + i * size_x, y + j * size_y, size_x, size_y,
|
||||
color);
|
||||
} else if (bg != color) {
|
||||
if (size_x == 1 && size_y == 1)
|
||||
writePixel(x + i, y + j, bg);
|
||||
else
|
||||
writeFillRect(x + i * size_x, y + j * size_y, size_x, size_y, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bg != color) { // If opaque, draw vertical line for last column
|
||||
if (size_x == 1 && size_y == 1)
|
||||
writeFastVLine(x + 5, y, 8, bg);
|
||||
else
|
||||
writeFillRect(x + 5 * size_x, y, size_x, 8 * size_y, bg);
|
||||
}
|
||||
|
||||
endWrite();
|
||||
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::writePixel(int16_t x, int16_t y, uint16_t color)
|
||||
{
|
||||
// Clip first...
|
||||
if ((x >= 0) && (x < _TFTwidth) && (y >= 0) && (y < _TFTheight)) {
|
||||
// THEN set up transaction (if needed) and draw...
|
||||
startWrite();
|
||||
setAddrWindow(x, y, 1, 1);
|
||||
SPI_WRITE16(color);
|
||||
endWrite();
|
||||
}
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
|
||||
{
|
||||
if ((x >= 0) && (x < _TFTwidth) && h) { // X on screen, nonzero height
|
||||
if (h < 0) { // If negative height...
|
||||
y += h + 1; // Move Y to top edge
|
||||
h = -h; // Use positive height
|
||||
}
|
||||
if (y < _TFTheight) { // Not off bottom
|
||||
int16_t y2 = y + h - 1;
|
||||
if (y2 >= 0) { // Not off top
|
||||
// Line partly or fully overlaps screen
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
h = y2 + 1;
|
||||
} // Clip top
|
||||
if (y2 >= _TFTheight) {
|
||||
h = _TFTheight - y;
|
||||
} // Clip bottom
|
||||
writeFillRectPreclipped(x, y, 1, h, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void SmartyKit_DisplayDriver::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
|
||||
{
|
||||
if (w && h) { // Nonzero width and height?
|
||||
if (w < 0) { // If negative width...
|
||||
x += w + 1; // Move X to left edge
|
||||
w = -w; // Use positive width
|
||||
}
|
||||
if (x < _TFTwidth) { // Not off right
|
||||
if (h < 0) { // If negative height...
|
||||
y += h + 1; // Move Y to top edge
|
||||
h = -h; // Use positive height
|
||||
}
|
||||
if (y < _TFTheight) { // Not off bottom
|
||||
int16_t x2 = x + w - 1;
|
||||
if (x2 >= 0) { // Not off left
|
||||
int16_t y2 = y + h - 1;
|
||||
if (y2 >= 0) { // Not off top
|
||||
// Rectangle partly or fully overlaps screen
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
w = x2 + 1;
|
||||
} // Clip left
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
h = y2 + 1;
|
||||
} // Clip top
|
||||
if (x2 >= _TFTwidth) {
|
||||
w = _TFTwidth - x;
|
||||
} // Clip right
|
||||
if (y2 >= _TFTheight) {
|
||||
h = _TFTheight - y;
|
||||
} // Clip bottom
|
||||
writeFillRectPreclipped(x, y, w, h, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void SmartyKit_DisplayDriver::writeFillRectPreclipped(int16_t x, int16_t y,
|
||||
int16_t w, int16_t h,
|
||||
uint16_t color) {
|
||||
startWrite();
|
||||
setAddrWindow(x, y, w, h);
|
||||
writeColor(color, (uint32_t)w * h);
|
||||
endWrite();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SmartyKit_DisplayDriver::setRotation(uint8_t m) {
|
||||
rotation = m % 4; // can't be higher than 3
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
m = (MADCTL_MX | MADCTL_BGR);
|
||||
_TFTwidth = ILI9341_TFTWIDTH;
|
||||
_TFTheight = ILI9341_TFTHEIGHT;
|
||||
break;
|
||||
case 1:
|
||||
m = (MADCTL_MV | MADCTL_BGR);
|
||||
_TFTwidth = ILI9341_TFTHEIGHT;
|
||||
_TFTheight = ILI9341_TFTWIDTH;
|
||||
break;
|
||||
case 2:
|
||||
m = (MADCTL_MY | MADCTL_BGR);
|
||||
_TFTwidth = ILI9341_TFTWIDTH;
|
||||
_TFTheight = ILI9341_TFTHEIGHT;
|
||||
break;
|
||||
case 3:
|
||||
// m = (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
|
||||
m = (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
|
||||
m = (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_ML | MADCTL_MH | MADCTL_BGR);
|
||||
_TFTwidth = ILI9341_TFTHEIGHT;
|
||||
_TFTheight = ILI9341_TFTWIDTH;
|
||||
break;
|
||||
}
|
||||
|
||||
sendCommand(ILI9341_MADCTL, &m, 1);
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::clearFullScreen(uint16_t color = ILI9341_WHITE)
|
||||
{
|
||||
startWrite();
|
||||
setAddrWindow(0, 0, _TFTwidth, _TFTheight);
|
||||
for (int y = 0; y < _TFTheight; y++)
|
||||
{
|
||||
|
||||
for (int x = 0; x < _TFTwidth; x++)
|
||||
{
|
||||
SPI_WRITE16(color);
|
||||
}
|
||||
}
|
||||
endWrite();
|
||||
}
|
||||
|
||||
|
||||
void SmartyKit_DisplayDriver::clearScreen(uint16_t color = ILI9341_WHITE)
|
||||
{
|
||||
if (rotation == 3)
|
||||
{
|
||||
uint16_t color2 = color;
|
||||
startWrite();
|
||||
setAddrWindow(_workingScreenLeftMargin, _workingScreenTopMargin, _workingScreenWidth, _workingScreenHeight);
|
||||
for (int y = 0; y < _workingScreenHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < _workingScreenWidth; x++)
|
||||
{
|
||||
if (y % 2 == 0)
|
||||
SPI_WRITE16(color);
|
||||
else
|
||||
SPI_WRITE16(color2);
|
||||
}
|
||||
}
|
||||
endWrite();
|
||||
}
|
||||
else if (rotation == 0)
|
||||
{
|
||||
uint16_t color2 = color;
|
||||
startWrite();
|
||||
setAddrWindow(_workingScreenLeftMargin, _workingScreenTopMargin, _workingScreenWidth, _workingScreenHeight);
|
||||
for (int y = 0; y < _workingScreenHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < _workingScreenWidth; x++)
|
||||
{
|
||||
if (y % 2 == 0)
|
||||
SPI_WRITE16(color);
|
||||
else
|
||||
SPI_WRITE16(color2);
|
||||
}
|
||||
}
|
||||
endWrite();
|
||||
}
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::scrollTo(uint16_t y) {
|
||||
|
||||
int scroll = y;
|
||||
if (y > SCREEN_HEIGHT)
|
||||
scroll = SCREEN_HEIGHT;
|
||||
|
||||
startWrite();
|
||||
setAddrWindow(0, 0, SCREEN_WIDTH, scroll);
|
||||
//draw bgColor line to erase
|
||||
for (uint16_t i = 0; i < scroll; i++)
|
||||
{
|
||||
for (int x = 0; x < SCREEN_WIDTH; x++)
|
||||
SPI_WRITE16(bgColor);
|
||||
}
|
||||
endWrite();
|
||||
//scroll screen
|
||||
uint8_t data[2];
|
||||
data[0] = (y) >> 8;
|
||||
data[1] = (y) & 0xff;
|
||||
sendCommand(ILI9341_VSCRSADD, (uint8_t *)data, 2);
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::drawScreenRect(uint16_t color)
|
||||
{
|
||||
if (rotation == 0 || rotation == 3)
|
||||
{
|
||||
startWrite();
|
||||
setAddrWindow(_workingScreenLeftMargin, _workingScreenTopMargin + _workingScreenHeight, _workingScreenWidth, 1);
|
||||
for (int x = 0; x < _workingScreenWidth; x++)
|
||||
SPI_WRITE16(color);
|
||||
endWrite();
|
||||
}
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::drawHLine(uint16_t y, uint16_t color)
|
||||
{
|
||||
//converting screen coordinates to memory coordinates
|
||||
int yLine;
|
||||
if ((scrollLine + y) < SCREEN_HEIGHT)
|
||||
yLine = scrollLine + y;
|
||||
else
|
||||
yLine = (scrollLine + y) - SCREEN_HEIGHT;
|
||||
|
||||
if (rotation == 0)
|
||||
{
|
||||
startWrite();
|
||||
setAddrWindow(0, yLine, SCREEN_WIDTH, 1);
|
||||
for (int x = 0; x < SCREEN_WIDTH; x++)
|
||||
{
|
||||
SPI_WRITE16(color);
|
||||
}
|
||||
endWrite();
|
||||
}
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::setScrollMargins(uint16_t top, uint16_t bottom) {
|
||||
// TFA+VSA+BFA must equal 320
|
||||
if (top + bottom <= ILI9341_TFTHEIGHT) {
|
||||
uint16_t middle = ILI9341_TFTHEIGHT - top - bottom;
|
||||
uint8_t data[6];
|
||||
data[0] = top >> 8;
|
||||
data[1] = top & 0xff;
|
||||
data[2] = middle >> 8;
|
||||
data[3] = middle & 0xff;
|
||||
data[4] = bottom >> 8;
|
||||
data[5] = bottom & 0xff;
|
||||
sendCommand(ILI9341_VSCRDEF, (uint8_t *)data, 6);
|
||||
}
|
||||
}
|
||||
|
||||
void SmartyKit_DisplayDriver::scrollToNextLine(void)
|
||||
{
|
||||
if (rotation == 0 || rotation == 3) //build-in hardware scroll
|
||||
{
|
||||
startWrite();
|
||||
setAddrWindow(0, scrollLine, _workingScreenWidth, LINE_HEIGHT);
|
||||
//draw bgColor line to erase
|
||||
for (uint16_t i = 0; i < LINE_HEIGHT; i++)
|
||||
{
|
||||
for (int x = 0; x < SCREEN_WIDTH; x++)
|
||||
SPI_WRITE16(bgColor);
|
||||
}
|
||||
endWrite();
|
||||
|
||||
if ((scrollLine + LINE_HEIGHT) < SCREEN_HEIGHT)
|
||||
scrollLine += LINE_HEIGHT;
|
||||
else
|
||||
scrollLine = (scrollLine + LINE_HEIGHT) - SCREEN_HEIGHT;
|
||||
|
||||
//scroll screen
|
||||
uint8_t data[2];
|
||||
data[0] = (scrollLine) >> 8;
|
||||
data[1] = (scrollLine) & 0xff;
|
||||
sendCommand(ILI9341_VSCRSADD, (uint8_t *)data, 2);
|
||||
}
|
||||
}
|
@ -0,0 +1,404 @@
|
||||
/* SmartyKit 1 - 2.8" TFT 320x240 Display driver
|
||||
* http://www.smartykit.io/
|
||||
* Copyright (C) 2019-2022, Sergey Panarin <contact@smartykit.io>
|
||||
*
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _SMARTYKIT_DISPLAY_DRIVER_IL9341H_
|
||||
#include <SPI.h>
|
||||
|
||||
//SmartyKit Display Driver parameters
|
||||
#define ILI9341_TFTWIDTH 240 ///< ILI9341 max TFT width
|
||||
#define ILI9341_TFTHEIGHT 320 ///< ILI9341 max TFT height
|
||||
|
||||
#define TFT_TFTwidth 320
|
||||
#define TFT_TFTheight 240
|
||||
#define SCREEN_COLS 40
|
||||
#define SCREEN_ROWS 24
|
||||
#define LINE_WIDTH 6
|
||||
#define LINE_HEIGHT 8
|
||||
#define SCREEN_WIDTH SCREEN_COLS*LINE_WIDTH
|
||||
#define SCREEN_HEIGHT SCREEN_ROWS*LINE_HEIGHT
|
||||
#define MARGIN_TOP 3*LINE_HEIGHT
|
||||
#define MARGIN_BOTTOM 3*LINE_HEIGHT
|
||||
#define MARGIN_LEFT (TFT_TFTwidth - SCREEN_COLS*LINE_WIDTH)/2
|
||||
#define MARGIN_RIGHT (TFT_TFTwidth - SCREEN_COLS*LINE_WIDTH)/2
|
||||
#define SCREEN_TOP MARGIN_TOP
|
||||
#define SCREEN_BOTTOM (TFT_TFTheight - MARGIN_BOTTOM)
|
||||
#define SCREEN_LEFT MARGIN_LEFT
|
||||
#define SCREEN_RIGHT (TFT_TFTwidth - MARGIN_RIGHT)
|
||||
#define SCREEN_RECT_MARGIN 3
|
||||
|
||||
//driver commands and parameters
|
||||
#define ILI9341_NOP 0x00 ///< No-op register
|
||||
#define ILI9341_SWRESET 0x01 ///< Software reset register
|
||||
#define ILI9341_RDDID 0x04 ///< Read display identification information
|
||||
#define ILI9341_RDDST 0x09 ///< Read Display Status
|
||||
|
||||
#define ILI9341_SLPIN 0x10 ///< Enter Sleep Mode
|
||||
#define ILI9341_SLPOUT 0x11 ///< Sleep Out
|
||||
#define ILI9341_PTLON 0x12 ///< Partial Mode ON
|
||||
#define ILI9341_NORON 0x13 ///< Normal Display Mode ON
|
||||
|
||||
#define ILI9341_RDMODE 0x0A ///< Read Display Power Mode
|
||||
#define ILI9341_RDMADCTL 0x0B ///< Read Display MADCTL
|
||||
#define ILI9341_RDPIXFMT 0x0C ///< Read Display Pixel Format
|
||||
#define ILI9341_RDIMGFMT 0x0D ///< Read Display Image Format
|
||||
#define ILI9341_RDSELFDIAG 0x0F ///< Read Display Self-Diagnostic Result
|
||||
|
||||
#define ILI9341_INVOFF 0x20 ///< Display Inversion OFF
|
||||
#define ILI9341_INVON 0x21 ///< Display Inversion ON
|
||||
#define ILI9341_GAMMASET 0x26 ///< Gamma Set
|
||||
#define ILI9341_DISPOFF 0x28 ///< Display OFF
|
||||
#define ILI9341_DISPON 0x29 ///< Display ON
|
||||
|
||||
#define ILI9341_CASET 0x2A ///< Column Address Set
|
||||
#define ILI9341_PASET 0x2B ///< Page Address Set
|
||||
#define ILI9341_RAMWR 0x2C ///< Memory Write
|
||||
#define ILI9341_RAMRD 0x2E ///< Memory Read
|
||||
|
||||
#define ILI9341_PTLAR 0x30 ///< Partial Area
|
||||
#define ILI9341_VSCRDEF 0x33 ///< Vertical Scrolling Definition
|
||||
#define ILI9341_MADCTL 0x36 ///< Memory Access Control
|
||||
#define ILI9341_VSCRSADD 0x37 ///< Vertical Scrolling Start Address
|
||||
#define ILI9341_PIXFMT 0x3A ///< COLMOD: Pixel Format Set
|
||||
|
||||
#define ILI9341_FRMCTR1 \
|
||||
0xB1 ///< Frame Rate Control (In Normal Mode/Full Colors)
|
||||
#define ILI9341_FRMCTR2 0xB2 ///< Frame Rate Control (In Idle Mode/8 colors)
|
||||
#define ILI9341_FRMCTR3 \
|
||||
0xB3 ///< Frame Rate control (In Partial Mode/Full Colors)
|
||||
#define ILI9341_INVCTR 0xB4 ///< Display Inversion Control
|
||||
#define ILI9341_DFUNCTR 0xB6 ///< Display Function Control
|
||||
|
||||
#define ILI9341_PWCTR1 0xC0 ///< Power Control 1
|
||||
#define ILI9341_PWCTR2 0xC1 ///< Power Control 2
|
||||
#define ILI9341_PWCTR3 0xC2 ///< Power Control 3
|
||||
#define ILI9341_PWCTR4 0xC3 ///< Power Control 4
|
||||
#define ILI9341_PWCTR5 0xC4 ///< Power Control 5
|
||||
#define ILI9341_VMCTR1 0xC5 ///< VCOM Control 1
|
||||
#define ILI9341_VMCTR2 0xC7 ///< VCOM Control 2
|
||||
|
||||
#define ILI9341_RDID1 0xDA ///< Read ID 1
|
||||
#define ILI9341_RDID2 0xDB ///< Read ID 2
|
||||
#define ILI9341_RDID3 0xDC ///< Read ID 3
|
||||
#define ILI9341_RDID4 0xDD ///< Read ID 4
|
||||
|
||||
#define ILI9341_GMCTRP1 0xE0 ///< Positive Gamma Correction
|
||||
#define ILI9341_GMCTRN1 0xE1 ///< Negative Gamma Correction
|
||||
//#define ILI9341_PWCTR6 0xFC
|
||||
|
||||
#define MADCTL_MY 0x80 ///< Bottom to top
|
||||
#define MADCTL_MX 0x40 ///< Right to left
|
||||
#define MADCTL_MV 0x20 ///< Reverse Mode
|
||||
#define MADCTL_NOTMV 0x00 ///< Reverse Mode
|
||||
|
||||
#define MADCTL_ML 0x10 ///< LCD refresh Bottom to top
|
||||
#define MADCTL_RGB 0x00 ///< Red-Green-Blue pixel order
|
||||
#define MADCTL_BGR 0x08 ///< Blue-Green-Red pixel order
|
||||
#define MADCTL_MH 0x04 ///< LCD refresh right to left
|
||||
|
||||
// Color definitions
|
||||
#define ILI9341_BLACK 0x0000 ///< 0, 0, 0
|
||||
#define ILI9341_NAVY 0x000F ///< 0, 0, 123
|
||||
#define ILI9341_DARKGREEN 0x03E0 ///< 0, 125, 0
|
||||
#define ILI9341_DARKCYAN 0x03EF ///< 0, 125, 123
|
||||
#define ILI9341_MAROON 0x7800 ///< 123, 0, 0
|
||||
#define ILI9341_PURPLE 0x780F ///< 123, 0, 123
|
||||
#define ILI9341_OLIVE 0x7BE0 ///< 123, 125, 0
|
||||
#define ILI9341_LIGHTGREY 0xC618 ///< 198, 195, 198
|
||||
#define ILI9341_DARKGREY 0x7BEF ///< 123, 125, 123
|
||||
#define ILI9341_BLUE 0x001F ///< 0, 0, 255
|
||||
#define ILI9341_GREEN 0x07E0 ///< 0, 255, 0
|
||||
#define ILI9341_CYAN 0x07FF ///< 0, 255, 255
|
||||
#define ILI9341_RED 0xF800 ///< 255, 0, 0
|
||||
#define ILI9341_MAGENTA 0xF81F ///< 255, 0, 255
|
||||
#define ILI9341_YELLOW 0xFFE0 ///< 255, 255, 0
|
||||
#define ILI9341_WHITE 0xFFFF ///< 255, 255, 255
|
||||
#define ILI9341_ORANGE 0xFD20 ///< 255, 165, 0
|
||||
#define ILI9341_GREENYELLOW 0xAFE5 ///< 173, 255, 41
|
||||
#define ILI9341_PINK 0xFC18 ///< 255, 130, 198
|
||||
|
||||
// Possible values for SPITFT.connection:
|
||||
#define TFT_HARD_SPI 0 ///< Display interface = hardware SPI
|
||||
#define TFT_SOFT_SPI 1 ///< Display interface = software SPI
|
||||
|
||||
#define TFT_PORTRAIT 1
|
||||
#define TFT_LANDSCAPE 0
|
||||
|
||||
#define CURSOR_RELATIVE 1
|
||||
#define CURSOR_ABSOLUTE 0
|
||||
|
||||
#define SCREEN_FULL_SCREEN 0
|
||||
#define SCREEN_CLIPPED 1
|
||||
|
||||
|
||||
#if defined(__AVR__)
|
||||
#define DEFAULT_SPI_FREQ 2000000 ///< Hardware SPI default speed
|
||||
#else
|
||||
#define DEFAULT_SPI_FREQ 4000000L ///< Hardware SPI default speed
|
||||
#endif
|
||||
|
||||
#if defined(__AVR__)
|
||||
#define AVR_WRITESPI(x) for (SPDR = (x); (!(SPSR & _BV(SPIF)));)
|
||||
#endif
|
||||
|
||||
// #undef USE_FAST_PINIO
|
||||
|
||||
|
||||
|
||||
|
||||
// clang-format off
|
||||
static const uint8_t PROGMEM initcmd[] = {
|
||||
0xEF, 3, 0x03, 0x80, 0x02,
|
||||
0xCF, 3, 0x00, 0xC1, 0x30, //Power control B (CFh)
|
||||
0xED, 4, 0x64, 0x03, 0x12, 0x81, //Power on sequence control (EDh)
|
||||
0xE8, 3, 0x85, 0x00, 0x78, //Driver timing control A (E8h) 0xE8, 3, 0x85, 0x00, 0x78,
|
||||
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, //Power control A (CBh)
|
||||
0xF7, 1, 0x20, //Pump ratio control (F7h)
|
||||
0xEA, 2, 0x00, 0x00, //Driver timing control B (EAh) 0xEA, 2, 0x00, 0x00,
|
||||
ILI9341_PWCTR1 , 1, 0x23, // Power control VRH[5:0]
|
||||
ILI9341_PWCTR2 , 1, 0x10, // Power control SAP[2:0];BT[3:0]
|
||||
ILI9341_VMCTR1 , 2, 0x3e, 0x28, // VCM control
|
||||
ILI9341_VMCTR2 , 1, 0x86, // VCM control2
|
||||
ILI9341_MADCTL , 1, 0x48, // Memory Access Control
|
||||
ILI9341_VSCRSADD, 1, 0x00, // Vertical scroll zero
|
||||
ILI9341_PIXFMT , 1, 0x55,
|
||||
ILI9341_FRMCTR1 , 2, 0x00, 0x18,
|
||||
ILI9341_DFUNCTR , 3, 0x08, 0x82, 0x27, // Display Function Control
|
||||
0xF2, 1, 0x00, // 3Gamma Function Disable
|
||||
ILI9341_GAMMASET , 1, 0x01, // Gamma curve selected
|
||||
ILI9341_GMCTRP1 , 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma
|
||||
0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
|
||||
ILI9341_GMCTRN1 , 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma
|
||||
0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
|
||||
ILI9341_SLPOUT , 0x80, // Exit Sleep
|
||||
ILI9341_DISPON , 0x80, // Display on
|
||||
0x00 // End of list
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// Standard ASCII 5x7 font
|
||||
static const unsigned char font[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x3E, 0x6B,
|
||||
0x4F, 0x6B, 0x3E, 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x18, 0x3C, 0x7E, 0x3C,
|
||||
0x18, 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
|
||||
0x18, 0x3C, 0x18, 0x00, 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, 0x18, 0x24,
|
||||
0x18, 0x00, 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x30, 0x48, 0x3A, 0x06, 0x0E,
|
||||
0x26, 0x29, 0x79, 0x29, 0x26, 0x40, 0x7F, 0x05, 0x05, 0x07, 0x40, 0x7F,
|
||||
0x05, 0x25, 0x3F, 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x7F, 0x3E, 0x1C, 0x1C,
|
||||
0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x14, 0x22, 0x7F, 0x22, 0x14, 0x5F,
|
||||
0x5F, 0x00, 0x5F, 0x5F, 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, 0x66, 0x89,
|
||||
0x95, 0x6A, 0x60, 0x60, 0x60, 0x60, 0x60, 0x94, 0xA2, 0xFF, 0xA2, 0x94,
|
||||
0x08, 0x04, 0x7E, 0x04, 0x08, 0x10, 0x20, 0x7E, 0x20, 0x10, 0x08, 0x08,
|
||||
0x2A, 0x1C, 0x08, 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x1E, 0x10, 0x10, 0x10,
|
||||
0x10, 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x30, 0x38, 0x3E, 0x38, 0x30, 0x06,
|
||||
0x0E, 0x3E, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F,
|
||||
0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14,
|
||||
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x23, 0x13, 0x08, 0x64, 0x62, 0x36, 0x49,
|
||||
0x56, 0x20, 0x50, 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, 0x1C, 0x22, 0x41,
|
||||
0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x08,
|
||||
0x08, 0x3E, 0x08, 0x08, 0x00, 0x80, 0x70, 0x30, 0x00, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x00, 0x00, 0x60, 0x60, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02,
|
||||
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x72, 0x49,
|
||||
0x49, 0x49, 0x46, 0x21, 0x41, 0x49, 0x4D, 0x33, 0x18, 0x14, 0x12, 0x7F,
|
||||
0x10, 0x27, 0x45, 0x45, 0x45, 0x39, 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x41,
|
||||
0x21, 0x11, 0x09, 0x07, 0x36, 0x49, 0x49, 0x49, 0x36, 0x46, 0x49, 0x49,
|
||||
0x29, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00,
|
||||
0x00, 0x08, 0x14, 0x22, 0x41, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x41,
|
||||
0x22, 0x14, 0x08, 0x02, 0x01, 0x59, 0x09, 0x06, 0x3E, 0x41, 0x5D, 0x59,
|
||||
0x4E, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x3E,
|
||||
0x41, 0x41, 0x41, 0x22, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x49, 0x49,
|
||||
0x49, 0x41, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x3E, 0x41, 0x41, 0x51, 0x73,
|
||||
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x41, 0x7F, 0x41, 0x00, 0x20, 0x40,
|
||||
0x41, 0x3F, 0x01, 0x7F, 0x08, 0x14, 0x22, 0x41, 0x7F, 0x40, 0x40, 0x40,
|
||||
0x40, 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x3E,
|
||||
0x41, 0x41, 0x41, 0x3E, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x3E, 0x41, 0x51,
|
||||
0x21, 0x5E, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x26, 0x49, 0x49, 0x49, 0x32,
|
||||
0x03, 0x01, 0x7F, 0x01, 0x03, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x1F, 0x20,
|
||||
0x40, 0x20, 0x1F, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x63, 0x14, 0x08, 0x14,
|
||||
0x63, 0x03, 0x04, 0x78, 0x04, 0x03, 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
|
||||
0x7F, 0x41, 0x41, 0x41, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x41, 0x41,
|
||||
0x41, 0x7F, 0x04, 0x02, 0x01, 0x02, 0x04, 0x40, 0x40, 0x40, 0x40, 0x40,
|
||||
0x00, 0x03, 0x07, 0x08, 0x00, 0x20, 0x54, 0x54, 0x78, 0x40, 0x7F, 0x28,
|
||||
0x44, 0x44, 0x38, 0x38, 0x44, 0x44, 0x44, 0x28, 0x38, 0x44, 0x44, 0x28,
|
||||
0x7F, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x08, 0x7E, 0x09, 0x02, 0x18,
|
||||
0xA4, 0xA4, 0x9C, 0x78, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x44, 0x7D,
|
||||
0x40, 0x00, 0x20, 0x40, 0x40, 0x3D, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,
|
||||
0x00, 0x41, 0x7F, 0x40, 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x7C, 0x08,
|
||||
0x04, 0x04, 0x78, 0x38, 0x44, 0x44, 0x44, 0x38, 0xFC, 0x18, 0x24, 0x24,
|
||||
0x18, 0x18, 0x24, 0x24, 0x18, 0xFC, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x48,
|
||||
0x54, 0x54, 0x54, 0x24, 0x04, 0x04, 0x3F, 0x44, 0x24, 0x3C, 0x40, 0x40,
|
||||
0x20, 0x7C, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x3C, 0x40, 0x30, 0x40, 0x3C,
|
||||
0x44, 0x28, 0x10, 0x28, 0x44, 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x44, 0x64,
|
||||
0x54, 0x4C, 0x44, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x77, 0x00,
|
||||
0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x3C,
|
||||
0x26, 0x23, 0x26, 0x3C, 0x1E, 0xA1, 0xA1, 0x61, 0x12, 0x3A, 0x40, 0x40,
|
||||
0x20, 0x7A, 0x38, 0x54, 0x54, 0x55, 0x59, 0x21, 0x55, 0x55, 0x79, 0x41,
|
||||
0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut
|
||||
0x21, 0x55, 0x54, 0x78, 0x40, 0x20, 0x54, 0x55, 0x79, 0x40, 0x0C, 0x1E,
|
||||
0x52, 0x72, 0x12, 0x39, 0x55, 0x55, 0x55, 0x59, 0x39, 0x54, 0x54, 0x54,
|
||||
0x59, 0x39, 0x55, 0x54, 0x54, 0x58, 0x00, 0x00, 0x45, 0x7C, 0x41, 0x00,
|
||||
0x02, 0x45, 0x7D, 0x42, 0x00, 0x01, 0x45, 0x7C, 0x40, 0x7D, 0x12, 0x11,
|
||||
0x12, 0x7D, // A-umlaut
|
||||
0xF0, 0x28, 0x25, 0x28, 0xF0, 0x7C, 0x54, 0x55, 0x45, 0x00, 0x20, 0x54,
|
||||
0x54, 0x7C, 0x54, 0x7C, 0x0A, 0x09, 0x7F, 0x49, 0x32, 0x49, 0x49, 0x49,
|
||||
0x32, 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut
|
||||
0x32, 0x4A, 0x48, 0x48, 0x30, 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x3A, 0x42,
|
||||
0x40, 0x20, 0x78, 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 0x3D, 0x42, 0x42, 0x42,
|
||||
0x3D, // O-umlaut
|
||||
0x3D, 0x40, 0x40, 0x40, 0x3D, 0x3C, 0x24, 0xFF, 0x24, 0x24, 0x48, 0x7E,
|
||||
0x49, 0x43, 0x66, 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 0xFF, 0x09, 0x29, 0xF6,
|
||||
0x20, 0xC0, 0x88, 0x7E, 0x09, 0x03, 0x20, 0x54, 0x54, 0x79, 0x41, 0x00,
|
||||
0x00, 0x44, 0x7D, 0x41, 0x30, 0x48, 0x48, 0x4A, 0x32, 0x38, 0x40, 0x40,
|
||||
0x22, 0x7A, 0x00, 0x7A, 0x0A, 0x0A, 0x72, 0x7D, 0x0D, 0x19, 0x31, 0x7D,
|
||||
0x26, 0x29, 0x29, 0x2F, 0x28, 0x26, 0x29, 0x29, 0x29, 0x26, 0x30, 0x48,
|
||||
0x4D, 0x40, 0x20, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x38, 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 0x2F, 0x10, 0x28, 0x34, 0xFA, 0x00,
|
||||
0x00, 0x7B, 0x00, 0x00, 0x08, 0x14, 0x2A, 0x14, 0x22, 0x22, 0x14, 0x2A,
|
||||
0x14, 0x08, 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old
|
||||
// code
|
||||
0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block
|
||||
0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block
|
||||
0x00, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x14, 0x14,
|
||||
0x14, 0xFF, 0x00, 0x10, 0x10, 0xFF, 0x00, 0xFF, 0x10, 0x10, 0xF0, 0x10,
|
||||
0xF0, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x14, 0x14, 0xF7, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0xFF, 0x14, 0x14, 0xF4, 0x04, 0xFC, 0x14, 0x14, 0x17,
|
||||
0x10, 0x1F, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0x1F, 0x00,
|
||||
0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10,
|
||||
0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x00, 0x00, 0x00, 0xFF,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x14, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x1F,
|
||||
0x10, 0x17, 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14, 0x17, 0x10, 0x17,
|
||||
0x14, 0x14, 0xF4, 0x04, 0xF4, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x17,
|
||||
0x14, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0xF4, 0x14, 0x10,
|
||||
0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x1F, 0x10, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x1F, 0x14, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x00, 0x00, 0xF0, 0x10, 0xF0,
|
||||
0x10, 0x10, 0xFF, 0x10, 0xFF, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x10, 0x10,
|
||||
0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x38, 0x44, 0x44,
|
||||
0x38, 0x44, 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta
|
||||
0x7E, 0x02, 0x02, 0x06, 0x06, 0x02, 0x7E, 0x02, 0x7E, 0x02, 0x63, 0x55,
|
||||
0x49, 0x41, 0x63, 0x38, 0x44, 0x44, 0x3C, 0x04, 0x40, 0x7E, 0x20, 0x1E,
|
||||
0x20, 0x06, 0x02, 0x7E, 0x02, 0x02, 0x99, 0xA5, 0xE7, 0xA5, 0x99, 0x1C,
|
||||
0x2A, 0x49, 0x2A, 0x1C, 0x4C, 0x72, 0x01, 0x72, 0x4C, 0x30, 0x4A, 0x4D,
|
||||
0x4D, 0x30, 0x30, 0x48, 0x78, 0x48, 0x30, 0xBC, 0x62, 0x5A, 0x46, 0x3D,
|
||||
0x3E, 0x49, 0x49, 0x49, 0x00, 0x7E, 0x01, 0x01, 0x01, 0x7E, 0x2A, 0x2A,
|
||||
0x2A, 0x2A, 0x2A, 0x44, 0x44, 0x5F, 0x44, 0x44, 0x40, 0x51, 0x4A, 0x44,
|
||||
0x40, 0x40, 0x44, 0x4A, 0x51, 0x40, 0x00, 0x00, 0xFF, 0x01, 0x03, 0xE0,
|
||||
0x80, 0xFF, 0x00, 0x00, 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x36, 0x12, 0x36,
|
||||
0x24, 0x36, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00, 0x18, 0x18, 0x00,
|
||||
0x00, 0x00, 0x10, 0x10, 0x00, 0x30, 0x40, 0xFF, 0x01, 0x01, 0x00, 0x1F,
|
||||
0x01, 0x01, 0x1E, 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x3C, 0x3C, 0x3C,
|
||||
0x3C, 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP
|
||||
};
|
||||
|
||||
// allow clean compilation with [-Wunused-const-variable=] and [-Wall]
|
||||
static inline void avoid_unused_const_variable_compiler_warning(void) {
|
||||
(void)font;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//SmartyKit Display Driver Class members
|
||||
class SmartyKit_DisplayDriver
|
||||
{
|
||||
public:
|
||||
SmartyKit_DisplayDriver::SmartyKit_DisplayDriver(int cs, int dc, int mosi, int clk, int rst, int miso);
|
||||
|
||||
SmartyKit_DisplayDriver::~SmartyKit_DisplayDriver()
|
||||
{
|
||||
if(spiClass)
|
||||
spiClass->endTransaction();
|
||||
}
|
||||
SPIClass *spiClass;
|
||||
SPISettings spiSettings;
|
||||
int connection;
|
||||
int clipScreen;
|
||||
uint8_t rotation;
|
||||
int16_t _TFTwidth; //full TFT width
|
||||
int16_t _TFTheight; //full TFT height
|
||||
int16_t _workingScreenWidth; //screen area width: SCREEN_WIDTH
|
||||
int16_t _workingScreenHeight; //screen area height: SCREEN_HEIGHT
|
||||
int16_t _workingScreenTopMargin;
|
||||
int16_t _workingScreenLeftMargin;
|
||||
int16_t scrollLine;
|
||||
int16_t cursor_x;
|
||||
int16_t cursor_y;
|
||||
int16_t screen_col;
|
||||
int16_t screen_row;
|
||||
|
||||
int16_t textsize_x;
|
||||
int16_t textsize_y;
|
||||
int8_t _dc;
|
||||
int8_t _rst; ///< Reset pin # (or -1)
|
||||
int8_t _cs; ///< Chip select pin # (or -1)
|
||||
int8_t _sck;
|
||||
int8_t _mosi;
|
||||
int8_t _miso;
|
||||
|
||||
uint16_t color;
|
||||
uint16_t bgColor;
|
||||
char madeWithLove[40];
|
||||
|
||||
bool bCursorOn;
|
||||
|
||||
//functions
|
||||
void setup(uint16_t setupColor, uint16_t setupBgColor, char* madeWithLoveString);
|
||||
void initSPI(void);
|
||||
void sendCommand(uint8_t commandByte, const uint8_t *dataBytes, uint8_t numDataBytes);
|
||||
void sendCommand(uint8_t commandByte, uint8_t *dataBytes = 0, uint8_t numDataBytes = 0);
|
||||
void spiWrite(uint8_t b); // Write single byte as DATA
|
||||
void writeCommand(uint8_t cmd);
|
||||
void setAddrWindow(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h);
|
||||
inline void writeColor(uint16_t color, uint32_t len);
|
||||
inline void startWrite(void);
|
||||
inline void endWrite(void);
|
||||
|
||||
void setRotation(uint8_t m);
|
||||
void clearFullScreen(uint16_t color = ILI9341_WHITE);
|
||||
void clearScreen(uint16_t color = ILI9341_WHITE);
|
||||
void splashScreen();
|
||||
|
||||
void drawScreenRect(uint16_t color);
|
||||
void drawHLine(uint16_t y, uint16_t color);
|
||||
void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
inline void writeFillRectPreclipped(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||
void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||
void scrollTo(uint16_t y);
|
||||
void setScrollMargins(uint16_t top, uint16_t bottom);
|
||||
void scrollToNextLine(void);
|
||||
void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size);
|
||||
void writePixel(int16_t x, int16_t y, uint16_t color);
|
||||
void setCursor(int16_t x, int16_t y, uint8_t relative = CURSOR_RELATIVE);
|
||||
void print(uint8_t c, uint16_t color = ILI9341_GREEN);
|
||||
|
||||
inline void SPI_BEGIN_TRANSACTION(void) { };
|
||||
inline void SPI_END_TRANSACTION(void) { };
|
||||
void SPI_WRITE16(uint16_t w);
|
||||
//for TFT_SOFT_SPI
|
||||
inline void SPI_MOSI_HIGH(void) { PORTC = PORTC | B000100;}; //MOSI = A2 = PC2
|
||||
inline void SPI_MOSI_LOW(void) { PORTC = PORTC & B111011;}; //MOSI = A2 = PC2
|
||||
inline void SPI_SCK_HIGH(void) { PORTC = PORTC | B001000;}; //SCK = A3 = PC3
|
||||
inline void SPI_SCK_LOW(void) { PORTC = PORTC & B110111;}; //SCK = A3 = PC3
|
||||
inline void SPI_DC_HIGH(void) { digitalWrite(_dc, HIGH); };
|
||||
inline void SPI_DC_LOW(void) { digitalWrite(_dc, LOW); };
|
||||
inline void SPI_CS_LOW(void) { digitalWrite(_cs, LOW); };
|
||||
inline void SPI_CS_HIGH(void) { digitalWrite(_cs, HIGH); };
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user