;*****************************************************************************
; 	All rights reserved by Dipl.-Ing (FH) Andreas Hoeger
;	Ditzenbrunner Str. 64, 71254 Ditzingen, Germany
;	Telefon: (+497156)490980	Telefax: (+497156)490981
;	E-Mail: ingbuero@andreas-hoeger.de
;*****************************************************************************
;
;       8051- Programm fuer ATMEL Flash- Mikrocontroller AT89S53
;	
;	Teilprogramm fuer ZSTG, wird durch INCLUDE eingebunden
;
;       Autor: Andreas Hoeger
;       Datum: 14.04.2001		
;
;	Aenderungen:
;
;	14_04_01: Neuerstellung für DCF77 Empfaenger
;	02_03_02: Bugfix; B Akku auch auf Stack sichern
;
;*****************************************************************************


        ;*********************************************************************
	;****** Interruptroutine für Timer 0 / DCF77 Signalauswertung ********
        ;*********************************************************************

	; Diese Interruptroutine dient der DCF77 Signalauswertung.
	; Der Timer 0 arbeitet mit einem Prescaler, ist also 13 Bit breit.
	; Der Systemtakt ist 16 MHz. (1/16 MHz = 62,5 ns)
	; Ein Programmtakt ist 12 cycles lang, also 0,75 us.
	; Der Timer wird bei jedem Programmtakt erhöht, lauft also bei 
	; 8192 * 0.75 us = 6.144 ms ueber und erzeugt in diesem Raster
	; Timer 0 overflow Interrupts.

	; Darauf beruht die Auswertung des DCF77 Signals.
	; Es muss in jeder Sekunde der DCF77-Low- Impuls detektiert und 
	; dessen Laenge ermittelt werden.
	; Ein 100 ms LOW Impuls entspricht "logisch 0"
	; Ein 200 ms LOW Impuls entspricht "logisch 1"

	; Waehrend  100 ms kommen  16,27 Interrupts
	; Waehrend  200 ms kommen  32,55 Interrupts
	; Waehrend 1000 ms kommen 162,76 Interrupts

	; Es wird die Anzahl der Interrupts mit Signal = 0 ermittelt um
	; zu unterscheiden, ob 100 ms oder 200 ms Impulsdauer.

	; Wenn die Anzahl High- Impulse die Anzahl 163 ueberschreitet, liegt 
	; Sekunde 59 vor, die ohne LOW- Impuls gesendet wird. 
	; Daraus wird erkannt, dass jetzt wieder Bit 0 folgen wird.

	; bei power-on muß zuerst eine "Sekunde 59" gesucht werden um die 
	; Counter definiert starten zu koennen.

	; DCF77_TAKEOFF.0 wird verwendet, um zu unterscheiden ob erste "sek59"
	; bereits gefunden wurde oder noch nicht.

	; DCF77_TAKEOFF.1 wird verwendet, um zu unterscheiden, ob die 
	; Zeitinformation vollständig ist (Bit = 1) oder im Aufbau (Bit = 0)
	; Es erfolgt dann keine CAN- Ausgabe
	
irq_t0:	
	push	PSW
	push	ACC
	push	B
	mov	DCF77_PUSHPOP,R7
	push	DCF77_PUSHPOP		; R7 wird in IRQ verwendet

	
	; nur fuer Interrupt- Test
	; cpl	LED
	; nur fuer Interrupt- Test

	;******	PowerOn Pruefung zur Synchronisation *************************

powerontest:

	jb	DCF77_TAKEOFF.0,no_poweron	; zu Auswerteroutine gehen
						; sonst auf erste "Sek 59"
						; warten zur Synchronisation
						; der Zaehler
	jb	DCF77_SIGNAL,poweronhigh

poweronlow:

	mov	DCF77_INITWAIT,#00H		; reset Zaehler f. Erkennung
						; erster Langimpuls
	jmp	popweg				; gehe zu RETI
				
