;------

; MICROCHIP KEELOQ CODE HOPPING SIMPLE DECODER

;

;------

;------

; LEGAL NOTICE

;

; The information contained in this document is proprietary and

; confidential information of Microchip Technology Inc. Therefore all

; parties are required to sign a non-disclosure agreement before

; receiving this document.

;

; The information contained in this Application Note is for suggestion

; only. It is your responsibility to ensure that your application meets

; with your specifications. No representation or warranty is given and

; no liability is assumed by Microchip Technology Incorporated with

; respect to the accuracy or use of such information or infringement of

; patents or other intellectual property arising from such use or

; otherwise.

;------

;------

; SIMPLE DECODER WITH ONE STEP LEARN AND SINGLE KEY

;------

;

;PROGRAM INFORMATION: FILE: SIMDEC11.ASM

; DATE: 8 SEPTEMBER 1998

; VER.: 1.1

; CKSM: XXXXH - FUSES:RC,WDT=ON,CP=ON

; ASM.: MPASM VERSION 2.13 USED

; INCL: NONE

; TABS: 8

;------

; CONFIGURATION CONTROL:

;

; -VERSION 1.1 S. DAWSON

;

; FILE: SIMDEC11.ASM.

; DATE: 8 SEPTEMBER 1998

; VER.: 1.1

; FUSES: RC,WDT=ON,CP=ON.

; ASM.: MPASM VERSION 2.13 USED.

; INCL: NONE

;

; CHANGES:

; 1. CODE HAS BECOME A RESERVED WORD IN MPASM - CHANGED IT TO DISC

; 2. ADDED DISCLAIMER

;

;

; DATE VERSION LINE CHANGES

; 08/14/96 1.0 FIRST VERSION

;------

LIST P=16C54,R=DEC

;------

;******USER DEFINITIONS******

MAX_USERS EQU 15

; This is the maximum number of transmitters that the system is able to

; learn (1 to 15).

;------

; 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

; USER DEFINED REGISTER

FLAGS EQU 07H ; USER FLAG REGISTER

ADDRESS EQU 08H ; ADDRESS REGISTER

TXNUM EQU 09H ; CURRENT TX

OUTBYT EQU 0AH ; GENERAL DATA REGISTER

MASK EQU OUTBYT ; MASK REGISTER USED IN DECRYPTION

TMP_CNT EQU OUTBYT ; TEMPORARY COUNTER

; COUNTER REGISTERS

CNT0 EQU 0BH ; LOOP COUNTERS

CNT1 EQU 0CH

CNT2 EQU 0DH

CNT_HI EQU 0EH ; 16 BIT CLOCK COUNTER

CNT_LW EQU 0FH

; CIRCULAR BUFFER REGISTER

CSR0 EQU 10H ; 64 BIT RECEIVE SHIFT REGISTER

CSR1 EQU 11H

CSR2 EQU 12H

CSR3 EQU 13H

CSR4 EQU 14H

CSR5 EQU 15H

CSR6 EQU 16H

CSR7 EQU 17H

; TEMP REGISTERS

TMP1 EQU 18H ; TEMP REGISTER FOR READ AND WRITE

TMP2 EQU 19H ; TEMP REGISTER FOR READ AND WRITE

REG EQU 1AH ; NOT USED

REG1 EQU 1BH ; NOT USED

KEY0 EQU 1CH ; 64 BIT KEY SHIFT REGISTER

KEY1 EQU 1DH

KEY2 EQU 1EH

KEY3 EQU 1FH

KEY4 EQU CNT2

KEY5 EQU CSR5

KEY6 EQU CSR6

KEY7 EQU CSR7

; ***** 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 01H ; LEARN POINTER

; ********* PORTA BIT DEFINITIONS *******

RES0 EQU 0H ; RESERVED PIN

RFIN EQU 1H ; RF INPUT

LRN EQU 2H ; LEARN BUTTON

LED EQU 3H ; LEARN INDICATOR LED OUTPUT - VALID SIGNAL

; ********* PORTB BIT DEFINITIONS *******

S0 EQU 0H ; S0 OUTPUT

S1 EQU 1H ; S1 OUTPUT

S2 EQU 2H ; S2 OUTPUT

S3 EQU 3H ; S3 OUTPUT

