    #include <xc.inc>
      CONFIG  FOSC = HS             
      CONFIG  WDTE = OFF            
      CONFIG  PWRTE = OFF           
      CONFIG  BOREN = OFF           
      CONFIG  LVP = OFF             
      CONFIG  CPD = OFF             
      CONFIG  WRT = OFF             
      CONFIG  CP = OFF              
    DELAY_A equ 0x70	
    DELAY_MULTIPLIER equ 0x71	;variable for the multiplier		
    cmd_addr equ 0x72	;variable for the ROM command address 
    Mms_MULTIPLIER equ 0x74	; this variable is to store the required inner iteration steps for delay.
    bit_counter	equ 0x75 ; variable for the counting the number of bits that are being sent
    byte_recd equ 0x76	; variable for storing the read byte	
    byte_recd_1 equ 0x77	; variable for storing byte 1 of the LSB of the converted temperature 	
; ==== Program Flows ====== 

 
;=========  Example3 uart =========
     psect RESET_VECT,class=CODE,delta=2
    RESET_VECT:		;reset vector
	goto setup
    psect INT_VECT,class=CODE,delta=2 ;pic10/12/16
    INT_VECT:		;interrupt vector
	retfie
    setup:		; All of these address needs to be in capital letter
	;=== uart related set up =====
	call uart_init	
	; ======== bank1 here ==================
;	bsf STATUS,5	; bank1 is selected 
	call init_var
	; ======== bank0 here ========================
	bcf STATUS,5	; now, bank0 is selected by assigning 0 to bit 5 and bit 6=0 by default ?00
	; =========== end ===============================================
    main:
	call reset_pulse    ; step1 initialization
        call rom_skip_cmd   ; step2 issue skip cmd.
        call t_convert	    ; step3 issue function cmd t-convert
	
	call reset_pulse    ; step1 initialization
	call rom_skip_cmd   ; step2 issue skip cmd.
	call read_scratchPad ; step3 issue function to read scratchPad

	call read_byte	    ;  read the byte 1 LSB
	call send_read_bit  ; send the LSB byte to uart
	goto pause_here	
	goto main
	
    pause_here:
    	goto pause_here
    ; === DS section ==============
    reset_pulse:
        call PIC_bus_rx		; To start in rx mode
	call PIC_bus_tx	; pull the bus low for tx
	call delay_480us
	call PIC_bus_rx		; release the bus
	call delay_60us		; wait for the bus to pull high
	call delay_10us		; wait for DS to pull the bus low
	call register_DS_presence
	call delay_480us
	return
	
    register_DS_presence:
	bcf STATUS,5	; now, bank0
    	btfsc PORTB,0
	goto send_NACK
	call send_ACK
	return

    t_convert:
        call init_Tconv_var
	call PIC_bus_rx		; release the bus
	goto write_Byte
	call PIC_bus_rx		; release the bus
	call delay_800ms
	return
    read_scratchPad:
        call init_var_readScratchPad
	call PIC_bus_rx		; release the bus
	goto write_Byte	
	call PIC_bus_rx		; release the bus
	call read_byte
	call send_read_bit
	call reset_pulse
	return

    PIC_bus_tx:
	bsf STATUS,5	; bank1 is selected by assigning 1 to bit 5 and bit 6=0 by default 01
	movlw 0x00 ; assigns B0 as output
	movwf TRISB	; set PORTD as input pins	    
	bcf STATUS,5	; now, bank0
	bcf PORTB,0
	return
    PIC_bus_rx:
	bsf STATUS,5	; bank1 is selected by assigning 1 to bit 5 and bit 6=0 by default 01
	movlw 0x01 ; assigns B0 as input
	movwf TRISB	; set PORTB as input pins	    
	bcf STATUS,5	; now, bank0
	bcf PORTB,0
	return        	
    ; ==== write command byte ===========	
    rom_skip_cmd:
	call init_var	
	call PIC_bus_rx		; release the bus first
    write_Byte:
        btfss cmd_addr,0
	goto write_0
    write_1:
	call PIC_bus_tx	; pull the bus low for tx
	call delay_1us
	call PIC_bus_rx	; release the bus, i.e. turn to Rx mode
	call delay_60us	; and hold that for at least 60us
	call send_bit_1	
	goto next_bit
    write_0:
	call PIC_bus_tx	; pull the bus low for tx
	call delay_60us	; and hold that for at least 60us
	call PIC_bus_rx	; release the bus, i.e. turn to Rx mode
	call send_bit_0
    next_bit:
    	decfsz bit_counter
	goto shift_bit
	goto start_function_cmd
    shift_bit:	
	rrf cmd_addr,1	; right shift of the register bit
	goto write_Byte	; go check if the new bit zero is '1' or '0'
    ;========================================	
    start_function_cmd:
	call send_space
	return

    read_byte:
	clrf byte_recd	    ; initialize the variable
	bcf STATUS,0	    ; clear the carry bit
	call PIC_bus_rx	    ; refresh the pin direction for output then input	
    read_bit:	
    	call PIC_bus_tx	    ; pull the bus low for a brief 1us
    	call PIC_bus_rx	    ; release the bus		
	call delay_15us	    ; wait 15us from DS