poweronhigh:

	inc	DCF77_INITWAIT			; Zaehler f. Erkennung
						; erster Langimpuls ++
	
	mov	A,DCF77_INITWAIT
	cjne	A,#DCF77_COMP_59,umleitung_ljmp1	; kein Langimpuls

sek59found:
	
	mov	DCF77_CNT_HIGH,#01H		; damit Bit 0 nicht gleich 
						; ausgewertet wird;
						; Hinweis: Erkennung "sek59"
						; bedeutet nicht dass
						; nun Nullen kommen !
						; es kommen "Resteinsen" bis
						; sek 59 fertig ist
	mov	DCF77_CNT_LOW,#00H		; auf Null; setzt später
						; den Rest im High Counter
						; zurueck
	mov	DCF77_BITNR,#00H
	mov	DCF77_TAKEOFF,#01H		; Freigabe erteilen,
						; auf erste "Sek59" wurde
						; synchronisiert
umleitung_ljmp1:
						
	jmp	popweg

	;****** hier beginnen die Hauptroutine fuer die Zeit nach PowerOn ****
	;****** schon wieder 6,144 ms Zeit vorbei, pruefen ob LOW oder HIGH 
no_poweron:
	
	jb	DCF77_SIGNAL,signal_high

	;******	LOW- Signal liegt an *****************************************

signal_low:

	mov	A,DCF77_CNT_LOW
	cjne	A,#00H,incimpcnt

	mov	DCF77_CNT_HIGH,#00H	; DCF77_CNT_LOW == 0 ? 
					; ja --> "Sekundenbeginn"
				     	; reset DCF77_CNT_HIGH

incimpcnt:		
	inc	DCF77_CNT_LOW		; increment CDF77_CNT_LOW

	jmp	popweg

	;******	HIGH- Signal liegt an ****************************************

signal_high:

	mov	R7,DCF77_CNT_HIGH	; DCF77_CNT_HIGH == 0 ? 
					; Dann ist das der erste High Zustand 
					; und die Impulslaenge kann 
					; ausgewertet werden
	cjne	R7,#00H,umleitung_ljmp
	jmp	bit_auswert

umleitung_ljmp:
	ljmp	count_highs

bit_auswert:

	mov	A,DCF77_CNT_LOW		; Impulslaenge > 22 ? 
					;	nein --> 100 ms --> 0
				        ;       ja   --> 200 ms --> 1
	mov	DCF77_IRQCNT1,#DCF77_COMP_IMP	; Vergleichswert in Counter 
						; laden fuer Impulslaenge
implength:
	dec	A
	jz	set_nulleintrag		; weiter, A war kleiner als 
					; Vergleichswert --> 100 ms Impuls
	djnz	DCF77_IRQCNT1,implength
					; A war groesser als Vergleichswert
					; --> 200 ms Impuls
	;jmp 	set_einseintrag
set_einseintrag:

	mov	DCF77_BITMERK, #01H	; Eins eintragen in Merker
	jmp	biteintrag

set_nulleintrag:

	mov	DCF77_BITMERK, #00H	; Null eintragen in Merker
	; jmp	biteintrag

biteintrag:	; Auswerteprinzip: 
		; DCF77_BITNR :8 teilen (DIV AB teilt A durch B)
		; Die Ganzzahl (in A) ist die Bytenummer, 
		; Der Rest (in B) ist die Bitnummer

	mov	A,DCF77_BITNR	
	mov	B,#08H
	div 	AB	; in A ist jetzt die Bytenumer
			; in B ist jetzt die Bitnummer
	mov	DCF77_BYTENR,ACC

;******

vglbyte0:
	cjne	A,#00H,vglbyte1		
	mov	DCF77_DATA0,#00H	; Bits 7..0 always not used

	; solange in Byte 0 eingetragen wird, ist die Botschaft konsistent
	; und kann auf CAN ausgegeben werden.
	; ansonsten ist die Botschaft im Aufbau, CAN- Ausgabe muss 
	; unterbunden werden. Dies geschieht mittels Bit TAKEOFF.1
	; DCF77_TAKEOFF.1 = 0: nicht auf CAN ausgeben
	; DCF77_TAKEOFF.1 = 1: auf CAN ausgeben

	setb	DCF77_TAKEOFF.1

	jmp	vglend1

