;www.joyta.ru

	include		p16f628.inc
	__config _WDT_ON & _MCLRE_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _BODEN_OFF

;программа для частоты процессора 4 МГц!!!

 cblock 0x20
 dsdat0
 dsdat1
 dsdat2
 dsdat3
 dsdat4
 dsdat5
 dsdat6
 dsdat7
 var_01
 var_02
 var_03
 var_04
 var_05
 var_06
 _4del
 _ms_del
 endc

DQ		equ		4
Bp1		equ		2
Bp2		equ		3

;-------

		org 0x00
		movlw	b'00000111'
		movwf	CMCON		;компараторы не используются
		bcf		PORTA, 1	;!!!!!!!!!!!!!
		bcf 	STATUS, RP1
		bsf 	STATUS, RP0	;bank 1
		movlw	b'11110001'
		movwf	TRISA
		movlw	b'00000001'
		movwf	TRISB
		movlw	b'01111010'
		movwf	OPTION_REG
		bcf		STATUS, RP0	;bank 0

		movlw	d'50'
		movwf	var_01
start_test:
		btfsc	PORTB, 0	
		goto	d_start
		movlw	d'100'
		call 	_ms_delay
		decfsz	var_01, f
		goto	start_test
		call	_clean_eeprom ;кнопка нажата более 5с - очистить EEPROM
		
		movlw	d'114'
		movwf	var_01
		movlw	d'31'
		movwf	var_02
		movlw	d'2'
		movwf	var_03
		call	_sound
		movlw	d'67'
		call	_ms_delay
		call	_sound

d_start:
;задержка ~72 мс
		sleep
;передаём ипульс сброса	
		bcf		PORTA, DQ
		bsf		STATUS, RP0	;bank 1
		bcf		TRISA, DQ	;DQ - выход
		bcf		STATUS, RP0	;bank 0
		movlw	d'124'		;задержка 502 мкс
		call	_4delay
		bsf		STATUS, RP0 ;bank 1
		bsf		TRISA, DQ	;DQ - вход
		bcf		STATUS, RP0	;bank 0
		movlw	d'16'		;задержка 70 мкс
		call 	_4delay
		btfsc	PORTA, DQ	;на DQ низкий уровень?
		goto	d_start		;нет - начать с начала
		movlw	d'106'		;задержка 430 мкс
		call	_4delay
		btfss	PORTA, DQ	;на DQ высокий уровень?
		goto	d_start		;нет - начать с начала
		
			
;передаём команду "читать серийный номер"
		movlw	0x33		;код команды
		call	send_byte
;--------------------------------
;принимаем передаваемый "таблеткой" серийный номер
		movlw 	dsdat0		;адрес первого байта
		movwf  	FSR
		movlw	d'8'		;количество байт
		movwf	var_03
_next_rc_byte:
		call	receive_byte
		movwf	INDF
		incf	FSR, f
		decfsz	var_03, f
		goto	_next_rc_byte
	

		movf	dsdat0, f
		btfsc	STATUS, Z
		goto	_error_data
		
		
;вычисляем CRC
		clrf	var_04
		movlw	d'7'
		movwf 	var_01
		movlw 	dsdat0
		movwf 	FSR
Next_byte:
        movlw   0x08
        movwf   var_02
		movf	INDF, w
		movwf 	var_03
DoCRC_Loop:
        xorwf   var_04, w
        movwf   var_05
        rrf     var_05, w
        movf    var_04, w
        btfsc   STATUS, C
        xorlw   b'00011000'
        movwf   var_05
        rrf     var_05, w
        movwf   var_04
        bcf     STATUS, C
        rrf     var_03, f
		movf    var_03, w
        decfsz  var_02, f
        goto    DoCRC_Loop
		incf 	FSR, f
		decfsz	var_01, f
		goto 	Next_byte
;в переменной var_04 - crc первых 7-ми байт
;сравниваем её с принятой(пер. dsdat7)
		movf 	var_04, w
		xorwf 	dsdat7, w
		btfss 	STATUS, Z
		goto 	_error_data

		clrwdt			;сброс watсhdog таймера

		call	search_eeprom
		xorlw	0x01
		btfss	STATUS, Z
		goto	f_id

ok_id	call	_identify_ok
		goto	d_start
		
f_id	call	_identify_failed
		goto	d_start

search_eeprom:
;поиск в EEPROM серийного номера
		clrw
		bsf		STATUS, RP0	;bank 1
		movwf	EEADR
		bsf		EECON1, RD
		movf	EEDATA, w
		bcf		STATUS, RP0	;bank 0
		movwf	var_01	;количество ключей
		movlw	0x01
		movwf	var_02	;адрес в EEPROM
_next_sr:		
		movlw	d'6'
		movwf	var_03	;номер проверяемого байта
		movlw	dsdat1
		movwf	FSR
