;Mérőrendszer tesztprogi ROD 426-hoz PIC16f690-re kimenet I2C - slave
;( I2C -- AN734 felhasználásával )
;		Vss		<20>		GND
;		Vdd		<1>	+5V
;		PORTA5	<2>	---	Oszcillátor <CLKIN>
;		PORTA4	<3>	---	Oszcillátor <CLKOUT>
;		PORTA3	<4>	---	MCLR/Vpp
;		PORTC5	<5>	- PWM P1A	(-Jel/servo)
;		PORTC4	<6>	- PWM P1B	(-Jel/servo)
;		PORTC3	<7>	- PWM P1C	(-Jel/servo)
;		PORTC6	<8>	- !üres bemenet! (PortC2 kimenete-Jel/servo)
;		PORTC7	<9>	- Végállás	(-Jel/servo)
;		PORTB7	<10>	- Ref.	(-Jel/servo)
;		PORTB6	<11>	- I2C SCL
;		PORTB5	<12>	- -- I2C hiba LED
;		PORTB4	<13>	- I2C SDA
;		PORTC2	<14>	- PWM P1D	(-Jel/servo PortC6-al összekötve?)
;		PORTC1	<15>	- Mérőrendszer "B" jel
;		PORTC0	<16>	- Mérőrendszer "Zero" jel
;		PORTA2	<17>	-/INT --Mérőrendszer "A" jel
;		PORTA1	<18>	---	ICSPCLK
;		PORTA0	<19>	---	ICSPDAT
;
;**********************************************************************
;                                                                     *
;    Notes:    portB,5 "L" i2c hibajelzéskor                                                       *
;                                                                     *
;**********************************************************************


	list		p=16f690		; list directive to define processor
	#include	<P16F690.inc>		; processor specific variable definitions
	errorlevel	-302
	
	__CONFIG    _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF


; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.



;***** VARIABLE DEFINITIONS
statusz	udata	0x20
;	parancs status = TX+0
Pstatus	res	1	;bit0 - RESET (ref. törlése)
			;   1 - hajtás eng.
			;   2 - ref.-et felvenni
			;   3 - motor előre (parancs-JOG)
			;   4 - motor hátra (parancs-JOG)
;	aktuális status =RX+0
Astatus	res	1	;bit0 - hiba [van-volt]
			;   1 - végállás
			;   2 - ref. felvéve
			;   3 - motor előre (forog)
			;   4 - motor hátra (forog)

;	PWM-hez
direction	res	1	;EQU	0x22
;ipwm		res	1	;EQU	0x23
JPR2		res	1

	;várakozáshoz
d1		res	1	;EQU	0x24
d2		res	1	;EQU	0x25
d3		res	1	;EQU	0x26
d4		res	1	;EQU	0x27


tár	udata	0x2A
Index		res	1	;EQU	0x7A	; Index to receive buffer
Temp		res	1	;EQU	0x7B	;
VI2C		res	1	;volt I2C megszólitás (bit 7)

MCOUNT		res	1	;EQU	0x3C
DCOUNT		res	1	;EQU	0x3D
MTEMP		res	1	;EQU	0x3F

	;matekhez
matek	udata	0x30
REGA0		res	1	;EQU	0x30		;lsb
REGA1		res	1	;EQU	0x31
REGA2		res	1	;EQU	0x32
REGA3		res	1	;EQU	0x33		;msb	dec.'127' fölött a szám negativ!
REGA4		res	1
REGB0		res	1	;EQU	0x34		;lsb
REGB1		res	1	;EQU	0x35
REGB2		res	1	;EQU	0x36
REGB3		res	1	;EQU	0x37		;msb	dec.'127' fölött a szám negativ!
REGB4		res	1
REGC0		res	1	;EQU	0x38		;lsb
REGC1		res	1	;EQU	0x39
REGC2		res	1	;EQU	0x3A
REGC3		res	1	;EQU	0x3B		;msb	dec.'127' fölött a szám negativ!
REGC4		res	1


	;Méréshez:
JelA		EQU	0x2		;PortA
JelB		EQU	0x1		;PortC
JelZ		EQU	0x0		;PortC
számláló	udata	0x40
BeSzE		res	1	;EQU	0x40		;előjel a számlálóhoz
BeSzH		res	1	;EQU	0x41		;bemeneti számláló
BeSzM		res	1	;EQU	0x42
BeSzL		res	1	;EQU	0x43
	;jeladó
Konst1H		res	1	;EQU	0x44		;jel/fordulat L
Konst1L		res	1	;EQU	0x45		;jel/fordulat H
Konst2H		res	1	;EQU	0x46		;jel/mm L
Konst2L		res	1	;EQU	0x47		;jel/mm H

	;tárolt számok
T3H		res	1	;EQU	0x48	;Mérőrendszer számláló H
T3M		res	1	;EQU	0x49	;Mérőrendszer számláló M
T3L		res	1	;EQU	0x4A	;Mérőrendszer számláló L
Ref		res	1	;EQU	0x4F	;0-nincs ref. 1-van

;---------------------------------------------------------------------
; Variable declarations
;---------------------------------------------------------------------

; I2C bufferkezeléshez:
buffer	udata	0x50
RXBuffer	res	0x08	;EQU	0x50	;1+15 byte TX_BUF-nek fenntartva
TXBuffer	res	0x08	;EQU	0x60	;1+15 byte RX_BUF-nek fenntartva

;szabad	udata	0x60

; Megszakításhoz:
;ment	udata	0x2D
;w_temp		res	1	;EQU	0x7D
;status_temp	res	1	;EQU	0x7E
;pclath_temp	res	1	;EQU	0x7F
;
FSRsave		EQU	0x7C
w_temp		EQU	0x7D
status_temp	EQU	0x7E
pclath_temp	EQU	0x7F
;**********************************************************************


