;----------------------------------------------------------------------------
;              M A I N   I N T E R R U P T     P R O G R A M M                   
;----------------------------------------------------------------------------





TimeKey: 	;============ HEADER =========== 
		sei			;global INT enable	
		push	r16		;push R16
		ldi	r16,177
		out	TCNT0,r16	;T/C0 start from 177
	
		in	r16,sreg	;push sreg
		push	r16		;push sreg
		push	R17		;
		push	r18		;store used registers
		push	XL		;Push Rx in STACK
		push	XH		;
		push	ZL		;
		push	ZH		;
		;================================



	;============== 200 Hz Section ====================	

	;================ INDICATION =======================
	;---------------- Read KeyIN ----------------------------------
	clc			;0=>Carry
	sbis	PIND,4		;read KEY pressed
	sec			;Set Carry Flag
	rol	KeyIN		;Write bit to KeyIN (NORMAL, 1-Pressed)
	;----------------------------------------------------------
	;------------------- ADD POINTS ------------------------------
	ldi	XL,BIND0	;Load first Addr BIND
	ldi	r17,8		;Counter
	mov	r18,Points	;Points=>temp
adpnt:	ld	r16,X		;(BIND0+Counter)=>temp2
	sbrc	r18,7		;
	ori	r16,0x04	;Set point (BIND0+Counter)
	st	X+,r16		;temp2=>(BIND0+Counter)
	lsl	r18		;R(7)=>C
	dec	r17		;Dec Counter
	brne	adpnt		;Loop
	;----------------------------------------------------------
	;------------------- OFF IND ------------------------------
	in	r16,portb		;Read OUT register
	ori	r16,0x0F		;
	out	portb,r16		;OFF IND

	;---------------- Set IND Position ------------------------
	ldi	ZL,IND_POS*2		;Load Addr IND_POS
	ldi	XL,BIND0		;Load first Addr BIND
	mov	r16,IND_CNT		;
	sbrc	r16,6			;compare IND counter & 32D
	subi	XL,-4			;switch to BIND1
	andi	r16,0x03		;extract IND Position 
	add	ZL,r16			;ADD IND Position SHIFT TO IND_POS
	add	XL,r16			;ADD IND Position SHIFT TO BIND
	ld	R16,X			;Load data to R16 from adress X 

	;------------- SYMBOL OUT THRU SHIFT RG --------------------
	ldi	r17,8		;set counter=8 bits
TK1:	cbi 	PORTD,5		;DATA "0" => 74LS164
	sbrc	r16,7		;if bit 7=0 then GO OVER
	sbi 	PORTD,PD5	;DATA "1" => 74LS164
	lsl	r16		;Shift left r16
	sbi 	PORTD,6		;CLOCK strobe for 74LS164
	cbi 	PORTD,6		;CLOCK strobe for 74LS164
	dec	r17		;dec counter
	brne	TK1		;loop

	;------------------- ON IND ------------------------------
	in	r16,portb		;Read OUT register
	lpm				;Read IND_POS
	and	r16,r0			;Set new IND position
	out	portb,r16		;ON IND
	;---------------------------------------------------------

	;============= END 200 Hz Section ==============================




	;============== 50 Hz Section ====================	
	;--------------- PRESCALER (:4) ------------------
	mov	r16,IND_CNT	;
	andi	r16,0x03	;? IND Position=0 ?
	breq	TRC0
	rjmp	HZ50E		; IF "YES" then GO OUT
	;-------------------------------------------------


	;============ MicroLan PROCESSING ================

TRC0:	tst	LineBisy	;IF Counter for MicroLan>0
	brne	TRC1		;Then GO OVER Termo Conversion

	;-------------- READ TEMPERATURE -------------------------

	;---------------- Step 1. Initialization -----------------
	rcall	RSTPULS		; SET "RESET PULSE"
	;---------------------------------------------------------
	ldi	r16,33		;
	rcall	dl		;WAIT 68mkSec "Presense pulse"
	;---------------------------------------------------------
	sts	MkLan_YES,r31	;Write "NO MkLan Present"
	sbic	pind,MkLan	;IF MicroLAN=1 (NO "Presense pulse")
	rjmp	TRCE		;then go out
	
