;4 button IR Changed for 12f675 remake from
;Nigel Goodwin 2002
list p=12F675 ;tell assembler what chip we are using
include "P12F675.inc" ;include the defaults for the chip
errorlevel 0,-302 ;suppress bank selection messages
__config _CPD_OFF&_CP_OFF & _BODEN_OFF & _MCLRE_OFF &_PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;sets the configuration settings (oscillator type etc.)
cblock h'20' ;start of general purpose registers
count ;used in looping routines
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
LoX
Bit_Cntr
Cmd_Byte
Dev_Byte
Flags
Flags2
tmp1 ;temporary storage
tmp2
tmp3
lastdev
lastkey
shadow
endc
LED_PORT equ GPIO
LED_TRIS equ TRISIO
IR_In equ 0x03 ;input assignment for IR data
LED0 equ 0x00
LED1 equ 0x01
LED2 equ 0x02
LED3 equ 0x04
EEPROM_Addr equ 0x00 ;address of EEPROM byte used
ErrFlag equ 0x00
StartFlag equ 0x01 ;flags used for received bit
One equ 0x02
Zero equ 0x03
New equ 0x07 ;flag used to show key released
TV_ID equ 0x01 ;TV device ID
But1 equ 0x00 ;numeric button ID's
But2 equ 0x01
But3 equ 0x02
But4 equ 0x03
org 0x0000
goto Start
org 0x0004
retfie
Start movlw 0x07
movwf CMCON ;turn comparators off
clrf ANSEL
clrf VRCON
Initialise
call 0x3FF
movwf OSCCAL
movlw 0xFF
movwf TRISIO
clrf count
clrf GPIO
clrf Flags
clrf Dev_Byte
clrf Cmd_Byte
clrf shadow
SetPorts bsf STATUS,RP0 ;select bank 1
movlw b'00101000' ;make all LED pins outputs
movwf LED_TRIS
movlw b'00101000' ;make all IR port pins inputs
; movwf LED_TRIS
; bcf STATUS, RP0 ;select bank 0
call EE_Read ;restore previous settings
Main
call ReadIR ;read IR signal
call ProcKeys ;do something with commands received
goto Main ;loop for ever
ProcKeys
btfss Flags2, New
retlw 0x00 ;return if not new keypress
movlw TV_ID ;check for TV ID code
subwf Dev_Byte, w
btfss STATUS , Z
retlw 0x00 ;return if not correct code
movlw But1 ;test for button 1
subwf Cmd_Byte, w
btfss STATUS , Z
goto Key1 ;try next key if not correct code
movfw shadow
xorlw 1<<LED0
movwf shadow
movwf LED_PORT
call EE_Write ;save the settings
retlw 0x00
Key1 movlw But2 ;test for button 1
subwf Cmd_Byte, w
btfss STATUS , Z
goto Key2 ;try next key if not correct code
movfw shadow
xorlw 1<<LED1
movwf shadow
movwf LED_PORT
call EE_Write ;save the settings
retlw 0x00
Key2 movlw But3 ;test for button 1
subwf Cmd_Byte, w
btfss STATUS , Z
goto Key3 ;try next key if not correct code
movfw shadow
xorlw 1<<LED2
movwf shadow
movwf LED_PORT
call EE_Write ;save the settings
retlw 0x00
Key3 movlw But4 ;test for button 1
subwf Cmd_Byte, w
btfss STATUS , Z
retlw 0x00 ;try next key if not correct code
movfw shadow
xorlw 1<<LED3
movwf shadow
movwf LED_PORT
call EE_Write ;save the settings
retlw 0x00
EE_Read bsf STATUS,RP0 ; Bank 1
movlw EEPROM_Addr
movwf EEADR ; Address to read
bsf EECON1,RD ; EE Read
movf EEDATA,W ; W = EEDATA
bcf STATUS,RP0 ; Bank 0
movwf shadow
movwf LED_PORT ; restore previous value
retlw 0x00
EE_Write movf shadow,w ; read current value
bsf STATUS,RP0 ; Bank 1
bsf EECON1,WREN ; Enable write
bcf INTCON,GIE ;Disable INTs
movwf EEDATA ; set EEPROM data
movlw EEPROM_Addr
movwf EEADR ; set EEPROM address
movlw 0x55
movwf EECON2 ; Write 55h
movlw 0xAA
movwf EECON2 ; Write AAh
bsf EECON1,WR ; Set WR bit
bsf INTCON,GIE ;Enable INTS
; begin write
bcf STATUS,RP0 ; Bank 0
btfss PIR1,EEIF ; wait for write to complete.
goto $-1
bcf PIR1,EEIF ; and clear the 'write complete' flag
bsf STATUS,RP0 ; Bank 1
bcf EECON1,WREN ; Disable write
bcf STATUS,RP0 ; Bank 0
retlw 0x00
;IR routines
ReadIR call Read_Pulse
btfss Flags, StartFlag
goto ReadIR ;wait for start pulse (2.4mS)
Get_Data movlw 0x07 ;set up to read 7 bits
movwf Bit_Cntr
clrf Cmd_Byte
Next_RcvBit2 call Read_Pulse
btfsc Flags,StartFlag ;abort if another Start bit
goto ReadIR
btfsc Flags,ErrFlag ;abort if error
goto ReadIR
bcf STATUS , C
btfss Flags, Zero
bsf STATUS , C
rrf Cmd_Byte , f
decfsz Bit_Cntr , f
goto Next_RcvBit2
rrf Cmd_Byte,f ;correct bit alignment for 7 bits
Get_Cmd movlw 0x05 ;set up to read 5 bits
movwf Bit_Cntr
clrf Dev_Byte
Next_RcvBit call Read_Pulse
btfsc Flags,StartFlag ;abort if another Start bit
goto ReadIR
btfsc Flags,ErrFlag ;abort if error
goto ReadIR
bcf STATUS , C
btfss Flags, Zero
bsf STATUS , C
rrf Dev_Byte , f
decfsz Bit_Cntr , f
goto Next_RcvBit
rrf Dev_Byte,f ;correct bit alignment for 5 bits
rrf Dev_Byte , f
rrf Dev_Byte , f
retlw 0x00
;end of ReadIR
;read pulse width, return flag for StartFlag, One, Zero, or ErrFlag
;output from IR receiver is normally high, and goes low when signal received
Read_Pulse clrf LoX
btfss LED_PORT,IR_In ;wait until high
goto $-1
clrf tmp1
movlw 0xC0 ;delay to decide new keypress
movwf tmp2 ;for keys that need to toggle
Still_High btfss LED_PORT,IR_In ;and wait until goes low
goto Next
incfsz tmp1,f
goto Still_High
incfsz tmp2,f
goto Still_High
bsf Flags2,New ;set New flag if no button pressed
goto Still_High
Next nop
nop
nop
nop
nop ;waste time to scale pulse
nop ;width to 8 bits
nop
nop
nop
nop
nop
nop
incf LoX, f
btfss LED_PORT, IR_In
goto Next ;loop until input high again
; test if Zero, One, or Start (or error)
Chk_Pulse clrf Flags
TryError movf LoX,w ; check if pulse too small
addlw d'255'-d'20' ; if LoX <= 20
btfsc STATUS , C
goto TryZero
bsf Flags,ErrFlag ; Error found, set flag
retlw 0x00
TryZero movf LoX,w ; check if zero
addlw d'255'-d'60' ; if LoX <= 60
btfsc STATUS , C
goto TryOne
bsf Flags,Zero ; Zero found, set flag
retlw 0x00
TryOne movf LoX,w ; check if one
addlw d'255'-d'112' ; if LoX <= 112
btfsc STATUS , C
goto TryStart
bsf Flags,One ; One found, set flag
retlw 0x00
TryStart movf LoX,w ; check if start
addlw d'255'-d'180' ; if LoX <= 180
btfsc STATUS , C
goto NoMatch
bsf Flags,StartFlag ; Start pulse found
retlw 0x00
NoMatch ; pulse too long
bsf Flags,ErrFlag ; Error found, set flag
retlw 0x00
;end of pulse measuring routines
;Delay routines
Delay255 movlw 0xff ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
d0 movwf count1
d1 movlw 0xC7
movwf counta
movlw 0x01
movwf countb
Delay_0 decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
retlw 0x00
;end of Delay routines
org 0x2100
data 00; initial value of shadow
end