;-----------------------------------------------------------------
; Name:			INT.asm
; Description:	Tests external interrup functionality.
; 				When a respective switch is pressed, the program will
; 				increment or decrement LEDs attached to PortB via ISR
; Author:		Max Koessick
; Class:		EEL5666C, Intelligent Machine Design Lab
; Date:			June 4, 2003
; Revision		FINAL (with EICRA!!!!)
; Changes to Date:
;				6/1/03 Working with EICRB only, 2 Ints doing dec/inc of LEDs
;				6/5/03 Fixed EICRA bug and added one more external interrupt to 
;					   prepare for servo control
;				6/14/03 Added INT4
;						Added Pullups to PORTD input pins to work with
;							bump switches.
			
;-----------------------------------------------------------------

.include "m128def.inc"

; Interrupt service vectors

.org $0000
	rjmp Reset						; Reset vector
.org INT0addr
	rjmp IntV0						; INT0 vector (ext. interrupt from pin D0)--Front Left	
.org INT1addr	
	rjmp IntV1						; INT1 vector (ext. interrupt from pin D1)--Front Right
.org INT2addr		
	rjmp IntV2						; INT2 vector (ext. interrupt from pin D2)--Left Rear
.org INT3addr			
	rjmp IntV3						; INT3 vector (ext. interrupt from pin D3)--Right Rear

; Bump Switch Map
; PD0->Front Left
; PD1->Front Right
; PD2->Left Rear
; PD3->Right Rear

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

.def		mpr=r16					; defines multipurpose register
.def		mpr2=r17				; multipurpose register 2
.def		mpr3=r18				; multipurpose register 3
.def		mpr4=r19
.def		mpr5=r20
.def		dirreg=r21

;-----------------------------------------------------------------
; 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-----------------------------------------
	ldi		mpr,(1<<PB5)|(1<<PB6)|(1<<PB7)					; Set TEMP to $FF to...
	out		DDRB,mpr					; ...set data direction to "out"

	ldi		mpr,(1<<PE3)
	out		DDRE,mpr
	
	ldi		mpr,$ff
	out		DDRC,mpr

	clr		mpr
	out		PORTC,mpr				; ...all lights off!

	clr 	mpr						; clear all bits
	ldi		mpr2,(1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)
									; Define pull ups on the input pins of PORTD
	out 	DDRD,mpr				; Set 'D' as input
	out		PORTD,mpr2


;-----Enabling Interrupts-----------------------------------------

;Clear INT0 and INT1 in EIMSK register
	in		mpr,EIMSK
	cbr		mpr,(0<<INT0)+(0<<INT1)+(0<<INT2)+(0<<INT3) ; Disable int 0,1,2 to set level control
	out		EIMSK,mpr
;Set level sense control
	ldi		r30,EICRA
	ld		mpr,Z
	sbr 	mpr,(1<<ISC00)+(1<<ISC01)+(1<<ISC10)+(1<<ISC11)+(1<<ISC20)+(1<<ISC21)+(1<<ISC30)+(1<<ISC31)				
									; Set three pairs of interrupt control bits high
	st		Z,mpr
;Clear any interrupts pending in EIFR
	in		mpr,EIFR
	sbr     mpr, (1<<INTF0)+(1<<INTF1)+(1<<INTF2)+(1<<INTF3);Set interrupt flag in EIFR
	out		EIFR,mpr
;Set INT0 and INT1 in EIMSK register
	in		mpr,EIMSK
	sbr		mpr,(1<<INT0)+(1<<INT1)+(1<<INT2)+(1<<INT3) ; int masks 0 and 1 set
	out		EIMSK,mpr

;-----Enable Output Compare 1A-C----------------------------------------

	ldi		mpr,0b11111100			; Set Timer1 to PWM mode 8
	out		TCCR1A,mpr

	ldi		mpr,0b00010011			; Prescaler = 64
	out		TCCR1B,mpr

	call	settop

;	ldi		mpr3,$02
;	ldi		mpr4,$24
;	out		OCR1AH,mpr3
;	out		OCR1AL,mpr4				; Set DIRservo = 1.5ms Neutral
;
;	ldi		mpr,$02
;	out		OCR1BH,mpr
;	ldi		mpr,$25
;	out		OCR1BL,mpr				; Set SPEEDservo = 1.5ms NeutralB

;Clear MPR2 for use as counter
	clr		mpr2
	ldi		DIRreg,$ff

;Enable global interrupts

	sei

mainloop:

	cpi		DIRreg,$00
	brne	next
	
	call	set1a

	call	set1b


	rjmp	next2
next:
	cpi		DIRreg,$01
	brne	next2	
	call 	updateOCR1b
	nop

next2:

	rjmp 	mainloop					;loop here forever.



UpdateOCR1b:

	in		mpr,SREG
		
	cli

	ldi		mpr3,$02
	ldi		mpr4,$22f
	out		OCR1AH,mpr3
	out		OCR1AL,mpr4

	ldi		mpr3,$02
	ldi		mpr4,$35
	out		OCR1BH,mpr3
	out		OCR1BL,mpr4

	out		SREG,mpr

	ret

SETtop:
	in		mpr,SREG

	cli

	ldi		mpr3,$02
	ldi		mpr4,$4c
	out		ICR1H,mpr3
	out		ICR1L,mpr4				; Set Top Value to 1177 = $499
									; Period = 20ms
	out		SREG,mpr

	ret
SET1A:
	in		mpr,SREG
		
	cli

	ldi		mpr3,$02
	ldi		mpr4,$1b
	out		OCR1AH,mpr3
	out		OCR1AL,mpr4

	out		SREG,mpr
	
	ret

set1b:
	in		mpr,SREG
		
	cli

	ldi		mpr3,$02
	ldi		mpr4,$1F
	out		OCR1BH,mpr3
	out		OCR1BL,mpr4

	out		SREG,mpr
	
	ret
;-----------------------------------------------------------------
;
; Int0 vector - decrease count

IntV0:
	ldi		mpr2,$FF
	ldi		DIRreg,$00

	rjmp	Int01				
	reti

;-----------------------------------------------------------------
;
; Int1 vector - increase count

IntV1:
	ldi 	mpr2,$01				;drop to common code to display new count
	ldi		DIRreg,$01

	rjmp	Int01

IntV2:
	ldi		mpr2,$02

	rjmp	int01

IntV3:
	ldi		mpr2,$03
	
Int01:
	mov		mpr3,mpr2				;display on LEDs
	com		mpr3
	out		PORTC,mpr3

	reti







