Added patches to G5 decoder for AVR

This commit is contained in:
Laurence Bank
2024-09-23 23:54:06 +01:00
parent 222fa17bba
commit 928c10f7cf
7 changed files with 76 additions and 60 deletions
+3 -3
View File
@@ -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();
+2 -1
View File
@@ -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;
}
+22 -20
View File
@@ -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; j<iLen; j++) {
uc = *pData++;
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);
}
}
}
} /* SPIWriteByte() */
} /* SPIWriteBytes() */
void bbepWriteCmd(BBEPDISP *pBBEP, uint8_t ucCMD)
{
digitalWrite(pBBEP->iDCPin, 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; i<iLen; i++) {
SPIWriteByte(pBBEP, pData[i]);
}
SPIWriteBytes(pBBEP, pData, iLen);
digitalWrite(pBBEP->iCSPin, HIGH);
}
+13
View File
@@ -4,6 +4,9 @@
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#ifdef __AVR__
#include <avr/pgmspace.h>
#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
+2
View File
@@ -20,6 +20,8 @@
#include <Arduino.h>
#include <SPI.h>
// foreward references
void bbepWakeUp(BBEPDISP *pBBEP);
//
// Initialize the GPIO pins and SPI for use by bb_eink
//
+28 -23
View File
@@ -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; ty<end_y && ty < pBBEP->native_height; ty++) {
g5_decode_line(&g5dec, u8Cache);
for (ty=dy; ty<end_y && rc == G5_SUCCESS && ty < pBBEP->native_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;
+6 -13
View File
@@ -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)