	list	b=4
;************************************************************************
; Philips RC5(X) Infrared protocol implemented with 6-8 pin Microchip 	*
; microcontrollers from 10F2xx series.									*
;																		*
;	Last modified:	2012-05-28											*
#define	VersionMajor	0x10	;										*
#define	VersionMinor	0x02	;										*
;																		*
; 10F200, 10F202, 10F204, 10F206, 10F220, 10F222						*
;   many other,  6-8 pin 12F2xx device may be used						*
;	   - 6 byte RAM from 0x10 - 0x15 used only							*
;	   - no more than 256 word of program memory needed					*
;	   - IOC on 3-5 pins												*
;	   - 8 level stack													* 
;																		*
;************************************************************************
;																		*
;	Pins:																*
;		GPIO:															*
;			0: Button 1													*
;			1: Button 2													*
;			2: IR Led output											*
;			3: Button 3													*
;																		*
;************************************************************************

	errorlevel	-302			; Register in operand not in bank 0.

	ifdef	__10F200
		list	p=10f200		; 10F200 can be used
		#include <p10f200.inc>	; processor specific variable definitions
		__CONFIG _CP_OFF & _WDTE_OFF & _MCLRE_OFF & _IntRC_OSC
#define OSCCAL_Loc	0x00FF
    endif
	ifdef	__10F202
		list	p=10f202		; 10F202 can be used
		#include <p10f202.inc>	; processor specific variable definitions
		__CONFIG _CP_OFF & _WDTE_OFF & _MCLRE_OFF & _IntRC_OSC
#define OSCCAL_Loc	0x01FF
    endif
	ifdef	__10F204
		list	p=10f204		; 10F204 can be used
		#include <p10f204.inc>	; processor specific variable definitions
		__CONFIG _CP_OFF & _WDTE_OFF & _MCLRE_OFF & _IntRC_OSC
#define OSCCAL_Loc	0x00FF
    endif
	ifdef	__10F206
		list	p=10f206		; 10F206 can be used
		#include <p10f206.inc>	; processor specific variable definitions
		__CONFIG _CP_OFF & _WDTE_OFF & _MCLRE_OFF & _IntRC_OSC
#define OSCCAL_Loc	0x01FF
    endif
	ifdef	__10F220
		list	p=10f220		; 10F220 can be used
		#include <p10f220.inc>	; processor specific variable definitions
		__CONFIG _CP_OFF & _WDTE_OFF & _MCLRE_OFF & _IOFSCS_4MHZ
#define OSCCAL_Loc	0x00FF
    endif
	ifdef	__10F222
		list	p=10f222		; 10F222 can be used
		#include <p10f222.inc>	; processor specific variable definitions
		__CONFIG _CP_OFF & _WDTE_OFF & _MCLRE_OFF & _IOFSCS_4MHZ
#define OSCCAL_Loc	0x01FF
    endif

	ifndef	PCL
		error	"Invalid processor type selected"
	endif

F_OSC	EQU	.4000000			; 4.00 MHz clock frequency used

								; Default address to use afther power up
#define	DefaultAddress		0x1D	; Used when ADDRESS button up   during powerup
#define	MenuCode			0x0F
#define	BSW1Code			0x09
#define	BSW2Code			0x05

	__idlocs		0xC000 | (VersionMajor << 8) | (VersionMinor)

	cblock	0x10
		comcode					; Command code to send
		address					; Address to send  -  bit 5: toggle bit
		cntr					; Delay counter
		bitcnt					; Bit counter
		shift
		delay
	endc

	if bitcnt > 0x2F
		error "Too many variable used"
	endif

	org		OSCCAL_Loc
Restart:
		movlw	0x1B

		org		0x0000
POWERON
		clrwdt

	ifdef	OSCCAL
		movwf	OSCCAL
	endif

	ifdef	ADCON0				; If controller has A/D - disable it
		clrf	ADCON0
	endif

	ifdef	CMCON0				; If controller has comparator - disable it
		clrf	CMCON0
	endif

		movlw	0x81 			; Pullups on, Disable IOC wake up	
		option
		movlw	0xFB
		tris	GPIO			; Bit 2 Ir Led output, 3: Menu button, 1: Button 2, 0: Button 1

		clrf	GPIO

		btfsc	STATUS,GPWUF
		goto	ButtonDown

		movlw	DefaultAddress	; address = default address
		movwf	address			; Clear toggle bit

