; *************************************************************************** ; 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) M_SPIHW_MASTER_SEND_BYTE r16 ; mov r16, r17 ; rcall SPIHW_MasterTransfer ; (R16) M_SPIHW_MASTER_SEND_BYTE r17 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) M_SPIHW_MASTER_SEND_BYTE r16 ; mov r16, r17 ; rcall SPIHW_MasterTransfer ; (R16) M_SPIHW_MASTER_SEND_BYTE r17 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