
;-----------------------------------------------------------------
; Name:			Output Compare Test.asm
; Description:	Test Output Compare PWM Mode 8 Functionality.
;				new clock speed at 16 MHz

; Author:		Max Koessick
; Class:		EEL5666C, Intelligent Machine Design Lab
; Date:			July 29, 2003
; Revision		1.a

; General Info:
; Servo period is 20ms; i.e. the servo is sent a 1.0-2.0ms pulse 
; 	every 20 ms.  Using a clock speed of 16 MHz/256(prescaler), the 
;	new clock is equal to 16us.  A TOP value must be defined in order 
;	to create the proper PWM.  The value for TOP is (20ms/2)/16us.  The TCNT1 
;	register counts to this value and then back down again.  A compare 
;	match is made on both the upcount and downcount.  These 2 compare
;	matches generate the PWM.

;	Formulas:
;		(20ms/2)/16us=625=0x271=TOP
;			*TCNT counts up to TOP and back down again, so desired 
;			 period=TOP*2
;			*NEUTRAL (1.5ms)--Compare match made twice while upcounting and
;			 downcounting.  Needed period = .75ms.
;			 .75ms/16us=47 clocks.  TOP - 47 = OCR1A
;			 Experiment with this number to get the servo in *exact* neutral
;			 postion
;			*+90 (2.0ms) Similiar to above
;			*-90 (1.0ms) Ditto
			
;-----------------------------------------------------------------
.nolist
.include "m128def.inc"
.list
; Interrupt service vectors

.org $0000
	rjmp Reset						; Reset vector

	
;-----------------------------------------------------------------
; Register defines for main loop
;-----------------------------------------------------------------


.def		mpr		=r16			; defines multipurpose register
.def		mpr2	=r17			; multipurpose register 2
.def		delay	=r18			; servo direction register (values 1-3)
.def		delay2	=r19			; General Purpose Delay Register
.def		delay3	=r20			; General Purpose Delay Register


; Equate statements

.equ		L90H 	= 	$4a			; Left 90 degrees upper byte
.equ		L90L	=	$38
.equ		NH		= 	$48			; Neutral Position High Byte
.equ		NL		=	$44
.equ		R90H 	= 	$46			; Right 90 deg. High Byte
.equ		R90L	=	$50
.equ		TOPH	=	$4e			; Top High Byte
.equ		TOPL	=	$20
.equ		ZERO	= 	$00
.equ		ONEs	=	$FF


;-----------------------------------------------------------------
; Reset vector
;-----------------------------------------------------------------

Reset:
;-----Setting Stackpointer----------------------------------------
	ldi		MPR,low(RAMEND)			; Set stackptr to ram end
	out		SPL,MPR
	ldi 	MPR, high(RAMEND)
	out 	SPH, MPR

;-----Set Port Directions-----------------------------------------
	ser		mpr						; Set TEMP to $FF to...
	out		DDRB,mpr				; ...set data direction to "out"
	out		DDRE,mpr
;	ldi		mpr2,(1<<PB5)|(1<<PB6)|(1<<PB7)
;	out		PortB,mpr2
;	ldi		mpr2,(1<<PE3)|(1<<PE4)|(1<<PE5)
;	out		PORTE,mpr2

	out 	DDRC,mpr
	out		PORTC,mpr	

	clr 	mpr						; clear all bits
	out 	DDRD,mpr				; Set 'D' as input

;-----Disable A/D-------------------------------------------------
	ldi		mpr,$80					; Disable ADC
	out		ACSR,mpr

;-----Enable Output Compare 1A-C----------------------------------------

	ldi		mpr,0b11111100			; Set Timer1 to PWM mode 8
	out		TCCR1A,mpr
	ldi		r30,TCCR3B				; Set Timer3 to PWM mode 8
	st		Z,mpr

	ldi		mpr,0b00010100			; Set Timer1 to Prescale - 256
	out		TCCR1B,mpr
	ldi		r30,TCCR3B
	st		Z,mpr					; Set Timer3 to Prescale - 256

	ldi		mpr,TOPH
	ldi		mpr2,TOPL
	out		ICR1H,mpr
	out		ICR1L,mpr2				; Set Top Value to 625 = $4e20
									; Period = 20ms
	ldi		r30,ICR3H				; Set same values for Timer3
	st		Z,mpr
	ldi		r30,ICR3L
	st		Z,mpr2

	ldi		mpr,ZERO				; Clear the TCNT1 register
	out		TCNT1H,mpr
	out		TCNT1L,mpr

	ldi		r30,TCNT3H
	st		Z,mpr
	ldi		r30,TCNT3L
	st		Z,mpr

mainloop:

	ldi		r30,OCR1AH
	ldi		mpr,L90L
	st		Z,mpr

	ldi		r30,OCR1AL
	ldi		mpr,L90H
	st		Z,mpr

	ldi		r30,OCR3AH
	ldi		mpr,L90L
	st		Z,mpr

	ldi		r30,OCR3AL
	ldi		mpr,L90H
	st		Z,mpr
;mainloop:

	rjmp mainloop					;loop here forever.

