PROCESSOR PIC16F84A RADIX DEC INCLUDE "P16F84A.INC" __CONFIG _XT_OSC & _CP_OFF & _WDT_ON & _PWRTE_ON ;======================================================================================== ; ; PIC16F84A ; -------_-------- ; HCSVDD | 1 RA2 RA1 18| CLK (to IO slave: S2) ; | 2 RA3TC RA0 17| DATA (to IO slave: PWM) ; | 3 RA4 OSC1 16| OSCin ; reset | 4 MCLR OSC2 15| OSCtest ; Vss | 5 Vss Vdd 14| Vdd ; | 6 RB0 RB7 13| PROG ; | 7 RB1 RB6 12| LED ; | 8 RB2 RB5 11| ; | 9 RB3 RB4 10| ; ---------------- ; ;======================================================================================== ; MACROS #DEFINE BANK0 bcf STATUS,RP0 #DEFINE BANK1 bsf STATUS,RP0 ;======================================================================================== ; I/O PORT ASSIGNEMENT ; PORTA BIT DEFINITIONS #DEFINE DATA PORTA,0 ; (IN/OUT) Data (PWM) for Programming HCS #DEFINE CLK PORTA,1 ; (OUT) Clock (S2) for Programming HCS #DEFINE HCSVDD PORTA,2 ; (OUT) HCS Vdd line ; PORTB BIT DEFINITIONS #DEFINE LED PORTB,6 ; (OUT) Program/failure led indicator #DEFINE PROG PORTB,7 ; (IN) Programming Key #DEFINE SWRES PORTB,7 ; (IN) Sw reset Key on programming failure ;--------------- ; PORT DIRECTION DEFINE REG #DEFINE K_MASKPA B'11111000' ; PORTA: TRI-STATE VALUE #DEFINE K_MASKPB B'10111111' ; PORTB: TRI-STATE VALUE #DEFINE K_MASKPA_PROG B'11111000' ; PORTB: TRI-STATE FOR PROGRAMMING HCS #DEFINE K_MASKPA_VERI B'11111001' ; PORTB: TRI-STATE FOR VERIFY HCS #DEFINE K_OPTION B'00000111' ; OPTION REGISTER SETTING ; PORTB PULL-UP ON, TMR0 associated to Tcy, Prescaler=1:256 ;======================================================================================== ; GENERAL PURPOSE RAM REGISTERS CBLOCK 0x0C ; 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 MYCONT ; " 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 ; End of define general purpose RAM register ;======================================================================================== ; ************** 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 0 ; 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 MCODE_0 0xCDEF ; MANUFACTURER CODE, LSWORD #DEFINE MCODE_1 0x89AB #DEFINE MCODE_2 0x4567 #DEFINE MCODE_3 0x0123 ; MSWORD #DEFINE SYNC 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 1 ; 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 ;======================================================================================== ;======================================================================================== ;======================================================================================== ; SUBROUTINES SUBROUTINES SUBROUTINES SUBROUTINES SUBROUTINES ;======================================================================================== ;======================================================================================== ;======================================================================================== ; FUNCTION : INITREG ; DESCRIPTION : REGISTER INIZIALIZATION ;======================================================================================== INITREG clrf STATUS clrf INTCON ; INTERRUPT DISABLED clrf PORTA ; RESET PORTA clrf PORTB ; RESET PORTB BANK1 movlw K_OPTION ; INT CLK, PRESCALER TO TMR0, ON PULL-UP movwf OPTION_REG movlw K_MASKPA ; SETUP PORTA movwf TRISA movlw K_MASKPB ; SETUP PORTB movwf TRISB BANK0 clrf TMR0 return ;======================================================================================== ; FUNCTION : INITREG ; DESCRIPTION : REGISTER INIZIALIZATION ;======================================================================================== CLEAR_RAM movlw 0x0C movwf FSR CLEAR_RAM_LOOP clrf INDF incf FSR,F movlw 0x50 xorwf FSR,W skpz goto CLEAR_RAM_LOOP return ;======================================================================================== ; 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 PIC16F84A EEPROM DATA, ; AND INCREMENT IT INTO NEW SER_x ;======================================================================================== READ_SN movlw SER_3 movwf FSR clrf MYCONT ; COUNTER OF BYTE ; READ FROM DATA EEPROM READ_SN_A clrwdt movf MYCONT,W movwf EEADR BANK1 bsf EECON1, RD ; do a read clrwdt btfsc EECON1, RD ; Read done ? goto $-2 BANK0 movf EEDATA,W movwf INDF incf MYCONT, F movlw .4 xorwf MYCONT, W ; TEST IF 4 BYTE READ bz READ_SN_INC decf FSR, F goto READ_SN_A READ_SN_INC incfsz SER_3, F ; LOW BYTE: INCREMENT SN goto READ_SN_X incfsz SER_2, F goto READ_SN_X incfsz SER_1, F goto READ_SN_X incf SER_0, F READ_SN_X return ;======================================================================================== ; FUNCTION : WRITE_SN () ; DESCRIPTION : SAVE INTO PIC16F84A EEPROM DATA THE LAST PROGRAMMED SERIAL ; : NUMBER ;======================================================================================== WRITE_SN clrwdt movlw SER_3 movwf FSR clrf MYCONT ; COUNTER OF BYTE ; WRITTEN TO DATA EEPROM WRITE_SN_BYTE clrwdt movf MYCONT, W movwf EEADR movf INDF, W movwf EEDATA BANK1 bcf EECON1, EEIF bsf EECON1, WREN ; enable Write movlw 0x55 movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1, WR WRITE_SN_A clrwdt btfsc EECON1, WR ; Write complete ? goto WRITE_SN_A bcf EECON1, WREN ; disable Write VERIFY_WRITE BANK0 movf EEDATA, W BANK1 bsf EECON1, RD ; do a read clrwdt btfsc EECON1, RD ; Read done ? goto $-2 BANK0 xorwf EEDATA, W BNZ EE_ERR ; EEPROM WRITE ERROR incf MYCONT, F movlw .4 xorwf MYCONT, W ; TEST IF WRITTEN ALL THE 4 BYTES BZ WRITE_SN_X decf FSR, F goto WRITE_SN_BYTE WRITE_SN_X return ;======================================================================================== ; FUNCTION : MEM_MAP () ; DESCRIPTION : PREPARE THE WORDS TO BE PROGRAMMED ;======================================================================================== 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 COUNTER (1 WORD) WORD_4_LO movlw LOW(SYNC) movwf INDF incf FSR, F WORD_4_HI movlw HIGH(SYNC) 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) 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 WORD_11 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 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 : GET KEY or SIMPLE_KEY_GEN () ; DESCRIPTION : ENCRYPTION KEY = MANUFACTURER CODE STORED IN ROM ;======================================================================================== SIMPLE_KEY_GEN movlw HIGH(MCODE_3) ; COPY THE MANUFACTURER CODE INTO movwf KEY7 ; ENCRYPTION KEY (BYTE) movlw LOW(MCODE_3) movwf KEY6 movlw HIGH(MCODE_2) movwf KEY5 movlw LOW(MCODE_2) movwf KEY4 movlw HIGH(MCODE_1) movwf KEY3 movlw LOW(MCODE_1) movwf KEY2 movlw HIGH(MCODE_0) movwf KEY1 movlw LOW(MCODE_0) movwf KEY0 return ;======================================================================================== ;======================================================================================== ;======================================================================================== ; END SUBROUTINES END SUBROUTINES END SUBROUTINES ;======================================================================================== ;======================================================================================== ;======================================================================================== ; FUNCTION : START () ; DESCRIPTION : PROGRAM START ROUTINE ;======================================================================================== START call INITREG call CLEAR_RAM bsf LED ; LED ON PWUP movlw .250 ; WAIT 250Msec with LED ON call WAIT_WMSEC bcf LED ; LED OFF goto M_LOOP ;======================================================================================== ; FUNCTION : M_LOOP () ; DESCRIPTION : MAIN PROGRAM ROUTINE ;======================================================================================== M_LOOP clrwdt ; WAIT FOR PROGRAMMING BUTTON PRESS btfsc PROG goto M_LOOP call DEBOUNCE ;---------------------------------------------------------------------------------------- ; PROGRAMMING ROUTINES ;---------------------------------------------------------------------------------------- M_KEY_GEN call READ_SN ; READ FROM EE SN TO BE PROGRAMMED clrwdt if KEY_METHOD==1 call NORMAL_KEY_GEN else call SIMPLE_KEY_GEN endif call MAP_SET ; PREPARE EEPROM MEMORY MAP ;--------------- ; ENTER IN PROGRAMMING MODE AND BULK ERASE M_PROGRAMMING M_PROG_INIT bcf DATA ; DATA=0 bcf CLK ; CLK=0 bsf HCSVDD ; HCS POWER ON BANK1 movlw K_MASKPA_PROG movwf TRISA BANK0 call WAIT_16MSEC M_PROG_SETUP bsf CLK ; DATA=0, CLK=1 movlw Tps ; WAIT Program mode Setup Time (Tps) call WAIT_WMSEC bsf DATA ; DATA=1, CLK=1 movlw Tph1 ; WAIT Program Hold Time 1 (Tph1) call WAIT_WMSEC bcf DATA ; DATA=0, CLK=1 movlw Tph2 ; WAIT Program Hold Time 2 (Tph2) call WAIT_uS M_PROG_BULK_ER bcf CLK ; DATA=0, CLK=0 movlw Tpbw ; WAIT Program Bulk Write Time (Tpbw) call WAIT_WMSEC ;--------------- ; CLOCK INTO HCS THE WORDS TO BE PROGRAMMED clrf TMP_CNT ; NUMBER OF WORD TRASMITTED movlw WORD0 ; SET INDIRECT PONTER TO INIT EE MAP movwf FSR M_NEW_WORD call PREPARE_WRD ;--------------- ; OUTPUT WORD ROTATE clrf TXNUM ; NUMBER OF BIT TRASMITTED FOR EACH WORD M_TX_BIT bsf CLK ; CLK=1 clrc rrf WRD_HI, F ; ROTATE BIT TO OUTPUT rrf WRD_LO, F ; into CARRY FLAG skpnc goto M_PROG_DHI nop M_PROG_DLO bcf DATA ; DATA=0 goto M_PROG_BIT M_PROG_DHI bsf DATA ; DATA=1 M_PROG_BIT movlw Tclkh call WAIT_uS ; DELAY bcf CLK ; CLK=0 movlw Tclkl call WAIT_uS ; DELAY ;--------------- M_PROG_CHK_WORD incf TXNUM, F ; INCREMENT NUMBER OF BIT TRASMITTED movlw .16 ; CHECK IF END OF WORD TRASMITTED (16 BITS) xorwf TXNUM, W skpz goto M_TX_BIT ; TRASMIT NEXT BIT ;--------------- ; END OUTPUT WORD M_END_WORD bcf DATA ; DATA=0 movlw Twc ; WAIT FOR WORD Write Cycle Time (Twc) call WAIT_WMSEC ;--------------- M_CECHK_PRG_END incf TMP_CNT, F ; INCREMENT NUMBER OF WORD PROGRAMMED movlw NUM_WRD ; CHECK NUMBER OF WORD TRASMITTED xorwf TMP_CNT, W skpz goto M_NEW_WORD ; PROGRAM NEW WORD ;---------------------------------------------------------------------------------------- ; VERIFY ROUTINE ;---------------------------------------------------------------------------------------- M_VERIFY BANK1 movlw K_MASKPA_VERI ; I/O TRISTATE FOR VERIFY movwf TRISA BANK0 clrwdt movlw WORD0 ; SET INDIRECT POINTER TO INIT EE MAP movwf FSR clrf TMP_CNT ; NUMBER OF WORDS RECIVED clrf TXNUM ; NUMBER OF BIT RECEIVED FOR EACH WORD ;--------------- M_VER_BITIN clrc ; RECIVE DATA BIT FROM HCS FOR VERIFY btfsc DATA ; TEST and ROTATE RECEIVED BIT INTO WORD BUFFER setc rrf WRD_HI, F rrf WRD_LO, F incf TXNUM, F movlw .16 xorwf TXNUM, W ; TEST IF RECEIVED A COMPLETE WORD skpz goto M_VER_CLKHI ;--------------- M_VERIFY_WORD movf WRD_LO, W ; 16th BIT RECIVED (WORD) -> 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 call WRITE_SN ; WRITE LAST SN PROGRAMMED INTO ; PIC16F84A EEPROM DATA 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 clrf PORTA 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 ;---------------------------------------------------------------------------------------- ; PIC16F84A DATA EEPROM WRITE ERROR; LED ON FOREVER EE_ERR clrf PORTA bsf LED ; LED ON clrwdt goto $-1 ;---------------------------------------------------------------------------------------- ; INIZIALIZE THE SER NUM STORED IN THE FIRST 4 BYTES OF THE INTERNAL EE DATA MEMORY ;---------------------------------------------------------------------------------------- ORG 0x2100 DE 0x00 DE 0x00 DE 0x00 DE 0x00 ;---------------------------------------------------------------------------------------- ;======================================================================================== ; END OF FILE ;======================================================================================== END