;****************************************************************
;                     McCoi II- Ketten Öler			;
;								;
;          AVR 90S1200, 4 MHz, externer Oszillator		;
;								;
;      (c) 2001-2003 MDvP                   mailto:MDvP@gmx.de	;
;****************************************************************
; Changes:							;
;	V1.0	Funktionsfähig
;	V1.1	Stellung 0: Testmodus
;	V1.2	LEDs zur Kontrolle von Rheed und Regensensor
;	V2.0	Low-Power, kann an Batterie angeschlossen beleiben, 
;		Layoutänderung
;	V2.1	10.04.2002
;		Bugfix: SREGSave
;		Vorpumpen auf 50 Pulse begrenzt
;		Im Normalbetrieb minimum 10 Sekunden zwischen Pumpen
;	V2.2	24.07.2002
;		Kein Pumpen bei V<15km/h (im Normalmode)
;		Initialisierung sicherer
;	V2.3	31.07.2002
;		Bugfix: Die Sicherheitsvorkehrungen bewirkten Mangelschmierung
;		bei höheren Geschwindigkeiten
;	V2.4	19.01.2003
;		Tropfenzähler zur Tankkontrolle
;		Tank leer => Rheed LED Dauerleuchten!
;		Initalisierung und Abschaltung bei geschaltetem Rheed geändert
;		Pumpenabschaltung durch Timerinterrupt
;		NC-Step-Version integriert (auskommentiert)
;	V2.a	Aprilia-Version für Hall-Geber, 
;		kein Sleep, muß über Zündung angeschlossen werden
;****************************************************************

.include "1200def.inc"		; Definitionen für den AT90S1200
;.include "2313def.inc"		; Definitionen für den AT90S2313 (NC-Step-Version)

				; Radkonstanten für je 250m
.equ	Rad		=160	; 190/50-17 U=1,96m

.equ	RheedSW		=PD2	;(INT0)
.equ	Taste		=PD3
.equ	RheedLED	=PD4
.equ	RegenLED	=PD5

;-----low Register


;-----high Register
.def	Cnt	=r16		; Zähler für je 250m
.def	Cnt1	=r17
.def	Wert	=r18		; Vergleichswert
.def	Wert_in	=r19		; Vergleichswert
.def	c0	=r20		; Zähler delay-Schleife
.def	c1	=r21		; Zähler innere delay-Schleife
.def	c2	=r22		; Zähler Frequenz-Schleife
.def	cP	=r23		; Zähler Pumpenpulse beim Vorpumpen
.def	temp	=r24		; Temporär-Register
.def	SREGSave=r25		; Retten des SREG bei Interrupt
.def	TimeP	=r26		; Zeitzähler zwischen Prumstößen
.def	Time1	=r27		; Zeitzähler
.def	Time2	=r28		; Zeitzähler für Ausschaltung und Geschwindigkeit


.CSEG				; Code Segment

; -----Interrupts
.ORG 	$000
		rjmp	Reset		; Program Start
.ORG 	INT0addr
		rjmp	Rheed		; Rheed Impuls
.ORG 	OVF0addr
		cbi	PORTD,6		; Pumpe ausschalten
.ORG	ACIaddr
		reti

.db "McCoi2.a"
.db "19.04.03"
.db "(c) ",$4D,$44,$76,$50 		; Signatur
;****************************************************************
.macro	delay				; Warteschleife 1 ms pro übergebenen Wert
		ldi 	c0,(@0<<2)	; max 63 ms!
d0:		ldi 	c1,249
d1:		nop
		dec 	c1
		brne 	d1
		dec 	c0
		brne 	d0
.endmacro
;****************************************************************
.macro	freq				; Warteschleife 0,25 ms
		ldi 	c2,250
f0:		nop
		dec 	c2
		brne 	f0
.endmacro
;****************************************************************
; Initialisierung						;
;****************************************************************
Reset:		wdr
		ldi 	temp,0b00001000	; (MDvP-Version)
		out 	PORTD,temp	; Pull-ups einschalten, LEDs aus
		ldi 	temp,0b00001111	; 
		out 	WDTCR,temp	; Watchdog 2s
		ldi	temp,0b00110011	; Int 0 steigende Flanke, Power down
		out	MCUCR,temp 
		ldi 	temp,0b01110011	; Counter PD3 und Int0 PD2 als Eingang
		out 	DDRD,temp	
		ldi 	temp,0b11110000	; 
		out 	PORTB,temp	; Port B Pull-ups im oberen Nibble ein
		ldi 	temp,0b00001100	; Komparator und
		out 	DDRB,temp	; oberes Nibble Port B als Eingang 
		ldi	temp,0b01000000
		out	GIMSK,temp	; Int 0 Enable
		cbi	ACSR,ACD	; Komparator an
		ldi	temp,0b00000101
		out 	TCCR0,temp	; Counter prescale 1024
		clr	temp
		out 	TCNT0,temp	; reset Counter
		ldi	temp,0b00000010
		out 	TIMSK,temp	; Counter Overflow Interrupt enable
		clr	cP		; Pulszähler zurücksetzen
		clr	Cnt		; Umdrehungszähler löschen
		clr	Cnt1		; 250m-Zähler zurücksetzen
		clr	TimeP
		clr	Time1
		clr	Time2
		ldi	Wert,10		; erstmal auf 2500m initialisieren
		sei			; Interrupts ein