TRC2:	sbis	pind,MkLan	;IF MicroLAN=0 
	rjmp	TRC2		;then WAIT END of "Presense pulse"

	;--------- Step 2. ROM Command ---------------------
	ldi	r18,0xCC	;comand SKIP ROM => data
	sts	MkLan_YES,r18	;Write "YES MkLan Present"
	rcall	BLNOUT		;Transvert 1 Byte MkLan
	;---------------------------------------------------

	;------ Step 3. Function Command -------------------

	ldi	r18,0xBE	;comand READ SCRATCHPAD [BEh] => data
	rcall	BLNOUT		;Transvert 1 Byte MkLan

	;-------------- Exchange Data --------------------
	ser	r18		;exequite READ ROM FF=> data 
	rcall	BLNOUT		;Transvert 1 Byte MkLan
	mov	LNTMPR_L,r16	;Move LSB=>LNTMPR_L

	ser	r18		;exequite READ ROM FF=> data 
	rcall	BLNOUT		;Transvert 1 Byte MkLan
	mov	LNTMPR_H,r16	;Move MSB=>LNTMPR_H

	;------------- Correction temperature ------------
	ldi	r16,DS_Type	;4-for DS18S20,7-for DS18B20
TRC3:	lsl	LNTMPR_L	;
	rol	LNTMPR_H	;
	dec	r16		;
	brne	TRC3		;
	;------------- END READ TEMPERATURE --------------


	;---------------- PREPARE NEXT CONVERSION ----------------
	;---------------- Step 1. Initialization -----------------
	rcall	RSTPULS		; SET "RESET PULSE"
	;------------ Pause 514 mkSec ----------------------------
	ser	r16		;256=>R16
	rcall	dl		;Wait 514 mkSec
	;----------- Step 2.ROM Command --------------------
	ldi	r18,0xCC	;comand SKIP ROM => data
	rcall	BLNOUT		;Transvert 1 Byte MkLan
	;------ Step 3. Function Command -------------------
	ldi	r18,0x44	;comand CONVERT T [44h] => data
	rcall	BLNOUT		;Transvert 1 Byte MkLan
	;------------- Prepare next conversion ----------------
	ldi	r16,0xB2	;50D+Flag=>Counter for MicroLan
	mov	LineBisy,r16	;100mSec=>LineBisy (Set conversion time+I2C time) 
	sbi	portd,MkLan	;1=>MicroLAN	
	sbi	ddrd,MkLan	;"Strong 1"=>MicroLAN
	;---------------------------------------------------------
	;------------- END PREPARE NEXT CONVERSION ---------------
	
TRC1:	;--------- Counter for MicroLan (Line Bisy) Control -------
	dec	LineBisy	;LineBisy=LineBisy-1

	ldi	r16,0x8A	;Load const 10D+Flag=>Counter for MicroLan
	cp	LineBisy,r16	;?Counter for MicroLan=10D?
	brne	TRCE		;
	ldi	r16,10		;
	mov	LineBisy,r16	;10D=>Counter for MicroLan
	cbi	ddrd,MkLan	;1=>MicroLAN
	cbi	portd,MkLan	;O.C.=>MicroLAN	
TRCE:	
	;============ END of MicroLan PROCESSING ==================				


	;============== KEYSCAN MODULE =============================
	;---------------- AntiBUZZZ --------------------------------
	cp	KeyIN,KeyInOld		;? KeyIn=KeyInOld
	MOV	KeyInOld,KeyIN		;KeyIn=>KeyInOld
	brne	ac1			; If no - GO OVER
	mov	KeyS,KeyIN		;Set new KeyS
ac1: 	clr	KeyIN			;Clear KeyIN

	;---------- Edgle Analys -----------------
	tst	KeyS		;KeyS>0 ?
	brne	key3		;if YES then count ...
	tst	KeySold		;KeyS_old=0 ?
	brne	key2		;if NO then go set keys
	clr	TmKEY		;0=>TmKEY
	rjmp	keyE		;GO OUT

key2:	;------- SET pulled Keys -----------
	ldi	r16,0xF3	;if K2 or K3
	and	r16,KeySold	;? KeyS_old=K2 or K3 ?
	brne	key5		;if yes then GO ...
	mov	KeyD,KeySold	;Set KeyD
key5:	clr	KeySold		;Clear KeyS_old
	rjmp	keyE		;GO out

	;-------- SET rising Keys -------------------
key3:	inc	TmKEY		;TmKey=TmKey+1
	or	KeySold,KeyS	;Store KeyS

	ldi	r16,0xFC	;if K0 or K1
	and	r16,KeySold	;? KeyS_old=K0 or K1 ?
	brne	key1		;if NO then GO SET NO repeated Keys

	;------- SET repited Keys -----------
	cpi	TmKEY,1		;?TmKEY=0.02Sec?
	breq	keyset		;IF YES then set KeyD

	;------------ AutoRepeat -------------------
	cpi	TmKEY,50	;?TmKEY=1Sec?
	brne	keyE		;IF NO then GO OUT
	lds	r16,AUTORPT	;Load Autorepeat constant
	sub	TmKEY,r16	;TmKey=TmKey-0.16Sec
	rjmp	keyset		;GO set KeyD
	;-------------------------------------------