;******

vglbyte1:

	; in allen anderen Fällen befindet sich die CAN- Botschaft 
	; im Aufbau und darf nicht ausgegeben werden

	clr	DCF77_TAKEOFF.1

	; jetzt weiter mit eigentlicher Auswertung

	cjne	A,#01H,vglbyte2
	mov	DCF77_DATA1,#00H	; Bits 14..8 not used
	mov	R7,B
	cjne	R7,#07H,vglend1
	jnb	DCF77_BITMERK.0,byte17clr  ; wenn A = 0 ist: CLR bit

	setb	DCF77_DATA1.7  		  ; es war bit 15
	jmp	vglend1
byte17clr:
	clr	DCF77_DATA1.7
	jmp	vglend1

vglend1:
	ljmp	vglend
;******

vglbyte2:
	cjne	A,#02H,vglbyte3
	mov	R7,B
;--0--					
					; Bit 0 nicht benutzt (Bit 16)
;--1---
vgl21:	cjne	R7,#01H,vgl22
	jnb	DCF77_BITMERK.0,byte21clr  

	setb	DCF77_DATA2.1  		  
	jmp	vglend2
byte21clr:
	clr	DCF77_DATA2.1
	jmp	vglend2
;--2---
vgl22:	cjne	R7,#02H,vgl23
	jnb	DCF77_BITMERK.0,byte22clr  

	setb	DCF77_DATA2.2  		  
	jmp	vglend2
byte22clr:
	clr	DCF77_DATA2.2
	jmp	vglend2
;--3---
vgl23:	cjne	R7,#03H,vgl24
	jnb	DCF77_BITMERK.0,byte23clr  

	setb	DCF77_DATA2.3 		  
	jmp	vglend2
byte23clr:
	clr	DCF77_DATA2.3
	jmp	vglend2
;--4---
vgl24:	cjne	R7,#04H,vgl25
	jnb	DCF77_BITMERK.0,byte24clr  

	setb	DCF77_DATA2.4 		  
	jmp	vglend2
byte24clr:
	clr	DCF77_DATA2.4
	jmp	vglend2
;--5---
vgl25:	cjne	R7,#05H,vgl26
	jnb	DCF77_BITMERK.0,byte25clr  

	setb	DCF77_DATA2.5 		  
	jmp	vglend2
byte25clr:
	clr	DCF77_DATA2.5
	jmp	vglend2
;--6---
vgl26:	cjne	R7,#06H,vgl27
	jnb	DCF77_BITMERK.0,byte26clr  

	setb	DCF77_DATA2.6 		  
	jmp	vglend2
byte26clr:
	clr	DCF77_DATA2.6
	jmp	vglend2
;--7---
vgl27:	cjne	R7,#07H,vglend2
	jnb	DCF77_BITMERK.0,byte27clr  

	setb	DCF77_DATA2.7 		  
	jmp	vglend2
byte27clr:
	clr	DCF77_DATA2.7
	jmp	vglend2

vglend2:
	ljmp	vglend

;******

vglbyte3:
	cjne	A,#03H,vgl3uml
	mov	R7,B
;--0--					
vgl30:	cjne	R7,#00H,vgl31
	jnb	DCF77_BITMERK.0,byte30clr  

	setb	DCF77_DATA3.0  		  
	jmp	vglend3
byte30clr:
	clr	DCF77_DATA3.0
	jmp	vglend3	
;------
vgl3uml:
	jmp	vglbyte4				
;--1---
vgl31:	cjne	R7,#01H,vgl32
	jnb	DCF77_BITMERK.0,byte31clr  

	setb	DCF77_DATA3.1  		  
	jmp	vglend3
byte31clr:
	clr	DCF77_DATA3.1
	jmp	vglend3
;--2---
vgl32:	cjne	R7,#02H,vgl33
	jnb	DCF77_BITMERK.0,byte32clr  

	setb	DCF77_DATA3.2  		  
	jmp	vglend3
byte32clr:
	clr	DCF77_DATA3.2
	jmp	vglend3
;--3---
vgl33:	cjne	R7,#03H,vgl34
	jnb	DCF77_BITMERK.0,byte33clr  

	setb	DCF77_DATA3.3 		  
	jmp	vglend3
byte33clr:
	clr	DCF77_DATA3.3
	jmp	vglend3
;--4---
vgl34:	cjne	R7,#04H,vgl35
	jnb	DCF77_BITMERK.0,byte34clr  

	setb	DCF77_DATA3.4 		  
	jmp	vglend3
byte34clr:
	clr	DCF77_DATA3.4
	jmp	vglend3
;--5---
vgl35:	cjne	R7,#05H,vgl36
	jnb	DCF77_BITMERK.0,byte35clr  

	setb	DCF77_DATA3.5 		  
	jmp	vglend3
byte35clr:
	clr	DCF77_DATA3.5
	jmp	vglend3
;--6---
vgl36:	cjne	R7,#06H,vgl37
	jnb	DCF77_BITMERK.0,byte36clr  

	setb	DCF77_DATA3.6 		  
	jmp	vglend3
byte36clr:
	clr	DCF77_DATA3.6
	jmp	vglend3
;--7---
vgl37:	cjne	R7,#07H,vglend3
	jnb	DCF77_BITMERK.0,byte37clr  

	setb	DCF77_DATA3.7 		  
	jmp	vglend3
byte37clr:
	clr	DCF77_DATA3.7
	jmp	vglend3

vglend3:
	ljmp	vglend

;******

vglbyte4:
	cjne	A,#04H,vgl4uml
	mov	R7,B
;--0--					
vgl40:	cjne	R7,#00H,vgl41
	jnb	DCF77_BITMERK.0,byte40clr  

	setb	DCF77_DATA4.0  		  
	jmp	vglend4
byte40clr:
	clr	DCF77_DATA4.0
	jmp	vglend4					
;------
vgl4uml:
	jmp	vglbyte5
;--1---
vgl41:	cjne	R7,#01H,vgl42
	jnb	DCF77_BITMERK.0,byte41clr  

	setb	DCF77_DATA4.1  		  
	jmp	vglend4
byte41clr:
	clr	DCF77_DATA4.1
	jmp	vglend4
;--2---
vgl42:	cjne	R7,#02H,vgl43
	jnb	DCF77_BITMERK.0,byte42clr  

	setb	DCF77_DATA4.2  		  
	jmp	vglend4
byte42clr:
	clr	DCF77_DATA4.2
	jmp	vglend4
;--3---
vgl43:	cjne	R7,#03H,vgl44
	jnb	DCF77_BITMERK.0,byte43clr  

	setb	DCF77_DATA4.3 		  
	jmp	vglend4
byte43clr:
	clr	DCF77_DATA4.3
	jmp	vglend4
;--4---
vgl44:	cjne	R7,#04H,vgl45
	jnb	DCF77_BITMERK.0,byte44clr  

	setb	DCF77_DATA4.4 		  
	jmp	vglend4
byte44clr:
	clr	DCF77_DATA4.4
	jmp	vglend4
;--5---
vgl45:	cjne	R7,#05H,vgl46
	jnb	DCF77_BITMERK.0,byte45clr  

	setb	DCF77_DATA4.5 		  
	jmp	vglend4
byte45clr:
	clr	DCF77_DATA4.5
	jmp	vglend4
;--6---
vgl46:	cjne	R7,#06H,vgl47
	jnb	DCF77_BITMERK.0,byte46clr  

	setb	DCF77_DATA4.6 		  
	jmp	vglend4
byte46clr:
	clr	DCF77_DATA4.6
	jmp	vglend4
