
; Инициализация DS1820
; ресурcы	Y, r16
;--------------------------------------------------------------------------
RESET_PULSE:
	sbi	DDRB, DDB2		; порт на вывод

;--------------------------------------------------------------------------
	ldi	YH, High(999)		; заряжаем таймер на 500 мкСек
	ldi	YL, Low(999)
	rcall	INIT_TIMER_1

RESET_PULSE_0:
	wdr
	lds	r16, ONE_WIRE_flag
	sbrs	r16, Timeout_T1_compl	; ждем окончания отсчета
	rjmp	RESET_PULSE_0

;--------------------------------------------------------------------------
	cbi	DDRB, DDB2		; порт на ввод

;--------------------------------------------------------------------------
	cli
RESET_PULSE_1:
	ldi	YH, High(99)		; заряжаем таймер на 50 мкСек
	ldi	YL, Low(99)
	rcall	INIT_TIMER_1

RESET_PULSE_3:
	wdr
	lds	r16, ONE_WIRE_flag
	sbrs	r16, Timeout_T1_compl	; ждем окончания отсчета
	rjmp	RESET_PULSE_3
;--------------------------------------------------------------------------
	ldi	YH, High(999)		; заряжаем таймер на 500 мкСек
	ldi	YL, Low(999)
	rcall	INIT_TIMER_1

	sbis	PINB, PINB2		; ждем ответ DS1820	
	rjmp	RESET_PULSE_2		; ответ получен 	

	sei
	lds	r16, ONE_WIRE_flag
	cbr	r16, (1<<Error_1wire_dev)
	sts	ONE_WIRE_flag, r16	; флаг, датчик не обнаружен	
	rjmp	RESET_RET

RESET_PULSE_2:
	sei
	lds	r16, ONE_WIRE_flag
	sbr	r16, (1<<Error_1wire_dev)
	sts	ONE_WIRE_flag, r16	; флаг, датчик обнаружен		

RESET_RET:
	wdr
	lds	r16, ONE_WIRE_flag
	sbrs	r16, Timeout_T1_compl	; ждем окончания отсчета
	rjmp	RESET_RET

	ret

; Передача мастером L уровня
; ресурсы	Y, r16
;--------------------------------------------------------------------------
L_MASTER_TX:
	cli
	sbi	DDRB, DDB2		; порт на вывод

	ldi	YH, High(139)		; заряжаем таймер на 70 мкСек
	ldi	YL, Low(139)
	rcall	INIT_TIMER_1

L_MASTER_TX_0:	
	lds	r16, ONE_WIRE_flag
	sbrs	r16, Timeout_T1_compl	; ждем окончания отсчета
	rjmp	L_MASTER_TX_0

	cbi	DDRB, DDB2		; импеданс (подтяжка)

	nop
	nop
	nop
	nop

	ret	

; Передача мастером H уровня
; ресурсы	Y, r16
;--------------------------------------------------------------------------
H_MASTER_TX:
	cli
	sbi	DDRB, DDB2		; порт на вывод

	nop
	nop				; 2 мкСек
	nop
	nop

	cbi	DDRB, DDB2		; импеданс (подтяжка)

	ldi	YH, High(149)		; заряжаем таймер на 75 мкСек
	ldi	YL, Low(149)
	rcall	INIT_TIMER_1
	
H_MASTER_TX_0:	
	lds	r16, ONE_WIRE_flag
	sbrs	r16, Timeout_T1_compl	; ждем окончания отсчета
	rjmp	H_MASTER_TX_0

	ret

; Прием мастером бита
; выход: 	бит C регистра SREG содержит принятый бит
; ресурсы	r16
;--------------------------------------------------------------------------
MASTER_RX:
	cli
	sbi	DDRB, DDB2		; порт на вывод

	nop
	nop				; 2 мкСек
	nop
	nop

	cbi	DDRB, DDB2		; импеданс (подтяжка)

	nop				; 8 uSec
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop

	sbic	PINB, PINB2		; считываем бит	
	rjmp	H_L_MASTER_RX_1	

	ldi	YH, High(139)		; [1] заряжаем таймер на 70 мкСек
	ldi	YL, Low(139)            ; [1]
	rcall	INIT_TIMER_1            ; [3]

H_L_MASTER_RX_0:
	lds	r16, ONE_WIRE_flag
	sbrs	r16, Timeout_T1_compl	; ждем окончания отсчета
	rjmp	H_L_MASTER_RX_0

	clc
	ret
	
H_L_MASTER_RX_1:
	ldi	YH, High(139)		; [1] заряжаем таймер на 70 мкСек
	ldi	YL, Low(139)            ; [1]
	rcall	INIT_TIMER_1            ; [3]