;Constant Definitions
#define	Slave_cím	'X'	; I2C address (pl. X,Y,Z,S)
#define	RX_BUF_LEN	TXBuffer-RXBuffer	;d'15'
#define	TX_BUF_LEN	TXBuffer-RXBuffer	;d'15'



	ORG		0x000		; processor reset vector
  	goto		KEZD		; go to beginning of program


	ORG		0x004		; interrupt vector location
	movwf		w_temp		; save off current W register contents
	swapf		STATUS,w	; move status register into W register
	clrf		STATUS		;bank 0 - IRP,RP1,RP0 torölve
	movwf		status_temp	; save off contents of STATUS register
	movf		PCLATH,w	; move pclath register into W register
	movwf		pclath_temp	; save off contents of PCLATH register
	movf	FSR,W
	movwf	FSRsave

Jel_A_int:
	btfss	INTCON,INTF		;<INTCON,1> PORT A2 (JelA) okozta a megszakitást
	goto	I2C_ISR
RA_INT:
	btfss	PORTC,JelB
	goto	Előre
	goto	Hátra
Előre:
	incfsz	T3L,f
	goto	Ki_számol
	incfsz	T3M,f
	goto	Ki_számol
	incf	T3H,f
	goto	Ki_számol
Hátra:
	decf	T3L,f
	movf	T3L,w
	xorlw	D'255'
	btfss	STATUS,Z
	goto	Ki_számol
	decf	T3M,f
	movf	T3M,w
	xorlw	D'255'
	btfss	STATUS,Z
	goto	Ki_számol
	decf	T3H,f
	goto	Ki_számol
Ki_számol:
	bcf	INTCON,INTF
;	goto	Ki_ISR	;így gyorsabb, ha egyszerre van

I2C_ISR:
	banksel PIR1		;bank0
	btfss	PIR1,SSPIF	; <PIR1,3> Is this a SSP interrupt?	
	goto	Ki_ISR		; Nem volt I2C
	bcf	PORTB,5		;LED bekapcsolása
	bcf	PIR1,SSPIF
	call	I2C_kezelés	;Volt SSP interrupt!
	movf	RXBuffer+0,W	;parancs
	movwf	Pstatus		;"Pstatus"-ban tárolása
	goto	Ki_ISR
;


Ki_ISR:
	banksel	FSRsave
	movf	FSRsave,W
	movwf	FSR	
	movf		pclath_temp,w	; retrieve copy of PCLATH register
	movwf		PCLATH		; restore pre-isr PCLATH register contents	
	swapf		status_temp,w	; retrieve copy of STATUS register
	movwf		STATUS		; restore pre-isr STATUS register contents
	swapf		w_temp,f
	swapf		w_temp,w	; restore pre-isr W register contents
	retfie				; return from interrupt


;---------------------------------------------------------------------
; Macros
;---------------------------------------------------------------------

memset	macro	Buf_addr,Value,Length

	movlw	Length		; This macro loads a range of data memory
	movwf	Temp		; with a specified value.  The starting
	movlw	Buf_addr	; address and number of bytes are also 
	movwf	FSR		; specified.
SetNext	movlw	Value	;Ez a makró betölti az adatmemória kezdőcímét
	movwf	INDF		; és a byte-ok számát.. (i2c)
	incf	FSR,F
	decfsz	Temp,F
	goto	SetNext
	endm


LFSR	macro	Address,Offset	; This macro loads the correct value
	movlw	Address		; into the FSR given an initial data 
	movwf	FSR		; memory address and offset value.
	movf	Offset,W	;Ez a makró betölti az első adatmemória címét
	addwf	FSR,F		;az FSR-be és eltólja az offset értékével.. (i2c)
	endm

;		
KEZD:	;oszcillátor beállítása
	banksel	OSCCON		;bank0
	movlw	b'01110001'	;8MHz-rendszer a belső oszciról
	movwf	OSCCON
	movlw	0x0
	movwf	OSCTUNE		;gyári kalibráció

	;Forgójeladó állandói
	;menetemelkedes [um] / jelszám [fordulatonként]
	;lehetőleg csak a Konst.L-ben legyen adat!
	;ha Konst.H nem 0  méréstartomány csökken!
	banksel	Konst1L
	goto	K2500

;4096-os jeladó, 2mm-es orsó - x=4*2
K4096:
	movlw	0x7D	;szorzó (2000/x=125)
	movwf	Konst1L	;
	movlw	0x0
	movwf	Konst1H
	movlw	0x0	;osztó (4096/x=256)
	movwf	Konst2L
	movlw	0x1
	movwf	Konst2H
	goto	KONSTVEG

;2500-as jeladó, 2mm-es orsó - x=2*2
K2500:
	movlw	0xF4	;szorzó (2000/x=500)
	movwf	Konst1L	;
	movlw	0x01
	movwf	Konst1H
	movlw	0x71	;osztó (2500/x=625)
	movwf	Konst2L
	movlw	0x2
	movwf	Konst2H
	goto	KONSTVEG

;1500-as jeladó, 2mm-es orsó - x=2*2
K1500:
	movlw	0xF4	;szorzó (2000/X=500)
	movwf	Konst1L	;
	movlw	0x1
	movwf	Konst1H
	movlw	0x77	;osztó (1500/X=375)
	movwf	Konst2L
	movlw	0x1
	movwf	Konst2H
	goto	KONSTVEG

;1000-es jeladó, 2mm-es orsó - x=3*2
K1000:
	movlw	0xFA	;szorzó (2000/X=250)
	movwf	Konst1L	;
	movlw	0x0
	movwf	Konst1H
	movlw	0x7D	;osztó (1000/X=125)
	movwf	Konst2L
	movlw	0x0
	movwf	Konst2H
KONSTVEG:

