avr: add support for run-length-encoded images, converted existing images

saves much ressource space especially with larger images!
This commit is contained in:
Martin Preuss
2026-01-16 16:42:49 +01:00
parent 0aa4e6846a
commit 283374b5cd
4 changed files with 281 additions and 308 deletions

View File

@@ -12,6 +12,7 @@
.equ DISPLAY_IMAGETYPE_IDX2 = 1 ; 2 bit indexed image
.equ DISPLAY_IMAGETYPE_IDX2RLE = 2 ; 2 bit indexed image, RLE-encoded

View File

@@ -47,10 +47,17 @@ ili9341ImageDraw:
brne ili9341ImageDraw_ret
cpi r18, DISPLAY_IMAGETYPE_IDX2
breq ili9341ImageDraw_idx2
cpi r18, DISPLAY_IMAGETYPE_IDX2RLE
breq ili9341ImageDraw_idx2rle
; add more here
rjmp ili9341ImageDraw_ret
ili9341ImageDraw_idx2:
rcall ili9341ImageIdx2Draw ; (any)
rjmp ili9341ImageDraw_ret
ili9341ImageDraw_idx2rle:
rcall ili9341ImageIdx2rleDraw
rjmp ili9341ImageDraw_ret
; add more here
ili9341ImageDraw_ret:
ret
; @end
@@ -146,7 +153,7 @@ ili9341ImageIdx2CopyColormap_l1:
; @param r9:r8 W
; @param r11:r10 H
; @param Z pointer to pixel data of IDX2 image
; @clobbers R10, R16, R18, R19, R20, R21, R22, R23, R24, R25, X, Z
; @clobbers R10, R16, R17, R20, R21, R22, R23, R24, R25, X, Z
ili9341ImageIdx2WritePixels:
clr r22
@@ -169,11 +176,11 @@ ili9341ImageIdx2WritePixels_l1:
add xl, r21 ; add to X -> pos in palette
adc xh, r21
sub xh, r21
ld r18, X+
ld r19, X
mov r16, r19 ; send to SPI
ld r17, X+
ld r16, X
; send to SPI (high byte first)
rcall SPIHW_MasterTransfer ; (R16)
mov r16, r18
mov r16, r17
rcall SPIHW_MasterTransfer ; (R16)
dec r22 ; pixelCounterInByte
@@ -186,6 +193,143 @@ ili9341ImageIdx2WritePixels_l1:
; ---------------------------------------------------------------------------
; @routine ili9341ImageIdx2rleDraw
; @param R1:R0 background color
; @param R5:R4 X (dest)
; @param R7:R6 Y (dest)
; @param Z pointer to IDX2 image
; @clobbers any
ili9341ImageIdx2rleDraw:
rcall ili9341ImageIdx2CopyColormap ; (R16, X)
; read image width and height
adiw zh:zl, RES_IMAGE_OFFS_WIDTH_LO
lpm r8, Z+ ; read width (lo)
lpm r9, Z+
lpm r10, Z+ ; read height
lpm r11, Z
adiw zh:zl, (RES_IMAGE_OFFS_PIXELS_LO-RES_IMAGE_OFFS_HEIGHT_HI) ; skip 3 bytes
lpm r16, Z+
lpm zh, Z
mov zl, r16
or r16, zh
breq ili9341ImageIdx2rleDraw_ret
; write image
push r15
in r15, SREG
cli
rcall ili9341BeginSpi ; (r16, r17)
rcall ili9341SetAddressWindow ; (R16, R20, R21)
ldi r16, ILI9341_CMD_RAMWR ; start writing ro RAM
rcall ili9341SendCommand
cbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS low
sbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D high (DATA)
rcall ili9341ImageIdx2rleWritePixels ; (R10, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, X, Z)
sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
rcall ili9341EndSpi ; (R16)
out SREG, r15
pop r15
ili9341ImageIdx2rleDraw_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ili9341ImageIdx2rleWritePixels
; @param r9:r8 W
; @param r11:r10 H
; @param Z pointer to pixel data of IDX2 image
; @clobbers R10, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, X, Z
ili9341ImageIdx2rleWritePixels:
clr r22 ; pixelCounterInByte
clr r18 ; RLE control byte
clr r19 ; RLE repeated byte
ili9341ImageIdx2rleWritePixels_vertLoop:
mov r20, r8 ; runWidth
ili9341ImageIdx2rleWritePixels_horizLoop:
tst r22 ; pixelCounterInByte
brne ili9341ImageIdx2rleWritePixels_l1
rcall ili9341ImageIdx2rleGetNextByte ; (R16)
ldi r22, 4 ; 4 pixels per byte
ili9341ImageIdx2rleWritePixels_l1:
clr r21 ; temp (receives current pixel)
lsl r23 ; shift upper two bits into runtime var
rol r21
lsl r23
rol r21
lsl r21 ; 2 bytes per color
ldi xl, LOW(ili9341ImageColormap)
ldi xh, HIGH(ili9341ImageColormap)
add xl, r21 ; add to X -> pos in palette
adc xh, r21
sub xh, r21
ld r17, X+
ld r16, X
; send to SPI (high byte first)
rcall SPIHW_MasterTransfer ; (R16)
mov r16, r17
rcall SPIHW_MasterTransfer ; (R16)
dec r22 ; pixelCounterInByte
dec r20 ; runWidth
brne ili9341ImageIdx2rleWritePixels_horizLoop
dec r10 ; height
brne ili9341ImageIdx2rleWritePixels_vertLoop
ret
; @end
; ---------------------------------------------------------------------------
; @routine ili9341ImageIdx2rleGetNextByte
;
; @param r18 current controly byte (bit 7=1: repeat, bits 0-6: counter), updated on return
; @param r19 current repeat byte, updated on return
; @param Z current pixel data pointer
; @return r23 byte read
; @clobbers r16
ili9341ImageIdx2rleGetNextByte:
; get next byte somehow
mov r16, r18
andi r16, 0x7f
brne ili9341ImageIdx2rleGetNextByte_haveBytes
; counter is zero, read next control byte
lpm r18, Z+ ; read control byte
sbrc r18, 7
lpm r19, Z+ ; with repeat, read repeated byte
ili9341ImageIdx2rleGetNextByte_haveBytes:
sbrc r18, 7 ; if bit 7=1:
mov r23, r19 ; copy repeated byte
sbrs r18, 7 ; if bit 7=0:
lpm r23, Z+ ; read next byte (norepeat sequence)
; dec counter while keeping bit 7
mov r16, r18
andi r16, 0x7f ; clear bit 7
dec r16 ; dec counter
andi r18, 0x80 ; clear counter part of CNTRL byte
or r18, r16 ; or new counter into CNTRL byte
ret
; @end
; ---------------------------------------------------------------------------
; @routine ili9341ImageReadColormap