H_L_MASTER_RX_1_:
	lds	r16, ONE_WIRE_flag
	sbrs	r16, Timeout_T1_compl	; ждем окончания отсчета
	rjmp	H_L_MASTER_RX_1_

	sec
	ret

; Передача байта данных мастером
; Вход: 	r18 - передаваемый байт. 
; Ресурсы:      r17, r18 
;--------------------------------------------------------------------------
MASTER_TX_BYTE:
	ldi	r17, 8

MASTER_TX_BYTE_LOOP:	
	sei

	clc
	ror	r18
	brcs	MASTER_TX_BYTE_1	

MASTER_TX_BYTE_0:
	rcall	L_MASTER_TX	
	rjmp	MASTER_TX_BYTE_2

MASTER_TX_BYTE_1:	
	rcall	H_MASTER_TX	
		
MASTER_TX_BYTE_2:
	dec	r17
	brne	MASTER_TX_BYTE_LOOP
	ret	

; Прием байта данных мастером
; Выход: 	r18 - принятый байт
; Ресурсы:      r17, r18 
;--------------------------------------------------------------------------
MASTER_RX_BYTE:
	clr	r18
	ldi	r17, 8

MASTER_RX_BYTE_LOOP:	
	sei
	wdr
	rcall	MASTER_RX
	ror	r18

	dec	r17
	brne	MASTER_RX_BYTE_LOOP

	ret

; Прием буфера данны 1wire
; Вход:		r19 - количество принимаемых байт
; Ресурсы:	X, r18, r19 
;--------------------------------------------------------------------------
LOOP_RX_BUFER:
	ldi	XL, Low(DATA_BUF)	; инициализируем буфер данных
	ldi	XH, High(DATA_BUF)
	
LOOP_RX_BUFER_0:
	wdr
	rcall	MASTER_RX_BYTE
	st	X+, r18
	dec	r19
	brne	LOOP_RX_BUFER_0

	ret

; инициализируем таймер_1
; режим CTC
; вход: YL - значение регистра OCR1AL
;	YH - значение регистра OCR1AH
; Ресурсы:      Y, r16
;--------------------------------------------------------------------------
INIT_TIMER_1:
	cli                                     ; [1]
	out	TCNT1H, ZERO			; [1]
	out	TCNT1L, ZERO                    ; [1]
	out	OCR1AH, YH                      ; [1]
	out	OCR1AL, YL                      ; [1]
	in	r16, TIMSK                      ; [1]
	sbr	r16, (1<<OCIE1A)                ; [1]
	out	TIMSK, r16                      ; [1]
	out	TCCR1A, ZERO                    ; [1]
	ldi	r16, (1<<WGM12)|(1<<CS10)       ; [1]
	out	TCCR1B, r16                     ; [1]

	lds	r16, ONE_WIRE_flag              ; [2]
	cbr	r16, (1<<Timeout_T1_compl)	; [1] инициализируем флаг отсчета 
	sts	ONE_WIRE_flag, r16	        ; [2]

	reti	                                ; [4]

; обработчик прерываний таймера 1
;--------------------------------------------------------------------------
TIMER_1_REQUEST:
	push	r16
	in	r16, SREG
	push 	r16

	out	TCCR1B, ZERO			; запрещаем работу таймера
	in	r16, TIMSK
	cbr	r16, (1<<OCIE1A)
	out	TIMSK, r16

	lds	r16, ONE_WIRE_flag
	sbr	r16, (1<<Timeout_T1_compl)	; отсчет закончен 
	sts	ONE_WIRE_flag, r16	

	pop	r16
	out	SREG, r16
	pop	r16	

	reti

;--------------------------------------------------------------------------
; Программный метод вычисления CRC8 
; вход: 	r16 - количество подсчитываемых байт
; выход: 	CRC8_BYTE - байт вычисленой контрольной суммы 
; ресурсы:	r16...r19, Z, Y не сохраняются 
;--------------------------------------------------------------------------

#define	N	r16
#define	a	r17
#define	b	r18
#define	rrbit	r19

CRC_8:
	wdr
	ldi 	YL, Low(DATA_BUF)
	ldi	YH, High(DATA_BUF)
	sts	CRC8_BYTE, ZERO	

CRC_8_:
	ld	a, Y+
	lds	rrbit, CRC8_BYTE
	rcall	UPD_CRC
	sts	CRC8_BYTE, rrbit 
	dec	N
	brne	CRC_8_

	ret

