;**********************************************************************
; GLD_Pulse_1200.asm included in GLDAB_1200	09/10/06 By KK
; Alain Bizot
;2009/10/06 By KK  throttle low ->no motor Stop run motor ->stop at magnet detect
;**********************************************************************
; THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION WITH NO WARRANTIES.
; OVIRC AND THE DESIGNER SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR
; SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON
; WHATSOEVER.
;
;INIT******************************************************************
Init_PulseIO:
; int Timer1 -> CCP1
	movlw B'00000001' 	;... PS1:1=0.. Fosc/4=0 ... T1_0N=1
	movwf T1CON 		;timer 3 control->CCP1

; int Capture Pulse IN
	movlw	B'00000101'		;Capture every rising eidge
	movwf 	CCP1CON	;(B0)

; init IT CCP
	bcf		PIR1,CCP1IF	;raz flag CCP
	banksel	PIE1		;(B1)
	bsf		PIE1,CCP1IE	;enable it CCP

;WARNING: IOC (B2) must be init 0010 0000 for IOC_5 detection
	movlw		B'00100000'
	movwf		IOC		;(B1)
	banksel	PIR1		;(B0)
	return			;GP2/CCP1 pin: pulse expected from RX

;======================================================================
; Pulse In GPIO,2 (CAPTURE) -> Pulse OUT GPIO,4 (COMPARE)
;======================================================================
PulseIO:
	btfss	PIR1,CCP1IF		;(B0) tst flag ccp?
	goto	NoPulse		;no pulse IN >25mS -> 1mS pulse/25mS
	bcf	PIR1,CCP1IF		;raz flag CCP
; test if Capture or Compare
	btfsc	CCP1CON,CCP1M3	;(B0)
	goto	CompOUT		; "1"xxx
; test if Lead or  Trail (fall) of input pulse
	btfss	CCP1CON,CCP1M0
	goto	Fall_edge		; go pic up the falling edge ...O10"0"

;LEADING edge ...010"1" -----------------------------------------------
	movf    CCPR1L,W        ;(B0) else store leading edge value
	movwf	LEADING         	; into 16 bit work LEADING
	movf	CCPR1H,W
	movwf	LEADING+1
;
	bsf	Flag_B,Flag_Pls	; LEADING edge flag set       $$$ 25 02 
	bcf	CCP1CON, CCP1M0 	; Now change for trailing edge CAPTURE
	return	          	;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;No PULSE IN -> PULSE=1mS
NoPulse:
	btfss	INTCON,T0IF	;IT Timer0 ?
	return
;
	bcf	INTCON,T0IF	;IT Timer0 => no pulse IN
	movlw	Tau1mS_LO	;1mS
	movwf	TauIN
	movlw	Tau1mS_HI	;
	movwf	TauIN+1
	goto	Processing

;
;FALLING edge ...010"0"------------------------------------------------        
Fall_edge:			; ...010"0"
	btfss	Flag_B,Flag_Pls
	return		; this not a valid pulse !
	bcf	Flag_B,Flag_Pls
	movf	CCPR1L,W    ; Store the captured value into
	movwf	TauIN     ; TauIN_LO and ...
	movf	CCPR1H,W
	movwf	TauIN+1	;             ... TauIN_HI
; 16 bit subtract      TauIN = TauIN - LEADING
	SUB16   TauIN, LEADING

;*****PROCESSING ******************************************************
Processing:
	btfsc	Flag_B,Flag_OPS	;starting up or operational ?
	goto	Operational

;-----STARTING UP -----------------------------------------------------
	btfsc	Flag_A,Flag_T0	;Threshold setting ?
	goto	Proc_Time1

	CMP16	TauIN,Tau175	;Tau_IN > 1.75mS
	btfsc	STATUS,C		;
	goto	Thr_set		;C=1 YES TauIN >= 1.75
;No_Thr_Set				 C=0 NO
	btfsc	Flag_A,Flag_T5
	goto	Go_OPS_State

	CMP16	TauIN, Tau125	;Tau pulse IN < 1.25 mS ?
	btfsc	STATUS,C		;C=0: YES TauIN < Tau125
	goto	Reset_Count		;C=1: NO >=

	decfsz Count_sec,f	;delay 2sec throttle low --> OPS !
	goto	PulseValue_1mS
	bcf	GPIO,Red_LED
	movlw	T_sec
	movwf	Count_sec
	decfsz Count_Delay,f
	goto	PulseValue_1mS	
	bsf	Flag_A,Flag_T5	;goto operational state

Reset_Count:
	bsf	GPIO,Red_LED	;LED=off
	movlw	T_sec
	movwf	Count_sec
	movlw	Delay_1
	movwf	Count_Delay

