obniz
Version:
obniz sdk for javascript
2,184 lines (2,116 loc) • 33.5 kB
JavaScript
//SainSmart ST7735 1.8" TFT LCD 128x160 pixel
class SainSmartTFT18LCD {
constructor() {
this.keys = ['vcc', 'gnd', 'scl', 'sda', 'dc', 'res', 'cs'];
this.required = ['scl', 'sda', 'dc', 'res', 'cs'];
this.displayIoNames = {
vcc: 'vcc',
gnd: 'gnd',
scl: 'scl',
sda: 'sda',
dc: 'dc',
res: 'res',
cs: 'cs',
};
}
static info() {
return {
name: 'SainSmartTFT18LCD',
};
}
wired(obniz) {
this.debugprint = false;
this.obniz = obniz;
this.io_dc = obniz.getIO(this.params.dc);
this.io_res = obniz.getIO(this.params.res);
this.io_cs = obniz.getIO(this.params.cs);
this.obniz.setVccGnd(this.params.vcc, this.params.gnd, '5v');
this.params.frequency = 16 * 1000 * 1000; //16MHz
this.params.mode = 'master';
this.params.clk = this.params.scl;
this.params.mosi = this.params.sda;
this.params.drive = '3v';
this.spi = this.obniz.getSpiWithConfig(this.params);
this.io_dc.output(true);
this.io_cs.output(false);
this.width = ST7735_TFTWIDTH;
this.height = ST7735_TFTHEIGHT;
this.writeBuffer = []; //1024bytes bufferring
this._setPresetColor();
this.init();
}
print_debug(v) {
if (this.debugprint) {
console.log(
'SainSmartTFT18LCD: ' + Array.prototype.slice.call(arguments).join('')
);
}
}
_deadSleep(waitMsec) {
let startMsec = new Date();
while (new Date() - startMsec < waitMsec);
}
_reset() {
this.io_res.output(false);
this._deadSleep(10);
this.io_res.output(true);
this._deadSleep(10);
}
writeCommand(cmd) {
this.io_dc.output(false);
this.io_cs.output(false);
this.spi.write([cmd]);
this.io_cs.output(true);
}
writeData(data) {
this.io_dc.output(true);
this.io_cs.output(false);
this.spi.write(data);
this.io_cs.output(true);
}
write(cmd, data) {
if (data.length == 0) return;
this.writeCommand(cmd);
this.writeData(data);
}
async asyncwait() {
return await this.spi.writeWait([0x00]);
}
_writeFlush() {
while (this.writeBuffer.length > 0) {
if (this.writeBuffer.length > 1024) {
let data = this.writeBuffer.slice(0, 1024);
this.writeData(data);
this.writeBuffer.splice(0, 1024);
} else {
if (this.writeBuffer.length > 0) this.writeData(this.writeBuffer);
this.writeBuffer = [];
}
}
}
_writeBuffer(data) {
if (data && data.length > 0) {
this.writeBuffer = this.writeBuffer.concat(data);
} else {
this._writeFlush();
}
}
color16(r, g, b) {
// 1st byte (r & 0xF8 | g >> 5)
// 2nd byte (g & 0xFC << 3 | b >> 3)
return ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
}
_initG() {
// initialize for Green Tab
this.writeCommand(ST7735_SLPOUT); //Sleep out & booster on
this.obniz.wait(120);
this.write(ST7735_FRMCTR1, [0x01, 0x2c, 0x2d]);
this.write(ST7735_FRMCTR2, [0x01, 0x2c, 0x2d]);
this.write(ST7735_FRMCTR3, [0x01, 0x2c, 0x2d, 0x01, 0x2c, 0x2d]);
this.write(ST7735_INVCTR, [0x07]);
this.write(ST7735_PWCTR1, [0xa2, 0x02, 0x84]);
this.write(ST7735_PWCTR2, [0xc5]);
this.write(ST7735_PWCTR3, [0x0a, 0x00]);
this.write(ST7735_PWCTR4, [0x8a, 0x2a]);
this.write(ST7735_PWCTR5, [0x8a, 0xee]);
this.write(ST7735_VMCTR1, [0x0e]);
this.write(ST7735_GMCTRP1, [
0x02,
0x1c,
0x07,
0x12,
0x37,
0x32,
0x29,
0x2d,
0x29,
0x25,
0x2b,
0x39,
0x00,
0x01,
0x03,
0x10,
]);
this.write(ST7735_GMCTRN1, [
0x03,
0x1d,
0x07,
0x06,
0x2e,
0x2c,
0x29,
0x2d,
0x2e,
0x2e,
0x37,
0x3f,
0x00,
0x00,
0x02,
0x10,
]);
this.write(ST7735_COLMOD, [ST7735_16bit]); // color format: 16bit/pixel
}
init() {
this._reset();
this._initG();
this.setDisplayOn();
this.setRotation(0);
}
setDisplayOn() {
this.writeCommand(ST7735_DISPON);
}
setDisplayOff() {
this.writeCommand(ST7735_DISPOFF);
}
setDisplay(on) {
if (on == true) this.setDisplayOn();
else this.setDisplayOff();
}
setInversionOn() {
this.writeCommand(ST7735_INVON);
}
setInversionOff() {
this.writeCommand(ST7735_INVOFF);
}
setInversion(inversion) {
if (inversion == true) this.setInversionOn();
else this.setInversionOff();
}
setRotation(m) {
const MADCTL_MY = 0x80;
const MADCTL_MX = 0x40;
const MADCTL_MV = 0x20;
// const MADCTL_ML = 0x10;
const MADCTL_RGB = 0x00; //always RGB, never BGR
// const MADCTL_MH = 0x04;
let data;
let rotation = m % 4; // can't be higher than 3
switch (rotation) {
case 0:
data = [MADCTL_MX | MADCTL_MY | MADCTL_RGB];
this.width = ST7735_TFTWIDTH;
this.height = ST7735_TFTHEIGHT;
break;
case 1:
data = [MADCTL_MY | MADCTL_MV | MADCTL_RGB];
this.width = ST7735_TFTHEIGHT;
this.height = ST7735_TFTWIDTH;
break;
case 2:
data = [MADCTL_RGB];
this.width = ST7735_TFTWIDTH;
this.height = ST7735_TFTHEIGHT;
break;
case 3:
data = [MADCTL_MX | MADCTL_MV | MADCTL_RGB];
this.width = ST7735_TFTHEIGHT;
this.height = ST7735_TFTWIDTH;
break;
}
this.write(ST7735_MADCTL, data);
this.setAddrWindow(0, 0, this.width - 1, this.height - 1);
}
setAddrWindow(x0, y0, x1, y1) {
this.print_debug(
`setAddrWindow: (x0: ${x0}, y0: ${y0}) - (x1: ${x1}, y1: ${y1})`
);
if (x0 < 0) x0 = 0;
if (y0 < 0) y0 = 0;
if (x1 < 0) x1 = 0;
if (y1 < 0) y1 = 0;
// column addr set
this.write(ST7735_CASET, [0x00, x0, 0x00, x1]); // XSTART-XEND
// row addr set
this.write(ST7735_RASET, [0x00, y0, 0x00, y1]); // YSTART-YEND
// write to RAM
this.writeCommand(ST7735_RAMWR);
this.writeBuffer = [];
}
//__swap(a, b) { let t = a; a = b; b = t; }
fillScreen(color) {
this.fillRect(0, 0, this.width, this.height, color);
}
fillRect(x, y, w, h, color) {
if (x >= this.width || y >= this.height) return;
if (x + w - 1 >= this.width) w = this.width - x;
if (y + h - 1 >= this.height) h = this.height - y;
this.setAddrWindow(x, y, x + w - 1, y + h - 1);
let hi = color >> 8,
lo = color & 0xff;
let data = [];
for (y = h; y > 0; y--) {
for (x = w; x > 0; x--) {
data.push(hi);
data.push(lo);
}
}
this._writeBuffer(data);
this._writeBuffer(); //for flush
}
drawRect(x, y, w, h, color) {
this.drawHLine(x, y, w, color);
this.drawHLine(x, y + h - 1, w, color);
this.drawVLine(x, y, h, color);
this.drawVLine(x + w - 1, y, h, color);
}
drawCircle(x0, y0, r, color) {
let f = 1 - r;
let ddF_x = 1;
let ddF_y = -2 * r;
let x = 0;
let y = r;
this.drawPixel(x0, y0 + r, color);
this.drawPixel(x0, y0 - r, color);
this.drawPixel(x0 + r, y0, color);
this.drawPixel(x0 - r, y0, color);
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
this.drawPixel(x0 + x, y0 + y, color);
this.drawPixel(x0 - x, y0 + y, color);
this.drawPixel(x0 + x, y0 - y, color);
this.drawPixel(x0 - x, y0 - y, color);
this.drawPixel(x0 + y, y0 + x, color);
this.drawPixel(x0 - y, y0 + x, color);
this.drawPixel(x0 + y, y0 - x, color);
this.drawPixel(x0 - y, y0 - x, color);
}
}
_drawCircleHelper(x0, y0, r, cornername, color) {
let f = 1 - r;
let ddF_x = 1;
let ddF_y = -2 * r;
let x = 0;
let y = r;
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
if (cornername & 0x4) {
this.drawPixel(x0 + x, y0 + y, color);
this.drawPixel(x0 + y, y0 + x, color);
}
if (cornername & 0x2) {
this.drawPixel(x0 + x, y0 - y, color);
this.drawPixel(x0 + y, y0 - x, color);
}
if (cornername & 0x8) {
this.drawPixel(x0 - y, y0 + x, color);
this.drawPixel(x0 - x, y0 + y, color);
}
if (cornername & 0x1) {
this.drawPixel(x0 - y, y0 - x, color);
this.drawPixel(x0 - x, y0 - y, color);
}
}
}
fillCircle(x0, y0, r, color) {
this.drawVLine(x0, y0 - r, 2 * r + 1, color);
this._fillCircleHelper(x0, y0, r, 3, 0, color);
}
_fillCircleHelper(x0, y0, r, cornername, delta, color) {
let f = 1 - r;
let ddF_x = 1;
let ddF_y = -2 * r;
let x = 0;
let y = r;
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
if (cornername & 0x1) {
this.drawVLine(x0 + x, y0 - y, 2 * y + 1 + delta, color);
this.drawVLine(x0 + y, y0 - x, 2 * x + 1 + delta, color);
}
if (cornername & 0x2) {
this.drawVLine(x0 - x, y0 - y, 2 * y + 1 + delta, color);
this.drawVLine(x0 - y, y0 - x, 2 * x + 1 + delta, color);
}
}
}
drawRoundRect(x, y, w, h, r, color) {
this.drawHLine(x + r, y, w - 2 * r, color); // Top
this.drawHLine(x + r, y + h - 1, w - 2 * r, color); // Bottom
this.drawVLine(x, y + r, h - 2 * r, color); // Left
this.drawVLine(x + w - 1, y + r, h - 2 * r, color); // Right
this._drawCircleHelper(x + r, y + r, r, 1, color);
this._drawCircleHelper(x + w - r - 1, y + r, r, 2, color);
this._drawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4, color);
this._drawCircleHelper(x + r, y + h - r - 1, r, 8, color);
}
fillRoundRect(x, y, w, h, r, color) {
this.fillRect(x + r, y, w - 2 * r, h, color);
this._fillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, color);
this._fillCircleHelper(x + r, y + r, r, 2, h - 2 * r - 1, color);
}
drawTriangle(x0, y0, x1, y1, x2, y2, color) {
this.drawLine(x0, y0, x1, y1, color);
this.drawLine(x1, y1, x2, y2, color);
this.drawLine(x2, y2, x0, y0, color);
}
fillTriangle(x0, y0, x1, y1, x2, y2, color) {
let a, b, y, last;
// Sort coordinates by Y order (y2 >= y1 >= y0)
if (y0 > y1) {
y1 = [y0, (y0 = y1)][0]; //this._swap(y0, y1);
x1 = [x0, (x0 = x1)][0]; //this._swap(x0, x1);
}
if (y1 > y2) {
y2 = [y1, (y1 = y2)][0]; //this._swap(y2, y1);
x2 = [x1, (x1 = x2)][0]; //this._swap(x2, x1);
}
if (y0 > y1) {
y1 = [y0, (y0 = y1)][0]; //this._swap(y0, y1);
x1 = [x0, (x0 = x1)][0]; //this._swap(x0, x1);
}
if (y0 == y2) {
// Handle awkward all-on-same-line case as its own thing
a = b = x0;
if (x1 < a) a = x1;
else if (x1 > b) b = x1;
if (x2 < a) a = x2;
else if (x2 > b) b = x2;
this.drawHLine(a, y0, b - a + 1, color);
return;
}
let dx01 = x1 - x0,
dy01 = y1 - y0,
dx02 = x2 - x0,
dy02 = y2 - y0,
dx12 = x2 - x1,
dy12 = y2 - y1,
sa = 0,
sb = 0;
if (y1 == y2) last = y1;
// include y1 scanline
else last = y1 - 1; // skip it
for (y = y0; y <= last; y++) {
a = x0 + Math.floor(sa / dy01);
b = x0 + Math.floor(sb / dy02);
sa += dx01;
sb += dx02;
if (a > b) b = [a, (a = b)][0]; //this._swap(a,b);
this.drawHLine(a, y, b - a + 1, color);
}
sa = dx12 * (y - y1);
sb = dx02 * (y - y0);
for (; y <= y2; y++) {
a = x1 + Math.floor(sa / dy12);
b = x0 + Math.floor(sb / dy02);
sa += dx12;
sb += dx02;
if (a > b) b = [a, (a = b)][0]; //this._swap(a,b);
this.drawHLine(a, y, b - a + 1, color);
}
}
drawVLine(x, y, h, color) {
if (x >= this.width || y >= this.height) return;
if (y + h - 1 >= this.height) h = this.height - y;
this.setAddrWindow(x, y, x, y + h - 1);
let hi = color >> 8,
lo = color & 0xff;
let data = [];
while (h--) {
data.push(hi);
data.push(lo);
}
this.writeData(data);
}
drawHLine(x, y, w, color) {
if (x >= this.width || y >= this.height) return;
if (x + w - 1 >= this.width) w = this.width - x;
this.setAddrWindow(x, y, x + w - 1, y);
let hi = color >> 8,
lo = color & 0xff;
let data = [];
while (w--) {
data.push(hi);
data.push(lo);
}
this.writeData(data);
}
drawLine(x0, y0, x1, y1, color) {
let step = Math.abs(y1 - y0) > Math.abs(x1 - x0);
if (step) {
y0 = [x0, (x0 = y0)][0]; //this._swap(x0, y0);
y1 = [x1, (x1 = y1)][0]; //this._swap(x1, y1);
}
if (x0 > x1) {
x1 = [x0, (x0 = x1)][0]; //this._swap(x0, x1);
y1 = [y0, (y0 = y1)][0]; //this._swap(y0, y1);
}
let dx = x1 - x0;
let dy = Math.abs(y1 - y0);
let err = dx / 2;
let ystep = y0 < y1 ? 1 : -1;
for (; x0 <= x1; x0++) {
if (step) {
this.drawPixel(y0, x0, color);
} else {
this.drawPixel(x0, y0, color);
}
err -= dy;
if (err < 0) {
y0 += ystep;
err += dx;
}
}
}
drawPixel(x, y, color) {
if (x < 0 || x >= this.width || y < 0 || y >= this.height) return;
this.setAddrWindow(x, y, x + 1, y + 1);
this.writeData([color >> 8, color & 0xff]);
}
drawChar(x, y, ch, color, bg, size) {
// bg = bg || color;
size = size || 1;
if (
x >= this.width || // Clip right
y >= this.height || // Clip bottom
x + 6 * size - 1 < 0 || // Clip left
y + 8 * size - 1 < 0
)
// Clip top
return;
if (color != bg) {
this.drawChar2(x, y, ch, color, bg, size);
return;
}
let c = ch.charCodeAt(0);
for (let i = 0; i < 6; i++) {
let line = i == 5 ? 0 : font[c * 5 + i];
for (let j = 0; j < 8; j++) {
if (line & 0x1) {
if (size == 1)
// default size
this.drawPixel(x + i, y + j, color);
else {
// big size
this.fillRect(x + i * size, y + j * size, size, size, color);
}
} else if (bg != color) {
if (size == 1)
// default size
this.drawPixel(x + i, y + j, bg);
else {
// big size
this.fillRect(x + i * size, y + j * size, size, size, bg);
}
}
line >>= 1;
}
}
}
drawChar2(x, y, ch, color, bg, size) {
// bg = bg || color;
size = size || 1;
if (
x >= this.width || // Clip right
y >= this.height || // Clip bottom
x + 6 * size - 1 < 0 || // Clip left
y + 8 * size - 1 < 0 // Clip top
)
return;
let pixels = new Array(6 * 8 * size * size);
let c = ch.charCodeAt(0);
for (let i = 0; i < 6; i++) {
let line = i == 5 ? 0 : font[c * 5 + i];
for (let j = 0; j < 8; j++) {
let cl = line & 0x1 ? color : bg;
for (let w = 0; w < size; w++) {
for (let h = 0; h < size; h++) {
pixels[
i * (1 * size) + w + (j * (6 * size * size) + h * (6 * size))
] = cl;
}
}
line >>= 1;
}
}
this.rawBound16(x, y, 6 * size, 8 * size, pixels);
}
rawBound16(x, y, width, height, pixels) {
let rgb = [];
pixels.forEach(function(v) {
rgb.push((v & 0xff00) >> 8);
rgb.push(v & 0xff);
});
this.setAddrWindow(x, y, x + width - 1, y + height - 1);
this._writeBuffer(rgb);
this._writeBuffer(); //for flush
}
drawString(x, y, str, color, bg, size, wrap) {
// bg = bg || color;
size = size || 1;
// wrap = wrap || true;
for (let n = 0; n < str.length; n++) {
let c = str.charAt(n);
if (c == '\n') {
y += size * 8;
x = 0;
} else if (c == '\r') {
// skip em
} else {
this.drawChar(x, y, c, color, bg, size);
x += size * 6;
if (wrap && x > this.width - size * 6) {
y += size * 8;
x = 0;
}
}
}
return [x, y];
}
drawContextBound(context, x0, y0, width, height, x1, y1, gray) {
x0 = x0 || 0;
y0 = y0 || 0;
width = width || context.canvas.clientWidth;
height = height || context.canvas.clientHeight;
x1 = x1 || 0;
y1 = y1 || 0;
gray = gray || false;
this.write(ST7735_COLMOD, [ST7735_18bit]); //18bit/pixel
let imageData = context.getImageData(x0, y0, width, height).data;
let rgb = [];
for (let n = 0; n < imageData.length; n += 4) {
let r = imageData[n + 0];
let g = imageData[n + 1];
let b = imageData[n + 2];
if (!gray) {
rgb.push(r);
rgb.push(g);
rgb.push(b);
} else {
let gs = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
rgb.push(gs);
rgb.push(gs);
rgb.push(gs);
}
}
this.write(ST7735_COLMOD, [ST7735_18bit]); //18bit/pixel
this.setAddrWindow(x1, y1, x1 + width - 1, y1 + height - 1);
this._writeBuffer(rgb);
this._writeBuffer(); //for flush
this.write(ST7735_COLMOD, [ST7735_16bit]); //16bit/pixel
}
drawContext(context, gray) {
gray = gray || false;
this.drawContextBound(context, 0, 0, this.width, this.height, 0, 0, gray);
}
rawBound(x, y, width, height, pixels) {
let rgb = [];
pixels.forEach(function(v) {
rgb.push((v & 0xff0000) >> 16);
rgb.push((v & 0xff00) >> 8);
rgb.push(v & 0xff);
});
this.write(ST7735_COLMOD, [ST7735_18bit]); //18bit/pixel
this.setAddrWindow(x, y, x + width - 1, y + height - 1);
this._writeBuffer(rgb);
this._writeBuffer(); //for flush
this.write(ST7735_COLMOD, [ST7735_16bit]); //16bit/pixel
}
raw(pixels) {
this.raw(0, 0, this.width, this.height, pixels);
}
_setPresetColor() {
this.color = {
AliceBlue: 0xf7df,
AntiqueWhite: 0xff5a,
Aqua: 0x07ff,
Aquamarine: 0x7ffa,
Azure: 0xf7ff,
Beige: 0xf7bb,
Bisque: 0xff38,
Black: 0x0000,
BlanchedAlmond: 0xff59,
Blue: 0x001f,
BlueViolet: 0x895c,
Brown: 0xa145,
BurlyWood: 0xddd0,
CadetBlue: 0x5cf4,
Chartreuse: 0x7fe0,
Chocolate: 0xd343,
Coral: 0xfbea,
CornflowerBlue: 0x64bd,
Cornsilk: 0xffdb,
Crimson: 0xd8a7,
Cyan: 0x07ff,
DarkBlue: 0x0011,
DarkCyan: 0x0451,
DarkGoldenRod: 0xbc21,
DarkGray: 0xad55,
DarkGreen: 0x0320,
DarkKhaki: 0xbdad,
DarkMagenta: 0x8811,
DarkOliveGreen: 0x5345,
DarkOrange: 0xfc60,
DarkOrchid: 0x9999,
DarkRed: 0x8800,
DarkSalmon: 0xecaf,
DarkSeaGreen: 0x8df1,
DarkSlateBlue: 0x49f1,
DarkSlateGray: 0x2a69,
DarkTurquoise: 0x067a,
DarkViolet: 0x901a,
DeepPink: 0xf8b2,
DeepSkyBlue: 0x05ff,
DimGray: 0x6b4d,
DodgerBlue: 0x1c9f,
FireBrick: 0xb104,
FloralWhite: 0xffde,
ForestGreen: 0x2444,
Fuchsia: 0xf81f,
Gainsboro: 0xdefb,
GhostWhite: 0xffdf,
Gold: 0xfea0,
GoldenRod: 0xdd24,
Gray: 0x8410,
Green: 0x0400,
GreenYellow: 0xafe5,
HoneyDew: 0xf7fe,
HotPink: 0xfb56,
IndianRed: 0xcaeb,
Indigo: 0x4810,
Ivory: 0xfffe,
Khaki: 0xf731,
Lavender: 0xe73f,
LavenderBlush: 0xff9e,
LawnGreen: 0x7fe0,
LemonChiffon: 0xffd9,
LightBlue: 0xaedc,
LightCoral: 0xf410,
LightCyan: 0xe7ff,
LightGoldenRodYellow: 0xffda,
LightGray: 0xd69a,
LightGreen: 0x9772,
LightPink: 0xfdb8,
LightSalmon: 0xfd0f,
LightSeaGreen: 0x2595,
LightSkyBlue: 0x867f,
LightSlateGray: 0x7453,
LightSteelBlue: 0xb63b,
LightYellow: 0xfffc,
Lime: 0x07e0,
LimeGreen: 0x3666,
Linen: 0xff9c,
Magenta: 0xf81f,
Maroon: 0x8000,
MediumAquaMarine: 0x6675,
MediumBlue: 0x0019,
MediumOrchid: 0xbaba,
MediumPurple: 0x939b,
MediumSeaGreen: 0x3d8e,
MediumSlateBlue: 0x7b5d,
MediumSpringGreen: 0x07d3,
MediumTurquoise: 0x4e99,
MediumVioletRed: 0xc0b0,
MidnightBlue: 0x18ce,
MintCream: 0xf7ff,
MistyRose: 0xff3c,
Moccasin: 0xff36,
NavajoWhite: 0xfef5,
Navy: 0x0010,
OldLace: 0xffbc,
Olive: 0x8400,
OliveDrab: 0x6c64,
Orange: 0xfd20,
OrangeRed: 0xfa20,
Orchid: 0xdb9a,
PaleGoldenRod: 0xef55,
PaleGreen: 0x9fd3,
PaleTurquoise: 0xaf7d,
PaleVioletRed: 0xdb92,
PapayaWhip: 0xff7a,
PeachPuff: 0xfed7,
Peru: 0xcc27,
Pink: 0xfe19,
Plum: 0xdd1b,
PowderBlue: 0xb71c,
Purple: 0x8010,
RebeccaPurple: 0x6193,
Red: 0xf800,
RosyBrown: 0xbc71,
RoyalBlue: 0x435c,
SaddleBrown: 0x8a22,
Salmon: 0xfc0e,
SandyBrown: 0xf52c,
SeaGreen: 0x2c4a,
SeaShell: 0xffbd,
Sienna: 0xa285,
Silver: 0xc618,
SkyBlue: 0x867d,
SlateBlue: 0x6ad9,
SlateGray: 0x7412,
Snow: 0xffdf,
SpringGreen: 0x07ef,
SteelBlue: 0x4416,
Tan: 0xd5b1,
Teal: 0x0410,
Thistle: 0xddfb,
Tomato: 0xfb08,
Turquoise: 0x471a,
Violet: 0xec1d,
Wheat: 0xf6f6,
White: 0xffff,
WhiteSmoke: 0xf7be,
Yellow: 0xffe0,
YellowGreen: 0x9e66,
};
}
}
if (typeof module === 'object') {
module.exports = SainSmartTFT18LCD;
}
//----------------------------------------------------------
// commands
// const INITR_GREENTAB = 0x0;
// const INITR_REDTAB = 0x1;
// const INITR_BLACKTAB = 0x2;
const ST7735_TFTWIDTH = 128;
const ST7735_TFTHEIGHT = 160;
// const ST7735_NOP = 0x00;
// const ST7735_SWRESET = 0x01;
// const ST7735_RDDID = 0x04;
// const ST7735_RDDST = 0x09;
// const ST7735_RDDPM = 0x0a;
// const ST7735_SLPIN = 0x10;
const ST7735_SLPOUT = 0x11;
// const ST7735_PTLON = 0x12;
// const ST7735_NORON = 0x13;
const ST7735_INVOFF = 0x20;
const ST7735_INVON = 0x21;
const ST7735_DISPOFF = 0x28;
const ST7735_DISPON = 0x29;
const ST7735_CASET = 0x2a;
const ST7735_RASET = 0x2b;
const ST7735_RAMWR = 0x2c;
// const ST7735_RAMRD = 0x2e;
// const ST7735_PTLAR = 0x30;
const ST7735_COLMOD = 0x3a;
const ST7735_MADCTL = 0x36;
const ST7735_FRMCTR1 = 0xb1;
const ST7735_FRMCTR2 = 0xb2;
const ST7735_FRMCTR3 = 0xb3;
const ST7735_INVCTR = 0xb4;
// const ST7735_DISSET5 = 0xb6;
const ST7735_PWCTR1 = 0xc0;
const ST7735_PWCTR2 = 0xc1;
const ST7735_PWCTR3 = 0xc2;
const ST7735_PWCTR4 = 0xc3;
const ST7735_PWCTR5 = 0xc4;
const ST7735_VMCTR1 = 0xc5;
// const ST7735_RDID1 = 0xda;
// const ST7735_RDID2 = 0xdb;
// const ST7735_RDID3 = 0xdc;
// const ST7735_RDID4 = 0xdd;
// const ST7735_PWCTR6 = 0xfc;
const ST7735_GMCTRP1 = 0xe0;
const ST7735_GMCTRN1 = 0xe1;
// Color definitions
// const ST7735_BLACK = 0x0000;
// const ST7735_BLUE = 0x001f;
// const ST7735_RED = 0xf800;
// const ST7735_GREEN = 0x07e0;
// const ST7735_CYAN = 0x07ff;
// const ST7735_MAGENTA = 0xf81f;
// const ST7735_YELLOW = 0xffe0;
// const ST7735_WHITE = 0xffff;
const ST7735_18bit = 0x06; // 18bit/pixel
const ST7735_16bit = 0x05; // 16bit/pixel
// standard ascii 5x7 font
const font = [
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,
0x21,
0x54,
0x54,
0x78,
0x41,
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,
0xf0,
0x29,
0x24,
0x29,
0xf0,
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,
0x32,
0x48,
0x48,
0x48,
0x32,
0x32,
0x4a,
0x48,
0x48,
0x30,
0x3a,
0x41,
0x41,
0x21,
0x7a,
0x3a,
0x42,
0x40,
0x20,
0x78,
0x00,
0x9d,
0xa0,
0xa0,
0x7d,
0x39,
0x44,
0x44,
0x44,
0x39,
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,
0xaa,
0x00,
0x55,
0x00,
0xaa,
0xaa,
0x55,
0xaa,
0x55,
0xaa,
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,
0x7c,
0x2a,
0x2a,
0x3e,
0x14,
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,
];