;------------------------------------------------------
; PROJECT : 3 CHANNEL TX IR REMOTE
; INTERNAL 4 MHz
; MPLAB : 7.11 , Assembly
; RC5 FORMAT @38KHz , 35% DUTY CYCLE
; ADDRESS = 0X0B  0000 1011 you may change
; CH1  = 0X01
; CH2  = 0X02
; CH3  = 0X03
; CH4  = 0X04
; CH5  = 0X05
; NOT USE TOGGLE ALWAY = 0
; WWW.SIXCA.COM
; 4-JULY 2005
; 
; FREE TO USE FOR PERSONAL OR EVEN COMERCIAL PRODUCT
;------------------------------------------------------

	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 CH1	GPIO,0	; CONNECT WITH TX SWITCH CHANNEL 1
#DEFINE CH2	GPIO,1	; CONNECT WITH TX SWITCH CHANNEL 2
#DEFINE CH3	GPIO,3	; CONNECT WITH TX SWITCH CHANNEL 3
#DEFINE CH4	GPIO,4	; CONNECT WITH TX SWITCH CHANNEL 4
#DEFINE CH5	GPIO,5	; CONNECT WITH TX SWITCH CHANNEL 5
#DEFINE IR	GPIO,2	; CONNECT WITH IR LED WITH TRANSISTOR DRIVES
#DEFINE TOG_BIT TOGGLE,0 ; TOGLE BIT NOT USE FOR THIS PROJECT	
#DEFINE CH1_CMD	0X01	; CHANNEL 1 COMMAND
#DEFINE CH2_CMD	0X02	; CHANNEL 2 COMMAND
#DEFINE CH3_CMD	0X03	; CHANNEL 3 COMMAND
#DEFINE CH4_CMD	0X04	; CHANNEL 4 COMMAND
#DEFINE CH5_CMD	0X05	; CHANNEL 5 COMMAND

	cblock	0x20
CNT1
CNT2
CNT3
CNT4
TOGGLE
CMD	; IR COMMAND BUFFER
	endc

	ORG	0x000
	
	BCF		IR
	;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
	BCF		OPTION_REG,7    ; ENABLE WEAK PULL-UP
	BCF		WPU,2		; DISABLE WEAK PULL-UP FOR GPIO2
	MOVLW	B'00111011'	; GPIO<0,1,3> = INPUT , GPIO 2 = OUTPUT
	MOVWF	TRISIO
	BSF		IOCB,IOCB0
	BSF		IOCB,IOCB1
	BSF		IOCB,IOCB3
	BSF		IOCB,IOCB4
	BSF		IOCB,IOCB5
	BSF		INTCON,GPIE
	BCF		STATUS,RP0	
	BCF		INTCON,GIE	
	BCF		TOG_BIT
	
;------------------------------------
; MAIN LOOP	
MAIN:
	SLEEP				; GOTO SLEEP MODE(I am sleepy! and need to save my energy)
	BTFSS	CH1
	GOTO	DO_CH1
	BTFSS	CH2
	GOTO	DO_CH2
	BTFSS	CH3
	GOTO	DO_CH3
	BTFSS	CH4
	GOTO	DO_CH4
	BTFSS	CH5
	GOTO	DO_CH5
	GOTO	MAIN	

;------------------------------------
DO_CH1:
	CALL	DEBOUNCE
	BTFSC	CH1
	GOTO	MAIN
	MOVLW	CH1_CMD		; LOAD COMMANE FOR CHANNEL 1
	MOVWF	CMD
	CALL	SEND_RC5
	;
	BTFSS	CH1
	GOTO	$-1			; WAIT FOR SWITCH RELEASED
	;
	CALL	DEBOUNCE	; DELAY AFTER SWITCH RELEASED
	GOTO	MAIN

;------------------------------------	
DO_CH2:
	CALL	DEBOUNCE
	BTFSC	CH2
	GOTO	MAIN
	MOVLW	CH2_CMD		; LOAD COMMANE FOR CHANNEL 1
	MOVWF	CMD
	CALL	SEND_RC5
	;
	BTFSS	CH2
	GOTO	$-1			; WAIT FOR SWITCH RELEASED
	;
	CALL	DEBOUNCE	; DELAY AFTER SWITCH RELEASED
	GOTO	MAIN
	;
;------------------------------------	
DO_CH3:
	CALL	DEBOUNCE
	BTFSC	CH3
	GOTO	MAIN
	MOVLW	CH3_CMD		; LOAD COMMANE FOR CHANNEL 1
	MOVWF	CMD
	CALL	SEND_RC5
	;
	BTFSS	CH3
	GOTO	$-1			; WAIT FOR SWITCH RELEASED
	;
	CALL	DEBOUNCE	; DELAY AFTER SWITCH RELEASED
	GOTO	MAIN
	;	
