From ff8db6a210f4eb3aabb1b20b8eef97be989973c0 Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Sun, 29 Jan 2023 15:47:12 +0100 Subject: [PATCH] LCD: Completed, works now. --- avr/lcd.asm | 399 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 370 insertions(+), 29 deletions(-) diff --git a/avr/lcd.asm b/avr/lcd.asm index 3febb52..35e8f97 100644 --- a/avr/lcd.asm +++ b/avr/lcd.asm @@ -1,4 +1,22 @@ + +; +; - page 0 is top line, page 7 ist bottom line +; - column 0 is the leftmost colum, column 127 is the rightmost column +; - a page has a height of 8 (->8 bits) +; - when writing a byte to a position (e.g. page 0, column 0) +; - writing to chip RAM is done in columns +; +; Page 0: col 0 col 1 ... col 127 +; Row 0(LSB) 0/0 1/0 ... 127/0 +; Row 1 0/1 1/1 ... 127/1 +; Row 2 0/2 1/2 ... 127/2 +; Row 3 0/3 1/3 ... 127/3 +; ... +; Row 7(MSB) 0/7 1/7 ... 127/7 +; and so one + + ; *************************************************************************** ; defines @@ -10,6 +28,11 @@ .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 + ; *************************************************************************** @@ -36,12 +59,51 @@ LCD_Init: ldi zl, LOW(lcdInitCommandsBegin) ldi zh, HIGH(lcdInitCommandsBegin) - ldi r16, (lcdInitCommandsEnd-lcdInitCommandsBegin)*2 + ldi r16, 8 rcall lcdWriteCommandsFromFlash ldi r16, 0 rcall LCD_Fill + ldi r16, 255 + rcall LCD_Fill + + ldi r16, 0 + rcall LCD_Fill + + ldi r18, 0 + ldi r19, 0 + rcall LCD_SetCursor + + ldi zl, LOW(lcdHelloMsg1) + ldi zh, HIGH(lcdHelloMsg1) + 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 @@ -82,53 +144,87 @@ lcdWriteCommandsFromFlash_error: +; --------------------------------------------------------------------------- +; LCD_SetCursor +; +; Set cursor. +; +; IN: +; - R18: X +; - R19: Y +; OUT: +; - nothing +; REGS: r1, r2, r16 (R16, R17, R18, R22) + +LCD_SetCursor: + mov r1, r18 + mov r2, r19 + rcall twiStart ; (R22) + ldi r16, (LCD_TWI_ADDRESS*2) + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) + brcc LCD_SetCursor_error + + ldi r16, LCD_CMD_MODE + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) + brcc LCD_SetCursor_error + mov r16, r2 + andi r16, 0x07 + ori r16, 0xb0 + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) + brcc LCD_SetCursor_error + mov r16, r1 + andi r16, 0x0f + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) + brcc LCD_SetCursor_error + mov r16, r1 + andi r16, 0xf0 + swap r16 + ori r16, 0x10 + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) + brcc LCD_SetCursor_error + + rcall twiStop ; (R22) + sec + ret +LCD_SetCursor_error: + rcall twiStop ; (R22) + clc + ret + + + ; - R16: data to write LCD_Fill: mov r20, r16 - rcall twiStart - - ldi r16, (LCD_TWI_ADDRESS*2) - rcall twiSendByte - brcc LCD_Fill_error - tst r16 - brne LCD_Fill_error - ldi r21, 0 ; Y LCD_Fill_loopY: - ldi r16, 0xb0 ; set page address (data byte and next control byte follow, data byte is a command) - add r16, r21 - rcall twiSendByte + clr r18 + mov r19, r21 + rcall LCD_SetCursor brcc LCD_Fill_error - tst r16 - brne LCD_Fill_error - ldi r16, 0x01 ; set lower column address - rcall twiSendByte + + rcall twiStart + ldi r16, (LCD_TWI_ADDRESS*2) + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_Fill_error - tst r16 - brne LCD_Fill_error - - ldi r16, 0x10 ; set higher column bits - rcall twiSendByte + ldi r16, LCD_DATA_MODE + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_Fill_error - tst r16 - brne LCD_Fill_error ldi r19, 0 LCD_Fill_loopX: mov r16, r20 + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) rcall twiSendByte brcc LCD_Fill_error - tst r16 - brne LCD_Fill_error inc r19 cpi r19, LCD_WIDTH brcs LCD_Fill_loopX - + rcall twiStop inc r21 - cpi r21, 8 + cpi r21, LCD_PAGE_COUNT brcs LCD_Fill_loopY - rcall twiStop sec ret LCD_Fill_error: @@ -137,13 +233,258 @@ LCD_Fill_error: ret +; --------------------------------------------------------------------------- +; LCD_PrintFromFlash +; +; Print a string from flash at the current position. +; +; IN: +; - Z: position of string to print +; OUT: +; - CFLAG: set if okay, cleared otherwise +; REGS: +LCD_PrintFromFlash: + lsl zl + rol zh + rcall twiStart + ldi r16, (LCD_TWI_ADDRESS*2) + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) + brcc LCD_PrintFromFlash_error + ldi r16, LCD_DATA_MODE + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) + brcc LCD_PrintFromFlash_error + +LCD_PrintFromFlash_loop: + lpm r16, z+ + tst r16 + breq LCD_PrintFromFlash_end + push zh + push zl + rcall lcdPrintOneChar + pop zl + pop zh + brcc LCD_PrintFromFlash_error + rjmp LCD_PrintFromFlash_loop +LCD_PrintFromFlash_end: + rcall twiStop + sec + ret + +LCD_PrintFromFlash_error: + rcall twiStop + clc + ret + + + +; --------------------------------------------------------------------------- +; LCD_PrintChar +; +; Print a character at the current position. +; +; IN: +; - R16: char +; OUT: +; REGS: r16, r17, Z +LCD_PrintChar: + rcall twiStart + ldi r16, (LCD_TWI_ADDRESS*2) + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) + brcc LCD_PrintChar_error + ldi r16, LCD_DATA_MODE + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) + brcc LCD_PrintChar_error + + rcall lcdPrintOneChar + brcc LCD_PrintChar_error + rcall twiStop + sec + ret + +LCD_PrintChar_error: + rcall twiStop + clc + ret + + + +; --------------------------------------------------------------------------- +; lcdPrintOneChar +; +; Print a character at the current position. +; +; IN: +; - R16: char +; OUT: +; REGS: r16, r17, Z + +lcdPrintOneChar: + rcall lcdGetCharMatrix + ldi r16, 0 ; spacing between chars + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) + brcc lcdPrintOneChar_error + ldi r19, 6 +lcdPrintOneChar_loop: + lpm r16, z+ + rcall twiSendByteExpectAck ; (R16, R17, R18, R22) + brcc lcdPrintOneChar_error + dec r19 + brne lcdPrintOneChar_loop + sec + ret + +lcdPrintOneChar_error: + clc + ret + + +; --------------------------------------------------------------------------- +; lcdGetCharMatrix +; +; Get pointer to matrix of given char. +; +; IN: +; - R16: char +; OUT: +; - Z: pos of character matrix (ready for LPM) +; REGS: r16, r17, Z +lcdGetCharMatrix: + cpi r16, 95+32 + brcc lcdGetCharMatrix_l1 + cpi r16, 32 + brcc lcdGetCharMatrix_l2 +lcdGetCharMatrix_l1: + ldi r16, 32 +lcdGetCharMatrix_l2: + ldi r17, 32 + sub r16, r17 + mov zl, r16 + clr zh + clr r17 + lsl zl ; *2 + rol zh + add zl, r16 ; *3 + adc zh, r17 + lsl zl ; *6 + rol zh + ldi r16, LOW(lcdFont6x8*2) + ldi r17, HIGH(lcdFont6x8*2) + add zl, r16 + adc zh, r17 + ret + 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 -lcdInitCommandsEnd: + +lcdHelloMsg1: .db "ILD :-)", 0 +;lcdHelloMsg2: .db "1234567890ABCDEFGH", 0, 0 +lcdHelloMsg2: .db "ICH LIEBE DICH!", 0 +lcdHelloMsg3: .db "abcdefghijklmnopqr", 0, 0 +lcdHelloMsg4: .db "abcde", 0 + +lcdFont6x8: + .db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; 0 + .db 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 ; ! 1 + .db 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 ; " 2 + .db 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 ; # 3 + .db 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 ; $ 4 + .db 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 ; % 5 + .db 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 ; & 6 + .db 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 ; ' 7 + .db 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 ; ( 8 + .db 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 ; ) 9 + .db 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 ; * 10 + .db 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 ; + 11 + .db 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 ; , 12 + .db 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 ; - 13 + .db 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 ; . 14 + .db 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 ; / 15 + .db 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E ; 0 16 + .db 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 ; 1 17 + .db 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 ; 2 18 + .db 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 ; 3 19 + .db 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 ; 4 20 + .db 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 ; 5 21 + .db 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 ; 6 22 + .db 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 ; 7 23 + .db 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 ; 8 24 + .db 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E ; 9 25 + .db 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 ; : 26 + .db 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 ; ; 27 + .db 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 ; < 28 + .db 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 ; = 29 + .db 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 ; > 30 + .db 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 ; ? 31 + .db 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E ; @ 32 + .db 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C ; A 33 + .db 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 ; B 34 + .db 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 ; C 35 + .db 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C ; D 36 + .db 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 ; E 37 + .db 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 ; F 38 + .db 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A ; G 39 + .db 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F ; H 40 + .db 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 ; I 41 + .db 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 ; J 42 + .db 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 ; K 43 + .db 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 ; L 44 + .db 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F ; M 45 + .db 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F ; N 46 + .db 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E ; O 47 + .db 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 ; P 48 + .db 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E ; Q 49 + .db 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 ; R 50 + .db 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 ; S 51 + .db 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 ; T 52 + .db 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F ; U 53 + .db 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F ; V 54 + .db 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F ; W 55 + .db 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 ; X 56 + .db 0x00, 0x07, 0x08, 0x70, 0x08, 0x07 ; Y 57 + .db 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 ; Z 58 + .db 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 ; [ 59 + .db 0x00, 0x02, 0x04, 0x08, 0x10, 0x20 ; \ 60 + .db 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 ; ] 61 + .db 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 ; ^ 62 + .db 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 ; _ 63 + .db 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 ; ' 64 + .db 0x00, 0x20, 0x54, 0x54, 0x54, 0x78 ; a 65 + .db 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38 ; b 66 + .db 0x00, 0x38, 0x44, 0x44, 0x44, 0x20 ; c 67 + .db 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F ; d 68 + .db 0x00, 0x38, 0x54, 0x54, 0x54, 0x18 ; e 69 + .db 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02 ; f 70 + .db 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C ; g 71 + .db 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78 ; h 72 + .db 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00 ; i 73 + .db 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00 ; j 74 + .db 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00 ; k 75 + .db 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00 ; l 76 + .db 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78 ; m 77 + .db 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78 ; n 78 + .db 0x00, 0x38, 0x44, 0x44, 0x44, 0x38 ; o 79 + .db 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18 ; p 80 + .db 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC ; q 81 + .db 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08 ; r 82 + .db 0x00, 0x48, 0x54, 0x54, 0x54, 0x20 ; s 83 + .db 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20 ; t 84 + .db 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C ; u 85 + .db 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C ; v 86 + .db 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C ; w 87 + .db 0x00, 0x44, 0x28, 0x10, 0x28, 0x44 ; x 88 + .db 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C ; y 89 + .db 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44 ; z 90 + .db 0x00, 0x08, 0x36, 0x41, 0x41, 0x00 ; { 91 + .db 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00 ; | 92 + .db 0x00, 0x00, 0x41, 0x41, 0x36, 0x08 ; } 93 + .db 0x00, 0x08, 0x04, 0x08, 0x10, 0x08 ; ~ 94 +