📄 hcs301_pro.asm
字号:
EE_KEY EQU $ ; EEPROM KEY BASE ADDRESS
RETLW 088H ; EKEY_0 LSB
RETLW 077H ; EKEY_1
RETLW 066H ; EKEY_2
RETLW 055H ; EKEY_3
RETLW 044H ; EKEY_4
RETLW 033H ; EKEY_5
RETLW 022H ; EKEY_6
RETLW 011H ; EKEY_7 MSB
;-------------------------------------------------------------------------
;
; FUNCTION : TST_RTCC ()
;
; DESCRIPTION : TEST TIMER0 COUNTER AND UPDATE OUTPUT IF REQUIRED
;
; PAGE : 0
;
;-------------------------------------------------------------------------
TST_RTCC
CLRWDT ; RESET WATCHDOG TIMER
MOVFW STATUS
XORWF TIMER0,W
ANDLW 080H
BTFSS STATUS,Z
GOTO TST_RTCC_2 ; TEST FOR 32MS TIMEOUT
RETLW 0H ; QUICK RETURN TO RECEIVE ROUTINE
; **** INCREASE 16 BIT CLOCK TIMER *******
TST_RTCC_2
BCF STATUS,OVF
MOVFW TIMER0
ANDLW 080H
IORWF STATUS
INCF CNT_LW ; INCREASE 16 COUNTER
BTFSC STATUS,Z ; INCR MS BYTE IF ZERO (OVERFLOW)
INCF CNT_HI
MOVLW TRISA ; UPDATE TRIS REGISTER FOR PORTA
TRIS PORTA
MOVLW RDCFG ; UPDATE TRIS REGISTER FOR PORTB
TRIS PORTB
BTFSS TIMER0,7 ; TEST FOR 32MS TIMEOUT
RETLW 0H ; QUICK RETURN TO RECEIVE ROUTINE
; *********** UPDATE LED IF REQUIRED ********
TST_LED
MOVLW PASS1 ; TEST IF IN 1ST PASS OF SELFLEARN
XORWF SREG,W
SKPZ ; ... IF NOT BYPASS
GOTO TST_500
BSF PORTA,LED ; INDICATE 1ST VALID TX RECEIVED
; ***** TEST FOR 500 MS TIMEMOUT ON OUTPUTS **********
TST_500
BTFSS CNT_LW,4 ; TEST FOR 500 MS TIMEOUT
GOTO TST_30 ; ... IF NOT TEST 30S TIMEOUT
BCF FLAGS,OUT_500 ; RESET 500 MS OUTPUT INICATION
BCF PORTB,B_LRN ; RESET LEARN BUTTON CODE
MOVLW 0F0H
ANDWF PORTB,1 ; DOWN ALL PULSE OUTPUTS
CLRF OLD_BUT
; ********* TEST FOR 30 S LEARN TIMEOUT *************
TST_30
MOVLW NORMAL ; TIMEOUT USE ONLY WITH LEARN
XORWF SREG,W
SKPNZ
GOTO TST_END ; ... IF NOT RETURN
BTFSC CNT_HI,2 ; TEST FOR LEARN TIMEOUT
GOTO RESET ; IF TIMEMOUT FORCE SOFT RESET
TST_END
RETLW 0H
;-------------------------------------------------------------------------
;
; FUNCTION : DECRYPT ()
;
; DESCRIPTION : DECRYPTS 32 BIT [HOP1:HOP4] USING [CSR0:CSR7]
;
; PAGE : 0 ( NOTE : MUST BE LOWER HALF OF PAGE )
;
;-------------------------------------------------------------------------
DECRYPT
MOVLW 11+1 ; 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 10000B ; 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
RLF MASK
BTFSC HOP1,0 ; SHIFT MASK ANOTHER 1X IF BIT 0 SET
RLF MASK
; 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
ADDWF PC ; ADD THE INDEX TO THE PROGRAM COUNTER
; [ MUST BE IN LOWER HALF OF PAGE ]
TABLE
MOVLW 02EH ; BITS 4:3 WERE 00
GOTO TABLE_END ; END OF LOOKUP
MOVLW 074H ; BITS 4:3 WERE 01
GOTO TABLE_END ; END OF LOOKUP
MOVLW 05CH ; BITS 4:3 WERE 10
GOTO TABLE_END ; END OF LOOKUP
MOVLW 03AH ; BITS 4:3 WERE 11
TABLE_END
ANDWF MASK ; ISOLATE THE CORRECT BIT
MOVLW 0 ; COPY THE BIT TO BIT 7
SKPZ ; COPY THE BIT TO BIT 7
MOVLW 10000000B ; 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 ; LEFT ROTATE MASK TO GET BIT 7 INTO
CARRY
RLF HOP1 ; SHIFT IN THE NEW BIT
RLF HOP2
RLF HOP3
RLF HOP4
ROTATE_KEY
CLRC ; CLEAR CARRY
BTFSC KEY7,7 ; SET CARRY IF LEFTMOST BIT SET
SETC ; SET CARRY IF LEFTMOST BIT SET
RLF KEY0 ; LEFT-ROTATE THE 64-BIT KEY
RLF KEY1
RLF KEY2
RLF KEY3
RLF KEY4
RLF KEY5
RLF KEY6
RLF KEY7
DECFSZ CNT0 ; INNER LOOP 48 TIMES
GOTO DECRYPT_INNER ; INNER LOOP 48 TIMES
DECFSZ CNT1 ; 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 : RECEIVE ()
;
; DESCRIPTION : RECEIVE ROUTINE FOR NTQ106/HCS TRANSMITTERS
;
; PAGE : 0
;
;-------------------------------------------------------------------------
RECEIVE
;******** WAIT FOR HEADER AND CALIBRATE *******************
BCF FLAGS,NTQ106 ; RESET NTQ106 TRANSMISSION FLAG
BTFSS PORTA,RFIN ; INPUT LOW?
GOTO RMT_0 ; YES; RECEIVE ERROR
MOVLW 10 ; 10 ms TIMER
MOVWF CNT1
RCV0
MOVLW 200
MOVWF CNT0
RCV1
BTFSS PORTA,RFIN ; INPUT HIGH?
GOTO RCV2 ; NO, JUMP OUT OF LOOP
DECFSZ CNT0 ; YES, CONTINUE WITH TIMING LOOP
GOTO RCV1 ; 5 us X CNT0
DECFSZ CNT1 ; DO 1 ms LOOP CNT1 TIMES
GOTO RCV0
RCV2
CLRF CNT0 ; CLEAR CALIB COUNTER LOW BYTE
CLRF CNT1 ; CLEAR CALIB COUNTER HIGH BYTE
RCV3
BTFSC PORTA,RFIN ; [2][2] INPUT HIGH?
GOTO RCV6 ; [0][0] YES--END CALIBRATION
MOVLW (MAX+2559)/10/256 ; [1][1] LOAD W WITH TIMEOUT VALUE
INCF CNT0 ; [1][1] LOW BYTE OF COUNTER
BTFSS STATUS,Z ; [1][2] OVERFLOW IN LOW BYTE?
GOTO RCV5 ; [2][0] NO-DON'T UPDATE HIGH BYTE
RCV4
INCF CNT1 ; [0][1] YES--INCREMENT HIGH BYTE
SUBWF CNT1,W ; [0][1] COUNTER > MAX.?
BTFSC STATUS,C ; [0][2] COUNTER > MAX.?
GOTO RMT_0 ; [0][0] YES--HEADER TOO LONG
RCV5
CLRWDT ; [1][1]
GOTO RCV3 ; [2][2] LOOP BACK
; TOTAL 10/13us (WTH/WTHOUT CARRY)
RCV6
CLRC
RRF CNT1
RRF CNT0
RRF CNT1
RRF CNT0
RRF CNT1
RRF CNT0 ; TOTAL: 7 us
; DIVIDE CNT1:CNT0 BY 8 (600/8=75)
MOVLW MIN/80
SUBWF CNT0,W
BTFSS STATUS,C ; NEGATIVE?
GOTO RMT_0 ; YES--HEADER SHORTER THAN MIN.
; ************* VALID HEADER RECEIVED *********************
RCV7
MOVLW NBITS ; VALID START MARKER WAS RECEIVED
MOVWF CNT1
MOVF CNT0,W
MOVWF CNT2 ; CNT2 = CNT0
MOVLW 5
SUBWF CNT2,1
GOTO DL1 ; COMPENSATE FOR FIRST BIT
;*************** WAIT FOR NEXT BIT ************************
; First timeout--to prevent HCS preamble being
; seen as data when the decoder calibrates on the
; HCS Guard Time.
; Normal mode data arrives at 0.5 Te
; Preamble pulses arrive at 1.5 Te
; Timeout = 1 Te
;
; Second Timeout--To check for HCS360 narrow mode
; Timeout = 1.5 Te (middle of preamble if not narrow mode)
;
; Third Timeout--Wait for narrow mode bit
; Bit arrives after 1 Te
; Timeout must be 1.5 Te for maximum value of Te, which
; can't be done with a 5 cycle loop and 8 bit counter.
; Thus make timeout = 255x5 = 1275 = 1.18 Te(max)
;**********************************************************
RCV8 ; Timeout = 1BPW
MOVLW 1H ; Compensate for RTCC
SUBWF CNT0,0 ; and CSR processing
MOVWF CNT2
RCV9
BTFSC PORTA,RFIN ; (2) Wait for Next rising edge
GOTO RCV11 ; (0) If rising edge found, sample
GOTO $+1 ; (2) Delay 2 cycles
CLRWDT ; (1) Clear watchdog Timer
DECFSZ CNT2 ; (1) Decrement Timeout Value
GOTO RCV9 ; (2) Loop Back
RCV9A
RLF CNT0,W
MOVWF CNT2 ; 6xCNT0x2 = 3/2(CNT2x8) = 1.5 Te
RCV10
BTFSC PORTA,RFIN ; (2) Check if clear - Data
GOTO RMT01 ; (0) If high - Preamble
CLRWDT ; (1) Clear watchdog Timer
DECFSZ CNT2,1 ; (1) Decrement Timeout Counter
GOTO RCV10 ; (2) Loop back
MOVLW 0FFH ; Timeout = 1.18 Te(max)
MOVWF CNT2 ; Refer to explanation above
RCV10A
BTFSC PORTA,RFIN ; (2) Wait for rising edge
GOTO RCV11 ; (0) Edge found--Process
DECFSZ CNT2,1 ; (1) Decrement Timeout counter
GOTO RCV10A ; (2) Loop Back
GOTO RMT01 ; (0) (5) TIMEOUT--no edge found
RCV11
MOVF CNT0,W ; CALIBRATION COUNTER
MOVWF CNT2 ; (NOMINALLY 75 FOR 300 us PULSE)
DECF CNT2
DECF CNT2
GOTO $+1
DL1
CLRWDT ; RESET WATCHDOG TIMER
DECFSZ CNT2 ;
GOTO DL1 ; CNT0 X 4 us
BTFSS PORTA,RFIN ; INPUT HIGH? FIRST SAMPLE
GOTO RMT01 ; NO--ERROR
MOVF CNT0,W ; CALIBRATION COUNTER
MOVWF CNT2 ; (NOMINALLY 75 FOR 300 us PULSE)
DECF CNT2
CLRC ; OPTIONAL--LITTLE DIFFERENCE
RLF CNT2 ; MULTIPLY BY 2 FOR 600 us
GOTO $+1
DL2
CLRWDT ; RESET WATCHDOG TIMER
DECFSZ CNT2
GOTO DL2 ; CNT0 X 4 us
BCF FLAGS,BITIN ; CLEAR BIT POSITION
BTFSS PORTA,RFIN ; LEAVE 0 IF LINE HIGH
BSF FLAGS,BITIN ; MAKE 1 IF LINE LOW
MOVF CNT0,W ; CALIBRATION COUNTER
MOVWF CNT2 ; (NOMINALLY 75 FOR 300 us PULSE)
CLRC ; OPTIONAL--LITTLE DIFFERENCE
RLF CNT2 ; MULTIPLY BY 2 FOR 600 us
MOVLW 5 ; [1]
SUBWF CNT2 ; [1]
BCF STATUS,C ; [1]
CALL ROT_SHIFT ; [10]+[2] CSR SHIFT + CALL
BTFSC FLAGS,BITIN ; [1]
BSF CSR7,7 ; [1]
DL3
CLRWDT ; RESET WATCHDOG TIMER
DECFSZ CNT2 ;
GOTO DL3 ; CNT0 X 4 us
BTFSC PORTA,RFIN ; INPUT LOW? THIRD SAMPLE
GOTO RMT0 ; NO--RECEIVE ERROR
CALL TST_RTCC ; CHECK RTCC
DECFSZ CNT1 ; LAST BIT?
GOTO RCV8 ; NO--GET NEXT BIT
GOTO RMT1
RMT_0
BSF CNT1,4 ; HEADER ERROR--FORCE COUNTER > 8
RMT0 ; HERE IF FAIL ON 3RD SAMPLE
DECF CNT1,1 ; COMPENSATE FOR ROTATE BEFORE DL3
RMT01 ; HERE IF FAIL ON 1ST SAMPLE
CALL TST_RTCC ; CHECK RTCC
MOVLW 9H ; TEST FOR NTQ106 TRANSMISSION
SUBWF CNT1,W ; IF CARRY FLAG SET (RX NOT OK)
BTFSC STATUS,C
RETLW 0 ; HERE IF NOT ALL BITS RECEIVED OK
RMT2
CALL ROT_SHIFT ; COMPLETE 64-BIT SHIFT
DECFSZ CNT1 ; COMPLETE 64-BIT SHIFT
GOTO RMT2
CLRF SER_0 ; CLEAR UPPER BYTE OF SERIAL NR
BSF FLAGS,NTQ106 ; INDICATE NTQ106 TX RECEIVED
RMT1
CLRC ; CLEAR CARRY FLAG [ RECEIVE OK ]
MOVFW SREG
XORLW PASS2
SKPNZ ; DON'T CLR TXNUM CONTAINS LRN POS
RETLW 0
BTFSS FLAGS,OUT_500 ; TEST IF 500 MS TIMEOUT
BSF PORTA,LED ; ... IF SO SET LED ON
CLRC
RETLW 0 ; RETURN WITH 1
;-------------------------------------------------------------------------
;
; FUNCTION : TST_LEARN ()
;
; DESCRIPTION : TEST AND HANDLE LEARN BUTTON
;
; PAGE : 0
;
;-------------------------------------------------------------------------
TST_LEARN1
CLRWDT ; RESET WATCHDOG TIMER
BTFSC PORTA,LEARN ; CHECK FOR LEARN BUTTON PRESSED
RETLW 0 ; ... IF NOT RETURN
CLRF CNT_HI ; RESET EVENT COUNTER
CLRF CNT_LW
TST_LEARN2
CALL TST_RTCC ; CALL RTCC UPDATE ROUTINE
BTFSS CNT_HI,0 ; TEST FOR ERASE TIMEMOUT,8.2 SEC
GOTO TST_LEARN3 ; IF NOT WAIT FOR LEARN KEY LIFT
MOVLW PASS1 ; INDICATE FIRST STATE OF LEARN
MOVWF SREG
BSF STATUS,PA0 ; SELECT PAGE #1
GOTO NTQ_ERASE ; ERASE ALL LEARNED TRANSMITTERS
TST_LEARN3
BSF PORTA,LED ; LED ON TO INDICATE LEARN
BTFSS PORTA,LEARN ; WAIT FOR LEARN BUTTON LIFT
GOTO TST_LEARN2 ; ... IF NOT CHECK TIMER
MOVLW 2H ; TEST IF LEARN PRESS > THAN 64 MS
SUBWF CNT_LW,W
SKPC
RETLW 0 ; ... IF NOT ABORT LEARN
MOVLW PASS1 ; INDICATE FIRST STATE OF LEARN
MOVWF SREG
RETLW 0H
;-------------------------------------------------------------------------
;
; FUNCTION : SENDC ()
;
; DESCRIPTION : SEND EEPROM COMMAND
;
; PAGE : 0
;
;-------------------------------------------------------------------------
SENDC1
CLRWDT ; RESET WATCHDOG TIMER
BCF PORTB,CS ; RESET CS STATE
BCF PORTB,CLK ; RESET CLK STATE
BCF PORTB,DIO ; RESET DIO STATE
MOVLW WRCFG
TRIS PORTB ; DIO = OUTPUT
GOTO $+1 ; WAIT FOR OUTPUTS TO SETTLE
BSF PORTB,CS ; SELECT EEPROM
SETC ; START BIT = 1
MOVLW 9D ; START BIT + 8 DATA BITS
MOVWF CNT1
SENDC2
SKPC ; TEST BIT
BCF PORTB,DIO ; WRITE TO DIO
SKPNC ; TEST BIT
BSF PORTB,DIO ; WRITE TO DIO
GOTO $+1 ; WAIT 2 US
RLF OUTBYT ; GET NEXT BIT INTO CARRY
BSF PORTB,CLK ; CLOCK HIGH
GOTO $+1 ; WAIT 2 US
GOTO $+1 ; WAIT 2 US
BCF PORTB,CLK ; CLOCK LOW
DECFSZ CNT1 ; LOOP COUNTER
GOTO SENDC2
BCF PORTB,DIO ; AVOID CONTENTION WITH READ
RETLW 0
;-------------------------------------------------------------------------
;
; FUNCTION : EEWRITE ()
;
; DESCRIPTION : ENCRYPT AND WRITE 16 BIT VALUE TO EEPROM
;
; PAGE : 0
;
;-------------------------------------------------------------------------
EEWRITE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -