
;*************************************************************** 
;* Project Name        : mérés 2 házi
;* Project Description : 
; 
; Johnson-számlálós futófény; sebességét a BT0(+) és a BT1(-) módosítja
; a sebesség változtatás léptéke 100ms, a késleltetés intervalluma 100-1500ms
;
;* Author              : Szombathelyi Tamás
;* Lab_group           : i1hde15
;* Last edited         : 2008.04.27
;
;***************************************************************
;* "AVR ExperimentBoard" port assignment information:
;***************************************************************
;*
;* LED0(P):PortC.0          LED4(P):PortC.4
;* LED1(P):PortC.1          LED5(P):PortC.5
;* LED2(S):PortC.2          LED6(S):PortC.6
;* LED3(Z):PortC.3          LED7(Z):PortC.7        INT:PortE.4
;*
;* SW0:PortG.0     SW1:PortG.1     SW2:PortG.4     SW3:PortG.3
;* 
;* BT0:PortE.5     BT1:PortE.6     BT2:PortE.7     BT3:PortB.7
;*
;***************************************************************
;*
;* AIN:PortF.0     NTK:PortF.1    OPTO:PortF.2     POT:PortF.3
;*
;***************************************************************
;*
;* LCD1(VSS) = GND         LCD9(DB2): -
;* LCD2(VDD) = VCC         LCD10(DB3): -
;* LCD3(VO ) = GND         LCD11(DB4): PortA.4
;* LCD4(RS ) = PortA.0     LCD12(DB5): PortA.5
;* LCD5(R/W) = GND         LCD13(DB6): PortA.6
;* LCD6(E  ) = PortA.1     LCD14(DB7): PortA.7
;* LCD7(DB0) = -           LCD15(BLA): VCC
;* LCD8(DB1) = -           LCD16(BLK): PortB.5 (1=Backlight ON)
;*
;***************************************************************

.include "m128def.inc" ; Definition file for ATmega128 
;* Program Constants 
.equ const =$00 ; Generic Constant Structure example  
;* Program Variables Definitions 




.equ	tconst	= 10			; időzítési konstans (T = 10*10 msec)

.equ	max_delay	= 150		; maximális lépésköz     - x10ms
.equ	min_delay	= 10		; minimális lépésköz     - x10ms
.equ	delta_delay	= 10		; lépésközök különbsége  - x10ms

.equ	start_delay	= 40		; kezdeti lépésköz       - x10ms


		;***** Regiszterkiosztás ***** 

.def	temp	= r16			; ált. segédregiszter 
.def	temp2	= r17			; ált. segédreg. 2.
.def	wait	= r18			; aktuális lépésköz - x10ms
.def	buttons	= r19			;







;*************************************************************** 
;* Reset & Interrupt Vectors  
.cseg 
.org $0000 ; Define start of Code segment 
	jmp RESET ; Reset Handler, jmp is 2 word instruction 

	reti ; INT0 Handler on $0002, dummy 
	nop 
	reti ; INT1 Handler, if INTn used, 'reti' and 'nop' 
	     ; will be replaced by 'jmp INTn_Handler_Address'
	nop 
	reti ; INT2 Handler 
	nop 
	reti ; INT3 Handler 
	nop 
	reti ; INT4 Handler 
	nop 

	jmp	BT0_IRQ
	;reti ; INT5 Handler; BT0
	;nop 

	jmp	BT1_IRQ
	;reti ; INT6 Handler; BT1
	;nop 

	reti ; INT7 Handler 
	nop 
	reti ; Timer2 Compare Match Handler 
	nop 
	reti ; Timer2 Overflow Handler 
	nop 
	reti ; Timer1 Capture Event Handler 
	nop 
	reti ; Timer1 Compare Match A Handler 
	nop 
	reti ; Timer1 Compare Match B Handler 
	nop 
	reti ; Timer1 Overflow Handler 
	nop 
	
	jmp timerIRQ ; Timer0 Compare Match Handler 
	 
	
	reti ; Timer0 Overflow Handler 
	nop 
	reti ; SPI Transfer Complete Handler 
	nop 
	reti ; USART0 RX Complete Handler 
	nop 
	reti ; USART0 Data Register Empty Hanlder 
	nop 
	reti ; USART0 TX Complete Handler 
	nop 
	reti ; ADC Conversion Complete Handler 
	nop 
	reti ; EEPROM Ready Hanlder 
	nop 
	reti ; Analog Comparator Handler 
	nop 
	reti ; Timer1 Compare Match C Handler 
	nop
	reti ; Timer3 Capture Event Handler 
	nop 
	reti ; Timer3 Compare Match A Handler 
	nop 
	reti ; Timer3 Compare Match B Handler 
	nop 
	reti ; Timer3 Compare Match C Handler 
	nop 
	reti ; Timer3 Overflow Handler 
	nop 
	reti ; USART1 RX Complete Handler 
	nop 
	reti ; USART1 Data Register Empty Hanlder 
	nop 
	reti ; USART1 TX Complete Handler 
	nop 
	reti ; Two-wire Serial Interface Handler 
	nop 
	reti ; Store Program Memory Ready Handler 
	nop 
	
