;************************************************************************************************************************ ; ; RECEPTOR DE CONTROLE REMOTO PARA PORTÃO ; ; ; BY CLÁUDIO LÁRIOS 17-11-2011 PUBLICADO:19/05/2012 ; ; ; ; ; PROJETO BASEADO EM 'NOTE APLICATTION MICROCHIP/KEELOG' ADAPTADO PARA FUNCIONAR COM EEPROM INTERNA DO ; PIC 12F629 E PARA ESTA APLICAÇÃO ESPECIFICA. USE OSCILADOR INTERNO DE 4 MHZ. RESET INTERNO (PINO COMO ENTRADA) ; USO RESTRITO PARA FINS NÃO COMERCIAIS APENAS. ; (CUIDADOS ESPECIAIS DEVEM SER TOMADOS AO MANUSEAR EQUIPAMENTO ELETRICO LIGADOS NA REDE ELETRICA.) ; FUNÇÃO: RECEBER SINAL DE UM HCS200/201/300/301 E DECODIFICAR ; ACIONANDO SAIDAS TEMPORIZADAS NO PIC. ; OBS. GRAVAR A MESMA CHAVE NO HCS E NO PIC PARA FUNCIONAR. ; GRAVADOR: USE HCS_PROG OU HCS_PROG_TINY PARA GRAVAR HCS200...301. ; USE A MESMA 'KEY' AQUI E NO TRANSMISSOR. USE:DISC=SERIAL ; PODE APRENDER ATÉ 15 'CHAVEIRINHOS' (TRANSMISSORES) ; APERTE 'LRN' E DEPOIS ACIONE O CONTROLE REMOTO PARA APRENDER SEU CÓDIGO. ; APERTE 'LRN' POR MAIS DE 15 SEG PARA APAGAR TODOS OS CONTROLES DA MEMÓRIA (PERDA/ROUBO DE CONTROLE). ; APÓS ISTO, OS CONTROLES RESTANTES TEM QUE SEREM REAPRENDIDOS. ; USA O PINO 2 (GP5) TANTO COMO SAIDA PARA APAGAR LED LEARN COMO ENTRADA PARA RECONHECER APRENDIZADO. ; ;------------------------------------------------------------------------------ ; PINAGEM DO PIC 12F629: ; PINO 1- +VCC ; PINO 2- IN/OUT - LED 'LEARN' AO +VCC VIA RESISTOR DE 4K7 AO PINO 2 E DO PINO 2 AO RESISTOR DE 470 A CHAVE 'LRN' A MASSA ; PINO 3- IN - INTERRUPTOR FIM DE CURSO S2 A MASSA.NÃO NECESSITA DE PULL-UP. USE REEDSWITCH COM UM IMÃ PERMANENTE. ; PINO 4- IN - PULLUP 10K AO VCC E INTERRUPTOR FIM DE CURSO S1 A MASSA. USE REEDSWITCH COM UM IMÃ PERMANENTE. ; PINO 5- SAIDA RELE M1 VIA TRANSISTOR NPN ; PINO 6- SAIDA RELE M2 VIA TRANSISTOR NPN ; PINO 7- IN RF (ENTRADA DE PULSOS)OBS. USE UM DIODO E RESISTORES PARA REDUZIR RUIDO DO TX ; PINO 8- MASSA ;------------------------------------------------------------------------------ ; SIMPLE DECODER WITH ONE STEP LEARN AND SINGLE KEY LIST P=12f629 , R=DEC INCLUDE "P12F629.INC" ;-------------------------- ERRORLEVEL -302 __CONFIG _CP_OFF & _PWRTE_ON & _WDT_ON & _INTRC_OSC_NOCLKOUT & _BODEN_ON & _MCLRE_OFF ;---------------------------------------------------- ;******USER DEFINITIONS****** MAX_USERS EQU .15 ; This is the maximum number of transmitters that the system is able to ; learn (1 to 15). ;------------------------------------------------------------------------------ #DEFINE BANK0 BCF STATUS,RP0 ;SETA BANK0 DE MEMORIA #DEFINE BANK1 BSF STATUS,RP0 ;SETA BANK1 ; GENERAL PURPOSE REGISTERS IND EQU 00H ; INDIRECT ADDRESS REGISTER RTCC EQU 01H ; REAL TIME COUNTER CLOCK PC EQU 02H ; PROGRAM COUNTER STATUS EQU 03H ; STATUS REGISTER FSR EQU 04H ; FILE SELECT REGISTER PORTA EQU 05H ; PORT A PORTB EQU 06H ; PORT B ;CMCON EQU 1FH ;CONTROLE DOS COMPARADORES ; USER DEFINED REGISTER AFLAG EQU 40H ;FLAG PARA O ALARME #DEFINE FLEDP AFLAG,4 ;FLAG AUXILIAR P/ O PISCAR DO LED #DEFINE ON AFLAG,0 ;FLAG AUXILIAR P/ ON/OFF DO ALARME #DEFINE FLRN AFLAG,2 ;FLAG AUXILIAR DE LEARN ATIVADO #DEFINE FPA AFLAG,3 ; FLAG DE PORTA ABERTA #DEFINE ONA AFLAG,1 ; FLAG DE LIGAR POR TEMPO INICIAL ;-------------------------------------------------------- FLAGS EQU 20H ; USER FLAG REGISTER ADDRESS EQU 21H ; ADDRESS REGISTER TXNUM EQU 22H ; CURRENT TX OUTBYT EQU 23H ; GENERAL DATA REGISTER MASK EQU OUTBYT ; MASK REGISTER USED IN DECRYPTION TMP_CNT EQU OUTBYT ; TEMPORARY COUNTER ; COUNTER REGISTERS CNT0 EQU 24H ; LOOP COUNTERS CNT1 EQU 25H CNT2 EQU 26H CNT_HI EQU 27H ; 16 BIT CLOCK COUNTER CNT_LW EQU 28H CNT_HIX EQU 41H ;CONTADOR EXTRA PARA ALARME HIGH (TEMPO DE 3 MIN) CNT_LWX EQU 42H ;CONTADOR EXTRA PARA ALARME LOW ; CIRCULAR BUFFER REGISTER CSR0 EQU 29H ; 64 BIT RECEIVE SHIFT REGISTER CSR1 EQU 2AH CSR2 EQU 2BH CSR3 EQU 2CH CSR4 EQU 2DH CSR5 EQU 2EH CSR6 EQU 2FH CSR7 EQU 30H ; TEMP REGISTERS TMP1 EQU 31H ; TEMP REGISTER FOR READ AND WRITE TMP2 EQU 32H ; TEMP REGISTER FOR READ AND WRITE REG EQU 33H ; NOT USED REG1 EQU 34H ; NOT USED KEY0 EQU 35H ; 64 BIT KEY SHIFT REGISTER KEY1 EQU 36H KEY2 EQU 37H KEY3 EQU 38H KEY4 EQU CNT2 KEY5 EQU CSR5 KEY6 EQU CSR6 KEY7 EQU CSR7 AUX EQU 39H AUX8 EQU 46H SITUAÇÃO EQU 47H R1 EQU 3AH R2 EQU 3BH STMP1 EQU 3CH STMP2 EQU 3DH SADDRESS EQU 3EH SW EQU 3FH CP EQU 43H FILTRO1 EQU 44H FILTRO2 EQU 45H TF2 EQU .5 ; ***** USER REGISTER RE-MAPPINGS *************** HOP1 EQU CSR0 ; 32 BIT HOPCODE REGISTER HOP2 EQU CSR1 HOP3 EQU CSR2 HOP4 EQU CSR3 ; RECEIVED TRANSMISSION OPEN 32 BITS SER_0 EQU CSR7 ; 28 BIT SERIAL NUMBER SER_1 EQU CSR6 SER_2 EQU CSR5 SER_3 EQU CSR4 ; RECEIVED TRANSMISSION ENCRYPTED 32 BITS FUNC EQU CSR3 ; BUTTON CODE & USER BIT FUNCTION BYTE DISC EQU CSR2 ; DISCRIMINATION VALUE CNTR_HI EQU CSR1 ; 16 BIT RX COUNTER HIGH BYTE CNTR_LW EQU CSR0 ; 16 BIT RX COUNTER LOW BYTE ; ********* EEPROM MEMORY ******* LRNPTR EQU 3FH ; LEARN POINTER 01H ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #DEFINE RFIN GPIO,0 ;PINO 7 IN RF #DEFINE LRN GPIO,5 ;PINO 4 IN LEARN BOTTON #DEFINE LED GPIO,5 ;PINO 2 OUT LED (MESMO PINO DO ACIMA) #DEFINE S2 GPIO,4 ;PINO 3- ENTRADA DE S2 ,ACIONA COM NEGATIVO #DEFINE M1 GPIO,2 ;PINO 5 -SAIDA DO MOTOR #DEFINE M2 GPIO,1 ;PINO 6-SAIDA DO MOTOR #DEFINE S1 GPIO,3 ;PINO 3- ENTRADA DE S1 ,ACIONA COM NEGATIVO ; ********* COMPILER DEFINES ****************** NBITS EQU .64 ; MAXIMUM TRANSMISSION BIT LENGTH MIN EQU .560 ; TRANSMISSION HEADER MINIMUM LENGTH [ S] ITRISA EQU B'111001' ; PORTA: TRI-STATE VALUE GP5 LED/LRN COMO ENTRADA INICIALMENTE OTRISA EQU B'011001' ; PORTA: TRI-STATE VALUE GP5 LED/LRN COMO SAIDA PARA APAGA LED ;****** FLAGS DEFINITIONS ************** BITIN EQU 0H ; RF BIT VALUE LRNF EQU 1H ; LEARN FLAG SEC_CNT EQU 2H ; SECOND COUNTER IS BEING CHECKED RELEARN EQU 3H ; RELEARNING A TRANSMITTER ;****** STATUS REGISTER BIT DEFINITIONS ***************** C EQU 0 ; CARRY DC EQU 1 ; DIGIT CARRY Z EQU 2 ; ZERO PD EQU 3 ; POWER DOWN TO EQU 4 ; TIMEOUT PA0 EQU 5 ; NOT USED PA1 EQU 6 ; NOT USED ;------------------------------------------------------------------------------ ORG H'2100' ;vetor de eeprom ;------------------------------------------------------------------------------ ORG 00H goto RESET ORG 04H RETFIE ;------------------------------------------------------------------------------ ; ; FUNCTION : RESET () ; ; ;------------------------------------------------------------------------------ RESET MOVLW 0X07 MOVWF CMCON ;DESLIGA COMPARADORES MOVLW B'000111' ; SETUP RTCC PRESCALER OPTION CLRF GPIO ; RESET PORTA MOVLW ITRISA ; SETUP PORTA TRIS GPIO CLRF CNT_HIX CLRF CNT_LWX ;APAGA CONTADORES AUXILIARES DE TEMPO CLRF FLAGS ; RESET FLAGS GOTO M_LOOP ; GOTO MAIN PROGRAM LOOP ;----------------------------------------------------------------- ; FUNCTION : ROT_SHIFT() ; ; DESCRIPTION : RIGHT ROTATE 64 BIT RECEIVE SHIFT REGISTER ; ;------------------------------------------------------------------------------ ROT_SHIFT RRF CSR7,F RRF CSR6,F RRF CSR5,F RRF CSR4,F RRF CSR3,F RRF CSR2,F RRF CSR1,F RRF CSR0,F RETLW .0 ;------------------------------------------------------------------------------ ; ; FUNCTION : TX_LOOKUP () ; ; DESCRIPTION : TRANSMITTER ADDRESS CALCULATION ; ;------------------------------------------------------------------------------ TX_LOOKUP MOVF TXNUM,W ; USE TRANSMITTER NUMBER TO CALCULATE MOVWF ADDRESS ; ADDRESS OF TRANSMITER BLOCK CLRC ; MULTIPLY BY 4 RLF ADDRESS,F RLF ADDRESS,F RETLW .0 ; RETURN ;------------------------------------------------------------------------------ ; ; FUNCTION : TST_RTCC () ; ; DESCRIPTION : UPDATE RTCC COUNTER ; ;------------------------------------------------------------------------------ TST_RTCC CLRWDT ; RESET WATCHDOG TIMER MOVLW ITRISA ; UPDATE TRI-STATE REGISTER FOR PORTA TRIS GPIO BTFSS RTCC,7 ; TEST FOR 32MS TIMEOUT ON RTCC MSB RETLW .0 ; ... DO QUICK RETURN TO RECEIVE ROUTINE ; **** INCREASE 16 BIT CLOCK TIMER ******* BTFSS CNT_HIX,2 GOTO Y8 BCF M1 ;DESLIGA MOTORES APOS 22 SEG (CNT_HIX,2) [PARA 44SEG USE CNT_HIX,3] BCF M2 CLRF CNT_HIX CLRF CNT_LWX INCF SITUAÇÃO,F ;EVITA UM APERTO A MAIS QUANDO MOTOR PARA POR TEMPO Y8 BCF RTCC,7 ; CLEAR MSB OF RTCC INCF CNT_LW,F ; INCREASE 16 COUNTER SKPNZ ; INCREASE UPPER BYTE IF ZERO ( OVERFLOW ) INCF CNT_HI,F INCF CNT_LWX,F ; INCREASE 16 COUNTER ADICIONAL SKPNZ ; INCREASE UPPER BYTE IF ZERO ( OVERFLOW ) INCF CNT_HIX,F ;CONTAGEM MAXIMA 34 MIN. RETURN ;------------------------------------------------------------------------------ ; ; FUNCTION : TST_TIMER() ; ; DESCRIPTION : TEST 32MS TIMER AND UPDATE OUTPUTS IF REQUIRED ; ; ;------------------------------------------------------------------------------ TST_TIMER ; ***** TEST FOR 500 MS TIMEMOUT ON OUTPUTS ********** ; BTFSS CNT_LW,4 ; TEST FOR 500 MS TIMEOUT ; GOTO TST_30 ; ... IF NOT TEST 30S TIMEOUT ; MOVLW 0F0H ; ANDWF PORTB,F ; DOWN ALL PULSE OUTPUTS ; CLRF GPIO ;DESLIGA SAIDAS ; ********* TEST FOR 30 S LEARN TIMEOUT ************* TST_30 BTFSS FLAGS,LRNF GOTO TST_END BTFSC CNT_HI,2 ; TEST FOR LEARN TIMEOUT BCF FLRN ;APAGA FLAG 'LEARN' RETLW 1H TST_END RETLW 0H ;------------------------------------------------------------------------------ AGUARDE ;ROTINA DE ATRASO ENTRE OPERAÇÕES DE EEPROM MOVLW .64 MOVWF R1 CG2 CLRWDT MOVLW .255 MOVWF R2 DECFSZ R2,F GOTO $-1 DECFSZ R1,F GOTO CG2 RETURN ;------------------------------------------------------------------------------ ; ; FUNCTION : EEWRITE () ; ; DESCRIPTION : WRITE 16 BIT VALUE TO EEPROM ; ; ;------------------------------------------------------------------------------ EEWRITE ; ******* EEPROM WRITE ENABLE ****************** ;endereço esta em ADDRESS ;DADOS A ESCREVER ESTA EM TMP1(MSB) E TMP2 (LSB) CALL AGUARDE clrwdt movfw ADDRESS MOVWF AUX BCF STATUS,C RLF AUX,F ;AUXILIAR X 2 MOVFW AUX BANK1 movwf EEADR BANK0 MOVFW TMP1 ;PEGA PRIMEIRO DADO BANK1 movwf EEDATA bcf EECON1, EEIF bsf EECON1, WREN ; enable Write\par movlw 0x55 movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1, WR WRITE_SN_A clrwdt btfsc EECON1, WR ; Write complete ?\par goto WRITE_SN_A bcf EECON1, WREN ; disable Write\par BANK0 clrwdt ESPERA1 ;DELAY ENTRE APAGAMENTOS CALL AGUARDE INCF AUX,F MOVFW AUX BANK1 movwf EEADR BANK0 MOVFW TMP2 ;PEGA SEGUNDO DADO BANK1 movwf EEDATA bcf EECON1, EEIF bsf EECON1, WREN ; enable Write\par movlw 0x55 movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1, WR WRITE_SN_B clrwdt btfsc EECON1, WR ; Write complete ?\par goto WRITE_SN_B bcf EECON1, WREN ; disable Write\par BANK0 CALL AGUARDE RETURN ;------------------------------------------------------------------------------ ; ; FUNCTION : EEREAD () ; ; DESCRIPTION : READ 16 BIT VALUE FROM EEPROM ; ; ; ;------------------------------------------------------------------------------ EEREAD ;endereço esta em ADDRESS ;DADOS LIDOS SERÃO ESCRITOS EM TMP1(MSB) E TMP2 (LSB) clrwdt MOVFW ADDRESS MOVWF AUX BCF STATUS,C RLF AUX,F MOVFW AUX BANK1 movwf EEADR bsf EECON1, RD ; do a read\par clrwdt btfsc EECON1, RD ; Read done ?\par goto $-2 movf EEDATA,W BANK0 MOVWF TMP1 ;RECUPERA PRIMEIRO NUMERO DA EEPROM clrwdt INCF AUX,F MOVFW AUX BANK1 movwf EEADR bsf EECON1, RD ; do a read\par clrwdt btfsc EECON1, RD ; Read done ?\par goto $-2 movf EEDATA,W BANK0 MOVWF TMP2 ;RECUPERA SEGUNDO NUMERO DA EEPROM clrwdt RETLW 0H ;------------------------------------------------------------------------------ APAGAEEPROM ;OK TESTADA E APROVADA ; ROTINA PARA APAGAR TODAS AS POSIÇOES DA EEPROM DO 16F628 MOVLW 0X80 ;TOTAL DE 128 + 1 BYTES DE EEPROM MOVWF AUX RET6 CLRWDT MOVFW AUX MOVLW .1 ;ACERTA ENDEREÇO TIRANDO 1 SUBWF AUX,W BANK1 movwf EEADR MOVLW 0XFF movwf EEDATA bcf EECON1, EEIF bsf EECON1, WREN ; enable Write\par movlw 0x55 movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1, WR WRITE_SN_C clrwdt btfsc EECON1, WR ; Write complete ?\par goto WRITE_SN_C bcf EECON1, WREN ; disable Write\par BANK0 DECFSZ AUX,F GOTO ESPERA clrwdt RETLW 0H ESPERA ;DELAY ENTRE APAGAMENTOS MOVLW .8 MOVWF R1 CG1 MOVLW .255 MOVWF R2 DECFSZ R2,F GOTO $-1 DECFSZ R1,F GOTO CG1 GOTO RET6 ;------------------------------------------------------------------------------ ; ; FUNCTION : DECRYPT () ; ; DESCRIPTION : DECRYPTS 32 BIT [HOP1:HOP4] USING [CSR0:CSR7] ; ;------------------------------------------------------------------------------ ;ATENÇÃO!!! ABAIXO ESTÁ A 'KEY' QUE TEM QUE SER A MESMA DO TRANSMISSOR ; SERVINDO QUALQUER ENCODER COMO HCS200 , 201, 300, 301 (O QUE TIVER DISPONIVEL ) ; MUDE AQUI PARA O MESMO VALOR PARA SEU TRANSMISSOR (KEY QUE FOI PROGRAMADO NO HCS 200...301) DECRYPT MOVLW 01H ;MENOS SIGNIFICATIVO (LSB) MOVWF KEY0 MOVLW 23H MOVWF KEY1 MOVLW 45H MOVWF KEY2 MOVLW 67H MOVWF KEY3 MOVLW 89H MOVWF KEY4 MOVLW 0ABH MOVWF KEY5 MOVLW 0CDH MOVWF KEY6 MOVLW 0EFH ; LOAD FIXED 64 BIT KEY MSB MOVWF KEY7 MOVLW .12 ; OUTER LOOP 11+1 TIMES MOVWF CNT1 ; OUTER LOOP 11+1 TIMES DECRYPT_OUTER MOVLW .48 ; INNER LOOP 48 TIMES MOVWF CNT0 ; INNER LOOP 48 TIMES DECRYPT_INNER CLRWDT ; RESET WATCHDOG TIMER MOVFW CNT1 ; LAST 48 LOOPS RESTORE THE KEY XORLW .1 ; LAST 48 LOOPS RESTORE THE KEY SKPNZ ; LAST 48 LOOPS RESTORE THE KEY GOTO ROTATE_KEY ; LAST 48 LOOPS RESTORE THE KEY ; THE LOOKUP TABLE IS COMPRESSED INTO IN 4 BYTES TO SAVE SPACE ; USE THE 3 LOW INDEX BITS TO MAKE UP AN 8-BIT BIT MASK ; USE THE 2 HIGH INDEX BITS TO LOOK UP THE VALUE IN THE TABLE ; USE THE BIT MASK TO ISOLATE THE CORRECT BIT IN THE BYTE ; PART OF THE REASON FOR THIS SCHEME IS BECAUSE NORMAL TABLE LOOKUP ; REQUIRES AN ADDITIONAL STACK LEVEL CLRC ; CLEAR CARRY (FOR THE LEFT SHIFT) MOVLW .1 ; INITIALISE MASK = 1 BTFSC HOP3,3 ; SHIFT MASK 4X IF BIT 2 SET MOVLW B'10000' ; SHIFT MASK 4X IF BIT 2 SET MOVWF MASK ; INITIALISE MASK = 1 BTFSS HOP2,0 ; SHIFT MASK ANOTHER 2X IF BIT 1 SET GOTO $+3 RLF MASK,F RLF MASK,F BTFSC HOP1,0 ; SHIFT MASK ANOTHER 1X IF BIT 0 SET RLF MASK,F ; MASK HAS NOW BEEN SHIFTED 0-7 TIMES ACCORDING TO BITS 2:1:0 MOVLW .0 ; TABLE INDEX = 0 BTFSC HOP4,1 IORLW .2 ; IF BIT 3 SET ADD 2 TO THE TABLE INDEX BTFSC HOP4,6 IORLW .4 ; IF BIT 4 SET ADD 4 TO THE TABLE INDEX movwf AUX MOVLW .6 SUBWF AUX,W BTFSC STATUS,Z GOTO SEIS MOVLW .4 SUBWF AUX,W BTFSC STATUS,Z GOTO QUATRO MOVLW .2 SUBWF AUX,W BTFSC STATUS,Z GOTO DOIS MOVLW 02EH GOTO TABLE_END DOIS MOVLW 074H GOTO TABLE_END QUATRO MOVLW 05CH GOTO TABLE_END SEIS MOVLW 03AH GOTO TABLE_END TABLE_END ANDWF MASK,F ; ISOLATE THE CORRECT BIT BY ANDING WITH MASK MOVLW .0 ; COPY THE BIT TO BIT 7 SKPZ ; COPY THE BIT TO BIT 7 MOVLW B'10000000' ; COPY THE BIT TO BIT 7 XORWF HOP2,W ; ONLY INTERESTED IN BIT HOP2,7 XORWF HOP4,W ; ONLY INTERESTED IN BIT HOP4,7 XORWF KEY1,W ; ONLY INTERESTED IN BIT KEYREG1,7 MOVWF MASK ; STORE W TEMPORARILY (WE NEED BIT 7) RLF MASK,F ; LEFT ROTATE MASK TO GET BIT 7 INTO THE CARRY RLF HOP1,F ; SHIFT IN THE NEW BIT RLF HOP2,F RLF HOP3,F RLF HOP4,F ROTATE_KEY CLRC ; CLEAR CARRY BTFSC KEY7,7 ; SET CARRY IF LEFTMOST BIT SET SETC ; SET CARRY IF LEFTMOST BIT SET RLF KEY0,F ; LEFT-ROTATE THE 64-BIT KEY RLF KEY1,F RLF KEY2,F RLF KEY3,F RLF KEY4,F RLF KEY5,F RLF KEY6,F RLF KEY7,F DECFSZ CNT0,F ; INNER LOOP 48 TIMES GOTO DECRYPT_INNER ; INNER LOOP 48 TIMES DECFSZ CNT1,F ; OUTER LOOP 12 TIMES (11 + 1 TO RESTORE KEY) GOTO DECRYPT_OUTER ; OUTER LOOP 12 TIMES (11 + 1 TO RESTORE KEY) RETLW 0 ; RETURN ;------------------------------------------------------------------------------ ; ; FUNCTION : LOAD_CNT_VALS() ; ; DESCRIPTION : LOAD COUNTERS INTO WRITE BUFFERS ; ;------------------------------------------------------------------------------ LOAD_CNT_VALS MOVFW CNTR_HI ; LOAD MSB OF COUNTER MOVWF TMP1 MOVFW CNTR_LW ; LOAD LSB OF COUNTER MOVWF TMP2 RETLW .0 ;------------------------------------------------------------------------------ ; ; FUNCTION : RECEIVE() ; ; DESCRIPTION : RECEPTION ROUTINE FOR PWM TRANSMISSIONS ; ; ;------------------------------------------------------------------------------ RECEIVE ;******** WAIT FOR HEADER AND CALIBRATE ******************* BTFSS RFIN ; INPUT LOW? GOTO RMT_0 ; YES; RECEIVE ERROR MOVLW .10 ; 10 ms TIMER MOVWF CNT1 RCV0 MOVLW .200 MOVWF CNT0 RCV1 BTFSS RFIN ; [2] INPUT HIGH? GOTO RCV2 ; [0] NO, JUMP OUT OF LOOP DECFSZ CNT0,1 ; [1] YES, CONTINUE WITH TIMING LOOP GOTO RCV1 ; [2] 5 us X CNT0 DECFSZ CNT1,1 ; [0] DO 1 ms LOOP CNT1 TIMES GOTO RCV0 ; [0] RCV2 CLRF CNT0 ; [1] CLEAR CALIB COUNTER LOW BYTE CLRF CNT1 ; [1] CLEAR CALIB COUNTER HIGH BYTE ;************************************************************************* ; 2.5 IS AVERAGE FOR DETECTING FALLING EDGE IN RCV1 ; 2 INSTRUCTIONS FOR JUMP OUT RCV1 TO RCV2 ; 2 INSTRUCTIONS FOR RCV2 - CLEAR CALIBRATION COUNTER ; TOTAL 6.5 INSTRUCTIONS < 1 CALIBRATION LOOP SO DISCARD ;************************************************************************* RCV3 BTFSC RFIN ; [2][2] INPUT HIGH? GOTO RCV6 ; [0][0] YES--END CALIBRATION INCF CNT0,1 ; [1] INCREMENT 16BIT COUNTER SKPNZ ; [2] INCF CNT1,1 ; [0] CLRWDT ; [1] RESET WATCH DOG TIMER NOP ; [1] BTFSS CNT1,3 ; [1] GOTO RCV3 ; [2] GOTO RMT_0 ; [0] ; TOTAL = 10 RCV6 CLRC ; [1] DIVIDE CNT1:CNT0 BY 8 (600/8=75) RRF CNT1,1 ; [1] RRF CNT0,1 ; [1] RRF CNT1,1 ; [1] RRF CNT0,1 ; [1] RRF CNT1,1 ; [1] RRF CNT0,1 ; [1] MOVLW MIN/80 ; [1] SUBWF CNT0,W ; [1] BTFSS STATUS,C ; [2] NEGATIVE? GOTO RMT_0 ; [0] YES--HEADER SHORTER THAN MIN. ; TOTAL = 11 ; ************* VALID HEADER RECEIVED ********************* RCV7 MOVLW NBITS ; [1] VALID START MARKER WAS RECEIVED MOVWF CNT1 ; [1] MOVF CNT0,W ; [1] MOVWF CNT2 ; [1] CNT2 = CNT0 MOVLW 6H ; [1] SEE NOTE BELOW SUBWF CNT2,1 ; [1] GOTO DL1 ; [2] COMPENSATE FOR FIRST BIT ; TOTAL = 8 ;********************************************************************************** ; 2.5 IS AVERAGE PLAY BETWEEN RISING EDGE AND JUMP OUT OF CALIBRATION LOOP. ; 2 FOR JUMP OUT OF RCV3 TO RCV6 ; 11 INSTRUCTIONS FOR RVC6 - CAIBRATION COUNTER DIVIDE ; 8 INSTRUCTIONS FOR RCV7 - COMPENSATE FOR POST CALIBRATION CALCUATIONS ; TOTAL 22.5 INSTRUCTIONS BETWEEN RISING EDGE AND ENTERING DL1 ; THEREFORE SUBTRACT 22.5/4 = 5.625 TO COMPENSATE FOR POST CALCULATION ON 1ST BIT ;********************************************************************************** RCV8 MOVLW 4H ; [1] WAIT A MAXIMUM OF 4 Te MOVWF TMP_CNT ; [1] SET TEMP LOOP COUNTER RCV10A MOVFW CNT0 ; [1] and CSR processing MOVWF CNT2 ; [1] Refer to explanation above RCV10B BTFSC RFIN ; [2] Wait for rising edge GOTO RCV11 ; [0] Edge found--Process CLRWDT ; [1] Clear watchdog Timer BTFSC RFIN ; [2] Wait for Next rising edge GOTO RCV11 ; [0] Edge found--Process DECFSZ CNT2,1 ; [1] Decrement Timeout counter GOTO RCV10B ; [2] Loop Back ; TOTAL = 8, RFIN CHECKED EVERY 4uS ON AVERAGE DECFSZ TMP_CNT,1 ; [1] ALL Te PERIODS GOTO RCV10A ; [2] ... NO, THEN WAIT FOR NEXT ONE GOTO RMT01 ; [0] ... YES, [0] TIMEOUT--no edge found RCV11 MOVLW 3H ; [1] SEE NOTE BELOW SUBWF CNT0,W ; [1] MOVWF CNT2 ; [1] ;************************************************************************* ; 2 SETUP OF TEMP LOOP COUNTER ( ONLY ONCE ) ; 2 SETUP TE LOOP COUNTER ( MAX 4 ) ; 3 DECREMENT TEMP LOOP COUNTER ( MAX 4 ) ; 4 IS THE AVERAGE PLAY BETWEEN EDGE AND EDJE BEING DETECTED IN RCV9 ; 2 JUMP OUT OF RCV10B TO RCV11 ; 3 FOR RCV11 ; TOTAL 10 INSTRUCTIONS BETWEEN EDGE AND ENTERING DL1 ; THEREFORE SUBTRACT 10/4 = 2.5 => 3 DL1 LOOPS TO COMPENSATE FOR ;************************************************************************* DL1 CLRWDT ; [1] RESET WATCHDOG TIMER DECFSZ CNT2,1 ; [1] [2, IF SKIP] GOTO DL1 ; [2] CNT0 X 4 us SAMPLE1 BTFSS RFIN ; [2] INPUT HIGH? FIRST SAMPLE GOTO RMT01 ; [0] NO--ERROR MOVF CNT0,W ; [1] CALIBRATION COUNTER MOVWF CNT2 ; [1] (NOMINALLY 75 FOR 300 us PULSE) DECF CNT2,1 ; [1] SUBTRACT 2 FROM FINAL CALIB COUNTER TO COMPENATE FOR THIS GOTO $+1 ; [2] NOP ; [1] ; TOTAL = 8 => 1 LOOP COUNTER DL2 CLRWDT ; [1] RESET WATCHDOG TIMER GOTO $+1 ; [2] WASTE TIME GOTO $+1 ; [2] WASTE TIME DECFSZ CNT2,1 ; [1] GOTO DL2 ; [2] CNT0 X 8 us [ CNT0 x Te ] SAMPLE2 BCF FLAGS,BITIN ; [1] CLEAR BIT POSITION BTFSS RFIN ; [1.5] LEAVE 0 IF LINE HIGH BSF FLAGS,BITIN ; [0.5] MAKE 1 IF LINE LOW ; SUB TOTAL = 3 CYCLES CALL ROT_SHIFT ; [11]+[2] CSR SHIFT + CALL BCF CSR7,7 ; [1] BTFSC FLAGS,BITIN ; [1.5] BSF CSR7,7 ; [0.5] ; SUB TOTAL = 16 CYCLES MOVF CNT0,W ; [1] CALIBRATION COUNTER MOVWF CNT2 ; [1] (NOMINALLY 75 FOR 300 us PULSE) MOVLW 3 ; [1] SEE CALCULATION BELOW SUBWF CNT2,1 ; [1] NOP ; [1] ; SUB TOTAL = 5 CYCLE ; TOTAL = 24 => 24/8 = 3 LOOP COUNTERS ;************************************************************************* ; TOTAL = 24 INSTRUCTIONS ; SUBTRACT 24/8 = 3 TO COMPESATE FOR UPDATEING CSR AND OTHER PROCESSING ; AFTER DATA SAMPLE IS TAKEN. ;************************************************************************* DL3 GOTO $+1 ; [2] WASTE TIME GOTO $+1 ; [2] WASTE TIME CLRWDT ; [1] RESET WATCHDOG TIMER DECFSZ CNT2,1 ; [1] GOTO DL3 ; [2] CNT0 X 8 us [ CNT0 X Te ] SAMPLE3 BTFSC RFIN ; [2] INPUT LOW? THIRD SAMPLE GOTO RMT0 ; [0] NO--RECEIVE ERROR CALL TST_RTCC ; [11] CHECK RTCC DECFSZ CNT1,1 ; [1] LAST BIT? GOTO RCV8 ; [2] ... NO, GET NEXT BIT GOTO RMT1 ; TOTAL = 14 CYCLES RMT_0 RMT0 RMT01 BSF STATUS,C ; INVALID TRANSMISSION RETLW 1 ; RETURN RMT1 BANK1 BCF TRISIO,5 ;VIRA SAIDA BANK0 BCF LED ; VALID TRANSMISSION FORMAT, LED ON MOVLW 0FH ; FORCE OPEN BUTTON CODES TO ZERO ANDWF SER_0,1 CLRC ; VALID SERIAL NUMBER => VALID TX RETLW .0 ; RETURN ;------------------------------------------------------------------------------ ; ; FUNCTION : M_LOOP () ; ; DESCRIPTION : MAIN PROGRAM ROUTINE ; ;------------------------------------------------------------------------------ M_LOOP MOVFW SITUAÇÃO XORLW 0X01 BTFSC STATUS,Z ;SE IGUAL A 1 GOTO T6K MOVFW SITUAÇÃO XORLW 0X03 BTFSS STATUS,Z ;SE IGUAL A 1 GOTO T7K BTFSC S1 GOTO T7K BCF M1 BCF M2 GOTO INCSIT T6K BTFSC S2 GOTO T7K BCF M1 BCF M2 INCSIT INCF SITUAÇÃO,F ;EVITA UM APERTO A MAIS QUANDO MOTOR PARA COM FIM DE CURSO ;ANDLW 0X03 ;MOVWF SITUAÇÃO T7K BANK1 BSF TRISIO,5 ;VIRA ENTRADA BANK0 BTFSS LRN ;TESTA BOTÃO 'LEARN' GOTO LEARN ; TEST & HANDLE LEARN BUTTON APERTADO CALL TST_RTCC ; UPDATE TIMER CALL TST_TIMER ; HANDLE TIMER - UPDATE OUTPUTS CALL RECEIVE ; RECEIVE TRANSMISSION BC M_LOOP ; CHECK IF TRANSMISSION VALID M_SEARCH CLRF TXNUM ; TEST FIRST POSITION ; ******* COMPARE LOWER WORD OF SERIAL NUMBER ******** M_SERIAL CALL TX_LOOKUP ; GET TX BASE ADDRESS INCF ADDRESS,F ; SOMA 2 INCF ADDRESS,F CALL EEREAD ; READ LOWER 16-BITS OF SER# FROM EEPROM MOVFW TMP1 ; COMPARE RX AND EEPROM VALUES XORWF SER_2,W BNZ M_NEXT ; IF NOT EQUAL CHECK NEXT MOVFW TMP2 ; COMPARE RX AND EEPROM VALUES XORWF SER_3,W BNZ M_NEXT ; IF NOT EQUAL CHECK NEXT ; ******* COMPARE UPPER WORD OF SERIAL NUMBER ******** M_SERIAL2 INCF ADDRESS,F ; POINT TO NEXT ENTRY CALL EEREAD ; READ UPPER 16-BITS OF SER# FROM EEPROM MOVFW TMP1 ; COMPARE RX AND EEPROM VALUES XORWF SER_0,W BNZ M_NEXT ; IF NOT EQUAL CHECK NEXT MOVFW TMP2 ; COMPARE RX AND EEPROM VALUES XORWF SER_1,W BNZ M_NEXT ; IF NOT EQUAL CHECK NEXT BTFSS FLAGS,LRNF ; LEARN MODE GOTO M_HOP ; FOUND TRANSMITTER - DECRYPT BSF FLAGS,RELEARN ; SET RELEARN FLAG GOTO LEARN_F ; FOUND TRANSMITTER - LEARN ; **** SEARCH NEXT POSITION FOR SERIAL NUMBER ***** M_NEXT INCF TXNUM,F ; POINT TO NEXT TRANSMITTER POSITION MOVLW MAX_USERS ; TEST FOR LAST POSITION SUBWF TXNUM,W BTFSS STATUS,C ; NOT FOUND IN MAP GOTO M_SERIAL ; TRY NEXT POSITION M_NF BTFSS FLAGS,LRNF ; LEARN MODE GOTO M_LOOP ; NO... INVALID SERIAL NUMBER GOTO LEARN_NF ; NEW TRANSMITTER - USE POINTER FOR LEARN ; ********** DECRYPT HOPCODE ********************* M_HOP CALL DECRYPT ; DECRYPT HOPCODE ; ********* TEST DICRIMINATION VALUE ************* M_DIS MOVFW SER_3 ; SERIAL NUBER LSB MUST BE EQUAL XORWF DISC,W ; TO DISCRIMINATION VALUE BNZ M_LOOP ; *************** CHECK COUNTERS VALID ************ BCF FLAGS,SEC_CNT ; CHECK FIRST COUNTER M_CNT CALL TX_LOOKUP ; POINT LOWER 16 BIT COUNTER BTFSC FLAGS,SEC_CNT ; IF SECOND COUNTER IS USED INCF ADDRESS,F ; INCREMENT ADDRESS CALL EEREAD ; READ LOWER 16 BIT COUNTER FROM EEPROM ; ************ CHECK COUNTER WINDOWS *********** M_SUB MOVFW TMP2 ; 16 BIT COUNTER SUBSTRACTION SUBWF CNTR_LW,W MOVWF TMP2 SKPC ; SKIP IF NO BORROW INCF TMP1,F ; ... ELSE INCR HI BYTE MOVFW TMP1 SUBWF CNTR_HI,W MOVWF TMP1 BCF TMP1,0 ; MAKE ACCEPTED WINDOW 512 M_CHECK0 MOVFW TMP1 ; TEST IF IN WINDOW ( UPPER BYTE ) BTFSC STATUS,Z GOTO M_CHECK2 ; GO AND CHECK LOWER BYTE BTFSC FLAGS,SEC_CNT ; IF SECOND COUNTER GOTO M_LOOP ; ERROR - GOTO MAIN LOOP BSF FLAGS,SEC_CNT ; SET FLAG FOR SECOND COUNTER CHECK GOTO M_CNT ; AND CHECK IT M_CHECK2 MOVFW TMP2 ; CHECK LOWER BYTE BZ M_TZERO ; IF REPEAT - RESET TIMEOUT COUNTER ;*************************************************************** ; ESCRITA NA EEPROM DOS CONTADORES ; ************ UPDATE EEPROM COUNTER *********** M_UPDATE CALL TX_LOOKUP ; GET CURRENT TX BASE ADDRESS CALL LOAD_CNT_VALS ; LOAD COUNTER VALUES CALL EEWRITE ; UPDATE FIRST COUNTER INCF ADDRESS,F CALL LOAD_CNT_VALS ; LOAD COUNTER VALUES CALL EEWRITE ; UPDATE SECOND COUNTER ; ******** UPDATE OUTPUT WITH CURRENT BUTTON CODE ******** M_OUTPUT MOVLW 0F0H ; MASK ONLY BUTTON CODES ANDWF FUNC,1 SWAPF FUNC,1 ; GET BUTTON CODE FROM FUNC BYTE ; BTFSC FUNC,0 ; CHANGE BUTTON TO S-OUTPUT FORMAT ; BSF FUNC,4 ; [ S2 S1 S0 S3 ] ; CLRC ; RRF FUNC,W MOVFW FUNC M_OUTPUT1 CLRWDT ; MOVWF GPIO ; UPDATE PORT WITH FUNCTION CODE (GPIO,1) XXXXXXXXXXXXXXXXXXXXXXXXX BTFSC FUNC,0 GOTO LIGJ BTFSC FUNC,1 GOTO LIGJ BTFSC FUNC,2 GOTO LIGJ BTFSS FUNC,3 GOTO M_END ;FALHA LIGJ INCF SITUAÇÃO,W ANDLW 0X03 ;LIMITA CONTAGEM A 0 - 3 MOVWF SITUAÇÃO XORLW 0X01 BTFSC STATUS,Z ;SE IGUAL A 1 GOTO VAL1 MOVFW SITUAÇÃO XORLW 0X03 BTFSC STATUS,Z ;SE IGUAL A 1 GOTO VAL3 BCF M1 ;DESLIGA TODAS AS SAIDAS BCF M2 GOTO M8 ; WAIT FOR NEXT TRANMISSION ; GOTO RESET ;PREVINE TRAVAMENTOS VAL1 BCF M2 ;LIGA M1 BSF M1 GOTO M8 VAL3 BCF M1 ;LIGA M2 BSF M2 M8 M_TZERO CLRF CNT_HI ; RESET RTCC CLOCK CLRF CNT_LW CLRF CNT_HIX CLRF CNT_LWX M_END BSF LED GOTO M_LOOP ; WAIT FOR NEXT TRANMISSION ;----------------------------------------------------------------- ;------------------------------------------------ INTERVALO CLRF CNT_LW CLRF CNT_HI X5 CLRWDT BTFSS RTCC,7 GOTO X5 BCF RTCC,7 ; CLEAR MSB OF RTCC INCF CNT_LW,F ; INCREASE 16 COUNTER SKPNZ ; INCREASE UPPER BYTE IF ZERO ( OVERFLOW ) INCF CNT_HI,F BTFSS CNT_LW,2 GOTO X5 RETURN ;------------------------------------------------------------------------------ ; ; FUNCTION : LEARN () ; ; DESCRIPTION : LEARN ROUTINE ; ;------------------------------------------------------------------------------ LEARN BSF FLRN ;FLAG DE LEARN ATIVADO CLRF CNT_LW ; RESET TIMER CLRF CNT_HI BANK1 BSF TRISIO,5 ;ENTRADA BANK0 LEARN1 ;BCF LED ; LED ON (O PROPRIO BOTÃO LIGARA) CALL TST_RTCC ; UPDATE TIMER BTFSC LRN ; TEST FOR BUTTON RELEASE GOTO LEARN2 ; ENTER LEARN MODE BTFSS CNT_HI,0 ; TEST FOR ERASE ALL GOTO LEARN1 ; LOOP BACK ; ******* EEPROM ERASE ALL ****************** BSF LED ;FORÇA APAGAMENTO DO LED MESMO COM INTERRUPTOR LIGADO ERASE_ALL BANK1 BCF TRISIO,5 ;VIRA SAIDA CALL TEMPOAP BANK1 BSF TRISIO,5 ;VIRA ENTRADA BANK0 CLRWDT ; CLEAR WATCHDOG TIMER BTFSS LRN ; WAIT FOR BUTTON RELEASE GOTO ERASE_ALL ; LOOP BACK CALL APAGAEEPROM GOTO RESET ; START OVER TEMPOAP MOVLW 0XFF MOVWF AUX8 DECFSZ AUX8,F GOTO $-1 RETURN LEARN2 ;BSF LED ; CLEAR LED DESNECESSARIO: APAGA PELO PROPRIO BOTÃO BSF FLAGS,LRNF ; SET LEARN FLAG LEARN3 CALL TST_RTCC ; UPDATE TIMER CALL TST_TIMER ; CHECK FOR LEARN TIMEOUT CALL RECEIVE ; RECEIVE TRANSMISSION BC LEARN3 ; CHECK IF TRANSMISSION VALID GOTO M_SEARCH ; CHECK IF SERIAL NUMBER IS IN MAP LEARN_NF ; *** IF SERIAL NOT IN MAP READ SELFLEARN POINTER *** MOVLW LRNPTR ; POINT TO LEARN POINTER MOVWF ADDRESS CALL EEREAD ; READ LEARN POINTER FROM EEPROM MOVF TMP2,W ; CHECK LOWER BYTE MOVLW 0H ; LOAD 0 DEFAULT BTFSC STATUS,Z ; IF LOWER != 0 LEARN ON 0 MOVF TMP1,W ; ELSE LEARN ON TMP1 VALUE MOVWF TXNUM ; LOAD TXNUM LEARN_F CALL TX_LOOKUP INCF ADDRESS,F ;SOMA 2 INCF ADDRESS,F MOVFW SER_2 ; GET LOWER 16 BIT OF SERIAL NUMBER MOVWF TMP1 MOVFW SER_3 MOVWF TMP2 CALL EEWRITE ; ... AND WRITE TO EEPROM INCF ADDRESS,F ;TESTE SOMA 2 MOVFW SER_0 ; GET UPPER 16 BIT OF SERIAL NUMBER MOVWF TMP1 MOVFW SER_1 MOVWF TMP2 CALL EEWRITE ; ... AND WRITE TO EEPROM ; *** DECRYPT HOP CODE *** LEARN_DEC CALL DECRYPT ; DECRYPTION ROUTINE ; *** CHECK DISCRIMINATION VALUE *** LEARN_CHK MOVFW SER_3 ; CHECK LOWER BYTE OF SERIAL NUMBER XORWF DISC,W ; AGAINST DISCRIMINATION VALUE BZ LEARN_UP ; UPDATE LEARN POINTER GOTO CANCEL_LEARN ; ERROR CANCEL LEARN MODE ; ********* UPDATE LEARN POINTER ********** LEARN_UP CALL TX_LOOKUP ; GET CURRENT TX BASE ADDRESS CALL LOAD_CNT_VALS CALL EEWRITE ; WRITE LSB WORD OF COUNTER TO EEPROM BTFSC FLAGS,RELEARN ; IF RELEARN GOTO BYPASS_POINTER_WRITE ; DONT UPDATE POINTER INCF TXNUM,F ; INCREMENT LEARN POINTER MOVLW MAX_USERS ; ALLOW 0 .. MAX_USERS - 1 SUBWF TXNUM,W MOVLW 0H ; IF MAX WRAP TO 0 BTFSS STATUS,C MOVF TXNUM,W ; ELSE USE TXNUM MOVWF TMP1 ; FOR WRITE OPERATION CLRF TMP2 ; CLEAR LOWER BYTE MOVLW LRNPTR ; POINT TO LEARN POINTER MOVWF ADDRESS CALL EEWRITE ; UPDATE LEARN POINTER IN EEPROM BYPASS_POINTER_WRITE BCF LED ; LED ON TO INDICATE VALID LEARN BANK1 BCF TRISIO,5 ;SAIDA BANK0 CLRF CNT_LW ; CLEAR COUNTER LOW BYTE SUCCESS CALL TST_RTCC ; INDICATE SUCCESSFUL LEARN BTFSS CNT_LW,4 ; LED ON FOR 0.5 SEC GOTO SUCCESS ; LOOP BACK CANCEL_LEARN BCF FLAGS,LRNF ; CLEAR LEARN FLAG BCF FLAGS,RELEARN ; CLEAR RELEARN FLAG BSF LED ;APAGA LED BANK1 BSF TRISIO,5 ;ENTRADA BANK0 BCF FLRN ;DESLIGA FLAG MODO APRENDIZADO GOTO M_LOOP ; RETURN TO MAIN LOOP - LED OFF ;------------------------------------------------ FILTRO ; FILTRO PARA EVITAR DISPAROS ESPURIOS NA PORTA MOVLW 0XFF MOVWF FILTRO1 MOVLW TF2 MOVWF FILTRO2 DECFSZ FILTRO1,F GOTO $-1 DECFSZ FILTRO2,F GOTO $-3 RETURN END