;**** includes **** 
.include "m8def.inc"

; Load immediate word into the resister pair.
;
;	ldiw	Z,var
.macro	ldiw
	ldi	@0L,low(@1)
	ldi	@0H,high(@1)
.endm
; Output immediate
;
;	outi	port,var
.macro	outi
	ldi	r16,@1
	out	@0,r16
.endm
.MACRO cpi16	;cpi16	ra,rb,0xHHHH	;ra:rb-0xHHHH	set flags:N,C,Z
		push	@0
		push	@1
		subi	@1,low(@2)
		sbci	@0,high(@2)
		pop	@1
		pop	@0
.ENDMACRO

;*****************************
;* レジスタ変数　設定 *
;*****************************

.def	temp1	= r16
.def	temp2	= r17
.def	temp3	= r18
.def	temp4	= r19
.def	lcd_data= r20
.def	CL	= r24
.def	CH	= r25

;*****************************
;*　 ビット　設定　　*
;*****************************

;**  PORTB  ***
.equ	lcd_rs	= 5	
.equ	sf	= 4

;**  PORTD  **

.equ	lcd_rw	= 2
.equ	lcd_enb	= 3
.equ	lcd_db4 = 4
.equ	lcd_db5 = 5
.equ	lcd_db6 = 6
.equ	lcd_db7 = 7


	
;*********************
;* 割込みベクター *
;*********************
.dseg

	d_dat:	.byte	1000	;データ保存


.cseg


	RJMP start ;各種ﾘｾｯﾄ
	reti	;RJMP EXT_INT0 ;外部割り込み要求0
	reti	;EXT_INT1 ;外部割り込み要求1
	reti	;TIM2_COMP ;ﾀｲﾏ/ｶｳﾝﾀ2 比較一致
	reti	;TIM2_OVF ;ﾀｲﾏ/ｶｳﾝﾀ2 ｵｰﾊﾞｰﾌﾛｰ
	reti	;TIM1_CAPT ;ﾀｲﾏ/ｶｳﾝﾀ1 ｷｬﾌﾟﾁｬ発生
	rjmp	TIM1_COMPA ;ﾀｲﾏ/ｶｳﾝﾀ1 比較A 一致
	reti	;TIM1_COMPB ;ﾀｲﾏ/ｶｳﾝﾀ1 比較B 一致
	reti	;TIM1_OVF ;ﾀｲﾏ/ｶｳﾝﾀ1 ｵｰﾊﾞｰﾌﾛｰ
	reti	;TIM0_OVF ;ﾀｲﾏ/ｶｳﾝﾀ0 ｵｰﾊﾞｰﾌﾛｰ
	reti	;SPI_STC ;SPI 転送完了
	reti	;USART_RXC ;USART 受信完了
	reti	;USART_DRE ;USART 送信ﾊﾞｯﾌｧ空
	reti	;USART_TXC ;USART 送信完了
	reti	;ADC_E ;ADC 変換完了
	reti	;EE_RDY ;EEPROM 操作可
	reti	; ANA_COMP ;ｱﾅﾛｸﾞ ｺﾝﾊﾟﾚｰﾀ出力遷移
	reti	;TWSI ;2 線式ｼﾘｱﾙ ｲﾝﾀｰﾌｪｰｽ状態変化
	reti	;SPM_RDY ;SPM 命令操作可


;*********************
;* メイン プログラム *
;*********************
start:

	ldi	temp1,low(RAMEND)
	out	SPL,temp1
	ldi	temp1,high(RAMEND)
	out	SPH,temp1	;init Stack Pointer 
	

	ldi	temp1,0xff
	out	DDRD,temp1	; pd0~7 out port
	ldi	temp1,0x00	; pd0~7 clear	
	out	PORTD,temp1	

	ldi	temp1,0xff
	out	DDRB,temp1	; pb0~7 out port
	ldi	temp1,0x00	; pb0~7 clear	
	out	PORTB,temp1	



USATR_int:
	outi	UBRRH,0				;12.8MHz/[(20+1)x16]-->38.4kHz
	outi	UBRRL,6				;12.8MHz/[(6+1)x16]-->115.2kHz
	outi	UCSRB,(1<<RXEN)|(1<<TXEN)	;RXEN：受信許可、TXEN：送信許可
;	outi	UCSRC,(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0) ;data 8bit

; 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


ADC_int:
	outi	ADMUX,1<<REFS0				;基準電圧VCC、結果右揃え、Ch0選択
	outi	ADCSR,(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)	;ADC on,ADCck=12.8M/64=200k
time1_int:
	outi	TCCR1A,0		;CTC動作
	outi	TIMSK,1<<OCIE1A		;比較一致割込A使用
	outi	TCNT1H,0		;カウンタクリア
	outi	TCNT1L,0

main0:


	ldi	lcd_data,0x84
 	rcall	lcd_cmd
	ldi	lcd_data,'R'
	rcall	lcd_dsp
	ldi	lcd_data,'e'
	rcall	lcd_dsp
	ldi	lcd_data,'a'
	rcall	lcd_dsp
	ldi	lcd_data,'d'
	rcall	lcd_dsp
	ldi	lcd_data,'y'
	rcall	lcd_dsp