DIO EQU 4H ; EEPROM DATA LINE

CLK EQU 5H ; EEPROM SERIAL CLOCK

CS EQU 6H ; EEPROM CHIP SELECT

RES1 EQU 7H ; RESERVED PIN

; ********* COMPILER DEFINES ******************

NBITS EQU 64 ; MAXIMUM TRANSMISSION BIT LENGTH

MIN EQU 560 ; TRANSMISSION HEADER MINIMUM LENGTH [鍿]

TRISA EQU 0111B ; PORTA: TRI-STATE VALUE

WRCFG EQU 00000000B ; PORTB: EEPROM WRITE TRI-STATE VALUE

RDCFG EQU 00010000B ; PORTB: EEPROM READ TRI-STATE VALUE

;****** 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

;------

; PAGE 0:

;------

ORG 00H

;------

;

; FUNCTION : RESET ()

;

; DESCRIPTION : PROGRAM RESET ROUTINE

;

;------

RESET

MOVLW 000111B ; SETUP RTCC PRESCALER

OPTION

CLRF PORTA ; RESET PORTA

CLRF PORTB ; RESET PORTB

MOVLW TRISA ; SETUP PORTA

TRIS PORTA

MOVLW WRCFG ; SETUP PORTB

TRIS PORTB

CLRF FLAGS ; RESET FLAGS

GOTO M_LOOP ; GOTO MAIN PROGRAM LOOP

;------

;

; FUNCTION : ROT_SHIFT()

;

; DESCRIPTION : RIGHT ROTATE 64 BIT RECEIVE SHIFT REGISTER

;

; NOTE : THIS ROUTINE MUST BE IN THE LOWER HALF OF THE PAGE

;

;------

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

;

; NOTE : THIS ROUTINE MUST BE IN THE LOWER HALF OF THE PAGE

;

;------

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

MOVLW 04H ; AND ADD 4

ADDWF ADDRESS,F

RETLW 0 ; RETURN

;------

;

; FUNCTION : TST_RTCC ()

;

; DESCRIPTION : UPDATE RTCC COUNTER

;

; NOTE : THIS ROUTINE MUST BE IN THE LOWER HALF OF THE PAGE

;

;------

TST_RTCC

CLRWDT ; RESET WATCHDOG TIMER

MOVLW TRISA ; UPDATE TRI-STATE REGISTER FOR PORTA

TRIS PORTA

BTFSS RTCC,7 ; TEST FOR 32MS TIMEOUT ON RTCC MSB

RETLW 0 ; ... DO QUICK RETURN TO RECEIVE ROUTINE

; **** INCREASE 16 BIT CLOCK TIMER *******

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

RETLW 0

;------

;

; FUNCTION : TST_TIMER()

;

; DESCRIPTION : TEST 32MS TIMER AND UPDATE OUTPUTS IF REQUIRED

;

; NOTE : THIS ROUTINE MUST BE IN THE LOWER HALF OF THE PAGE

;

;------

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

; ********* TEST FOR 30 S LEARN TIMEOUT *************

TST_30 BTFSS FLAGS,LRNF

GOTO TST_END

BTFSC CNT_HI,2 ; TEST FOR LEARN TIMEOUT

GOTO RESET ; ... IF LEARN TIMEMOUT FORCE SOFT RESET

TST_END

RETLW 0H

;------

;

; FUNCTION : SENDC ()

;

; DESCRIPTION : SEND EEPROM COMMAND

;

; NOTE : THIS ROUTINE MUST BE IN THE LOWER HALF OF THE PAGE

;

;------

SENDC

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,F ; 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,F ; LOOP COUNTER

GOTO SENDC2

BCF PORTB,DIO ; AVOID CONTENTION WITH READ

RETLW 0

;------

;

; FUNCTION : EEWRITE ()

;

; DESCRIPTION : WRITE 16 BIT VALUE TO EEPROM

;

; NOTE : THIS ROUTINE MUST BE IN THE LOWER HALF OF THE PAGE

;

;------

EEWRITE

; ******* EEPROM WRITE ENABLE ******************

WRITE0 MOVLW 30H ; WRITE ENABLE COMMAND

MOVWF OUTBYT

CALL SENDC ; SEND COMMAND TO EEPROM

