;  ------ PC Remote Control System ------
;  ------ Processor AT89C2051 24PC ------

#INCLUDE "LIBREG.ASM"	;8051 SFR set

CLK_KHZ	= 11059		;OSC frequency, KHZ
BAUD_RATE	= 9600		;Serial port baud rate, baud
BAUD	= 2560-(((CLK_KHZ*10000)/(12*16*BAUD_RATE))+5)
BAUD	= BAUD/10

;  ------ Constantes ------

STACK	.EQU 050H		;stack location
ACTIVE	.EQU 080H		;active mode PCON value
IDLE	.EQU 081H		;idle mode PCON value
SYS	.EQU 006H		;RC-5 system

;  ------ Ports ------

;IR receiver out:
SER	.EQU INT0

;Mode jumper:
;Open (high) - "System And Command" mode
;Shorted to Ground (low) - "Command Only" mode
MOD	.EQU T1

;  ------ Vectors Area ------

	.ORG 0000H	;reset vector
	LJMP INIT
	.ORG 0003H	;INT0 vector
	LJMP RC5

;  ------ Main Program ------

INIT:	MOV SP,#STACK	;stack init
	CLR P1.0		;ground AIN1
	CLR P1.1		;ground AIN2

	CLR TR0          	;timer 0 stop
	CLR TR1          	;timer 1 stop
	MOV SCON,#11000000B	;serial port init for mode 3, REN=0
	MOV TMOD,#00100001B	;timer 1 init for auto-reload mode
	MOV PCON,#ACTIVE	;set double baud rate
	MOV TH1,#BAUD      	;timer 1 reload register load
	MOV TL1,#BAUD      	;timer 1 load
	SETB TR1		;timer 1 start

	SETB PX0 		;high   INT0 priority
	SETB IT0 		;fall   INT0 activating
	SETB EX0
	SETB EA          	;interrupts enable

MAIN:	NOP
	MOV PCON,#IDLE
	LJMP MAIN

;  ------RC5 Program Decoder------

RC5_DF	.EQU B.0		;data flag
RC5_PF	.EQU B.1		;period flag
RC5_N	=(1+2*(CLK_KHZ/188))/2
RC5_N1	=(1+2*(CLK_KHZ/249))/2
RC5_N2	=(1+2*(CLK_KHZ/382))/2
RC5_NT	=(1+2*(CLK_KHZ/135))/2

RC5:      PUSH PSW		;RC5-code program decoding
	SETB RS0
	SETB RS1		;bank 3
	MOV R5,A
	MOV R6,B

	MOV B,#2
	MOV R2,#2		;system byte init for 7 received bits
	MOV R3,#4		;command byte init for 6 received bits
	MOV R0,#R32	;R32 address load

	MOV R1,#RC5_N
WLOW:	JB SER,WHIGH
	MOV R4,#16
	DJNZ R4,$
	DJNZ R1,WLOW	;wait up to 2362uS for SER = 1
	SJMP NORC5	;jump if time is over

WHIGH:	MOV R1,#RC5_N
SAMPLE:	MOV R4,#8
	DJNZ R4,$
SAM1:	MOV R4,#3
	DJNZ R4,$
SAM2:	MOV R4,#2
	DJNZ R4,$
SAM3:	MOV C,SER
	MOV ACC.0,C
	XRL A,B
	JNB ACC.0,TRANS
	DJNZ R1,SAMPLE	;sample SER up to 2362uS
	SJMP NORC5	;jump if time is over

TRANS:	CPL RC5_DF	;transition detected
	MOV A,R1
	ADD A,#-RC5_N1
	JC NORC5		;jump if <577.5uS
	MOV A,R1
	ADD A,#-RC5_N2
	JC TRANS1
	JB RC5_PF,NORC5	;jump if >1200uS
	SJMP STDATA
TRANS1:	CPL RC5_PF
	MOV R1,#RC5_N
	JB RC5_PF,SAM1
STDATA:	MOV C,RC5_DF
	MOV A,@R0
	RLC A		;save data bit
	MOV @R0,A
	MOV R1,#RC5_N
	JNC SAM2
	INC R0		;system done, begin command
	MOV A,R0
	MOV R1,#RC5_N
	JNB ACC.2,SAM3

	MOV R1,#RC5_N
WLW:	JB SER,TRM
	MOV R4,#16
	DJNZ R4,$
	DJNZ R1,WLW	;wait up to 2362uS for SER = 1
	SJMP NORC5	;jump if time is over

TRM:	MOV R1,#RC5_NT
TERM:	JNB SER,NORC5
	MOV R4,#16
	DJNZ R4,$
	DJNZ R1,TERM

	MOV A,R2		;system nom. and control bit in R2
	ANL A,#1FH
	JB MOD,T3		;jump if "System And Command" mode

	CJNE A,#SYS,NORC5	;system number check
	SJMP T4		;jump if "Command Only" mode

T3:	MOV SBUF,A	;system code load to SBUF
	JNB TI,$		;wait for transmitter empty
	CLR TI		;clear transmitter flag

T4:	MOV SBUF,R3	;command code load to SBUF
	JNB TI,$		;wait for transmitter empty
	CLR TI		;clear transmitter flag

NORC5:	CLR IE0
	MOV B,R6
	MOV A,R5
	POP PSW
	RETI

	.END
