354 lines
10 KiB
NASM
354 lines
10 KiB
NASM
; ***************************************************************************
|
|
; copyright : (C) 2025 by Martin Preuss
|
|
; email : martin@libchipcard.de
|
|
;
|
|
; ***************************************************************************
|
|
; * This file is part of the project "AqHome". *
|
|
; * Please see toplevel file COPYING of that project for license details. *
|
|
; ***************************************************************************
|
|
|
|
#ifndef AQH_AVR_ILI9341_IMAGES_ASM
|
|
#define AQH_AVR_ILI9341_IMAGES_ASM
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; data
|
|
|
|
.dseg
|
|
|
|
ili9341ImageColormap:
|
|
.byte 8
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
.cseg
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ili9341ImageDraw
|
|
|
|
; @param R1:R0 background color
|
|
; @param R5:R4 X (dest)
|
|
; @param R7:R6 Y (dest)
|
|
; @param Z pointer to image
|
|
; @clobbers any
|
|
|
|
ili9341ImageDraw:
|
|
adiw zh:zl, RES_IMAGE_OFFS_TYPE_LO
|
|
lpm r18, Z+
|
|
lpm r19, Z
|
|
sbiw zh:zl, RES_IMAGE_OFFS_TYPE_LO+1
|
|
tst r19
|
|
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
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ili9341ImageIdx2Draw
|
|
|
|
; @param R1:R0 background color
|
|
; @param R5:R4 X (dest)
|
|
; @param R7:R6 Y (dest)
|
|
; @param Z pointer to IDX2 image
|
|
; @clobbers any
|
|
|
|
ili9341ImageIdx2Draw:
|
|
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 ili9341ImageIdx2Draw_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 ili9341ImageIdx2WritePixels ; (R10, R16, 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
|
|
|
|
ili9341ImageIdx2Draw_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ili9341ImageIdx2CopyColormap
|
|
|
|
; @param R1:R0 background color
|
|
; @param Z pointer to IDX2 image
|
|
; @clobbers r16, X
|
|
|
|
ili9341ImageIdx2CopyColormap:
|
|
; get colormap
|
|
ldi xl, LOW(ili9341ImageColormap)
|
|
ldi xh, HIGH(ili9341ImageColormap)
|
|
push zl
|
|
push zh
|
|
adiw zh:zl, RES_IMAGE_OFFS_COLORMAP_LO
|
|
lpm r16, Z+
|
|
lpm zh, Z
|
|
mov zl, r16
|
|
or r16, zh
|
|
breq ili9341ImageIdx2CopyColormap_l1 ; no color map
|
|
adiw zh:zl, 2 ; skip numOfEntries
|
|
rcall ili9341ImageReadColormap
|
|
ili9341ImageIdx2CopyColormap_l1:
|
|
pop zh
|
|
pop zl
|
|
sts ili9341ImageColormap, r0
|
|
sts ili9341ImageColormap+1, r1 ; store background color in pos 0 of colormap
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ili9341ImageIdx2WritePixels
|
|
|
|
; @param r9:r8 W
|
|
; @param r11:r10 H
|
|
; @param Z pointer to pixel data of IDX2 image
|
|
; @clobbers R10, R16, R17, R20, R21, R22, R23, R24, R25, X, Z
|
|
|
|
ili9341ImageIdx2WritePixels:
|
|
clr r22
|
|
ili9341ImageIdx2WritePixels_vertLoop:
|
|
mov r20, r8 ; runWidth
|
|
ili9341ImageIdx2WritePixels_horizLoop:
|
|
tst r22 ; pixelCounterInByte
|
|
brne ili9341ImageIdx2WritePixels_l1
|
|
lpm r23, Z+ ; runByte
|
|
ldi r22, 4 ; 4 pixels per byte
|
|
ili9341ImageIdx2WritePixels_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 ili9341ImageIdx2WritePixels_horizLoop
|
|
dec r10 ; height
|
|
brne ili9341ImageIdx2WritePixels_vertLoop
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @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
|
|
|
|
; @param X dest pointer for colormap in SDRAM (8 bytes, i.e. 4 colors by 2 bytes)
|
|
; @param Z src byte pointer of colormap (for LPM!)
|
|
|
|
ili9341ImageReadColormap:
|
|
ldi r17, 8 ; 8 bytes
|
|
ili9341ImageReadColormap_loop:
|
|
lpm r16, Z+
|
|
st X+, r16
|
|
dec r17
|
|
brne ili9341ImageReadColormap_loop
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|