BCF PORTB,CS ; END COMMAND, DESELECT

; ******** WRITE 16-BIT WORD TO EEPROM *********

WRITE1 MOVFW ADDRESS ; GET EEPROM ADDRESS

MOVWF OUTBYT

BSF OUTBYT,6 ; WRITE COMMAND

CALL SENDC ; SEND COMMAND TO EEPROM

MOVLW 16D ; 16 DATA BITS

MOVWF CNT1

WRITE2

BTFSS TMP1,7 ; TEST MSB OF 16 BIT WORD

BCF PORTB,DIO ; SET DATA BIT

BTFSC TMP1,7 ; ... ELSE

BSF PORTB,DIO ; CLEAR DATA BIT

GOTO $+1 ; WAIT 2 US

RLF TMP2,F ; SHIFT LO BYTE

BSF PORTB,CLK ; CLOCK HIGH

GOTO $+1 ; WAIT 2 US

RLF TMP1,F ; SHIFT HI BYTE

BCF PORTB,CLK ; CLOCK LOW

DECFSZ CNT1,F

GOTO WRITE2 ; LOOP COUNTER

WAITACK

BCF PORTB,CS ; END OF WRITE COMMAND, DESELECT

MOVLW RDCFG

TRIS PORTB ; DIO = INPUT

BSF PORTB,CS ; CS HIGH TO WAIT FOR ACK

WRITE5

BTFSC PORTB,DIO ; CHECK FOR ACK

GOTO WRITE6 ; WDT RESET ON NO ACK

GOTO WRITE5

WRITE6 BCF PORTB,CS ; END OF ACK

; ******* EEPROM WRITE DISABLE ****************

MOVLW 000H ; WRITE DISABLE COMMAND

MOVWF OUTBYT

CALL SENDC

BCF PORTB,CS ; END OF DISABLE COMMAND, DESELECT

INCF ADDRESS,F ; POINT TO NEXT EEPROM ADDRESS ( BY DEFAULT )

RETLW 0H

;------

;

; FUNCTION : EEREAD ()

;

; DESCRIPTION : READ 16 BIT VALUE FROM EEPROM

;

; NOTE : THIS ROUTINE MUST BE IN THE LOWER HALF OF THE PAGE

;

;------

EEREAD

MOVFW ADDRESS

MOVWF OUTBYT

BSF OUTBYT,7 ; COMMAND = READ

CALL SENDC ; SEND COMMAND

MOVLW RDCFG

TRIS PORTB ; DIO = INPUT

MOVLW 16D ; 16 BITS TO READ

MOVWF CNT1

READ0 BSF PORTB,CLK ; CLOCK HIGH

RLF TMP2,F ; SHIFT LO BYTE

BCF TMP2,0 ; ASSUME BIT WILL BE 1

BTFSC PORTB,DIO ; READ DIO LINE

BSF TMP2,0 ; COPY BIT TO REGISTER

BCF PORTB,CLK ; CLOCK LOW

RLF TMP1,F ; SHIFT HI BYTE

DECFSZ CNT1,F ; LOOP COUNTER

GOTO READ0

BCF PORTB,CS ; END READ CYCLE

RETLW 0H

;------

;

; FUNCTION : DECRYPT ()

;

; DESCRIPTION : DECRYPTS 32 BIT [HOP1:HOP4] USING [CSR0:CSR7]

;

; NOTE : THIS ROUTINE MUST BE IN THE LOWER HALF OF THE PAGE

;

;------

; THE KEY USED IS A FIXED KEY WHICH IS NOT SERIAL NUMBER DEPENDANT

; THE USER MUST CHOOSE A KEY AND CHANGE THE CODE HERE TO REFLECT THAT KEY

DECRYPT

MOVLW 0EFH ; LOAD FIXED 64 BIT KEY LSB

MOVWF KEY0

MOVLW 0CDH

MOVWF KEY1

MOVLW 0ABH

MOVWF KEY2

MOVLW 089H

MOVWF KEY3

MOVLW 067H

MOVWF KEY4

MOVLW 045H

MOVWF KEY5

MOVLW 023H

MOVWF KEY6

MOVLW 01H ; LOAD FIXED 64 BIT KEY MSB

MOVWF KEY7

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,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

ADDWF PC,F ; 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