diff --git a/esp_idf/mini_epaper_s3/main/mini_epaper_s3.c b/esp_idf/mini_epaper_s3/main/mini_epaper_s3.c index 4a2e642..2acc7f0 100644 --- a/esp_idf/mini_epaper_s3/main/mini_epaper_s3.c +++ b/esp_idf/mini_epaper_s3/main/mini_epaper_s3.c @@ -18,7 +18,7 @@ void app_main(void) init_ulp_program(); /* Go to sleep, only the ULP Risc-V will run */ - printf("Entering in deep sleep\n\n"); +// printf("Entering in deep sleep\n\n"); /* 5 second delay to ensure we can reflash from USB */ // vTaskDelay(500); @@ -35,9 +35,9 @@ static void init_ulp_program(void) ESP_ERROR_CHECK(err); /* The first argument is the period index, which is not used by the ULP-RISC-V timer - * The second argument is the period in microseconds, which gives a wakeup time period of: 20ms + * The second argument is the period in microseconds */ - ulp_set_wakeup_period(0, 5000000); // 5 seconds + ulp_set_wakeup_period(0, 20000); // 20 miliseconds for first wakeup /* Start the program */ err = ulp_riscv_run(); diff --git a/esp_idf/mini_epaper_s3/main/ulp/main.c b/esp_idf/mini_epaper_s3/main/ulp/main.c index 024c0de..5480e28 100644 --- a/esp_idf/mini_epaper_s3/main/ulp/main.c +++ b/esp_idf/mini_epaper_s3/main/ulp/main.c @@ -20,6 +20,7 @@ #include "ulp_riscv.h" #include "ulp_riscv_utils.h" #include "ulp_riscv_gpio.h" +#include "ulp_common.h" // Tell the bb_epaper library not to include code related to // drawing with a back buffer for the epaper panel @@ -65,6 +66,6 @@ int main (void) // } // } /* ulp_riscv_halt() is called automatically when main exits */ -// ulp_set_wakeup_period(0, 5000000); // period in usec +// ulp_set_wakeup_period(0, 25000000); // period of next wake up in usec return 0; } diff --git a/esp_idf/s3_ulp_io.inl b/esp_idf/s3_ulp_io.inl index 5e759d0..6651bb7 100644 --- a/esp_idf/s3_ulp_io.inl +++ b/esp_idf/s3_ulp_io.inl @@ -112,32 +112,36 @@ void bbepInitIO(BBEPDISP *pBBEP, uint8_t u8DC, uint8_t u8RST, uint8_t u8BUSY, ui // // Bit Bang SPI // -void SPIWriteByte(BBEPDISP *pBBEP, uint8_t uc) +void SPIWriteBytes(BBEPDISP *pBBEP, uint8_t *pData, int iLen) { -uint8_t u8MOSI = pBBEP->iMOSIPin; -uint8_t u8SCK = pBBEP->iCLKPin; +const uint8_t u8MOSI = pBBEP->iMOSIPin; +const uint8_t u8SCK = pBBEP->iCLKPin; +uint8_t uc; - if (uc == 0 || uc == 0xff) { // special case - ulp_riscv_gpio_output_level(u8MOSI, (uc & 1)); - for (int i=0; i<8; i++) { - ulp_riscv_gpio_output_level(u8SCK, 1); // no delays needed since it runs at a slow clock - ulp_riscv_gpio_output_level(u8SCK, 0); - } - } else { - for (int i=0; i<8; i++) { - ulp_riscv_gpio_output_level(u8MOSI, (uc & 0x80)); // msb first - ulp_riscv_gpio_output_level(u8SCK, 1); // no delays needed since it runs at a slow clock - uc <<= 1; - ulp_riscv_gpio_output_level(u8SCK, 0); + for (int j=0; jiDCPin, LOW); digitalWrite(pBBEP->iCSPin, LOW); - SPIWriteByte(pBBEP, ucCMD); + SPIWriteBytes(pBBEP, &ucCMD, 1); digitalWrite(pBBEP->iDCPin, HIGH); digitalWrite(pBBEP->iCSPin, HIGH); } /* bbepWriteCmd() */ @@ -145,9 +149,7 @@ void bbepWriteCmd(BBEPDISP *pBBEP, uint8_t ucCMD) void bbepWriteData(BBEPDISP *pBBEP, uint8_t *pData, int iLen) { digitalWrite(pBBEP->iCSPin, LOW); - for (int i=0; iiCSPin, HIGH); } diff --git a/src/Group5.h b/src/Group5.h index 122d07f..9fff9a2 100644 --- a/src/Group5.h +++ b/src/Group5.h @@ -4,6 +4,9 @@ #include #include #include +#ifdef __AVR__ +#include +#endif // // Group5 1-bit image compression library // Written by Larry Bank @@ -82,7 +85,17 @@ typedef struct g5_dec_image_tag } G5DECIMAGE; // Due to unaligned memory causing an exception, we have to do these macros the slow way +#ifdef __AVR__ +// assume PROGMEM as the source of data +inline uint32_t TIFFMOTOLONG(uint8_t *p) +{ + uint32_t u32 = pgm_read_dword(p); + return __builtin_bswap32(u32); +} +#else #define TIFFMOTOLONG(p) (((uint32_t)(*p)<<24UL) + ((uint32_t)(*(p+1))<<16UL) + ((uint32_t)(*(p+2))<<8UL) + (uint32_t)(*(p+3))) +#endif // __AVR__ + #define TOP_BIT 0x80000000 #define MAX_VALUE 0xffffffff // Must be a 32-bit target processor diff --git a/src/arduino_io.inl b/src/arduino_io.inl index e27c8db..6810aca 100644 --- a/src/arduino_io.inl +++ b/src/arduino_io.inl @@ -20,6 +20,8 @@ #include #include +// foreward references +void bbepWakeUp(BBEPDISP *pBBEP); // // Initialize the GPIO pins and SPI for use by bb_eink // diff --git a/src/bb_ep_gfx.inl b/src/bb_ep_gfx.inl index 67697af..51fcec2 100644 --- a/src/bb_ep_gfx.inl +++ b/src/bb_ep_gfx.inl @@ -594,20 +594,25 @@ unsigned int c; uint8_t *s, bInvert = 0; BB_GLYPH *pGlyph; uint8_t *pBits, u8CMD1, u8CMD2, u8CMD, u8EndMask; +uint8_t first, last; + + if (pBBEP == NULL || pFont == NULL) return; // invalid param if (x == -1) x = pBBEP->iCursorX; if (y == -1) y = pBBEP->iCursorY; + first = pgm_read_byte(&pFont->first); + last = pgm_read_byte(&pFont->last); if (x == CENTER_X) { // center the string on the e-paper dx = i = 0; while (szMsg[i]) { c = szMsg[i++]; - if (c < pFont->first || c > pFont->last) // undefined character + if (c < first || c > last) // undefined character continue; // skip it - c -= pFont->first; // first char of font defined + c -= first; // first char of font defined pGlyph = &pFont->glyphs[c]; // glyph info for this character - dx += pGlyph->xAdvance; + dx += pgm_read_byte(&pGlyph->xAdvance); } x = (pBBEP->native_width - dx)/2; if (x < 0) x = 0; @@ -615,26 +620,26 @@ uint8_t *pBits, u8CMD1, u8CMD2, u8CMD, u8EndMask; // Point to the start of the compressed data pBits = (uint8_t *)pFont; pBits += sizeof(BB_FONT); - pBits += (pFont->last - pFont->first + 1) * sizeof(BB_GLYPH); + pBits += (last - first + 1) * sizeof(BB_GLYPH); i = 0; while (szMsg[i] && x < pBBEP->native_width && y < pBBEP->native_height) { c = szMsg[i++]; - if (c < pFont->first || c > pFont->last) // undefined character + if (c < first || c > last) // undefined character continue; // skip it - c -= pFont->first; // first char of font defined + c -= first; // first char of font defined pGlyph = &pFont->glyphs[c]; // glyph info for this character - if (pGlyph->width > 1) { // skip this if drawing a space - s = pBits + pGlyph->bitmapOffset; // start of compressed bitmap data - if (pFont->rotation == 0 || pFont->rotation == 180) { - h = pGlyph->height; - w = pGlyph->width; - dx = x + pGlyph->xOffset; // offset from character UL to start drawing - dy = y + pGlyph->yOffset; + if (pgm_read_byte(&pGlyph->width) > 1) { // skip this if drawing a space + s = pBits + pgm_read_word(&pGlyph->bitmapOffset); // start of compressed bitmap data + if (pgm_read_word(&pFont->rotation) == 0 || pgm_read_word(&pFont->rotation) == 180) { + h = pgm_read_word(&pGlyph->height); + w = pgm_read_byte(&pGlyph->width); + dx = x + pgm_read_word(&pGlyph->xOffset); // offset from character UL to start drawing + dy = y + pgm_read_word(&pGlyph->yOffset); } else { // rotated - w = pGlyph->height; - h = pGlyph->width; - dx = x + pGlyph->yOffset; // offset from character UL to start drawing - dy = y + pGlyph->xOffset; + w = pgm_read_word(&pGlyph->height); + h = pgm_read_byte(&pGlyph->width); + dx = x + pgm_read_word(&pGlyph->yOffset); // offset from character UL to start drawing + dy = y + pgm_read_word(&pGlyph->xOffset); } if ((dy + h) > pBBEP->native_height) { // trim it h = pBBEP->native_height - dy; @@ -644,7 +649,7 @@ uint8_t *pBits, u8CMD1, u8CMD2, u8CMD, u8EndMask; u8EndMask <<= (8-(w & 7)); } end_y = dy + h; - ty = (pGlyph[1].bitmapOffset - (intptr_t)(s - pBits)); // compressed size + ty = (pgm_read_word(&pGlyph[1].bitmapOffset) - (intptr_t)(s - pBits)); // compressed size if (ty < 0 || ty > 4096) ty = 4096; // DEBUG rc = g5_decode_init(&g5dec, w, h, s, ty); if (rc != G5_SUCCESS) return; // corrupt data? @@ -689,8 +694,8 @@ uint8_t *pBits, u8CMD1, u8CMD2, u8CMD, u8EndMask; u8CMD = u8CMD2; // second plane is red (inverted) } bbepWriteCmd(pBBEP, u8CMD); // memory write command - for (ty=dy; tynative_height; ty++) { - g5_decode_line(&g5dec, u8Cache); + for (ty=dy; tynative_height; ty++) { + rc = g5_decode_line(&g5dec, u8Cache); u8Cache[iSrcPitch-1] &= u8EndMask; // clean pixels beyond character width u8Cache[iSrcPitch] = 0; if (dx & 7) { // need to shift it over by 1-7 bits @@ -710,10 +715,10 @@ uint8_t *pBits, u8CMD1, u8CMD2, u8CMD, u8EndMask; } // for y } } // if not drawing a space - if (pFont->rotation == 0 || pFont->rotation == 180) { - x += pGlyph->xAdvance; // width of this character + if (pgm_read_word(&pFont->rotation) == 0 || pgm_read_word(&pFont->rotation) == 180) { + x += pgm_read_byte(&pGlyph->xAdvance); // width of this character } else { - y += pGlyph->xAdvance; + y += pgm_read_byte(&pGlyph->xAdvance); } } // while drawing characters pBBEP->iCursorX = x; diff --git a/src/g5dec.inl b/src/g5dec.inl index 4bf3466..07ebd52 100644 --- a/src/g5dec.inl +++ b/src/g5dec.inl @@ -115,7 +115,6 @@ static void Decode_Begin(G5DECIMAGE *pPage) { int i, xsize; int16_t *CurFlips, *RefFlips; - uint8_t *pBuf, *pBufEnd; xsize = pPage->iWidth; @@ -135,21 +134,15 @@ static void Decode_Begin(G5DECIMAGE *pPage) pPage->pCur = CurFlips; pPage->pRef = RefFlips; - - pBuf = pPage->pSrc; -// -// Some files may have leading 0's that would confuse the decoder -// Valid G5 data can't begin with a 0 -// - pBufEnd = &pBuf[128]; // DEBUG - while (pBuf < pBufEnd && pBuf[0] == 0) - { pBuf++; } - - pPage->pBuf = pBuf; - pPage->ulBits = TIFFMOTOLONG(pBuf); // load 32 bits to start + pPage->pBuf = pPage->pSrc; + pPage->ulBits = TIFFMOTOLONG(pPage->pSrc); // load 32 bits to start pPage->ulBitOff = 0; // Calculate the number of bits needed for a long horizontal code +#ifdef __AVR__ + pPage->iHLen = 16 - __builtin_clz(pPage->iWidth); +#else pPage->iHLen = 32 - __builtin_clz(pPage->iWidth); +#endif } /* Decode_Begin() */ // // Decode a single line of G5 data (private function)