;	call delay_15us	    ; wait 15us from DS		
	bcf STATUS,5	; now, bank0
	btfsc PORTB,0	    ; check if B0=0
	bsf byte_recd,7	    ; DS transmits the LSB first, thus update the bit7 in the variable and keep shifting them to the right. 
	call delay_50us	    
	decfsz bit_counter,1	; decrease the bit counter by 1 an check if it's zero 
	goto read_bit_sub	    ; read the next bit
	return
        read_bit_sub:	
	rrf byte_recd,1	    ; right shift if not the last bit
	goto read_bit	    ; read the next bit
    ; =====================================================================
    ; ===== delay modules =================================================
    delay_Mms:		;At the end of this, it takes 49ms 
    	call delay_193us    ;
	decfsz DELAY_MULTIPLIER,1   ;keep decrementing till DELAY_MULTIPLIER=0 if so skip the next line
	goto delay_Mms
	return
    delay_193us:	; total delay time is about 192s
	movf Mms_MULTIPLIER,0	; put Mms_MULTIPLIER to W
	movwf DELAY_A	; move the Mms_MULTIPLIER from W 
    delay_a:		; this line is executed after the movwf DELAY_A
	decfsz DELAY_A,1 ;value in DELAY_A=DELAY_A-1 and skip if DELAY_A=0. 
			 ; The 1 indicates that the decremented value is put back to DELAY_A
	goto delay_a	; keep the decrement process; if value in DELAY_A=0, this goto line is skipped
	return		; and this return line is executed. It returns to the next line when the call insx was executed.
    delay_480us:	
	movlw 0xFF	; delay a total of 480us with 255+255+135 as the value of Mms_MULTIPLIER
	movwf Mms_MULTIPLIER	; 255
	call delay_193us	; delay 193us
	call delay_193us	; delay another 193us
	movlw 0x87		; 135    
	movwf Mms_MULTIPLIER
	call delay_193us	; delay another 103us, therefore 193x2+103=489us	
	return
    delay_10us:
    	movlw 0x0A	; delay 10us with 10 as the value of Mms_MULTIPLIER
	movwf Mms_MULTIPLIER	; 10
	call delay_193us	; delay 193us
	return
    delay_60us:
    	movlw 0x4E	; delay 60us with 78 as the value of Mms_MULTIPLIER
	movwf Mms_MULTIPLIER	; 78
	call delay_193us	; delay 193us
	return	
    delay_15us:
    	movlw 0x12	; delay 15us with 18 as the value of Mms_MULTIPLIER
	movwf Mms_MULTIPLIER	; 18
	call delay_193us	; delay 193us
	return	

    delay_45us:
    	movlw 0x3A	; delay 15us with 58 as the value of Mms_MULTIPLIER
	movwf Mms_MULTIPLIER	; 58
	call delay_193us	; delay 193us
	return		
    delay_50us:
    	movlw 0x41	; delay 50us with 65 as the value of Mms_MULTIPLIER
	movwf Mms_MULTIPLIER	; 65
	call delay_193us	; delay 193us
	return			
    delay_800ms:
	movlw 0x08	; assign 8 to W
	movwf bit_counter ; assign 8 bits to the counter	
	delay_800ms_loop:
    	movlw 0xFF	; 
	movwf Mms_MULTIPLIER	; 255
	movlw 0xFF  ; move 255 to W
	movwf DELAY_MULTIPLIER	; 255 to DELAY_MULTIPLIER	
	call delay_Mms    ; this is about 98ms delay and 
	decfsz bit_counter  ; this is to be repeated 8 times
	goto delay_800ms_loop    
	return
    delay_1us:
	nop
	nop
	nop
	nop
	return
    ;==========================================  

    ; ====== uart section =====================
    
    send_read_bit:
    	movlw 0x08	; assign 8 to W
	movwf bit_counter ; assign 8 bits to the counter
	read_and_send_next_bit:
	btfss byte_recd,0
	goto send_bit_0_head	
	call send_bit_1
	how_many_bit:
	decfsz bit_counter,1	; decrease the bit counter by 1 an check if it's zero
	goto roll_next_bit	    ; read the next bit
	call send_space
	return
    roll_next_bit:
	rrf byte_recd,1	    ; right shift is not the last bit	    
	goto read_and_send_next_bit    
    send_bit_0_head:
	call send_bit_0
	goto how_many_bit
    
	
    send_NACK:
	movlw 'N'
	call pic_tx
	return
    
    send_ACK:
	movlw 'A'
	call pic_tx	
	movlw 'C'
	call pic_tx	
	movlw 'K'
	call pic_tx			
	movlw ' '
	call pic_tx				
	return
    send_bit_1:
	movlw '1'
	call pic_tx					
	return
    send_bit_0:
	movlw '0'
	call pic_tx					
	return	
    send_space:
	movlw ' '
	call pic_tx					
	return	

