;*************************************************************************
; 
; Controller is AT90S2313
; 
; Writen by Kostas Elenis 
; Rev 1
; 05/02/2002
;
; This program mesures two positive voltages (samples) connected to AIN1
; through a 4053 CMOS multiplexer controlled by AVR(PB2), and also checks
; for a key is pressed, connected at PB2, PD3 (high level).
; The voltage connected to AIN1 is compared with a continiously rising
; voltage at AIN0 that is provited by a A/D (R-2R Ladder) connected at
; PD3(lsb)..PD6 and PB4..PB7(msb)
; The results (bytes) of the two scaned voltages with a sync byte, a key
; pressed byte, a voltage checksum byte are transmited to UART
;
;*************************************************************************



.include "2313def.inc

;********************** register definitions ***********************

	.def  	foo	=r16     	;General use registers
	.def  	button	=r17
	.def  	Trim	=r18
	.def  	Heading	=r19
	.def  	adv	=r20
	.def  	mask	=r21
	.def	chksuml	=r22
	.def	chksumh	=r23

;********************** general declarations ***********************

	;Port D pins	
	.equ	Lights	=2

	;Port B pins
	.equ	Horn	=3

;***************** Baud Rates for a 4 Mhz Crystal ******************

	.equ  	B2400 =103
	.equ  	B4800 =51
	.equ  	B9600 =25
	.equ  	B19200=12

;*********************** Set UART Baud rate ************************

	.equ  	BAUD = B9600

;********************* Initialize hardware ports *******************

reset:
   	ldi	foo,low(RAMEND)
	out	SPL,foo			;Set stack pointer to last internal RAM location
	ldi   	foo,BAUD
   	out   	UBRR,foo    		;Set Baud rate
      	ldi   	foo,0b00001000    	;Enable: Tx without INT 
   	out   	UCR,foo
	ldi   	foo,0b11110100		;set PORTB to output 
	out   	DDRB,foo		;except AIN1,AIN0 and PB3 (inputs)
     	ldi   	foo,0b01111010    	;set PORTD to output 
   	out   	DDRD,foo		;except RxD,PD2 (inputs)
Start:
	clr	chksuml
	clr	chksumh
	clr	button
	sbic	PINB,Horn		;scan PB3 for "1"
	ori	button,0b11110000	;set key variable high if "1"
	sbic	PIND,Lights		;scan PD2 for "1"
	ori	button,0b00001111	;set key variable high if "1"
	ldi	mask,0b00000100	;select speed trimmer
	rcall	Get_Trim		;get trim voltage
	mov	Trim,adv
	com	adv			;calculate delay
	breq	Loop1
	rcall	SetDelay
Loop1:	
	mov	chksuml,Trim		;start add to checksum
	clr	mask			;select speed trimmer
	rcall	Get_Trim		;get trim voltage
	mov	Heading,adv
	com	adv			;calculate delay
	breq	Loop2
	rcall	SetDelay
Loop2:	
	add	chksuml,Heading	;add to checksum
	brcc	Loop3
	inc	chksumh	
Loop3:					
	add	chksuml,button		;calculate checksum
	brcc	Loop4
	inc	chksumh	
Loop4:					;start transmiting byte package
	ldi	adv,0b10101010
	rcall	UartSend		;First send sync byte $AA
	mov	adv,Trim
	rcall	UartSend		;Send speed byte
	mov	adv,Heading
	rcall	UartSend		;Send heading byte
	mov	adv,button
	rcall	UartSend		;Send key variable byte
	mov	adv,chksuml
	rcall	UartSend		;Send Checksum Low Byte
	mov	adv,chksumh
	rcall	UartSend		;Send Checksum High Byte
	rjmp	Start
SetDelay:
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	rcall	Delay_50us
	dec	adv
	breq	exit_b
	rjmp	SetDelay
Get_Trim:
      	out   	PORTB,mask		;firt select trim and clear high bits
	clr   	adv
ramp:	
	mov	foo,adv
	andi	foo,0b00001111		;mask four low bit of byte "foo"
	swap	foo
	lsr	foo
	out   	PORTD,foo
	mov	foo,adv
	andi	foo,0b11110000		;mask four high bit of byte "foo"
	or	foo,mask
	out   	PORTB,foo
	rcall	Delay_50us
	sbic  	ACSR,ACO 		;If D/A voltage > Vin
     	ret				;exit and report value
	nop
  	inc	adv
	breq	exit_a			;exit if overflow and report max value
	rjmp  	ramp
exit_a:
	ser	adv
exit_b:	
	ret
UartSend:
	sbis 	Usr,UDRE     		;wait until the last byte was transmited
	rjmp 	UartSend
	out 	udr,adv     		;Now its ok to send	
	ret
Delay_50us:
   	ldi   	foo,0x10		;$3F = 50us
delay100:
   	dec   	foo
   	brne  	delay100
	ret