;megszakit0:		;INTCON--	bit7 GIE (=1 ált. megsz. eng.)
			;		bit6 PEIE (=1 periférikus megsz. ált. eng. /TIMER1, TIMER2, EEPROM, soros modul, PWM)
			;		bit5 T0IE (=1 TIMER0 túlcsordulás interraptját eng. ha a bit2=0)
			;		bit4 INTE (=1 RB0/INT megszakitás eng. ha a bit1=0)
			;		bit3 RBIE (=1 PORTB int. eng. ha a bit0=0)
			;PIE1--		bit7 EEIE (=1 belső EEPROM irásának befejezését jelző int. eng.)
			;		bit6 CM1E (=1 belső comparátorok átbillenésekor int eng.)
			;		bit5 RCIE (=1 RS232 vételi tároló megtelt int. eng.)
			;		bit4 TXIE (=1 RS232 adási tároló kiürült int.eng)
			;		bit3 SSPIE (=1 SSP-<I2C> modul megszakítás eng.)
			;		bit2 CCPIE (=1 Capture-Compare-PWM modul int. eng.)
			;		bit1 TMR2IE (=1 Timer 2 int. eng.)
			;		bit0 TMR1IE (=1 Timer 1 int. eng.)
			;PIR1	( a PIE1 jelz<bitjei )
	;	movlw	b'11011000'
	;	movwf	INTCON		;nem most kezeljk!

;	BCF	STATUS,IRP	;Bank 0,1
;	BSF	STATUS,RP0	;Bank1
;	MOVLW	b'10001111'	;0-3 s 5. bit Vref.-et adja!
;	MOVWF	VRCON
	banksel	OPTION_REG
	MOVLW	b'10001111'
	MOVWF	OPTION_REG
;	BSF	OPTION_REG,7	;'-RBPU' portB "pullupot" (gyenge felhŁz s) Kikapcsolva
;	BCF	OPTION_REG,6	;'INTEDG' =1 RB0/INT lefutó jelre; =0 felfutóra
;	BCF	OPTION_REG,5	;'T0CS' =1 TMR0 CLK Inp RA4-rl; =0 bels ˘r r˘l
;	BCF	OPTION_REG,4	;'T0SE' =1 TMR0 lefut˘ lre lptet; =0 felfut˘ra
;	BSF	OPTION_REG,3	;eloszt˘ a WDT-hez, (0-- a Timer0-hoz)
;	BSF	OPTION_REG,2	;eloszt s=128	000-	1:1,  Timer0-n l	1:2
;	BSF	OPTION_REG,1	;			100-	1:16			1:32
;	BSF	OPTION_REG,0	;			111-	1:128			1:256

;	BCF	STATUS,RP0	;Bank0
;	MOVLW	b'10000111'		;3. bit RA0 s RA1-et v lasztja ki
					;0-2. bit kt compar tor bels Uref-el
;	MOVWF	CMCON		;b'10000111' = compar torok letiltva (port A0-A4 norm l)


tmr1_alapra:
	banksel	T1CON
	movlw	b'00000000'	;0. bit kapcsolja ki (ill. be =1) az idzitt
	movwf	T1CON
	movwf	TMR1L
	movwf	TMR1H

;Portok beállítása:
	movlw	0x0
	banksel	CM1CON0
	movwf	CM1CON0		;1.comparátor kikapcsolva
	movwf	CM2CON0		;2.comparátor kikapcsolva
	banksel	PORTA
	CLRF	PORTA
	CLRF	PORTB	
	CLRF	PORTC

PortA:
	banksel	ANSEL		;Bank2
	clrf	ANSEL		;digital I/O ->0-7
	clrf	ANSELH		;digital I/O ->8-11
;	bsf	STATUS,RP0	;Bank 1
;	bcf	STATUS,RP1
	banksel	TRISA
	MOVLW	b'11111111'	;bitx=0 ->kimenet, =1 ->bemenet
	MOVWF	TRISA		;RA0-ICSPDAT, RA2-ICSPCLK, RA4-5-oszc.

PortB:	movlw	b'11011111'	;set RB<7-4> input (-nincs több)
	movwf	TRISB		;RB4-SDA, RB5-I2C_hiba, RB6-SCL

PortC:	MOVLW	b'11000011'	;bitx=0 ->kimenet, =1 ->bemenet
	MOVWF	TRISC		;PortC-->PWM<2-5>, Jel-PORTC7(+RB7)

	banksel	T3H
	clrf	T3H
	clrf	T3M
	clrf	T3L
	clrf	VI2C
	clrf	Astatus
	clrf	Pstatus
	clrf	RXBuffer+0

I2C_ind:
	call	I2C_SETUP
	call	PWM_ind

	bcf	PIR1,SSPIF
	BSF	INTCON,PEIE	;Enable all peripheral interrupts
;	BSF	INTCON,TOIE	;TIMER0 megszakithat, MOST NEM
	BCF	INTCON,INTF	;jelzőbit törlése HA RA2 már bebillentette
	BSF	INTCON,INTE	;portA2 megszakithat (mérőrendszer "A")
	BSF	INTCON,GIE	;Ált. megszakitás eng.

;CSAK a FLAG bitre van szükség (lehet, hogy ez nem kell)		
	banksel	PIE1		; Enable interrupts
	bsf	PIE1,SSPIE	;I2C_SETUP -ban volt!


Fut:
	call	Mérés0	;Pozicíó mérése és
	movlw	Slave_cím
	movwf	TXBuffer+0
	movf	Astatus,W	;a küldéshez
	movwf	TXBuffer+1	;előkészítése
	btfss	BeSzE,0
	goto	TX_1
	comf	REGA0
	comf	REGA1
	comf	REGA2
	comf	REGA3
	comf	REGA4	
TX_1:	movf	REGA0,W
	movwf	TXBuffer+2
	movf	REGA1,W
	movwf	TXBuffer+3
	movf	REGA2,W
	movwf	TXBuffer+4
	movf	REGA3,W
	movwf	TXBuffer+5
	movf	REGA4,W
	movwf	TXBuffer+6
	movlw	0x0
	movwf	TXBuffer+7
	movwf	TXBuffer+8
	
I2CErr_clr:	nop
	banksel	PORTB		; hiba LED ki
	bsf	PORTB,5



