; ; Dallas TouchMemory routines ; (c) 1997 Pavel Korensky ; ; Freely usable for non-commercional use. ; Commercional use strictly prohibited ; ; DS_PORT equ PORTA ; Dallas port DS_BIT equ 4 ; Dallas bit ; ; Dallas TouchMemory commands - Touch Multikey specifically ; READ_ROM equ 0x33 SKIP_ROM equ 0xCC MATCH_ROM equ 0x55 WRITE_SCR equ 0x96 READ_SCR equ 0x69 COPY_SCR equ 0x3C WRITE_PSW equ 0x5A WRITE_SUB equ 0x99 READ_SUB equ 0x66 FAM_MULTIKEY equ 0x02 ;***************************************************************** ; ; Some macros ; ;***************************************************************** DSIN macro ; Set Dallas as input bsf STATUS, RP0 bsf TRISA,DS_BIT bcf STATUS, RP0 endm DSOUT macro ; Set Dallas as output - 1 bsf STATUS, RP0 bcf TRISA, DS_BIT bcf STATUS, RP0 bsf DS_PORT, DS_BIT endm ;************************************************************ ; ; Touch Memory routines ; ;************************************************************ ;************************************************************ ; ; Delay 67 us - For PRESENCE routine ; ;************************************************************ D67us: movlw 6 movwf del4 D67l_4 movlw 1 movwf del3 D67l_3 movlw 1 movwf del2 D67l_2 movlw 5 movwf del1 D67l_1 decfsz del1 goto D67l_1 decfsz del2 goto D67l_2 decfsz del3 goto D67l_3 decfsz del4 goto D67l_4 retlw 0 ;************************************************************ ; ; Delay 498 us - For RESET pulse ; ;************************************************************ D498us: movlw 1 movwf del4 D498l_4 movlw 1 movwf del3 D498l_3 movlw 0x4d movwf del2 D498l_2 movlw 4 movwf del1 D498l_1 decfsz del1 goto D498l_1 decfsz del2 goto D498l_2 decfsz del3 goto D498l_3 decfsz del4 goto D498l_4 retlw 0 ;************************************************************ ; ; Delay 2 us - Recovery time etc. ; ;************************************************************ D2us: nop retlw 0 ;************************************************************ ; ; Touch_Reset - Reset memory and check presence ; ; Return: 0 if memory not present, 1 if present, 3 if short circuit ; ;************************************************************ Touch_Reset DSOUT ; Set DS for output bcf DS_PORT, DS_BIT ; 0 to 1-wire call D498us ; wait tRSTL bsf DS_PORT, DS_BIT ; 1 to 1-wire DSIN ; Set DS for input call D67us ; wait tPDH btfsc DS_PORT, DS_BIT ; Presence pulse ? retlw 0 ; Return 0 if not call D498us ; Wait some time btfsc DS_PORT, DS_BIT ; 1-wire back HI ? retlw 1 ; return 1 if so retlw 2 ; Probably short circuit ;************************************************************* ; ; Write_DS_Byte - write byte from W to 1-wire ; ;************************************************************* Write_DS_Byte DSOUT ; Set DS for output movwf Temp1 ; store W movlw 8 movwf Temp ; 8 bits wdsb1: bcf DS_PORT, DS_BIT ; 0 to 1-wire call D2us ; wait 2 usec rrf Temp1,F ; rotate right skpnc ; if not carry, 0 to 1-wire bsf DS_PORT, DS_BIT call D67us ; wait 67 usec bsf DS_PORT, DS_BIT ; 1 to 1-wire call D2us ; wait tREC decfsz Temp goto wdsb1 ; loop for 8 bits DSIN ; Set DS for input retlw 0 ;************************************************************** ; ; Read_DS_Byte - read byte from DS to W ; ;************************************************************** Read_DS_Byte movlw 8 movwf Temp clrf Temp1 rdsb1: DSOUT ; set DS for output bcf DS_PORT, DS_BIT ; Start pulse call D2us ; wait DSIN nop nop ; wait a bit clrc ; clear carry btfsc DS_PORT, DS_BIT ; bit is 0 ? setc ; set carry if not rrf Temp1,F ; carry to Temp1 call D67us ; wait 67 usec decfsz Temp ; cycle for 8 bits goto rdsb1 movf Temp1,W ; byte to W return ;************************************************************************ ; ; DS_CRC8 - Will calculate 8 bit CRC for DALLAS DS components ; ; Input: Byte for CRC in W ; Return: Byte in W, CRC in CRC8 ;************************************************************************ DS_CRC8 movwf del2 movwf Temp ; Save byte movlw 8 ; 8 bits movwf Temp1 ; store counter movf Temp,W ; byte to W CRC8_L1 xorwf CRC8,W ; xor movwf del1 ; temp store rrf del1,W movf CRC8,W ; fetch last CRC skpnc ; if not C, skip xorlw 0x18 ; xor with fixed movwf CRC8 ; store new CRC rrf CRC8,F ; update new CRC clrc ; clear carry rrf Temp,F ; next bit movf Temp,W decfsz Temp1 ; count bits goto CRC8_L1 ; movf del2,W ; fetch original to W return ;************************************************************************* ; ; DS_CRC16 - Will calculate 16bit CRC for DALLAS DS components ; ; Input: Byte for CRC in W ; Output: Original byte in W, ; CRC16_HI and CRC16_LO new value of CRC16 ; ;************************************************************************* DS_CRC16 movwf del1 movwf Temp ; store W movlw 8 ; 8 bits movwf Temp1 movf Temp,W ; fetch W Crc_Get_Bit rrf Temp,F ; bit in C movf Temp,W ; value to W skpnc goto Crc_In_1 btfss CRC16_LO,0 ; lowest bit set ? goto Crc_Cont ; goto count with C=0 setc goto Crc_Cont ; goto count with C=1 Crc_In_1 btfsc CRC16_LO,0 ; lowest bit zero ? clrc ; if no, C=0 = complement Crc_Cont skpc goto Crc_Shift ; if C=0 only shift btfsc CRC16_HI,6 ; complement 15th bit of CRC goto Crc1 bsf CRC16_HI,6 ; if clear, set goto Crc2 Crc1 bcf CRC16_HI,6 ; if set, clear Crc2 btfsc CRC16_LO,1 ; complement 2nd bit of CRC goto Crc3 bsf CRC16_LO,1 goto Crc_Shift Crc3 bcf CRC16_LO,1 Crc_Shift rrf CRC16_HI,F ; 16bit rotate rrf CRC16_LO,F movf Temp,W decfsz Temp1 goto Crc_Get_Bit movf del1,W ; fetch the original byte return ;**************************************************************************** ; ; Get_DS_Serial - Get Key serial number to buffer ; ; Argument - W=start of buffer ; Return - W=0x01 OK, W=0x02 bad button ; ;**************************************************************************** Get_DS_Serial movwf FSR clrf CRC8 ; clear CRC8 movlw READ_ROM call Write_DS_Byte ; Read ROM call Read_DS_Byte ; Fam. code call DS_CRC8 movwf INDF incf FSR call Read_DS_Byte ; Ser 1 call DS_CRC8 movwf INDF incf FSR call Read_DS_Byte ; Ser 2 call DS_CRC8 movwf INDF incf FSR call Read_DS_Byte ; Ser 3 call DS_CRC8 movwf INDF incf FSR call Read_DS_Byte ; ser 4 call DS_CRC8 movwf INDF incf FSR call Read_DS_Byte ; ser 5 call DS_CRC8 movwf INDF incf FSR call Read_DS_Byte ; ser 6 call DS_CRC8 movwf INDF incf FSR call Read_DS_Byte ; CRC call DS_CRC8 movf CRC8,W ; CRC to W iorlw 0 ; is 0 ? skpz retlw 2 ; if not, error retlw 1 ; else OK