; ; - 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 .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 ; *************************************************************************** ; data .dseg lcdDataBegin: lcdDataEnd: ; *************************************************************************** ; code .cseg LCD_Init: sbi DDRA, PORTA2 ; debug sbi PORTA, PORTA2 ; debug (off) ldi zl, LOW(lcdInitCommandsBegin) ldi zh, HIGH(lcdInitCommandsBegin) 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 ; - 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) sec ret lcdWriteCommandsFromFlash_error: rcall twiStop clc ret ; --------------------------------------------------------------------------- ; 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 ldi r21, 0 ; Y LCD_Fill_loopY: clr r18 mov r19, r21 rcall LCD_SetCursor brcc LCD_Fill_error rcall twiStart ldi r16, (LCD_TWI_ADDRESS*2) rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_Fill_error ldi r16, LCD_DATA_MODE rcall twiSendByteExpectAck ; (R16, R17, R18, R22) brcc LCD_Fill_error ldi r19, 0 LCD_Fill_loopX: mov r16, r20 rcall twiSendByteExpectAck ; (R16, R17, R18, R22) rcall twiSendByte brcc LCD_Fill_error inc r19 cpi r19, LCD_WIDTH brcs LCD_Fill_loopX rcall twiStop inc r21 cpi r21, LCD_PAGE_COUNT brcs LCD_Fill_loopY sec ret LCD_Fill_error: rcall twiStop clc 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 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