📄 lcd.asm
字号:
/* ***********************************************************************
**
** Copyright (C) 2002 Romuald Bialy (MIS) <romek_b@o2.pl>.
**
**
** Yampp-7/USB - low level support library.
** Nokia 6610 Color LCD driver
**
*************************************************************************
**
** This file is part of the yampp system by Jesper Hansen
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
*************************************************************************
**
** Revision History
**
** when what who why
**
** 2004-01-01 2.00 MIS initial public release for colour LCD
** 2004-01-07 2.01 MIS fixed support for national characters displaying
**
*********************************************************************** */
#define __ASSEMBLER__ 1
#define __SFR_OFFSET 0
#include <avr/io.h>
#define LCD_ASM
#include "lcd.h"
#define __tmp_reg__ r0
#define __zero_reg__ r1
.comm lcd_x,1
.comm lcd_y,1
.comm bkg_color,1
.comm text_color,1
.comm setcolmark,1
.text
.extern vs1001_init_io
.extern delay10
;************************************************
wrtab1: clr r24
wrl1: rcall lcd_wrdata
subi r24,lo8(-2)
cpi r24,8
brne wril2
inc r24
wril2: cpi r24,0x11
brne wrl1
ret
;************************************************
;LCD control routine
;void lcd_init(u08 mode)
.global lcd_init
lcd_init:
clr r24
sts bkg_color,r24
dec r24
sts text_color,r24
sbi PORTB,LCD_CS ;deselect Display
sbi DDRB,LCD_CS ;
call vs1001_init_io ;init SPI
cbi PORTB,LCD_CS ;select Display
#ifdef EPSON_LCD
ldi r24,LCD_CMD_PWRCTRL ;Power Control
rcall lcd_wrcmd
ldi r24,0x0F ;On all internal boosters and other power stages
rcall lcd_wrdata
#else
ldi r24,LCD_CMD_SWRESET ;Reset
rcall lcd_wrcmd
#endif
call delay100
ldi r24,LCD_CMD_SLEEPOUT ;Sleep_out
rcall lcd_wrcmd
ldi r24,LCD_CMD_DISPON ;display on
rcall lcd_wrcmd
ldi r24,LCD_CMD_BSTRON ;booster on
rcall lcd_wrcmd
call delay100
ldi r24,LCD_CMD_MADCTL ;Memory data acces control
rcall lcd_wrcmd
ldi r24,MADCTL_HORIZ ;X Mirror and BGR format (needed)
rcall lcd_wrdata
#ifdef EPSON_LCD
ldi r24,0x02 ;Colour mode (second data for MADCTRL)
rcall lcd_wrdata
ldi r24,0x01 ;Colour mode (second data for MADCTRL)
rcall lcd_wrdata
ldi r24,0xBB ;Display setup
rcall lcd_wrcmd
ldi r24,0x01 ;Normal mode
rcall lcd_wrdata
#else
ldi r24,LCD_CMD_COLMOD ;Colour mode
rcall lcd_wrcmd
ldi r24,0x02 ;256 colour mode select
rcall lcd_wrdata
#endif
ldi r24,LCD_CMD_INVON ;Non Invert mode
rcall lcd_wrcmd
ldi r24,LCD_CMD_RGBSET ;LUT write
rcall lcd_wrcmd
rcall wrtab1
rcall wrtab1
ldi r24,0x00
rcall lcd_wrdata
ldi r24,0x07
rcall lcd_wrdata
ldi r24,0x0B
rcall lcd_wrdata
ldi r24,0x0F
rcall lcd_wrdata
ldi r24,45
rcall lcd_contrast
;fall trough
;************************************************
;clear LCD
;void lcd_clrscr(void)
.global lcd_clrscr
lcd_clrscr: sts lcd_x,__zero_reg__
sts lcd_y,__zero_reg__
cbi PORTB,LCD_CS ;select Display
ser r24
ser r22
ldi r20,0x80
mov r18,r20
rcall lcd_window1
ldi r24,LCD_CMD_RAMWR ;write memory
rcall lcd_wrcmd
ldi r31, 0x42
ldi r30, 0x04
lds r24,bkg_color
LCD_CLEAR_1: rcall lcd_wrdata
sbiw r30,1
brne LCD_CLEAR_1
sbi PORTB,LCD_CS ;deselect Display
ret
;************************************************
;void lcd_off(void)
.global lcd_off
lcd_off: rcall lcd_clrscr
cbi PORTB,LCD_CS ;select Display
ldi r24,LCD_CMD_SLEEPIN ;Sleep_IN
rcall lcd_wrcmd
sbi PORTB,LCD_CS ;deselect Display
ret
;************************************************
;void lcd_color(u08 bkg, u08 text)
.global lcd_color
lcd_color: sts bkg_color,r24
sts text_color,r22
ret
;************************************************
; r24
;void lcd_contrast(u08 cont)
.global lcd_contrast
lcd_contrast: mov r25,r24
cbi PORTB,LCD_CS ;select Display
ldi r24,LCD_CMD_SETCON ;set contrast cmd.
rcall lcd_wrcmd
mov r24,r25 ;contrast value
subi r24,lo8(-10)
rcall lcd_wrdata
#ifdef EPSON_LCD
ldi r24,0x03 ;bias
rcall lcd_wrdata
#endif
sbi PORTB,LCD_CS ;deselect Display
ret
;************************************************
;display a bar
;Lenght(on display) is in r25 and value(how much is filled) in r24
;
; r25 r24 r23 r22
;void lcd_bar(u16 len:val, u16 bkgcol:fillcol)
.global lcd_bar
lcd_bar: mov r21,r24
cbi PORTB,LCD_CS ;select Display
ldi r24,LCD_CMD_MADCTL ;Memory data acces control
rcall lcd_wrcmd
ldi r24,MADCTL_VERT ;X Mirror + vertical addresing mode
rcall lcd_wrdata
#ifdef EPSON_LCD
ldi r24,0x02 ;Colour mode (second data for MADCTRL)
rcall lcd_wrdata
ldi r24,0x01 ;Colour mode (second data for MADCTRL)
rcall lcd_wrdata
#endif
push r22
lds r24,lcd_x
lds r22,lcd_y
mov r20,r24
add r20,r25
inc r20
mov r18,r22
subi r18,lo8(-13)
rcall lcd_window1 ;create window xlen = R25, ylen = 14
pop r22
ldi r24,LCD_CMD_RAMWR ;write memory command
rcall lcd_wrcmd
rcall send_begin
bar_lop: tst r21
brne bar_2
rcall send_empty
inc r21
rjmp bar_3
bar_2: rcall send_full
bar_3: dec r21
dec r25
brne bar_lop
rcall send_begin
ldi r24,LCD_CMD_MADCTL ;Memory data acces control
rcall lcd_wrcmd
ldi r24,MADCTL_HORIZ ;Return to horizontal addresing
rcall lcd_wrdata
#ifdef EPSON_LCD
ldi r24,0x02 ;Colour mode (second data for MADCTRL)
rcall lcd_wrdata
ldi r24,0x01 ;Colour mode (second data for MADCTRL)
rcall lcd_wrdata
#endif
sbi PORTB,LCD_CS ;deselect Display
ret
send_begin: ldi r20,14 ;send vertical line of bar
clr r24
sb1: rcall lcd_wrdata
dec r20
brne sb1
ret
send_full: rcall sf2 ;send full bar patterrn
mov r24,r23
rcall lcd_wrdata
rcall lcd_wrdata
ldi r20,8
mov r24,r22
sf1: rcall lcd_wrdata
dec r20
brne sf1
mov r24,r23
rcall lcd_wrdata
rcall lcd_wrdata
sf2: clr r24
rjmp lcd_wrdata
send_empty: rcall sf2 ;send empty bar patterrn
ldi r20,12
mov r24,r23
se1: rcall lcd_wrdata
dec r20
brne se1
rjmp sf2
;************************************************
; r24 r22
#ifndef EPSON_LCD
#define lcd_wind2 lcd_wind1
#endif
;void lcd_gotoxy(u08 x, u08 y) Assume as this display is used in 128x128 pixels mode
.global lcd_gotoxy
lcd_gotoxy:
sts lcd_x,r24
sts lcd_y,r22
ldi r20,0x81
mov r18,r20
; r24 r22 r20 r18
;void lcd_window(u08 xp, u08 yp, u08 xe, u08 ye)
.global lcd_window
lcd_window:
cbi PORTB,LCD_CS ;select Display
rcall lcd_window1
sbi PORTB,LCD_CS ;deselect Display
ret
lcd_window1: mov r1,r24
ldi r24,LCD_CMD_CASET ;set X
rcall lcd_wrcmd
mov r24,r1 ;xp
clr r1
rcall lcd_wind2
mov r24,r20 ;xe
rcall lcd_wind2
ldi r24,LCD_CMD_PASET ;set Y
rcall lcd_wrcmd
mov r24,r22 ;yp
rcall lcd_wind1
mov r24,r18 ;ye
lcd_wind1: subi r24,lo8(-2)
#ifdef EPSON_LCD
lcd_wind2: inc r24
#endif
rjmp lcd_wrdata
;************************************************
;void lcd_newline(void)
lcd_newline:
sts lcd_x,__zero_reg__ ; lcd_x = 0
lds r18,lcd_y ; lcd_y++
subi r18,lo8(-14)
cpi r18,126 ; Ymax
brsh lcd_nl2
sts lcd_y,r18
lcd_nl2: ret
;************************************************
;display a character
; r24
;void lcd_putchar(u08 data)
.global lcd_putchar
lcd_putchar:
cpi r24,'\n'
brne lcd_pc2
rjmp lcd_newline
lcd_pc2: cpi r24,'\r'
breq lcd_nl2
cpi r24,0xff ;test text color token
brne lcd_pc3
sts setcolmark,r24 ;mark that next byte is color code
ret
lcd_pc3: lds r25,setcolmark
tst r25
breq lcd_pc4
sts text_color,r24
sts setcolmark,__zero_reg__
ret
lcd_pc4: lds r25,lcd_x
cpi r25,124 ;Xmax
brsh lcd_nl2
;------------------------------
lcd_data: push r30
push r31
cbi PORTB,LCD_CS ;enable LCD
tst r24 ;test for code > 127
brmi NATCH ;go to national chars printing
LCD_SENDASC: subi r24,lo8(30) ;substract offset to first char
ldi r25,14 ;14 byte/char
mul r24,r25 ;compute character offset
ldi r30,lo8(ASCIITAB) ;set pointer to Ascii table
ldi r31,hi8(ASCIITAB)
add r30, r0
adc r31, r1
clr __zero_reg__
rcall DISPSET
LCD_CHAR_1: lpm r23,Z+ ;load byte from ASCII table
rcall SEND_LIN
brne LCD_CHAR_1 ;next byte
LCD_CHAR_2: sbi PORTB,LCD_CS ;disable LCD
lds r24,lcd_x ;update X position to next char
subi r24,lo8(-8)
sts lcd_x,r24
pop r31
pop r30
ret
;------------------------------
NATCH: mov r25,r24
clr r31
ldi r30,EEPROM_LANGTAB ;codes conversion table addres
NTABS: rcall get_eep1
tst r24
breq NTABNF ;test for 0 -> end of table -> print "_"
cp r24,r25 ;is this char ?
breq NATCH_F ;yes, display it
cpi r30,(EEPROM_LANGTAB+20) ;check for table end
brne NTABS ;next search
NTABNF: ldi r24,'_' ;end of table -> print "_"
rjmp LCD_SENDASC
NATCH_F: subi r30,(EEPROM_LANGTAB+1) ;substract chargen table base = char number
ldi r25,14 ;14 bytes per char
mul r30,r25
movw r30,r0
clr __zero_reg__
subi r30,lo8(-EEPROM_LANGCHARS) ;add character generator table offset
sbci r31,hi8(-EEPROM_LANGCHARS) ;add character generator table offset
rcall DISPSET
NAT_CHAR_1: rcall get_eep1 ;get byte from eeprom
mov r23,r24
rcall SEND_LIN ;Send over SPI
brne NAT_CHAR_1 ;next byte
rjmp LCD_CHAR_2
;------------------------------
DISPSET: ldi r24,LCD_CMD_CASET
rcall lcd_wrcmd
lds r24,lcd_x ;xp = lcd_x
rcall lcd_wind2
subi r24,lo8(-7) ;xe = lcd_x + 7
rcall lcd_wrdata
ldi r24,LCD_CMD_PASET
rcall lcd_wrcmd
lds r24,lcd_y ;yp = lcd_y
rcall lcd_wind1
subi r24,lo8(-13) ;ye = lcd_y + 13
rcall lcd_wrdata
ldi r24,LCD_CMD_RAMWR ;write memory command
rjmp lcd_wrcmd
;------------------------------
SEND_LIN: ldi r22,8
SL_2: lds r24,bkg_color ;send 8 bytes pixel data
rol r23
brcc SL_3
lds r24,text_color
SL_3: rcall lcd_wrdata ;Send over SPI
dec r22
brne SL_2
dec r25
ret
;------------------------------
get_eep1: out EEARH,r31
out EEARL,r30
sbi EECR,EERE ;eeprom read
in r24,EEDR ;get byte from eeprom
adiw r30,1 ;increament address
ret
;************************************************
;send an LCD command
.global lcd_wrcmd
lcd_wrcmd:
cbi SPCR,SPE ;disable SPI
cbi PORTB,PB5 ;clear MOSI
rjmp send_dc
;************************************************
;send LCD data
; r24
;void lcd_wrdata(u08 data)
.global lcd_wrdata
lcd_wrdata:
cbi SPCR,SPE ;disable SPI
sbi PORTB,PB5 ;set MOSI High
send_dc:
sbi PORTB,PB7 ;SCK Hi
cbi PORTB,PB7 ;SCK Lo
sbi SPCR,SPE ;enable SPI
;fall trough
;************************************************
;using the SPI for communication
SPI_SEND: out SPDR,r24 ;load byte in SPI data register
SPI_SEND_0: sbis SPSR,SPIF
rjmp SPI_SEND_0 ;transmitt byte to LCD
in r0,SPDR
ret
;************************************************
; r25/r24
;void lcd_puts(char *s)
.global lcd_puts
lcd_puts:
movw r30,r24
sbiw r30,0 ; test for zero
breq lcd_p3
lcd_p2:
ld r24,Z+
tst r24
breq lcd_p3
rcall lcd_putchar
rjmp lcd_p2
lcd_p3: ret
; r25/r24
;void lcd_progputs(char *s)
.global lcd_progputs
lcd_progputs:
movw r30,r24
sbiw r30,0 ; test for zero
breq lcd_p3
lcd_pp2:
lpm r24,Z
tst r24
breq lcd_p3
rcall lcd_putchar
adiw r30,1
rjmp lcd_pp2
;Ascii table for character definition
ASCIITAB:
#include "ascii.def"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -