Code:
; IrOn-Off-v2-555.asm
; 01feb18
; Derived of IrOn-Off.hex from http://www.ivica-novakovic.from.hr/IrOn-Off-eng.htm
; Command to compile in Linux:
; gpasm -n IrOn-Off-v2-555.asm -o IrOn-Off-v2-555.hex
PROCESSOR 12F629
#INCLUDE p12f629.inc
; Watchdog ON
; __CONFIG _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_ON & _INTRC_OSC_NOCLKOUT
; Watchdog OFF
__CONFIG _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
ERRORLEVEL -302 ; Don't complain about BANK 1 Registers during assembly
; RAM-Variables
LRAM_0x20 equ 0x20
LRAM_0x21 equ 0x21
LRAM_0x22 equ 0x22
LRAM_0x23 equ 0x23
LRAM_0x28 equ 0x28
LRAM_0x32 equ 0x32 ; temporary register to store data (between swapping bytes for example)
; Address 0x3A...0x43 (10 bytes) is a buffer that stores the received IR stream code, to handling
LRAM_0x44 equ 0x44
LRAM_0x45 equ 0x45
LRAM_0x46 equ 0x46
LRAM_0x47 equ 0x47
LRAM_0x4A equ 0x4A
LRAM_0x4B equ 0x4B
LRAM_0x4C equ 0x4C
LRAM_0x4D equ 0x4D
LRAM_0x50 equ 0x50 ; bit 0 = NoToggle flag (enable (bit 0 = 0) or disable (bit 0 = 1) the PIC's output invertion)
LRAM_0x52 equ 0x52
LRAM_0x53 equ 0x53
LRAM_0x5D equ 0x5D ; Counter. Used as byte counter and index by the handler routines of the IR stream
LRAM_0x5E equ 0x5E
;-------------------------------------------------------------------------------
; Defines
;-------------------------------------------------------------------------------
#DEFINE selBank0 BCF STATUS,RP0 ; select RAM bank 0
#DEFINE selBank1 BSF STATUS,RP0 ; select RAM bank 1
#DEFINE ON_OFF GPIO,0 ; on/off output
#DEFINE LED GPIO,2
#DEFINE PRG_BUTTON GPIO,4 ; programming button
#DEFINE IR_RECV GPIO,5 ; input pin for command received from ir receiver
;-------------------------------------------------------------------------------
; Constants
;-------------------------------------------------------------------------------
OUT_PIN equ 0 ; saida para o acionamento/desligamento (GPIO0)
IRREC_PIN equ 5 ; entrada do codigo recebido pelo receptor infravermelho (12F629 pin 2 - GPIO5)
PRG_BTN equ 4 ; programming button (12F629 pin 3 - GPIO4)
LED_PIN equ 2 ; IO do LED indicador da recepcao/programacao (GPIO2)
; Start of code
ORG H'0000'
; Reset-Vector
GOTO LADR_0x005A ; goes to the beginning of the program
NOP
NOP
NOP
; Interrupt-Vector
RETFIE ; ignore interrupts
; Reads EEPROM memory
; Input: W contains EEPROM address to read
; Output: W contains the data read
LADR_0x0001
BSF STATUS,RP0 ; select bank 1
MOVWF EEADR ; copy address in EEADR
BSF EECON1,0 ; prepara leitura
MOVF EEDATA,W ; loads data in EEPROM into W register
GOTO LADR_0x0055 ; returns to RAM bank 0 and exits of this sub-routine
; Writes a data (W value) in internal EEPROM
LADR_0x0006
BSF STATUS,RP0 ; select bank 1
MOVWF EEDATA ; copy data in EEDATA
BSF EECON1,2 ; enable writing in EEPROM
; DO NOT CHANGE THIS INSTRUCTIONS ORDER!
MOVLW 0x55 ; writing initiate (!!! REQUIRED SEQUENCE #1 !!!)
MOVWF EECON2 ; !!! REQUIRED SEQUENCE #2 !!!
MOVLW 0xAA ; !!! REQUIRED SEQUENCE #3 !!!
MOVWF EECON2 ; !!! REQUIRED SEQUENCE #4 !!!
BSF EECON1,1 ; write dada into EEPROM (!!! REQUIRED SEQUENCE #5 !!!)
BCF EECON1,2 ; clears WREN flag (!!! REQUIRED !!!)
; Waits writting have been finished
LADR_0x000E
BTFSC EECON1,1 ; is the writing completed?
GOTO LADR_0x000E ; no, then waits
GOTO LADR_0x0055 ; yes, then returns to RAM bank 0 and exits from this sub-routine
; Parece ser um timer com W contendo o tempo da pausa
LADR_0x0013
MOVWF LRAM_0x22
LADR_0x0014
MOVLW 0xFF ; b'11111111' d'255'
ADDWF LRAM_0x22,F
BTFSS STATUS,C
ADDWF LRAM_0x23,F
BTFSS STATUS,C
GOTO LADR_0x0055
MOVLW 0x03 ; b'00000011' d'003'
MOVWF LRAM_0x21
MOVLW 0xDF ; b'11011111' d'223'
CALL LADR_0x0020
GOTO LADR_0x0014
LADR_0x0020
ADDLW 0xE8 ; b'11101000' d'232'
MOVWF LRAM_0x20
COMF LRAM_0x21,F
MOVLW 0xFC ; b'11111100' d'252'
BTFSS STATUS,C
GOTO LADR_0x0029
LADR_0x0026
ADDWF LRAM_0x20,F
BTFSC STATUS,C
GOTO LADR_0x0026
LADR_0x0029
ADDWF LRAM_0x20,F
; CLRWDT
INCFSZ LRAM_0x21,F
GOTO LADR_0x0026
LADR_0x002F
BTFSS LRAM_0x20,1
GOTO LADR_0x0033
NOP
GOTO LADR_0x0033
LADR_0x0033
RETURN
LADR_0x0034
BCF STATUS,C
RRF LRAM_0x21,F
RRF LRAM_0x20,F
ADDLW 0xFF ; b'11111111' d'255'
BTFSC STATUS,C
GOTO LADR_0x0034
MOVF LRAM_0x20,W
GOTO LADR_0x0055
LADR_0x003C
MOVWF LRAM_0x22
MOVLW 0x03 ; b'00000011' d'003'
GOTO LADR_0x0045
LADR_0x003F
MOVWF LRAM_0x22
MOVLW 0x01 ; b'00000001' d'001'
GOTO LADR_0x0045
;
SubRout_04
MOVF LRAM_0x47,W
MOVWF LRAM_0x23
MOVF LRAM_0x46,W
LADR_0x0042
MOVWF LRAM_0x22
MOVLW 0x06 ; b'00000110' d'006'
LADR_0x0045
MOVWF LRAM_0x28
MOVF LRAM_0x23,W
SUBWF LRAM_0x21,W
BTFSS STATUS,Z
GOTO LADR_0x004C
MOVF LRAM_0x22,W
SUBWF LRAM_0x20,W
LADR_0x004C
MOVLW 0x04 ; b'00000100' d'004'
BTFSC STATUS,C
MOVLW 0x01 ; b'00000001' d'001'
BTFSC STATUS,Z
MOVLW B'00000010' ; bitmask
ANDWF LRAM_0x28,W
BTFSS STATUS,Z
MOVLW 0xFF ; b'11111111' d'255'
LADR_0x0055
; BCF STATUS,IRP ;
; BCF STATUS,RP0 ;
BCF STATUS,RP0 ; returns to RAM bank 0
; CLRWDT ; resets watchdog timer
RETURN
;------------------------------------------
; Sets up GPIO's and SFR's (program start)
;------------------------------------------
LADR_0x005A
CLRF INTCON ; disable all interrupts
CLRF T1CON ; stops TMR1
BCF PIR1,0 ; clears TMR1 overflow flag
MOVLW B'00000111' ; bitmask
MOVWF CMCON ; disable comparators
CLRF GPIO ; let all outputs pins in low level
BSF STATUS,RP0 ; select bank 1
BCF OPTION_REG,7 ; enable internal pull-up resistors
MOVLW B'00110010' ; bitmask
MOVWF WPU ; internal pull-ups resistors enabled on pins 2, 3 and 6 (IR data, programming button and 555 output)
MOVWF GPIO ; turns pins 2, 3 and 6 as inputs, another all pins as outputs
CALL 0x03FF ; gets calibration value
MOVWF OSCCAL ; copy it in OSCCAL
BCF STATUS,RP0 ; returns to bank 0
CLRF LRAM_0x50 ; o bit 4 deste endereco _PARECE_ conter um flag que indica o recebimento de dados ou nivel baixo pelo pino 2
; Program loop?
LADR_0x007C
CALL LADR_0x0203 ; checks if programming button has been pressed
CALL LADR_0x0122 ; checks if remote controler was actived
; CLRWDT ; keeps WDT reseted
BTFSC LRAM_0x50,4 ; this is a flag?
CALL LADR_0x0084
GOTO LADR_0x007C
LADR_0x0084
BSF GPIO,2 ; turn on LED on 12F629 pin 5 (indicating that the remote control has been pressed)
CALL Upd_LED ; updates 12F629 pin 5
CLRF LRAM_0x5D ; EEPROM initial address
LADR_0x0089
CALL Counter_Test
BTFSC STATUS,C ; is index < 10?
GOTO LADR_0x009E ; no, the last byte in EEPROM and RAM was compared and are equals
MOVF LRAM_0x5D,W ; yes, then copy index value to W
CALL LADR_0x0001 ; gets byte in EEPROM
MOVWF LRAM_0x53 ; copy it in address 0x53
MOVF LRAM_0x5D,W ; restore index value in W register
ADDLW 0x3A ; pointer to IR stream data address in RAM
MOVWF FSR
MOVF INDF,W ; gets byte in address indicated by FSR
MOVWF LRAM_0x32 ; copy it to address 0x32
; CLRWDT
MOVF LRAM_0x53,W
SUBWF LRAM_0x32,W ; compares byte stored in EEPROM IR stream data with the byte written in RAM IR stream data
BTFSS STATUS,Z ; bytes are equal?
GOTO LADR_0x00A3 ; bytes are different (wrong IR code)
LADR_0x009C
INCFSZ LRAM_0x5D,F ; increments index (next byte)
GOTO LADR_0x0089 ; gets next byte to compare
; If IR stream code is right, then toggle output
LADR_0x009E
CALL Toggle_Output ; inverts output (pin 7) status
LADR_0x00A3
BCF LRAM_0x50,4
MOVLW 0x01
MOVWF LRAM_0x44 ; b'00000001' d'001'
CLRF LRAM_0x45 ; b'00000000' d'000'
LADR_0x00A7
CALL SubRout_02
BTFSS STATUS,Z
GOTO LADR_0x00B9
; CLRWDT
BTFSS GPIO,5
BSF LRAM_0x50,4
LADR_0x00B5
; incrementa 16 bits contido em 0x45,0x44 (MSB,LSB)
INCF LRAM_0x44,F
BTFSC STATUS,Z ; testa 256
INCFSZ LRAM_0x45,F ; incrementa 0x45 (byte high) se 0x44 (byte low) = 256
GOTO LADR_0x00A7
LADR_0x00B9
; CLRWDT
BTFSC LRAM_0x50,4
GOTO LADR_0x00A3
LADR_0x00BD
MOVLW 0x01 ; b'00000001' d'001'
MOVWF LRAM_0x44
CLRF LRAM_0x45
LADR_0x00C0
CALL SubRout_02
BTFSS STATUS,Z
GOTO LADR_0x00D2
; CLRWDT
BTFSS GPIO,5
GOTO LADR_0x00A3 ;
LADR_0x00CE
INCF LRAM_0x44,F
BTFSC STATUS,Z
INCFSZ LRAM_0x45,F
GOTO LADR_0x00C0
LADR_0x00D2
BCF GPIO,2 ; turn off LED on pin 5
GOTO Upd_LED ; updates LED status
LADR_0x00D7
CLRF LRAM_0x5D ; initializes index counter with 0
; Fills 10 bytes in RAM (IR stream data buffer) with 0xFF
LADR_0x00D8
CALL Counter_Test ; stream end test
BTFSC STATUS,C
GOTO LADR_0x00E4
MOVF LRAM_0x5D,W
ADDLW 0x3A ; pointer to IR stream data in RAM
MOVWF FSR ; FSR now has the address to write
MOVLW 0xFF ; value to fill stream data into RAM
MOVWF INDF ; write 0xFF into address indicated by FSR
INCFSZ LRAM_0x5D,F ; index++
GOTO LADR_0x00D8 ; next write (to until 10 bytes)
LADR_0x00E4
CLRF LRAM_0x44
CLRF LRAM_0x45
LADR_0x00E6
INCF LRAM_0x44,F
BTFSC STATUS,Z
INCF LRAM_0x45,F
CALL LADR_0x0122
; CLRWDT ; for debug only
BTFSC LRAM_0x50,4
GOTO LADR_0x00FA
MOVF LRAM_0x44,W
MOVWF LRAM_0x20
MOVF LRAM_0x45,W
MOVWF LRAM_0x21
MOVLW 0xFD ; b'11111101' d'253'
MOVWF LRAM_0x23
MOVLW 0xE8 ; b'11101000' d'232'
CALL LADR_0x003C
BTFSS STATUS,Z
GOTO LADR_0x0119
GOTO LADR_0x00E6
; Starts the stream writing (copy) from RAM to the EEPROM
LADR_0x00FA
BCF GPIO,2 ; turn off LED on pin 5
CALL Upd_LED ; updates LED status
CLRF LRAM_0x5D ; initializes index/byte counter with zero
; Copy 10 bytes from RAM (address 3Ah up to 43h) to EEPROM
LADR_0x00FF
CALL Counter_Test ; checks if index/byte counter reached the end (LRAM_0x5D = 10)
BTFSC STATUS,C ; skip if no
GOTO LADR_0x0111 ; writing has ended
MOVF LRAM_0x5D,W
ADDLW 0x3A ; adds counter value with address of the first stream byte in RAM, to get the address of byte to read
MOVWF FSR
MOVF INDF,W ; gets byte to copy
MOVWF LRAM_0x32 ; copy it to address 32h
MOVF LRAM_0x5D,W ; copy counter value (index) to W register
BSF STATUS,RP0 ; select bank 1
MOVWF EEADR ; copy counter value (index) to EEADR
BCF STATUS,RP0 ; returns to bank 0
MOVF LRAM_0x32,W
CALL LADR_0x0006 ; writes byte in EEPROM
INCFSZ LRAM_0x5D,F ; next byte
GOTO LADR_0x00FF
LADR_0x0111
MOVLW 0x01 ; b'00000001' d'001'
MOVWF LRAM_0x23
MOVLW 0xF4 ; b'11110100' d'244'
CALL LADR_0x0013
BSF GPIO,2 ; turn on LED on pin 5
CALL Upd_LED ; updates LED status
LADR_0x0119
MOVLW 0x03 ; b'00000011' d'003'
MOVWF LRAM_0x23
MOVLW 0xE8 ; b'11101000' d'232'
CALL LADR_0x0013
BCF GPIO,2 ; turn off LED on pin 5
GOTO Upd_LED ; updates LED status
LADR_0x0122
BCF LRAM_0x50,4 ; resets stream end flag
; CLRWDT ; for debug only
BTFSC GPIO,5 ;
RETURN ;
LADR_0x0128
CALL Start_TMR1
CALL Wait_IRHigh ; waits IR pin to return for level high
CALL Stop_TMR1 ; stops TMR1 and copy it to LRAM_0x4A/LRAM_0x4B and LRAM_0x20/LRAM_0x21
MOVLW 0x01 ; b'00000001' d'001'
MOVWF LRAM_0x23
MOVLW 0x5E ; b'01011110' d'094' "^"
CALL LADR_0x003C
BTFSC STATUS,Z
RETURN
LADR_0x0144
CALL SubRout_03
MOVLW 0x04 ; b'00000100' d'004'
MOVWF LRAM_0x23
MOVLW 0xE2 ; b'11100010' d'226'
CALL LADR_0x003C
BTFSS STATUS,Z
GOTO LADR_0x0153
MOVLW 0xE2 ; b'11100010' d'226'
MOVWF LRAM_0x46
MOVLW 0x04 ; b'00000100' d'004'
MOVWF LRAM_0x47
GOTO LADR_0x0180
LADR_0x0153
CALL SubRout_03
MOVLW 0x0A ; b'00001010' d'010'
MOVWF LRAM_0x23
MOVLW 0x8C ; b'10001100' d'140'
CALL LADR_0x003C
BTFSS STATUS,Z
GOTO LADR_0x0162
MOVLW 0x84 ; b'10000100' d'132'
MOVWF LRAM_0x46
MOVLW 0x03 ; b'00000011' d'003'
MOVWF LRAM_0x47
GOTO LADR_0x0190
LADR_0x0162
CALL SubRout_03
MOVLW 0x0C ; b'00001100' d'012'
MOVWF LRAM_0x23
MOVLW 0xE4 ; b'11100100' d'228'
CALL LADR_0x003C
BTFSS STATUS,Z
GOTO LADR_0x0171
MOVLW 0xEE ; b'11101110' d'238'
MOVWF LRAM_0x46
MOVLW 0x02 ; b'00000010' d'002'
MOVWF LRAM_0x47
GOTO LADR_0x0190
LADR_0x0171
CALL SubRout_03
MOVLW 0x0C ; b'00001100' d'012'
MOVWF LRAM_0x23
MOVLW 0xE4 ; b'11100100' d'228'
CALL LADR_0x0042
BTFSS STATUS,Z
GOTO LADR_0x0180
MOVLW 0xB0 ; b'10110000' d'176'
MOVWF LRAM_0x46
MOVLW 0x04 ; b'00000100' d'004'
MOVWF LRAM_0x47
GOTO LADR_0x0188
LADR_0x0180
CALL Wait_IRLow
CALL Wait_IRHigh
LADR_0x0188
CALL Wait_IRLow
CALL Wait_IRHigh
LADR_0x0190
CLRF LRAM_0x5D ; initializes index/byte counter with zero
LADR_0x0191
CALL Counter_Test ; test for stream data end
BTFSC STATUS,C ; has stream data ended?
GOTO LADR_0x0201 ; no,
MOVLW 0x01
MOVWF LRAM_0x5E
LADR_0x0198
; CLRWDT ; for debug only
MOVLW 0x05 ; b'00000101' d'005'
SUBWF LRAM_0x5E,W
BTFSC STATUS,C
GOTO LADR_0x01FF
CALL Start_TMR1
; Checks end of IR command
LADR_0x01A5
; CLRWDT ; for debug only
BTFSS GPIO,5 ; checks if pin 2 of 12F629 is high
GOTO LADR_0x01B0 ; pin 2 of 12F629 is low
; CLRWDT ; for debug only
MOVLW 0x07 ; test for de TMR1 byte high
SUBWF TMR1H,W ; the carry flag will be set if TMR1H >= 7
BTFSS STATUS,C ;
GOTO LADR_0x01A5 ;
LADR_0x01B0
CALL Stop_TMR1 ; stops TMR1 and copy it to LRAM_0x4A/LRAM_0x4B and LRAM_0x20/LRAM_0x21
CALL SubRout_04
BTFSS STATUS,Z
GOTO LADR_0x01C8
BSF LRAM_0x52,7
GOTO Jump_01
LADR_0x01C8
BCF LRAM_0x52,7
Jump_01
CALL SubRout_01
;----------------------------------------------------------------
; Starts length measuring, in TMR1, of level low on 12F629 pin 2
;----------------------------------------------------------------
CALL Start_TMR1
CALL Wait_IRHigh
CALL Stop_TMR1
CALL SubRout_04
BTFSS STATUS,Z
GOTO LADR_0x01F5
BSF LRAM_0x52,7
GOTO Jump_02
LADR_0x01F5
BCF LRAM_0x52,7
Jump_02
CALL SubRout_01
INCFSZ LRAM_0x5E,F
GOTO LADR_0x0198
LADR_0x01FF
INCFSZ LRAM_0x5D,F
GOTO LADR_0x0191
LADR_0x0201
BSF LRAM_0x50,4
RETURN
; Checks if programming button is pressed
LADR_0x0203
; CLRWDT ; for debug only
BTFSC GPIO,4 ; is pressed the programming button?
RETURN ; no
; Starts programming procedure
LADR_0x0207
MOVLW 0x01 ; b'00000001' d'001'
MOVWF LRAM_0x4C
CLRF LRAM_0x4D
LADR_0x020A
MOVF LRAM_0x4C,W
MOVWF LRAM_0x20
MOVF LRAM_0x4D,W
MOVWF LRAM_0x21
MOVLW 0x13 ; b'00010011' d'019'
MOVWF LRAM_0x23
MOVLW 0x88 ; b'10001000' d'136'
CALL LADR_0x003F
BTFSS STATUS,Z
GOTO LADR_0x021C
; CLRWDT ; for debug only
BTFSC GPIO,4 ; is pressed the programming button?
GOTO LADR_0x0203 ; no
INCF LRAM_0x4C,F ; yes
BTFSC STATUS,Z
INCFSZ LRAM_0x4D,F
GOTO LADR_0x020A
LADR_0x021C
BSF GPIO,2 ; turn on LED on 12F629 pin 5
CALL Upd_LED ; updates LED status on 12F629 pin 5
CALL LADR_0x00D7
BCF GPIO,2 ; turn off LED on 12F629 pin 5
CALL Upd_LED ; updates LED status on 12F629 pin 5
RETURN
; Updates LED status
Upd_LED
BSF STATUS,RP0 ; select bank 1
BCF GPIO,2
BCF STATUS,RP0 ; returns to bank 0
RETURN
; Dois pontos do programa usa esta sub-rotina
SubRout_01
MOVF LRAM_0x5D,W
ADDLW 0x3A ; b'00111010' d'058' ":"
MOVWF FSR
MOVF LRAM_0x52,W
MOVWF INDF
BCF STATUS,C ; clears bit
RRF LRAM_0x52,F ; read bit in carry flag
RETURN
; Dois pontos do programa usa esta sub-rotina
SubRout_02
MOVF LRAM_0x44,W
MOVWF LRAM_0x20
MOVF LRAM_0x45,W
MOVWF LRAM_0x21
MOVLW 0x03 ; b'00000011' d'003'
MOVWF LRAM_0x23
MOVLW 0xE8 ; b'11101000' d'232'
GOTO LADR_0x003F
; Clears TMR1 and LRAM_0x4A/LRAM_0x4B and starts TMR1
Start_TMR1
BCF PIR1,0 ; clears the TMR1 overflow flag
MOVLW 0x00
MOVWF LRAM_0x4A ; clears LRAM_0x4A
MOVWF LRAM_0x4B ; clears LRAM_0x4B
MOVWF TMR1L ; clears TMR1L
MOVWF TMR1H ; clears TMR1H
BSF T1CON,0 ; enable TMR1 counting
RETURN
; Stops TMR1, copy it to LRAM_0x4A/LRAM_0x4B and LRAM_0x20/LRAM_0x21
Stop_TMR1
BCF T1CON,0 ; stops TMR1
MOVF TMR1L,W
MOVWF LRAM_0x4A ; copy TMR1L in LRAM_0x4A
MOVF TMR1H,W
MOVWF LRAM_0x4B ; copy TMR1H in LRAM_0x4B
; Copy LRAM_0x4A/LRAM_0x4B in LRAM_0x20/LRAM_0x21
SubRout_03
MOVF LRAM_0x4A,W
MOVWF LRAM_0x20
MOVF LRAM_0x4B,W
MOVWF LRAM_0x21
RETURN
; Waits IR pin go to level low
Wait_IRLow
; CLRWDT ; for debug only
BTFSC GPIO,5 ; is IR out pin low?
GOTO Wait_IRLow ; no
RETURN ; yes
; Waits IR pin go to level high
Wait_IRHigh
; CLRWDT ; for debug only
BTFSS GPIO,5 ; is IR out pin high?
GOTO Wait_IRHigh ; no
RETURN ; yes
; Checks if counter reached the end (.10)
; Returns carry flag = 1 if yes
Counter_Test
; CLRWDT ; for debug only
MOVLW .10 ; counter end limit
SUBWF LRAM_0x5D,W ; compares LRAM_0x5D with .10
RETURN
; Inverts PIC12F629 output (pin 7) state
Toggle_Output
MOVLW B'00000001' ; bitmask
XORWF GPIO,F ; toggle output state
BSF STATUS,RP0 ; select bank 1
BCF GPIO,0 ; updates the output with the new level
BCF STATUS,RP0 ; returns to bank 0
RETURN
End
Bookmarks