key1:	;------- SET NO repeated Keys -----------
	cpi	TmKEY,60	;?TmKEY=1.2Sec?
	brne	keyE		;IF NO then GO OUT
	ldi	r16,0x80	;
	or	KeySold,r16	;KeyS_old=KeyS_old+80h
	rjmp	keyset
	     ;------- Write new KeyD -----------
keyset:		mov	KeyD,KeySold	;Set KeyD
key4:		ser	RST25		;SET WDT Reset max
keyE:	;========== END of KEYSCAN MODULE ===========================


;=========== READ PCF TIME & BDD->BIN Convert=> PCFTM_L/PCFTM_H ===========
	;---------- Test LINE READY ----------------------
	sbrc	LineBisy,7	;IF LineBisy>0   (Line not Ready?)
	rjmp	RDTME		;Then Skip Reading
	;----------- Addressing --------------------------	
	rcall	sta		;Start transfer I2C
	ldi	r16,ADDR_WR	;
	rcall	I2COUT		;Sent Slave WRITE ADDR
	ldi	r16,3		;Subaddr
	rcall	I2COUT		;Sent Word ADDR
	;------------- Read ---------
	rcall	sta		;Restart transfer I2C
	ldi	r16,ADDR_RD	;
	rcall	I2COUT		;Sent Slave READ ADDR (FFh=>R16)
	;-------- 1-st byte ---------
	mov	ACK,r16		;Set FFh=>ACK (continued)
	rcall	I2CIN		;Read "Minutes"
	push	R16		;Store "Minutes" (LOW BDD)
	;-------- 2-st byte ---------
	clr	ACK		;Set 0=>ACK (last byte)
	rcall	I2CIN		;Read "Hours"
				;"Hours"=>r16(HIGH BDD)
	;----------------------------	
	rcall	sto		;Stop transfer I2C
	;----------------------------	

	;------ BDD to BINARY format convert -----------
	;input - R16(HIGH),pop R16(LOW)BDD-format
	;output- 2 byte PCFTM_H(HIGH)/PCFTM_L(LOW)BIN-format 

	clr	XL		;clear tmp BIN TIME LOW
	clr	XH		;clear tmp BIN TIME HIGH

	ldi	ZL,low((clcconst+1)*2)	;set Z pointer to DECconst in FLASH(HOURS)

	swap	r16		;
	rcall	BDD_BIN		;Calculate position one 
	swap	r16		;
	rcall	BDD_BIN		;Calculate position two

	pop	r16		;"Minutes"(LOW BDD)=>temp
	swap	r16		;
	rcall	BDD_BIN		;Calculate position three 
	swap	r16		;
	rcall	BDD_BIN		;Calculate position thour

	sts	PCFTM_L,XL	;Store LOW byte PCF Time
	sts	PCFTM_H,XH	;Store HIGH byte PCF Time
;				clr	XH		;Restore 0=>XH
RDTME:	;=====================================================================


	;========== Time Delay DL1  ======================
	tst	DL1		;IF DL1=0
	breq	dl01E		;Then GO Over
	dec	DL1		;ELSE DL1=DL1-1
dl01E:	;==================================================

	;============ RING Counter  =======================
	tst	RING		;IF RING=0
	breq	RNGE		;Then GO Over
	inc	RING		;ELSE RING=RING+1
	brne	RNGE		;Then GO Over
	inc	RING		;ELSE RING=RING+1
RNGE:	;==================================================

HZ50E:	;================== END 50 Hz Section ====================================


;======================== 6.25 Hz Section ====================================
	;--------- PRESCALER (:32)6.25 Hz ----------------
	mov	r16,IND_CNT	;
	andi	r16,0x1F	;? IND Position=0 ?
	brne	Hz625E		; IF "no 0" then GO OUT
	;-------------------------------------------------

	;----------- TimeReset 25Sec ---------------------
	tst	RST25		;IF RST25=0
	breq	TRSTE		;Then GO Over
	dec	RST25		;ELSE RST=RST-1 
	WDR			;Reset Watchdog Timer
TRSTE:	
Hz625E:
;====================== END 6.25 Hz Section ====================================



	;========= 12.5 Hz Section =======================
	;--------- PRESCALER (:16)12.5 Hz ----------------
	mov	r16,IND_CNT	;
	andi	r16,0x0F	;? IND Position=0 ?
	brne	PEXE5		; IF "no 0" then GO OUT

;================ EXEQUTE TIMER PROGRAMM ===========================
	clr	PGM_ADDR	;0=>PGM_ADDR(r17)
	clr	r16		;0=>tmp Points
	clr	XL		;Clear temp PGM Time (LOW)
	clr	XH		;Clear temp PGM Time (HIGH)

