; DS1821_3.ASM
;
; Sets high and low thresholds and then reads the thresholds. 
;  
; Finally programs Bit 2 (T/R) of the Status register to logic one,
; such that the device will in the future boot up in the thermostat
; mode.  Note that the POL bit is programmed to a logic one.  Status
; register is read.
;
; High and low thresholds and content of status register are displayed
; on serial LCD. 
;
; The device may later be returned to the 1-wire communications mode
; by bringing V_DD low and pulsing DQ low 16 times.  This is illustrated
; in program DS1821_4.ASM.
; 
;
; 16C84						DS1821 (TO-220)
; PORTB, Bit 0 (term 6) ------------------------ DQ (term 3)
;
;	  				        GRD (term 2)
;					        +5V (term 1)
;
; PORTA, Bit 1 (terminal 18) ------ TX ----------> to RX on Serial LCD
;
; Note that a 10K pullup resistor to +5V is required on the DQ lead.
;
; Note that LCD_CTRL.ASM is included at the end of this program.
;
; copyright, Peter H. Anderson, MSU, July 25, '97
;

	LIST p=16c84
#include <c:\mplab\p16c84.inc>	
	__CONFIG 11h

	CONSTANT DATA_PIN=0	; define pin on PORTB
	CONSTANT BASE_VAR=0CH

TH		EQU BASE_VAR+0
TL		EQU BASE_VAR+1
STAT		EQU BASE_VAR+2

_N	   	EQU BASE_VAR+3	; these vars used by the 
O_BYTE	   	EQU BASE_VAR+4	; common 1-wire routines
I_BYTE	   	EQU BASE_VAR+5
LOOP3	   	EQU BASE_VAR+6
LOOP2	   	EQU BASE_VAR+7
LOOP1	   	EQU BASE_VAR+8
TEMP	   	EQU BASE_VAR+9

; Program		

	ORG 000H	
MAIN:
	CALL CONFIG_DEVICE	; 0CH 01H, Includes a 20 msec delay

	MOVLW .40		; high threshold set to 40 degrees C
	MOVWF TH

	MOVLW .35		; low threshold to 35 degs C
	MOVWF TL

	CALL WRITE_TH		; 01H TH_VAL, Includes a 20 msec delay
	CALL WRITE_TL		; 02H TL_VAL, Includes a 20 msec delay

	CALL READ_TH		; A1H followed by a read
	CALL READ_TL		; A2H followed by a read

	CALL SET_THERM_MODE	; 0CH 06H set in thermostat mode
        CALL READ_STAT		; ACH followed by a read

        CALL DISPLAY		; display TH, TL and Status Register in 
				; natural binary

DONE:	GOTO DONE
	
CONFIG_DEVICE:
	CALL INIT

	MOVLW 0CH
	MOVWF O_BYTE
	CALL OUT_BYTE
	
	MOVLW 02H		; single shot mode, active polarity = 1
	MOVWF O_BYTE
	CALL OUT_BYTE
	
	MOVLW .20		; 20 msec delay
	MOVWF LOOP1
	CALL DELAY_N_MS
	
	RETURN

WRITE_TH:
	CALL INIT

	MOVLW 01H
	MOVWF O_BYTE
	CALL OUT_BYTE

	MOVF TH, W
	MOVWF O_BYTE
	CALL OUT_BYTE

	MOVLW .20		; 20 msec delay
	MOVWF LOOP1
	CALL DELAY_N_MS
	
	RETURN

WRITE_TL:
	CALL INIT

	MOVLW 02H
	MOVWF O_BYTE
	CALL OUT_BYTE

	MOVF TL, W
	MOVWF O_BYTE
	CALL OUT_BYTE

	MOVLW .20		; 20 msec delay
	MOVWF LOOP1
	CALL DELAY_N_MS

	RETURN

READ_TH:
	CALL INIT

	MOVLW 0A1H
	MOVWF O_BYTE
	CALL OUT_BYTE
	CALL IN_BYTE
	MOVF I_BYTE, W
	MOVWF TH

        RETURN

READ_TL:
	CALL INIT

	MOVLW 0A2H
	MOVWF O_BYTE
	CALL OUT_BYTE
	CALL IN_BYTE
	MOVF I_BYTE, W
	MOVWF TL

        RETURN