;--7---
vgl47:	cjne	R7,#07H,vglend4
	jnb	DCF77_BITMERK.0,byte47clr  

	setb	DCF77_DATA4.7 		  
	jmp	vglend4
byte47clr:
	clr	DCF77_DATA4.7
	jmp	vglend4

vglend4:
	ljmp	vglend

;******;******

vglbyte5:
	cjne	A,#05H,vgl5uml
	mov	R7,B
;--0--					
vgl50:	cjne	R7,#00H,vgl51
	jnb	DCF77_BITMERK.0,byte50clr  

	setb	DCF77_DATA5.0  		  
	jmp	vglend5
byte50clr:
	clr	DCF77_DATA5.0
	jmp	vglend5					
;------
vgl5uml:
	jmp	vglbyte6
;--1---
vgl51:	cjne	R7,#01H,vgl52
	jnb	DCF77_BITMERK.0,byte51clr  

	setb	DCF77_DATA5.1  		  
	jmp	vglend5
byte51clr:
	clr	DCF77_DATA5.1
	jmp	vglend5
;--2---
vgl52:	cjne	R7,#02H,vgl53
	jnb	DCF77_BITMERK.0,byte52clr  

	setb	DCF77_DATA5.2  		  
	jmp	vglend5
byte52clr:
	clr	DCF77_DATA5.2
	jmp	vglend5
;--3---
vgl53:	cjne	R7,#03H,vgl54
	jnb	DCF77_BITMERK.0,byte53clr  

	setb	DCF77_DATA5.3 		  
	jmp	vglend5
byte53clr:
	clr	DCF77_DATA5.3
	jmp	vglend5
;--4---
vgl54:	cjne	R7,#04H,vgl55
	jnb	DCF77_BITMERK.0,byte54clr  

	setb	DCF77_DATA5.4 		  
	jmp	vglend5
byte54clr:
	clr	DCF77_DATA5.4
	jmp	vglend5
;--5---
vgl55:	cjne	R7,#05H,vgl56
	jnb	DCF77_BITMERK.0,byte55clr  

	setb	DCF77_DATA5.5 		  
	jmp	vglend5
byte55clr:
	clr	DCF77_DATA5.5
	jmp	vglend5
;--6---
vgl56:	cjne	R7,#06H,vgl57
	jnb	DCF77_BITMERK.0,byte56clr  

	setb	DCF77_DATA5.6 		  
	jmp	vglend5
byte56clr:
	clr	DCF77_DATA5.6
	jmp	vglend5
;--7---
vgl57:	cjne	R7,#07H,vglend5
	jnb	DCF77_BITMERK.0,byte57clr  

	setb	DCF77_DATA5.7 		  
	jmp	vglend5
byte57clr:
	clr	DCF77_DATA5.7
	jmp	vglend5

vglend5:
	ljmp	vglend

;******;******

vglbyte6:
	cjne	A,#06H,vgl6uml
	mov	R7,B
;--0--					
vgl60:	cjne	R7,#00H,vgl61
	jnb	DCF77_BITMERK.0,byte60clr  

	setb	DCF77_DATA6.0  		  
	jmp	vglend6
byte60clr:
	clr	DCF77_DATA6.0
	jmp	vglend6					
;------
vgl6uml:
	jmp	vglbyte7
;--1---
vgl61:	cjne	R7,#01H,vgl62
	jnb	DCF77_BITMERK.0,byte61clr  

	setb	DCF77_DATA6.1  		  
	jmp	vglend6
byte61clr:
	clr	DCF77_DATA6.1
	jmp	vglend6
;--2---
vgl62:	cjne	R7,#02H,vgl63
	jnb	DCF77_BITMERK.0,byte62clr  

	setb	DCF77_DATA6.2  		  
	jmp	vglend6
byte62clr:
	clr	DCF77_DATA6.2
	jmp	vglend6
;--3---
vgl63:	cjne	R7,#03H,vgl64
	jnb	DCF77_BITMERK.0,byte63clr  

	setb	DCF77_DATA6.3 		  
	jmp	vglend6