;	call	I2Cfigyelése	;Parancs vétele
WDT_	clrWDT			;I2C-be ha belefagy reset
;	movlw	b'00000110'	;csak PWM teszthez
;	movwf	Pstatus		;"Pstatus"-ban tárolása
;	movwf	REGA0		;csak..
	btfsc	Pstatus,0	;RESET volt
	goto	RESET_
	goto	Fut_1

RESET_:	bcf	Astatus,2	; -referencia törlése (RESET volt)
	bcf	Pstatus,1	;hajtás eng. törlése
	bcf	Pstatus,2	;refet felvenni törlése
	bcf	Pstatus,3	; -JOG motor előre törlése
	bcf	Pstatus,4	; -JOG motor előre törlése

Fut_1:	btfss	Pstatus,1	;hajtás engedélyezve?
	call	lassít


;	goto	Fut		;csak I2C próbához
	call	Poz_ell
	goto	Fut


;**** Ciklusok: ****
;	PRÓBA	most nincs! - megszakításból lesz indítva.
I2Cfigyelése:	;megszakítás fenntartva a mérőrendszernek!!!
	banksel VI2C		;bank0
;	bcf	PORTB,5		;LED bekapcsolása
	btfss	VI2C,7		; volt SSP interrupt?	
	goto	nem_ssp		; Nem I2C volt
	bsf	SSPCON,CKP	;órajel mehet <bit4>
	bcf	VI2C,7
	call	I2C_kezelés	;Volt SSP interrupt!
	movf	RXBuffer+0,W	;parancs
	movwf	Pstatus		;"Pstatus"-ban tárolása
nem_ssp:
	return


;
;	banksel PIR1	;megszakítás rutinban van
;	btfss	PIR1,SSPIF	; <PIR1,3> Is this a SSP interrupt?	
;	goto	nem_ssp		; Nem volt SSP interrupt
;;	banksel PIR1
;	bcf	PIR1,SSPIF
;	call	I2C_kezelés	; Yes, service SSP interrupt.
;
;	movf	RXBuffer+0,W	;és
;	movwf	Pstatus		;"Pstatus"-ban tárolása
;nem_ssp:
;	return


; * Init PWM for Full Bridge Output */
PWM_ind:
	banksel	CCP1CON
	movlw	b'00001100'	;b'01001100
	movwf	CCP1CON	; Full Bridge Forward; P1A, P1C active-high; P1B, P1D active-high\par
		;PWM modult nem most kell aktiválni!
	banksel	CCPR1L
	movlw	0x0
	movwf	CCPR1L	; Start with zero Duty Cycle\par

	banksel	PR2
	movlw	0x65
	movwf	PR2	; PWM ciklusidő - Frequency: 4.90 KHz
	banksel	JPR2
	movwf	JPR2
	banksel	TMR2
	clrf	TMR2	; Start with zero Counter\par
	
	banksel	T2CON	;CSAK akkor, ha van hajtásengedélyezés?
	movlw	b'00000101'	;gyorsítás-lassítás
	movwf	T2CON	; Postscale: 1:1, Timer2=On, Prescale = 1:4\par
;				bit:6-3    bit:2        bit:1-0
	banksel	T1CON
	movlw	0x0
	movwf	T1CON	;ha T1CON=0x1 - TMR1 indul
	clrf	TMR1H
	clrf	TMR1L
	
;	banksel	PWM1CON
;	movlw	b'10001000'	;bit7-restart eng. többi osztás
;	movwf	PWM1CON
;	banksel	PSTRCON
;	movlw	b'00001111'	;"P1[A-D] közvetlen" kimenetre
;	movwf	PSTRCON
	
	banksel	direction	;Bank0
	movlw	0x0
	movwf	direction	; Start with Forward Direction\par
	movlw	0x0
	movwf	CCPR1L	;ipwm
;	call	Melőre	;csak induláshoz
	return

Poz_ell:
	banksel	direction	;Bank0
	movf	RXBuffer+1,w	;REGA-ban a pill. poz.
	movwf	REGB0			;REGB-ben a cél poz.
	movf	RXBuffer+2,w
	movwf	REGB1
	movf	RXBuffer+3,w
	movwf	REGB2
	movf	RXBuffer+4,w
	movwf	REGB3
	movf	RXBuffer+5,w
	movwf	REGB4
	call	subtract	;REGA-ban "lemaradás"
	btfss	Pstatus,1	;hajtás engedélyezve?
	goto	lassít
	btfss	PORTC,7		;végálláson?
	goto	vég1
	goto	vég0
vég0:	bsf	Astatus,1	;végállás!
	goto	lassít
vég1:	bcf	Astatus,1	;nincs végálláson
poz_1:
	btfsc	Pstatus,2	;refet felvenni
	goto	Zmérés
	btfsc	Pstatus,3	;JOG előre
	goto	pelőre
	btfsc	Pstatus,4	;JOG hátra
	goto	phátra
;ha volt célpozíció !!! és ref. - tűz oda!
;	btfsc	Pstatus,5 	;PRÓBA - most nem
	btfsc	REGA4,7	;REGA3,7	;-ha koordinátát kapott
	goto	pelőre		;parancs előre
	goto	phátra		;parancs hátra

Motorciklus:		;végig Bank0
;	btfsc	ipwm,4

phátra:
	movf	CCPR1L,W
	addlw	0xFF
	btfss	STATUS,C
	call	Mhátra
	btfsc	direction,0	;clrf	TMR1H
	goto	p0
	call	lassít
;	sublw	0x0
	btfss	STATUS,Z	;leállt?
	goto	t00	;fékezünk tovább
	movlw	0x0	;jöhet az irányváltás
	movwf	CCP1CON	;PWM kimenet kikapcsolása
	call	LONGDLY_100
	btfsc	direction,0
	goto	Melőre
	goto	Mhátra
	
p0:	call	gyorsít
	goto	ciklusvég
		