;****************************************************************
; Hauptschleife liest den Wegstrecken-Wert ein			;
;****************************************************************
Loop:		wdr			; watchdog reset
		sbi     PORTB,PB2	; Regensensor an
		cbi	PORTB,PB3
		freq			; 0,25ms warten
		clr	Wert_in		; Vergleichswert einlesen
		sbis	PINB,4
		sbr	Wert_in,4
		sbis	PINB,5		; Bit 1 und 2 des Hex-Schalters
		sbr	Wert_in,16	; im Layout vertauscht
		sbis	PINB,6		; also zurücktauschen
		sbr	Wert_in,8
		sbis	PINB,7
		sbr	Wert_in,32
		cbi	PORTD,RheedLED	; LED aus (MDvP-Version)
		cbi	PORTD,RegenLED	; LED aus (MDvP-Version)
		tst	Wert_in
		brne	NoTest		; Testmode?
		clr	Time1		; Abschaltung verhindern
		sbis	PIND,RheedSW	; Rheed kontakt geschlossen?
		sbi	PORTD,RheedLED	; LED an
		sbic	ACSR,ACO	; Regen?
		sbi	PORTD,RegenLED	; LED an
		sbic	PIND,Taste	; Taste nicht gedrückt
		ldi	cP,50		; dann Zähler laden
		tst	cP		; Anzahl Pulse abgelaufen?
		breq	NoTest		; Ja, dann weiter
		sbic	PIND,Taste	; Taste gedrückt?
		rjmp	NoTest		; Nein -> Weiter, sonst
		delay	50
		sbic	PIND,Taste	; Taste immer noch gedrückt? (Entprellzeit)
		rjmp	NoTest		; Nein -> Weiter, sonst
		dec	cP		; Pulszähler 
		sbi 	PORTD,6		; Pumpe 50 ms an
		delay	50
		cbi	PORTD,6		; Pumpe aus
NoTest:		subi	Wert_in,-3	; Offset addieren (min 750m)
		sbic	ACSR,ACO	; wenn Regen
		subi	Wert_in,2	; dann 500 m abziehen
		mov	Wert,Wert_in
		cbi     PORTB,PB2       ; Regensensor negativ
		sbi	PORTB,PB3
		freq			; 0,25ms warten
		inc	Time1		; Zeitzähler ~32sec
		brne	Loop
		sbrs	TimeP,7
		inc	TimeP
		sbrs	Time2,7
		inc	Time2
LoopEnd:	rjmp	Loop		; wieder von vorne beginnen
;****************************************************************
; Rheed Impuls, Zählen			;
;****************************************************************
Rheed:		sbis	PIND,Taste	; Taste gedrückt?
		reti			; Wenn Ja -> Zurück
		in	SREGSave,SREG	; Status-Reg sichern
		inc	Cnt		; Umdrehungszähler erhöhen
		cpi	Cnt,Rad		; Radkonstante erreicht?
		brne	Rh_end
		clr	Cnt		; Umdrehungszähler löschen
		inc	Cnt1		; 250m-Zähler erhöhen
		cp	Cnt1,Wert	; Vergleichswert erreicht?
		brlo	Rh_end
		clr	Cnt1		; 250m-Zähler zurücksetzen
		cpi	TimeP,80	; nach etwa 10 s darf wieder gepumpt werden
		brlo	Rh_end
		cpi	Time2,4		; nur bei > 15 km/h pumpen
		brsh	Rh_wait		; sonst warten
		sbi 	PORTD,6		; Pumpe an
		clr	TimeP		; Zeitzähler für Pumpe zurücksetzen
		out 	TCNT0,TimeP	; reset Counter
		ldi	temp,0b00000010
		out 	TIFR,temp	; Counter Overflow Interrupt-Flag löschen
Rh_end:		clr	Time2		; Zeitzähler zurücksetzen
		out	SREG,SREGSave	; Status Reg zurückschreiben
		reti	
Rh_wait:	mov	Cnt1,Wert
		dec	Cnt1
		ldi	Cnt,Rad-1
		clr	Time2
		out	SREG,SREGSave	; Status Reg zurückschreiben
		reti	
;****************************************************************