;*************************************************************** 
;* MAIN program, Initialisation part
.org $0046;
M_INIT:
RESET: 
;* Stack Pointer init, 
;  Set stack pointer to top of RAM 
	ldi temp, LOW(RAMEND) ; RAMEND = max address in RAM"
	out SPL, temp 	      ; RAMEND value in "m128def.inc" 
	ldi temp, HIGH(RAMEND) 
	out SPH, temp 


ldi wait, start_delay ; kezdő késleltetés beállítás

ldi temp2, 0x00	      ; diagnosztikai regiszter inicializálás



;******************************* Portok inicializálása *******************************


	;*** PORTC.0-7: LED0-7 ***

		ldi		temp,0b11111111		; portbitek kimenetek
		out		DDRC,temp			; PORTC kimenet

;******************************* NYOMÓGOMB INICIALIZÁLÁS *******************************
; IRQ5 - BT0
; IRQ6 - BT1

	;*** PORTE.0-7: Gombok bemenetre állítása ***

		ldi		temp, 0b00000000   ;  mind bemenet!
		out 	DDRE, temp
;		ldi		temp, 0b11111111
;		out		PORTE,temp

;***** Az Interruptok kezelését bekapcsoljuk a BT0 és BT1 gombra *****

		ldi 	temp, 0b00101000			; BT0 és BT1 lefutó élre reagáljon
		out 	EICRB, temp
		ldi 	temp, 0b01100000			; csak BT0 és BT1 lenyomására reagáljon
		out 	EIMSK, temp



;***** Timer 0 inicializálása *****

		ldi		temp,0b00001111
				;	   0.......		; FOC=0
				;	   .0..1...		; WGM=10 (CTC mod)
				;	   ..00....		; COM=00 (kimenet tiltva)
				;	   .....111		; CS0=111 (CLK/1024)
		out		TCCR0,temp			; Timer 0 TCCR0 regiszter
		ldi		temp,108			; 11059200Hz/1024 = 108*100 - 100Hz - 10ms
		out		OCR0,temp			; Timer 0 OCR0 regiszter
		ldi		temp,0b00000010
				;	   000000..		; Timer2,1 IT tiltva
				;	   ......1.		; OCIE0=1
				;	   .......0		; TOIE0=0
		out		TIMSK,temp			; Timer IT Mask regiszter
		sei							; globális IT engedélyezve
									; a nyomógombok IRQ-ját is engedélyezi





;*************************************************************** 
;* MAIN program, Endless loop part;  nyomógomb állapot figyelése...
 
M_LOOP: 

; vagy itt kéne a nyomógombok portját beolvasni, vagy a megszakításrutinban


	jmp M_LOOP ; Endless Loop  



;*****************************************************************************
;* 10 msec Timer IT rutin
;*****************************************************************************


	.dseg			; 

	count :	.byte	tconst		; Timer számláló, helyfoglalás RAM-ban 
;	wait  :	.byte	100			; helyfoglalás a lépésköz-késleltető számára(10-150), KIHAGYVA!!!
;	prev_b:	.byte	0b00000000	; nyomógombok ,,előző'' állapota, KIHAGYVA!!!



;count:	.db	tconst		; az AVR2 assembler ezt a formát (.db) is elfogadja
				; AVR2 választás: Project/AVR Assembler Setup 

	.cseg


timerIRQ:
		push	temp				; segédregiszter mentése
		in		temp,SREG			; státusz mentése
		push	temp

		lds		temp,count			; Timer számláló betöltése,
		dec		temp				; csökkentése
		sts		count,temp			; és tárolása
		brne	IRQ_end				; ha nem járt le, 
		sts		count,wait			; különben számláló visszaállítása a kezdő állapotra



;		com		temp2
;		mov		temp, wait
;		and		temp, temp2
;		out		PortC,wait			; diagnosztikai célokra: lépésköz kiíratása+villogtatás
;		jmp		IRQ_end


		in		temp,PORTC			; LED állapot beolvasása
		clc
;		sbrs	sstate,3			; SW3 aktív ?
;		jmp		t0it0				; ugrás, ha igen
		rol		temp				; LED-ek léptetése előre
		brcs	if_carry_set		; ha a carry 1, akkor kiírható a kimenetre
		sbr		temp,1				; különben a kezdő bitet kigyújtjuk(Johnson-számláló)