PEXE1:	rcall	RD_EE0		;Read 2*Data EEPROM (LOW=>EETIME_L, HIGH=>EETIME_H)
	sbrs	EETMP_H,3	;IF PGMxx "Not Active"
	rjmp	PEXE2		;Then go Write new PORTB
	
	mov	ZL,EETMP_H		;
	andi	ZL,0x07			;Mask EETIME_H

	lds	r18,PCFTM_L		;READ Time(LOW)	
	cp	r18,EETMP_L		;Compare real Time
	lds	r18,PCFTM_H		;READ Time(HIGH)	
	cpc	r18,ZL			;  and  PGM Time
	brlo	PEXE3			;IF real Time<PGM Time Then GO Next PGM Time
 	
	cp	EETMP_L,XL		;Compare new PGM Time
	cpc	ZL,XH			;  and temp PGM Time
	brlo	PEXE3			;IF new Time<temp PGM Time Then GO Next PGM Time
 	
	mov	XL,EETMP_L		;Write New temp PGM Time (LOW)
	mov	XH,ZL			;Write New temp PGM Time (HIGH)
	mov	r16,EETMP_H		;Write New temp Points
	andi	r16,0xF0		;Mask New temp Points

PEXE3:	inc	PGM_ADDR	;PGM_ADDR=PGM_ADDR+1
	cpi	PGM_ADDR,60	;IF PGM_ADDR=60
	brne	PEXE1		;Then go Write new PORTB 

PEXE2:	in	r18,PORTB	;get old PORTB
	andi	r18,0x0F	;clear old PORTB
	or	r18,r16		;set new PORTB

	;------------ Read stored Termo Threshold ---------------
	ldi	r17,61			;Set 1/2 1-st EEAddr termo threshold
	rcall	RD_EE0			;Read 2*Data EEPROM (NOT Corrected)
	;---------------------------------------------------------
	;---------- Test Activity Termocontrol ----------------
	clr	r17		;Clear temp TRMFLAG
	sbrs	EETMP_L,0	;IF TERMOSTAT NOT ACTIVE
	rjmp	PEXE4		;GO OVER TERMOCONTROL
	;------------- Termocontrol ---------------------------
	andi	r18,0xEF	;Clear P4 (ON BOARD RELAY)
	;---------- Set Termostat IND Points ---------------------
	ldi	r17,0x10	;Set flashing point 0 position TRMFLAG
	;------------- Compare Termo & Threshold -----------------
	clr	r16			;OFF HEATER (0x00=>HEATER)
	dec	EETMP_L
	cp	EETMP_L,LNTMPR_L	;Compare real temperature & Threshold
	cpc	EETMP_H,LNTMPR_H	;Compare real temperature & Threshold
	brlt	PEXE6			;IF real termo lower then ON HEATER
	inc	r16			;ON HEATER (0x01=>HEATER)
PEXE6:	;-----------------------------------------------------------
	tst	r16		;IF HEATER OFF (=0)
	breq	PEXE4		;THEN GO put new PORTB
	ori	r18,0x10	;Set P4 (ON BOARD RELAY)
	ldi	r17,0x11	;Set permanent point 0 position TRMFLAG
	;------------------------------------------------------
PEXE4:	out	PORTB,r18	;put new PORTB
	sts	TRMFLAG,r17	;Store new TRMFLAG
PEXE5:	clr	XH		;Restore 0=>XH
;=====================================================================





	;=========== FOOTER ====================
EXIT:	inc	IND_CNT		;ADD indication counter
	pop	ZH		;
	pop	ZL		;
	pop	XH		;
	pop	XL		;
	pop	r18		;restore used registers
	pop	R17		;
	pop	r16		;Pop Rx from STACK
	out	sreg,r16	;Pop sreg
	pop	r16		;pop R16
	;=======================================
	RETI
;=========================================================================


;====================== S U B R O U T I N E S ============================

;=============== Summ one dig LOW nibble R16 ==========================
;---------- BDD const in (Z), R16 not change, Z=Z+2 -------------------
	;----- Changed R0,R17,R18,XL,XH ----------------------

BDD_BIN:	push	r16		;copy data
		andi	r16,0x0F	;mask low nibble

		lpm			;
		mov	r17,r0		;read DDCONST (LOW)
		inc	ZL		;Z=Z+1
		lpm			;
		mov	r18,r0		;read DDCONST (HIGH)
		inc	ZL		;Z=Z+1

bddb1:		tst	r16		;IF Counter=0
		breq	bddb2		;GO OVER
		add	XL,r17		;SUMM LOW byte
		adc	XH,r18		;SUMM HIGH byte
		dec	r16		;
		rjmp	bddb1		;NEXT step

bddb2:		pop	r16		;restore data

		RET
;-----------------------------------------------------------------------
;========================== E N D ===============================