From 143180d68baad16c9cfdf3ffd18807969645f1a9 Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Thu, 22 May 2025 00:42:55 +0200 Subject: [PATCH] ili9341: added bitblit routines. --- avr/modules/lcd2/ili9341/main.asm | 588 ++++++++++++++++++------------ 1 file changed, 349 insertions(+), 239 deletions(-) diff --git a/avr/modules/lcd2/ili9341/main.asm b/avr/modules/lcd2/ili9341/main.asm index 8da3db6..4c91dbf 100644 --- a/avr/modules/lcd2/ili9341/main.asm +++ b/avr/modules/lcd2/ili9341/main.asm @@ -106,9 +106,14 @@ ILI9341_Init: ldi xl, LOW(0x260) ldi xh, HIGH(0x260) +; set foreground color + ldi r16, 0b00000000 ; black + mov r2, r16 + mov r3, r16 + ; set character ldi r16, 65 - rcall ili9341_WriteCharacterX2At + rcall ili9341_WriteCharacterX4At sec ret @@ -259,74 +264,24 @@ ILI9341_FillScreen: -; --------------------------------------------------------------------------- -; @routine ILI9341_FillRect -; @param r3:r2 color -; @param r5:r4 X0 -; @param r7:r6 Y0 -; @param r9:r8 X1/W -; @param r11:r10 Y1/H - -ILI9341_FillRect: - rcall ili9341BeginSpi ; (R16, R17) - push r8 ; W - push r9 - push r10 - push r11 - ldi r16, 1 - - sub r8, r16 ; X1=X+W-1 - sbc r9, r16 - add r9, r16 - add r8, r4 - adc r9, r5 - - sub r10, r16 ; Y1=Y+H-1 - sbc r11, r16 - add r11, r16 - add r10, r6 - adc r11, r7 - rcall ili9341SetAddressWindow ; (R16) - pop r11 - pop r10 - pop r9 - pop r8 - - mov r18, r2 ; color - mov r19, r3 - mov r22, r10 ; H low - mov r23, r11 ; H high - ldi r16, ILI9341_CMD_RAMWR ; start writing ro RAM - rcall ili9341SendCommand -ILI9341_FillRect_loopH: - mov r24, r8 ; W low - mov r25, r9 ; W high -ILI9341_FillRect_loopW: - rcall ili9341Send16BitData ; send r19:r18 - sbiw r25:r24, 1 - brne ILI9341_FillRect_loopW - mov r24, r22 ; H low - mov r25, r23 ; H high - sbiw r25:r24, 1 ; dec - mov r22, r24 ; save in r23:r22 - mov r23, r25 - brne ILI9341_FillRect_loopH - rcall ili9341EndSpi - ret -; @end - - - ; --------------------------------------------------------------------------- ; @routine ili9341SetAddressWindow ; ; @param r5:r4 X0 ; @param r7:r6 Y0 -; @param r9:r8 X1 -; @param r11:r10 Y1 -; @clobbers R16 +; @param r9:r8 W +; @param r11:r10 H +; @clobbers R16, r20, r21 ili9341SetAddressWindow: + ; 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 @@ -336,11 +291,19 @@ ili9341SetAddressWindow: mov r16, r4 rcall ili9341SendData ; X1 - mov r16, r9 + mov r16, r21 rcall ili9341SendData - mov r16, r8 + mov r16, r20 rcall ili9341SendData + ; 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 @@ -350,9 +313,9 @@ ili9341SetAddressWindow: mov r16, r6 rcall ili9341SendData ; Y1 - mov r16, r11 + mov r16, r21 rcall ili9341SendData - mov r16, r10 + mov r16, r20 rcall ili9341SendData ret @@ -360,6 +323,272 @@ ili9341SetAddressWindow: +; --------------------------------------------------------------------------- +; @routine ILI9341_FillRect +; @param r3:r2 color +; @param r5:r4 X0 +; @param r7:r6 Y0 +; @param r9:r8 X1/W +; @param r11:r10 Y1/H + +ILI9341_FillRect: + push r15 + in r15, SREG + cli + + rcall ili9341BeginSpi ; (R16, R17) + rcall ili9341SetAddressWindow ; (R16, r20, r21) + + mov r18, r2 ; color + mov r19, r3 + mov r22, r10 ; H low + mov r23, r11 ; H high + 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) +ILI9341_FillRect_loopH: + mov r24, r8 ; W low + mov r25, r9 ; W high +ILI9341_FillRect_loopW: + mov r16, r19 + rcall SPIHW_MasterTransfer + mov r16, r18 + rcall SPIHW_MasterTransfer + sbiw r25:r24, 1 + brne ILI9341_FillRect_loopW + mov r24, r22 ; H low + mov r25, r23 ; H high + sbiw r25:r24, 1 ; dec + mov r22, r24 ; save in r23:r22 + mov r23, r25 + brne ILI9341_FillRect_loopH + sbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS high + rcall ili9341EndSpi + out SREG, r15 + pop r15 + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine ili9341BitBlit + +; @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) + +ili9341BitBlit: + 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 + mov r23, r11 + cbi SPIHW_SS_OUTPUT, SPIHW_SS_PIN ; SS low + sbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D high (DATA) +ili9341BitBlit_loopH: + mov r24, r8 + mov r25, r9 +ili9341BitBlit_loopW: + ld r18, X+ + ld r19, X+ + mov r16, r19 + rcall SPIHW_MasterTransfer ; (R16) + mov r16, r18 + rcall SPIHW_MasterTransfer ; (R16) + sbiw r25:r24, 1 + brne ili9341BitBlit_loopW + mov r24, r22 + mov r25, r23 + sbiw r25:r24, 1 + mov r22, r24 + mov r23, r25 + brne ili9341BitBlit_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, 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 ili9341_WriteCharacterX1At @@ -374,215 +603,96 @@ ili9341SetAddressWindow: ; @clobbers r16, r17, r18, r19, r24, r25, x, z ili9341_WriteCharacterX1At: + ; render character push xl push xh - rcall ili9341WriteCharacterFromFont8x8x1 ; (r17, r24, r25, x, z) + rcall ili9341WriteCharacterFromFont8x8 ; (r17, r24, r25, x, z) pop xh pop xl - ldi r17, 7 - ; calc X1 - mov r8, r4 - mov r9, r5 - add r8, r17 - adc r9, r17 - sub r9, r17 - ; calc Y1 - mov r10, r6 - mov r11, r7 - add r10, r17 - adc r11, r17 - sub r11, r17 - - rcall ili9341BeginSpi ; (r16, r17) - rcall ili9341SetAddressWindow ; (R16) - ldi r16, 8 ; increment X pos for next char - add r4, r16 - adc r5, r16 - sub r5, r16 + ; set width and height + ldi r16, 8 + mov r8, r16 + clr r9 + mov r10, r16 + clr r11 - ldi r16, ILI9341_CMD_RAMWR ; start writing ro RAM - rcall ili9341SendCommand - ldi r17, 64 ; 8x8 -ili9341_WriteCharacterX1At_loop: - ld r18, X+ - ld r19, X+ - rcall ili9341Send16BitData - dec r17 - brne ili9341_WriteCharacterX1At_loop - rcall ili9341EndSpi - ret + rjmp ili9341BitBlit ; @end + ; --------------------------------------------------------------------------- ; @routine ili9341_WriteCharacterX2At -; @param R16 character to write -; @param r5:r4 X -; @param r7:r6 Y -; @param r1:r0 background color -; @param r3:r2 foreground color -; @param Z pointer to font -; @param X pointer to RAM to store data to +; @param R16 character to write +; @param r5:r4 X +; @param r7:r6 Y +; @param r1:r0 background color +; @param r3:r2 foreground color +; @param Z pointer to font +; @param X pointer to RAM to store data to +; @return r5:r4 new X (advanced by character width) ; @clobbers r16, r17, r18, r19, r24, r25, x, z ili9341_WriteCharacterX2At: + ; render character push xl push xh - rcall ili9341WriteCharacterFromFont8x8x2 ; (r17, r24, r25, x, z) + rcall ili9341WriteCharacterFromFont8x8 ; (r17, r24, r25, x, z) pop xh pop xl - ldi r17, 15 - ; calc X1 - mov r8, r4 - mov r9, r5 - add r8, r17 - adc r9, r17 - sub r9, r17 - ; calc Y1 - mov r10, r6 - mov r11, r7 - add r10, r17 - adc r11, r17 - sub r11, r17 - - rcall ili9341BeginSpi ; (r16, r17) - rcall ili9341SetAddressWindow ; (R16) - ldi r16, 16 ; increment X pos for next char - add r4, r16 - adc r5, r16 - sub r5, r16 - ldi r16, ILI9341_CMD_RAMWR ; start writing ro RAM - rcall ili9341SendCommand - ldi r17, 0 ; 256 bytes -ili9341_WriteCharacterX2At_loop: - ld r18, X+ - ld r19, X+ - rcall ili9341Send16BitData - dec r17 - brne ili9341_WriteCharacterX2At_loop - rcall ili9341EndSpi - ret + ; set width and height + ldi r16, 8 + mov r8, r16 + clr r9 + mov r10, r8 + clr r11 + + rjmp ili9341BitBlitStretch2 ; @end ; --------------------------------------------------------------------------- -; @routine ili9341WriteCharacterFromFont8x8x1 +; @routine ili9341_WriteCharacterX4At -; @param R16 character to write -; @param R1:R0 background color -; @param R3:R2 foreground color -; @param Z pointer to font -; @param X pointer to RAM to store data to -; @clobbers r17, r24, r25, x, z +; @param R16 character to write +; @param r5:r4 X +; @param r7:r6 Y +; @param r1:r0 background color +; @param r3:r2 foreground color +; @param Z pointer to font +; @param X pointer to RAM to store data to +; @return r5:r4 new X (advanced by character width) +; @clobbers r16, r17, r18, r19, r24, r25, x, z -ili9341WriteCharacterFromFont8x8x1: - rcall ili9341GetCharPosInFont8x8 ; (r17, r24, r25, z) - ldi r25, 8 ; 8 bytes -ili9341WriteCharacterFromFont8x8x1_loop1: - ldi r24, 8 ; 8 bits - lpm r17, Z+ -ili9341WriteCharacterFromFont8x8x1_loop2: - lsr r17 - brcs ili9341WriteCharacterFromFont8x8x1_writeForeground - st X+, r0 - st X+, r1 - rjmp ili9341WriteCharacterFromFont8x8x1_loop2end -ili9341WriteCharacterFromFont8x8x1_writeForeground: - st X+, r2 - st X+, r3 -ili9341WriteCharacterFromFont8x8x1_loop2end: - dec r24 - brne ili9341WriteCharacterFromFont8x8x1_loop2 - dec r25 - brne ili9341WriteCharacterFromFont8x8x1_loop1 - ret +ili9341_WriteCharacterX4At: + ; render character + push xl + push xh + rcall ili9341WriteCharacterFromFont8x8 ; (r17, r24, r25, x, z) + pop xh + pop xl + + ; set width and height + ldi r16, 8 + mov r8, r16 + clr r9 + mov r10, r8 + clr r11 + + rjmp ili9341BitBlitStretch4 ; @end -; --------------------------------------------------------------------------- -; @routine ili9341WriteCharacterFromFont8x8x2 - -; @param R16 character to write -; @param R1:R0 background color -; @param R3:R2 foreground color -; @param Z pointer to font -; @param X pointer to RAM to store data to -; @clobbers r17, r22, r23, r24, r25, x, z - -ili9341WriteCharacterFromFont8x8x2: - rcall ili9341GetCharPosInFont8x8 ; (r17, r24, r25, z) - ldi r25, 8 ; 8 bytes -ili9341WriteCharacterFromFont8x8x2_loop1: - ldi r24, 8 ; 8 bits - lpm r17, Z+ -ili9341WriteCharacterFromFont8x8x2_loop2: - lsr r17 - brcs ili9341WriteCharacterFromFont8x8x2_writeForeground - mov r22, r0 - mov r23, r1 - rjmp ili9341WriteCharacterFromFont8x8x2_loop2end -ili9341WriteCharacterFromFont8x8x2_writeForeground: - mov r22, r2 - mov r23, r3 -ili9341WriteCharacterFromFont8x8x2_loop2end: - st X+, r22 - st X+, r23 - st X+, r22 - st X+, r23 - adiw xh:xl, 28 ; move to next row (8*4)-4 - st X+, r22 - st X+, r23 - st X+, r22 - st X+, r23 - sbiw xh:xl, 32 ; move back to previous row - dec r24 - brne ili9341WriteCharacterFromFont8x8x2_loop2 - adiw xh:xl, 32 ; skip next line (we already wrote it) - dec r25 - brne ili9341WriteCharacterFromFont8x8x2_loop1 - ret -; @end -; --------------------------------------------------------------------------- -; @routine ili9341GetCharPosInFont8x8 -; @param R16 character to write -; @param Z pointer to font -; @return Z pointer to begin of char data -; @clobbers r17, r24, r25, z - -ili9341GetCharPosInFont8x8: - mov r24, r16 - lpm r17, Z+ ; first char num - sub r24, r17 - brcc ili9341GetCharPosInFont8x8_firstValueOkay - adiw zh:zl, 1 ; use first char - ret -ili9341GetCharPosInFont8x8_firstValueOkay: - lpm r17, Z+ - cp r24, r17 - brcs ili9341WriteCharacterFromFont8x8_gotPos - ret -ili9341WriteCharacterFromFont8x8_gotPos: - clr r25 - lsl r24 ; R16x8 - rol r25 - lsl r24 - rol r25 - lsl r24 - rol r25 - add zl, r24 - adc zh, r25 - ret -; @end