;****************************************************************
;                     McCoi - Ketten Öler			;
;								;
;          AVR 90S1200, 4 MHz, externer Oszillator		;
;								;
;	Changes:						;
;	17.4.	bug bei Zählroutine korrigiert			;
;	20.4.	Autopumpen bei Hex-Schalterstellung 0		;
;		sonst Einzelpulse				;
;		LEDs zum testen		 			;
;								;
;      (c) 2001 MDvP                   mailto:MDvP@gmx.de	;
;****************************************************************

.include "1200def.inc"		; Definitionen für den AT90S1200

				; 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	RheedLED	=PD3
.equ	RegenLED	=PD5
.equ	RheedSW		=PD4

;-----Register
.def	Cnt	=r16		; Zähler für je 250m
.def	Wert	=r17		; Vergleichswert
.def	Wert_in	=r18
.def	c0	=r19		; Zähler delay-Schleife
.def	c1	=r20		; Zähler innere delay-Schleife
.def	c2	=r21		; Zähler Frequenz-Schleife
.def	temp	=r22		; Temporär-Register
.def	temp1	=r23		; Temporär-Register


.CSEG				; Code Segment

; -----Interrupts
.ORG 	$000
		rjmp	Reset		; Program Start
.ORG 	INT0addr
		rjmp	Taste		; Taste gedrückt - INT 0
.ORG 	OVF0addr
		rjmp	Pumpe		; Counter Overflow, alle 250m
.ORG	ACIaddr
		reti

.db $28,$63,$29,$32,$30,$30,$31,$20,$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:		ldi 	temp,0b00001110	; 
		out 	WDTCR,temp	; Watchdog 1s
		ldi	temp,0b00000010	; Int 0 fallende Flanke 
		out	MCUCR,temp	; (ein Pumpstoss pro Tastendruck) 
		ldi	temp,0b01000000
		out	GIMSK,temp	; Int 0 Enable
		ldi	temp,0b00000010
		out 	TIMSK,temp	; Counter Overflow Interrupt Enable
		ldi 	temp,0b00001100	; Komparator und
		out 	DDRB,temp	; oberes Nibble Port B als Eingang 
		ldi 	temp,0b11110000	; 
		out 	PORTB,temp	; Port B Pull-ups im oberen Nibble ein
		ldi 	temp,0b01101011
		out 	DDRD,temp	; Counter PD4 und Int PD2 als Eingang
		ldi 	temp,0b00010100
		out 	PORTD,temp	; Pull-ups einschalten
		sbi	PORTD,RheedLED	; LED aus
		sbi	PORTD,RegenLED	; LED aus
		ldi 	temp,0b00000110
		out 	TCCR0,temp	; Counter 0 fallende Flanke
		ldi	temp,Rad	
		out 	TCNT0,temp	; Radkonstante in Counter
		clr 	Cnt		; 250 m-Zähler reset
		sei			; Interrupts ein
;****************************************************************
; Hauptschleife, erzeugt Wechselspannung für Betauungssensor	;
; und liest den Wegstrecken-Wert ein				;
;****************************************************************
Loop:		wdr			; watchdog reset
		cbi	PORTB,2		; Sensor-Spannung positiv
		sbi	PORTB,3
		freq			; 0,25 ms delay (für 2kHz)
		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
		tst	Wert_in		; Schalterstellung 0?
		brne	L1
		ldi	temp,0b00000000	; Int 0 low level (Dauerpumpen)
		sbis	PIND,RheedSW	; Wenn Rheed
		cbi	PORTD,RheedLED	; LED an
		sbic	PIND,RheedSW	; sonst
		sbi	PORTD,RheedLED	; LED aus
		sbis	ACSR,ACO	; Wenn Regen:
		cbi	PORTD,RegenLED	; LED an
		sbic	ACSR,ACO	; Wenn kein Regen:
		sbi	PORTD,RegenLED	; LED aus
		rjmp	L2
L1:		sbi	PORTD,RegenLED	; LEDs aus
		sbi	PORTD,RheedLED
		ldi	temp,0b00000010	; Int 0 fallende Flanke 
L2:		out	MCUCR,temp
		subi	Wert_in,-3	; Offset addieren (min 750m)
		sbis	ACSR,ACO	; Wenn Regen:
		subi	Wert_in,2	; dann 500 m abziehen
		mov	Wert,Wert_in	; Sichern
		cbi	PORTB,3		; Sensor-Spannung negativ
		sbi	PORTB,2
		freq			; 0,25 ms delay (für 2kHz)
		rjmp	Loop		; wieder von vorne beginnen

;****************************************************************
; Counter overflow, alle 250m				;
;****************************************************************
Pumpe:		ldi	temp1,Rad
		out 	TCNT0,temp1	; Timer 0 reset
		inc	Cnt		; weiterzählen
		cp	Cnt,Wert	; Wert erreicht?
		brlo	P1		; nein->dann nix tun, sonst:
		clr	Cnt		; Zähler zurücksetzten
		sbi 	PORTD,6		; Pumpe an
		delay	50		; 50 ms warten
		cbi	PORTD,6		; Pumpe aus
P1:		reti

;****************************************************************
; Interrupt, gedrückte Taste, Vorpumpen 			;
; wenn der Interrupt auf fallende Flanke gesetzt ist 		;
;               erfolgt ein Pumpstoß pro Tastendruck		;
; wenn er auf low-level (MCUCR=0) steht				;
;               erfolgt Dauerbetrieb mit 10 Hz			;
;****************************************************************
Taste:		sbi 	PORTD,6		; Pumpe 50 ms an
		delay	50
		cbi	PORTD,6		; Pumpe aus
		delay	50		; 50 ms warten
		reti	
;****************************************************************