if_carry_set:
		out		PORTC,temp			; LED-ek beállítása
IRQ_end:
		pop		temp				; regiszterek visszaállítása
		out		SREG,temp
		pop		temp
		reti







BT0_IRQ:
		push	temp				; segédregiszter mentése
		in		temp,SREG			; státusz mentése
		push	temp
;		cli							; interruptok tiltása, ha szükséges

		cpi		wait, max_delay
		brsh	maximum_elerve		; ugrik, ha elértük/meghaladtuk a maximális késleltetést

		lds		temp, delta_delay	; beolvassuk a lépésköz-különbség értékét
		add		wait, temp			; mellyel megnöveljük a lépésközt

maximum_elerve:
;		sei							; interruptok engedélyezése, ha az előbb tiltottuk
		pop		temp				; regiszterek visszaállítása
		out		SREG,temp
		pop		temp
		reti


BT1_IRQ:
		push	temp				; segédregiszter mentése
		in		temp,SREG			; státusz mentése
		push	temp
;		cli							; interruptok tiltása, ha szükséges

		cpi		wait, min_delay
		breq	minimum_elerve		; ugrik, ha elértük a minimális késleltetést
		cpi		wait, min_delay
		brlo	minimum_elerve		; ugrik, ha wait kisebb mint a minimális késleltetés
		subi	wait, delta_delay	; csökkentjük WAIT-ot a lépésközzel

minimum_elerve:
;		sei							; interruptok engedélyezése, ha az előbb tiltottuk
		pop		temp				; regiszterek visszaállítása
		out		SREG,temp
		pop		temp
		reti



; régebbi, elbukott megszakításrutin
; hibája, hogy a nyomógombok állapotát minden megszakítás alkalmával lekérdezi,
; mely bizonytalan ideig is eltarthat, és a sok ugrás átláthatatlanná teszi a kódot
; csak a LED-léptető és a visszaszámláló részt használtam fel belőle,

/*
timerIRQ:
		push	temp				; segédregiszter mentése
		in		temp,SREG			; státusz mentése
		push	temp
		push	temp2

; nyomógomb kezelő rutin
		ldi		temp2,10

		lds		temp,prev_b			; előző állapot beolvasása
		in		buttons,PORTE		; nyomógomb státus beolvasás
		andi	buttons,0b01100000	; maszkolás
		breq	continue			; ugrik, ha a nyomógombok FEL vannak engedve
		cpc		buttons,temp		; összehasonlítás az előző állapottal
		breq	continue			; ugrik ha nincs változás a gombok állapotában
		sbrc	buttons,5
		jmp		BT1_ell				; ugrik, ha BT0 nincs lenyomva
		sbrs	temp,5
		jmp		BT1_ell				; ugrik, ha BT0 előzőleg is le volt nyomva
		lds		temp,wait			; különben növelő algoritmus...
		cpi		temp,150
		breq	continue			; ugrik, ha elérte a maximális késleltetést
		add		temp,temp2			; különben megnövel és letárol
		sts		wait,temp
		jmp		continue			; letárol és ugrik

BT1_ell:

		sbrc	buttons,6
		jmp		continue			; ugrik, ha BT1 nincs lenyomva
		sbrs	temp,6
		jmp		continue			; ugrik, ha BT1 előzőleg is le volt nyomva
		lds		temp,wait			; különben csökkentő algoritmus...
		cpi		temp,10
		breq	continue			; ugrik, ha elérte a minimális késleltetést
		sub		temp,temp2			; különben csökkent és letárol
		sts		wait,temp


continue:
		sts		prev_b,buttons		; nyomógomb előzőállapot letárolása

		lds		temp,count			; Timer számláló
		dec		temp				; csökkentése
		sts		count,temp			; és tárolása
		brne	IRQ_end				; ugrás, ha nem járt le
		lds		temp,wait			; számláló visszaállítása a kezdő állapotra
		sts		count,temp


		in		temp,PORTC			; LED állapot beolvasása
		clc

;		sbrs	sstate,3			; SW3 aktív ?
;		jmp		t0it0				; ugrás, ha igen


		rol		temp				; LED-ek léptetése előre
		brcs	if_carry_set		; ha a carry 1, akkor kiírható a kimenetre
		sbr		temp,1				; különben a kezdő bitet kigyújtjuk(Johnson-számláló)
if_carry_set:
		out		PORTC,temp			; LED-ek beállítása

IRQ_end:
		pop		temp2
		pop		temp				; regiszterek visszaállítása
		out		SREG,temp
		pop		temp
dummy:	reti


*/




