;--------------------------
; THIS IS RX
; PROJECT :3 channel remote control
; INTERNAL 4 MHz
; RC5 FORMAT @38KHz , 35% duty cycle
; ADDRESS = 0X0B
; ch1  = 0X01
; ch2  = 0X02
; ch3  = 0X03
; ch4  = 0X04
; ch5  = 0X05
; NOT USE TOGGLE ALWAY = 0
; 4-JULY-2005
;--------------------------

	list P=12F629
	#include <P12F629.INC>
	__config _WDT_OFF & _INTRC_OSC_NOCLKOUT & _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_ON
	errorlevel  -302  ; suppress message 302 from list file


#DEFINE IR	GPIO,3	; IR LED input with R10K pull-up to vcc
#DEFINE OUT1_M	0x01		; RA0
#DEFINE OUT2_M	0x02		; RA1
#DEFINE OUT3_M	0x04		; RA2
#DEFINE OUT4_M	0x10		; RA4
#DEFINE OUT5_M	0x20		; RA5
#DEFINE TOG_BIT TOGGLE,0
#DEFINE ADDRS	0X0B        ; 0000 1011        ; 0000 1110 
#DEFINE CH1_CMD	0X01
#DEFINE CH2_CMD	0X02
#DEFINE CH3_CMD	0X03
#DEFINE CH4_CMD	0X04
#DEFINE CH5_CMD	0X05


	cblock	0x20
CNT1
CNT2
CNT3
CNT4
TEMP
TOGGLE
ADDR
CMD
	endc

	ORG	0x000

	;BSF	STATUS,RP0
	;CALL	0X3FF
	;MOVWF	OSCCAL
	;BCF	STATUS,RP0
	;	
	CALL	DEBOUNCE
	
	MOVLW	0X07
	MOVWF	CMCON		; MAKE ALL GPIO TO DIGITAL I/O
	BSF		STATUS,RP0
	MOVLW	0X01
	MOVWF	OPTION_REG
 	MOVLW	B'00001000'
	MOVWF	TRISIO
	CLRF	IOCB
	BCF		STATUS,RP0	
	BCF		INTCON,GIE
	CLRF	GPIO		; turn off all output
	;	
MAIN:
	CALL	DELAY3500
	CALL	GET_RC5	
	BTFSC	STATUS,C
	GOTO	MAIN
	;				
	MOVF	ADDR,W	
	XORLW	ADDRS
	BTFSS	STATUS,Z
	GOTO	MAIN		; ADDRESS ERROR
	;	
	MOVF	CMD,W
	ANDLW	0X07		; MASK 2 LSB
	ADDWF	PCL,F
	GOTO	MAIN		; COMMAND 0X00 NOT USE OR COMMAND ERROR
	GOTO	DO_CH1
	GOTO	DO_CH2
	GOTO	DO_CH3
	GOTO	DO_CH4
	GOTO	DO_CH5
	GOTO	MAIN
	GOTO	MAIN
	
DO_CH1:
	MOVLW	OUT1_M
	GOTO	CHANGE
	;
DO_CH2:
	MOVLW	OUT2_M
	GOTO	CHANGE
	;
DO_CH3:
	MOVLW	OUT3_M
	GOTO	CHANGE
	;
DO_CH4:
	MOVLW	OUT4_M
	GOTO	CHANGE
	;
DO_CH5:
	MOVLW	OUT5_M

CHANGE:
	XORWF	GPIO,F

	call	delay
	clrf	GPIO
	
	GOTO	MAIN

delay
	return
;======================================
; READ RC5 Format
; OUTPUT : TOGGLE.7 = TOGGLE BIT
;	       ADDR = ADDRESS 5 BIT 
;	        CDM = COMMAND 6 BIT
;	          C = 0 READ OK
;		    = 1 READ ERROR
;======================================
GET_RC5:
	BTFSC	IR
	GOTO	GET_RC5		; WAIT IR LOW
	CLRF	TMR0		; clear timer 0
	NOP
	BCF		INTCON,T0IF	; CLR timer 0 flag
	NOP
	;
	BTFSC	INTCON,T0IF     
	GOTO	ERR1		
	;
	BTFSS	IR
	GOTO	$-3
	;	
	MOVF	TMR0,W		
	;MOVLW	0xC8		; FOR TEST
	MOVWF	TEMP
	MOVLW	0XFF		; 1020 mS = 255*4
	SUBWF	TEMP,W
	BTFSC	STATUS,C
	GOTO	ERR1		; ERROR IF Time > 1020 uS
	MOVLW	0XC8		; 800 mS
	SUBWF	TEMP,W
	BTFSS	STATUS,C
	GOTO	ERR1		; ERROR IF Time < 800 uS  (C8h * TM0 Prescaler = 800 uS )
	;
	BTFSC	IR  		; Time validate 800uS-1020uS
	GOTO	$-1		; WAIT TO LOW (Syn BIT)
	CALL	DELAY1252	; DELAY 3/4 BIT LENGHT=1252 uS
	;
	BTFSS	IR
	BCF		TOGGLE,7	
	BTFSC	IR
	BSF		TOGGLE,7	
	;		
	BTFSS	IR
	GOTO	$+4
	BTFSC	IR
	GOTO	$-1
	GOTO	READ	
	;
	BTFSS	IR
	GOTO	$-1

