thickline and gradientline

This commit is contained in:
nitko12 2020-07-30 09:24:30 +02:00
parent 536fe7928b
commit 42f43d4b26
2 changed files with 217 additions and 423 deletions

View File

@ -1,9 +1,8 @@
#include "Inkplate.h"
#include <stdlib.h>
#include "Adafruit_GFX.h"
#include "WiFi.h"
#include "HTTPClient.h"
#include "Inkplate.h"
Adafruit_MCP23017 mcp;
SPIClass spi2(HSPI);
SdFat sd(&spi2);
@ -330,13 +329,13 @@ uint8_t Inkplate::getDisplayMode() {
return _displayMode;
}
int Inkplate::drawBitmapFromSD(SdFile* p, int x, int y, bool invert) {
int Inkplate::drawBitmapFromSD(SdFile* p, int x, int y) {
if(sdCardOk == 0) return 0;
struct bitmapHeader bmpHeader;
readBmpHeaderSd(p, &bmpHeader);
if (bmpHeader.signature != 0x4D42 || bmpHeader.compression != 0 || !(bmpHeader.color == 1 || bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24)) return 0;
readBmpHeader(p, &bmpHeader);
if (bmpHeader.signature != 0x4D42 || bmpHeader.compression != 0 || !(bmpHeader.color == 1 || bmpHeader.color == 24)) return 0;
if ((bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24 || bmpHeader.color == 32) && getDisplayMode() != INKPLATE_3BIT) {
if ((bmpHeader.color == 24 || bmpHeader.color == 32) && getDisplayMode() != INKPLATE_3BIT) {
selectDisplayMode(INKPLATE_3BIT);
}
@ -344,71 +343,68 @@ int Inkplate::drawBitmapFromSD(SdFile* p, int x, int y, bool invert) {
selectDisplayMode(INKPLATE_1BIT);
}
if (bmpHeader.color == 1) drawMonochromeBitmapSd(p, bmpHeader, x, y, invert);
if (bmpHeader.color == 4) drawGrayscaleBitmap4Sd(p, bmpHeader, x, y, invert);
if (bmpHeader.color == 8) drawGrayscaleBitmap8Sd(p, bmpHeader, x, y, invert);
if (bmpHeader.color == 24) drawGrayscaleBitmap24Sd(p, bmpHeader, x, y, invert);
if (bmpHeader.color == 1) drawMonochromeBitmap(p, bmpHeader, x, y);
if (bmpHeader.color == 24) drawGrayscaleBitmap24(p, bmpHeader, x, y);
return 1;
}
int Inkplate::drawBitmapFromSD(char* fileName, int x, int y, bool invert) {
int Inkplate::drawBitmapFromSD(char* fileName, int x, int y) {
if(sdCardOk == 0) return 0;
SdFile dat;
if (dat.open(fileName, O_RDONLY)) {
return drawBitmapFromSD(&dat, x, y, invert);
return drawBitmapFromSD(&dat, x, y);
} else {
return 0;
}
}
int Inkplate::drawBitmapFromWeb(WiFiClient* s, int x, int y, int len, bool invert) {
struct bitmapHeader bmpHeader;
readBmpHeaderWeb(s, &bmpHeader);
if (bmpHeader.signature != 0x4D42 || bmpHeader.compression != 0 || !(bmpHeader.color == 1 || bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24)) return 0;
void Inkplate::drawThickLine(int x1, int y1, int x2, int y2, int color, float thickness)
{
float deg = atan2f((float)(y2 - y1), (float)(x2 - x1));
if ((bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24 || bmpHeader.color == 32) && getDisplayMode() != INKPLATE_3BIT) {
selectDisplayMode(INKPLATE_3BIT);
}
float l1 = tan(deg);
float k1 = (float)y1 - l1 * (float)x1;
if (bmpHeader.color == 1 && getDisplayMode() != INKPLATE_1BIT) {
selectDisplayMode(INKPLATE_1BIT);
}
if (bmpHeader.color == 1) drawMonochromeBitmapWeb(s, bmpHeader, x, y, len, invert);
if (bmpHeader.color == 4) drawGrayscaleBitmap4Web(s, bmpHeader, x, y, len, invert);
if (bmpHeader.color == 8) drawGrayscaleBitmap8Web(s, bmpHeader, x, y, len, invert);
if (bmpHeader.color == 24) drawGrayscaleBitmap24Web(s, bmpHeader, x, y, len, invert);
float degShift = (l1 < 0 ? M_PI_2 : -M_PI_2);
return 1;
int x3 = (int)round((float)x1 + thickness / 2.0 * cos(deg + degShift));
int y3 = (int)round((float)y1 + thickness / 2.0 * sin(deg + degShift));
int x4 = (int)round((float)x2 + thickness / 2.0 * cos(deg + degShift));
int y4 = (int)round((float)y2 + thickness / 2.0 * sin(deg + degShift));
x1 = (int)round((float)x1 + thickness / 2.0 * cos(deg - degShift));
y1 = (int)round((float)y1 + thickness / 2.0 * sin(deg - degShift));
x2 = (int)round((float)x2 + thickness / 2.0 * cos(deg - degShift));
y2 = (int)round((float)y2 + thickness / 2.0 * sin(deg - degShift));
fillTriangle(x1, y1, x2, y2, x3, y3, color);
fillTriangle(x2, y2, x4, y4, x3, y3, color);
}
int Inkplate::drawBitmapFromWeb(char* url, int x, int y, bool invert) {
if (WiFi.status() != WL_CONNECTED) return 0;
int ret = 0;
void Inkplate::drawGradientLine(int x1, int y1, int x2, int y2, int color1, int color2, float thickness) {
int n = color2 - color1;
bool sleep = WiFi.getSleep();
WiFi.setSleep(false);
float px = (float)(x2 - x1) / (float)n;
float py = (float)(y2 - y1) / (float)n;
HTTPClient http;
http.getStream().setNoDelay(true);
http.getStream().setTimeout(1);
http.begin(url);
int httpCode = http.GET();
if (httpCode == 200) {
int32_t len = http.getSize();
if (len > 0) {
WiFiClient * dat = http.getStreamPtr();
ret = drawBitmapFromWeb(dat, x, y, len, invert);
for (int i = 0; i < n; ++i)
{
if (abs(thickness + 1) < 0.1)
drawLine((int)((float)x1 + (float)i * px), (int)((float)y1 + (float)i * py),
(int)((float)x1 + (float)(i + 1) * px), (int)((float)y1 + (float)(i + 1) * py),
color1 + i);
else
drawThickLine((int)((float)x1 + (float)i * px), (int)((float)y1 + (float)i * py),
(int)((float)x1 + (float)(i + 1) * px), (int)((float)y1 + (float)(i + 1) * py),
color1 + i,
thickness);
}
}
http.end();
WiFi.setSleep(sleep);
return ret;
}
int Inkplate::sdCardInit() {
spi2.begin(14, 12, 13, 15);
sdCardOk = sd.begin(15, SD_SCK_MHZ(25));
@ -819,7 +815,7 @@ uint16_t Inkplate::read16(uint8_t* c) {
return (*(c) | (*(c + 1) << 8));
}
void Inkplate::readBmpHeaderSd(SdFile *_f, struct bitmapHeader *_h) {
void Inkplate::readBmpHeader(SdFile *_f, struct bitmapHeader *_h) {
uint8_t header[100];
_f->rewind();
_f->read(header, 100);
@ -834,21 +830,7 @@ void Inkplate::readBmpHeaderSd(SdFile *_f, struct bitmapHeader *_h) {
return;
}
void Inkplate::readBmpHeaderWeb(WiFiClient *_s, struct bitmapHeader *_h) {
uint8_t header[34];
_s->read(header, 34);
_h->signature = read16(header + 0);
_h->fileSize = read32(header + 2);
_h->startRAW = read32(header + 10);
_h->dibHeaderSize = read32(header + 14);
_h->width = read32(header + 18);
_h->height = read32(header + 22);
_h->color = read16(header + 28);
_h->compression = read32(header + 30);
return;
}
int Inkplate::drawMonochromeBitmapSd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert) {
int Inkplate::drawMonochromeBitmap(SdFile *f, struct bitmapHeader bmpHeader, int x, int y) {
int w = bmpHeader.width;
int h = bmpHeader.height;
uint8_t paddingBits = w % 32;
@ -859,18 +841,14 @@ int Inkplate::drawMonochromeBitmapSd(SdFile *f, struct bitmapHeader bmpHeader, i
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read();
if (invert)
pixelRow = ~pixelRow;
for (int n = 0; n < 32; n++) {
drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n))));
drawPixel((i * 32) + n + x, h - j + y, !(pixelRow & (1ULL << (31 - n))));
}
}
if (paddingBits) {
uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read();
if (invert)
pixelRow = ~pixelRow;
for (int n = 0; n < paddingBits; n++) {
drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n))));
drawPixel((i * 32) + n + x, h - j + y, !(pixelRow & (1ULL << (31 - n))));
}
}
}
@ -878,62 +856,7 @@ int Inkplate::drawMonochromeBitmapSd(SdFile *f, struct bitmapHeader bmpHeader, i
return 1;
}
int Inkplate::drawGrayscaleBitmap4Sd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert) {
int w = bmpHeader.width;
int h = bmpHeader.height;
uint8_t paddingBits = w % 8;
w /= 8;
f->seekSet(bmpHeader.startRAW);
int i, j;
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read();
if (invert)
pixelRow = ~pixelRow;
for (int n = 0; n < 8; n++) {
drawPixel((i * 8) + n + x, h - 1 - j + y, (pixelRow & (0xFULL << (28 - n*4))) >> (28 - n*4 + 1));
}
}
if (paddingBits) {
uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read();
if (invert)
pixelRow = ~pixelRow;
for (int n = 0; n < paddingBits; n++) {
drawPixel((i * 8) + n + x, h - 1 - j + y, ((pixelRow & (0xFULL << (28 - n*4)))) >> (28 - n*4 + 1));
}
}
}
f->close();
return 1;
}
int Inkplate::drawGrayscaleBitmap8Sd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert) {
int w = bmpHeader.width;
int h = bmpHeader.height;
char padding = w % 4;
f->seekSet(bmpHeader.startRAW);
int i, j;
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
uint8_t px = 0;
if (invert)
px = 255-f->read();
else
px = f->read();
drawPixel(i + x, h - 1 - j + y, px>>5);
}
if (padding) {
for (int p = 0; p < 4-padding; p++) {
f->read();
}
}
}
f->close();
return 1;
}
int Inkplate::drawGrayscaleBitmap24Sd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert) {
int Inkplate::drawGrayscaleBitmap24(SdFile *f, struct bitmapHeader bmpHeader, int x, int y) {
int w = bmpHeader.width;
int h = bmpHeader.height;
char padding = w % 4;
@ -947,14 +870,10 @@ int Inkplate::drawGrayscaleBitmap24Sd(SdFile *f, struct bitmapHeader bmpHeader,
//display.drawPixel(i + x, h - j + y, (uint8_t)(px*7));
//So then, we are convertng it to grayscale using good old average and gamma correction (from LUT). With this metod, it is still slow (full size image takes 4 seconds), but much beter than prev mentioned method.
uint8_t px = 0;
if (invert)
px = ((255-f->read()) * 2126 / 10000) + ((255-f->read()) * 7152 / 10000) + ((255-f->read()) * 722 / 10000);
else
px = (f->read() * 2126 / 10000) + (f->read() * 7152 / 10000) + (f->read() * 722 / 10000);
uint8_t px = (f->read() * 2126 / 10000) + (f->read() * 7152 / 10000) + (f->read() * 722 / 10000);
//drawPixel(i + x, h - j + y, gammaLUT[px]);
drawPixel(i + x, h - 1 - j + y, px>>5);
//drawPixel(i + x, h - j + y, px/32);
drawPixel(i + x, h - j + y, px>>5);
//drawPixel(i + x, h - j + y, px/32);
}
if (padding) {
for (int p = 0; p < padding; p++) {
@ -966,190 +885,6 @@ int Inkplate::drawGrayscaleBitmap24Sd(SdFile *f, struct bitmapHeader bmpHeader,
return 1;
}
int Inkplate::drawMonochromeBitmapWeb(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert) {
int w = bmpHeader.width;
int h = bmpHeader.height;
uint8_t paddingBits = w % 32;
int total = len - 34;
w /= 32;
uint8_t* buf = (uint8_t*) ps_malloc(total);
if (buf == NULL)
return 0;
int pnt = 0;
while (pnt < total) {
int toread = s->available();
if (toread > 0) {
int read = s->read(buf+pnt, toread);
if (read > 0)
pnt += read;
}
}
int i, j, k = bmpHeader.startRAW - 34;
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++];
if (invert)
pixelRow = ~pixelRow;
for (int n = 0; n < 32; n++) {
drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n))));
}
}
if (paddingBits) {
uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++];
if (invert)
pixelRow = ~pixelRow;
for (int n = 0; n < paddingBits; n++) {
drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n))));
}
}
}
free(buf);
return 1;
}
int Inkplate::drawGrayscaleBitmap4Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert) {
int w = bmpHeader.width;
int h = bmpHeader.height;
char paddingBits = w % 8;
int total = len - 34;
w /= 8;
uint8_t* buf = (uint8_t*) ps_malloc(total);
if (buf == NULL)
return 0;
int pnt = 0;
while (pnt < total) {
int toread = s->available();
if (toread > 0) {
int read = s->read(buf+pnt, toread);
if (read > 0)
pnt += read;
}
}
int i, j, k = bmpHeader.startRAW - 34;
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++];
if (invert)
pixelRow = ~pixelRow;
for (int n = 0; n < 8; n++) {
drawPixel((i * 8) + n + x, h - 1 - j + y, (pixelRow & (0xFULL << (28 - n*4))) >> (28 - n*4 + 1));
}
}
if (paddingBits) {
uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++];
if (invert)
pixelRow = ~pixelRow;
for (int n = 0; n < paddingBits; n++) {
drawPixel((i * 8) + n + x, h - 1 - j + y, ((pixelRow & (0xFULL << (28 - n*4)))) >> (28 - n*4 + 1));
}
}
}
free(buf);
return 1;
}
int Inkplate::drawGrayscaleBitmap8Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert) {
int w = bmpHeader.width;
int h = bmpHeader.height;
char padding = w % 4;
int total = len - 34;
uint8_t* buf = (uint8_t*) ps_malloc(total);
if (buf == NULL)
return 0;
int pnt = 0;
while (pnt < total) {
int toread = s->available();
if (toread > 0) {
int read = s->read(buf+pnt, toread);
if (read > 0)
pnt += read;
}
}
int i, j, k = bmpHeader.startRAW - 34;
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
uint8_t px = 0;
if (invert)
px = 255-buf[k++];
else
px = buf[k++];
drawPixel(i + x, h - 1 - j + y, px>>5);
}
if (padding) {
for (int p = 0; p < 4-padding; p++) {
k++;
}
}
}
free(buf);
return 1;
}
int Inkplate::drawGrayscaleBitmap24Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert) {
int w = bmpHeader.width;
int h = bmpHeader.height;
char padding = w % 4;
int total = len - 34;
uint8_t* buf = (uint8_t*) ps_malloc(total);
if (buf == NULL)
return 0;
int pnt = 0;
while (pnt < total) {
int toread = s->available();
if (toread > 0) {
int read = s->read(buf+pnt, toread);
if (read > 0)
pnt += read;
}
}
int i, j, k = bmpHeader.startRAW - 34;
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
//This is the proper way of converting True Color (24 Bit RGB) bitmap file into grayscale, but it takes waaay too much time (full size picture takes about 17s to decode!)
//float px = (0.2126 * (readByteFromSD(&file) / 255.0)) + (0.7152 * (readByteFromSD(&file) / 255.0)) + (0.0722 * (readByteFromSD(&file) / 255.0));
//px = pow(px, 1.5);
//display.drawPixel(i + x, h - j + y, (uint8_t)(px*7));
//So then, we are convertng it to grayscale using good old average and gamma correction (from LUT). With this metod, it is still slow (full size image takes 4 seconds), but much beter than prev mentioned method.
uint8_t px = 0;
if (invert)
px = ((255-buf[k++]) * 2126 / 10000) + ((255-buf[k++]) * 7152 / 10000) + ((255-buf[k++]) * 722 / 10000);
else
px = (buf[k++] * 2126 / 10000) + (buf[k++] * 7152 / 10000) + (buf[k++] * 722 / 10000);
//drawPixel(i + x, h - j + y, gammaLUT[px]);
drawPixel(i + x, h - 1 - j + y, px>>5);
//drawPixel(i + x, h - j + y, px/32);
}
if (padding) {
for (int p = 0; p < padding; p++) {
k++;
}
}
}
free(buf);
return 1;
}
void Inkplate::precalculateGamma(uint8_t* c, float gamma) {
for (int i = 0; i < 256; i++) {
c[i] = int(round((pow(i / 255.0, gamma)) * 15));

View File

@ -11,75 +11,139 @@
#endif
#include "Adafruit_GFX.h"
#include "Wire.h"
#include "SPI.h"
#include "Adafruit_MCP23017.h"
#include "SPI.h"
#include "SdFat.h"
#include "WiFiClient.h"
#include "Wire.h"
#define INKPLATE_GAMMA 1.45
#define E_INK_WIDTH 800
#define E_INK_HEIGHT 600
#define BLACK 1
#define WHITE 0
#define GPIO0_ENABLE 8
#define INKPLATE_1BIT 0
#define INKPLATE_3BIT 1
#define PAD1 0
#define PAD2 1
#define PAD3 2
#define INKPLATE_GAMMA 1.45
#define E_INK_WIDTH 800
#define E_INK_HEIGHT 600
#define BLACK 1
#define WHITE 0
#define GPIO0_ENABLE 8
#define INKPLATE_1BIT 0
#define INKPLATE_3BIT 1
#define PAD1 0
#define PAD2 1
#define PAD3 2
#define DATA 0x0E8C0030 //D0-D7 = GPIO4 GPIO5 GPIO18 GPIO19 GPIO23 GPIO25 GPIO26 GPIO27
#define DATA 0x0E8C0030 //D0-D7 = GPIO4 GPIO5 GPIO18 GPIO19 GPIO23 GPIO25 GPIO26 GPIO27
#define CL 0x01 //GPIO0
#define CL_SET {GPIO.out_w1ts = CL;}
#define CL_CLEAR {GPIO.out_w1tc = CL;}
#define CL 0x01 //GPIO0
#define CL_SET \
{ \
GPIO.out_w1ts = CL; \
}
#define CL_CLEAR \
{ \
GPIO.out_w1tc = CL; \
}
#define LE 0x04 //GPIO2
#define LE_SET {GPIO.out_w1ts = LE;}
#define LE_CLEAR {GPIO.out_w1tc = LE;}
#define LE 0x04 //GPIO2
#define LE_SET \
{ \
GPIO.out_w1ts = LE; \
}
#define LE_CLEAR \
{ \
GPIO.out_w1tc = LE; \
}
#define CKV 0x01 //GPIO32
#define CKV_SET {GPIO.out1_w1ts.val = CKV;}
#define CKV_CLEAR {GPIO.out1_w1tc.val = CKV;}
#define CKV 0x01 //GPIO32
#define CKV_SET \
{ \
GPIO.out1_w1ts.val = CKV; \
}
#define CKV_CLEAR \
{ \
GPIO.out1_w1tc.val = CKV; \
}
#define SPH 0x02 //GPIO33
#define SPH_SET {GPIO.out1_w1ts.val = SPH;}
#define SPH_CLEAR {GPIO.out1_w1tc.val = SPH;}
#define SPH 0x02 //GPIO33
#define SPH_SET \
{ \
GPIO.out1_w1ts.val = SPH; \
}
#define SPH_CLEAR \
{ \
GPIO.out1_w1tc.val = SPH; \
}
//#define SPV 15 //GPIO15
//#define SPV_SET {digitalWrite(SPV, HIGH);}
//#define SPV_CLEAR {digitalWrite(SPV, LOW);}
//I/O Expander - A Channel
#define GMOD 1 //GPIOA1
#define GMOD_SET {mcp.digitalWrite(GMOD, HIGH);}
#define GMOD_CLEAR {mcp.digitalWrite(GMOD, LOW);}
#define GMOD 1 //GPIOA1
#define GMOD_SET \
{ \
mcp.digitalWrite(GMOD, HIGH); \
}
#define GMOD_CLEAR \
{ \
mcp.digitalWrite(GMOD, LOW); \
}
#define OE 0 //GPIOA0
#define OE_SET {mcp.digitalWrite(OE, HIGH);}
#define OE_CLEAR {mcp.digitalWrite(OE, LOW);}
#define OE 0 //GPIOA0
#define OE_SET \
{ \
mcp.digitalWrite(OE, HIGH); \
}
#define OE_CLEAR \
{ \
mcp.digitalWrite(OE, LOW); \
}
#define SPV 2 //GPIOA5
#define SPV_SET {mcp.digitalWrite(SPV, HIGH);}
#define SPV_CLEAR {mcp.digitalWrite(SPV, LOW);}
#define SPV 2 //GPIOA5
#define SPV_SET \
{ \
mcp.digitalWrite(SPV, HIGH); \
}
#define SPV_CLEAR \
{ \
mcp.digitalWrite(SPV, LOW); \
}
#define WAKEUP 3 //GPIOA3
#define WAKEUP_SET {mcp.digitalWrite(WAKEUP, HIGH);}
#define WAKEUP_CLEAR {mcp.digitalWrite(WAKEUP, LOW);}
#define WAKEUP 3 //GPIOA3
#define WAKEUP_SET \
{ \
mcp.digitalWrite(WAKEUP, HIGH); \
}
#define WAKEUP_CLEAR \
{ \
mcp.digitalWrite(WAKEUP, LOW); \
}
#define PWRUP 4 //GPIOA4
#define PWRUP_SET {mcp.digitalWrite(PWRUP, HIGH);}
#define PWRUP_CLEAR {mcp.digitalWrite(PWRUP, LOW);}
#define PWRUP 4 //GPIOA4
#define PWRUP_SET \
{ \
mcp.digitalWrite(PWRUP, HIGH); \
}
#define PWRUP_CLEAR \
{ \
mcp.digitalWrite(PWRUP, LOW); \
}
#define VCOM 5 //GPIOA6
#define VCOM_SET {mcp.digitalWrite(VCOM, HIGH);}
#define VCOM_CLEAR {mcp.digitalWrite(VCOM, LOW);}
#define VCOM 5 //GPIOA6
#define VCOM_SET \
{ \
mcp.digitalWrite(VCOM, HIGH); \
}
#define VCOM_CLEAR \
{ \
mcp.digitalWrite(VCOM, LOW); \
}
#define CKV_CLOCK ckvClock();
#ifndef _swap_int16_t
#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; }
#define _swap_int16_t(a, b) \
{ \
int16_t t = a; \
a = b; \
b = t; \
}
#endif
extern Adafruit_MCP23017 mcp;
@ -88,27 +152,29 @@ extern SdFat sd;
static void ckvClock();
static void usleep1();
class Inkplate : public Adafruit_GFX {
public:
uint8_t* D_memory_new;
uint8_t* _partial;
uint8_t* D_memory4Bit;
uint8_t * _pBuffer;
const uint8_t LUT2[16] = {B10101010, B10101001, B10100110, B10100101, B10011010, B10011001, B10010110, B10010101, B01101010, B01101001, B01100110, B01100101, B01011010, B01011001, B01010110, B01010101};
const uint8_t LUTW[16] = {B11111111, B11111110, B11111011, B11111010, B11101111, B11101110, B11101011, B11101010, B10111111, B10111110, B10111011, B10111010, B10101111, B10101110, B10101011, B10101010};
const uint8_t LUTB[16] = {B11111111, B11111101, B11110111, B11110101, B11011111, B11011101, B11010111, B11010101, B01111111, B01111101, B01110111, B01110101, B01011111, B01011101, B01010111, B01010101};
const uint8_t pixelMaskLUT[8] = {B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000};
const uint8_t pixelMaskGLUT[2] = {B00001111, B11110000};
const uint8_t discharge[16] = {B11111111, B11111100, B11110011, B11110000, B11001111, B11001100, B11000011, B11000000, B00111111, B00111100, B00110011, B00110000, B00001111, B00001100, B00000011, B00000000};
//BLACK->WHITE
class Inkplate : public Adafruit_GFX
{
public:
uint8_t *D_memory_new;
uint8_t *_partial;
uint8_t *D_memory4Bit;
uint8_t *_pBuffer;
const uint8_t LUT2[16] = {B10101010, B10101001, B10100110, B10100101, B10011010, B10011001, B10010110, B10010101, B01101010, B01101001, B01100110, B01100101, B01011010, B01011001, B01010110, B01010101};
const uint8_t LUTW[16] = {B11111111, B11111110, B11111011, B11111010, B11101111, B11101110, B11101011, B11101010, B10111111, B10111110, B10111011, B10111010, B10101111, B10101110, B10101011, B10101010};
const uint8_t LUTB[16] = {B11111111, B11111101, B11110111, B11110101, B11011111, B11011101, B11010111, B11010101, B01111111, B01111101, B01110111, B01110101, B01011111, B01011101, B01010111, B01010101};
const uint8_t pixelMaskLUT[8] = {B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000};
const uint8_t pixelMaskGLUT[2] = {B00001111, B11110000};
const uint8_t discharge[16] = {B11111111, B11111100, B11110011, B11110000, B11001111, B11001100, B11000011, B11000000, B00111111, B00111100, B00110011, B00110000, B00001111, B00001100, B00000011, B00000000};
//BLACK->WHITE
//THIS IS OKAYISH WAVEFORM FOR GRAYSCALE. IT CAN BE MUCH BETTER.
const uint8_t waveform3Bit[8][7] = {{0, 0, 0, 0, 1, 1, 1}, {0, 0, 1, 1, 1, 2, 1}, {0, 1, 1, 2, 1, 2, 1}, {0, 0, 1, 1, 2, 1, 2}, {1, 1, 1, 2, 2, 1, 2}, {0, 0, 1, 1, 1, 2, 2}, {0, 1, 1, 2, 1, 2, 2}, {0, 0, 0, 0, 0, 0, 2}};
const uint8_t waveform3Bit[8][7] = {{0, 0, 0, 0, 1, 1, 1}, {0, 0, 1, 1, 1, 2, 1}, {0, 1, 1, 2, 1, 2, 1}, {0, 0, 1, 1, 2, 1, 2}, {1, 1, 1, 2, 2, 1, 2}, {0, 0, 1, 1, 1, 2, 2}, {0, 1, 1, 2, 1, 2, 2}, {0, 0, 0, 0, 0, 0, 2}};
//const uint8_t waveform3Bit[8][12] = {{3,3,3,1,1,1,1,1,1,1,2,0}, {3,3,3,3,1,1,1,1,1,1,2,0}, {3,3,3,3,3,1,1,1,1,1,2,0}, {3,3,3,3,3,3,1,1,1,1,2,0}, {3,3,3,3,3,3,3,1,1,1,2,0}, {3,3,3,3,3,3,3,2,1,1,2,0}, {3,3,3,3,3,3,3,3,3,1,2,0}, {3,3,3,3,3,3,3,3,3,3,2,0}};
//const uint8_t waveform3Bit[16][12] = {{0,0,0,0,0,0,1,2,1,1,0,3},{0,0,1,1,1,2,2,2,1,1,0,3},{0,0,0,1,1,2,2,2,1,1,0,3}, {0,0,0,1,2,1,2,1,2,1,3}, {0,0,2,1,2,1,2,1,2,1,3}, {0,0,1,2,2,1,1,1,1,2,0,3}, {0,0,0,2,1,1,1,1,0,2,0,3}, {0,0,2,1,2,2,1,1,1,2,0,3}, {0,0,0,2,2,2,1,1,1,2,0,3}, {0,0,0,0,0,0,2,1,1,2,0,3}, {0,0,0,0,0,2,2,1,1,2,0,3}, {0,0,0,0,0,1,1,1,2,2,0,3}, {0,0,0,0,1,2,1,2,1,2,0,3}, {0,0,0,0,1,1,2,2,1,2,0,3},{0,0,0,0,1,1,1,2,2,2,0,3}, {0,0,0,0,0,0,0,0,0,2,0,3}};
//PVI waveform for cleaning screen, not sure if it is correct, but it cleans screen properly.
const uint32_t waveform[50] = {0x00000008, 0x00000008, 0x00200408, 0x80281888, 0x60a81898, 0x60a8a8a8, 0x60a8a8a8, 0x6068a868, 0x6868a868, 0x6868a868, 0x68686868, 0x6a686868, 0x5a686868, 0x5a686868, 0x5a586a68, 0x5a5a6a68, 0x5a5a6a68, 0x55566a68, 0x55565a64, 0x55555654, 0x55555556, 0x55555556, 0x55555556, 0x55555516, 0x55555596, 0x15555595, 0x95955595, 0x95959595, 0x95949495, 0x94949495, 0x94949495, 0xa4949494, 0x9494a4a4, 0x84a49494, 0x84948484, 0x84848484, 0x84848484, 0x84848484, 0xa5a48484, 0xa9a4a4a8, 0xa9a8a8a8, 0xa5a9a9a4, 0xa5a5a5a4, 0xa1a5a5a1, 0xa9a9a9a9, 0xa9a9a9a9, 0xa9a9a9a9, 0xa9a9a9a9, 0x15151515, 0x11111111};
struct bitmapHeader {
const uint32_t waveform[50] = {0x00000008, 0x00000008, 0x00200408, 0x80281888, 0x60a81898, 0x60a8a8a8, 0x60a8a8a8, 0x6068a868, 0x6868a868, 0x6868a868, 0x68686868, 0x6a686868, 0x5a686868, 0x5a686868, 0x5a586a68, 0x5a5a6a68, 0x5a5a6a68, 0x55566a68, 0x55565a64, 0x55555654, 0x55555556, 0x55555556, 0x55555556, 0x55555516, 0x55555596, 0x15555595, 0x95955595, 0x95959595, 0x95949495, 0x94949495, 0x94949495, 0xa4949494, 0x9494a4a4, 0x84a49494, 0x84948484, 0x84848484, 0x84848484, 0x84848484, 0xa5a48484, 0xa9a4a4a8, 0xa9a8a8a8, 0xa5a9a9a4, 0xa5a5a5a4, 0xa1a5a5a1, 0xa9a9a9a9, 0xa9a9a9a9, 0xa9a9a9a9, 0xa9a9a9a9, 0x15151515, 0x11111111};
struct bitmapHeader
{
uint16_t signature;
uint32_t fileSize;
uint32_t startRAW;
@ -118,65 +184,58 @@ class Inkplate : public Adafruit_GFX {
uint16_t color;
uint32_t compression;
};
Inkplate(uint8_t _mode);
Inkplate(uint8_t _mode);
void begin(void);
void drawPixel(int16_t x0, int16_t y0, uint16_t color);
void clearDisplay();
void display();
void partialUpdate();
void drawBitmap3Bit(int16_t _x, int16_t _y, const unsigned char* _p, int16_t _w, int16_t _h);
void drawPixel(int16_t x0, int16_t y0, uint16_t color);
void clearDisplay();
void display();
void partialUpdate();
void drawBitmap3Bit(int16_t _x, int16_t _y, const unsigned char *_p, int16_t _w, int16_t _h);
void setRotation(uint8_t);
void einkOff(void);
void einkOn(void);
void selectDisplayMode(uint8_t _mode);
void einkOff(void);
void einkOn(void);
void selectDisplayMode(uint8_t _mode);
uint8_t getDisplayMode();
int drawBitmapFromSD(SdFile* p, int x, int y, bool invert = false);
int drawBitmapFromSD(char* fileName, int x, int y, bool invert = false);
int drawBitmapFromWeb(WiFiClient* s, int x, int y, int len, bool invert = false);
int drawBitmapFromWeb(char* url, int x, int y, bool invert = false);
int drawBitmapFromSD(SdFile *p, int x, int y);
int drawBitmapFromSD(char *fileName, int x, int y);
void drawThickLine(int x1, int y1, int x2, int y2, int color, float thickness);
void drawGradientLine(int x1, int y1, int x2, int y2, int color1, int color2, float thickness = -1);
int sdCardInit();
SdFat getSdFat();
SPIClass getSPI();
uint8_t getPanelState();
uint8_t readTouchpad(uint8_t);
int8_t readTemperature();
double readBattery();
uint8_t readTouchpad(uint8_t);
int8_t readTemperature();
double readBattery();
void vscan_start();
void vscan_write();
void hscan_start(uint32_t _d = 0);
void vscan_end();
void clean();
void cleanFast(uint8_t c, uint8_t rep);
void cleanFast2(uint8_t c, uint8_t n, uint16_t d);
void pinsZstate();
void pinsAsOutputs();
void cleanFast(uint8_t c, uint8_t rep);
void cleanFast2(uint8_t c, uint8_t n, uint16_t d);
void pinsZstate();
void pinsAsOutputs();
private:
private:
uint8_t gammaLUT[256];
int8_t _temperature;
uint8_t _panelOn = 0;
uint8_t _rotation = 0;
uint8_t _displayMode = 0; //By default, 1 bit mode is used
int8_t _temperature;
uint8_t _panelOn = 0;
uint8_t _rotation = 0;
uint8_t _displayMode = 0; //By default, 1 bit mode is used
int sdCardOk = 0;
uint8_t _blockPartial = 1;
uint8_t _beginDone = 0;
void display1b();
void display3b();
uint32_t read32(uint8_t* c);
uint16_t read16(uint8_t* c);
void readBmpHeaderSd(SdFile *_f, struct bitmapHeader *_h);
void readBmpHeaderWeb(WiFiClient *_s, struct bitmapHeader *_h);
int drawMonochromeBitmapSd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert);
int drawGrayscaleBitmap4Sd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert);
int drawGrayscaleBitmap8Sd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert);
int drawGrayscaleBitmap24Sd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert);
int drawMonochromeBitmapWeb(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert);
int drawGrayscaleBitmap4Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert);
int drawGrayscaleBitmap8Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert);
int drawGrayscaleBitmap24Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert);
void precalculateGamma(uint8_t* c, float gamma);
void display3b();
uint32_t read32(uint8_t *c);
uint16_t read16(uint8_t *c);
void readBmpHeader(SdFile *_f, struct bitmapHeader *_h);
int drawMonochromeBitmap(SdFile *f, struct bitmapHeader bmpHeader, int x, int y);
int drawGrayscaleBitmap24(SdFile *f, struct bitmapHeader bmpHeader, int x, int y);
void precalculateGamma(uint8_t *c, float gamma);
};
#endif