; 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