Added red color support

This commit is contained in:
Laurence Bank
2024-09-15 14:45:21 +01:00
parent 8f8fe2f26d
commit 584fa773ba
5 changed files with 166 additions and 243 deletions
+67 -2
View File
@@ -108,7 +108,7 @@ const uint8_t epd29_init_sequence_full[] PROGMEM = {
0x00 // end of table
};
const uint8_t epd42r_init_sequence[] PROGMEM = {
const uint8_t epd42r_init_sequence_full[] PROGMEM = {
0x01, 0x12, // soft reset
BUSY_WAIT,
0x02, 0x74, 0x54, // set analog block control
@@ -948,6 +948,7 @@ const EPD_PANEL panelDefs[] PROGMEM = {
{0}, // undefined panel
{400, 300, epd42_init_sequence_full, NULL, epd42_init_sequence_part, 0, BBEI_CHIP_UC81xx}, // EPD42_400x300
{400, 300, epd42b_init_sequence_full, epd42b_init_sequence_fast, epd42b_init_sequence_part, 0, BBEI_CHIP_SSD16xx}, // EPD42B_400x300
{122, 250, epd213_122x250_init_sequence_full, NULL, epd213_122x250_init_sequence_part, 0, BBEI_CHIP_SSD16xx}, // EPD213_122x250 WaveShare
{122, 250, epd213b_init_sequence_full, NULL, epd213b_init_sequence_part, 0, BBEI_CHIP_SSD16xx}, // EPD213B_122x250
{128, 296, epd293_init_sequence_full, epd293_init_sequence_fast, epd293_init_sequence_part, 0, BBEI_CHIP_SSD16xx}, // EPD293_128x296
{128, 296, epd294_init_sequence_full, NULL, NULL, 0, BBEI_CHIP_SSD16xx}, // EPD294_128x296
@@ -958,6 +959,9 @@ const EPD_PANEL panelDefs[] PROGMEM = {
{128, 296, epd29r_init_sequence_full, NULL, NULL, BBEI_3COLOR, BBEI_CHIP_SSD16xx}, // EPD29R_128x296
{192, 176, epd122_init_sequence_full, epd122_init_sequence_fast, epd122_init_sequence_part, 0, BBEI_CHIP_SSD16xx}, // EPD122_192x176
{152, 152, epd154r_init_sequence_full, NULL, NULL, BBEI_3COLOR, BBEI_CHIP_SSD16xx}, // EPD154R_152x152
{400, 300, epd42r_init_sequence_full, NULL, NULL, BBEI_3COLOR, BBEI_CHIP_SSD16xx}, // EPD42R_400x300
{400, 300, epd42r2_init_sequence_full, NULL, NULL, BBEI_3COLOR, BBEI_CHIP_UC81xx}, // EPD42R2_400x300
{240, 416, epd37_init_sequence_full, NULL, epd37_init_sequence_part, 0, BBEI_CHIP_UC81xx}, // EPD37_240x416
};
int bbeiSetPanelType(BBEIDISP *pBBEI, int iPanel)
{
@@ -1059,12 +1063,73 @@ uint8_t *s;
} // while more commands to send
} /* bbeiSendCMDSequence() */
//
// Fill the display with a color or byte pattern
// e.g. all black (0x00) or all white (0xff)
// if there is no backing buffer, write directly to
// the EPD's framebuffer
//
void bbeiFill(BBEIDISP *pBBEI, unsigned char ucData, int iPlane)
{
uint8_t uc1, uc2;
int y, iSize, iPitch;
uint8_t ucCMD1, ucCMD2;
if (pBBEI == NULL) return;
pBBEI->iCursorX = pBBEI->iCursorY = 0;
iPitch = ((pBBEI->native_width+7)/8);
iSize = pBBEI->native_height * iPitch;
if (pBBEI->ucScreen) { // there's a local framebuffer, use it
if (ucData == BBEI_WHITE) ucData = 0xff;
else if (ucData == BBEI_BLACK) ucData = 0;
memset(pBBEI->ucScreen, ucData, iSize);
} else { // write directly to the EPD's framebuffer
if (pBBEI->iFlags & BBEI_3COLOR) {
if (ucData == BBEI_WHITE) {
uc1 = 0xff; uc2 = 0x00; // red plane has priority
} else if (ucData == BBEI_BLACK) {
uc1 = 0x00; uc2 = 0x00;
} else if (ucData == BBEI_RED) {
uc1 = 0x00; uc2 = 0xff;
}
} else { // for B/W, both planes get the same data
if (ucData == BBEI_WHITE) ucData = 0xff;
else if (ucData == BBEI_BLACK) ucData = 0;
uc1 = uc2 = ucData;
}
if (pBBEI->chip_type == BBEI_CHIP_UC81xx) {
ucCMD1 = UC8151_DTM2;
ucCMD2 = UC8151_DTM1;
} else {
ucCMD1 = SSD1608_WRITE_RAM;
ucCMD2 = SSD1608_WRITE_ALTRAM;
}
// Write one or both memory planes to the EPD
if (iPlane == PLANE_0 || iPlane == PLANE_DUPLICATE) { // write to first plane
bbeiSetPosition(pBBEI, 0,0, pBBEI->native_width, pBBEI->native_height);
bbeiWriteCmd(pBBEI, ucCMD1);
for (y=0; y<pBBEI->native_height; y++) {
memset(u8Cache, uc1, iPitch); // the data is overwritten after each write
bbeiWriteData(pBBEI, u8Cache, iPitch);
} // for y
}
if (iPlane == PLANE_1 || iPlane == PLANE_DUPLICATE) { // write to first plane
bbeiSetPosition(pBBEI, 0,0, pBBEI->native_width, pBBEI->native_height);
bbeiWriteCmd(pBBEI, ucCMD2);
for (y=0; y<pBBEI->native_height; y++) {
memset(u8Cache, uc2, iPitch); // the data is overwritten after each write
bbeiWriteData(pBBEI, u8Cache, iPitch);
} // for y
}
}
} /* bbeiFill() */
int bbeiRefresh(BBEIDISP *pBBEI, int iMode)
{
if (iMode != REFRESH_FULL && iMode != REFRESH_FAST && iMode != REFRESH_PARTIAL)
return BBEI_ERROR_BAD_PARAMETER;
bbeiWakeUp(pBBEI); // tickle the reset line
switch (iMode) {
case REFRESH_FULL:
bbeiSendCMDSequence(pBBEI, pBBEI->pInitFull);
+37 -183
View File
@@ -574,9 +574,9 @@ void bbeiWriteStringCustom(BBEIDISP *pBBEI, BB_FONT *pFont, int x, int y, char *
{
int rc, i, h, w, end_y, dx, dy, ty, iSrcPitch, iPitch;
unsigned int c;
uint8_t *s;
uint8_t *s, bInvert = 0;
BB_GLYPH *pGlyph;
uint8_t *pBits, u8CMD, u8EndMask;
uint8_t *pBits, u8CMD1, u8CMD2, u8CMD, u8EndMask;
if (x == -1)
x = pBBEI->iCursorX;
@@ -636,9 +636,16 @@ uint8_t *pBits, u8CMD, u8EndMask;
iPitch = (w+7)/8;
// start writing into the correct plane
if (pBBEI->chip_type == BBEI_CHIP_UC81xx) {
u8CMD = /*(iPlane) ? UC8151_DTM1 : */UC8151_DTM2;
u8CMD1 = UC8151_DTM2;
u8CMD2 = UC8151_DTM1;
} else {
u8CMD = /*(iPlane) ? SSD1608_WRITE_ALTRAM :*/ SSD1608_WRITE_RAM;
u8CMD1 = SSD1608_WRITE_RAM;
u8CMD2 = SSD1608_WRITE_ALTRAM;
}
u8CMD = u8CMD1;
if (iColor == BBEI_BLACK) bInvert = 1;
else if (iColor == BBEI_RED && (pBBEI->iFlags & BBEI_3COLOR)) {
u8CMD = u8CMD2; // second plane is red (inverted)
}
bbeiWriteCmd(pBBEI, u8CMD); // memory write command
for (ty=dy; ty<end_y && ty < pBBEI->native_height; ty++) {
@@ -657,7 +664,7 @@ uint8_t *pBits, u8CMD, u8EndMask;
*s++ = uc0; // store final byte
*s++ = 0; // and a zero for good measure
}
if (iColor == BBEI_BLACK) InvertBytes(u8Cache, iPitch);
if (bInvert) InvertBytes(u8Cache, iPitch);
bbeiWriteData(pBBEI, u8Cache, iPitch); // write each row into the EPD framebuffer
} // for y
} // if not drawing a space
@@ -669,14 +676,15 @@ uint8_t *pBits, u8CMD, u8EndMask;
} // while drawing characters
pBBEI->iCursorX = x;
pBBEI->iCursorY = y;
} /* EPDWriteStringDirect() *///
} /* EPDWriteStringCustom() */
//
// Draw a string of normal (8x8), small (6x8) or large (16x32) characters
// At the given col+row
//
int bbeiWriteString(BBEIDISP *pBBEI, int x, int y, char *szMsg, int iSize, int iColor)
{
int i, iFontOff, iLen;
uint8_t c, *s, ucCMD1, ucCMD2;
uint8_t c, *s, ucCMD, ucCMD1, ucCMD2;
int iOldFG; // old fg color to make sure red works
uint8_t u8Temp[128];
@@ -688,10 +696,9 @@ uint8_t u8Temp[128];
ucCMD1 = SSD1608_WRITE_RAM;
ucCMD2 = SSD1608_WRITE_ALTRAM;
}
// If we're in bufferless mode, we'll need to invert the requested color
if (!pBBEI->ucScreen) {
iColor = 1 - iColor; // invert the color
ucCMD = ucCMD1;
if ((pBBEI->iFlags & BBEI_3COLOR) && iColor == BBEI_RED || pBBEI->iPlane == 1) {
ucCMD = ucCMD2; // write to second plane for red
}
if (x == -1 || y == -1) // use the cursor position
{
@@ -720,14 +727,14 @@ uint8_t u8Temp[128];
// we can't directly use the pointer to FLASH memory, so copy to a local buffer
u8Temp[0] = 0; // first column is blank
memcpy_P(&u8Temp[1], &ucFont[iFontOff], 7); // only needed on AVR
if (iColor == BBEI_WHITE) InvertBytes(u8Temp, 8);
if (iColor == BBEI_BLACK) InvertBytes(u8Temp, 8);
iLen = 8;
if (pBBEI->iCursorX + iLen > pBBEI->width) { // clip right edge
iLen = pBBEI->width - pBBEI->iCursorX;
}
if (!pBBEI->ucScreen) { // bufferless mode, rotate the coordinate system to fit the situation
bbeiSetPosition(pBBEI, pBBEI->native_width-8-pBBEI->iCursorY, pBBEI->iCursorX, 8, pBBEI->native_height-pBBEI->iCursorX);
bbeiWriteCmd(pBBEI, ucCMD1); // write to "new" plane
bbeiWriteCmd(pBBEI, ucCMD); // write to "new" plane
bbeiWriteData(pBBEI, u8Temp, iLen);
} else { // draw in memory
// DEBUG
@@ -751,7 +758,7 @@ uint8_t u8Temp[128];
s = (unsigned char *)&ucSmallFont[(int)c*5];
u8Temp[0] = 0; // first column is blank
memcpy_P(&u8Temp[1], s, 6);
if (iColor == BBEI_WHITE)
if (iColor == BBEI_BLACK)
InvertBytes(u8Temp, 6);
// Stretch the font to double width + double height
memset(&u8Temp[6], 0, 24); // write 24 new bytes
@@ -789,7 +796,7 @@ uint8_t u8Temp[128];
{
if (ty < 3) // top half
{
if (iColor == BBEI_WHITE) {
if (iColor == BBEI_BLACK) {
pDest[1] &= ~(1 << ((ty * 2)+1));
pDest[2] &= ~(1 << ((ty * 2)+1));
pDest[1] &= ~(1 << ((ty+1) * 2));
@@ -803,7 +810,7 @@ uint8_t u8Temp[128];
}
else if (ty == 3) // on the border
{
if (iColor == BBEI_WHITE) {
if (iColor == BBEI_BLACK) {
pDest[1] &= ~0x80; pDest[2] &= ~0x80;
pDest[13] &= ~1; pDest[14] &= ~1;
} else {
@@ -813,7 +820,7 @@ uint8_t u8Temp[128];
}
else // bottom half
{
if (iColor == BBEI_WHITE) {
if (iColor == BBEI_BLACK) {
pDest[13] &= ~(1 << (2*(ty-4)+1));
pDest[14] &= ~(1 << (2*(ty-4)+1));
pDest[13] &= ~(1 << ((ty-3) * 2));
@@ -830,7 +837,7 @@ uint8_t u8Temp[128];
{
if (ty < 4) // top half
{
if (iColor == BBEI_WHITE) {
if (iColor == BBEI_BLACK) {
pDest[1] &= ~(1 << ((ty * 2)+1));
pDest[2] &= ~(1 << ((ty+1) * 2));
} else {
@@ -840,7 +847,7 @@ uint8_t u8Temp[128];
}
else
{
if (iColor == BBEI_WHITE) {
if (iColor == BBEI_BLACK) {
pDest[13] &= ~(1 << (2*(ty-4)+1));
pDest[14] &= ~(1 << ((ty-3) * 2));
} else {
@@ -857,10 +864,10 @@ uint8_t u8Temp[128];
iLen = pBBEI->width - pBBEI->iCursorX;
if (!pBBEI->ucScreen) { // bufferless mode
bbeiSetPosition(pBBEI, pBBEI->native_width-8-pBBEI->iCursorY, pBBEI->iCursorX, 8, iLen);
bbeiWriteCmd(pBBEI, ucCMD1); // write to "new" plane
bbeiWriteCmd(pBBEI, ucCMD); // write to "new" plane
bbeiWriteData(pBBEI, &u8Temp[6], iLen);
bbeiSetPosition(pBBEI, pBBEI->native_width-16-pBBEI->iCursorY, pBBEI->iCursorX, 8, iLen);
bbeiWriteCmd(pBBEI, ucCMD1); // write to "new" plane
bbeiWriteCmd(pBBEI, ucCMD); // write to "new" plane
bbeiWriteData(pBBEI, &u8Temp[18], iLen);
} else { // write to RAM
// DEBUG
@@ -885,13 +892,13 @@ uint8_t u8Temp[128];
// we can't directly use the pointer to FLASH memory, so copy to a local buffer
u8Temp[0] = 0; // first column is blank
memcpy_P(&u8Temp[1], &ucSmallFont[(int)c*5], 5);
if (iColor == BBEI_WHITE) InvertBytes(u8Temp, 6);
if (iColor == BBEI_BLACK) InvertBytes(u8Temp, 6);
iLen = 6;
if (pBBEI->iCursorX + iLen > pBBEI->width) // clip right edge
iLen = pBBEI->width - pBBEI->iCursorX;
if (!pBBEI->ucScreen) { // bufferless mode
bbeiSetPosition(pBBEI, pBBEI->iCursorX, pBBEI->iCursorY, 8, iLen);
bbeiWriteCmd(pBBEI, ucCMD1); // write to "new" plane
bbeiWriteCmd(pBBEI, ucCMD); // write to "new" plane
bbeiWriteData(pBBEI, u8Temp, iLen);
} else { // write to RAM
// DEBUG
@@ -910,186 +917,33 @@ uint8_t u8Temp[128];
pBBEI->iFG = iOldFG; // restore color
return BBEI_ERROR_BAD_PARAMETER; // invalid size
} /* bbeiWriteString() */
#ifdef FUTURE
//
// Get the width of text in a custom font
//
void bbeiGetStringBox(BB_FONT *pFont, char *szMsg, int *width, int *top, int *bottom)
void bbeiGetStringBox(BB_FONT *pFont, const char *szMsg, int *width, int *top, int *bottom)
{
int cx = 0;
unsigned int c, i = 0;
GFXglyph *pGlyph;
BB_GLYPH *pBBG;
int miny, maxy;
if (width == NULL || top == NULL || bottom == NULL || pFont == NULL || szMsg == NULL) return; // bad pointers
miny = 100; maxy = 0;
miny = 1000; maxy = 0;
while (szMsg[i]) {
c = szMsg[i++];
if (c < pFont->first || c > pFont->last) // undefined character
continue; // skip it
c -= pFont->first; // first char of font defined
pGlyph = &pFont->glyph[c];
cx += pGlyph->xAdvance;
if (pGlyph->yOffset < miny) miny = pGlyph->yOffset;
if (pGlyph->height+pGlyph->yOffset > maxy) maxy = pGlyph->height+pGlyph->yOffset;
pBBG = &pFont->glyphs[c];
cx += pBBG->xAdvance;
if (pBBG->yOffset < miny) miny = pBBG->yOffset;
if (pBBG->height+pBBG->yOffset > maxy) maxy = pBBG->height+pBBG->yOffset;
}
*width = cx;
*top = miny;
*bottom = maxy;
} /* bbeiGetStringBox() */
//
// Draw a string of characters in a custom font
// A back buffer must be defined
//
int bbeiWriteStringCustom(BBEIDISP *pBBEI, GFXfont *pFont, int x, int y, char *szMsg, uint8_t ucColor)
{
int i, end_y, dx, dy, tx, ty, iBitOff;
unsigned int c;
uint8_t *s, *d, bits, ucFill=0, ucMask, uc;
GFXfont font;
GFXglyph glyph, *pGlyph;
int iPitch, iRedOffset = 0;
if (pBBEI == NULL || pFont == NULL)
return BBEI_ERROR_BAD_PARAMETER;
if (pBBEI->ucScreen == NULL && pBBEI->type >= EPD42_400x300) {
// EPD direct draw mode; colors are inverted
if (ucColor == BBEI_BLACK)
ucColor = 1-ucColor;
ucFill = 0xff;
}
if (x == -1)
x = pBBEI->iCursorX;
if (y == -1)
y = pBBEI->iCursorY;
if (ucColor >= BBEI_YELLOW && pBBEI->iFlags & (BBEI_3COLOR | BBEI_4COLOR)) {
// use the second half of the image buffer
iRedOffset = pBBEI->width * ((pBBEI->height+7)/8);
ucFill = 0x00;
ucColor = BBEI_BLACK;
}
iPitch = pBBEI->width;
// in case of running on Harvard architecture, get copy of data from FLASH
memcpy_P(&font, pFont, sizeof(font));
pGlyph = &glyph;
i = 0;
while (szMsg[i] && x < pBBEI->width)
{
c = szMsg[i++];
if (c < font.first || c > font.last) // undefined character
continue; // skip it
c -= font.first; // first char of font defined
memcpy_P(&glyph, &font.glyph[c], sizeof(glyph));
dx = x + pGlyph->xOffset; // offset from character UL to start drawing
dy = y + pGlyph->yOffset;
s = font.bitmap + pGlyph->bitmapOffset; // start of bitmap data
// Bitmap drawing loop. Image is MSB first and each pixel is packed next
// to the next (continuing on to the next character line)
iBitOff = 0; // bitmap offset (in bits)
bits = uc = 0; // bits left in this font byte
end_y = dy + pGlyph->height;
if (dy < 0) { // skip these lines
iBitOff += (pGlyph->width * (-dy));
dy = 0;
}
if (!pBBEI->ucScreen) {
memset(u8Cache, ucFill, sizeof(u8Cache));
}
for (ty=dy; ty<end_y && ty < pBBEI->height; ty++) {
ucMask = 1<<(ty & 7); // destination bit number for this line
if (pBBEI->ucScreen) {
d = &pBBEI->ucScreen[iRedOffset + (ty >> 3) * iPitch + dx]; // internal buffer dest
} else {
d = u8Cache; // no ram; buffer 8 lines at a time
}
for (tx=0; tx<pGlyph->width; tx++) {
if (bits == 0) { // need to read more font data
uc = pgm_read_byte(&s[iBitOff>>3]); // get more font bitmap data
bits = 8 - (iBitOff & 7); // we might not be on a byte boundary
iBitOff += bits; // because of a clipped line
uc <<= (8-bits);
} // if we ran out of bits
if ((dx+tx) < pBBEI->width) { // foreground pixel
if (uc & 0x80) {
if (ucColor == BBEI_BLACK)
d[tx] |= ucMask;
else
d[tx] &= ~ucMask;
} else {
if (ucColor == BBEI_BLACK)
d[tx] &= ~ucMask;
else
d[tx] |= ucMask;
}
}
bits--; // next bit
uc <<= 1;
} // for x
if (!pBBEI->ucScreen && (ucMask == 0x80 || ty == end_y-1)) { // dump this line
bbeiSetPosition(pBBEI, dx, (ty & 0xfff8), pGlyph->width*8, 1);
bbeiWriteData(pBBEI, u8Cache, pGlyph->width);
memset(u8Cache, ucFill, sizeof(u8Cache)); // NB: assume no DMA
}
} // for y
x += pGlyph->xAdvance; // width of this character
} // while drawing characters
pBBEI->iCursorX = x;
pBBEI->iCursorY = y;
return BBEI_SUCCESS;
} /* bbeiWriteStringCustom() */
#endif // FUTURE
//
// Fill the display with a color or byte pattern
// e.g. all black (0x00) or all white (0xff)
// if there is no backing buffer, write directly to
// the EPD's framebuffer
//
void bbeiFill(BBEIDISP *pBBEI, unsigned char ucData, int iPlane)
{
uint8_t uc;
int y, iSize, iPitch;
uint8_t ucCMD1, ucCMD2;
if (pBBEI == NULL) return;
pBBEI->iCursorX = pBBEI->iCursorY = 0;
iPitch = ((pBBEI->native_width+7)/8);
iSize = pBBEI->native_height * iPitch;
uc = ucData;
if (ucData == BBEI_WHITE) uc = 0xff;
else if (ucData == BBEI_BLACK) uc = 0;
if (pBBEI->ucScreen) { // there's a local framebuffer, use it
memset(pBBEI->ucScreen, uc, iSize);
} else { // write directly to the EPD's framebuffer
if (pBBEI->chip_type == BBEI_CHIP_UC81xx) {
ucCMD1 = UC8151_DTM1;
ucCMD2 = UC8151_DTM2;
} else {
ucCMD1 = SSD1608_WRITE_RAM;
ucCMD2 = SSD1608_WRITE_ALTRAM;
}
// Write one or both memory planes to the EPD
if (iPlane == PLANE_0 || iPlane == PLANE_DUPLICATE) { // write to first plane
bbeiSetPosition(pBBEI, 0,0, pBBEI->native_width, pBBEI->native_height);
bbeiWriteCmd(pBBEI, ucCMD1);
for (y=0; y<pBBEI->native_height; y++) {
memset(u8Cache, uc, iPitch); // the data is overwritten after each write
bbeiWriteData(pBBEI, u8Cache, iPitch);
} // for y
}
if (iPlane == PLANE_1 || iPlane == PLANE_DUPLICATE) { // write to first plane
bbeiSetPosition(pBBEI, 0,0, pBBEI->native_width, pBBEI->native_height);
bbeiWriteCmd(pBBEI, ucCMD2);
for (y=0; y<pBBEI->native_height; y++) {
memset(u8Cache, uc, iPitch); // the data is overwritten after each write
bbeiWriteData(pBBEI, u8Cache, iPitch);
} // for y
}
}
} /* bbeiFill() */
void bbeiAllocBuffer(BBEIDISP *pBBEI)
{
pBBEI->ucScreen = (uint8_t *)malloc(pBBEI->width * ((pBBEI->height+7)>>3));
+11 -1
View File
@@ -76,6 +76,11 @@ void bbeiWaitBusy(BBEIDISP *pBBEI)
//
void bbeiCMD2(BBEIDISP *pBBEI, uint8_t cmd1, uint8_t cmd2)
{
if (!pBBEI->is_awake) {
// if it's asleep, it can't receive commands
bbeiWakeUp(pBBEI);
pBBEI->is_awake = 1;
}
digitalWrite(pBBEI->iDCPin, LOW);
#ifndef ARDUINO_ARCH_ESP32
digitalWrite(pBBEI->iCSPin, LOW);
@@ -93,6 +98,11 @@ void bbeiCMD2(BBEIDISP *pBBEI, uint8_t cmd1, uint8_t cmd2)
//
void bbeiWriteCmd(BBEIDISP *pBBEI, uint8_t cmd)
{
if (!pBBEI->is_awake) {
// if it's asleep, it can't receive commands
bbeiWakeUp(pBBEI);
pBBEI->is_awake = 1;
}
digitalWrite(pBBEI->iDCPin, LOW);
#ifndef ARDUINO_ARCH_ESP32
digitalWrite(pBBEI->iCSPin, LOW);
@@ -117,8 +127,8 @@ void bbeiSleep(BBEIDISP *pBBEI, int bDeep)
}
} else {
bbeiCMD2(pBBEI, SSD1608_DEEP_SLEEP, (bDeep) ? 0x02 : 0x01); // deep sleep mode 1 keeps RAM, mode 2 loses RAM
return;
}
pBBEI->is_awake = 0;
} /* bbeiSleep() */
//
// Write 1 or more bytes as DATA (D/C set high)
+35 -44
View File
@@ -314,78 +314,52 @@ char ucTemp[4];
//
#ifndef __AVR__
size_t BBEINK::write(uint8_t c) {
#ifdef FUTURE
char szTemp[2]; // used to draw 1 character at a time to the C methods
int w, h;
szTemp[0] = c; szTemp[1] = 0;
if (_bbei.pFreeFont == NULL) { // use built-in fonts
if (_bbei.iFont == -1) { // scaled 5x7 font
h = (int)(_bbei.u32FontScaleY >> 8) * 8;
w = (int)(_bbei.u32FontScaleX >> 8) * 6;
} else if (_bbei.iFont == FONT_8x8 || _bbei.iFont == FONT_6x8) {
if (_bbei.pFont == NULL) { // use built-in fonts
if (_bbei.iFont == FONT_8x8 || _bbei.iFont == FONT_6x8) {
h = 8;
w = (_bbei.iFont == FONT_8x8) ? 8 : 6;
} else if (_bbei.iFont == FONT_12x16 || _bbei.iFont == FONT_16x16) {
} else if (_bbei.iFont == FONT_12x16) {
h = 16;
w = (_bbei.iFont == FONT_12x16) ? 12 : 16;
} else { w = 16; h = 32; }
w = 12;
}
if (c == '\n') { // Newline?
_bbei.iCursorX = 0; // Reset x to zero,
_bbei.iCursorY += h; // advance y one line
// should we scroll the screen up 1 line?
if (_bbei.iCursorY >= _bbei.height && _bbei.ucScreen && _bbei.bScroll) {
obdScroll1Line(&_bbei, h/8);
if (_bbei.render) {
obdDumpBuffer(&_bbei, NULL, false, false, false);
}
_bbei.iCursorY -= h;
}
} else if (c != '\r') { // Ignore carriage returns
if (_bbei.wrap && ((_bbei.iCursorX + w) > _bbei.width)) { // Off right?
_bbei.iCursorX = 0; // Reset x to zero,
_bbei.iCursorY += h; // advance y one line
// should we scroll the screen up 1 line?
if (_bbei.iCursorY >= _bbei.height && _bbei.ucScreen && _bbei.bScroll) {
obdScroll1Line(&_bbei, h/8);
if (_bbei.render) {
obdDumpBuffer(&_bbei, NULL, false, false, false);
}
_bbei.iCursorY -= h;
}
}
if (_bbei.iFont == -1) { // scaled drawing
obdScaledString(&_bbei, _bbei.iCursorX, _bbei.iCursorY, szTemp, FONT_6x8, _bbei.iFG, _bbei.u32FontScaleX, _bbei.u32FontScaleY, 0);
_bbei.iCursorX += w;
} else {
obdWriteString(&_bbei, 0, -1, -1, szTemp, _bbei.iFont, _bbei.iFG, _bbei.render);
if (_bbei.wrap && ((_bbei.iCursorX + w) > _bbei.width)) { // Off right?
_bbei.iCursorX = 0; // Reset x to zero,
_bbei.iCursorY += h; // advance y one line
}
bbeiWriteString(&_bbei, -1, -1, szTemp, _bbei.iFont, _bbei.iFG);
}
} else { // Custom font
BB_FONT *pBBF = (BB_FONT *)_bbei.pFont;
if (c == '\n') {
_bbei.iCursorX = 0;
_bbei.iCursorY += (uint8_t)pgm_read_byte(&_bbei.pFreeFont->yAdvance);
_bbei.iCursorY += pBBF->height;
} else if (c != '\r') {
uint8_t first = pgm_read_word((const uint8_t*)&_bbei.pFreeFont->first);
if ((c >= first) && (c <= (uint8_t)pgm_read_word((const uint8_t*)&_bbei.pFreeFont->last))) {
GFXglyph *glyph = pgm_read_glyph_ptr(_bbei.pFreeFont, c - first);
w = pgm_read_byte(&glyph->width);
h = pgm_read_byte(&glyph->height);
if (c >= pBBF->first && c <= pBBF->last) {
BB_GLYPH *pBBG = &pBBF->glyphs[c-pBBF->first];
w = pBBG->width;
h = pBBG->height;
if ((w > 0) && (h > 0)) { // Is there an associated bitmap?
int16_t xo = (int8_t)pgm_read_word((const uint8_t*)&glyph->xOffset);
int16_t xo = pBBG->xOffset;
w += xo; // xadvance
h = (uint8_t)pgm_read_byte(&_bbei.pFreeFont->yAdvance);
h = pBBF->height;
if (_bbei.wrap && ((_bbei.iCursorX + w) > _bbei.width)) {
_bbei.iCursorX = 0;
_bbei.iCursorY += h;
}
bbeiWriteStringCustom(&_bbei, _bbei.pFreeFont, -1, -1, szTemp, _bbei.iFG);
bbeiWriteStringCustom(&_bbei, (BB_FONT *)_bbei.pFont, -1, -1, szTemp, _bbei.iFG, _bbei.iPlane);
}
}
}
}
#endif // FUTURE
return 1;
} /* write() */
#endif // !__AVR__
@@ -467,4 +441,21 @@ void BBEINK::drawString(const char *pText, int x, int y)
}
} /* drawString() */
void BBEINK::setPlane(int iPlane)
{
_bbei.iPlane = iPlane;
}
int BBEINK::getPlane(void)
{
return _bbei.iPlane;
}
int BBEINK::getChip(void)
{
return _bbei.chip_type;
}
void BBEINK::getStringBox(const char *szMsg, int *width, int *top, int *bottom)
{
bbeiGetStringBox((BB_FONT *)_bbei.pFont, szMsg, width, top, bottom);
}
#endif // __cplusplus
+16 -13
View File
@@ -44,11 +44,10 @@ enum {
#define DEEP_SLEEP 1
// Display refresh modes
enum {
REFRESH_FULL=0,
REFRESH_FAST,
REFRESH_PARTIAL
};
#define REFRESH_FULL 0
#define REFRESH_FAST 1
#define REFRESH_PARTIAL 2
// controller chip types
enum {
BBEI_CHIP_NOT_DEFINED = 0,
@@ -90,7 +89,8 @@ enum {
EPD_PANEL_UNDEFINED=0,
EPD42_400x300, // WFT0420CZ15
EPD42B_400x300, // DEPG0420BN / GDEY042T81
EPD213B_104x212,
EPD213_122x250, // waveshare
EPD213B_122x250, // GDEY0213B74
EPD293_128x296,
EPD294_128x296, // Waveshare newer 2.9" 1-bit 128x296
EPD295_128x296, // harvested from Solum 2.9" BW ESLs
@@ -100,6 +100,9 @@ enum {
EPD29R_128x296,
EPD122_192x176, // GDEM0122T61
EPD154R_152x152,
EPD42R_400x300,
EPD42R2_400x300, // GDEQ042Z21
EPD37_240x416, // GDEY037T03
EPD_PANEL_COUNT
};
#ifdef FUTURE
@@ -108,14 +111,10 @@ enum {
EPD29_128x296,
EPD29B_128x296,
EPD29Y_128x296, // DEPG0290YN
EPD42R_400x300,
EPD42R2_400x300, // GDEQ042Z21
EPD213R_104x212,
EPD213R2_122x250, // DEPG0213RW
EPD213R_104x212_d,
EPD213_104x212,
EPD213_122x250, // waveshare
EPD213B_122x250, // GDEY0213B74
EPD154_152x152, // GDEW0154M10
EPD154R_152x152,
EPD154Y_152x152, // DEPG0154YN
@@ -126,7 +125,6 @@ enum {
EPD266Y_152x296, // DEPG0266YN
EPD31R_168x296, // DEPG0310RW
EPD37Y_240x416, // DEPG0370YN
EPD37_240x416, // GDEY037T03
EPD579_792x272, // GDEY0579T93
EPD583R_600x448,
EPD75_800x480, // GDEY075T7
@@ -260,7 +258,7 @@ uint32_t iSpeed;
uint32_t iTimeout; // for e-ink panels
uint8_t iDCPin, iMOSIPin, iCLKPin, iCSPin, iRSTPin, iBUSYPin;
uint8_t x_offset, y_offset; // memory offsets
uint8_t bBitBang, iPlane;
uint8_t is_awake, iPlane;
const uint8_t *pInitFull; // full update init sequence
const uint8_t *pInitFast; // fast update init sequence
const uint8_t *pInitPart; // partial update init sequence
@@ -320,7 +318,10 @@ class BBEINK
void sleep(int bDeep);
void wait(bool bQuick = false);
void drawString(const char *pText, int x, int y);
void setPlane(int iPlane);
int getPlane(void);
int getChip(void);
void getStringBox(const char *szMsg, int *width, int *top, int *bottom);
#ifdef FUTURE
void setPlane(int iPlane);
void drawSprite(uint8_t *pSprite, int cx, int cy, int iPitch, int x, int y, uint8_t iPriority);
@@ -344,8 +345,10 @@ class BBEINK
size_t write(uint8_t ucChar);
void delayMicroseconds(int iTime);
#else
#ifndef __AVR__
using Print::write;
virtual size_t write(uint8_t);
#endif // __AVR__
#endif // _LINUX_
private: