diff --git a/src/bb_ei.inl b/src/bb_ei.inl index 9499fd7..8fcab97 100644 --- a/src/bb_ei.inl +++ b/src/bb_ei.inl @@ -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; ynative_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; ynative_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); diff --git a/src/bb_ei_gfx.inl b/src/bb_ei_gfx.inl index d99d090..8e51f06 100644 --- a/src/bb_ei_gfx.inl +++ b/src/bb_ei_gfx.inl @@ -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; tynative_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; tyheight; 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; txwidth; 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; ynative_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; ynative_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)); diff --git a/src/bb_ei_io.inl b/src/bb_ei_io.inl index 63d70e3..b6b43e4 100644 --- a/src/bb_ei_io.inl +++ b/src/bb_ei_io.inl @@ -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) diff --git a/src/bb_eink.cpp b/src/bb_eink.cpp index 02eef1f..587ab67 100644 --- a/src/bb_eink.cpp +++ b/src/bb_eink.cpp @@ -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 diff --git a/src/bb_eink.h b/src/bb_eink.h index e52e1bf..1e5ff31 100644 --- a/src/bb_eink.h +++ b/src/bb_eink.h @@ -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: