;**** includes **** 2012/7/8 ck=4Mhz
.include "tn861Adef.inc"

.macro	ldiw	;	ldiw	Z(X,Y),var
	ldi	@0L,low(@1)
	ldi	@0H,high(@1)
.endm

.macro	outi
	ldi	r16,@1
	out	@0,r16
.endm

.MACRO subi16	;subi16	ra,rb,0xHHHH
                 subi	@1,low(@2)
                 sbci	@0,high(@2)
.ENDMACRO 
.MACRO cpi16	;cpi16	ra,rb,0xHHHH	;ra:rb-0xHHHH	set flags:N,C
		push	@0
		push	@1
		subi	@1,low(@2)
		sbci	@0,high(@2)
cp162:	pop	@1
		pop	@0
.ENDMACRO
.MACRO subi24	;subi24	ra,rb,rc,0xHHHHHH
                 subi	@2,low(@3)
                 sbci	@1,high(@3)
                 sbci	@0,byte3(@3)
.ENDMACRO 
.MACRO cpi24	;cpi24	ra,rb,rc,0xHHHHHH	;ra:rb:rc-0xHHHHHH	set flags:N,C
		push	@0
		push	@1
		push	@2
		subi	@2,low(@3)
		sbci	@1,high(@3)
		sbci	@0,byte3(@3)
		pop	@2
		pop	@1
		pop	@0
.ENDMACRO
;*****************************
;* レジスタ変数　設定 *
;*****************************

.def	temp1	= r16
.def	temp2	= r17
.def	temp3	= r18
.def	temp4	= r19
.def	lcd_data= r20
.def	data	= r21
.def	bz_f	= r25

;*****************************
;*　 ビット　設定　　*
;*****************************
 
;**  PORTA  ***
.equ	lcd_rs	= 0
.equ	lcd_rw	= 1
.equ	lcd_enb	= 2
;.equ		= 3
.equ	lcd_db4 = 4
.equ	lcd_db5 = 5
.equ	lcd_db6 = 6
.equ	lcd_db7 = 7
;**  PORTB  ***
;.equ			= 0
.equ	bz	= 1
;.equ			= 2
.equ	ds_dat	= 3	;DS18B20 data
;.equ			= 4
;.equ			= 5 
;.equ			= 7 

.dseg
sp_dat:		.byte 9

;.eseg	;EEPROM add


.cseg
	 	 rjmp	RESET   ;各種ﾘｾｯﾄ
		 reti;	rjmp	 EXT_INT0	 ;外部割り込み要求0
		 reti;	rjmp	 PCINT	 ;I/Oﾋﾟﾝ ﾚﾍﾞﾙ変化
		 reti;	rjmp	TIM1_COMPA	 ;ﾀｲﾏ/ｶｳﾝﾀ1比較A一致
		 reti;	rjmp	 TIM1_COMPB	 ;ﾀｲﾏ/ｶｳﾝﾀ1比較B一致
		 reti;	rjmp	TIM1_OVF	 ;ﾀｲﾏ/ｶｳﾝﾀ1溢れ
		 rjmp	 TIM0_OVF	 ;ﾀｲﾏ/ｶｳﾝﾀ0溢れ
		 reti;	rjmp	 USI_STRT	 ;多用途直列ｲﾝﾀｰﾌｪｰｽ 開始条件検出
		 reti;	rjmp	 USI_OVF	 ;多用途直列ｲﾝﾀｰﾌｪｰｽ 計数器溢れ
		 reti;	rjmp	 EE_RDY	 ;EEPROM 操作可
		 reti;	rjmp	 ANA_COMP	 ;ｱﾅﾛｸﾞ比較器出力遷移
		 reti;	rjmp	 ADC	 ;A/D変換完了
		 reti;	rjmp	 WDT	 ;ｳｫｯﾁﾄﾞｯｸﾞ計時完了
		 reti;	rjmp	 EXT_INT1	 ;外部割り込み要求1
		 reti;	rjmp	 TIM0_COMPA	 ;ﾀｲﾏ/ｶｳﾝﾀ0比較A一致
		 reti;	rjmp	 TIM0_COMPB	 ;ﾀｲﾏ/ｶｳﾝﾀ0比較B一致
		 reti;	rjmp	 TIM0_CAPT	 ;ﾀｲﾏ/ｶｳﾝﾀ0捕獲発生
		 reti;	rjmp	 TIM0_COMPD	 ;ﾀｲﾏ/ｶｳﾝﾀ0比較D一致
		 reti;	rjmp	 FAULT_PROTECT	 ;ﾀｲﾏ/ｶｳﾝﾀ1誤り保護
RESET:
	ldi	R16,HIGH(RAMEND)	;RAM最終ｱﾄﾞﾚｽ上位を取得
	out	SPH,R16	 ;ｽﾀｯｸ ﾎﾟｲﾝﾀ上位を初期化
	ldi	R16,LOW(RAMEND)	;RAM最終ｱﾄﾞﾚｽ下位を取得
	out	SPL,R16	 ;ｽﾀｯｸ ﾎﾟｲﾝﾀ下位を初期化
start:

	ldi	r16,0x80	;set cpu clk 4MHz
	out	CLKPR,r16
	ldi	r16,0x01	;1/2		
	out	CLKPR,r16

	ldi	temp1,0xf7	; pa0~2,4~7 out port "L"
	out	DDRA,temp1	; pa3 in port pull up
	ldi	temp1,0x08	; 	
	out	PORTA,temp1
	
	ldi	temp1,0x0a	; pb1,3 out port 1:L,3:H
	out	DDRB,temp1	; pb0,2,4~6 in port
	ldi	temp1,0x3d	; pb0,2,3~5 pull up,6:ADC	
	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,0x84
 	rcall	lcd_cmd
	ldi	lcd_data,'O'
	rcall	lcd_dsp
	ldi	lcd_data,'K'
	rcall	lcd_dsp

	clr		bz_f
ADC_set:
	ldi		r16,0b00001001 ;基準電圧AVCC=5V,ADC9(PB6)選択
	out		ADMUX,r16	;
	ldi		r16,(1<<ADEN)|(1<<ADPS2)|(1<<ADPS0)	;ADC_ck 4M/32=125k
	out		ADCSRA,r16

timer0_set:

	outi	TCCR0A,(1<<TCW0)	;16ビット動作
	outi	TIMSK,1<<TOIE0		;ﾀｲﾏ/ｶｳﾝﾀ0溢れ 割込み許可
	outi	TCCR0B,(1<<CS02)	;TCK=CK/256
	ldi		temp2,high(34286)	;割込み周期　約2s
	ldi		temp1, low(34286)	;2s/(1/4M/256)=31250,65536-31250=34286
	out		TCNT0H,temp2
	out		TCNT0L,temp1
	sei

main:

	rjmp main
	
TIM0_OVF:
	ldi		temp2,high(34286)	;割込み周期　約2s
	ldi		temp1, low(34286)	;2s/(1/4M/256)=31250,65536-31250=34286
	out		TCNT0H,temp2
	out		TCNT0L,temp1

	rcall	ds_int
	tst	temp2
	breq	t_c_1
	ldi	lcd_data,0x84
 	rcall	lcd_cmd
	ldi	lcd_data,'E'
	rcall	lcd_dsp
	ldi	lcd_data,'1'
	rcall	lcd_dsp
t_c_0:
	rjmp t_c_0

t_c_1:
	ldi	data,0xcc	;skip rom
	rcall	com_send
	ldi	data,0x44	;convert T
	rcall	com_send
	sbi PORTB,ds_dat
	ldi	temp1,250
	rcall	wait_ms
	ldi	temp1,250
	rcall	wait_ms
	ldi	temp1,250
	rcall	wait_ms
	ldi	temp1,50
	rcall	wait_ms
	ldi	lcd_data,0x8B
 	rcall	lcd_cmd
	rcall read_v
	cbi PORTB,ds_dat

	rcall	ds_int
	ldi	data,0x55	;match rom
	rcall	com_send
	ldiw z,code1*2
	ldi r22,8
convert2:
	lpm data,z+
	rcall	com_send
	dec r22
	brne convert2
	ldi	data,0xbe	;read scratchpad
	rcall	com_send
	rcall	read_scr
	ldi	lcd_data,0x80
 	rcall	lcd_cmd
	ldi	lcd_data,'I'
	rcall	lcd_dsp
	ldi	lcd_data,'n'
	rcall	lcd_dsp
	ldi	lcd_data,' '
	rcall	lcd_dsp
	rcall	temp_dsp

	rcall	ds_int
	ldi	data,0x55	;match rom
	rcall	com_send
	ldi r22,8
convert3:
	lpm data,z+
	rcall	com_send
	dec r22
	brne convert3
	ldi	data,0xbe	;read scratchpad
	rcall	com_send
	rcall	read_scr
	ldi	lcd_data,0xC0
 	rcall	lcd_cmd
	ldi	lcd_data,'O'
	rcall	lcd_dsp
	ldi	lcd_data,'u'
	rcall	lcd_dsp
	ldi	lcd_data,'t'
	rcall	lcd_dsp
	rcall	temp_dsp
	rcall bz_onoff
	reti

read_v:
	;Reset interrupt flag,Start A/D conversion
	ldi		r16,(1<<ADEN)|(1<<ADPS2)|(1<<ADPS0)|(1<<ADSC)|(1<<ADIF)
	out		ADCSRA,r16
read_v1:	
	in		r0,	ADCSRA
 	sbrs	r0,ADIF
 	rjmp	read_v1
	in	temp1,ADCL	
	in	temp2,ADCH
	lsl	temp1
	rol	temp2
	lsl	temp1
	rol	temp2
	lsl	temp1
	rol	temp2
	lsl	temp1
	rol	temp2	;0-5V  adcx16=0-1023*16V
	rcall bindec50	;r0r1.r2=1x.xV
	ldi	lcd_data,0x30
	add	lcd_data,r0
	rcall	lcd_dsp		;十位
	ldi	lcd_data,0x30
	add	lcd_data,r1
	rcall	lcd_dsp		;一位
	ldi	lcd_data,'.'
	rcall	lcd_dsp	
	ldi	lcd_data,0x30
	add	lcd_data,r2
	rcall	lcd_dsp		;0.1位
	ldi	lcd_data,'V'
	rcall	lcd_dsp
	ret

bz_onoff:
	lds	temp1,sp_dat
	lds	temp2,sp_dat+1
	tst	temp2
	brmi	bz_onoff3	;t<0
	cpi16   temp2,temp1,0x0009
	brcc	bz_onoff4	;t>0.5
bz_onoff3:
	tst	bz_f
	brne	bz_onoff8	;bz on → on
	ser	bz_f
	sbi	PORTB,bz	;bz off → on
	ldi	temp1,250
	rcall	wait_ms
	ldi	temp1,250
	rcall	wait_ms
	cbi	PORTB,bz	
	rjmp	bz_onoff8
bz_onoff4:
	cpi16   temp2,temp1,0x0011
	brcs	bz_onoff8	;t=0.5-1.0
bz_onoff5:			;t>1.0
	tst	bz_f
	breq	bz_onoff8
	clr	bz_f
	sbi	PORTB,bz		
	ldi	temp1,200
	rcall	wait_ms
	cbi	PORTB,bz
	ldi	temp1,200
	rcall	wait_ms
	sbi	PORTB,bz		
	ldi	temp1,200
	rcall	wait_ms
	cbi	PORTB,bz
bz_onoff8:
	ret

temp_dsp:
	lds	r22,sp_dat
	lds	r23,sp_dat+1
	tst	r23
	brpl	temp_dsp1
	clr	r24
	neg	r22
	sbc	r24,r23
;	andi r24,0x03
	mov temp2,r24
	ldi	r24,'-'
	rjmp	temp_dsp2
temp_dsp1:
	ldi	r24,' '
	andi	r23,0x0f
	mov temp2,r23