MainLoop
		movf	GPIO,w
		bcf		STATUS,GPWUF
		movlw	0x01 			; Pullups on, Enable IOC wake up	
		option
		
		sleep					; Goto sleep
		nop  					; Port change will wake up
		nop

ButtonDown

		movlw	0x81 			; Pullups on, Disable IOC wake up	
		option
		bcf		STATUS,GPWUF

		movf	GPIO,w
		movwf	shift
								; Button pressed
		xorlw	0x0B
		andlw	0x0B
		btfsc	STATUS,Z
		goto	KeyUp
		
		btfss	shift,3
		movlw	MenuCode
		btfss	shift,1
		movlw	BSW2Code
		btfss	shift,0
		movlw	BSW1Code
		movwf	comcode

SendPackets
								; Send command only 1 time
;Delay226ms
;		call	Delay113ms

; RC5 InfraRed Command Packet
;
;		Packet length: 24.899 ms, repeation time: 113.792 ms 		
;
;		Bit 1: 889uS - no pulses, 889us - 32 pulses 
;		Bit 0: 889uS - 32 pulses, 889us - no pulses 
;
;		 S  s   T   A4  A3  A2  A1  A0  C5  C4  C3  C2  C1  C0
;		|1 |s  |tg |a4 |a3 |a2 |a1 |a0 |c5 |c4 |c3 |c2 |c1 |c0 |
;
;		RC5  version s: second start bit : 1
;		RC5X version s: inverted bit 6 of command : !c6
;
;		a4..a0:	address
;		d6..d0: command
;		tg: toggle bit: send the same bit for repeated packet sending
;						send opposite bit for a new command


SendIrPacket
		call	SendBit1		; First  Startbit = 1
		btfss	comcode,6
		call	SendBit1		; Second Startbit = inv of bit 6 of command code 
		btfsc	comcode,6
		call	SendBit0

		movf	address,w		; toggle bit and 5 Bit address
		call	SendBits

		movf	comcode,w		; 6 Bit command code
		call	SendBits
		bcf   	GPIO,2			; Turn off IR LED

		call	Delay113ms

		movlw	0x20
		xorwf	address,f		; Invert toggle bit

KeyUp							; Wait for all keys up
		movf	GPIO,W

		xorlw	0x0B
		andlw	0x0B
		btfss 	STATUS,Z
		goto	KeyUp

NoKeyDown
		movlw	.50
		call	Delayms

		goto	MainLoop

SendBits
		movwf	shift			; Save data to send
		movlw	.6
		movwf	bitcnt			; Save bit count
SendBits_loop
		btfsc	shift,5			; Test bit
		call	SendBit1		; if bit==1 send a one
		btfss	shift,5
		call	SendBit0		; if bit==0 send a zero
		rlf		shift,f			; All bits to send are in the FSR, C is don't care
		decfsz	bitcnt,f		; Loop for all bits
		goto	SendBits_loop
		retlw	0

SendBit1

		movlw	.32
		movwf	cntr
SendPause1_loop
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		decfsz	cntr,f			;1
		goto	SendPause1_loop	;2


		movlw	.32
		movwf	cntr
SendBit1_loop
		BSF		GPIO,2			;1
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		BCF		GPIO,2			;1
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		goto	$+1				;2
		decfsz	cntr,f			;1
		goto	SendBit1_loop	;2
		retlw	0

SendBit0
								;  890us with 36kHz modulation
								; 27.7us Periodtime - 32 Impulses

		movlw	.32
		movwf	cntr
SendBit0_loop
		BSF		GPIO,2			;1
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		BCF		GPIO,2			;1
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		goto	$+1				;2
		decfsz	cntr,f			;1
		GOTO	SendBit0_loop	;2

SendPause0
		MOVLW	.32
		movwf	cntr
SendPause0_loop
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		nop
		nop
		nop
		nop						;4
		decfsz	cntr,f			;1
		GOTO	SendPause0_loop	;2
		retlw	0

Delay113ms
		movlw	.113
Delayms
		MOVWF	cntr
lDel1
		clrf	delay
lDel2
		NOP  
		DECFSZ	delay,f
		GOTO	lDel2
		DECFSZ	cntr,f
		GOTO	lDel1
		retlw	0

	END


