;--------------------------
; THIS IS RX
; PROJECT :3 channel remote control
; CRYSTAL 4 MHz
; RC5 FORMAT @38KHz , 35% duty cycle
; ADDRESS = 0X0B
; ch1  = 0X01
; ch2  = 0X02
; ch3  = 0X03
; NOT USE TOGGLE ALWAY = 0
; www.joyta.ru
;--------------------------

	list P=12F629
	#include <P12F629.INC>
	__config _WDT_OFF & _XT_OSC & _CP_ON & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_ON


#DEFINE IR	GPIO,3	; IR LED input with R10K pull-up to vcc
#DEFINE OUT1	GPIO,0	; Drive output 1
#DEFINE OUT2	GPIO,1	; Drive output 2
#DEFINE OUT3	GPIO,2	; Drive output 3
#DEFINE OUT1_M	0x01
#DEFINE OUT2_M	0x02
#DEFINE OUT3_M	0x04
#DEFINE TOG_BIT TOGGLE,0
#DEFINE ADDRS	0X0B        ; 0000 1011        ; 0000 1110 
#DEFINE CH1_CMD	0X01
#DEFINE CH2_CMD	0X02
#DEFINE CH3_CMD	0X03



CNT1	EQU	20H
CNT2	EQU	21H
CNT3	EQU	22H
CNT4	EQU	23H
TEMP	EQU	24H
TOGGLE	EQU	25H
ADDR	EQU	26H
CMD	EQU	27H




	ORG	000

	;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	0X03		; MASK 2 LSB
	ADDWF	PCL,F
	GOTO	MAIN		; COMMAND 0X00 NOT USE OR COMMAND ERROR
	GOTO	DO_CH1
	GOTO	DO_CH2
	GOTO	DO_CH3
	
DO_CH1: MOVLW	OUT1_M
	GOTO	CHANGE
	;
DO_CH2:	MOVLW	OUT2_M
	GOTO	CHANGE
	;
DO_CH3:	MOVLW	OUT3_M
CHANGE:	XORWF	GPIO,F	
	GOTO	MAIN

;======================================
; 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
	
	
		