_st_cmp:
		movf	var_02, w	;адрес в W
		bsf		STATUS, RP0	;bank 1
		movwf	EEADR		;W в регистр адреса
		bsf		EECON1, RD	;начать чтение
		movf	EEDATA, w	;из EEPROM в W
		bcf		STATUS, RP0	;bank 0
		xorwf	INDF, w		;сравнить прочитанный байт с байтом
							;серийного номера
		btfsc	STATUS, Z	;равны?
		goto	_next_cmp	;да, сравнить следующий
		movf	var_03, w	
		addwf	var_02, f	
		decfsz	var_01, f	;все номера сравнены?
		goto	_next_sr	;нет, сравнить снова
		clrw				;да, выйти из подпрограммы с W=0
		goto	exit_se 
								
_next_cmp:
		incf	FSR, f		;следующий байт серийного номера
		incf	var_02, f	;следующий байт EEPROM
		decfsz	var_03, f	;все байты проверены?
		goto	_st_cmp		;нет, проверить следующие
							;да - выйти из подпрограммы с W=1
		movlw	0x01
exit_se:		
		return

_identify_ok:
;сигнал "пользователь определён"
		movlw	d'45'		;556 Hz
		movwf	var_01	
		movlw	d'37'		;1/15 сек
		movwf	var_02
		movlw	d'2'
		movwf	var_03
		call	_sound
		movlw	d'40'		;625 Hz
		movwf	var_01
		movlw	d'42'		;1/15 сек
		movwf	var_02
		call	_sound
		movlw	d'67'		;
		call	_ms_delay	;
		movlw	d'30'		;833 Hz
		movwf	var_01
		movlw	d'111'		;1/7 сек
		movwf	var_02
		call	_sound
		movlw	d'15'
		movwf	var_01
		movlw	d'222'
		movwf	var_02
		call	_sound

		btfss	PORTB, 0		;!!!!!!!
		call	_write_serial	;!!!!!!!

		bsf		PORTA, 1

		movlw	d'7'
		movwf	dsdat0		;!!!!используется dsdat0
next_id_sound:
		movlw	d'14'
		movwf	var_01
		movlw	d'51'
		movwf	var_02
		movlw	d'14'
		movwf	var_03
		call	_sound
		movlw	d'100'
		call	_ms_delay
		decfsz	dsdat0, f
		goto	next_id_sound

		bcf		PORTA, 1
		
		return	
	
_identify_failed:
;сигнал "пользователь не определён"
		movlw	d'45'		;556 Hz
		movwf	var_01	
		movlw	d'37'		;1/15 сек
		movwf	var_02
		movlw	d'2'
		movwf	var_03
		call	_sound
		movlw	d'40'		;625 Hz
		movwf	var_01
		movlw	d'42'		;1/15 сек
		movwf	var_02
		call	_sound
		movlw	d'67'		;
		call	_ms_delay	;
		movlw	d'241'		;104 Hz
		movwf	var_01
		movlw	d'14'		;1/7 сек
		movwf	var_02
		call	_sound
		movlw	d'67'		;
		call	_ms_delay	;
		call	_sound

		btfss	PORTB, 0
		call	_write_serial

		movlw	d'7'
		movwf	var_01
		movlw	d'250'
		call	_ms_delay
		decfsz	var_01, f
		goto	$-3	
		
		return

;подпрограмма передачи байта
send_byte:
		movwf	var_01
		movlw	d'8'
		movwf	var_02		;количество передаваемых бит
next_tr_b:
		bcf		PORTA, DQ
		bsf		STATUS, RP0	;bank 1
		bcf		TRISA, DQ	;DQ - выход
		bcf		STATUS, RP0	;bank 0
		nop
		nop
		rrf		var_01, f
		btfsc	STATUS, C
		goto	_set_in
		nop
		nop
		goto	_no_set_in
_set_in:
		bsf 	STATUS, RP0	;bank 1
		bsf		TRISA, DQ	;DQ - вход
		bcf		STATUS, RP0 ;bank 0
_no_set_in:
		movlw	d'14'		;задержка 62 мкс
		call	_4delay
		bsf 	STATUS, RP0	;bank 1
		bsf		TRISA, DQ	;DQ - вход
		bcf		STATUS, RP0 ;bank 0
		nop
		nop
		nop
		nop
		decfsz	var_02, f
		goto	next_tr_b
		return

;подпрограмма приёма байта
receive_byte:
		movlw	d'8'		
		movwf	var_01
		clrf	var_02
next_rc_b:	
		bcf		PORTA, DQ
		bsf		STATUS, RP0	;bank 1
		bcf		TRISA, DQ	;DQ - выход
		bcf		STATUS, RP0	;bank 0
		nop
		nop
		nop
		nop
		nop
		nop
		bsf		STATUS, RP0 ;bank 1
		bsf		TRISA, DQ	;DQ - вход
		bcf		STATUS, RP0	;bank 0
		nop
		nop
		nop	
		bcf 	STATUS, C
		btfsc	PORTA, DQ
		bsf		STATUS, C
		rrf		var_02, f
		movlw	d'11'		;задержка 50 мкс
		call	_4delay
		decfsz	var_01, f
		goto	next_rc_b
		movf	var_02, w
		return
		