;UPD_CRC:	
;	ldi  	zl, 8				
;	ldi	zh, 0x18
;			
;UCRCU2:
;	mov	b, a			
;	eor	a, rrbit		
;	ror	a			
;	mov	a, rrbit		
;	brcc	UCRCU4	
;	eor	a, zh		
;
;UCRCU4:	
;	ror	a			
;	mov	rrbit, a
;	mov	a, b
;	lsr	a			
;	dec	zl
;	brne	UCRCU2		
;	mov	a, b
;
;	ret

;--------------------------------------------------------------------------
; Табличный метод вычисления CRC8 
;--------------------------------------------------------------------------
UPD_CRC:
	eor	rrbit, a		

	ldi	ZH, high(CRC_TAB<<1)
	ldi	ZL, low(CRC_TAB<<1)
	add	ZL, rrbit
	adc	ZH, ZERO
	lpm	rrbit, Z		

	ret

CRC_TAB:	
.db	0x00,  0x5e,  0xbc,  0xe2,  0x61,  0x3f,  0xdd,  0x83
.db	0xc2,  0x9c,  0x7e,  0x20,  0xa3,  0xfd,  0x1f,  0x41
.db	0x9d,  0xc3,  0x21,  0x7f,  0xfc,  0xa2,  0x40,  0x1e
.db	0x5f,  0x01,  0xe3,  0xbd,  0x3e,  0x60,  0x82,  0xdc
.db	0x23,  0x7d,  0x9f,  0xc1,  0x42,  0x1c,  0xfe,  0xa0
.db	0xe1,  0xbf,  0x5d,  0x03,  0x80,  0xde,  0x3c,  0x62
.db	0xbe,  0xe0,  0x02,  0x5c,  0xdf,  0x81,  0x63,  0x3d
.db	0x7c,  0x22,  0xc0,  0x9e,  0x1d,  0x43,  0xa1,  0xff
.db	0x46,  0x18,  0xfa,  0xa4,  0x27,  0x79,  0x9b,  0xc5
.db	0x84,  0xda,  0x38,  0x66,  0xe5,  0xbb,  0x59,  0x07
.db	0xdb,  0x85,  0x67,  0x39,  0xba,  0xe4,  0x06,  0x58
.db	0x19,  0x47,  0xa5,  0xfb,  0x78,  0x26,  0xc4,  0x9a
.db	0x65,  0x3b,  0xd9,  0x87,  0x04,  0x5a,  0xb8,  0xe6
.db	0xa7,  0xf9,  0x1b,  0x45,  0xc6,  0x98,  0x7a,  0x24
.db	0xf8,  0xa6,  0x44,  0x1a,  0x99,  0xc7,  0x25,  0x7b
.db	0x3a,  0x64,  0x86,  0xd8,  0x5b,  0x05,  0xe7,  0xb9
.db	0x8c,  0xd2,  0x30,  0x6e,  0xed,  0xb3,  0x51,  0x0f
.db	0x4e,  0x10,  0xf2,  0xac,  0x2f,  0x71,  0x93,  0xcd
.db	0x11,  0x4f,  0xad,  0xf3,  0x70,  0x2e,  0xcc,  0x92
.db	0xd3,  0x8d,  0x6f,  0x31,  0xb2,  0xec,  0x0e,  0x50
.db	0xaf,  0xf1,  0x13,  0x4d,  0xce,  0x90,  0x72,  0x2c
.db	0x6d,  0x33,  0xd1,  0x8f,  0x0c,  0x52,  0xb0,  0xee
.db	0x32,  0x6c,  0x8e,  0xd0,  0x53,  0x0d,  0xef,  0xb1
.db	0xf0,  0xae,  0x4c,  0x12,  0x91,  0xcf,  0x2d,  0x73
.db	0xca,  0x94,  0x76,  0x28,  0xab,  0xf5,  0x17,  0x49
.db	0x08,  0x56,  0xb4,  0xea,  0x69,  0x37,  0xd5,  0x8b
.db	0x57,  0x09,  0xeb,  0xb5,  0x36,  0x68,  0x8a,  0xd4
.db	0x95,  0xcb,  0x29,  0x77,  0xf4,  0xaa,  0x48,  0x16
.db	0xe9,  0xb7,  0x55,  0x0b,  0x88,  0xd6,  0x34,  0x6a
.db	0x2b,  0x75,  0x97,  0xc9,  0x4a,  0x14,  0xf6,  0xa8
.db	0x74,  0x2a,  0xc8,  0x96,  0x15,  0x4b,  0xa9,  0xf7
.db	0xb6,  0xe8,  0x0a,  0x54,  0xd7,  0x89,  0x6b,  0x35

