; irmod.inc, module for receving input from
; Sony remote controls using an active low IR receiver

; Port settings
IRTRIS          equ          TRISB      ;
IRPORT          equ          PORTB      ;
IRBIT           equ          4          ; IR on PORTB<4>

; Remote control parameters
HEADER_LENGTH   equ     D'24'      ; header length = 2300 - 2500 us
SPACE_LENGTH    equ     D'6'       ; space length = 500 - 700 us
ONE_LENGTH      equ     D'11'      ; one length = 1000 - 1200 us
ZERO_LENGTH     equ     D'6'       ; zero length = 500 - 700 us
END_LENGTH      equ     D'12'      ; tail length = 1100 - 1300 us

; bits in IR_FLAGS
BYTE_READY      equ     0       ; there is a signal in REC_BYTE2:REC_BYTE1
PREV            equ     1       ; value (1 = pulse, 0 = space) of last sample
RCV             equ     2       ; set if receiving a signal

; Variables
	org 0ch
IR_FLAGS        res     1       ; flags for IR reception
CURR_TIME       res     1       ; time (/100us) so far in current pulse/space
PULSE_TIME      res     1       ; length (/100us) of last pulse
SPACE_TIME      res     1       ; length (/100us) of last space
REC_BYTE1       res     1       ; first byte that received bits are shifted into
REC_BYTE2       res     1       ; second byte that received bits are shifted into
COUNTER         res     1       ; used as counter in various loops

; Macros

; if not(literal - 1 <= file <= literal + 1) goto toAdr
bNotClose MACRO file, literal, toAdr
	movf file,W             ; move file to W
	sublw literal + 1       ; if (literal + 1 - file < 0)
	bnc toAdr                ;   goto toAdr
	sublw 2                 ; if (1 + file - literal < 0)
	bnc toAdr                ;   goto toAdr
	ENDM



	org H'0100' ; start at adr 256

; setup for IR reception
irinit: bsf     STATUS,RP0      ; Select memory bank 1
	bsf     IRTRIS,IRBIT    ; IR is input
	bcf     STATUS,RP0      ; Select memory bank 0
	clrf    IR_FLAGS        ; clear IR data
	clrf    CURR_TIME
	clrf    PULSE_TIME
	clrf    SPACE_TIME
	clrf    REC_BYTE1
	clrf    REC_BYTE2
	return


; discards n least significant bits
; in REC_BYTE2:REC_BYTE1
; indata: n in W
dropn	movwf   COUNTER
rr16    bcf     STATUS,C
	rrf     REC_BYTE2,F
	rrf     REC_BYTE1,F
	decfsz  COUNTER,F       ; if (--COUNTER > 0) goto rr16
	goto rr16
	return


; IR signal sampling
; call this every 100 us
irrec   btfss   IR_FLAGS,RCV    ; are we receiving?
	goto    notRcv
	btfsc   IRPORT,IRBIT    ; is it a space? (active low)
	goto    isSpace
	btfss   IR_FLAGS,PREV   ; was previous a space?
	goto    spToPul
	incf    CURR_TIME,F     ; pulse -> pulse, just inc time
	goto    irend

spToPul movf    CURR_TIME,W
	movwf   SPACE_TIME      ; space_time = curr_time
	clrf    CURR_TIME       ; curr_time = 0
	bsf     IR_FLAGS,PREV   ; prev = 1
	goto    addBit

isSpace btfsc   IR_FLAGS,PREV   ; was previous a pulse?
	goto    pulToSp
	incf    CURR_TIME,F     ; space -> space, inc curr_time
	movf    CURR_TIME,W
	sublw   END_LENGTH      ; w = end_length - curr_time
	bc      irend          ; if (w >= 0) return
	movf    CURR_TIME,W
	movwf   SPACE_TIME      ; space_time = curr_time
	clrf    CURR_TIME       ; curr_time = 0
	bcf     IR_FLAGS,RCV    ; done receiving
	goto    addBit

pulToSp movf    CURR_TIME,W
	movwf   PULSE_TIME      ; pulse_time = curr_time
	clrf    CURR_TIME       ; curr_time = 0
	bcf     IR_FLAGS,PREV   ; prev = 0
	goto    irend

notRcv  btfsc   IRPORT,IRBIT    ; is it a space?
	goto    irend           ; if so, all is quiet
	bsf     IR_FLAGS,RCV    ; started receiving
	clrf    CURR_TIME       ; curr_time = 0
	clrf    REC_BYTE1       ; clear receiving bytes
	clrf    REC_BYTE2       ; clear receiving bytes
	bsf     IR_FLAGS,PREV   ; prev = 1
	goto    irend

addBit  bcf     STATUS,C
	bNotClose PULSE_TIME, ONE_LENGTH, rolByte
	bsf     STATUS,C        ; it's a one

rolByte rlf     REC_BYTE1,F     ; shift new bit into
	rlf     REC_BYTE2,F     ; receving bytes
	movf    SPACE_TIME,W
	sublw   END_LENGTH      ; w = end_length - space_time
	bc      irend          ; if (end_length >= space_time) return
	bsf     IR_FLAGS,BYTE_READY     ; we have a byte!

irend   return

	end



External Labels :