;------____--------------
_error_data:
		movlw	d'223'
		movwf	var_01
		movlw	d'9'
		movwf	var_02
		movlw	d'2'
		movwf	var_03
		call	_sound
		goto 	d_start

;подпрограмма "звуковой сигнал"
;var1 определяет частоту (var1=FRm/4/20/2/FRs-4) FRm - частота микроконтроллера(Hz), FRs - частота звука(Hz)
;var2 и var3 - определяет длительность. (var2*var3/2=FRs*dr) dr - длительность, сек
_sound:
		bsf		PORTA, Bp1
		bcf		PORTA, Bp2	
		movf	var_03, w
		movwf	var_06
_restore_cnt2:
		movf	var_02, w
		movwf	var_05
_restore_cnt1:
		movf	var_01, w
		movwf	var_04	
_dec_delay1:		
		nop
		nop
		nop
		movlw	d'3'
		call	_4delay
		decfsz	var_04, f
		goto 	_dec_delay1
		movlw	(1<<Bp1)+(1<<Bp2)
		xorwf	PORTA, f
		decfsz	var_05, f
		goto	_restore_cnt1
		decfsz	var_06, f
		goto	_restore_cnt2
		bcf		PORTA, Bp1
		bcf		PORTA, Bp2
		return	
		

;подпрограмма задержки ms
_ms_delay:
		movwf	_ms_del
_1000us:
		nop
		nop
		movlw	d'247'
		call	_4delay
		decfsz	_ms_del, f
		goto	_1000us
		return	
		
;подпрограмма задержки us
_4delay:
		movwf 	_4del
l4dl	clrwdt
		decfsz 	_4del, f
		goto 	l4dl
		return

_write_serial:
		movlw	dsdat1
		movwf	FSR
		bsf		STATUS, RP0 ;bank 1
		clrf	EEADR
		bsf		EECON1, RD
		movf	EEDATA, w
		bcf		STATUS, RP0; bank 0
		movwf	var_01	
		sublw	d'20'
		btfss	STATUS, C
		goto	_mem_full
		movf	var_01, w
		bcf		STATUS, C	;
		rlf		var_01, f	;умножаем var_01 на 6
		rlf		var_01, f	;-------//---------
		addwf	var_01, f	;------//---------
		addwf	var_01, f	;-----//---------
		incf	var_01, w	;var_01 +1
		bsf		STATUS, RP0	;bank 1
		bsf		EECON1, WREN
		movwf	EEADR
_next_byte:		
		movf	INDF, w	
		movwf	EEDATA
		call	_eeprom_write
		incf	EEADR, f
		incf	FSR, f
		movlw	dsdat7
		subwf	FSR, w
		btfss	STATUS, C
		goto	_next_byte
		bcf		EECON1, WREN
		clrf	EEADR
		bsf		EECON1, RD
		movf	EEDATA, w
		addlw	0x01
		bsf		EECON1, WREN
		movwf	EEDATA
		call	_eeprom_write
		bcf		EECON1, WREN
		bcf		STATUS, RP0 ;bank 0
		goto	exit_write_serial
_mem_full:
		movlw	d'30'
		movwf	var_01
		movlw	d'165'	
		movwf	var_02	
		movlw	d'2'
		movwf	var_03
		call	_sound
		movlw	d'67'		;
		call	_ms_delay	;
		movlw	d'34'
		movwf	var_01
		movlw	d'105'
		movwf	var_02
		call	_sound
		movlw	d'67'		;
		call	_ms_delay	;
		movlw	d'28'
		movwf	var_01
		movlw	d'178'
		movwf	var_02
		call	_sound
		movlw	d'67'		;
		call	_ms_delay	;
		movlw	d'45'
		movwf	var_01
		movlw	d'79'
		movwf	var_02
		call	_sound
exit_write_serial:
		return

_clean_eeprom:
		bsf		STATUS, RP0	;bank 1
		bsf 	EECON1, WREN		;разрешить запись
		clrf	EEADR
		movlw	0x00
		movwf	EEDATA
		goto	_write_first
_nx_adr	movlw	0xFF
		movwf	EEDATA
_write_first:
		call 	_eeprom_write
		incf	EEADR, f
		movlw	0x80
		subwf	EEADR, w
		btfss	STATUS, C
		goto	_nx_adr
		bcf		EECON1, WREN		;запретить запись
		bcf		STATUS, RP0 ;bank 0
		return	
		

_eeprom_write:
;		bcf 	INTCON, GIE	;запретить прерывания
		clrwdt
		movlw 	0x55
		movwf 	EECON2
		movlw 	0xAA
		movwf 	EECON2
		bsf 	EECON1, WR
eewrts	btfsc 	EECON1, WR
		goto 	eewrts
		return



		org 0x2100
		DATA 	0x00

		end