pelőre:
	movf	CCPR1L,W
	addlw	0xFF
	btfss	STATUS,C
	call	Melőre
	btfss	direction,0
	goto	p0
	call	lassít
;	sublw	0x0
	btfss	STATUS,Z	;leállt?
	goto	t00	;fékezünk tovább
	movlw	0x0	;jöhet az irányváltás
	movwf	CCP1CON	;PWM kimenet kikapcsolása
	btfsc	direction,0
	goto	Melőre
	goto	Mhátra

t00:	goto	ciklusvég
;	movf	CCPR1L,w
;;	comf	ipwm,w
;;	subwf	PR2,w
;	subwf	JPR2	;0x65	;=PR2
;	btfsc	STATUS,C
;	goto	Melőre
;	goto	Mhátra
;	
		;CCP1CON -P1M1(bit7)-P1M0(bit6)
		;	-11 full brige P1B-mod, P1C-activ, P1A,P1D inactiv
		;	-01 full brige P1D-mod, P1A-activ, P1B,P1C inactiv
		;	-10 half brige P1A,P1B-modulálva
Melőre:	movlw	0x0
	movwf	direction
	bsf	Astatus,3	;motor előre forog
	bcf	Astatus,4	;motor hátra forog
	call	vár1
	bsf	CCP1CON,2
	bsf	CCP1CON,3		
	bcf	CCP1CON,P1M1
	bsf	CCP1CON,P1M0
	call	vár1
	incf	CCPR1L,f
	goto	ciklusvég
Mhátra:
	movlw	0x1
	movwf	direction
	bcf	Astatus,3	;motor előre forog
	bsf	Astatus,4	;motor hátra forog
	call	vár1
	bsf	CCP1CON,2
	bsf	CCP1CON,3
	bsf	CCP1CON,P1M1
	bsf	CCP1CON,P1M0
	call	vár1
	incf	CCPR1L,f
	goto	ciklusvég
ciklusvég
;	incf	ipwm,f
	movf	CCPR1L,w
	subwf	JPR2,W
	btfsc	STATUS,C
	goto	c1
	movf	JPR2,w
;	movwf	ipwm
	movwf	CCPR1L

c1:	movf	CCPR1L,W
	sublw	0x0	;=PR2
	btfss	STATUS,C	;motor áll?
	return
	bcf	Astatus,3
	bcf	Astatus,4
	return

gyorsít:
	movf	CCPR1L,W
	sublw	0x65	;=PR2
	btfsc	STATUS,C
	incf	CCPR1L,f
	sublw	0x66	;=PR2+1
	btfss	STATUS,C
	decf	CCPR1L,f
	nop
	return
lassít:
	movf	CCPR1L,W
	sublw	0x0	;=PR2
	btfsc	STATUS,C
	goto	áll
	decf	CCPR1L,f
	return
áll:	bcf	Astatus,3
	bcf	Astatus,4
	return	

;Mérőrendszer nullázása, irány mindegy!
;referencia keresés
;Meres:	bcf	Astatus,2
;;	movlw	0x0
;;	movwf	Ref
;	movlw	0xFF
;	movwf	BeSzL
;	movwf	BeSzM
;	movwf	BeSzH
;	

Zmérés:		;ref. kapcsolótól függő irányban motor indul!
	btfss	Pstatus,1	;hajtás engedélyezve?
	return
	btfsc	PORTC,7		;végállás nyomva?
	return
	btfsc	PORTB,7		;ref. kapcsoló nyomva?
	goto	Zelőre
	goto	Zhátra
Zelőre:	call	Melőre
	goto	Zmérés_
Zhátra:	call	Mhátra
Zmérés_
;	call	I2Cfigyelése
	clrWDT
ZjelH:
	btfss	PORTC,JelZ
	goto	Zmérés
ZjelL:
	btfsc	PORTC,JelZ	;lefutó élre
	goto	ZjelL
	bsf	Astatus,2	;van referencia
;	movlw	0x1
;	movwf	Ref	;van referencia
	movlw	0x0	;T3...-ba a gépi 0
	movwf	T3H
	movwf	T3M
	movwf	T3L
	movf	T3L,W
	movwf	REGA0
	movf	T3M,W
	movwf	REGA1
	movf	T3H,W
	movwf	REGA2	;65535-ig REGA2=FF ha vissza, =0 ha előre
	movwf	REGA3	;ezért lehet: REGA2=REGA3=REGA4
	movwf	REGA4	
	bcf	Pstatus,2	;refpont felvéve-parancs törlés
	bcf	Pstatus,1	;hajtás tiltás, eng. I2C-ről
	clrf	RXBuffer+0	;nehogy újraolvassa a refpont-parancsot
	return




; remaining code goes here

;---------------------------------------------------------------------
I2C_SETUP
;		I2C slave beállítása
; Initializes program variables and peripheral registers.
;---------------------------------------------------------------------

	banksel	PCON
	bsf	PCON,NOT_POR
	bsf	PCON,NOT_BOR

	banksel	Index		; Clear various program variables
	clrf	Index

	clrf	PIR1


	banksel	SSPCON
	movlw	b'00110110'	;(0x36); I2C_SETUP SSP module SLAVE 
	movwf	SSPCON		; slave mode
;	bcf	SSPCON,CKP		;enable clock stretch
;	bsf	SSPCON2,GCEN	;enable general call

	movlw	Slave_cím
	movwf	Temp
	rlf	Temp,f	;talán ez is kell
	movf	Temp,w
	banksel	SSPADD
	movwf	SSPADD
	clrf	SSPSTAT
;megszakitás engedélyezés I2C_setup és PWM_indítás után!	
	bcf	STATUS,RP0
	return