wait_rx:

;割込み周期読込
	rcall	Rx		;load high
	mov	r17,r16
	rcall	Rx		;load low
	out	OCR1AH,r17	;12.8M/r17:r16
	out	OCR1AL,r16	;

	ldi	lcd_data,0x84
 	rcall	lcd_cmd
	ldi	lcd_data,'S'
	rcall	lcd_dsp
	ldi	lcd_data,'t'
	rcall	lcd_dsp
	ldi	lcd_data,'a'
	rcall	lcd_dsp
	ldi	lcd_data,'r'
	rcall	lcd_dsp
	ldi	lcd_data,'t'
	rcall	lcd_dsp
	outi	TCCR1B,(1<<WGM12)|(1<<CS10)	;ckT1=CK
	ldiw	Z,d_dat
	ldiw	C,0
	sei

main:
	tst	CH
	brmi	s_data
	rjmp	main

s_data:
	ldiw	C,0
	ldiw	Z,d_dat
s_data1:
	ld	r16,Z+
	rcall	Tx
	adiw	CL,1
	cpi16	CH,CL,1000
	brne	s_data1
	rjmp	main0

TIM1_COMPA:
	in	r15,SREG
	sbi	PORTB,sf

	sbi     ADCSR,ADIF	; Reset interrupt flag
 	sbi	ADCSR,ADSC      ; Start A/D conversion
ready:	
 	sbis	ADCSR,ADIF
 	rjmp	ready
	in	r17,ADCL	
	in	r16,ADCH
	st	Z+,r16
	st	Z+,r17
	adiw	CL,1
	cpi16	CH,CL,500
	brne	COMPA_E
	outi	TCCR1B,0	;カウンタ１停止
	ldi	CH,0x80
COMPA_E:
	cbi	PORTB,sf
	out	SREG,r15
	reti

Tx:
	SBIS UCSRA,UDRE 	;送信ﾊﾞｯﾌｧ空きでｽｷｯﾌﾟ
	RJMP Tx 		;送信ﾊﾞｯﾌｧ空き待機
	OUT UDR,R16 		;ﾃﾞｰﾀ送信(送信開始)
	RET 			;呼び出し元へ復帰

Rx:
	SBIS UCSRA,RXC 		;受信完了でｽｷｯﾌﾟ
	RJMP Rx 		;受信完了待機
	IN R16,UDR 		;受信ﾃﾞｰﾀ取得
	RET			;呼び出し元へ復帰
;****************************



;-----------------------------------------------;
; LCD - Send a data/cmd into LCD
	;PORTD   7   6   5   4   3   2    1   0
	;write   <-data(H/L)->  enb r/w   -   -
	;read   BF / address   
 	;PORTB 0:R/S               -
lcd_int:	; Internal reset
	ldi	lcd_data,0x30	; data='0011',RW = "L",E = "L"
	out	PORTD,lcd_data	
	cbi	PORTB,lcd_rs	; RS = "L"
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	nop			; I/O delay
	cbi	PORTD,lcd_enb	; E = "L"
	ret

lcd_dsp:
	rcall	lcd_bfch
	sbi	PORTB,lcd_rs	; RS = "H"
	ldi	temp3,0		; RW = "L",E = "L",data='xxxx'
	rjmp	lcd_cmd1
lcd_cmd:
	rcall	lcd_bfch
	cbi	PORTB,lcd_rs	; RS = "L"
	ldi	temp3,0		; 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	PORTD,lcd_data	; PORTD = data_H,RW
	sbi	PORTD,lcd_enb	; E = "H"
	mov	lcd_data,temp2	; 
	or	lcd_data,temp3	;data_L set
	nop					
	cbi	PORTD,lcd_enb	; E = "L"
	nop			; I/O delay				
	out	PORTD,lcd_data	; PORTD = data_L,RW
					
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	nop			; I/O delay
	cbi	PORTD,lcd_enb	; E = "L"
	ret

lcd_bfch:
	cbi	DDRD,lcd_db7	; lcd_db7 = INPUT
	sbi	PORTD,lcd_db7	; pullup
	sbi	PORTD,lcd_rw	; RW = "H"
	cbi	PORTB,lcd_rs	; RS = "L"
lcd_bfch1:
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	in	temp1,PIND
	cbi	PORTD,lcd_enb	; E = "L"
	nop
	nop
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	in	temp2,PIND
	cbi	PORTD,lcd_enb	; E = "L"

	andi	temp1,0x80	; Wait until busy flag becomes zero.
	brne	lcd_bfch1
	sbi	DDRD,lcd_db7	; lcd_db7 = OUTPUT
	cbi	PORTD,lcd_db7	; clear
	ret

wait_us:	;base 12.8MHz	
				;temp1　us (13clocks)
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks		
	dec	temp1		; 1clocks
	brne	wait_us		; 2clocks
	ret			; 

wait_ms:
				;temp1　ms
	ldi	temp2,200	;64*200=12800clocks

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