;====== READ ADDRESS 5 BIT ===========
; READ MSB FIRST
;	
READ:
	MOVLW	5
	MOVWF	TEMP	; LOOP COUNTER
	CLRF	ADDR
	;	
READ1:
	CALL	DELAY1252
	BTFSS	IR
	BCF		STATUS,C
	BTFSC	IR
	BSF		STATUS,C
	RLF		ADDR,F	; SHIFT LEFT ADDRESS
	;
	BTFSS	IR
	GOTO	$+4
	BTFSC	IR	; WAIT LOW
	GOTO	$-1
	GOTO	$+3
	;
	BTFSS	IR
	GOTO	$-1
	;
	DECFSZ	TEMP,F
	GOTO	READ1
	;
;====== READ COMMAND 6 BIT ===========	
; READ MSB FIRST
;
	MOVLW	6
	MOVWF	TEMP	; LOOP COUNTER
	CLRF	CMD
	;	
CMD1:
	CALL	DELAY1252
	BTFSS	IR
	BCF		STATUS,C
	BTFSC	IR
	BSF		STATUS,C
	RLF	CMD,F	; SHIFT LEFT COMMAND
	;
	BTFSS	IR
	GOTO	$+4
	BTFSC	IR
	GOTO	$-1
	GOTO	$+3
	;
	BTFSS	IR
	GOTO	$-1
	;
	DECFSZ	TEMP,F
	GOTO	CMD1
	;	
	MOVLW	0X3F	; 0011 1111
	ANDWF	CMD,F
	MOVLW	0X1F	; 0001 1111
	ANDWF	ADDR,F
	BCF	STATUS,C	; C=0 NO ERROR
	RETURN
	;
ERR1:
	BSF	STATUS,C	; C=1 HAVE ERROR	
	RETURN

;======================================
; DEBOUNCE SWITCH
; DELAY 15 mS
;======================================
DEBOUNCE:
	MOVLW	.1		; 1
	MOVWF	CNT1		; 1
DEL_1:
	MOVLW	.20
	MOVWF	CNT2		; 1
DEL_2:
	CLRF	CNT3		; 1
DEL_3:
	DECFSZ	CNT3,F		; 1/2
	GOTO	DEL_3		; 2
	DECFSZ	CNT2,F		; 1/2
	GOTO	DEL_2		; 2
	DECFSZ	CNT1,F		; 1/2
	GOTO	DEL_1		; 2
	RETLW	0		; 2

;======================================
; DELAY 1.252mS
;======================================
DELAY1252: 
	MOVLW	.1		; 1
	MOVWF	CNT1		; 1
REP_1:
	MOVLW	.5
	MOVWF	CNT2		; 1
REP_2:
	MOVLW	.81
	MOVWF	CNT3		; 1
REP_3:
	DECFSZ	CNT3,F		; 1/2
	GOTO	REP_3	; 2
	DECFSZ	CNT2,F		; 1/2
	GOTO	REP_2	; 2
	DECFSZ	CNT1,F		; 1/2
	GOTO	REP_1	; 2
	GOTO	$+1	
	GOTO	$+1	
	GOTO	$+1	
	GOTO	$+1	
	RETURN			; 2



DELAY3500:	
	MOVLW	.1		; 1
	MOVWF	CNT1	; 1
	MOVLW	.23
	MOVWF	CNT2	; 1
	MOVLW	.50
	MOVWF	CNT3
	DECFSZ	CNT3,F	; 1/2
	GOTO	$-1		; 2
	DECFSZ	CNT2,F	; 1/2
	GOTO	$-5		; 2
	DECFSZ	CNT1,F	; 1/2
	GOTO	$-9		; 2
	RETLW	0		; 2


	
	END
	
	
		
