;разьем платы: ;1- +12V, 2- GND ;3- INP1,GP3 no_use ;3к MCLR на +5V ;4- IO2, GP0 (OUT) HCS Vdd line ;5- IO3, GP1 (IN/OUT) Data (PWM) for Programming HCS ;6- IO4, GP2 (OUT) Clock (S2) for Programming HCS ;7- IO5, GP4 (OUT) Program/failure led indicator (активный "1") ;8- IO6, GP5 (IN) Programming Key (подтяжка на плюс) ;=========================================================================== ; MICROCHIP KEELOQ HCS200 - HCS300 - HCS301 STANDALONE PROGRAMMER ;=========================================================================== ; THIS STANDALONE PROGRAMMER APPLY THE NORMAL LEARN SCHEME TO GENERATE THE ; ENCRYPTION KEY STARTING FROM THE MANUFACTURER CODE AND THE SERIAL NUMBER. ; THE SERIAL NUMBER IS INCREMENTED EVERY TIME A HCS PROGRAMMING HAPPEN ; AND IS STORED IN THE INTERNAL DATA EEPROM OF THE PIC16F84A ; ; THE HCS MANUFACTURER CODE AND THE CONFIGURATION WORD CAN BE CHANGED ; IN THE SECTION BELOW NAMED "MODIFYABLE PROGRAMMING DEFINE" LIST P=PIC16F876A INCLUDE P16F876A.INC __FUSES _CP_ALL & _DEBUG_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC & _LVP_OFF __idlocs 0X0000 ;"" ;********************************************************** ;Карта eeprom: org 0x2100 ManufCode equ $-0x2100 ;мануфактурный код: 0123456789ABCDEF de 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01 SerialNumber equ $-0x2100 ;серийный номер, инкрементируется при каждой записи чипа de 0x01, 0x00, 0x00, 0x00 ;********************************************************** ;======================================================================================== ; MACROS #DEFINE BANK0 bcf STATUS,RP0 #DEFINE BANK1 bsf STATUS,RP0 ;======================================================================================== ;======================================================================================== ; GENERAL PURPOSE RAM REGISTERS CBLOCK 0X20 ; Word clocked into HCS WRD_HI, WRD_LO ; Words to be programmed into HCS (HCS MEMORY MAPPING) WORD0:2, WORD1:2, WORD2:2, WORD3:2 WORD4:2, WORD5:2, WORD6:2, WORD7:2 WORD8:2, WORD9:2, WORD10:2, WORD11:2 ; Other Variable for programming HCS TXNUM ; Number of bit clocked TMP_CNT ; Temporary Counter COUNT_HI, COUNT_LO ; Counter for Timing ; Generated Encryption KEY KEY7, KEY6, KEY5, KEY4 KEY3, KEY2, KEY1, KEY0 ; Circular Buffer used in decryption routine CSR4, CSR5, CSR6, CSR7 CSR0, CSR1, CSR2, CSR3 ; Counter used in decryption routine CNT0, CNT1 ; Mask register used in decryption routine MASK ; Temporary Register TMP0, TMP1, TMP2, TMP3 ; Temp register ENDC ;*********************************************************************** ;неиспольз. порты - выходы в ноль. ;SET_RXx состояние выхода при инициализации ;CONF_RXx =1 вход, =0 выход ; #DEFINE PROG PORTA,0 ;(IN) Programming Key (подтяжка на плюс) CONF_RA0 EQU 1<<0 SET_RA0 EQU 0<<0 ; #DEFINE LED PORTA,1 ;(OUT) Program/failure led indicator (активный "1") CONF_RA1 EQU 0<<1 SET_RA1 EQU 0<<1 ; #DEFINE HCSVDD PORTA,2 ;(OUT) HCS Vdd line #define BitHCSVDD 1<<2 CONF_RA2 EQU 0<<2 SET_RA2 EQU 0<<2 ; #DEFINE DATA PORTA,3 ;(IN/OUT) Data (PWM) for Programming HCS #define BitDATA 1<<3 CONF_RA3 EQU 0<<3 SET_RA3 EQU 0<<3 ; #DEFINE CLK PORTA,4 ;(OUT) Clock (S2) for Programming HCS #define BitCLK 1<<4 CONF_RA4 EQU 0<<4 SET_RA4 EQU 0<<4 ; #DEFINE RA5_NO_USE PORTA,5 CONF_RA5 EQU 0<<5 SET_RA5 EQU 0<<5 ; #DEFINE RA6_NO_USE PORTA,6 CONF_RA6 EQU 0<<6 SET_RA6 EQU 0<<6 ; #DEFINE RA7_NO_USE PORTA,7 CONF_RA7 EQU 0<<7 SET_RA7 EQU 0<<7 ; #DEFINE RB0_NO_USE PORTB,0 CONF_RB0 EQU 0<<0 SET_RB0 EQU 0<<0 ; #DEFINE RB1_NO_USE PORTB,1 CONF_RB1 EQU 0<<1 SET_RB1 EQU 0<<1 ; #DEFINE RB2_NO_USE PORTB,2 CONF_RB2 EQU 0<<2 SET_RB2 EQU 0<<2 ; #DEFINE RB3_NO_USE PORTB,3 CONF_RB3 EQU 0<<3 SET_RB3 EQU 0<<3 ; #DEFINE RB4_NO_USE PORTB,4 CONF_RB4 EQU 0<<4 SET_RB4 EQU 0<<4 ; #DEFINE RB5_NO_USE PORTB,5 CONF_RB5 EQU 0<<5 SET_RB5 EQU 0<<5 ; #DEFINE RB6_NO_USE PORTB,6 CONF_RB6 EQU 0<<6 SET_RB6 EQU 0<<6 ; #DEFINE RB7_NO_USE PORTB,7 CONF_RB7 EQU 0<<7 SET_RB7 EQU 0<<7 ; #DEFINE RC0_NO_USE PORTC,0 CONF_RC0 EQU 0<<0 SET_RC0 EQU 0<<0 ; #DEFINE RC1_NO_USE PORTC,1 CONF_RC1 EQU 0<<1 SET_RC1 EQU 0<<1 ; #DEFINE RC2_NO_USE PORTC,2 CONF_RC2 EQU 0<<2 SET_RC2 EQU 0<<2 ; #DEFINE RC3_NO_USE PORTC,3 CONF_RC3 EQU 0<<3 SET_RC3 EQU 0<<3 ; #DEFINE RC4_NO_USE PORTC,4 CONF_RC4 EQU 0<<4 SET_RC4 EQU 0<<4 ; #DEFINE RC5_NO_USE PORTC,5 CONF_RC5 EQU 0<<5 SET_RC5 EQU 0<<5 ; #DEFINE RC6_NO_USE PORTC,6 CONF_RC6 EQU 0<<6 SET_RC6 EQU 0<<6 ; #DEFINE RC7_NO_USE PORTC,7 CONF_RC7 EQU 0<<7 SET_RC7 EQU 0<<7 ; ;******************************************************************************************************** ;======================================================================================== ; ************** DECRYPTION REGISTER RE-MAPPINGS ******************* ; NOTE : INDIRECT ADDRESSING USED, DO NOT CHANGE REGISTER ASSIGNMENT ; ****************************************************************** ; 32 BIT HOPCODE BUFFER #DEFINE HOP1 CSR0 #DEFINE HOP2 CSR1 #DEFINE HOP3 CSR2 #DEFINE HOP4 CSR3 ; 28 BIT SERIAL NUMBER SER_3 EQU CSR7 ; LSB SER_2 EQU CSR6 SER_1 EQU CSR5 SER_0 EQU CSR4 ; MSB ;======================================================================================== ; MODIFYABLE PROGRAMMING DEFINE ;======================================================================================== #DEFINE KEY_METHOD 1 ; MUST BE 1 IF NORMAL KEY GENERATION METHOD TO BE USED ; MUST BE 0 IF SIMPLE KEY GENERATION METHOD TO BE USED ; (ENCRYPTION KEY= MANUFACTURER KEY) #DEFINE HCS30X 1 ; MUST BE 1 IF PROGRAMMING HCS300-301, ; MUST BE 0 IF PROGRAMMING HCS200 #DEFINE SYNC_COUNT 0X0000 ; SYNCRONOUS COUNTER #DEFINE SEED_0 0x0000 ; 2 WORD SEED VALUE #DEFINE SEED_1 0x0000 #DEFINE ENV_KEY 0x0000 ; ENVELOPE KEY ( NOT USED FOR HCS200) #DEFINE AUTOFF 1 ; AUTO SHUT OFF TIMER ( NOT USED FOR HCS200) #DEFINE DISC70 0x00 ; DISCRIMINATION BIT7-BIT0 #DEFINE DISC8 0 ; DISCRIMINATION BIT8 #DEFINE DISC9 0 ; DISCRIMINATION BIT9 #DEFINE OVR0 0 ; OVERFLOW BIT0 (DISC10 for HCS200) #DEFINE OVR1 0 ; OVERFLOW BIT1 (DISC11 for HCS200) #DEFINE VLOW 1 ; LOW VOLTAGE TRIP POINT SELECT BIT (1=High voltage) #DEFINE BSL0 0 ; BAUD RATE SELECT BIT0 #DEFINE BSL1 0 ; BAUD RATE SELECT BIT1 (RESERVED for HCS200) #DEFINE EENC 0 ; ENVELOPE ENCRYPTION SELECT (RESERVED for HCS200) #DEFINE DISEQSN 0 ; IF DISEQSN=1 SET DISCRIMINANT EQUAL TO SERNUM BIT10-0 ; IF DISEQSN=0 SET DISCRIMINANT AS DEFINED ABOVE ;======================================================================================== ; OTHER EQUATE ;======================================================================================== #DEFINE NUM_WRD .12 ; NUMBER OF WORD TO PROGRAM INTO HCS #DEFINE RES 0X0000 ; RESERVED WORD #DEFINE CONF_HI ((EENC<<7)|(BSL1<<6)|(BSL1<<5)|(VLOW<<4)|(OVR1<<3)|(OVR0<<2)|(DISC9<<1)|DISC8) ; ****** HCS TIME PROGRAMMING EQUATE ******** #DEFINE Tps .4 ; PROGRAM MODE SETUP TIME 4mS (3,5mS min, 4,5 max) #DEFINE Tph1 .4 ; HOLD TIME 1 4mS (3,5mS min) #DEFINE Tph2 .19 ; HOLD TIME 2 62uS (50uS min) #DEFINE Tpbw .3 ; BULK WRITE TIME 3mS (2,2mS min) #DEFINE Tclkh .10 ; CLOCK HIGH TIME 35uS (25uS min) #DEFINE Tclkl .10 ; CLOCK LOW TIME 35uS (25uS min) #DEFINE Twc .40 ; PROGRAM CYCLE TIME 40mS (36mS min) ; NOTE: FOR mS TIME DELAY USE WAIT_WMSEC SUBROUTINE ( W * 1mSec ) ; FOR uS TIME DELAY USE WAIT_uS SUBROUTINE ( 5 + Txxx*3 uS ) ;======================================================================================== ;======================================================================================== ;======================================================================================== ; FUNCTION : RESET () ; DESCRIPTION : PROGRAM RESET ROUTINE ;======================================================================================== ORG 0x00 RESET_VECTOR goto START ;======================================================================================== ; FUNCTION : ISR_VECTOR () ; DESCRIPTION : INTERRUPT SERVICE ROUTINE VECTOR ;======================================================================================== ORG 0x04 ISR_VECTOR retfie ;======================================================================================== ;======================================================================================== ; FUNCTION : WAIT_uS () ; DESCRIPTION : WAIT 5+W*3 MICROSECOND SUBROUTINE ;======================================================================================== WAIT_uS movwf COUNT_LO WAIT_uS_A decfsz COUNT_LO, F goto WAIT_uS_A return ;======================================================================================== ; FUNCTION : DEBOUNCE - WAIT_16MSEC - WAIT_WMSEC () ; DESCRIPTION : WAIT 16mSec or W mSec SUBROUTINE ;======================================================================================== DEBOUNCE WAIT_16MSEC movlw .16 WAIT_WMSEC movwf COUNT_HI WAITSET movlw .250 movwf COUNT_LO WAITLOOP clrwdt decfsz COUNT_LO,F goto WAITLOOP decfsz COUNT_HI,F goto WAITSET return ;======================================================================================== ; FUNCTION : BUTTON RELEASE () ; DESCRIPTION : WAIT FOR BUTTON RELEASE ;======================================================================================== BUTTON_RELEASE clrwdt btfss PROG goto BUTTON_RELEASE call DEBOUNCE return ;======================================================================================== ; FUNCTION : READ_SN () ; DESCRIPTION : READ LAST SERIAL NUMBER STORED IN THE EEPROM DATA, ; AND INCREMENT IT INTO NEW SER_x ;======================================================================================== READ_SN movlw SerialNumber call MovEeadrW call RdEepr_IncEeadr movwf SER_3 call RdEepr_IncEeadr movwf SER_2 call RdEepr_IncEeadr movwf SER_1 call RdEepr_IncEeadr movwf SER_0 READ_SN_X return ;======================================================================================== ; FUNCTION : WRITE_SN () ; DESCRIPTION : SAVE INTO EEPROM DATA THE LAST PROGRAMMED SERIAL ; : NUMBER ;======================================================================================== ;WRITE_SN errorlevel -302 ;Turn off banking message ;known tested (good) code MovEeadrW BSF STATUS,RP1 ;Bank 2 BCF STATUS,RP0 ; MOVWF EEADR BCF STATUS,RP1 RETURN WrEepr_IncEeadr BSF STATUS,RP1 ;Bank 2 BCF STATUS,RP0 ; MOVWF EEDATA BSF STATUS,RP0 ;Bank 3 BCF EECON1,EEPGD ;работа с памятью данных BSF EECON1,WREN ;разрешить запись movlw 55H movwf EECON2 movlw 0AAH movwf EECON2 bsf EECON1,WR ; wrp1_1 CLRWDT BTFSC EECON1,WR ; ожидание GOTO wrp1_1 ;конца записи BCF EECON1,WREN ;запретить запись VERIFY_WRITE BCF STATUS,RP0 ;Bank 2 movf EEDATA, W BSF STATUS,RP0 ;Bank 3 bsf EECON1, RD ; do a read clrwdt btfsc EECON1, RD ; Read done ? goto $-2 xorwf EEDATA, W BNZ EE_ERR ; EEPROM WRITE ERROR BCF STATUS,RP0 ;Bank 2 INCF EEADR,F ;продвинуть указатель адреса BCF STATUS,RP1 RETURN RdEepr_IncEeadr ;EEADR-адрес BSF STATUS,RP1 BSF STATUS,RP0 ;Bank 3 BCF EECON1,EEPGD ;работа с памятью данных BSF EECON1,RD ;чтение BCF STATUS,RP0 ;Bank 2 MOVF EEDATA,W ;данные INCF EEADR,F ;продвинуть указатель адреса BCF STATUS,RP1 RETURN errorlevel +302 ;Enable banking message ;untested code ;======================================================================================== ; FUNCTION : MEM_MAP () ; DESCRIPTION : PREPARE THE WORDS TO BE PROGRAMMED INTO HCS ;======================================================================================== MAP_SET movlw WORD0 movwf FSR WORD_0 ; ENCRYPTION KEY (4 WORD) WORD_0_LO movf KEY0,W movwf INDF incf FSR, F WORD_0_HI movf KEY1,W movwf INDF incf FSR, F WORD_1 WORD_1_LO movf KEY2,W movwf INDF incf FSR, F WORD_1_HI movf KEY3,W movwf INDF incf FSR, F WORD_2 WORD_2_LO movf KEY4,W movwf INDF incf FSR, F WORD_2_HI movf KEY5,W movwf INDF incf FSR, F WORD_3 WORD_3_LO movf KEY6,W movwf INDF incf FSR, F WORD_3_HI movf KEY7,W movwf INDF incf FSR, F WORD_4 ; SYNC_COUNT COUNTER (1 WORD) WORD_4_LO movlw LOW(SYNC_COUNT) movwf INDF incf FSR, F WORD_4_HI movlw HIGH(SYNC_COUNT) movwf INDF incf FSR, F WORD_5 ; RESERVED (1 WORD) WORD_5_LO movlw LOW(RES) movwf INDF incf FSR, F WORD_5_HI movlw HIGH(RES) movwf INDF incf FSR, F WORD_6 ; SERIAL NUMBER (2 WORD) WORD_6_LO movf SER_3, W ; LSByte movwf INDF incf FSR, F WORD_6_HI movf SER_2, W movwf INDF incf FSR, F WORD_7 WORD_7_LO movf SER_1, W movwf INDF incf FSR, F WORD_7_HI movf SER_0, W ; MSByte andlw B'00001111' iorlw (AUTOFF<<7) ; SET THE AUTO SHUT-OFF TIMER movwf INDF incf FSR, F WORD_8 ; SEED VALUE ( 2 WORD) WORD_8_LO movlw LOW(SEED_0) movwf INDF incf FSR, F WORD_8_HI movlw HIGH(SEED_0) movwf INDF incf FSR, F WORD_9 WORD_9_LO movlw LOW(SEED_1) movwf INDF incf FSR, F WORD_9_HI movlw HIGH(SEED_1) movwf INDF incf FSR, F WORD_10 ; ENVELOPE KEY (1 WORD) ; (RESERVED FOR HCS200 SET TO 0x0000) WORD_10_LO movlw (LOW(ENV_KEY) * HCS30X) movwf INDF incf FSR, F WORD_10_HI movlw (HIGH(ENV_KEY) * HCS30X) movwf INDF incf FSR, F ;!!! if DISEQSN==1 WORD_11_LO movf SER_3, W ; CONFIGURATION WORD movwf INDF ; LOWER BYTE=LOWEST BYTE OF SERIAL NUMBER incf FSR, F WORD_11_HI movf SER_2, W ANDLW B'00000011' ; MASK BIT OF SER. NUM. IORLW CONF_HI ; MASK OTHER BIT OF CONFIG WORD movwf INDF incf FSR, F else WORD_11_LO movlw DISC70 ; Discrimination bits (10 BIT) movwf INDF ; incf FSR, F ; WORD_11_HI movlw CONF_HI ; movwf INDF incf FSR, F endif return ;======================================================================================== ; FUNCTION : PREPARE_WRD () ; DESCRIPTION : PUT IN WRD_LO & WRD_HI THE WORD TO BE CLOCKED OUT (PWM) ;======================================================================================== PREPARE_WRD movf INDF, W movwf WRD_LO incf FSR, F movf INDF, W movwf WRD_HI incf FSR, F return ;======================================================================================== ; FUNCTION : DECRYPT () ; DESCRIPTION : DECRYPTS 32 BIT [HOP1:HOP4] USING [CSR0:CSR7] ;======================================================================================== 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 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 addwf PCL,F ; ADD THE INDEX TO THE PROGRAM COUNTER ; [ MUST BE IN LOWER HALF OF PAGE ] TABLE movlw 0x2E ; BITS 4:3 WERE 00 goto TABLE_END ; END OF LOOKUP movlw 0x74 ; BITS 4:3 WERE 01 goto TABLE_END ; END OF LOOKUP movlw 0x5C ; BITS 4:3 WERE 10 goto TABLE_END ; END OF LOOKUP movlw 0x3A ; BITS 4:3 WERE 11 TABLE_END andwf MASK,F ; ISOLATE THE CORRECT BIT 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 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 : CALC_KEY () ; DESCRIPTION : GENERATE 32 BITS ENCRYPTION KEY USING THE MANUFACTURER CODE STORED IN ROM ;======================================================================================== CALC_KEY iorwf SER_0,W ; PATCH 28 BIT SERIAL NUMBER movwf CSR3 ; ... AND COPY TO DECRYPT BUFFER movf SER_1,W movwf CSR2 movf SER_2,W movwf CSR1 movf SER_3,W movwf CSR0 CALC_KEY2 call DECRYPT ; DECRYPT 32 BIT USING MASTER KEY return ;======================================================================================== ; FUNCTION : NORMAL_KEY_GEN () ; DESCRIPTION : GENERATE THE 64 BITS ENCRYPTION KEY USING THE MANUFACTURER CODE STORED IN ROM ;======================================================================================== NORMAL_KEY_GEN call SIMPLE_KEY_GEN ;--------------- NORMAL_KEY_GEN_PATCH1 ; DERIVE LOWER 32 BITS OF DECRYPTION KEY FROM SN movlw 0x20 ; PATCH REQUIRED FOR HCS NORMAL ENCODER call CALC_KEY movf CSR3,W ; TEMPORARY STORE LOWER 32 BITS movwf TMP3 movfw CSR2 movwf TMP2 movfw CSR1 movwf TMP1 movfw CSR0 movwf TMP0 ;--------------- NORMAL_KEY_GEN_PATCH2 ; PATCH REQUIRED FOR HCS NORMAL ENCODER movlw 0x60 call CALC_KEY movfw CSR3 ; STORE UPPER 32 BITS OF DERIVED KEY movwf KEY7 ; .... IN 64 BIT KEY BUFFER movfw CSR2 movwf KEY6 movfw CSR1 movwf KEY5 movfw CSR0 movwf KEY4 ;--------------- NORMAL_KEY_GEN_REC movfw TMP3 ; RECOVER LOWER 32 BITS OF DERIVED KEY movwf KEY3 ; ... AND STORE IN 64 BIT KEY BUFFER movfw TMP2 movwf KEY2 movfw TMP1 movwf KEY1 movfw TMP0 movwf KEY0 return ;======================================================================================== ;======================================================================================== ; FUNCTION : GET KEY or SIMPLE_KEY_GEN () ; DESCRIPTION : ENCRYPTION KEY = MANUFACTURER CODE STORED IN ROM ;======================================================================================== SIMPLE_KEY_GEN movlw ManufCode ; COPY THE MANUFACTURER CODE INTO call MovEeadrW ; ENCRYPTION KEY (BYTE) call RdEepr_IncEeadr movwf KEY0 call RdEepr_IncEeadr movwf KEY1 call RdEepr_IncEeadr movwf KEY2 call RdEepr_IncEeadr movwf KEY3 call RdEepr_IncEeadr movwf KEY4 call RdEepr_IncEeadr movwf KEY5 call RdEepr_IncEeadr movwf KEY6 call RdEepr_IncEeadr movwf KEY7 return ;======================================================================================== ;******************************************************************************************************** START clrf STATUS clrf PCLATH movlw SET_RA0 | SET_RA1 | SET_RA2 | SET_RA3 | SET_RA4 | SET_RA5 ;начальное значение выходов movwf PORTA ; movlw SET_RB0 | SET_RB1 | SET_RB2 | SET_RB3 | SET_RB4 | SET_RB5 | SET_RB6 | SET_RB7 ; movwf PORTB ; movlw SET_RC0 | SET_RC1 | SET_RC2 | SET_RC3 | SET_RC4 | SET_RC5 | SET_RC6 | SET_RC7 ; movwf PORTC ; bsf STATUS,RP0 errorlevel -302 ;Turn off banking message, known tested (good) code movlw 0< VERIFY WORD xorwf INDF, W skpz goto PROG_ERR ; WORD LOW VERIFY ERROR incf FSR, F movf WRD_HI, W xorwf INDF, W skpz goto PROG_ERR ; WORD HIGH VERIFY ERROR incf FSR, F incf TMP_CNT, F movlw NUM_WRD xorwf TMP_CNT, W ; TEST IF RECEIVED ALL THE WORDS PROGRAMMED skpnz goto PROG_SUCCESS ; ALL 12 WORDS VERIFIED WITH SUCCESS clrf TXNUM ;--------------- M_VER_CLKHI bsf CLK ; CLK=1 movlw Tclkh ; WAIT TIME CLOCK HIGH call WAIT_uS M_VER_CLKLO bcf CLK ; CLK=0 movlw Tclkl ; WAIT TIME CLOCK LOW call WAIT_uS goto M_VER_BITIN ;---------------------------------------------------------------------------------------- PROG_SUCCESS ; WRITE LAST SN PROGRAMMED INTO EEPROM DATA movlw 1 addwf SER_3,f btfsc STATUS,C addwf SER_2,f btfsc STATUS,C addwf SER_1,f btfsc STATUS,C addwf SER_0,f movlw SerialNumber call MovEeadrW movf SER_3,w call WrEepr_IncEeadr movf SER_2,w call WrEepr_IncEeadr movf SER_1,w call WrEepr_IncEeadr movf SER_0,w call WrEepr_IncEeadr bsf LED ; LED ON FOR 0,4SEC movlw .200 call WAIT_WMSEC ; DELAY movlw .200 call WAIT_WMSEC ; DELAY goto PROG_END ;---------------------------------------------------------------------------------------- ; HCS PROGRAMMING ERROR ; WAIT FOR BUTTON PRESS PROG_ERR MOVLW 0xff ^ (BitDATA | BitCLK | BitHCSVDD) andwf PORTA,f movlw .20 ; 20 * 0,2SEC = 4SEC LED BLINKING movwf TMP_CNT PROG_ERR_LEDON bsf LED ; LED ON FOR 0,1SEC movlw .100 call WAIT_WMSEC ; DELAY PROG_ERR_LEDOFF bcf LED ; LED OFF FOR 0,1SEC movlw .100 call WAIT_WMSEC ; DELAY decfsz TMP_CNT,F goto PROG_ERR_LEDON PROG_ERR_X bcf LED goto PROG_END ;---------------------------------------------------------------------------------------- PROG_END bcf LED bcf HCSVDD call BUTTON_RELEASE goto M_LOOP ;---------------------------------------------------------------------------------------- ;DATA EEPROM WRITE ERROR; LED ON FOREVER EE_ERR BCF STATUS,RP1 BCF STATUS,RP0 MOVLW 0xff ^ (BitDATA | BitCLK | BitHCSVDD) andwf PORTA,f bsf LED ; LED ON clrwdt goto $-1 END