;---------------------------------------------------------------------
I2C_kezelés
;---------------------------------------------------------------------
;	The I2C code below checks for 5 states:
;	Az I2C alábbi kódot ellenőrzések 5 kimondja:
;	SSPSTAT(bit)
; (3)S-start bit  (5)D_A-adat/cím bit  (2)R_W-olvasás/írás bit  (0)BF-buffer full
;---------------------------------------------------------------------
;	State 1:  	I2C write operation, last byte was an address byte.
;			I2C írási művelet, címe bájt volt
;	SSPSTAT bits:  	S = 1, D_A = 0, R_W = 0, BF = 1
;
;	State 2:	  I2C write operation, last byte was a data byte.
;			I2C írási művelet, adat byte volt
;	SSPSTAT bits:	  S = 1, D_A = 1, R_W = 0, BF = 1
;
;	State 3:	  I2C read operation, last byte was an address byte.
;			I2C olvasási művelet, egy cím bájt.
;	SSPSTAT bits:	  S = 1, D_A = 0, R_W = 1, BF = 0
;
;	State 4:	  I2C read operation, last byte was a data byte.
;			I2C olvasási művelet, adat byte.
;	SSPSTAT bits:	  S = 1, D_A = 1, R_W = 1, BF = 0
;
;	State 5:  Slave I2C logic reset by NACK from master.
;		Master NACK-ot küldött:-Slave I2C logikát resettelje.
;	SSPSTAT bits:  S = 1, D_A = 1, R_W = 0, BF = 0
;
; For convenience, WriteI2C and ReadI2C functions have been used.
;	A kényelem, WriteI2C és ReadI2C funkció is használható.
;----------------------------------------------------------------------

	banksel	SSPSTAT
	movf	SSPSTAT,W	; Get the value of SSPSTAT
	andlw	b'00101101'	; Mask out unimportant bits in SSPSTAT.
	banksel	Temp		; Put masked value in Temp
	movwf	Temp		; for comparision checking.

State1:				; Write operation, last byte was an
	movlw	b'00001001'	; address, buffer is full.
	xorwf	Temp,W		; 
	btfss	STATUS,Z	; Are we in State1?
	goto	State2		; No, check for next state.....
	memset	RXBuffer,0,RX_BUF_LEN	; Clear the receive buffer.
	clrf	Index		; Clear the buffer index.
	banksel	SSPBUF	; Do a dummy read of the SSPBUF.
	movf	SSPBUF,W
	return
	
State2:				; Write operation, last byte was data,
	movlw	b'00101001'	; buffer is full.
	xorwf	Temp,W
	btfss	STATUS,Z	; Are we in State2?
	goto	State3		; No, check for next state.....
	LFSR	RXBuffer,Index	; Point to the buffer.
	banksel	SSPBUF	; Get the byte from the SSP.
	movf	SSPBUF,W
	movwf	INDF		; Put it in the buffer.
	incf	Index,F		; Increment the buffer pointer.
	movf	Index,W		; Get the current buffer index.
	sublw	RX_BUF_LEN	; Subtract the buffer length.
	btfsc	STATUS,Z	; Has the index exceeded the buffer length?
	clrf	Index		; Yes, clear the buffer index.
	return
	
State3:				; Read operation, last byte was an address
	movf	Temp,W ;
	andlw	b'00101100'	; Mask BF bit in SSPSTAT
	xorlw	b'00001100'
	btfss	STATUS,Z	; Are we in State3?
	goto	State4		; No, check for next state.....
	clrf	Index		; Clear the buffer index.
	LFSR	TXBuffer,Index	; Point to the buffer
	movf	INDF,W		; Get the byte from buffer.
	call	WriteI2C	; Write the byte to SSPBUF
	incf	Index,F		; Increment the buffer index.
	return
	
State4:				; Read operation, last byte was data,
	banksel	SSPCON	; buffer is empty.
	btfsc	SSPCON, CKP
	goto	State5
	movlw	b'00101100'
	xorwf	Temp,W
	btfss	STATUS,Z	; Are we in State4?
	goto	State5		; No, check for next state....
	movf	Index,W		; Get the current buffer index.
	sublw	TX_BUF_LEN	; Subtract the buffer length.
	btfsc	STATUS,Z	; Has the index exceeded the buffer length?
	clrf	Index		; Yes, clear the buffer index.
	LFSR	TXBuffer,Index	; Point to the buffer
	movf	INDF,W		; Get the byte
	call	WriteI2C	; Write to SSPBUF
	incf	Index,F		; Increment the buffer index.
	return

State5:
	movf	Temp,W	; NACK received when sending data to the master
	andlw	b'00101000'	; Mask RW bit in SSPSTAT
	xorlw	b'00101000'	;
	btfss	STATUS,Z	; is reset in this case.  R_W = 0, D_A = 1
	goto	I2CErr		; and BF = 0
	return			; If we arenĺt in State5, then something is 
				; wrong.

I2CErr:	nop
	banksel	PORTB		; Something went wrong!  Set LED
	bcf	PORTB,5		; and loop forever.  WDT will reset
;	call	i2cHiba		
;	goto	$	; device, if enabled. 
	return

;---------------------------------------------------------------------
; WriteI2C
;---------------------------------------------------------------------

WriteI2C
	banksel	SSPSTAT
	btfsc	SSPSTAT,BF	; Is the buffer full?
	goto	WriteI2C	; Yes, keep waiting.
	banksel	SSPCON		; No, continue.
DoI2CWrite
	bcf	SSPCON,WCOL	; Clear the WCOL flag.
	movwf	SSPBUF		; Write the byte in WREG
	btfsc	SSPCON,WCOL	; Was there a write collision?
	goto	DoI2CWrite
	bsf	SSPCON,CKP	; Release the clock.<bit4>
	return

;I2C rutin vége

;---------------------------------------------------------------------
ReadI2C			; nincs használva
;---------------------------------------------------------------------
	
	banksel	SSPBUF
	movf	SSPBUF,W	; Get the byte and put in WREG
;	bsf	SSPCON,CKP	;talán ide is kell?
	return
	
i2cHiba
	call	LONGDLY_100	; .......
	bsf	PORTB,5
	call	LONGDLY_100	; .......
	bcf	PORTB,5
	call	LONGDLY_100	; .......
	bsf	PORTB,5
	return