pic_tx:	
	
	bcf STATUS,5	; now, bank0 is selected 
	movwf TXREG ;W to TXREG which is the register (bank0) where data is assigned to annd get send 
	call uart_tx_poll ; check tranmission status	
	;bsf STATUS,5	; bank1 is selected 
	return

    uart_init:
	; bank1
	; Asyn Transmit
	bsf STATUS,5	; bank1 is selected by assigning 1 to bit 5 and bit 6=0 by default 01	
	movlw (1<<7) | (1<<4) ;left shit 1 to bit7 and bit4
	iorwf TRISC,1	;compare each bit in W and TRISC the result will be put to TRISC in bank1
			; to do it this way, iorwf, you maintain whaever the setting is in TRISC.	
	bcf TXSTA,6	; 8elect 8bits transmission; default=0
	bcf TXSTA,4	; 8elect Asyn mode; default=0
	bsf TXSTA,5	; enable transmit
	bcf TXSTA,2	; enable low speed baud rate instead of high speed(=1). Try high speed later on (defaule=0)
			; TRMT bit1 is a read only bit. We'll check this when the transmit is done.
	; baud rate setup
	movlw 25
	movwf SPBRG	;set the baudrate value as 25 as per low speed calculated data sheet based on 9.6k freq 
	; bank0
	bcf STATUS,5	; now, bank0 is selected by assigning 0 to bit 5 and bit 6=0 by default ?00
	return
    uart_tx_poll:
    uart_tx_done:	    ; check the transmit successful flag
	btfss PIR1,4   ; if this bit4 TXIF value=1,TXREG is empty and ready to process the next.
	goto uart_tx_done     
	bcf STATUS,5	; now, bank0 is selected
	return
    ; =======================================================================	
    ; ==== variables initialisation ============
    init_var:
	movlw 0x08	; assign 8 to W
	movwf bit_counter ; assign 8 bits to the counter
	movlw 0xCC	; assign 204 to W
	movwf cmd_addr	; assign the register to the skip command register
	bcf STATUS,0
	return
    init_Tconv_var:
	movlw 0x08	; assign 8 to W
	movwf bit_counter ; assign 8 bits to the counter
	movlw 0x44	; assign 68 to W
	movwf cmd_addr	; assign the register to the skip command register
	bcf STATUS,0
	return    
    init_var_readScratchPad:
	movlw 0x08	; assign 8 to W
	movwf bit_counter ; assign 8 bits to the counter
	movlw 0xBE	; assign 204 to W
	movwf cmd_addr	; assign the register to the skip command register
	bcf STATUS,0
	return	
    ;============================================
    
END RESET_VECT
