; *************************************************************************** ; 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