;------------------------------------	
DO_CH4:
	CALL	DEBOUNCE
	BTFSC	CH4
	GOTO	MAIN
	MOVLW	CH4_CMD		; LOAD COMMANE FOR CHANNEL 1
	MOVWF	CMD
	CALL	SEND_RC5
	;
	BTFSS	CH4
	GOTO	$-1			; WAIT FOR SWITCH RELEASED
	;
	CALL	DEBOUNCE	; DELAY AFTER SWITCH RELEASED
	GOTO	MAIN
	;	
;------------------------------------	
DO_CH5:
	CALL	DEBOUNCE
	BTFSC	CH5
	GOTO	MAIN
	MOVLW	CH5_CMD		; LOAD COMMANE FOR CHANNEL 1
	MOVWF	CMD
	CALL	SEND_RC5
	;
	BTFSS	CH5
	GOTO	$-1			; WAIT FOR SWITCH RELEASED
	;
	CALL	DEBOUNCE	; DELAY AFTER SWITCH RELEASED
	GOTO	MAIN
	;	
;======================================
; SEND LOGIC 0
;======================================
LOGIC0:
	MOVLW	.32		; 1
	MOVWF	CNT1		; 1
	;
LOG0_1:
	BSF		IR		; 1 MAKE IR HIGH 35% Duty cycle = 9 uS
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	;
	;===================================
	BCF		IR		; 1 MAKE IR LOW 17 uS
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	NOP			; 1
	;
	DECFSZ	CNT1,F		; 1/2
	GOTO	LOG0_1		; 2    26 uS
	;
	CALL	DELAY_OFF
	RETURN			; 2
	;
;======================================
; SEND LOGIC 1
;======================================
LOGIC1:
	CALL	DELAY_OFF	; DELAY 899 uS
	MOVLW	.32		; 1
	MOVWF	CNT1		; 1
	;
LOG1_1:
	BSF		IR		; 1 MAKE IR HIGH 35% Duty cycle = 9 uS
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	;
	;===================================
	BCF		IR		; 1 MAKE IR LOW 17 uS
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	GOTO	$+1
	NOP			; 1
	;
	DECFSZ	CNT1,F		; 1/2
	GOTO	LOG1_1		; 2
	;
	RETURN			; 2
	;
;======================================
; DELAY FOR NO CARRAIR
; DELAY ABOUT 835 uS
;======================================
DELAY_OFF:
	MOVLW	5		; 1
	MOVWF	CNT3		; 1	
	MOVLW	.54		; 1
	MOVWF	CNT4		; 1
	DECFSZ	CNT4,F		; 1/2
	GOTO	$-1		; 2	
	DECFSZ	CNT3,F  	; 1/2
	GOTO	$-5		; 2
	RETURN			; 2
	
;======================================
; SEND RC5 TO REMOTE
; INPUT : CMD (6 BIT IR COMMAND)
;======================================
SEND_RC5:
	; SEND 2 START  BIT
	CALL	LOGIC1
	CALL	LOGIC1
	; SEND TOGGLE BIT
	BTFSS	TOG_BIT
	GOTO	$+3
	CALL	LOGIC1
	GOTO	$+2
	CALL	LOGIC0

	; SEND ADDRESS 5 BIT FIX AT 01011 (0X0B) IT MAY BE CHANGED BY YOU
	CALL	LOGIC0	; 0  MSB FIRST BIT 4
	CALL	LOGIC1	; 1
	CALL	LOGIC0	; 0
	CALL	LOGIC1	; 1
	CALL	LOGIC1	; 1  LSB BIT 0
	;
	; SEND COMMAND 6 BIT(00HH LLLL) MSB FIRST
	BCF		STATUS,C
	RLF		CMD,F	; AFTER FIRST ROTAGE 0HHL LLL0
	RLF		CMD,F	; AFTER SECOND ROTAGE HHLL LL00
	;
	MOVLW	6
	MOVWF	CNT2
	;
	RLF		CMD,F    	; SEND MSB FIRST
	BTFSS	STATUS,C
	GOTO	$+3
	CALL	LOGIC1
	GOTO	$+2
	;
	CALL	LOGIC0
	DECFSZ	CNT2,F
	GOTO	$-7
	;
	RETLW	0		
	;	
	
;======================================
; 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
	
	END
	
	
		