Mérés0:
	banksel	T3L
	movf	T3L,W
	movwf	BeSzL
	movf	T3M,W
	movwf	BeSzM
	movf	T3H,W
	movwf	BeSzH

	btfsc	BeSzH,7
	goto	Bneg
	goto	Bpoz
Bneg:	bsf	BeSzE,0
	comf	BeSzH
	comf	BeSzM
	comf	BeSzL
	
	goto	Szamitas
Bpoz:	bcf	BeSzE,0
	goto	Szamitas


Szamitas:
	movf	BeSzL,w
	movwf	REGA0
	movf	BeSzM,w
	movwf	REGA1
	movf	BeSzH,w
	movwf	REGA2
	movlw	0x0
	movwf	REGA3
	movwf	REGA4

;szorzás: jel/fordulat
	movf	Konst1H,w
	movwf	REGB1
	movf	Konst1L,w
	movwf	REGB0
	movlw	0x0
	movwf	REGB2
	movwf	REGB3	
	movwf	REGB4
	call	multiply	;rega=rega*regb

;osztás: jel/mm
	movf	Konst2H,w
	movwf	REGB1
	movf	Konst2L,w
	movwf	REGB0
	movlw	0x0
	movwf	REGB2
	movwf	REGB3	
	movwf	REGB4
	call	divide		;rega=rega/regb
			;REGA-ban a koordináta (hex)
;	BeSzE -ben az előjel ha =0 pozitív, =1 negatív.
	return
	

;	*	*	*	*	*	*	*	*	*	*	*	*
;	5 byte-os (40 bites) matek !!!
;
;	CALL	subtract	;REGA.=REGA.-REGB. 
;	CALL	multiply	;REGA.=REGA.*REGB. 
; 	CALL	divide		;REGA.=REGA./REGB. 


      ;*** SIGNED SUBTRACT ***
      ;REGA - REGB -> REGA
      ;Return carry set if overflow
subtract:
      	call	negateb		;Negate REGB
      	skpnc
      	return			;Overflow

      ;*** SIGNED ADD ***
      ;REGA + REGB -> REGA
      ;Return carry set if overflow

add:	movf	REGA4,w		;Compare signs
      	xorwf	REGB4,w
      	movwf	MTEMP

      	call	addba		;Add REGB to REGA

      	clrc			;Check signs
      	movf	REGB4,w		;If signs are same
      	xorwf	REGA4,w		;so must result sign
      	btfss	MTEMP,7		;else overflow
      	addlw	0x80
      	return

      ;*** SIGNED MULTIPLY ***
      ;REGA * REGB -> REGA
      ;Return carry set if overflow

multiply:
      	clrf	MTEMP		;Reset sign flag
      	call	absa		;Make REGA positive
      	skpc
      	call	absb		;Make REGB positive
      	skpnc
      	return			;Overflow

      	call	movac		;Move REGA to REGC
      	call	clra		;Clear product

      	movlw	D'39'	;D'31'		;Loop counter
      	movwf	MCOUNT

muloop:	call	slac		;Shift left product and multiplicand
      	
      	rlf	REGC4,w		;Test MSB of multiplicand
      	skpnc			;If multiplicand bit is a 1 then
      	call	addba		;add multiplier to product
	
      	skpc			;Check for overflow
      	rlf	REGA4,w
      	skpnc
      	return

      	decfsz	MCOUNT,f	;Next
      	goto	muloop

      	btfsc	MTEMP,0		;Check result sign
      	call	negatea		;Negative
      	return


      ;*** SIGNED DIVIDE ***
      ;REGA / REGB -> REGA
      ;Remainder in REGC
      ;Return carry set if overflow or division by zero

divide:	clrf	MTEMP		;Reset sign flag
      	movf	REGB0,w		;Trap division by zero
      	iorwf	REGB1,w
      	iorwf	REGB2,w
      	iorwf	REGB3,w
      	iorwf	REGB4,w
      	sublw	0
      	skpc
      	call	absa		;Make dividend (REGA) positive
      	skpc
      	call	absb		;Make divisor (REGB) positive
      	skpnc
      	return			;Overflow

      	clrf	REGC0		;Clear remainder
      	clrf	REGC1
      	clrf	REGC2
      	clrf	REGC3
      	clrf	REGC4
      	call	slac		;Purge sign bit

      	movlw	D'39'	;D'31'		;Loop counter
      	movwf	MCOUNT

dvloop:	call	slac		;Shift dividend (REGA) msb into remainder (REGC)

      	movf	REGB4,w		;Test if remainder (REGC) >= divisor (REGB)
      	subwf	REGC4,w
      	skpz
      	movf	REGB3,w		;Test if remainder (REGC) >= divisor (REGB)
      	subwf	REGC3,w
      	skpz
      	goto	dtstgt
      	movf	REGB2,w
      	subwf	REGC2,w
      	skpz
      	goto	dtstgt
      	movf	REGB1,w
      	subwf	REGC1,w
      	skpz
      	goto	dtstgt
      	movf	REGB0,w
      	subwf	REGC0,w
dtstgt:	skpc			;Carry set if remainder >= divisor
      	goto	dremlt

      	movf	REGB0,w		;Subtract divisor (REGB) from remainder (REGC)
      	subwf	REGC0,f
      	movf	REGB1,w
      	skpc
      	incfsz	REGB1,w
      	subwf	REGC1,f
      	movf	REGB2,w
      	skpc
      	incfsz	REGB2,w
      	subwf	REGC2,f
      	movf	REGB3,w
      	skpc
      	incfsz	REGB3,w
      	subwf	REGC3,f
      	skpc
      	incfsz	REGB4,w
      	subwf	REGC4,f
      	clrc
      	bsf	REGA0,0		;Set quotient bit

dremlt:	decfsz	MCOUNT,f	;Next
      	goto	dvloop

      	btfsc	MTEMP,0		;Check result sign
      	call	negatea		;Negative
      	return

      ;*** ROUND RESULT OF DIVISION TO NEAREST INTEGER ***

