Files
aqhomecontrol/avr/modules/lcd2/ili9341/main.asm
2025-11-07 17:04:08 +01:00

279 lines
6.5 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_MAIN_ASM
#define AQH_AVR_ILI9341_MAIN_ASM
; generally we use the following parameters here:
; @param r1:r0 background color
; @param r3:r2 foreground color
; @param r5:r4 X0
; @param r7:r6 Y0
; @param r9:r8 X1/W
; @param r11:r10 Y1/H
; @param r13:r12 source data width in bytes (for bit blit, i.e. byte offset from
; one source data line to the next)
; ***************************************************************************
; data
.dseg
;ILI9341_buffer: .byte 128
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine ILI9341_Init @global
ILI9341_Init:
rcall ILI9341IoInit
rcall ILI9341_Reset
rcall ILI9341_LeaveSleepMode
ldi r16, 0xff
rcall ILI9341_SetBacklight
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ILI9341_Fini @global
ILI9341_Fini:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ili9341_SendCommands
;
; @clobbers r16
; Z=byte pointer to command list (as for LPM)
ili9341SendCommands:
rcall ili9341BeginSpi ; (R16, R17)
ili9341SendCommands_loop1:
lpm r16, Z+ ; read command
lpm r18, Z+ ; read number of args
cpi r18, 0xff ; end?
breq ili9341SendCommands_end
rcall ili9341SendCommand
mov r19, r18
andi r19, 1 ; if 1: need to skip filler byte
tst r18
breq ili9341SendCommands_loop1 ; no args, next command
ili9341SendCommands_loop2:
lpm r16, Z+
rcall ili9341SendData ; (R16)
dec r18
brne ili9341SendCommands_loop2
add zl, r19 ; possibly skip filler byte
adc zh, r19
sub zh, r19
rjmp ili9341SendCommands_loop1
ili9341SendCommands_end:
rcall ili9341EndSpi ; (R16)
ret
; @end
; ---------------------------------------------------------------------------
; @routine ILI9341_Reset @global
; @clobbers (R22)
ILI9341_Reset:
cbi ILI9341_RESET_OUTPUT, ILI9341_RESET_PIN
ldi r16, 100
rcall Utils_WaitForMilliSecs
sbi ILI9341_RESET_OUTPUT, ILI9341_RESET_PIN
ldi r16, 50
rcall Utils_WaitForMilliSecs
ldi zl, LOW(ili9341InitCommands*2)
ldi zh, HIGH(ili9341InitCommands*2)
rcall ili9341SendCommands
ldi r16, 120
rcall Utils_WaitForMilliSecs
rcall ili9341BeginSpi
ldi r16, 0x29 ; display on
rcall ili9341SendCommand
rcall ili9341EndSpi
ldi r16, 120
rcall Utils_WaitForMilliSecs
ret
; @end
; ---------------------------------------------------------------------------
; @routine ILI9341_SetBacklight @global
;
; @param r16 0=off, on otherwise
; @clobbers r16, r17
ILI9341_SetBacklight:
tst r16
brne ILI9341_SetBacklight_on
cbi ILI9341_LED_OUTPUT, ILI9341_LED_PIN
ret
ILI9341_SetBacklight_on:
sbi ILI9341_LED_OUTPUT, ILI9341_LED_PIN
ret ; DEBUG
push r16
rcall ili9341BeginSpi
ldi r16, ILI9341_CMD_WRITECTLDISPLAY
rcall ili9341SendCommand
; ldi r16, 0b00100100
ldi r16, 0x24
rcall ili9341SendData
ldi r16, ILI9341_CMD_SETDSPBRIGHTNESS
rcall ili9341SendCommand
pop r16
rcall ili9341SendData
ldi r16, 0xbe
rcall ili9341SendCommand
ldi r16, 0x0f
rcall ili9341SendData
rcall ili9341EndSpi
ret
; @end
ILI9341_LeaveSleepMode:
rcall ili9341BeginSpi
ldi r16, 0x11 ; sleep out
rcall ili9341SendCommand
rcall ili9341EndSpi
ldi r16, 120
rcall Utils_WaitForMilliSecs
rcall ili9341BeginSpi
ldi r16, 0x38 ; idle mode off
rcall ili9341SendCommand
rcall ili9341EndSpi
rcall ili9341BeginSpi
ldi r16, 0x13 ; normal mode on
rcall ili9341SendCommand
rcall ili9341EndSpi
ret
; @end
ili9341InitCommands:
#if 1
; display off
.db 0x28, 0
; PowerCtlA
.db 0xcb, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, 0x00
; PowerCtlB
.db 0xcf, 3, 0x00, 0xC1, 0x30, 0x00
; DriverTimingCtlA
.db 0xe8, 3, 0x85, 0x00, 0x78, 0x00
; DriverTimingCtlB
.db 0xea, 2, 0x00, 0x00
; _PowerSeqCtl
.db 0xed, 4, 0x64, 0x03, 0x12, 0x81
; PumpRatioCtl
.db 0xf7, 1, 0x20, 0x00
; PowerCtl1
.db 0xc0, 1, 0x23, 0x00 ; lookup!
; PowerCtl2
.db 0xc1, 1, 0x10, 0x00 ; lookup!
; VomCtl1
.db 0xc5, 2, 0x3e, 0x28 ; lookup!
; VomCtl2
.db 0xc7, 1, 0x86, 0x00 ; lookup!
; ColMod
.db 0x3A, 1, 0x55, 0x00 ; DPI=16bits/pixel, DBI=16bits/pixel
; FrameRateCtl
.db 0xb1, 2, 0x00, ILI9341_FRAMERATE_79_HZ
; DspFnCtl
.db 0xb6, 3, 0x08, 0x82, 0x27, 0x00
; GammaCurve
.db 0x26, 1, 0x01, 0x00
; PosGamma
.db 0xe0, 15
.db 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1
.db 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, 0x00
; NegGamma
.db 0xe1, 15
.db 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1
.db 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, 0x00
; memory access control (use ILI9341_MADCTL_MV to flip X/Y)
; MMMMBM
; YXVLGH00
.db 0x36, 1, 0b11101000, 0x00
; normal mode on
; .db 0x13, 0
; end
.db 0xff, 0xff
#else
.db 0xef, 3, 0x03, 0x80, 0x02, 0x00
.db 0xcf, 3, 0x00, 0xc1, 0x30, 0x00
.db 0xed, 4, 0x64, 0x03, 0x12, 0x81
.db 0xe8, 3, 0x85, 0x00, 0x78, 0x00
.db 0xcb, 5, 0x39, 0x2c, 0x00, 0x34, 0x02, 0x00
.db 0xf7, 1, 0x20, 0x00
.db 0xea, 2, 0x00, 0x00
.db 0xc0, 1, 0x23, 0x00
.db 0xc1, 1, 0x10, 0x00
.db 0xc5, 2, 0x3e, 0x28
; .db 0xc7, 1, 0x86, 0x00
.db 0xc7, 1, 0xb7, 0x00
.db 0x36, 1, 0b11101000, 0x00
.db 0x3a, 1, 0x55, 0x00
.db 0xb1, 2, 0x00, ILI9341_FRAMERATE_100_HZ
.db 0xb6, 3, 0x08, 0x82, 0x27, 0x00
.db 0xf2, 1, 0x00, 0x00
.db 0x26, 1, 0x01, 0x00
.db 0xe0, 15, 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1
.db 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00, 0x00
.db 0xe1, 15, 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1
.db 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f, 0x00
; end
.db 0xff, 0xff
#endif ; AQH_AVR_ILI9341_MAIN_ASM