253 lines
8.1 KiB
C
253 lines
8.1 KiB
C
|
// https://github.com/PaulStoffregen/ILI9341_t3
|
||
|
// http://forum.pjrc.com/threads/26305-Highly-optimized-ILI9341-(320x240-TFT-color-display)-library
|
||
|
|
||
|
/***************************************************
|
||
|
This is our library for the Adafruit ILI9341 Breakout and Shield
|
||
|
----> http://www.adafruit.com/products/1651
|
||
|
|
||
|
Check out the links above for our tutorials and wiring diagrams
|
||
|
These displays use SPI to communicate, 4 or 5 pins are required to
|
||
|
interface (RST is optional)
|
||
|
Adafruit invests time and resources providing this open source code,
|
||
|
please support Adafruit and open-source hardware by purchasing
|
||
|
products from Adafruit!
|
||
|
|
||
|
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||
|
MIT license, all text above must be included in any redistribution
|
||
|
****************************************************/
|
||
|
|
||
|
#ifndef _ILI9341_t3H_
|
||
|
#define _ILI9341_t3H_
|
||
|
|
||
|
//#include "Arduino.h"
|
||
|
#include "stdbool.h"
|
||
|
|
||
|
#define ILI9341_TFTWIDTH 240
|
||
|
#define ILI9341_TFTHEIGHT 320
|
||
|
|
||
|
#define ILI9341_NOP 0x00
|
||
|
#define ILI9341_SWRESET 0x01
|
||
|
#define ILI9341_RDDID 0x04
|
||
|
#define ILI9341_RDDST 0x09
|
||
|
|
||
|
#define ILI9341_SLPIN 0x10
|
||
|
#define ILI9341_SLPOUT 0x11
|
||
|
#define ILI9341_PTLON 0x12
|
||
|
#define ILI9341_NORON 0x13
|
||
|
|
||
|
#define ILI9341_RDMODE 0x0A
|
||
|
#define ILI9341_RDMADCTL 0x0B
|
||
|
#define ILI9341_RDPIXFMT 0x0C
|
||
|
#define ILI9341_RDIMGFMT 0x0A
|
||
|
#define ILI9341_RDSELFDIAG 0x0F
|
||
|
|
||
|
#define ILI9341_INVOFF 0x20
|
||
|
#define ILI9341_INVON 0x21
|
||
|
#define ILI9341_GAMMASET 0x26
|
||
|
#define ILI9341_DISPOFF 0x28
|
||
|
#define ILI9341_DISPON 0x29
|
||
|
|
||
|
#define ILI9341_CASET 0x2A
|
||
|
#define ILI9341_PASET 0x2B
|
||
|
#define ILI9341_RAMWR 0x2C
|
||
|
#define ILI9341_RAMRD 0x2E
|
||
|
|
||
|
#define ILI9341_PTLAR 0x30
|
||
|
#define ILI9341_MADCTL 0x36
|
||
|
#define ILI9341_PIXFMT 0x3A
|
||
|
|
||
|
#define ILI9341_FRMCTR1 0xB1
|
||
|
#define ILI9341_FRMCTR2 0xB2
|
||
|
#define ILI9341_FRMCTR3 0xB3
|
||
|
#define ILI9341_INVCTR 0xB4
|
||
|
#define ILI9341_DFUNCTR 0xB6
|
||
|
|
||
|
#define ILI9341_PWCTR1 0xC0
|
||
|
#define ILI9341_PWCTR2 0xC1
|
||
|
#define ILI9341_PWCTR3 0xC2
|
||
|
#define ILI9341_PWCTR4 0xC3
|
||
|
#define ILI9341_PWCTR5 0xC4
|
||
|
#define ILI9341_VMCTR1 0xC5
|
||
|
#define ILI9341_VMCTR2 0xC7
|
||
|
|
||
|
#define ILI9341_RDID1 0xDA
|
||
|
#define ILI9341_RDID2 0xDB
|
||
|
#define ILI9341_RDID3 0xDC
|
||
|
#define ILI9341_RDID4 0xDD
|
||
|
|
||
|
#define ILI9341_GMCTRP1 0xE0
|
||
|
#define ILI9341_GMCTRN1 0xE1
|
||
|
/*
|
||
|
#define ILI9341_PWCTR6 0xFC
|
||
|
|
||
|
*/
|
||
|
|
||
|
// Color definitions
|
||
|
#define ILI9341_BLACK 0x0000
|
||
|
#define ILI9341_BLUE 0x001F
|
||
|
#define ILI9341_RED 0xF800
|
||
|
#define ILI9341_GREEN 0x07E0
|
||
|
#define ILI9341_CYAN 0x07FF
|
||
|
#define ILI9341_MAGENTA 0xF81F
|
||
|
#define ILI9341_YELLOW 0xFFE0
|
||
|
#define ILI9341_WHITE 0xFFFF
|
||
|
|
||
|
|
||
|
//class ILI9341_t3 : public Print
|
||
|
//{
|
||
|
// public:
|
||
|
ILI9341_t3(uint8_t _CS, uint8_t _DC, uint8_t _RST = 255);
|
||
|
void begin(void);
|
||
|
void pushColor(uint16_t color);
|
||
|
void fillScreen(uint16_t color);
|
||
|
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||
|
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||
|
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||
|
void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||
|
void setRotation(uint8_t r);
|
||
|
void invertDisplay(bool i);
|
||
|
void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
|
||
|
// Pass 8-bit (each) R,G,B, get back 16-bit packed color
|
||
|
static uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
|
||
|
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
|
||
|
}
|
||
|
|
||
|
//uint8_t readdata(void);
|
||
|
uint8_t readcommand8(uint8_t reg, uint8_t index = 0);
|
||
|
|
||
|
// KJE Added functions to read pixel data...
|
||
|
uint16_t readPixel(int16_t x, int16_t y);
|
||
|
|
||
|
|
||
|
// from Adafruit_GFX.h
|
||
|
void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
|
||
|
void drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color);
|
||
|
void fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
|
||
|
void fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, 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);
|
||
|
void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
|
||
|
void drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
|
||
|
void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
|
||
|
void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color);
|
||
|
void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size);
|
||
|
void setCursor(int16_t x, int16_t y);
|
||
|
void setTextColor(uint16_t c);
|
||
|
void setTextColor(uint16_t c, uint16_t bg);
|
||
|
void setTextSize(uint8_t s);
|
||
|
void setTextWrap(bool w);
|
||
|
virtual size_t write(uint8_t);
|
||
|
int16_t width(void) { return _width; }
|
||
|
int16_t height(void) { return _height; }
|
||
|
uint8_t getRotation(void);
|
||
|
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
|
||
|
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||
|
|
||
|
|
||
|
// protected:
|
||
|
int16_t
|
||
|
_width, _height, // Display w/h as modified by current rotation
|
||
|
cursor_x, cursor_y;
|
||
|
uint16_t
|
||
|
textcolor, textbgcolor;
|
||
|
uint8_t
|
||
|
textsize,
|
||
|
rotation;
|
||
|
bool
|
||
|
wrap; // If set, 'wrap' text at right edge of display
|
||
|
|
||
|
// private:
|
||
|
uint8_t _rst;
|
||
|
uint8_t _cs, _dc;
|
||
|
uint8_t pcs_data, pcs_command;
|
||
|
|
||
|
void setAddr(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
|
||
|
__attribute__((always_inline)) {
|
||
|
writecommand_cont(ILI9341_CASET); // Column addr set
|
||
|
writedata16_cont(x0); // XSTART
|
||
|
writedata16_cont(x1); // XEND
|
||
|
writecommand_cont(ILI9341_PASET); // Row addr set
|
||
|
writedata16_cont(y0); // YSTART
|
||
|
writedata16_cont(y1); // YEND
|
||
|
}
|
||
|
//void waitFifoNotFull(void) __attribute__((always_inline)) {
|
||
|
void waitFifoNotFull(void) {
|
||
|
uint32_t sr;
|
||
|
uint32_t tmp __attribute__((unused));
|
||
|
do {
|
||
|
sr = SPI0.SR;
|
||
|
if (sr & 0xF0) tmp = SPI0_POPR; // drain RX FIFO
|
||
|
} while ((sr & (15 << 12)) > (3 << 12));
|
||
|
}
|
||
|
//void waitFifoEmpty(void) __attribute__((always_inline)) {
|
||
|
void waitFifoEmpty(void) {
|
||
|
uint32_t sr;
|
||
|
uint32_t tmp __attribute__((unused));
|
||
|
do {
|
||
|
sr = SPI0.SR;
|
||
|
if (sr & 0xF0) tmp = SPI0_POPR; // drain RX FIFO
|
||
|
} while ((sr & 0xF0F0) > 0); // wait both RX & TX empty
|
||
|
}
|
||
|
void waitTransmitComplete(void) __attribute__((always_inline)) {
|
||
|
uint32_t tmp __attribute__((unused));
|
||
|
while (!(SPI0.SR & SPI_SR_TCF)) ; // wait until final output done
|
||
|
tmp = SPI0_POPR; // drain the final RX FIFO word
|
||
|
}
|
||
|
void writecommand_cont(uint8_t c) __attribute__((always_inline)) {
|
||
|
SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
|
||
|
waitFifoNotFull();
|
||
|
}
|
||
|
void writedata8_cont(uint8_t c) __attribute__((always_inline)) {
|
||
|
SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
|
||
|
waitFifoNotFull();
|
||
|
}
|
||
|
void writedata16_cont(uint16_t d) __attribute__((always_inline)) {
|
||
|
SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_CONT;
|
||
|
waitFifoNotFull();
|
||
|
}
|
||
|
void writecommand_last(uint8_t c) __attribute__((always_inline)) {
|
||
|
waitFifoEmpty();
|
||
|
SPI0.SR = SPI_SR_TCF;
|
||
|
SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0);
|
||
|
waitTransmitComplete();
|
||
|
}
|
||
|
void writedata8_last(uint8_t c) __attribute__((always_inline)) {
|
||
|
waitFifoEmpty();
|
||
|
SPI0.SR = SPI_SR_TCF;
|
||
|
SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0);
|
||
|
waitTransmitComplete();
|
||
|
}
|
||
|
void writedata16_last(uint16_t d) __attribute__((always_inline)) {
|
||
|
waitFifoEmpty();
|
||
|
SPI0.SR = SPI_SR_TCF;
|
||
|
SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1);
|
||
|
waitTransmitComplete();
|
||
|
}
|
||
|
void HLine(int16_t x, int16_t y, int16_t w, uint16_t color)
|
||
|
__attribute__((always_inline)) {
|
||
|
setAddr(x, y, x+w-1, y);
|
||
|
writecommand_cont(ILI9341_RAMWR);
|
||
|
do { writedata16_cont(color); } while (--w > 0);
|
||
|
}
|
||
|
void VLine(int16_t x, int16_t y, int16_t h, uint16_t color)
|
||
|
__attribute__((always_inline)) {
|
||
|
setAddr(x, y, x, y+h-1);
|
||
|
writecommand_cont(ILI9341_RAMWR);
|
||
|
do { writedata16_cont(color); } while (--h > 0);
|
||
|
}
|
||
|
void Pixel(int16_t x, int16_t y, uint16_t color)
|
||
|
__attribute__((always_inline)) {
|
||
|
setAddr(x, y, x, y);
|
||
|
writecommand_cont(ILI9341_RAMWR);
|
||
|
writedata16_cont(color);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//};
|
||
|
|
||
|
#ifndef swap
|
||
|
#define swap(a, b) { typeof(a) t = a; a = b; b = t; }
|
||
|
#endif
|
||
|
|
||
|
#endif
|