round:	clrf	MTEMP		;Reset sign flag
      	call	absa		;Make positive
      	clrc
      	call	slc		;Multiply remainder by 2
      	movf	REGB4,w		;Test if remainder (REGC) >= divisor (REGB)
      	subwf	REGC4,w
      	skpz
      	movf	REGB3,w		;Test if remainder (REGC) >= divisor (REGB)
      	subwf	REGC3,w
      	skpz
      	goto	rtstgt
      	movf	REGB2,w
      	subwf	REGC2,w
      	skpz
      	goto	dtstgt
      	movf	REGB1,w
      	subwf	REGC1,w
      	skpz
      	goto	rtstgt
      	movf	REGB0,w
      	subwf	REGC0,w
rtstgt:	skpc			;Carry set if remainder >= divisor
      	goto	rremlt
      	incfsz	REGA0,f		;Add 1 to quotient
      	goto	rremlt
      	incfsz	REGA1,f
      	goto	rremlt
      	incfsz	REGA2,f
      	goto	rremlt
      	incfsz	REGA3,f
      	goto	rremlt
      	incf	REGA4,f
      	skpnz
      	return			;Overflow,return carry set
rremlt:	btfsc	MTEMP,0		;Restore sign
      	call	negatea
      	return


      ;UTILITY ROUTINES

      ;Add REGB to REGA (Unsigned)
      ;Used by add, multiply,

addba:	movf	REGB0,w		;Add lo byte
      	addwf	REGA0,f

      	movf	REGB1,w		;Add mid-lo byte
      	skpnc			;No carry_in, so just add
      	incfsz	REGB1,w		;Add carry_in to REGB
      	addwf	REGA1,f		;Add and propagate carry_out

      	movf	REGB2,w		;Add mid-hi byte
      	skpnc
      	incfsz	REGB2,w
      	addwf	REGA2,f

      	movf	REGB3,w		;Add hi byte
      	skpnc
      	incfsz	REGB3,w
      	addwf	REGA3,f
      	movf	REGB4,w		;Add upper byte
      	skpnc
      	incfsz	REGB4,w
      	addwf	REGA4,f
      	return


      ;Move REGA to REGC
      ;Used by multiply, sqrt

movac:	movf	REGA0,w
      	movwf	REGC0
      	movf	REGA1,w
      	movwf	REGC1
      	movf	REGA2,w
      	movwf	REGC2
      	movf	REGA3,w
      	movwf	REGC3
      	movf	REGA4,w
      	movwf	REGC4
      	return


      ;Clear REGB and REGA
      ;Used by sqrt

clrba:	clrf	REGB0
      	clrf	REGB1
      	clrf	REGB2
      	clrf	REGB3
      	clrf	REGB4

      ;Clear REGA
      ;Used by multiply, sqrt

clra:		clrf	REGA0
      	clrf	REGA1
      	clrf	REGA2
      	clrf	REGA3
      	clrf	REGA4
      	return


      ;Check sign of REGA and convert negative to positive
      ;Used by multiply, divide, bin2dec, round

absa:	rlf	REGA4,w
      	skpc
      	return		;Positive

      ;Negate REGA
      ;Used by absa, multiply, divide, bin2dec, dec2bin, round

negatea:
	movf	REGA3,w		;Save sign in w
      	andlw	0x80

      	comf	REGA0,f		;2's complement
     	comf	REGA1,f
      	comf	REGA2,f
      	comf	REGA3,f
      	comf	REGA4,f
      	incfsz	REGA0,f
      	goto	nega1
      	incfsz	REGA1,f
      	goto	nega1
      	incfsz	REGA2,f
      	goto	nega1
      	incfsz	REGA3,f
      	goto	nega1
      	incf	REGA4,f

nega1:	incf	MTEMP,f		;flip sign flag
      	addwf	REGA4,w		;Return carry set if -2147483648
      	return


      ;Check sign of REGB and convert negative to positive
      ;Used by multiply, divide

absb:		rlf	REGB4,w
      	skpc
      	return			;Positive

      ;Negate REGB
      ;Used by absb, subtract, multiply, divide

negateb:
	movf	REGB4,w		;Save sign in w
      	andlw	0x80

      	comf	REGB0,f		;2's complement
      	comf	REGB1,f
      	comf	REGB2,f
      	comf	REGB3,f
      	comf	REGB4,f
      	incfsz	REGB0,f
      	goto	negb1
      	incfsz	REGB1,f
      	goto	negb1
      	incfsz	REGB2,f
      	goto	negb1
      	incfsz	REGB3,f
      	goto	negb1
      	incf	REGB4,f

negb1:
     	incf	MTEMP,f		;flip sign flag
      	addwf	REGB4,w		;Return carry set if -2147483648
      	return


      ;Shift left REGA and REGC
      ;Used by multiply, divide, round

slac:	rlf	REGA0,f
      	rlf	REGA1,f
      	rlf	REGA2,f
      	rlf	REGA3,f
      	rlf	REGA4,f
slc:	rlf	REGC0,f
      	rlf	REGC1,f
      	rlf	REGC2,f
      	rlf	REGC3,f
      	rlf	REGC4,f
      	return

 




LONGDLY_100:	; 0,1sec delay
		; * 999998 * cycles
	movlw	0x1F
	movwf	d1
	movlw	0x4F
	movwf	d2
LONGDLY_0:
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	LONGDLY_0
				;2 cycles
	goto	$+1
	nop
	RETURN			;4 cycles (including call)

vár1:	movlw	0x10
	movwf	d1
	movlw	0x1
	movwf	d2
vár0:	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	vár0
				;2 cycles
	goto	$+1
	nop
	RETURN			;4 cycles (including call)




	ORG	0x2100			; data EEPROM location
	DT	" Mérőrendszer - Slave - Nemesházi"





	END                       ; end of program'
