;****************************************************************
;                     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)
;****************************************************************

.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		=128	; 160/60-17 U=1,96m
;.equ	Rad		=126	; 180/55-17 U=1,98m
;.equ	Rad		=124	; 190/55-17 U=2,01m
;.equ	Rad		=121	; 110/90-18 2,06
;.equ	Rad		=118	; 120/90-18 2,11
;.equ	Rad		=124	; 130/80-17

.equ	Tank		=200	; 200 ml Tank voll
.equ	ml		=16	; 16 Tropfen pro ml


.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

.def	mlCnt	=r29		; Tankinhaltszähler
.def	TankCnt	=r30		; Tropfenzähler

.CSEG				; Code Segment

; -----Interrupts
.ORG 	$000
		rjmp	Reset		; Program Start
.ORG 	INT0addr
		rjmp	Rheed		; Rheed Impuls
.ORG 	OVF0addr
		cbi	PORTD,6		; Pumpe ausschalten
		reti

.db "McCoi2.4"
.db "19.01.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
;nc-step;	ldi	temp,low(ramend)	; initialize stackpointer <T.O.>
;nc-step;	out	spl,temp		; (not needed for 90S1200)
		ldi 	temp,0b00001100	; (MDvP-Version)
;nc-step;	ldi 	temp,0b00111100	; (NC-Step-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,100
wait:		dec	temp		; Wartezeit für RC-Entprellglieder
		brne	wait
		sbic	PIND,RheedSW	; Rheed geschaltet
		rjmp	Start		; Nein, dann start, sonst
		cbi	PORTD,RheedSW	; Pullup aus
		wdr
		sleep			; weiter schlafen
Start:		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	Time2
		clr	cP		; Pulszähler zurücksetzen
		clr	Cnt		; Umdrehungszähler löschen
		clr	Cnt1		; 250m-Zähler zurücksetzen
		clr	TimeP
		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,1
		sbis	PINB,5		; Bit 1 und 2 des Hex-Schalters
		sbr	Wert_in,4	; im Layout vertauscht
		sbis	PINB,6		; also zurücktauschen
		sbr	Wert_in,2
		sbis	PINB,7
		sbr	Wert_in,8
		cbi	PORTD,RheedLED	; LED aus (MDvP-Version)
		cbi	PORTD,RegenLED	; LED aus (MDvP-Version)
;nc-step;	sbi	PORTD,RheedLED	; LED aus (NC-Step-Version)
;nc-step;	sbi	PORTD,RegenLED	; LED aus (NC-Step-Version)
		tst	TankCnt
		brne	Voll
		sbi	PORTD,RheedLED	; Tank leer -> LED an (MDvP-Version)
;nc-step;	cbi	PORTD,RheedLED	; Tank leer -> LED an (NC-Step-Version)
Voll:		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
		cli			; Interrupt verhindern
Pump:		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
		wdr
		dec	cP		; Pulszähler 
		sbi 	PORTD,6		; Pumpe 50 ms an
		delay	50
		cbi	PORTD,6		; Pumpe aus
		ldi	mlCnt,ml	; Tank voll beim Vorpumpen
		ldi	TankCnt,Tank
NoTest:		sei
		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	LoopEnd
		sbrs	TimeP,7
		inc	TimeP		; Zeitzähler erhöhen
		inc	Time2
		brne	LoopEnd		; wenn Zeit abgelaufen, dann
		cli
		ldi 	temp,0b00000100	; (MDvP-Version)
;nc-step;	ldi 	temp,0b00110100	; (NC-Step-Version)
		out 	PORTD,temp	; Pull-ups und LEDs ausschalten, außer INT0
		clr	temp
		out 	PORTB,temp	; Port B Pull-ups und LEDs aus
		sbi	ACSR,ACD	; Komparator aus
		out 	TCCR0,temp	; Counter aus
		sbis	PIND,RheedSW	; Wenn Rheed geschaltet
		rjmp	Ausnahme	; Ausschalten, sonst 
;nc-step;	ldi	temp,0b00011111	; Watchdog aus Sequenz (90S2313-Version)
;nc-step;	out	WDTCR,temp
		ldi	temp,0b00010111	; Watchdog aus 
		out	WDTCR,temp
		ldi	temp,0b00110000	; Int 0 Level-Irq, Powerdown
		out	MCUCR,temp
		sei
		wdr
		sleep
		ldi 	temp,0b00001111	; 
		out 	WDTCR,temp	; Watchdog an 2s
		ldi	temp,0b00110011	; Int 0 steigende Flanke, Power down
		out	MCUCR,temp 
		cbi	ACSR,ACD	; Komparator an
		ldi 	temp,0b11110000	; Port B Pull-ups im oberen Nibble ein
		out 	PORTB,temp	
		ldi 	temp,0b00001100	; Port D Pull-ups einschalten
		out 	PORTD,temp	
		ldi	temp,0b00000101	; Counter an, prescale 1024
		out 	TCCR0,temp	
LoopEnd:	rjmp	Loop		; wieder von vorne beginnen
Ausnahme:	cbi	PORTD,RheedSW	; Pullup aus
		wdr
		sleep
		rjmp	Reset
;****************************************************************
; 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,70	; 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
		dec	mlCnt		; ein Tropfen weniger
		brne	Rh_end		; wenn ein ml weniger
		ldi	mlCnt,ml	; Tropfenzähler laden
		tst	TankCnt		; Wenn Tank noch nicht leer
		breq	Rh_end
		dec	TankCnt		; ein ml weniger
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	
;****************************************************************

