LCD: Cleanup.

This commit is contained in:
Martin Preuss
2023-01-29 18:50:15 +01:00
parent adfbd73964
commit d560691a97

View File

@@ -1,5 +1,9 @@
; ***************************************************************************
; LCD module
; (c) 2023 Martin Preuss
;
; Some code in this module is based on C-code in Tiny4kOLED (https://github.com/datacute/Tiny4kOLED/tree/master/src)
; by Stephen Denne (MIT license), rewritten in AVR assembler
;
; - page 0 is top line, page 7 ist bottom line
; - column 0 is the leftmost colum, column 127 is the rightmost column
@@ -20,16 +24,13 @@
; ***************************************************************************
; defines
.equ LCD_CONTROLBYTE_DC_MASK = 0x40
.equ LCD_CONTROLBYTE_CO_MASK = 0x80
.equ LCD_TWI_ADDRESS = 0x3c
.equ LCD_WIDTH = 128
.equ LCD_HEIGHT = 64
.equ LCD_PAGE_COUNT = 8
.equ LCD_MULTIPLE = 2
.equ LCD_CMD_MODE = 0x00
.equ LCD_DATA_MODE = 0x40
@@ -53,10 +54,16 @@ lcdDataEnd:
LCD_Init:
sbi DDRA, PORTA2 ; debug
sbi PORTA, PORTA2 ; debug (off)
; ---------------------------------------------------------------------------
; LCD_Init
;
; IN:
; - nothing
; OUT:
; - CFLAG: set if okay, clear on error
; USED:
LCD_Init:
ldi zl, LOW(lcdInitCommandsBegin)
ldi zh, HIGH(lcdInitCommandsBegin)
ldi r16, 8
@@ -71,92 +78,50 @@ LCD_Init:
ldi r16, 0
rcall LCD_Fill
ldi r18, 0
ldi r18, 20
ldi r19, 0
rcall LCD_SetCursor
ldi zl, LOW(lcdHelloMsg1)
ldi zh, HIGH(lcdHelloMsg1)
ldi zl, LOW(lcdHelloMsg)
ldi zh, HIGH(lcdHelloMsg)
rcall LCD_PrintFromFlash
ldi r18, 0
ldi r19, 2
rcall LCD_SetCursor
ldi zl, LOW(lcdHelloMsg2)
ldi zh, HIGH(lcdHelloMsg2)
rcall LCD_PrintFromFlash
ldi r18, 0
ldi r19, 4
rcall LCD_SetCursor
ldi zl, LOW(lcdHelloMsg3)
ldi zh, HIGH(lcdHelloMsg3)
rcall LCD_PrintFromFlash
ldi r18, 10
ldi r19, 5
rcall LCD_SetCursor
ldi zl, LOW(lcdHelloMsg4)
ldi zh, HIGH(lcdHelloMsg4)
rcall LCD_PrintFromFlash
sec
ret
; ---------------------------------------------------------------------------
; LCD_Fini
;
; IN:
; - nothing
; OUT:
; - CFLAG: set if okay, clear on error
; USED:
; - R16: number of bytes to send
; - Z=pointer to data
lcdWriteCommandsFromFlash:
rcall twiStart
lsl zl
rol zh
mov r20, r16 ; number of bytes
ldi r16, (LCD_TWI_ADDRESS*2)
rcall twiSendByte
brcc lcdWriteCommandsFromFlash_error
tst r16
brne lcdWriteCommandsFromFlash_error
lcdWriteCommandsFromFlash_loop:
lpm r16, z+
rcall twiSendByte
brcc lcdWriteCommandsFromFlash_error
tst r16
brne lcdWriteCommandsFromFlash_error
dec r20
brne lcdWriteCommandsFromFlash_loop
rcall twiStop
sbi DDRA, PORTA2 ; debug
cbi PORTA, PORTA2 ; debug (on)
LCD_Fini:
sec
ret
lcdWriteCommandsFromFlash_error:
rcall twiStop
clc
ret
; ---------------------------------------------------------------------------
; LCD_SetCursor
;
; Set cursor.
; Set cursor. X is specified in pixels, Y is specified in character rows (8 pixels).
; Left upper corner is 0/0 (x/y), right lower corner is 127/7
;
; IN:
; - R18: X
; - R19: Y
; OUT:
; - nothing
; - CFLAG: set if okay, cleared otherwise
; REGS: r1, r2, r16 (R16, R17, R18, R22)
LCD_SetCursor:
in r15, SREG
cli
mov r1, r18
mov r2, r19
rcall twiStart ; (R22)
@@ -184,17 +149,31 @@ LCD_SetCursor:
brcc LCD_SetCursor_error
rcall twiStop ; (R22)
out SREG, r15
sec
ret
LCD_SetCursor_error:
rcall twiStop ; (R22)
out SREG, r15
clc
ret
; ---------------------------------------------------------------------------
; LCD_Fill
;
; Fill display RAM with the given value.
;
; IN:
; - R16: data to write
; OUT:
; - CFLAG: set if okay, cleared otherwise
; REGS: r15, r16, r18, r19, r20, r21 (r17, r22)
LCD_Fill:
in r15, SREG
cli
mov r20, r16
ldi r21, 0 ; Y
@@ -206,10 +185,10 @@ LCD_Fill_loopY:
rcall twiStart
ldi r16, (LCD_TWI_ADDRESS*2)
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
brcc LCD_Fill_error
ldi r16, LCD_DATA_MODE
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
brcc LCD_Fill_error
ldi r19, 0
@@ -225,14 +204,17 @@ LCD_Fill_loopX:
inc r21
cpi r21, LCD_PAGE_COUNT
brcs LCD_Fill_loopY
out SREG, r15
sec
ret
LCD_Fill_error:
rcall twiStop
out SREG, r15
clc
ret
; ---------------------------------------------------------------------------
; LCD_PrintFromFlash
;
@@ -242,8 +224,11 @@ LCD_Fill_error:
; - Z: position of string to print
; OUT:
; - CFLAG: set if okay, cleared otherwise
; REGS:
; REGS: r15, r16, Z (R17, R18, R22)
LCD_PrintFromFlash:
in r15, SREG
cli
lsl zl
rol zh
rcall twiStart
@@ -267,11 +252,13 @@ LCD_PrintFromFlash_loop:
rjmp LCD_PrintFromFlash_loop
LCD_PrintFromFlash_end:
rcall twiStop
out SREG, r15
sec
ret
LCD_PrintFromFlash_error:
rcall twiStop
out SREG, r15
clc
ret
@@ -285,8 +272,11 @@ LCD_PrintFromFlash_error:
; IN:
; - R16: char
; OUT:
; REGS: r16, r17, Z
; REGS: r15, r16, r17, Z
LCD_PrintChar:
in r15, SREG
cli
rcall twiStart
ldi r16, (LCD_TWI_ADDRESS*2)
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
@@ -298,10 +288,207 @@ LCD_PrintChar:
rcall lcdPrintOneChar
brcc LCD_PrintChar_error
rcall twiStop
out SREG, r15
sec
ret
LCD_PrintChar_error:
rcall twiStop
out SREG, r15
clc
ret
; ---------------------------------------------------------------------------
; LCD_PrintHexByte
;
; Convert a give byte into HEX and write it to the current position.
;
; IN:
; - R16: byte to convert to hex
; OUT:
; REGS: r15, r16, r17, Z
LCD_PrintHexByte:
in r15, SREG
cli
mov r20, r16
rcall twiStart
ldi r16, (LCD_TWI_ADDRESS*2)
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
brcc LCD_PrintHexByte_error
ldi r16, LCD_DATA_MODE
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
brcc LCD_PrintHexByte_error
mov r16, r20
rcall lcdPrintHexByte
brcc LCD_PrintHexByte_error
rcall twiStop
out SREG, r15
sec
ret
LCD_PrintHexByte_error:
rcall twiStop
out SREG, r15
clc
ret
; ---------------------------------------------------------------------------
; LCD_PrintHexWord
;
; Convert a give word into HEX and write it to the current position.
;
; IN:
; - r18: low byte of the word
; - r19: high byte of the word
; OUT:
; - CFLAG: set if okay, cleared otherwise
; REGS: r15, r16, r17, Z
LCD_PrintHexWord:
in r15, SREG
cli
push r18
push r19
rcall twiStart
ldi r16, (LCD_TWI_ADDRESS*2)
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
brcc LCD_PrintHexWord_error
ldi r16, LCD_DATA_MODE
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
brcc LCD_PrintHexWord_error
pop r19
pop r18
rcall lcdPrintHexWord
brcc LCD_PrintHexWord_error
rcall twiStop
out SREG, r15
sec
ret
LCD_PrintHexWord_error:
rcall twiStop
pop r19
pop r18
out SREG, r15
clc
ret
; ---------------------------------------------------------------------------
; lcdPrintHexWord
;
; Convert a give word into HEX and write it to the current position.
;
; IN:
; - r18: low byte of the word
; - r19: high byte of the word
; OUT:
; - CFLAG: set if okay, cleared otherwise
lcdPrintHexWord:
mov r16, r19
push r18
rcall lcdPrintHexByte
pop r18
brcc lcdPrintHexWord_error
mov r16, r18
rcall lcdPrintHexByte
brcc lcdPrintHexWord_error
sec
ret
lcdPrintHexWord_error:
clc
ret
; ---------------------------------------------------------------------------
; lcdPrintHexByte
;
; Convert a give byte into HEX and write it to the current position.
;
; IN:
; - R16: byte to convert to hex
; OUT:
; - CFLAG: set if okay, cleared otherwise
; REGS: r16, r20 (r16, r17)
lcdPrintHexByte:
mov r20, r16
swap r16
rcall lcdNibbleToAscii ; write high nibble (r16, r17)
rcall lcdPrintOneChar ; (r16, r17, Z)
brcc lcdPrintHexByte_error
mov r16, r20
rcall lcdNibbleToAscii ; write low nibble
rcall lcdPrintOneChar
brcc lcdPrintHexByte_error
sec
ret
lcdPrintHexByte_error:
clc
ret
; ---------------------------------------------------------------------------
; lcdNibbleToAscii
;
; Convert a nibble to an ASCII char.
; IN:
; - R16: byte (in bits 0-3)
; OUT:
; - R16: ASCII representation of that nibble (e.g. '0' for 0)
; REGS: r16, r17
lcdNibbleToAscii:
andi r16, 0xf
cpi r16, 10
brcs lcdNibbleToAscii_l1
ldi r17, 7
add r16, r17
lcdNibbleToAscii_l1:
ldi r17, '0'
add r16, r17
ret
; ---------------------------------------------------------------------------
; lcdWriteCommandsFromFlash
;
; IN:
; - R16: number of bytes to send
; - Z=pointer to data
; OUT:
; - CFLAG: set if okay, cleared otherwise
; REGS: r16, r20, Z (r17, r18, r22)
lcdWriteCommandsFromFlash:
rcall twiStart
lsl zl
rol zh
mov r20, r16 ; number of bytes
ldi r16, (LCD_TWI_ADDRESS*2)
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
brcc lcdWriteCommandsFromFlash_error
lcdWriteCommandsFromFlash_loop:
lpm r16, z+
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
brcc lcdWriteCommandsFromFlash_error
dec r20
brne lcdWriteCommandsFromFlash_loop
rcall twiStop ; (R22)
sec
ret
lcdWriteCommandsFromFlash_error:
rcall twiStop
clc
ret
@@ -316,10 +503,10 @@ LCD_PrintChar_error:
; IN:
; - R16: char
; OUT:
; REGS: r16, r17, Z
; REGS: r16, r19, Z (R17, R18, R22)
lcdPrintOneChar:
rcall lcdGetCharMatrix
rcall lcdGetCharMatrix ; (r16, r17, Z)
ldi r16, 0 ; spacing between chars
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
brcc lcdPrintOneChar_error
@@ -348,6 +535,7 @@ lcdPrintOneChar_error:
; OUT:
; - Z: pos of character matrix (ready for LPM)
; REGS: r16, r17, Z
lcdGetCharMatrix:
cpi r16, 95+32
brcc lcdGetCharMatrix_l1
@@ -378,17 +566,12 @@ lcdGetCharMatrix_l2:
lcdInitCommandsBegin: ; 28 bytes
.db LCD_CMD_MODE, 0xa8, ((LCD_PAGE_COUNT*8)-1), 0x8d, 0x14, 0xaf, 0xa1, 0xc8
lcdInitCommandsEnd:
.db 0xae, 0x00, 0x10, 0x40, 0x81, 0xcf, 0xa1, 0xc8
.db 0xa6, 0xa8, 0x3f, 0xd3, 0x00, 0xd5, 0x80, 0xd9
.db 0xf1, 0xda, 0x12, 0xdb, 0x40, 0x20, 0x02, 0x8d
.db 0x14, 0xa4, 0xa6, 0xaf
lcdHelloMsg1: .db "ILD :-)", 0
;lcdHelloMsg2: .db "1234567890ABCDEFGH", 0, 0
lcdHelloMsg2: .db "ICH LIEBE DICH!", 0
lcdHelloMsg3: .db "abcdefghijklmnopqr", 0, 0
lcdHelloMsg4: .db "abcde", 0
lcdHelloMsg: .db "AqHOME 2023", 0
; font taken from Tiny4kOLED (https://github.com/datacute/Tiny4kOLED/tree/master/src) by Stephen Denne (MIT license),
; original by Neven Boyanov
lcdFont6x8:
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; 0
.db 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 ; ! 1