787 lines
14 KiB
C++
787 lines
14 KiB
C++
|
|
#include "TFT_GC9D01N.h"
|
|
#include "Fonts.h"
|
|
|
|
void TFT_GC9D01N_Class::begin_tft_write()
|
|
{
|
|
SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0)); // RP2040 SDK -> 68us delay!
|
|
CS_L;
|
|
// SET_BUS_WRITE_MODE;
|
|
}
|
|
|
|
void TFT_GC9D01N_Class::end_tft_write()
|
|
{
|
|
// SPI_BUSY_CHECK; // Check send complete and clean out unused rx data
|
|
CS_H;
|
|
SPI.endTransaction(); // RP2040 SDK -> 0.7us delay
|
|
}
|
|
|
|
void TFT_GC9D01N_Class::writedata(uint8_t d)
|
|
{
|
|
begin_tft_write();
|
|
|
|
DC_D; // Play safe, but should already be in data mode 高电平1为数据
|
|
|
|
SPI.transfer(d);
|
|
|
|
CS_L; // Allow more hold time for low VDI rail
|
|
|
|
end_tft_write();
|
|
}
|
|
|
|
void TFT_GC9D01N_Class::writecommand(uint8_t c)
|
|
{
|
|
begin_tft_write();
|
|
|
|
DC_C; //高电平1为数据
|
|
|
|
SPI.transfer(c);//tft_Write_8(c);
|
|
|
|
DC_D;
|
|
|
|
end_tft_write();
|
|
|
|
}
|
|
|
|
void TFT_GC9D01N_Class::lcd_init()
|
|
{
|
|
|
|
RST_H;
|
|
delay(80);
|
|
|
|
RST_L;
|
|
delay(80);
|
|
|
|
RST_H;
|
|
delay(480);
|
|
|
|
|
|
writecommand(0xFE);
|
|
writecommand(0xEF);
|
|
|
|
writecommand(0x80);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x81);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x82);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x83);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x84);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x85);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x86);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x87);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x88);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x89);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x8A);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x8B);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x8C);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x8D);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x8E);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x8F);
|
|
writedata(0xFF);
|
|
|
|
writecommand(0x3A);
|
|
writedata(0x05);
|
|
|
|
writecommand(0xEC);
|
|
writedata(0x11);
|
|
|
|
|
|
writecommand(0x7E);
|
|
writedata(0x7a);
|
|
|
|
|
|
writecommand(0x74);
|
|
writedata(0x02);
|
|
writedata(0x0E);
|
|
writedata(0x00);
|
|
writedata(0x00);
|
|
writedata(0x28);
|
|
writedata(0x00);
|
|
writedata(0x00);
|
|
|
|
writecommand(0x98);
|
|
writedata(0x3E);
|
|
writecommand(0x99);
|
|
writedata(0x3E);
|
|
|
|
|
|
|
|
|
|
writecommand(0xB5);
|
|
writedata(0x0E);
|
|
writedata(0x0E);
|
|
writecommand(0x60);
|
|
writedata(0x38);
|
|
writedata(0x09);
|
|
writedata(0x6D);
|
|
writedata(0x67);
|
|
|
|
|
|
writecommand(0x63);
|
|
writedata(0x38);
|
|
writedata(0xAD);
|
|
writedata(0x6D);
|
|
writedata(0x67);
|
|
writedata(0x05);
|
|
|
|
|
|
writecommand(0x64);
|
|
writedata(0x38);
|
|
writedata(0x0B);
|
|
writedata(0x70);
|
|
writedata(0xAB);
|
|
writedata(0x6D);
|
|
writedata(0x67);
|
|
|
|
|
|
writecommand(0x66);
|
|
writedata(0x38);
|
|
writedata(0x0F);
|
|
writedata(0x70);
|
|
writedata(0xAF);
|
|
writedata(0x6d);
|
|
writedata(0x67);
|
|
|
|
writecommand(0x6A);
|
|
writedata(0x00);
|
|
writedata(0x00);
|
|
|
|
writecommand(0x68);
|
|
writedata(0x3B);
|
|
writedata(0x08);
|
|
writedata(0x04);
|
|
writedata(0x00);
|
|
writedata(0x04);
|
|
writedata(0x64);
|
|
writedata(0x67);
|
|
|
|
|
|
|
|
writecommand(0x6C);
|
|
writedata(0x22);
|
|
writedata(0x02);
|
|
writedata(0x22);
|
|
writedata(0x02);
|
|
writedata(0x22);
|
|
writedata(0x22);
|
|
writedata(0x50);
|
|
|
|
writecommand(0x6E);
|
|
writedata(0x00);
|
|
writedata(0x00);
|
|
writedata(0x00);
|
|
writedata(0x00);
|
|
writedata(0x07);
|
|
writedata(0x01);
|
|
writedata(0x13);
|
|
writedata(0x11);
|
|
|
|
writedata(0x0B);
|
|
writedata(0x09);
|
|
writedata(0x16);
|
|
writedata(0x15);
|
|
writedata(0x1D);
|
|
writedata(0x1E);
|
|
writedata(0x00);
|
|
writedata(0x00);
|
|
|
|
writedata(0x00);
|
|
writedata(0x00);
|
|
writedata(0x1E);
|
|
|
|
writedata(0x1D);
|
|
writedata(0x15);
|
|
writedata(0x16);
|
|
writedata(0x0A);
|
|
writedata(0x0C);
|
|
|
|
writedata(0x12);
|
|
writedata(0x14);
|
|
writedata(0x02);
|
|
writedata(0x08);
|
|
writedata(0x00);
|
|
writedata(0x00);
|
|
writedata(0x00);
|
|
writedata(0x00);
|
|
|
|
|
|
writecommand(0xA9);
|
|
writedata(0x1B);
|
|
|
|
writecommand(0xA8);
|
|
writedata(0x6B);
|
|
|
|
writecommand(0xA8);
|
|
writedata(0x6D);
|
|
|
|
writecommand(0xA7);
|
|
writedata(0x40);
|
|
|
|
writecommand(0xAD);
|
|
writedata(0x47);
|
|
|
|
|
|
writecommand(0xAF);
|
|
writedata(0x73);
|
|
|
|
writecommand(0xAF);
|
|
writedata(0x73);
|
|
|
|
writecommand(0xAC);
|
|
writedata(0x44);
|
|
|
|
writecommand(0xA3);
|
|
writedata(0x6C);
|
|
|
|
writecommand(0xCB);
|
|
writedata(0x00);
|
|
|
|
writecommand(0xCD);
|
|
writedata(0x22);
|
|
|
|
|
|
writecommand(0xC2);
|
|
writedata(0x10);
|
|
|
|
writecommand(0xC5);
|
|
writedata(0x00);
|
|
|
|
writecommand(0xC6);
|
|
writedata(0x0E);
|
|
|
|
writecommand(0xC7);
|
|
writedata(0x1f);
|
|
|
|
writecommand(0xC8);
|
|
writedata(0x0E);
|
|
|
|
writecommand(0xbf);
|
|
writedata(0x00);
|
|
|
|
writecommand(0xF9);
|
|
writedata(0x20);
|
|
|
|
writecommand(0x9b);
|
|
writedata(0x3b);
|
|
writecommand(0x93);
|
|
writedata(0x33);
|
|
writedata(0x7f);
|
|
writedata(0x00);
|
|
|
|
writecommand(0x70);
|
|
writedata(0x0E);
|
|
writedata(0x0f);
|
|
writedata(0x03);
|
|
writedata(0x0e);
|
|
writedata(0x0f);
|
|
writedata(0x03);
|
|
|
|
writecommand(0x71);
|
|
writedata(0x0e);
|
|
writedata(0x16);
|
|
writedata(0x03);
|
|
|
|
writecommand(0x91);
|
|
writedata(0x0e);
|
|
writedata(0x09);
|
|
|
|
|
|
|
|
writecommand(0xc3);
|
|
writedata(0x2c);
|
|
writecommand(0xc4);
|
|
writedata(0x1a);
|
|
|
|
|
|
|
|
|
|
writecommand(0xf0);
|
|
writedata(0x51);
|
|
writedata(0x13);
|
|
writedata(0x0c);
|
|
writedata(0x06);
|
|
writedata(0x00);
|
|
writedata(0x2f);
|
|
|
|
writecommand(0xf2);
|
|
writedata(0x51);
|
|
writedata(0x13);
|
|
writedata(0x0c);
|
|
writedata(0x06);
|
|
writedata(0x00);
|
|
writedata(0x33);
|
|
|
|
writecommand(0xf1);
|
|
writedata(0x3c);
|
|
writedata(0x94);
|
|
writedata(0x4f);
|
|
writedata(0x33);
|
|
writedata(0x34);
|
|
writedata(0xCf);
|
|
|
|
writecommand(0xf3);
|
|
writedata(0x4d);
|
|
writedata(0x94);
|
|
writedata(0x4f);
|
|
writedata(0x33);
|
|
writedata(0x34);
|
|
writedata(0xCf);
|
|
|
|
|
|
#define TFT_MAD_MY 0x80
|
|
#define TFT_MAD_MX 0x40
|
|
#define TFT_MAD_MV 0x20
|
|
#define TFT_MAD_ML 0x10
|
|
|
|
writecommand(0x36);
|
|
|
|
//#if LANDSCAPE
|
|
//writedata(0x00 | TFT_MAD_MX | TFT_MAD_MY);
|
|
|
|
#if (LANDSCAPE==2)||(PORTRAIT==2)
|
|
writedata(0x00);
|
|
#else
|
|
writedata(0x00 | TFT_MAD_MX | TFT_MAD_MY);
|
|
#endif
|
|
writecommand(0x11);
|
|
delay(200);
|
|
writecommand(0x29);
|
|
writecommand(0x2C);
|
|
|
|
|
|
}
|
|
|
|
//init lcd
|
|
int TFT_GC9D01N_Class::begin()
|
|
{
|
|
|
|
pinMode(TFT_BL, OUTPUT);
|
|
pinMode(TFT_SCLK, OUTPUT);
|
|
pinMode(TFT_MISO, OUTPUT);
|
|
pinMode(TFT_MOSI, OUTPUT);
|
|
pinMode(TFT_DC, OUTPUT);
|
|
|
|
pinMode(TFT_CS, OUTPUT);
|
|
pinMode(TFT_RST, OUTPUT);
|
|
|
|
ledcSetup(1, 1000, 10);
|
|
ledcAttachPin(TFT_BL, 1);
|
|
ledcWrite(1, 220);
|
|
|
|
// digitalWrite(TFT_BL, HIGH); //开启背光
|
|
delay(100);
|
|
SPI.begin(TFT_SCLK, TFT_MISO, TFT_MOSI, TFT_CS);
|
|
|
|
lcd_init();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
void TFT_GC9D01N_Class::backlight(uint8_t state)
|
|
{
|
|
ledcWrite(1, state);// digitalWrite(TFT_BL, state);
|
|
}
|
|
|
|
/**
|
|
* @brief Select the block area to write to 选择写的块区域
|
|
* @note
|
|
* @param Xstart:
|
|
* @param Xend:
|
|
* @param Ystart:
|
|
* @param Yend:
|
|
* @retval None
|
|
*/
|
|
void TFT_GC9D01N_Class::BlockWrite(unsigned int Xstart, unsigned int Xend, unsigned int Ystart, unsigned int Yend)
|
|
{
|
|
|
|
writecommand(0x2A);
|
|
writedata(Xstart >> 8);
|
|
writedata(Xstart);
|
|
writedata(Xend >> 8);
|
|
writedata(Xend);
|
|
|
|
writecommand(0x2B);
|
|
writedata(Ystart >> 8);
|
|
writedata(Ystart);
|
|
writedata(Yend >> 8);
|
|
writedata(Yend);
|
|
|
|
writecommand(0x2c);
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief Drawing function
|
|
* @note
|
|
* @param Xstart: starting x-coordinate x坐标开始
|
|
* @param Ystart: starting y-coordinate y坐标结束
|
|
* @param w: The width of the image
|
|
* @param h: The height of the image
|
|
* @param color:
|
|
* @retval None
|
|
*/
|
|
void TFT_GC9D01N_Class::DrawImage(unsigned int Xstart, unsigned int Ystart, unsigned int w, unsigned int h, uint16_t *color)
|
|
{
|
|
unsigned int i, j;
|
|
unsigned int Xend = Xstart + w;
|
|
unsigned int Yend = Ystart + h;
|
|
|
|
BlockWrite(Xstart, Xend - 1, Ystart, Yend - 1);
|
|
uint32_t len = w * h;
|
|
|
|
|
|
#if LANDSCAPE
|
|
|
|
SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0));
|
|
CS_L;
|
|
DC_D;
|
|
for (int i = 0; i <= h; i++) {
|
|
for (int j = w - 1 ; j >= 0 ; j--) {
|
|
SPI.transfer16(*(color + ((j * (Yend - Ystart)) + (i))));
|
|
}
|
|
}
|
|
CS_H;
|
|
SPI.endTransaction();
|
|
|
|
#else
|
|
|
|
SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0));
|
|
CS_L;
|
|
DC_D;
|
|
for (int i = 0; i <= h; i++) {
|
|
for (int j = w - 1 ; j >= 0 ; j--) {
|
|
SPI.transfer16(*color);
|
|
color++;
|
|
}
|
|
}
|
|
CS_H;
|
|
SPI.endTransaction();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
void TFT_GC9D01N_Class::DispColor(unsigned int Xstart, unsigned int Ystart, unsigned int Xend, unsigned int Yend, unsigned int color)
|
|
{
|
|
|
|
|
|
unsigned int i, j;
|
|
uint32_t len = TFT_HEIGHT * TFT_WIDTH;
|
|
BlockWrite(Xstart, Xend - 1, Ystart, Yend - 1);
|
|
|
|
SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0));
|
|
CS_L;
|
|
DC_D;
|
|
for (i = 0; i <= TFT_HEIGHT; i++) {
|
|
for (j = 0; j < TFT_WIDTH; j++) {
|
|
SPI.transfer16(color);
|
|
}
|
|
}
|
|
CS_H;
|
|
SPI.endTransaction();
|
|
|
|
}
|
|
|
|
void TFT_GC9D01N_Class::WriteOneDot(unsigned int color)
|
|
{
|
|
|
|
|
|
CS_L;
|
|
DC_D;
|
|
|
|
writedata(color >> 8);
|
|
writedata(color);
|
|
|
|
CS_H;
|
|
|
|
}
|
|
|
|
unsigned char ToOrd( char ch)
|
|
{
|
|
if (ch < 32) {
|
|
ch = 95;
|
|
} else if ((ch >= 32) && (ch <= 47)) {
|
|
ch = (ch - 32) + 10 + 62;
|
|
} else if ((ch >= 48) && (ch <= 57)) {
|
|
ch = ch - 48;
|
|
} else if ((ch >= 58) && (ch <= 64)) {
|
|
ch = (ch - 58) + 10 + 62 + 16;
|
|
} else if ((ch >= 65) && (ch <= 126)) {
|
|
ch = (ch - 65) + 10;
|
|
} else if (ch > 126) {
|
|
ch = 95;
|
|
}
|
|
|
|
return ch;
|
|
}
|
|
|
|
void hz816_s90(const unsigned char *p_ucHz, unsigned char *p_ucResult) //A conversion function that rotates an 8x16 character font 90 degrees clockwise 把8x16字符字模顺时针旋转90度的转换函数
|
|
{
|
|
|
|
unsigned char a;
|
|
|
|
unsigned char b;
|
|
|
|
unsigned char c;
|
|
|
|
unsigned char uiBuffer[16];
|
|
for (a = 0; a < 16; a++)
|
|
|
|
{
|
|
uiBuffer[a] = p_ucHz[a];
|
|
}
|
|
|
|
c = 0;
|
|
|
|
for (a = 0; a < 8; a++)
|
|
|
|
{
|
|
|
|
for (b = 0; b < 8; b++)
|
|
|
|
{
|
|
|
|
p_ucResult[c] = p_ucResult[c] << 1;
|
|
|
|
p_ucResult[c] = p_ucResult[c] & 0xfe;
|
|
|
|
if (uiBuffer[15 - b] >= 0x80)
|
|
|
|
{
|
|
|
|
p_ucResult[c] = p_ucResult[c] + 1;
|
|
|
|
}
|
|
|
|
uiBuffer[15 - b] = uiBuffer[15 - b] << 1;
|
|
|
|
|
|
}
|
|
|
|
c++;
|
|
|
|
for (b = 0; b < 8; b++)
|
|
|
|
{
|
|
|
|
p_ucResult[c] = p_ucResult[c] << 1;
|
|
|
|
p_ucResult[c] = p_ucResult[c] & 0xfe;
|
|
|
|
if (uiBuffer[7 - b] >= 0x80)
|
|
|
|
{
|
|
|
|
p_ucResult[c] = p_ucResult[c] + 1;
|
|
|
|
}
|
|
|
|
uiBuffer[7 - b] = uiBuffer[7 - b] << 1;
|
|
|
|
}
|
|
|
|
c++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void hz816_s270(const unsigned char *p_ucHz, unsigned char *p_ucResult)
|
|
{
|
|
|
|
unsigned char a;
|
|
|
|
unsigned char b;
|
|
|
|
unsigned char c;
|
|
|
|
unsigned char uiBuffer[16];
|
|
|
|
|
|
for (a = 0; a < 16; a++)
|
|
|
|
{
|
|
|
|
uiBuffer[a] = p_ucHz[a];
|
|
|
|
}
|
|
|
|
c = 0;
|
|
|
|
for (a = 0; a < 8; a++)
|
|
|
|
{
|
|
|
|
for (b = 0; b < 8; b++)
|
|
|
|
{
|
|
|
|
p_ucResult[c] = p_ucResult[c] << 1;
|
|
|
|
|
|
if ((uiBuffer[b] & 0x01) >= 0x01)
|
|
|
|
{
|
|
|
|
p_ucResult[c] = p_ucResult[c] + 1;
|
|
|
|
}
|
|
|
|
uiBuffer[b] = uiBuffer[b] >> 1;
|
|
|
|
|
|
}
|
|
|
|
c++;
|
|
|
|
for (b = 0; b < 8; b++)
|
|
|
|
{
|
|
|
|
p_ucResult[c] = p_ucResult[c] << 1;
|
|
|
|
if ((uiBuffer[8 + b] & 0x01) >= 0x01)
|
|
|
|
{
|
|
|
|
p_ucResult[c] = p_ucResult[c] + 1;
|
|
|
|
}
|
|
|
|
uiBuffer[8 + b] = uiBuffer[8 + b] >> 1;
|
|
|
|
}
|
|
|
|
c++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void TFT_GC9D01N_Class::DispOneChar( char ord, unsigned int Xstart, unsigned int Ystart, unsigned int TextColor, unsigned int BackColor) // ord:0~95
|
|
{
|
|
unsigned char hou[16] = {0};
|
|
unsigned char i, j;
|
|
unsigned char *p;
|
|
unsigned char dat;
|
|
unsigned int index;
|
|
|
|
|
|
index = ord;
|
|
|
|
if (index > 95)
|
|
index = 95;
|
|
|
|
index = index * ((FONT_W / 8) * FONT_H);
|
|
|
|
p = ascii;
|
|
p = p + index ;
|
|
|
|
|
|
#if LANDSCAPE
|
|
|
|
int y = Ystart;
|
|
y = y - 23;
|
|
Ystart = abs(y);
|
|
|
|
|
|
BlockWrite(Ystart, Ystart + (FONT_H - 1), Xstart, Xstart + (FONT_W - 1));
|
|
|
|
hz816_s90(p, hou);
|
|
|
|
for (i = 0; i < (FONT_W / 8 * FONT_H); i++) {
|
|
dat = hou[i];
|
|
for (j = 0; j < 8; j++) {
|
|
if ((dat << j) & 0x80) {
|
|
WriteOneDot(TextColor);
|
|
} else {
|
|
WriteOneDot(BackColor);
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
BlockWrite(Xstart, Xstart + (FONT_W - 1), Ystart, Ystart + (FONT_H - 1));
|
|
|
|
|
|
for (i = 0; i < (FONT_W / 8 * FONT_H); i++) {
|
|
dat = *p++;
|
|
for (j = 0; j < 8; j++) {
|
|
if ((dat << j) & 0x80) {
|
|
WriteOneDot(TextColor);
|
|
} else {
|
|
WriteOneDot(BackColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void TFT_GC9D01N_Class::DispStr( char *str, unsigned int Xstart, unsigned int Ystart, unsigned int TextColor, unsigned int BackColor)
|
|
{
|
|
|
|
while (!(*str == '\0')) {
|
|
DispOneChar(ToOrd(*str++), Xstart, Ystart, TextColor, BackColor);
|
|
|
|
#if LANDSCAPE
|
|
if (Xstart > ((TFT_HEIGHT - 1) - FONT_W)) {
|
|
//Xstart = 0;
|
|
//Ystart = Ystart - FONT_H;
|
|
} else {
|
|
Xstart = Xstart + FONT_W;
|
|
}
|
|
|
|
if (Ystart > ((TFT_WIDTH - 1) - FONT_H)) {
|
|
Ystart = 23;
|
|
}
|
|
#else
|
|
|
|
|
|
if (Xstart > ((TFT_WIDTH - 1) - FONT_W)) {
|
|
Xstart = 0;
|
|
Ystart = Ystart + FONT_H;
|
|
} else {
|
|
Xstart = Xstart + FONT_W;
|
|
}
|
|
|
|
if (Ystart > ((TFT_HEIGHT - 1) - FONT_H)) {
|
|
Ystart = 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
BlockWrite(0, TFT_WIDTH - 1, 0, TFT_HEIGHT - 1);
|
|
}
|