temp_dsp2:
	mov temp1,r22
	;temp2:temp1 x10/16=10xdeg
	lsl	temp1
	rol	temp2		;x2
	mov	temp3,temp1
	mov	temp4,temp2
	lsl	temp1
	rol	temp2
	lsl	temp1
	rol	temp2		;x8
	add	temp3,temp1			;L2:L1
	adc	temp4,temp2	;x10(2+8)	;H2:H1
	andi	temp3,0xf0	;L2:00
	swap	temp3		;00:L2
	mov	temp1,temp4	;H2:H1
	swap	temp1		;H1:H2
	mov	temp2,temp1	;H1:H2
	andi	temp1,0xf0	;H1:00
	or	temp1,temp3	;H1:L2
	andi	temp2,0x0f	;00:H2
	rcall	bindec40	;r1,r2,r3,r4
	tst	r1
	brne	temp_dsp3
	mov	lcd_data,r24
	rjmp	temp_dsp4
temp_dsp3:
	ldi	lcd_data,0x30
	add	lcd_data,r1
temp_dsp4:
	rcall	lcd_dsp		;百位
	or	r1,r2
	brne	temp_dsp5
	ldi	lcd_data,' '
	rjmp	temp_dsp6
temp_dsp5:
	ldi	lcd_data,0x30
	add	lcd_data,r2
temp_dsp6:
	rcall	lcd_dsp		;十位
	ldi	lcd_data,0x30
	add	lcd_data,r3
	rcall	lcd_dsp		;一位
	ldi	lcd_data,'.'
	rcall	lcd_dsp	
	ldi	lcd_data,0x30
	add	lcd_data,r4
	rcall	lcd_dsp		;0.1位
	ldi	lcd_data,0xdf
	rcall	lcd_dsp	
	ldi	lcd_data,'C'
	rcall	lcd_dsp
	ret

	
read_rom:
	ldi	temp4,9
	rjmp r_s_0
read_scr:
	ldi	temp4,9
r_s_0:
	ldiw	x,sp_dat
r_s_1:
	ldi	temp3,8
	clr	data
r_s_2:
	rcall	read_d
	lsr	temp2
	ror	data
	dec	temp3
	brne	r_s_2		
	st	x+,data
	dec	temp4
	brne	r_s_1
	ret


com_send:
	ldi	temp3,8
com_send1:
	lsr	data
	brcs	com_send2
	rcall	send0
	rjmp	com_send3
com_send2:
	rcall	send1	
com_send3:
	dec	temp3
	brne	com_send1
	ret

ds_int:
	clr temp2
	cbi PORTB,ds_dat
	ldi temp1,250	;bus low 480us+
	rcall wait_us
	ldi temp1,250
	rcall wait_us
	sbi PORTB,ds_dat

	ldi temp1,70	;wait 60+(60~240)us  -> 210
	rcall wait_us
	cbi DDRB,ds_dat	;input pull up
	sbic PINB,ds_dat
	ldi temp2,1	;no dev
	ldi temp1,250	;wait 480+(500=210+250+40)
	rcall wait_us
	ldi temp1,180
	rcall wait_us
	sbi DDRB,ds_dat	;output high
	ret

send0:
	cbi PORTB,ds_dat
	ldi temp1,70	;bus low 60~120us
	rcall wait_us
	sbi PORTB,ds_dat
	ldi temp1,5	;wait 1us+
	rcall wait_us
	ret
send1:
	cbi PORTB,ds_dat
	ldi temp1,5	;bus low 1~15us
	rcall wait_us
	sbi PORTB,ds_dat
	ldi temp1,70	;wait 60us+ 
	rcall wait_us
	ret

read_d:	;return bit 0:temp2=0,1:temp2=1 
	clr temp2
	cbi PORTB,ds_dat
	ldi temp1,2	;bus low 1us+
	rcall wait_us	
	cbi DDRB,ds_dat	;input
	ldi temp1,10	; ~15us 2+10
	rcall wait_us
	sbic PINB,ds_dat
	ldi temp2,1
	ldi temp1,60	;wait 49us+ 
	rcall wait_us
	sbi PORTB,ds_dat
	sbi DDRB,ds_dat	;output high
	ret		

			
;-----------------------------------------------;
; LCD - Send a data/cmd into LCD
	;PORTA   7   6   5   4   3   2    1   0
	;write   <-data(H/L)->  -   enb r/w  r/s  
	;read   BF   -   -   -   -   -    -   -  
 