;-------------
PulseValue_1mS:
	movlw	Tau1mS_LO
	movwf	TauOUT
	movlw	Tau1mS_HI
	movwf	TauOUT+1
	goto	PulseOut

;----THRESHOLD
Thr_set:
	decfsz Count_sec,f
	goto	PulseValue_1mS
	movlw	T_sec
	movwf	Count_sec
	call	Blink_LED		;Red_LED blinking
	decfsz Count_Delay,f
	goto	PulseValue_1mS	
	bsf	Flag_A,Flag_T0	;Throttle high OK -> throttle low
	goto	Reset_Count

Go_OPS_State:
	bcf	Flag_A,Flag_T1
	bsf	Flag_B,Flag_OPS	;operational >>>>>
	bsf	Flag_A,Flag_T3 ;stop at start up
	bsf	Flag_B,Flag_Stop	; ""
	goto	PulseValue_IN

Proc_Time1:
	btfsc	Flag_A,Flag_T2
	goto	Proc_Time2		;set threshold

	CMP16	TauIN, Tau125	;Tau pulse IN < 1.25 mS ?
	btfsc	STATUS,C		;C=0: TauIN < Tau125
	goto	Reset_Count
	decfsz Count_sec,f
	goto	PulseValue_1mS
	bcf	GPIO,Red_LED
	movlw	T_sec
	movwf	Count_sec
	decfsz Count_Delay,f
	goto	PulseValue_1mS	
	bsf	Flag_A,Flag_T2	;SET THRESHOLD
	bsf	GPIO,Red_LED

	movlw	T_sec
	movwf	Count_sec
	movlw	Delay_2		;4sec
	movwf	Count_Delay
	goto	PulseValue_1mS
	
;-----THRESHOLD SETTING -----------------------------------------------
Proc_Time2:
	decfsz Count_sec,f
	goto	PulseValue_IN
	movlw	T_sec
	movwf	Count_sec
	call	Blink_LED		;Red_LED blinking
	decfsz Count_Delay,f
	goto	PulseValue_IN
;-----set TauTHR = TauIN + 0.02mS
	movf	TauIN,w
	movwf	TauTHR
	movf	TauIN+1,w
	movwf	TauTHR+1
	ADDI16 TauTHR,0x28	;+ offset= 0.02mS
;
	bsf	Flag_B,Flag_Rcd	;TauOUT pulse --> RECORD TauTHR in EEPROM
	bsf	GPIO,Red_LED
	bcf	Flag_A,Flag_T0	
	bcf	Flag_A,Flag_T1
	bcf	Flag_A,Flag_T2
	bsf	Flag_B,Flag_OPS	; -> operational state
	goto	PulseValue_IN

;*****S.P. blinking ***************************************************
Blink_LED:
	btfss	GPIO,Red_LED
	goto	Led_set
	bcf	GPIO,Red_LED
	btfsc	GPIO,Red_LED
Led_set:
	bsf	GPIO,Red_LED
	return

;*****OPERATIONAL *****************************************************
Operational:
	CMP16	TauIN, TauTHR	;Tau pulse IN < 1.25 mS ?
	btfss	STATUS,C		
	goto	Proc_Time3		;C=0 TauIN < Tau125
	btfss	Flag_A,Flag_T3	;C=1 TauIN >= Tau125
	goto	PulseValue_IN
	bcf	Flag_A,Flag_T3	;clear all GLIDE sequence flags
	bcf	Flag_A,Flag_T4
	bcf	Flag_B,Flag_Stop
	bsf	GPIO,Red_LED	;LED=OFF
	goto	PulseValue_IN

Proc_Time3:
	btfsc	Flag_A,Flag_T3
	goto	Proc_T5
	bsf	Flag_A,Flag_T3

	movlw	T_sec
	movwf	Count_sec
	movlw	Delay_3	;MotorRunTime 1sec
	movwf	Count_Delay

Proc_T5:				;Speed low -> 2sec->change to 0
	btfss	Flag_B,Flag_Stop
	goto	Proc_stop	
	bsf	GPIO,Red_LED	; LED OFF
	goto	PulseValue_1mS	;Motor stop

Proc_stop:				;stop for 2 sec--> 0 sec
	bcf	GPIO,Red_LED	; LED ON
	;btfsc	Flag_A,Flag_T4
	goto	Wait_stop		;Time4-> wait for stop position

	;decfsz Count_sec,f
	;goto	PulseValue_1mS
	;movlw	T_sec	
	;movwf	Count_sec
	;decfsz Count_Delay,f	; count 2 sec
	;goto	PulseValue_1mS

