;**** includes **** 
.include "2313def.inc"

;*****************************
;* レジスタ変数　設定 *
;*****************************

.def	temp1	= r20
.def	temp2	= r21
.def	temp3	= r22
.def	temp4	= r23
.def	lcd_data= r24

;*****************************
;*　 ビット　設定　　*
;*****************************

;**  PORTB  ***


;.equ		= 0
.equ	lcd_rs	= 1
.equ	lcd_rw	= 2
.equ	lcd_enb	= 3
.equ	lcd_db4 = 4
.equ	lcd_db5 = 5
.equ	lcd_db6 = 6
.equ	lcd_db7 = 7


		
;*********************
;* 割込みベクター *
;*********************

.cseg

	rjmp	start		; Reset Handle




;*********************
;* メイン プログラム *
;*********************
start:

	ldi	temp1,low(RAMEND)
	out	SPL,temp1

	

	ldi	temp1,0xff
	out	DDRB,temp1	; pb0~7 out port
	ldi	temp1,0x00	; pb0~7 clear	
	out	PORTB,temp1	


; LCD - Initialize LCD controller

lcd_init:
	ldi		temp1,15	; wait for 15+ms
	rcall	wait_ms		; /
	rcall	lcd_int		; /
	ldi		temp1,5		; Wait for 4.1ms+
	rcall	wait_ms		; /
	rcall	lcd_int		; /
	ldi		temp1,100 	;wait for 100us+
	rcall	wait_us		; /
	rcall	lcd_int		; /

	ldi		lcd_data,0x20
	rcall	lcd_cmd
	ldi		temp1,100 		;wait for 100us+
	rcall	wait_us			; /
	ldi		lcd_data,0x28	; Data=4bit, Line=2, Font=5x7
	rcall	lcd_cmd			; /
	ldi		lcd_data,0x0c	; Display=ON, Cursor=OFF, Blink=OFF
	rcall	lcd_cmd			; /
	ldi		lcd_data,6		; Increment, No shift
	rcall	lcd_cmd			; /
	ldi		lcd_data,1		; clear ,homepos
	rcall	lcd_cmd

	ldi		lcd_data,0x80
 	rcall	lcd_cmd


	ldi		r16,0x30
lt:
	mov		lcd_data,r16
	rcall	lcd_dsp
	ldi		temp1,250
	rcall	wait_ms
	ldi		temp1,150
	rcall	wait_ms
	inc		r16
	cpi		r16,0x37
	brne	lt
	
	ldi		lcd_data,0xc0
 	rcall	lcd_cmd
	ldi		r16,0x41
lt1:
	mov		lcd_data,r16
	rcall	lcd_dsp
	ldi		temp1,250
	rcall	wait_ms
	ldi		temp1,150
	rcall	wait_ms
	inc		r16
	cpi		r16,0x48
	brne	lt1
main:

	
	rjmp	main
TIM1_OVF:
	reti	
	
;****************************

;-----------------------------------------------;
; LCD - Send a data/cmd into LCD
	;PORTB   7   6   5   4   3   2    1   0
	;write   <-data(H/L)->  enb r/w  rs   0
	;read   BF / address                  -
lcd_int:	; Internal reset
	ldi		lcd_data,0x30	; RS = "L",RW = "L",E = "L",data='0011'
	out		PORTB,lcd_data	
	sbi		PORTB,lcd_enb	; E = "H"
	nop						; I/O delay
	nop						; I/O delay
	nop						; I/O delay
	cbi		PORTB,lcd_enb	; E = "L"
	ret

lcd_dsp:
	rcall	lcd_bfch
	ldi		temp3,2			; RS = "H",RW = "L",E = "L",data='xxxx'
	rjmp	lcd_cmd1
lcd_cmd:
	rcall	lcd_bfch
	ldi		temp3,0			; RS = "L",RW = "L",E = "L",data='xxxx'
lcd_cmd1:
	mov		temp2,lcd_data
	swap	temp2
	andi	temp2,0xf0		;data_L save

	andi	lcd_data,0xf0   ;data_H set
	or		lcd_data,temp3
	out		PORTB,lcd_data	; PORTB = data_H,RS,RW
	sbi		PORTB,lcd_enb	; E = "H"
	mov		lcd_data,temp2	; 
	or		lcd_data,temp3	;data_L set
	nop						
	cbi		PORTB,lcd_enb	; E = "L"
	nop						; I/O delay				
	out		PORTB,lcd_data	; PORTB = data_L,RS,RW
					
	sbi		PORTB,lcd_enb	; E = "H"
	nop						; I/O delay
	nop						; I/O delay
	nop						; I/O delay
	cbi		PORTB,lcd_enb	; E = "L"
	ret

lcd_bfch:
	cbi		DDRB,lcd_db7	; lcd_db7 = INPUT
	sbi		PORTB,lcd_db7	; pullup
	sbi		PORTB,lcd_rw	; RW = "H"
	cbi		PORTB,lcd_rs	; RS = "L"
lcd_bfch1:
	sbi		PORTB,lcd_enb	; E = "H"
	nop						; I/O delay
	nop						; I/O delay
	in		temp1,PINB
	cbi		PORTB,lcd_enb	; E = "L"
	nop
	nop
	sbi		PORTB,lcd_enb	; E = "H"
	nop						; I/O delay
	nop						; I/O delay
	in		temp2,PINB
	cbi		PORTB,lcd_enb	; E = "L"

	andi	temp1,0x80		; Wait until busy flag becomes zero.
	brne	lcd_bfch1
	sbi		DDRB,lcd_db7	; lcd_db7 = OUTPUT
	cbi		PORTB,lcd_db7	; clear
	ret

wait_us:	;base 4.194MHz	
				;temp1　us (4clocks)
	nop			; 1clocks
	nop			; 1clocks	
	dec		temp1	; 1clocks
	brne	wait_us		; 2clocks
	ret			; 

wait_ms:
						;temp1　ms
	ldi		temp2,66   ;64*66=4195clocks

wait_ms_01:
	ldi		temp3,15    ;1clocks  4*(15+1)=64
wait_ms_02:
	nop					; 1clocks
	dec		temp3		; 1clocks
	brne	wait_ms_02	; 2clocks

	dec		temp2		; 1clocks
	brne	wait_ms_01	; 2clocks

	dec		temp1		; 1clocks	
	brne	wait_ms		; 2clocks
	ret
