Files
aqhomecontrol/avr/modules/lcd2/ili9341/graphops.asm

619 lines
15 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_GRAPHOPS_ASM
#define AQH_AVR_ILI9341_GRAPHOPS_ASM
; ---------------------------------------------------------------------------
; @routine Display_FillRect @global
;
; @param r3:r2 color
; @param r5:r4 X0
; @param r7:r6 Y0
; @param r9:r8 X1/W
; @param r11:r10 Y1/H
; @clobbers R16, R17, R20, R21, R22, R23, R24, R25
Display_FillRect:
#if 1
push r15
in r15, SREG
cli
rcall ili9341BeginSpi ; (R16, R17)
rcall ili9341SetAddressWindow ; (R16, r20, r21)
mov r22, r10 ; H low
mov r23, r11 ; H high
ldi r16, ILI9341_CMD_RAMWR ; start writing ro RAM
rcall ili9341SendCommand ; (R16)
cbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS low
sbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D high (DATA)
Display_FillRect_loopH:
mov r24, r8 ; W low
mov r25, r9 ; W high
Display_FillRect_loopW:
mov r16, r3
; rcall SPIHW_MasterTransfer ; (R16)
M_SPIHW_MASTER_SEND_BYTE r16 ; (R16)
mov r16, r2
; rcall SPIHW_MasterTransfer ; (R16)
M_SPIHW_MASTER_SEND_BYTE r16 ; (R16)
sbiw r25:r24, 1
brne Display_FillRect_loopW
mov r24, r22 ; remaining H low
mov r25, r23 ; remaining H high
sbiw r25:r24, 1 ; dec
mov r22, r24 ; save in r23:r22
mov r23, r25
brne Display_FillRect_loopH
sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
rcall ili9341EndSpi
out SREG, r15
pop r15
ret
#else
push r15
in r15, SREG
cli
rcall ili9341BeginSpi ; (R16, R17)
rcall ili9341SetAddressWindow ; (R16, r20, r21)
mov r20, r8
mov r21, r9
mov r22, r10
mov r23, r11
bigcall Utils_Mulu16x16_32
mov r24, r16
mov r25, r17
rcall displaySendColor
sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
rcall ili9341EndSpi
out SREG, r15
pop r15
ret
#endif
; @end
; ---------------------------------------------------------------------------
; @routine Display_DrawRect @global
;
; @param r3:r2 color
; @param r5:r4 X
; @param r7:r6 Y
; @param r9:r8 W
; @param r11:r10 H
Display_DrawRect:
push r15
in r15, SREG
cli
; upper H line
rcall Display_DrawHLine ; (R16, R17, R20, R21, R24, R25)
push r6 ; save Y0
push r7
add r6, r10 ; Y+=(H-1)
adc r7, r11
ldi r16, 1
clr r17
sub r6, r16
sbc r7, r17
; lower H line
rcall Display_DrawHLine
pop r7
pop r6
; left V line
rcall Display_DrawVLine
push r4 ; save X0
push r5
add r4, r8 ; X+=W-1
adc r5, r9
ldi r16, 1
clr r17
sub r4, r16
sbc r5, r17
; right V line
rcall Display_DrawVLine
pop r5
pop r4
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine Display_DrawHLine @global
;
; @param r3:r2 color
; @param r5:r4 X
; @param r7:r6 Y
; @param r9:r8 W
; @clobbers R16, R17, R20, R21, R24, R25
Display_DrawHLine:
push r15
in r15, SREG
cli
push r10
push r11
clr r10
inc r10 ; height is 1
clr r11
rcall ili9341BeginSpi ; (R16, R17)
rcall ili9341SetAddressWindow ; (R16, r20, r21)
pop r11
pop r10
mov r24, r8 ; W low
mov r25, r9 ; W high
rcall displaySendColor ; (R16)
rcall ili9341EndSpi
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine Display_DrawVLine @global
;
; @param r3:r2 color
; @param r5:r4 X0
; @param r7:r6 Y0
; @param r11:r10 H
; @clobbers R16, R17, R20, R21, R24, R25
Display_DrawVLine:
push r15
in r15, SREG
cli
push r8
push r9
clr r8
inc r8 ; width is 1
clr r9
rcall ili9341BeginSpi ; (R16, R17)
rcall ili9341SetAddressWindow ; (R16, r20, r21)
pop r9
pop r8
mov r24, r10 ; H low
mov r25, r11 ; H high
rcall displaySendColor ; (R16)
rcall ili9341EndSpi
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine displaySendColor
; @param r25:r24 number of pixel to write
; @param r3:r2 color to write
; @clobbers r16
displaySendColor:
ldi r16, ILI9341_CMD_RAMWR ; start writing ro RAM
rcall ili9341SendCommand ; (R16)
cbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS low
sbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D high (DATA)
displaySendColor_loop:
mov r16, r3
; rcall SPIHW_MasterTransfer ; (R16)
M_SPIHW_MASTER_SEND_BYTE r16
mov r16, r2
; rcall SPIHW_MasterTransfer ; (R16)
M_SPIHW_MASTER_SEND_BYTE r16
sbiw r25:r24, 1
brne displaySendColor_loop
sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
ret
; @end
; ---------------------------------------------------------------------------
; @routine Display_DrawChar @global
; @param R16 character to write
; @param R1:R0 background color
; @param R3:R2 foreground color
; @param R5:R4 X (dest)
; @param R7:R6 Y (dest)
; @param Z pointer to font
; @return R18 width of char written (in pixel)
; @return R19 height of char written (in pixel)
; @clobbers any, !Z
Display_DrawChar:
push r15
in r15, SREG
cli
push zl
push zh
mov r22, r16 ; save char to R22
adiw zh:zl, FONT_OFFS_WIDTH
lpm r8, Z+ ; char width in pixels
clr r9
lpm r10, Z ; char height in pixels
clr r11
sbiw zh:zl, FONT_OFFS_WIDTH+1
rcall ili9341BeginSpi ; (r16, r17)
rcall ili9341SetAddressWindow ; (R16, R20, R21)
ldi r16, ILI9341_CMD_RAMWR ; start writing ro RAM
rcall ili9341SendCommand ; (R16)
cbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS low
sbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D high (DATA)
mov r16, r22 ; char to write
rcall FONT_RenderChar ; (any)
pop zh
pop zl
sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
rcall ili9341EndSpi ; (R16)
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine Display_BitBlit @global
; @param r5:r4 X (dest)
; @param r7:r6 Y (dest)
; @param r9:r8 W
; @param r11:r10 H
; @param X source data pointer (RAM)
; @clobbers r16, r22, r23, r24, r25, X (r17, r20, r21)
Display_BitBlit:
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
mov r22, r10 ; store remaining height
mov r23, r11
cbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS low
sbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D high (DATA)
Display_BitBlit_loopH:
mov r24, r8 ; r25:r24=width in pixel
mov r25, r9
Display_BitBlit_loopW:
ld r18, X+ ; read color from X
ld r19, X+
; mov r16, r19
; rcall SPIHW_MasterTransfer ; (R16)
M_SPIHW_MASTER_SEND_BYTE r19
; mov r16, r18
; rcall SPIHW_MasterTransfer ; (R16)
M_SPIHW_MASTER_SEND_BYTE r18
sbiw r25:r24, 1
brne Display_BitBlit_loopW
mov r24, r22
mov r25, r23
sbiw r25:r24, 1
mov r22, r24
mov r23, r25
brne Display_BitBlit_loopH
sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
rcall ili9341EndSpi ; (R16)
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine ili9341BitBlitStretch2
; @param r5:r4 X (dest)
; @param r7:r6 Y (dest)
; @param r9:r8 W
; @param r11:r10 H
; @param X source data pointer (RAM)
; @clobbers r16, r22, r23, r24, r25, X (r17, r18, r19, r20, r21)
ili9341BitBlitStretch2:
push r15
in r15, SREG
cli
push r8
push r9
push r10
push r11
; width
lsl r8 ; x2
rol r9
; height
lsl r10 ; x2
rol r11
rcall ili9341BeginSpi ; (r16, r17)
rcall ili9341SetAddressWindow ; (R16, R20, R21)
pop r11
pop r10
pop r9
pop r8
ldi r16, ILI9341_CMD_RAMWR ; start writing ro RAM
rcall ili9341SendCommand
mov r22, r10
mov r23, r11
cbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS low
sbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D high (DATA)
ldi r17, 2
ili9341BitBlitStretch2_loopH:
mov r20, xl ; preserve for next run
mov r21, xh
rcall ili9341BitBlitStretchNWriteLine ; (r16, r17, r18, r19, r24, r25, X)
mov xl, r20
mov xh, r21
rcall ili9341BitBlitStretchNWriteLine ; (r16, r17, r18, r19, r24, r25, X)
mov r24, r22
mov r25, r23
sbiw r25:r24, 1
mov r22, r24
mov r23, r25
brne ili9341BitBlitStretch2_loopH
sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
rcall ili9341EndSpi ; (R16)
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine ili9341BitBlitStretch4
; @param r5:r4 X (dest)
; @param r7:r6 Y (dest)
; @param r9:r8 W
; @param r11:r10 H
; @param X source data pointer (RAM)
; @clobbers r16, r22, r23, r24, r25, X (r17, r20, r21)
ili9341BitBlitStretch4:
push r15
in r15, SREG
cli
push r8
push r9
push r10
push r11
; width
lsl r8 ; x2
rol r9
lsl r8 ; x4
rol r9
; height
lsl r10 ; x2
rol r11
lsl r10 ; x4
rol r11
rcall ili9341BeginSpi ; (r16, r17)
rcall ili9341SetAddressWindow ; (R16, R20, R21)
pop r11
pop r10
pop r9
pop r8
ldi r16, ILI9341_CMD_RAMWR ; start writing ro RAM
rcall ili9341SendCommand
mov r22, r10
mov r23, r11
ldi r17, 4
cbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS low
sbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D high (DATA)
ili9341BitBlitStretch4_loopH:
mov r20, xl ; preserve for next run
mov r21, xh
rcall ili9341BitBlitStretchNWriteLine ; (r16, r17, r18, r19, r24, r25, X)
mov xl, r20
mov xh, r21
rcall ili9341BitBlitStretchNWriteLine ; (r16, r17, r18, r19, r24, r25, X)
mov xl, r20
mov xh, r21
rcall ili9341BitBlitStretchNWriteLine ; (r16, r17, r18, r19, r24, r25, X)
mov xl, r20
mov xh, r21
rcall ili9341BitBlitStretchNWriteLine ; (r16, r17, r18, r19, r24, r25, X)
mov r24, r22
mov r25, r23
sbiw r25:r24, 1
mov r22, r24
mov r23, r25
brne ili9341BitBlitStretch4_loopH
sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
rcall ili9341EndSpi ; (R16)
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine ili9341BitBlitStretchNWriteLine
; @param r9:r8 width
; @param r17 repeat factor
; @param X source position of line
; @clobbers r16, r17, r18, r19, r24, r25, X
ili9341BitBlitStretchNWriteLine:
mov r24, r8
mov r25, r9
ili9341BitBlitStretchNWriteLine_loop1:
ld r18, X+
ld r19, X+
push r17
ili9341BitBlitStretchNWriteLine_loop2:
mov r16, r19
rcall SPIHW_MasterTransfer ; (R16)
mov r16, r18
rcall SPIHW_MasterTransfer ; (R16)
dec r17
brne ili9341BitBlitStretchNWriteLine_loop2
pop r17
sbiw r25:r24, 1
brne ili9341BitBlitStretchNWriteLine_loop1
ret
; @end
; ---------------------------------------------------------------------------
; @routine ili9341SetAddressWindow
;
; @param r5:r4 X0
; @param r7:r6 Y0
; @param r9:r8 W
; @param r11:r10 H
; @clobbers R16, r20, r21
ili9341SetAddressWindow:
rcall ili9341SetColumnAddress ; (R16, r20, r21)
rcall ili9341SetRowAddress ; (R16, r20, r21)
ret
; @end
; ---------------------------------------------------------------------------
; @routine ili9341SetColumnAddress
;
; @param r5:r4 X0
; @param r9:r8 W
; @clobbers R16, r20, r21
ili9341SetColumnAddress:
; calc XEnd (=X+W-1)
mov r20, r8
mov r21, r9
add r20, r4
adc r21, r5
subi r20, 1
sbci r21, 0
; send column address
ldi r16, ILI9341_CMD_CASET
rcall ili9341SendCommand ; (R16)
cbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS low
sbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D high (DATA)
; Xstart
mov r16, r5
rcall SPIHW_MasterTransfer ; (R16)
mov r16, r4
rcall SPIHW_MasterTransfer ; (R16)
; Xend
mov r16, r21
rcall SPIHW_MasterTransfer ; (R16)
mov r16, r20
rcall SPIHW_MasterTransfer ; (R16)
sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
ret
; @end
; ---------------------------------------------------------------------------
; @routine ili9341SetRowAddress
;
; @param r7:r6 Y0
; @param r11:r10 H
; @clobbers R16, r20, r21
ili9341SetRowAddress:
; calc YEnd (=Y+H-1)
mov r20, r10
mov r21, r11
add r20, r6
adc r21, r7
subi r20, 1
sbci r21, 0
; send row address
ldi r16, ILI9341_CMD_PASET
rcall ili9341SendCommand ; (R16)
cbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS low
sbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D high (DATA)
; Ystart
mov r16, r7
rcall SPIHW_MasterTransfer ; (R16)
mov r16, r6
rcall SPIHW_MasterTransfer ; (R16)
; Yend
mov r16, r21
rcall SPIHW_MasterTransfer ; (R16)
mov r16, r20
rcall SPIHW_MasterTransfer ; (R16)
sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high
ret
; @end
#endif ; AQH_AVR_ILI9341_GRAPHOPS_ASM