20 #include <avr/pgmspace.h> 22 #include "pins_arduino.h" 23 #include "wiring_private.h" 26 inline void spiWait17(
void) __attribute__((always_inline));
27 inline
void spiWait15(
void) __attribute__((always_inline));
28 inline
void spiWait14(
void) __attribute__((always_inline));
29 inline
void spiWait12(
void) __attribute__((always_inline));
30 inline
void spiWrite16(uint16_t data, int16_t count) __attribute__((always_inline));
31 inline
void spiWrite16s(uint16_t data) __attribute__((always_inline));
32 inline
void spiWrite16R(uint16_t data, int16_t count) __attribute__((always_inline));
46 digitalWrite(_rst, LOW);
47 pinMode(_rst, OUTPUT);
59 cursor_y = cursor_x = 0;
77 fontsloaded |= 0x0004;
81 fontsloaded |= 0x0010;
85 fontsloaded |= 0x0040;
89 fontsloaded |= 0x0080;
93 fontsloaded |= 0x0100;
107 asm volatile(
"nop\n\t" ::);
108 while (!(SPSR & _BV(SPIF)));
169 #ifdef SPI_HAS_TRANSACTION 170 #ifdef SUPPORT_TRANSACTIONS 172 static inline void spi_begin(
void) __attribute__((always_inline));
175 SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
178 static inline void spi_end(
void) __attribute__((always_inline));
180 static inline void spi_end(
void) {
181 SPI.endTransaction();
183 #else // we do not want to SUPPORT_TRANSACTIONS 188 #endif // SUPPORT_TRANSACTIONS 215 SPI.setClockDivider(SPI_CLOCK_DIV2);
216 SPI.setBitOrder(MSBFIRST);
217 SPI.setDataMode(SPI_MODE0);
224 digitalWrite(_rst, HIGH);
226 digitalWrite(_rst, LOW);
228 digitalWrite(_rst, HIGH);
234 static const uint8_t PROGMEM
273 0x09, 0x16, 0x09, 0x20,
274 0x21, 0x1B, 0x13, 0x19,
275 0x17, 0x15, 0x1E, 0x2B,
276 0x04, 0x05, 0x02, 0x0E,
278 0x0B, 0x14, 0x08, 0x1E,
279 0x22, 0x1D, 0x18, 0x1E,
280 0x1B, 0x1A, 0x24, 0x2B,
281 0x06, 0x06, 0x02, 0x0F,
352 0x02, 0x1c, 0x07, 0x12,
353 0x37, 0x32, 0x29, 0x2d,
354 0x29, 0x25, 0x2B, 0x39,
355 0x00, 0x01, 0x03, 0x10,
357 0x03, 0x1d, 0x07, 0x06,
358 0x2E, 0x2C, 0x29, 0x2D,
359 0x2E, 0x2E, 0x37, 0x3F,
360 0x00, 0x00, 0x02, 0x10,
369 if (tabcolor ==
INITB)
409 uint8_t numCommands, numArgs;
413 numCommands = pgm_read_byte(addr++);
414 while (numCommands--)
417 numArgs = pgm_read_byte(addr++);
419 numArgs &= ~ST7735_INIT_DELAY;
427 ms = pgm_read_byte(addr++);
428 delay( (ms==255 ? 500 : ms) );
442 int16_t ddF_y = - r - r;
480 int16_t ddF_y = -2 * r;
492 if (cornername & 0x8) {
496 if (cornername & 0x4) {
500 if (cornername & 0x2) {
504 if (cornername & 0x1) {
531 int16_t ddF_y = -r - r;
545 if (cornername & 0x1) {
549 if (cornername & 0x2) {
565 int32_t rx2 = rx * rx;
566 int32_t ry2 = ry * ry;
567 int32_t fx2 = 4 * rx2;
568 int32_t fy2 = 4 * ry2;
571 for (x = 0, y = ry, s = 2*ry2+rx2*(1-2*ry); ry2*x <= rx2*y; x++)
582 s += ry2 * ((4 * x) + 6);
585 for (x = rx, y = 0, s = 2*rx2+ry2*(1-2*rx); rx2*y <= ry2*x; y++)
596 s += rx2 * ((4 * y) + 6);
609 int32_t rx2 = rx * rx;
610 int32_t ry2 = ry * ry;
611 int32_t fx2 = 4 * rx2;
612 int32_t fy2 = 4 * ry2;
615 for (x = 0, y = ry, s = 2*ry2+rx2*(1-2*ry); ry2*x <= rx2*y; x++)
625 s += ry2 * ((4 * x) + 6);
628 for (x = rx, y = 0, s = 2*rx2+ry2*(1-2*rx); rx2*y <= ry2*x; y++)
638 s += rx2 * ((4 * y) + 6);
693 fillRect(x + r, y, w - r - r, h, color);
719 int16_t a, b, y, last;
723 tftswap(y0, y1); tftswap(x0, x1);
726 tftswap(y2, y1); tftswap(x2, x1);
729 tftswap(y0, y1); tftswap(x0, x1);
735 else if (x1 > b) b = x1;
737 else if (x2 > b) b = x2;
758 if (y1 == y2) last = y1;
761 for (y = y0; y <= last; y++) {
767 if (a > b) tftswap(a, b);
773 sa = dx12 * (y - y1);
774 sb = dx02 * (y - y0);
775 for (; y <= y2; y++) {
781 if (a > b) tftswap(a, b);
793 int16_t i, j, byteWidth = (w + 7) / 8;
795 for (j = 0; j < h; j++) {
796 for (i = 0; i < w; i++ ) {
797 if (pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) {
926 unsigned int str_width = 0;
930 if (font>1 && font<9)
931 widthtable = (
char *)pgm_read_word( &(
fontdata[font].widthtbl ) ) - 32;
935 uniCode = *(
string++);
937 if (font == 1) str_width += 6;
940 str_width += pgm_read_byte( widthtable + uniCode);
975 ((x + 6 * size - 1) < 0) ||
976 ((y + 8 * size - 1) < 0))
978 boolean fillbg = (bg != color);
983 if ((size==1) && fillbg)
987 setWindow(x, y, x+5, y+8);
988 for (int8_t i = 0; i < 5; i++ ) column[i] = pgm_read_byte(font + (c * 5) + i);
991 for (int8_t j = 0; j < 8; j++) {
992 for (int8_t k = 0; k < 5; k++ ) {
993 if (column[k] & mask) {
994 while (!(SPSR & _BV(SPIF)));
995 SPDR = color >> 8;
asm volatile(
"nop\n\t" ::);
996 while (!(SPSR & _BV(SPIF)));
1000 while (!(SPSR & _BV(SPIF)));
1001 SPDR = bg >> 8;
asm volatile(
"nop\n\t" ::);
1002 while (!(SPSR & _BV(SPIF)));
1008 while (!(SPSR & _BV(SPIF)));
1009 SPDR = bg >> 8;
while (!(SPSR & _BV(SPIF)));
1012 while (!(SPSR & _BV(SPIF)));
1018 for (int8_t i = 0; i < 5; i++ ) {
1019 uint8_t line = pgm_read_byte(font + c*5 + i);
1020 if (line & 0x1)
drawPixel(x + i, y, color);
1021 if (line & 0x2)
drawPixel(x + i, y + 1, color);
1022 if (line & 0x4)
drawPixel(x + i, y + 2, color);
1023 if (line & 0x8)
drawPixel(x + i, y + 3, color);
1024 if (line & 0x10)
drawPixel(x + i, y + 4, color);
1025 if (line & 0x20)
drawPixel(x + i, y + 5, color);
1026 if (line & 0x40)
drawPixel(x + i, y + 6, color);
1027 if (line & 0x80)
drawPixel(x + i, y + 7, color);
1031 for (int8_t i = 0; i < 5; i++ ) {
1032 uint8_t line = pgm_read_byte(font + c*5 + i);
1033 for (int8_t j = 0; j < 8; j++) {
1034 if (line & 0x1)
fillRect(x + (i * size), y + (j * size), size, size, color);
1035 else if (fillbg)
fillRect(x + i * size, y + j * size, size, size, bg);
1056 setWindow(x0, y0, x1, y1);
1058 while (!(SPSR & _BV(SPIF)));
1068 void TFT_ST7735::setWindow(int16_t x0, int16_t y0, int16_t x1, int16_t y1)
1172 while (!(SPSR & _BV(SPIF)));
1174 while (!(SPSR & _BV(SPIF)));
1194 while (!(SPSR & _BV(SPIF)));
1229 while (!(SPSR & _BV(SPIF)));
1262 while (!(SPSR & _BV(SPIF)));
1282 int8_t steep = abs(y1 - y0) > abs(x1 - x0);
1300 int16_t err = dx / 2;
1301 int8_t ystep = (y0 < y1) ? 1 : (-1);
1307 for (; x0 <= x1; x0++) {
1308 if ((x0 >= 0) && (y0 >= 0) && (y0 <
_width))
break;
1316 if (x0 > x1)
return;
1318 setWindow(y0, x0, y0,
_height);
1319 for (; x0 <= x1; x0++) {
1324 if ((y0 < 0) || (y0 >=
_width))
break;
1327 setWindow(y0, x0+1, y0,
_height);
1335 for (; x0 <= x1; x0++) {
1336 if ((x0 >= 0) && (y0 >= 0) && (y0 <
_height))
break;
1344 if (x0 > x1)
return;
1346 setWindow(x0, y0,
_width, y0);
1347 for (; x0 <= x1; x0++) {
1352 if ((y0 < 0) || (y0 >=
_height))
break;
1355 setWindow(x0+1, y0,
_width, y0);
1363 #else // FAST_LINE not defined so use more compact version 1368 int8_t steep = abs(y1 - y0) > abs(x1 - x0);
1379 int16_t dx = x1 - x0, dy = abs(y1 - y0);;
1382 int16_t err = dx >> 1, ystep = -1, xs = x0, dlen = 0;
1383 if (y0 < y1) ystep = 1;
1387 for (; x0 <= x1; x0++) {
1392 if (dlen == 1)
drawPixel(y0, xs, color);
1394 dlen = 0; y0 += ystep; xs = x0 + 1;
1401 for (; x0 <= x1; x0++) {
1406 if (dlen == 1)
drawPixel(xs, y0, color);
1408 dlen = 0; y0 += ystep; xs = x0 + 1;
1415 #endif // FAST_LINE option 1452 setWindow(x, y,
_width, y);
1468 if ((x >
_width) || (y >
_height) || (w==0) || (h==0))
return;
1474 setWindow(x, y, x + w - 1, y + h - 1);
1476 if (h > w) tftswap(h, w);
1490 return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
1498 #define MADCTL_MY 0x80 1499 #define MADCTL_MX 0x40 1500 #define MADCTL_MV 0x20 1501 #define MADCTL_ML 0x10 1502 #define MADCTL_RGB 0x00 1503 #define MADCTL_BGR 0x08 1504 #define MADCTL_MH 0x04 1614 if (uniCode ==
'\r')
return 1;
1615 unsigned int width = 0;
1623 width = pgm_read_byte(widtbl_f16 + uniCode-32);
1624 height = chr_hgt_f16;
1626 width = (width + 6) / 8;
1640 width = pgm_read_byte( pgm_read_word( &(
fontdata[
textfont].widthtbl ) ) + uniCode-32 );
1657 if (uniCode ==
'\n') {
1690 unsigned int width = 0;
1692 unsigned int flash_address = 0;
1699 flash_address = pgm_read_word(&chrtbl_f16[uniCode]);
1700 width = pgm_read_byte(widtbl_f16 + uniCode);
1701 height = chr_hgt_f16;
1711 flash_address = pgm_read_word( pgm_read_word( &(
fontdata[font].chartbl ) ) + uniCode*
sizeof(
void *) );
1712 width = pgm_read_byte( pgm_read_word( &(
fontdata[font].widthtbl ) ) + uniCode );
1713 height= pgm_read_byte( &
fontdata[font].height );
1727 #ifdef LOAD_FONT2 // chop out 962 bytes of code if we do not need it 1735 for (
int i = 0; i <
height; i++)
1739 for (
int k = 0; k < w; k++)
1741 line = pgm_read_byte(flash_address + w * i + k);
1743 if (textsize == 1) {
1758 if (line & 0x20)
fillRect(pX + 2 * textsize, pY, textsize, textsize,
textcolor);
1759 if (line & 0x10)
fillRect(pX + 3 * textsize, pY, textsize, textsize,
textcolor);
1760 if (line & 0x08)
fillRect(pX + 4 * textsize, pY, textsize, textsize,
textcolor);
1761 if (line & 0x04)
fillRect(pX + 5 * textsize, pY, textsize, textsize,
textcolor);
1762 if (line & 0x02)
fillRect(pX + 6 * textsize, pY, textsize, textsize,
textcolor);
1763 if (line & 0x01)
fillRect(pX + 7 * textsize, pY, textsize, textsize,
textcolor);
1774 setWindow(x, y, (x + w * 8) - 1, y + height - 1);
1777 for (
int i = 0; i <
height; i++)
1779 for (
int k = 0; k < w; k++)
1781 line = pgm_read_byte(flash_address + w * i + k);
1786 while (!(SPSR & _BV(SPIF)));
1787 SPDR = th;
asm volatile(
"nop\n\t" ::);
1788 while (!(SPSR & _BV(SPIF)));
1792 while (!(SPSR & _BV(SPIF)));
1793 SPDR = bh;
asm volatile(
"nop\n\t" ::);
1794 while (!(SPSR & _BV(SPIF)));
1802 while (!(SPSR & _BV(SPIF)));
1813 #ifdef LOAD_RLE //674 bytes of code 1821 int px = 0, py = pY, tpy = pY;
1826 byte ts = textsize - 1;
1831 line = pgm_read_byte(flash_address);
1837 px = x + textsize * (pc %
width);
1838 py = y + textsize * (pc /
width);
1841 px = x + pc %
width;
1842 py = y + pc /
width;
1846 while (!(SPSR & _BV(SPIF)));
1847 setWindow(px, py, px + ts, py + ts);
1852 while (!(SPSR & _BV(SPIF)));
1854 while (!(SPSR & _BV(SPIF)));
1859 while (!(SPSR & _BV(SPIF)));
1861 while (!(SPSR & _BV(SPIF)));
1866 if (px >= (x + width * textsize))
1878 while (!(SPSR & _BV(SPIF)));
1886 setWindow(x, y, x + width - 1, y + height - 1);
1891 line = pgm_read_byte(flash_address++);
1902 while (!(SPSR & _BV(SPIF)));
1919 uint8_t padding = 1;
1920 unsigned int cheight = 0;
1925 unsigned int cwidth =
textWidth(
string, font);
1969 if (poX < 0) poX = 0;
1971 if (poY < 0) poY = 0;
1975 while (*
string) sumX +=
drawChar(*(
string++), poX+sumX, poY, font);
1979 #ifndef PADDING_DEBUG 1982 int padXc = poX+sumX;
1989 padXc = (
padX-sumX)>>1;
1990 if (padXc>poX) padXc = poX;
2005 int padXc = poX+sumX;
2013 padXc = (
padX-sumX)>>1;
2014 if (padXc>poX) padXc = poX;
2063 ltoa(long_num, str, 10);
2078 float rounding = 0.5;
2083 for (uint8_t i = 0; i < dp; ++i) rounding /= 10.0;
2085 if (floatNumber < -rounding)
2090 floatNumber = -floatNumber;
2093 floatNumber += rounding;
2096 if (floatNumber >= 2147483647) {
2103 unsigned long temp = (
unsigned long)floatNumber;
2106 ltoa(temp, str + ptr, 10);
2109 while ((uint8_t)str[ptr] != 0) ptr++;
2117 floatNumber = floatNumber - temp;
2122 while ((i < dp) && (digits < 9))
2127 ltoa(temp, str + ptr, 10);
2129 floatNumber -= temp;
2148 " sbiw %[count],0\n" 2152 "1: out %[spi],%[hi]\n" 2159 " out %[spi],%[lo]\n" 2168 " sbiw %[count],1 \n" 2173 : [temp]
"=d" (temp), [count]
"+w" (count)
2174 : [spi]
"i" (_SFR_IO_ADDR(SPDR)), [lo]
"r" ((uint8_t)data), [hi]
"r" ((uint8_t)(data>>8))
2188 "out %[spi],%[hi]\n" 2195 " out %[spi],%[lo]\n" 2202 : [temp]
"=d" (temp)
2203 : [spi]
"i" (_SFR_IO_ADDR(SPDR)), [lo]
"r" ((uint8_t)data), [hi]
"r" ((uint8_t)(data>>8))
2221 "sbiw %[count],0 \n" 2225 "1: out %[spi],%[hi]\n" 2233 " out %[spi],%[lo]\n" 2242 " sbiw %[count],1 \n" 2247 : [temp]
"=d" (temp), [count]
"+w" (count)
2248 : [spi]
"i" (_SFR_IO_ADDR(SPDR)), [lo]
"r" ((uint8_t)(data>>8)), [hi]
"r" ((uint8_t)data)
void setTextDatum(uint8_t datum)
int16_t textWidth(char *string, int font)
int16_t drawString(char *string, int poX, int poY, int font)
void setTextSize(uint8_t size)
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)
void setRotation(uint8_t r)
int16_t drawRightString(char *string, int dX, int poY, int font)
uint16_t color565(uint8_t r, uint8_t g, uint8_t b)
#define ST7735_INIT_DELAY
void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t font)
void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
void spiWait14(void) __attribute__((always_inline))
void fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)
void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)
void fillEllipse(int16_t x0, int16_t y0, int16_t rx, int16_t ry, uint16_t color)
void spiWrite16s(uint16_t data) __attribute__((always_inline))
int16_t drawCentreString(char *string, int dX, int poY, int font)
const PROGMEM fontinfo fontdata[]
void spiWait12(void) __attribute__((always_inline))
void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color)
void writedata(uint8_t d)
void setCursor(int16_t x, int16_t y)
void drawEllipse(int16_t x0, int16_t y0, int16_t rx, int16_t ry, uint16_t color)
virtual size_t write(uint8_t)
void pushColors(uint16_t *data, uint8_t len)
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
int16_t drawFloat(float floatNumber, int decimal, int poX, int poY, int font)
void spiWait17(void) __attribute__((always_inline))
uint8_t getRotation(void)
void spiWrite16R(uint16_t data, int16_t count) __attribute__((always_inline))
void fillScreen(uint16_t color)
void pushColor(uint16_t color)
void fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color)
void drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color)
void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
int16_t fontHeight(int font)
void spiWait15(void) __attribute__((always_inline))
void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
void setTextColor(uint16_t color)
void setTextPadding(uint16_t x_width)
void commandList(const uint8_t *addr)
void writecommand(uint8_t c)
void invertDisplay(boolean i)
void setTextFont(uint8_t font)
void setTextWrap(boolean wrap)
void spiWrite16(uint16_t data, int16_t count) __attribute__((always_inline))
void setAddrWindow(int16_t x0, int16_t y0, int16_t x1, int16_t y1)
void drawPixel(uint16_t x, uint16_t y, uint16_t color)
void drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color)
uint16_t fontsLoaded(void)
int16_t drawNumber(long long_num, int poX, int poY, int font)
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)
void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color)
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)