; ***************************************************************************************
; ***************************************************************************************
; *  FILE..........: rc_rs232.asm							*
; *  AUTHOR........: Rasmus Geidnert							*
; *  DESCRIPTION...: Conversion of PPM-signal to RS232 for FMS R/C fligt simulator	*
; *  CPU...........: PIC16F84 & 12C508							*
; *  CREDITS.......: This code is an improvement of an interface by Vitaly Puzrin.	*
; *		     However this code is rewritten from scrach.			*
; *		     Exept the support for different processors that was copied.	*
; *  COPYRIGHT.....: Rasmus Geidnert, 2001						*
; *  HISTORY.......: DATE		COMMENT						*
; *  ---------------------------------------------------				*
; *		14.02.2001 	First version.						*
; *				Tested on PIC 16F84 and Hitec Focus 4.			*
; *		27.02.2001 	Code for the 12C508 added.				*
; *											*
; ***************************************************************************************
; ***************************************************************************************

;        LIST    F=INHX8M, P=12C508, R=HEX

	IFDEF __12C508

	#include <p12c508.inc>
	#DEFINE	OUTPUT	GPIO, 0			; the Output(exit) of the data 
	#DEFINE	RAM_START H '07' 
	__CONFIG _MCLRE_OFF & _CP_ON & _WDT_ON & _WDT_ON & _IntRC_OSC

	ELSE

	#include <p16f84.inc>
	#DEFINE	OUTPUT	PORTB, 2
	#DEFINE	RAM_START H '0C' __
;	__CONFIG	_CP_OFF & _PWRTE_ON & _WDT_ON & _XT_OSC
	__CONFIG	b'00000000000101'
	ENDIF

;Variables
	CBLOCK RAM_START		; First user RAM at 0x0C
		Time			; Used to measure pulse length	
		Del_rs232		; Delay variable used by Send
		Send_bit		; Temp storage for bit to be send with RS232
		Send_Count
		Bit_count		; used to count bits sent with RS 232
	ENDC

	org	0
;--------------------------- cpu specific command here ------------------
IFDEF __12C508
	movwf	OSCCAL		; Calebrating internal oscilator if PIC 12C508
ENDIF
	clrwdt			; clear watchdog timer

	movlw	B'00111010'
	option			; load option register

IFDEF	__12C508

	movlw	0FFh		; Set in and out ports
	movwf	GPIO
	bsf	OUTPUT
	movlw	B'00011110'
	tris	GPIO

ELSE

	movlw	0FFh		; Set in and out ports
	movwf	PORTA
	movwf	PORTB
	bsf	OUTPUT
	movlw	B'00010000'
	tris	PORTA
	movlw	B'00000000'
	tris	PORTB

ENDIF
;------------------------------------------------------------------------

	clrwdt				; Clear watchdog timer
	clrf	Time			; Clear counter variable
	clrf	TMR0
	movlw	h'FF'
	movwf	Time



Wait_first_front
	movf	TMR0, W			; Move Timer reg to W
	btfsc	STATUS, Z		; If still zero then do next command
	goto	Wait_first_front	; Loop if no pulse is detected
	nop
	nop
	nop

	;Delay 715uS - RS232 send + delay (495 + 220 )

Send
	movf	Time, W			; Move Time to temp variable Send_bit
	movwf	Send_bit
	MOVLW	h'08'
	MOVWF	Send_Count
	BCF	OUTPUT			; Set Outout to 0 (Start bit)
	BSF	Send_Count, 7
	GOTO	Del_232
rs1	BCF	Send_Count, 7
New_data
	RRF	Send_bit, F
	BTFSC	STATUS, C		; Test Carry if 1 then set output
	BSF	OUTPUT
	BTFSS	STATUS, C		; Test Carry if 0 then clear output
	BCF	OUTPUT
	BSF	Send_Count, 6
	GOTO	Del_232
rs2	BCF	Send_Count, 6
	DECFSZ	Send_Count, F		; Decreament skip if 0
	GOTO	New_data
	BSF	OUTPUT			; Set Output to 1 (Stop bit)
Del_232
	MOVLW	h'0B'			; Load delay variable
	MOVWF	Del_rs232
Del2_232
	DECFSZ	Del_rs232, F		; Decrement skip if 0 (F=store result in FileRegister) Loop 33us
	GOTO	Del2_232
	BTFSC	Send_Count, 7		; Bit Test 7 if set goto 00D
	GOTO	rs1
	BTFSC	Send_Count, 6		; Bit Test 6 if set goto 015
	GOTO	rs2

	clrwdt				; Clear watchdog timer
	clrf	Time			; Clear counter variable
	clrf	TMR0

	movlw	d'73'
	movwf	Del_rs232
Delay_220uS
	Decfsz	Del_rs232, F
	goto	Delay_220uS

Measure
	movf	TMR0, W			; Move Timer reg to W
	btfss	STATUS, Z		; Check if Timer is Zero
	goto	Send			; If TMR0 > 0 then pulse found -> send data
	incfsz	Time, F			; Time = Time +1 & skip next if result is zero
	goto	Measure			; If not lopped 256 times do one more

	movlw	H'FF'			; If no pulse send 0xFF
	movwf	Time

	goto	Wait_first_front

	sleep
	end