byte63clr:
	clr	DCF77_DATA6.3
	jmp	vglend6
;--4---
vgl64:	cjne	R7,#04H,vgl65
	jnb	DCF77_BITMERK.0,byte64clr  

	setb	DCF77_DATA6.4 		  
	jmp	vglend6
byte64clr:
	clr	DCF77_DATA6.4
	jmp	vglend6
;--5---
vgl65:	cjne	R7,#05H,vgl66
	jnb	DCF77_BITMERK.0,byte65clr  

	setb	DCF77_DATA6.5 		  
	jmp	vglend6
byte65clr:
	clr	DCF77_DATA6.5
	jmp	vglend6
;--6---
vgl66:	cjne	R7,#06H,vgl67
	jnb	DCF77_BITMERK.0,byte66clr  

	setb	DCF77_DATA6.6 		  
	jmp	vglend6
byte66clr:
	clr	DCF77_DATA6.6
	jmp	vglend6
;--7---
vgl67:	cjne	R7,#07H,vglend6
	jnb	DCF77_BITMERK.0,byte67clr  

	setb	DCF77_DATA6.7 		  
	jmp	vglend6
byte67clr:
	clr	DCF77_DATA6.7
	jmp	vglend6

vglend6:
	ljmp	vglend

;******;******

vglbyte7:
	cjne	A,#07H,vgl7uml
	mov	R7,B
;--0--					
vgl70:	cjne	R7,#00H,vgl71
	jnb	DCF77_BITMERK.0,byte70clr  

	setb	DCF77_DATA7.0  		  
	jmp	vglend7
byte70clr:
	clr	DCF77_DATA7.0
	jmp	vglend7					
;------
vgl7uml:
	jmp	vglend
;--1---
vgl71:	cjne	R7,#01H,vgl72
	jnb	DCF77_BITMERK.0,byte71clr  

	setb	DCF77_DATA7.1  		  
	jmp	vglend7
byte71clr:
	clr	DCF77_DATA7.1
	jmp	vglend7
;--2---
vgl72:	cjne	R7,#02H,vgl7uml
	jnb	DCF77_BITMERK.0,byte72clr  

	setb	DCF77_DATA7.2  		  
	jmp	vglend7
byte72clr:
	clr	DCF77_DATA7.2
	jmp	vglend7
;--3---
;	; Bits 3 ... 7 not used, always set to zero
;--7--- 

vglend7:
	clr	DCF77_DATA7.3	; Bits 3 ... 7 not used
	clr	DCF77_DATA7.4	; always set to zero
	clr	DCF77_DATA7.5
	clr	DCF77_DATA7.6	; these bits are "DCF77-bits"
	clr	DCF77_DATA7.7	; 59 ... 63

;	ljmp	vglend

;******

vglend:	

;******	

	inc	DCF77_BITNR		; Bitnummer fuer naechstes Bit
					; hochzaehlen

	mov	DCF77_CNT_LOW,#00H	; Impulslaenge zuruecksetzen
	;jmp	count_highs

count_highs:
	
	inc	DCF77_CNT_HIGH		;increment Zaehler für High-Bits

overflow_avoid:

	mov	A,DCF77_CNT_HIGH
	cjne	A,#DCF77_COMP_59,popweg		; kein overflow zu erwarten

	mov	DCF77_CNT_HIGH,#DCF77_OVER_DEC	; Counter wuerde ueberlaufen
						; --> kleineren Wert setzen

		; jetzt ist die Sekunde 59 ohne LOW Impuls angekommen
		; daher DCF77_BITNR auf 0 zurücksetzen

	mov	DCF77_BITNR,#00H	
	;jmp	popweg

popweg:	
	pop	DCF77_PUSHPOP
	mov	R7,DCF77_PUSHPOP
	pop	B	
	pop	ACC
	pop	PSW

	reti		

;*****************************************************************************
; ENDE DES QUELLTEXTES
;*****************************************************************************