READ_STAT:
	CALL INIT

	MOVLW 0ACH
	MOVWF O_BYTE
	CALL OUT_BYTE
	CALL IN_BYTE
	MOVF I_BYTE, W
	MOVWF STAT

        RETURN

SET_THERM_MODE:

	CALL INIT

	MOVLW 0CH
	MOVWF O_BYTE
	CALL OUT_BYTE
	
	MOVLW 06H		; thermostat mode, active polarity = 1
	MOVWF O_BYTE
	CALL OUT_BYTE

	MOVLW .20		; 20 msec delay
	MOVWF LOOP1
	CALL DELAY_N_MS
	
	RETURN

DISPLAY:
	CALL LCD_CLR
	MOVF TH, W		; display TH in natural binary
	CALL LCD_VAL
	MOVLW " "
	CALL LCD_CHAR		; output a space
	MOVF TL, W
	CALL LCD_VAL		; display TL in natural binary
        MOVLW " "
        CALL LCD_CHAR
        MOVF STAT, W
        CALL LCD_VAL
	RETURN

; The following are standard 1-Wire routines.

INIT:
        CALL	PIN_HI
        CALL	PIN_LO

	MOVLW	.50              ; 500 us delay
	CALL DELAY_10USEC

	CALL	PIN_HI		  
        MOVLW 	.50		; 500 usec delay
        CALL DELAY_10USEC

        RETURN

WAIT:        
        CALL 	IN_BYTE
        MOVLW 	0FFH
        SUBWF 	I_BYTE, W
        BTFSS 	STATUS, Z
        GOTO 	WAIT
	RETURN  

IN_BYTE:              ; returns byte in W
	MOVLW	.8
	MOVWF	 _N
        CLRF	I_BYTE

IN_BYTE_1:
	CALL PIN_LO		; momentary low on DATA_PIN
        NOP
	CALL PIN_HI
	NOP
	NOP
	NOP
	NOP
	NOP
        NOP
        MOVF	PORTB, W	; 7 usecs later, fetch from DATA_PIN
	MOVWF	TEMP                                                        
	BTFSS	TEMP, DATA_PIN
	BCF STATUS, C		; its a zero
	BTFSC	TEMP, DATA_PIN
	BSF STATUS, C		; its a one

        RRF	I_BYTE, F
	MOVLW .6		; now delay 60 usecs
        CALL	DELAY_10USEC
        DECFSZ	_N, F
        GOTO	IN_BYTE_1

        MOVFW	I_BYTE		; return the result in W
        RETURN

OUT_BYTE:
	MOVLW	.8
        MOVWF	_N
OUT_BYTE_1:
	RRF	O_BYTE, F
        BTFSS	STATUS, C
	GOTO	OUT_0
	GOTO	OUT_1	
OUT_BYTE_2:
	DECFSZ	_N, F
        GOTO	OUT_BYTE_1
        RETURN

OUT_0:
	CALL	PIN_LO		; bring DATA_PIN low
	MOVLW	.6		; for 60 usecs
	CALL 	DELAY_10USEC
        CALL	PIN_HI
        GOTO	OUT_BYTE_2

OUT_1:
	CALL	PIN_LO		; momentary low
        CALL	PIN_HI
        MOVLW .6
	CALL DELAY_10USEC
        GOTO	OUT_BYTE_2

;;;;;;

PIN_HI:
	BSF	STATUS, RP0
        BSF	TRISB, DATA_PIN		; high impedance
        BCF	STATUS, RP0
        
        RETURN

PIN_LO:
	BCF	PORTB, DATA_PIN
	BSF	STATUS, RP0
        BCF	TRISB, DATA_PIN		; low impedance zero
        BCF	STATUS, RP0
        
        RETURN

DELAY_LONG
	MOVLW .250	; 250 msec delay
	MOVWF LOOP1
DELAY_N_MS:
OUTTER:
	MOVLW	.110	; close to 1.0 msec delay when set to .110
	MOVWF 	LOOP2
INNER:
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	DECFSZ	LOOP2, F	; decrement and leave result in LOOP2 
				; skip next statement if zero
	GOTO INNER
	DECFSZ 	LOOP1, F
	GOTO OUTTER
	RETURN

DELAY_10USEC:	; provides a delay equal to W * 10 usecs
	MOVWF LOOP1
DELAY_10USEC_1:
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	DECFSZ LOOP1, F
	GOTO DELAY_10USEC_1
	RETURN

#include <a:\lcd\lcd_ctrl.asm>

	END