lcd_int:	; Internal reset
	ldi	lcd_data,0x30	; data='0011',RW = "L", RS = "L",E = "L"
	out	PORTA,lcd_data	
	sbi	PORTA,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	nop			; I/O delay
	cbi	PORTA,lcd_enb	; E = "L"
	ret

lcd_dsp:
	rcall	lcd_bfch
	ldi	temp3,0x01	; RW = "L",RS = "H",E = "L",data='xxxx'
	rjmp	lcd_cmd1
lcd_cmd:
	rcall	lcd_bfch
	ldi	temp3,0		; RW = "L",RS = "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	PORTA,lcd_data	; PORTA = data_H,RW
	sbi	PORTA,lcd_enb	; E = "H"
	mov	lcd_data,temp2	; 
	or	lcd_data,temp3	;data_L set
	nop						
	cbi	PORTA,lcd_enb	; E = "L"
	nop			; I/O delay				
	out	PORTA,lcd_data	; PORTA = data_L,RW
					
	sbi	PORTA,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	nop			; I/O delay
	cbi	PORTA,lcd_enb	; E = "L"
	ret

lcd_bfch:
	cbi	DDRA,lcd_db7	; lcd_db7 = INPUT
	sbi	PORTA,lcd_db7	; pullup
	sbi	PORTA,lcd_rw	; RW = "H"
	cbi	PORTA,lcd_rs	; RS = "L"
lcd_bfch1:
	sbi	PORTA,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	in	temp1,PINA
	cbi	PORTA,lcd_enb	; E = "L"
	nop
	nop
	sbi	PORTA,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	in	temp2,PINA
	cbi	PORTA,lcd_enb	; E = "L"

	andi	temp1,0x80	; Wait until busy flag becomes zero.
	brne	lcd_bfch1
	sbi	DDRA,lcd_db7	; lcd_db7 = OUTPUT
	cbi	PORTA,lcd_db7	; clear
	ret
;*********************************************
wait_us:	;base 4MHz	
				;temp1　us (4clocks)
	nop			; 1clocks
	dec	temp1		; 1clocks
	brne	wait_us		; 2clocks
	ret
;*********************************************	
wait_ms:	;temp1　ms at 4MHz
	ldi	temp2,50	;80*50=4000clocks
wait_ms_01:
	ldi	temp3,19    	;1clocks  4*(19+1)=80
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


;***************************************************************************
;*
;* "bindec" - 16-bit Binary to dec 
;*  bin:=temp2:temp1  dec=r5,r0,r1,r2,r3,r4
;***************************************************************************
bindec60:	;<99999 if 100,0000+ then r5=10+
	clr	r5
	clr r0
bindec61:
	cpi24	temp3,temp2,temp1,100000
	brcs	bindec62
	inc r5
	subi24	temp3,temp2,temp1,100000
	rjmp	bindec61
bindec62:
	tst temp3
	breq	bindec51
	inc r0
	subi24	temp3,temp2,temp1,10000
	rjmp	bindec62
bindec50:	;>9999
	clr	r0
bindec51:
	cpi16	temp2,temp1,10000
	brcs	bindec40
	subi16	temp2,temp1,10000
	inc	r0
	rjmp	bindec51
bindec40:	;>999
	clr	r1
bindec41:
	cpi16	temp2,temp1,1000
	brcs	bindec30
	subi16	temp2,temp1,1000
	inc	r1
	rjmp	bindec41
bindec30:	;>99
	clr	r2
bindec31:
	cpi16	temp2,temp1,100
	brcs	bindec20
	subi16	temp2,temp1,100
	inc	r2
	rjmp	bindec31
bindec20:	;>9
	clr	r3
bindec21:
	cpi	temp1,10
	brcs	bindec10
	subi	temp1,10
	inc	r3
	rjmp	bindec21
bindec10:	;<10
;	clr	r4
	mov	r4,temp1
	ret

 
code1:	.db 0x28,0xf1,0x39,0xb7,0x03,0x00,0x00,0xdf
code2:	.db 0x28,0x2a,0x9c,0x06,0x03,0x00,0x00,0x1c
;code2:	.db 0x28,0x94,0x46,0xb7,0x03,0x00,0x00,0xf5