;WARNING: IOC (B2) must be initiated at 0010 0000 for IOC5 detection
	;bsf	Flag_A,Flag_T4		;Wait for stop position
	;movlw	T_sec			;init timer
	;movwf	Count_sec
	;movlw	Delay_1		;Delay2->Delay1 change 4sec -> 2
	;movwf	Count_Delay
	;goto	PulseValue_1mS

;----------------------------------------------------------------------
Wait_stop:
	btfsc	GPIO,Det_Pos
	goto	Wait_stop1
	goto	Wait_stop2

Wait_stop1:
	decfsz Count_sec,f
	goto	PulseValue_Thr
	movlw	T_sec
	movwf	Count_sec
	decfsz Count_Delay,f	; 4 sec count->1sec count
	goto	PulseValue_Thr

;-------------
Wait_stop2:
	bsf	Flag_B,Flag_Stop
	goto	PulseValue_1mS

;------------
PulseValue_Thr:
	movf	TauTHR,w
	movwf	TauOUT
	movf	TauTHR+1,w
	movwf	TauOUT+1
	goto	PulseOut

;------------
PulseValue_IN:
	movf	TauIN,w
	movwf	TauOUT
	movf	TauIN+1,w
	movwf	TauOUT+1

;*****PULSE OUT *******************************************************
PulseOut:	;Timer0 reset (TIMEOUT re-init)
	bcf	INTCON,T0IE	;no Timer0 IT
	movlw	MS25		;32-25mS -> 25mS count
	movwf	TMR0		;(B0)
	bcf	INTCON,T0IF
	bsf	INTCON,T0IE	;Timer0 IT again

;pulse OUT positive edge & pulse timing computation
	bsf	GPIO,Pulse_OUT	; Pulse OUT set GPIO,4 (B0)
	BANKSEL PIE1		;(B1)
	bcf	PIE1,CCP1IE		; inhibit IT
	BANKSEL T1CON		;(B0)
;stop Timer1 and reset TMR1
	bcf	T1CON,TMR1ON			;Timer1 stop counting
	clrf	TMR1L			;(B0) reset TMR1
	clrf	TMR1H
;load pulse duration CAPTURE to CCP1
	movf	TauOUT,w
	movwf	CCPR1L
	movf	TauOUT+1,w
	movwf	CCPR1H
;Timer1 restart counting
	bsf	T1CON,TMR1ON		
; ...wait for Pulse OUT
	movlw B'00001010'		;switch to COMPARE mode
	movwf CCP1CON 		; CCP1 mode
	bcf	PIR1,CCP1IF
	BANKSEL PIE1		;(B1)
	bsf	PIE1,CCP1IE		;enable IT
	BANKSEL PIR1		;(B0)
	return			;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;======================================================================
; COMPARE: pulse OUT (GPIO,4)
CompOUT:
; pulse OUT fall edge
	bcf	GPIO,Pulse_OUT		;pulse OUT cleared!!!
; prepare for new pulse IN ...
	movlw B'00000101'		;switch to CAPTURE Leading edge
	movwf CCP1CON
;
	btfss	Flag_B,Flag_Rcd	;Record Tau_THR ?
	return			;No!
			
	bcf	Flag_B,Flag_Rcd	;Write Tau_Threshold in EEPROM
;-----WRITE EEPROM ----------------------------------------------------
	BANKSEL EECON1		;(B1)
	bsf	EECON1,WREN		;Enable write
	bcf	INTCON,GIE		;Disable INTs
	btfsc	INTCON,GIE
	goto	$-2
;Tau_Threshold --------------- LOW
	movf	TauTHR_LO,w		; 
	movwf	EEDAT			;data LO
	movlw	0x0F0			;
	movwf	EEADR			;address
;>>>>>required sequence
	movlw	0x55
	movwf	EECON2
	movlw	0xAA
	movwf	EECON2		;(B1)
	bsf	EECON1,WR		;Start the write
;>>>>>end of required sequence
	btfsc	EECON1,WR		; end of write=0
	goto	$-2

;Tau_Threshold --------------- HIGH
	movf	TauTHR_HI,w		; 
	movwf	EEDAT			;data HI
	movlw	0x0F1			;
	movwf	EEADR			;address + 1
;>>>>>required sequence
	movlw	0x55
	movwf	EECON2
	movlw	0xAA
	movwf	EECON2		;(B1)
	bsf	EECON1,WR		;Start the write
;>>>>>end of required sequence
	btfsc	EECON1,WR		; end of write=0
	goto	$-2

	bcf	EECON1,WREN		;Inhib write
	BANKSEL PIR1		;(0)
	bcf	PIR1,EEIF		;not necessary ... but ???
	bsf	INTCON,GIE		;Enable INTs
	return			;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;**********************************************************************    
;end PulseIO

